以下是12个Go并发编程的小测验,看看你能答对几道题? (持续增加中)
1 Mutex 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package mainimport ( "fmt" "sync" ) var mu sync.Mutexvar chain string func main () { chain = "main" A() fmt.Println(chain) } func A () { mu.Lock() defer mu.Unlock() chain = chain + " --> A" B() } func B () { chain = chain + " --> B" C() } func C () { mu.Lock() defer mu.Unlock() chain = chain + " --> C" }
A: 不能编译
B: 输出 main --> A --> B --> C
C: 输出 main
D: panic
2 RWMutex 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package mainimport ( "fmt" "sync" "time" ) var mu sync.RWMutexvar count int func main () { go A() time.Sleep(2 * time.Second) mu.Lock() defer mu.Unlock() count++ fmt.Println(count) } func A () { mu.RLock() defer mu.RUnlock() B() } func B () { time.Sleep(5 * time.Second) C() } func C () { mu.RLock() defer mu.RUnlock() }
A: 不能编译
B: 输出 1
C: 程序hang住
D: panic
3 Waitgroup 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package mainimport ( "sync" "time" ) func main () { var wg sync.WaitGroup wg.Add(1 ) go func () { time.Sleep(time.Millisecond) wg.Done() wg.Add(1 ) }() wg.Wait() }
A: 不能编译
B: 无输出,正常退出
C: 程序hang住
D: panic
4 双检查实现单例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package doublecheckimport ( "sync" ) type Once struct { m sync.Mutex done uint32 } func (o *Once) Do(f func () ) { if o.done == 1 { return } o.m.Lock() defer o.m.Unlock() if o.done == 0 { o.done = 1 f() } }
A: 不能编译
B: 可以编译,正确实现了单例
C: 可以编译,不正确的单例实现
D: 可以编译,但是程序运行会panic
5 Mutex 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package mainimport ( "fmt" "sync" ) type MyMutex struct { count int sync.Mutex } func main () { var mu MyMutex mu.Lock() var mu2 = mu mu.count++ mu.Unlock() mu2.Lock() mu2.count++ mu2.Unlock() fmt.Println(mu.count, mu2.count) }
A: 不能编译
B: 输出 1, 1
C: 输出 1, 2
D: panic
6 Pool 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 package mainimport ( "bytes" "fmt" "runtime" "sync" "time" ) var pool = sync.Pool{New: func () interface {} { return new (bytes.Buffer) }}func main () { go func () { for { processRequest(1 << 28 ) } }() for i := 0 ; i < 1000 ; i++ { go func () { for { processRequest(1 << 10 ) } }() } var stats runtime.MemStats for i := 0 ; ; i++ { runtime.ReadMemStats(&stats) fmt.Printf("Cycle %d: %dB\n" , i, stats.Alloc) time.Sleep(time.Second) runtime.GC() } } func processRequest (size int ) { b := pool.Get().(*bytes.Buffer) time.Sleep(500 * time.Millisecond) b.Grow(size) pool.Put(b) time.Sleep(1 * time.Millisecond) }
A: 不能编译
B: 可以编译,运行时正常,内存稳定
C: 可以编译,运行时内存可能暴涨
D: 可以编译,运行时内存先暴涨,但是过一会会回收掉
7 channel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package mainimport ( "fmt" "runtime" "time" ) func main () { var ch chan int go func () { ch = make (chan int , 1 ) ch <- 1 }() go func (ch chan int ) { time.Sleep(time.Second) <-ch }(ch) c := time.Tick(1 * time.Second) for range c { fmt.Printf("#goroutines: %d\n" , runtime.NumGoroutine()) } }
A: 不能编译
B: 一段时间后总是输出 #goroutines: 1
C: 一段时间后总是输出 #goroutines: 2
D: panic
8 channel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package mainimport "fmt" func main () { var ch chan int var count int go func () { ch <- 1 }() go func () { count++ close (ch) }() <-ch fmt.Println(count) }
A: 不能编译
B: 输出 1
C: 输出 0
D: panic
9 Map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package mainimport ( "fmt" "sync" ) func main () { var m sync.Map m.LoadOrStore("a" , 1 ) m.Delete("a" ) fmt.Println(m.Len()) }
A: 不能编译
B: 输出 1
C: 输出 0
D: panic
10 happens before 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package mainvar c = make (chan int )var a int func f () { a = 1 <-c } func main () { go f() c <- 0 print (a) }
A: 不能编译
B: 输出 1
C: 输出 0
D: panic
11 自定义Map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package mainimport "sync" type Map struct { m map [int ]int sync.Mutex } func (m *Map) Get(key int ) (int , bool ) { m.Lock() defer m.Unlock() i, ok := m.m[key] return i, ok } func (m *Map) Put(key, value int ) { m.Lock() defer m.Unlock() m.m[key] = value } func (m *Map) Len() int { return len (m.m) } func main () { var wg sync.WaitGroup wg.Add(2 ) m := Map{m: make (map [int ]int )} go func () { for i := 0 ; i < 10000000 ; i++ { m.Put(i, i) } wg.Done() }() go func () { for i := 0 ; i < 10000000 ; i++ { m.Len() } wg.Done() }() wg.Wait() }
go run quiz.go运行。
A: 不能编译
B: 可运行,无并发问题
C: 可运行,有并发问题
D: panic
12 slice 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package mainimport ( "fmt" "sync" ) func main () { var wg sync.WaitGroup wg.Add(2 ) var ints = make ([]int , 0 , 1000 ) go func () { for i := 0 ; i < 1000 ; i++ { ints = append (ints, i) } wg.Done() }() go func () { for i := 0 ; i < 1000 ; i++ { ints = append (ints, i) } wg.Done() }() wg.Wait() fmt.Println(len (ints)) }
A: 不能编译
B: 输出2000
C: 输出可能不是2000
D: panic
13 goroutine 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 package mainimport ( "fmt" "sync" "time" ) type T struct { V int } func (t *T) Incr(wg *sync.WaitGroup) { t.V++ wg.Done() } func (t *T) Print() { time.Sleep(1e9 ) fmt.Print(t.V) } func main () { var wg sync.WaitGroup wg.Add(10 ) var ts = make ([]T, 10 ) for i := 0 ; i < 10 ; i++ { ts[i] = T{i} } for _, t := range ts { go t.Incr(&wg) } wg.Wait() for _, t := range ts { go t.Print() } time.Sleep(5 * time.Second) }
A: 输出12345678910
B: 输出0123456789
C: 输出9999999999
D: 输出10101010101010101010
1. D
2. D
3. D
4. C
5. D
6. C
7. C
8. D
9. A
10. B
11. C
12. C
13. C
代码: go concurrency quiz