go面试问题
记录并持续学习在面试中遇到的golang问题。
defer
defer将一个function或method的调用推迟到它所在的函数执行完之后,返回到函数的调用者之前。或者是所在goroutine panic并返回调用者之前。
// 调用者得到的result = 42 func deferTime(result int){ defer func(){ result *= 7 }() result = 6 }
函数执行到defer时会将它的参数进行赋值,但defer的执行是在上面所说的时间点。当有多个defer被调用时,执行顺序为调用的逆序。
// print result: 3 2 1 0 func printDefer() { for i := 0; i < 4; i++ { defer fmt.Printf("%d ", i) } }
Golang GC
golang的垃圾回收使用的是mark-and-sweep算法,类似BFS。
从root object出发,mark完所以可达的object,遍历堆上没有被mark的节点并进行sweep。
传统的mark-and-sweep需要停止程序的执行(stop-the-world)来进行垃圾回收,go使用了一种可以和程序并行执行的tricolor-mark-and-sweep算法。
当进行垃圾回收时,可能并行地将unmark变为mark的操作有两种:创建物体和改变引用(用C的思考方式可以理解为指针的变更)。go会在编译时对这两种操作加入write barrier使得marker获取reference更改的信息。
对这两种情况,go会把新的引用(指针指向的物体)加入BFS的队列中,继续进行BFS直到队列为空。我看的talk说这个算法是可以和程序并行执行的,但我感觉sw eep的时候进程必须停止才行?
已经被mark,但reference改变,在这一轮GC中实际上应该为unmark的物体会在下一轮GC中被回收,即object在成为垃圾的两轮GC内被回收。
浙公网安备 33010602011771号