5

一道经常考的面试题 - Go语言中文网 - Golang中文社区

 1 year ago
source link: https://studygolang.com/articles/23333?fr=sidebar
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一道经常考的面试题

fox_lin · 2019-09-06 10:02:56 · 4571 次点击 · 预计阅读时间 1 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2019-09-06 10:02:56 的文章,其中的信息可能已经有所发展或是发生改变。

前段时间在找工作,也遇到一些不错的面试题,其中有一道很常见,记录一下,里面还有一点搞不明白的:

下面两段程序的输出是什么?

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            fmt.Println(i)
            wg.Done()
        }()
    }
    wg.Wait()
}
func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func(n int) {
            fmt.Println(n)
            wg.Done()
        }(i)
    }
    wg.Wait()
}

很多面试题解析里面说第一段的10个goroutine输出全部是10,我对这个结论是一直持怀疑态度的,因为输出什么,取决于那个goroutine里面代码被执行时外层i循环到哪里,经我实测,也符合我自己的想法。

但是那天那个面试官很肯定的说会全部输出一样的数,我忘记问他的理由是什么了。

关于第二段程序,乱序输出0-9,相信大家是没有异议的。总计有10^10种可能。针对第二段程序,那位面试官接着问了一个我觉得挺有水平的问题:这10^10种输出里面,肯定有一种是按顺序0-9依次输出的,能不能通过一些方法,让这段程序的输出顺序固定下来?这个问题我一时还真的抓不到要点了。。。后来在面试官不断的提点下,我才想到面试官的考点,不禁觉得这个面试官还是很有水平的。
第二段程序如何改动才能达到定序输出的效果呢?我们知道每个goroutine生成后,在P的本地G队列未满的时候,是依次加入到P的本地G队列里的,如果只有一个P可用,也就只有一个本地G队列存在,那么这些G的执行顺序其实是取决于P的G队列的顺序的,那么答案也就出来了,我们只要设置P的数量为1,即可达到定序输出的目的:

func main() {
    runtime.GOMAXPROCS(1)
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func(n int) {
            fmt.Println(n)
            wg.Done()
        }(i)
    }
    wg.Wait()
}

不过这里我还是有一点不明白的是,9为什么是第一个被输出的?我猜大概是跟GMP调度有关的。目前还不明白,有知道的同学可以指点我一下,谢谢。

以上如有错误,欢迎指出。


有疑问加站长微信联系(非本文作者)

280

本文来自:Segmentfault

感谢作者:fox_lin

查看原文:一道经常考的面试题

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK