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内被回收。

 

posted on 2020-04-26 22:00  重构ab  阅读(315)  评论(0)    收藏  举报