面试中有遇到几个golang的问题,记录一下
- recover能处理所有的异常吗
根据目前查到的资料和实践, recover能处理程序主动触发的panic和除0以及空指针访问、异常地址访问等错误,因此可以认为是能处理所有异常了。 - golang中常量是怎么实现的
这个问法还是很奇怪的, 从汇编中看是对字符串常量加了一个标号,同时设置为SRODATA,也就是只读,对数字常量直接在代码中作为立即数使用了 - golang的make和new的区别是什么
new有点像c++里面的new,用来初始化各种type,然后返回其指针。 只不过由于没有构造函数的存在,所以全部用零值来填充,比较特殊的是slice,map,channel, 它们的零值都是nil。另外由于golang直接可以用&struct{} 形式来初始化,所以平时用到new的机会也比较少。
make是用来初始化map,slice,以及channel的, 它返回的不是指针,而是对象本身。另外,make出来的map,slice,channel都是可以直接使用的。 - golang 的channel是怎么实现的
golang的channel是个结构体,里面大概包含了三大部分:
a. 指向内容的环形缓存区,及其相关游标
b. 读取和写入的排队goroutine链表
c. 锁
任何操作前都需要获得锁, 当写满或者读空的时候,就将当前goroutine加入到recvq或者sendq中, 并出让cpu(gopark)。 - 简单描述下golang的gc算法
golang现行的gc算法是三色标记法,三色指的是在gc过程中会把对象标记给黑,灰,白三色。
三色标记法是对标记-清除算法的优化,目的是减少stop the world的时间。
标记-清除算法:
对象只有黑白两色
- stop the world,即停止所有goroutine
- 从根对象(全局指针和栈上的对象)出发,把所有能直接或间接访问到的对象标记为黑色,其它所有对象标志为白色
- 清除所有白色对象
- start the world
三色标记法:
对象有黑白灰三色
- stop the world
- 将根对象全部标记为灰色
- start the world
- 在goroutine中进行对灰色对象进行遍历, 将灰色对象引用的每个对象标记为灰色,然后将该灰色对象标记为黑色。
- 重复执行4, 直接将所有灰色对象都变成黑色对象。
- stop the world,清除所有白色对象
这里4,5是与用户程序是并发执行的,所以stw的时间被大大缩短了。 不过这样做可能会导致新创建的对象被误清除,因此使用了写屏障技术来解决该问题,大体逻辑是当创建新对象时将新对象置为灰色。