还不知道面试结果
面试流程
- 自我介绍
- 语言层面的细节
- 项目经历
- 提问
倒是没让做算法题
语言层面
map是并发安全的吗
那肯定不是,map在写的过程中会检查标志位,如果有其他协程在写,会直接panic。日常开发过程中也经常看到这个panic。
map可以在遍历的时候删除吗
答:不可以,会遇到并发读写的panic
问:那如果是单协程呢?(问的有点东西,我楞了一下)
答:那应该可以(我不太确定,确实有点记不清了,实际上是可以的,但是从防御式编程的角度讲,不管语言支不支持这样做都不太好)
问: map删除key之后会理解清空,删除这块占用的内存吗?
答: 不会,会先写标志位,后续再进行删除。删除时会检查当前是否符合缩容的阈值,达到阈值进行缩容(可以,有点深度,问的我一愣一愣的,仔细回想了下相关知识点,但其实说的不完全对)
关于删除流程的官方答案:
- 检测是否存在并发写操作
- 计算key的hash值,找到落入的bucket
- 设置写标志位
- 检查次map是否在扩容的过程中,如果是则直接触发一次搬迁操作
- 两层循环,核心是找到key的具体位置,寻找过程都是类似的,在bucket中挨个cell寻找
- 找到对应位置后,对key或value进行“清零”操作
- count–,将对应位置的tophash值设置成emptyOne
- 检测此槽位是否都为空,若是将tophash改成emptyRest
- 若上一步成功,则进一步扩大战果,将此cell之前的tophash值为emptyOne的槽位都设置成emptyRest
channel的底层结构
我傻了,一点印象都没,所以换了一个问题
GMP调度模型了解吧,有缓冲的channel满了之后,GMP现在是一个什么样的状态
答:这要分两个场景来看,读和写,读没啥好说的,一直在消费。写的话因为缓冲区满了,会写不进去,这时候写协程g会堵塞,因为这类阻塞不是系统调用(我不太确定)。所以对应的m实际上不会阻塞,m可以去处理其他事情,例如帮忙消费队列信息,等队列有空位之后,再对这个g进行唤醒
答的时候我是有点懵的,gmp我还能掰扯两句,但是绑了一个实际案例,我心里就有点打鼓,我感觉我说的基本没错,就是阻塞时候是不是系统调用不太确定,后面查了一下,应该是这样的:满了之后会再次构建一个g,把g加到待发送队列,直接就挂起等待唤醒。感觉跟我说的差不多。
写在最后
后面就是项目经历了,就不说了。这么一复盘下来感觉还行?但是中间有一次换问题的操作,最终结果还是不太确定。
西巴