前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go并发编程小测验: 你能答对几道题?

Go并发编程小测验: 你能答对几道题?

作者头像
李海彬
发布2019-05-14 17:24:11
9420
发布2019-05-14 17:24:11
举报
文章被收录于专栏:Golang语言社区Golang语言社区
1 Mutex
代码语言:javascript
复制
 1 package main
 2 import (
 3    "fmt"
 4    "sync"
 5)
 6 var mu sync.Mutex
 7 var chain string
 8 func main() {
 9    chain = "main"
10    A()
11    fmt.Println(chain)
12}
13 func A() {
14    mu.Lock()
15    defer mu.Unlock()
16    chain = chain + " --> A"
17    B()
18}
19 func B() {
20    chain = chain + " --> B"
21    C()
22}
23 func C() {
24    mu.Lock()
25    defer mu.Unlock()
26    chain = chain + " --> C"
27}
  • A: 不能编译
  • B: 输出 main --> A --> B --> C
  • C: 输出 main
  • D: panic

2 RWMutex

代码语言:javascript
复制
 1 package main
 2 import (
 3    "fmt"
 4    "sync"
 5    "time"
 6)
 7 var mu sync.RWMutex
 8 var count int
 9 func main() {
10    go A()
11    time.Sleep(2 * time.Second)
12    mu.Lock()
13    defer mu.Unlock()
14    count++
15    fmt.Println(count)
16}
17 func A() {
18    mu.RLock()
19    defer mu.RUnlock()
20    B()
21}
22 func B() {
23    time.Sleep(5 * time.Second)
24    C()
25}
26 func C() {
27    mu.RLock()
28    defer mu.RUnlock()
29}
  • A: 不能编译
  • B: 输出 1
  • C: 程序hang住
  • D: panic

3 Waitgroup

代码语言:javascript
复制
 1 package main
 2 import (
 3    "sync"
 4    "time"
 5)
 6 func main() {
 7    var wg sync.WaitGroup
 8    wg.Add(1)
 9    go func() {
10        time.Sleep(time.Millisecond)
11        wg.Done()
12        wg.Add(1)
13    }()
14    wg.Wait()
15 }
  • A: 不能编译
  • B: 无输出,正常退出
  • C: 程序hang住
  • D: panic

4 双检查实现单例

代码语言:javascript
复制
 1 package doublecheck
 2 import (
 3    "sync"
 4)
 5 type Once struct {
 6    m    sync.Mutex
 7    done uint32
 8 }
 9 func (o *Once) Do(f func()) {
10    if o.done == 1 {
11        return
12    }
13    o.m.Lock()
14    defer o.m.Unlock()
15    if o.done == 0 {
16        o.done = 1
17        f()
18    }
19 }
  • A: 不能编译
  • B: 可以编译,正确实现了单例
  • C: 可以编译,有并发问题,f函数可能会被执行多次
  • D: 可以编译,但是程序运行会panic

5 Mutex

代码语言:javascript
复制
 1 package main
 2 import (
 3    "fmt"
 4    "sync"
 5 )
 6 type MyMutex struct {
 7    count int
 8    sync.Mutex
 9 }
10 func main() {
11    var mu MyMutex
12    mu.Lock()
13    var mu2 = mu
14    mu.count++
15    mu.Unlock()
16    mu2.Lock()
17    mu2.count++
18    mu2.Unlock()
19    fmt.Println(mu.count, mu2.count)
20 }
  • A: 不能编译
  • B: 输出 1, 1
  • C: 输出 1, 2
  • D: panic

6 Pool

代码语言:javascript
复制
 1 package main
 2 import (
 3    "bytes"
 4    "fmt"
 5    "runtime"
 6    "sync"
 7    "time"
 8)
 9 var pool = sync.Pool{New: func() interface{} { return new(bytes.Buffer) }}
10 func main() {
11    go func() {
12        for {
13            processRequest(1 << 28) // 256MiB
14        }
15    }()
16    for i := 0; i < 1000; i++ {
17        go func() {
18            for {
19                processRequest(1 << 10) // 1KiB
20            }
21        }()
22    }
23    var stats runtime.MemStats
24    for i := 0; ; i++ {
25        runtime.ReadMemStats(&stats)
26        fmt.Printf("Cycle %d: %dB\n", i, stats.Alloc)
27        time.Sleep(time.Second)
28        runtime.GC()
29    }
30}
31 func processRequest(size int) {
32    b := pool.Get().(*bytes.Buffer)
33    time.Sleep(500 * time.Millisecond)
34    b.Grow(size)
35    pool.Put(b)
36    time.Sleep(1 * time.Millisecond)
37 }
  • A: 不能编译
  • B: 可以编译,运行时正常,内存稳定
  • C: 可以编译,运行时内存可能暴涨
  • D: 可以编译,运行时内存先暴涨,但是过一会会回收掉

7 channel

代码语言:javascript
复制
 1 package main
 2 import (
 3    "fmt"
 4    "runtime"
 5    "time"
 6)
 7 func main() {
 8    var ch chan int
 9    go func() {
10        ch = make(chan int, 1)
11        ch <- 1
12    }()
13    go func(ch chan int) {
14        time.Sleep(time.Second)
15        <-ch
16    }(ch)
17    c := time.Tick(1 * time.Second)
18    for range c {
19        fmt.Printf("#goroutines: %d\n", runtime.NumGoroutine())
20    }
21}
  • A: 不能编译
  • B: 一段时间后总是输出 #goroutines: 1
  • C: 一段时间后总是输出 #goroutines: 2
  • D: panic

8 channel

代码语言:javascript
复制
 1 package main
 2 import "fmt"
 3 func main() {
 4    var ch chan int
 5    var count int
 6    go func() {
 7        ch <- 1
 8    }()
 9    go func() {
10        count++
11        close(ch)
12    }()
13    <-ch
14    fmt.Println(count)
15}
  • A: 不能编译
  • B: 输出 1
  • C: 输出 0
  • D: panic

9 Map

代码语言:javascript
复制
 1 package main
 2 import (
 3    "fmt"
 4    "sync"
 5)
 6 func main() {
 7    var m sync.Map
 8    m.LoadOrStore("a", 1)
 9    m.Delete("a")
10    fmt.Println(m.Len())
11}
  • A: 不能编译
  • B: 输出 1
  • C: 输出 0
  • D: panic

10 happens before

代码语言:javascript
复制
 1 package main
 2 var c = make(chan int)
 3 var a int
 4 func f() {
 5    a = 1
 6    <-c
 7}
 8 func main() {
 9    go f()
10    c <- 0
11    print(a)
12}
  • A: 不能编译
  • B: 输出 1
  • C: 输出 0
  • D: panic

11 自定义Map

代码语言:javascript
复制
 1 package main
 2 import "sync"
 3 type Map struct {
 4    m map[int]int
 5    sync.Mutex
 6}
 7 func (m *Map) Get(key int) (int, bool) {
 8    m.Lock()
 9    defer m.Unlock()
10    i, ok := m.m[key]
11    return i, ok
12}
13 func (m *Map) Put(key, value int) {
14    m.Lock()
15    defer m.Unlock()
16    m.m[key] = value
17}
18 func (m *Map) Len() int {
19    return len(m.m)
20}
21 func main() {
22    var wg sync.WaitGroup
23    wg.Add(2)
24    m := Map{m: make(map[int]int)}
25    go func() {
26        for i := 0; i < 10000000; i++ {
27            m.Put(i, i)
28        }
29        wg.Done()
30    }()
31    go func() {
32        for i := 0; i < 10000000; i++ {
33            m.Len()
34        }
35        wg.Done()
36    }()
37    wg.Wait()
38}

go run quiz.go运行。

  • A: 不能编译
  • B: 可运行,无并发问题
  • C: 可运行,有并发问题
  • D: panic

12 Slice

代码语言:javascript
复制
 1 package main
 2 import (
 3    "fmt"
 4    "sync"
 5)
 6 func main() {
 7    var wg sync.WaitGroup
 8    wg.Add(2)
 9    var ints = make([]int, 0, 1000)
10    go func() {
11        for i := 0; i < 1000; i++ {
12            ints = append(ints, i)
13        }
14        wg.Done()
15    }()
16    go func() {
17        for i := 0; i < 1000; i++ {
18            ints = append(ints, i)
19        }
20        wg.Done()
21    }()
22    wg.Wait()
23    fmt.Println(len(ints))
24}
  • A: 不能编译
  • B: 输出2000
  • C: 输出可能不是2000
  • D: panic
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2 RWMutex
  • 3 Waitgroup
  • 4 双检查实现单例
  • 5 Mutex
  • 6 Pool
  • 7 channel
  • 8 channel
  • 9 Map
  • 10 happens before
  • 11 自定义Map
  • 12 Slice
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档