返回信息流实习面试被问到:
1、go的协程和调度快在哪里(答的协程调度不需要内核参与,线程上下文切换要切换到内核态,并且协程栈只有2K,不知道答的对不对,感觉面试官不太满意)
2、他说换一种问法,用多线程的话,处理一个任务要开多少个线程(我答根据CPU瓶颈还是IO瓶颈不一样,如果CPU运算类型的任务,大概开和核数一样的线程,IO的话要更多,他说我这个思路对)
3、然后问我协程开多少个(我答可以开几万个)
4、他问我如果是i++操作,也能开一万个协程处理吗,那应该开多少个(我答不能,然后不会了)
5、他提示我比如HTTP请求,怎么开协程(我说一个请求开一个)
6、他又问请求太多了怎么办(我傻了,想了很久问他是不是想问我如何控制并发,协程池之类的。)
7、他就问我让我自己设计协程池需要怎么设计(我。。。。。不太会就随便说了说)
后面还问我学习了go的调度对平时编程有哪些帮助,我其实想说我就是背的八股,平时随便开的协程,没太体会出帮助来[ema1]
感觉一直没答出面试官想听的,确实是学艺不精,但还是想问问他想考察我什么,平时做的东西比较简单,求助下怎么回答这些问题,还有go真的需要协程池吗,不是已经很轻量级了嘛,而且go不是本身就不会立即释放掉运行完的goroutine结构体嘛,不太懂[ema23]
这是一条镜像帖。来源:北邮人论坛 / golang / #2357同步于 2022/3/25
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Golang机器人发帖
golang面试疑问求助
XinJiZheng
2022/3/25镜像同步9 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
runtime里可能有直接可以用的M,不用创建新的M。新建的G优先加入P的本地队列,不用加锁,除非加入全局G队列。P之间有work stealing,如果直接将task分配到指定线程,可能会出现某个线程很忙,其他线程闲着。
【 在 XinJiZheng 的大作中提到: 】
: 实习面试被问到:
: 1、go的协程和调度快在哪里(答的协程调度不需要内核参与,线程上下文切换要切换到内核态,并且协程栈只有2K,不知道答的对不对,感觉面试官不太满意)
: 2、他说换一种问法,用多线程的话,处理一个任务要开多少个线程(我答根据CPU瓶颈还是IO瓶颈不一样,如果CPU运算类型的任务,大概开和核数一样的线程,IO的话要更多,他说我这个思路对)
: ............
协程池还是需要的,可以参考网上的开源实现,并不复杂。请求太多可以用master worker架构,开100个worker,接受到请求后通过channel分发到worker
纯属没事硬卷八股文。你什么HTTP服务,需要开协程池。负责的说,你只要内存够用,几十万的协程数量都没问题,难道单机百万QPS吗,要协程池。你要真单机百万QPS,问题更大了,单机服务器异常了,你这百万QPS不就都报错了吗。
要回答清楚这个网络连接的问题,本质是epoll多路复用那套东西,和golang无关。
而且用了协程池,性能有变化?其实很多人还是在用线程池的逻辑想当然。GOLANG,绝大部分场景都不需要协程池。
以及绝大部分场景,golang的设计就是让你可以随便开协程,总有一些人,感觉这样太简单了,体现不出我的技术壁垒,非要找到不能随便开的原因。反而是随便开后,如何管控这些协程是比较关键的,但很多人都忽略这个
把调度模型看一下,应该可以满足大部分面试八股
协程池一般是不需要的,但是也可以封装,比如做一些recover panic的操作或者控制goroutine数量等
【 在 XinJiZheng 的大作中提到: 】
: 实习面试被问到:
: 1、go的协程和调度快在哪里(答的协程调度不需要内核参与,线程上下文切换要切换到内核态,并且协程栈只有2K,不知道答的对不对,感觉面试官不太满意)
: 2、他说换一种问法,用多线程的话,处理一个任务要开多少个线程(我答根据CPU瓶颈还是IO瓶颈不一样,如果CPU运算类型的任务,大概开和核数一样的线程,IO的话要更多,他说我这个思路对)
: ............
1、可以了解nginx是如何处理高并发(每核进程+epoll+结构体状态机)的;本质上nginx管理每个连接的结构体和go协程栈存的东西一样;
- 搞明白为什么有epoll, epoll的原理和使用场景,你的 1,2,4就能答上来了;
2.既然协程是结构体,那么内存够的话,理论上你想要多少就可以有多少;
- 就是你的问题3了;这个也可以结合nginx的单进程对比下;
- 协程可以起很多,但是其他开销就多起来了(可以查下有哪些开销和问题?),人生不能既要又要的;
3.怎么开协程?太多了怎么办?协程池怎么设计?
-上面提到了协程本质上是结构体,搞优化那就是复用了;运行时底层的有p结构的相关复用,往上一些就是goroutine的复用了;
-复用都是为了考虑创建的开销,如果创建的开销小,折腾池子也没啥用了;
-你把gouroutine理解成其他语言中的函数调用,协程池单纯的实现问题;
=====
最后,所谓的高并发,高性能我理解就是让cpu多干活,少切换;
把cpu理解成工人,那最好的方式就是工人坐在那里一直干,每个活源源不断的送到手上;
这个事情和工厂流水线是不是很相似了;