今天有个面试官和我讲 go 的协程比系统的线程更慢,这个我不能理解

173 天前
 qxdo1234
我不知道他的回答和我的回答哪个是有依据的,麻烦有大佬知道的,指正我一下,仅是探讨技术对错问题,谢谢。

他一上来问我 go 的协程能否做到线程不能做到的事,而且至少重复问了我 3 次。我回:总的来说是可以加快程序的运行效率。他就讲出了他的理论和依据,既然 go 协程是要由线程去接管运行的,资源也是从线程分来的,那么何谈加快运行效率,你原本线程要做的事还是没变,而且还多了管理协程的开销。后来他又提了一些问题试图来让我相信他这个理论和依据,不知道其中某个问题的时候,我回的是:不耗费资源的操作时,协程要更快,在耗费资源较多时,还是线程更快。然后他还是在反复和我纠结这个问题。在我看来 go 的协程实现是分割原本线程的资源,做到更轻量化和更灵活的资源调度。调用完资源空闲了就可以及时 gc ,就可以用更少的资源去做更多的事。到最后,他才说,我的大前提是,要做的事是非常耗费资源的操作,就感觉很搞不懂。

虽然我面试问题回答的很差,但是我依旧想知道这个问题,不知道有没有大佬来和我指正一下,
另外他还有第二个问题,既然协程这套理论这么牛逼,那么 c++ 为什么没有呢?(在我印象里 c++只有线程)
9165 次点击
所在节点    Go 编程语言
76 条回复
fanxinxiaozhan
172 天前
cpu 密集型用线程,io 密集型用协程
fgwmlhdkkkw
172 天前
@MrKrabs 这种情况在 go 里面也是一样啊,全是计算的时候,go 也没办法打断吧。
hefish
172 天前
op 哥,你碰到了一个杠精面试。pass 吧。。。
000sitereg
172 天前
其实也没那么复杂。一般又通俗的理解就是计算机的东西越底层效率越高,协程基于线程就不可能比线程的效率高。
DIO
172 天前
我面试过一个号称某大厂主任级别的技术管理,结果我们聊关于国内外( b 站,油管等)视频下载技术问题。我不太懂但是市面上有这么多盗版视频,总不能都是内部泄漏的吧,就觉得肯定有办法。他让我回去好好看看,说现在大厂都有办法杜绝任何方式扒源。。。
testcgd
172 天前
你们不在一个频道上啊,你应该一顿 gmp 叭啦叭啦上去糊他一脸
没有啥是协程能做线程不能做的,用户态写个协程库就等态了
1 、协程是为了提高资源利用率和减少上下文切换的开销
2 、c++也有协程,只是不是语言层面上的
kingcanfish
172 天前
@qxdo1234 #3 https://github.com/Tencent/libco 微信的 cpp 协程库 还有 这面试官水平太臭
dV9zZM1wROuBT16X
172 天前
水货
1. goroutine 也是要线程来运行的啊,性能只会一样
2. linux 线程栈空间 8M ,相关上下文切换需要保存的寄存器等资源比 g 更多
3. 让他看新闻,c 跟 cpp 都有 coroutine
xjzshttps
172 天前
线程成本高:

* 线程堆栈占用内存大
* 线程切换成本高,是需要内核才能切换

协程成本低:

* go 的堆栈是动态的,最初只会使用很小的内存空间
* go 协程切换是用户态的,成本低



另外 go 适合 io 密集型的,原生线程适合计算密集型。
zhmouV2
172 天前
@DIO 这什么大厂主任😂确实挺次的吧
agagega
172 天前
我总觉得这个面试官是喜欢在网上刷语言不重要,重要的是思想的那类人🤣
fds
172 天前
其实前面不少回答已经很准确了,我就补充下面试官的想法。面试官无非是想看看你对程序运行时的理解是否足够深入。Go 算是 C 语言的加强版,像 GC 、map 、channel 这些,你用 C 写就得找库或者自己实现,但 Go 就给你包装好了。协程也是一样,你用着是协程,但底层还是在线程上跑的,只不过 Go 帮你把调度逻辑写了,一个线程上可以根据需要不断切换执行各个协程的逻辑。你自己也可以实现这个,但太麻烦,而且大多数人写不对。至于为什么必须有线程,那是因为操作系统就只支持到线程。所以面试官说的确实没问题,算是考察下操作系统吧。当然这个知识点我觉得也就是层窗户纸。
mayli
172 天前
> 不耗费资源的操作时,协程要更快,在耗费资源较多时,还是线程更快。

有点笼统,资源的定义是啥没说清楚,不过

> 总的来说是可以加快程序的运行效率

这一点肯定不对,协程仅仅是增加了程序的并发度,效率不一定高。一般来说,协程和线程都是解决 IO 阻塞时 cpu 空闲问题,协程可以实现更高阻塞并发,线程虽然并发程度没有协程高,但是总体上一般认为效率比协程还是高的。这里的效率指的是,协程还需要额外的开销进行 cooperative 部分,比如把异步、回调包成类似同步的操作。
换一个说法,就对于非阻塞 IO 密集型任务,比如 CPU 上纯纯的 for-loop ,协程就毫无用处。

你回答给人感觉认识不够清晰,估计就 pass 了。或者是你跟他不匹配,觉得沟通费劲,至少你自己也觉得跟他沟通费劲,以后做同事也没意思。不如友好 byebye
liangzaiyi
172 天前
搞好前提就方便回答了。如果是 CPU 密集型,直接线程数等于 CPU 核数行了;如果是 IO 密集型,就算是单线程跑协程也比多线程好,资源的分配都不是一个级别的,可以搞一百万个协程,你试下搞一百万个线程看炸不炸。
Cannly
172 天前
认同 15 楼说法。面试官的问题应该分场景的。
如果一个线程的任务就是能跑满一个时间片,而不会在自己的时间片中提前结束任务,那么协程完全不必要。但是如果一个线程所分配的任务,比如只需要 1/10 时间片,那么,引入协程改造,确实能把未引入协程时给其它 cpu 的任务,以协程调度方式继续在本线程运行。这就减少了线程切换,更大限度的利用了 cpu 。
但是别忘了,操作系统调度的是线程作业,程序尽早出让某个线程 CPU 也是一种协调。尽可能霸占未必主流大部分程序
qxmqh
172 天前
太纠结技术细节,从对话能看出来,即使进入岗位,以后你的日子也不好过。
cowcomic
172 天前
如果只讨论协程和线程自身内部运行时的性能,那一定是线程更好
但线程的代价更高,占用的系统资源更多,创建线程的时间更长,线程间的资源交互更慢
所以在使用层面是需要通过应用场景来确定具体用哪个
hwdq0012
172 天前
c++17 之前 Boost fiber(类似 go 的协程) , boost croutine(没有调度器的协程) 都是有栈协程, c++17 开始 msvc 先有无栈协程, cpp 20 开始 各编译器都陆续有无栈协程了
HaibaraDP
172 天前
计算π值,我认为线程还是比协程快的,毕竟协程在线程的基础上套了一层。对于面试问题,应该反复和面试官沟通,确认他的问题后给出答案
LotusChuan
172 天前
这不是技术问题,是面试套路问题。面试得看人下菜,这也是体现沟通能力的一环。

问题 1 他想听到的就是协程适合 IO 密集型的业务,线程适合 CPU 密集型/普通业务。因为搜索引擎去搜网上论坛都是这种回答,面试官看过所以拿来问了,你得和他看的八股保持一致。

问题 2 他想听到的是协程很复杂,相比于线程来说会增加代码复杂性。他这么问的原理同上,网上论坛都是这么说的。至于 C++到底有没有协程他无所谓。

如果你有信心和能力说服面试官,那么再去尝试说服,不然就借坡下驴背他想听的八股就行了。一般来说面试官是说服不了的,因为他控制你面试是否通过的权力,为什么要接受你那一套?毕竟他自己那套也不是全错。

搜索引擎搜 rust async vs thread 的结果,第一条是 Reddit ,第二条是 Stackoverflow ,完全匹配面试官思路。

https://www.reddit.com/r/rust/comments/jgpvi3/asyncawait_vs_threadsatomics_and_when_you_use_each/

https://stackoverflow.com/questions/78541829/async-thread-vs-std-thread

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1120244

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX