抖音面试题

麻烦大家帮忙回答以下问题,下面代码的结果应该是 3 1 2 或者 3 2 1。这是为什么呢?我原来以为是调度协程的顺序不确定,但是一定先输出 3。不知道哪位大佬麻烦讲解一下。

一. 抖音面试题

ch := make(chan int, 10)
for i := 1; i <= 3; i++ {
go func(i int) {
ch <- i
}(i)
}

for i := 0; i < 3; i++ {
    fmt.Println(<-ch) // 3 1 2
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 14

这个和GMP调度模型有关,假如:go_1 先被入队、go_2 后被入队、go_3最后入队,让后调度器还在go_3这里进行调度,调度完成后按顺序执行

2个月前 评论
skyLee 2个月前

为什么会一定先输出3?协程执行的顺序都是不固定的,123 321 312 213 这种情况都会出现

2个月前 评论

file

2个月前 评论
SmileChiT (楼主) 2个月前
轻描淡写 (作者) 2个月前
bidianqing 2个月前

这道题的前提条件是:runtime.GOMAXPROCS(1)
默认情况下会因为处于自旋状态的MP模型会进行偷取其他队列的G,进而导致你的打印结果是个乱序的

2个月前 评论

package main

import (
    "fmt"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(1)
    for i := 0; i < 1000; i++ {
        OrderPrint()
        fmt.Println("---")
    }
}

func OrderPrint() {
    ch := make(chan int, 10)
    for i := 1; i <= 3; i++ {
        go func(i int) {
            ch <- i
        }(i)
    }
    for i := 0; i < 3; i++ {
        fmt.Println(<-ch) // 3 1 2
    }
}
2个月前 评论

顺序是随机的,可以做一下基准测试看看是不是

2个月前 评论

非常奇怪, 我本地(go.1.22)一直是 3,1,2
换playground 第一次 3,2,1 后面重复run 一直是 3,1,2 重新进playground 第一次 3,2,1

1个月前 评论
pinylin (作者) 1个月前

又试了试,是3这个数字太小了, 没法实现面试官要的效果,我本地一直 3,1,2

如果是30 ,就跟一楼说的一致, maxprocs=1时, 30,1,…,29

maxprocs>1时, 1,2,…,30

1个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
1
粉丝
0
喜欢
0
收藏
0
排名:2298
访问:632
私信
所有博文
社区赞助商