Golang面试题目-并发题目(选择题)

1、阅读下例代码,从以下四个选项中选择代码执行结果(Mutex相关)。

package mainimport (  "fmt"  "sync")var mu sync.Mutexvar chain stringfunc 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"}

选项如下:

  1. 不能编译

  2. 输出main-->A-->B-->C

  3. 输出main

  4. panic

解析:4。上述代码会产生死锁panic,因为Mutex是互斥锁。

2、阅读下例代码,从以下四个选项中选择代码执行结果(RWMutex相关)。

package mainimport (  "fmt"  "sync"  "time")var mu sync.RWMutexvar count intfunc 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()}

选项如下:

  1. 不能编译

  2. 输出 1

  3. 程序hang住

  4. panic

解析:4。上述代码会产生死锁panic,根据sync/rwmutex.go中的注释可以知道,读写锁当有一个协程在等待写锁时,其它协程是不能获得读锁,而在A和C中同一个调用链中间需要让出读锁,让写锁优先获取,而A的读锁又要求C调用完成,因此产生死锁。

3、阅读下例代码,从以下四个选项中选择代码执行结果(WaitGroup相关)。

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()}

选项如下:

  1. 不能编译

  2. 无输出,正常退出

  3. 程序hang住

  4. panic

解析:4。WaitGroup在调用Wait之后是不能再调用Add方法的。

4、阅读下例代码,从以下四个选项中选择代码执行结果(双检查实现单例)。

package mainimport "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()  }}

选项如下:

  1. 不能编译

  2. 可以编译,正确实现了单例

  3. 可以编译,有并发问题,f函数可能会被执行多次

  4. 可以编译,但是运行程序会panic

解析:3。在多核CPU中,因为CPU缓存会导致多个核心中变量值不同步。

5、阅读下例代码,从以下四个选项中选择代码执行结果(Mutex相关)。

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)}

选项如下:

  1. 不能编译

  2. 输出 1,1

  3. 输出 1,2

  4. panic

解析:4。加锁后复制变量,会将锁的状态也复制过来,所以mul其实是已经加锁的状态,再加锁会产生死锁。

6、阅读下例代码,从以下四个选项中选择代码执行结果(Pool相关)。

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) // 256MiB    }  }()  for i := 0; i < 1000; i++ {    go func() {      for {        processRequest(1 << 10) // 1KiB      }    }()  }  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)}

选项如下:

  1. 不能编译

  2. 可以编译,运行时正常,内存稳定

  3. 可以编译,运行时内存可能暴涨

  4. 可以编译,运行时内存先暴涨,但是过一会儿会回收掉

解析:3。在单核CPU中内存可能会稳定在256MB,如果是多核CPU则会暴涨。

7、阅读下例代码,从以下四个选项中选择代码执行结果(channel相关)。

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())  }}

选项如下:

  1. 不能编译

  2. 一段时间后总是输出 #goroutine:1

  3. 一段时间后总是输出 #goroutine:2

  4. panic

解析:3。因ch未初始化,读写channel都会阻塞,之后被第一个协程重新赋值,导致写的ch都会阻塞。

8、阅读下例代码,从以下四个选项中选择代码执行结果(channel相关)。

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)}

选项如下:

  1. 不能编译

  2. 输出 1

  3. 输出 0

  4. panic

解析:4。ch未被初始化,关闭时会报错。

9、阅读下例代码,从以下四个选项中选择代码执行结果(Map相关)。

package mainimport (  "fmt"  "sync")func main() {  var m sync.Map  m.LoadOrStore("a", 1)  m.Delete("a")  fmt.Println(m.Len())}

选项如下:

  1. 不能编译

  2. 输出 1

  3. 输出 0

  4. panic

解析:1。sync.Map没有Len方法。

10、阅读下例代码,选择代码执行结果(happens before相关)。

package mainvar c = make(chan int)var a intfunc f() {  a = 1  <-c}func main() {  go f()  c <- 0  print(a)}

选项如下:

  1. 不能编译

  2. 输出 1

  3. 输出 0

  4. panic

解析:2。c<-0会阻塞依赖与f()的执行。

扫码关注公众号,获取更多优质内容。   

 

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luyaran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值