1.gc时扫描栈区是不是只有 检查有没有栈区的对象指向堆区对象 这一个作用?栈区在函数调用结束时会自动回收函数占用的空间,是否代表函数占据的空间理论上不需要gc这种算法去做垃圾回收?
- goroutine stack 本身占的内存 allocManual、freeManual
- goroutine stack 上面的变量要参与 GC,是因为栈上对象可能有指向堆上的对象的指针。
2.GMP有的人说1/61并不是每隔60次去全局队列中找,而是每次都1/61的概率去全局队列中找,哪个对呢?
3.Go1.8之后的混合写屏障,怎么具体防止了 黑色新指向白色且被灰色不可达 导致的数据丢失?混合写屏障只优化了重新扫描栈,但没有优化延迟清理?
- 动画看一下~
- 延迟清理没有解决,标记期间新生成的对象都是黑色的,还是要等下一个 GC 周期扫描和 sweep
4.如果说逃逸分析是编译时的,但是我在占上分配一个运行时才能确定长度的slice,那逃逸分析是会被无效么?
- make([]int, os.Args[1]) => escape
5.怎样理解 Happens Before?
- 并发,memory barrier,load acq, store rel 概念太底层,应用程序员不好理解,所以为让应用程序员更好理解,抽象了一层,memory model。synOnce,do 之后,happen before 的保证。
6.m0主要做了什么事情。m0和其他m区别么
- 主线程 => runtime.main,m0 只能执行主线程的代码,退出后整个进程退出
7.channel的实现原理,直接拷贝 发生在什么时候?
- chan.go 搜索 direct
8.defer的实现原理,以及开放编码是怎么回事?
- 老版本就是个简单的 defer 链表处理
- 1.13 有些 defer 结构在栈上分配
- 1.14 open coded defer,链表 -> 一个字节8位,依次检查+普通函数调用,https://github.com/cch123/golang-notes/blob/master/1.14/defer.md
9.链表对GC不友好,这句话对吗?
- 链表指针多,确实对 gc 不友好
10.进入gc.markDone()时是已经标记完成了吗,然后再进入gcMarkTermination进行sweep吗? 还有Yuasa感觉会产生浮动垃圾,g1收集器好像也是Yuasa,它好像快照完,所有快照的引用不管是不是垃圾都不回收,然后下次再回收,导致有浮动垃圾
- 是的,就差 wbBuf 里的一些剩余工作,清空后就可以进 termination 了
- gcSweep –wake–> (sweep.g –> sweep)
- 后半句稍微有点没看懂,skip,微信群或者问答区说
11.为什么栈上开写屏障开销高?
- 因为栈上的变量操作频率高,goroutine 数量大
12.go 的map什么时候等量扩容?PPt看了又不理解了。
13.error类型是小写,为啥可在其他包中引用?看到书里说是预定义标识符,是全局块的一部分
14.曹大,channel调试的流程能简单演示一下吗
- 看一下 1,2 课的答疑
15.fatal error 错误 写测试的 时候是不是没有办法抓到处理?
- os.Exit()
- 捕捉不了
16.gc的触发时机,runtime.mallocgc,不太理解
- mallocgc 分配内存触发
17.GMP, g和m分别有具体的结构体,那p具体在源码上是什么呢?
- type p struct
18.程序刚启动,main.main作为主goroutine怎么绑定P,g0怎么工作,以及在main函数里go func,怎么新启动M和偷窃、调度?
- procresize 绑定了 p
- newproc, mstart
19.os.Exit不会执行defer,是不会执行子goroutine的defer、只会调用main函数的的defer对吗?那子goroutine里面调用函数的defer怎么才能正常执行到呢?kill哪个命令对应的是os.Exit?
20.cgo 代码如何调试?怎么捕获内存分配信息
21.现在想准备跳槽,系统方面有什么书可以推荐,go的课程信心挺足,系统方面都没头绪,不知道怎么准备,目标公司B站
- system design primer, grokking system design
- kratos, overlord
- 八股文,redis,mysql,mq,面向对象设计 solid,clean architecture
23.蚂蚁线上一个服务是几个pod做负载均衡?
23.现在工作一两年的面试已经八股文全覆盖了,工作年限再高一些问啥?
24.面试有问为什么要内存对齐,和高速缓存有什么关系。
- CPU 从内存里读数据,按八字节对齐会快一些
- 内存填充 pad,avoid false sharing => cache bouncing
- unsafe.Alignof
- structlayout, linter
25.a:=make([]*Person,0,0) 和 a:=[]*Person{} 这两种分配有区别吗?我dlv 调试看到的调用流程都是一样的
- var a []*Person, 如果后续没用到 a,那就不需要分配内存。题目中的两种写法是一定会分配内存
- a:=make([]*Person,0,0) ===== a:=[]*Person{}
- a := []byte{} escape, cap changed
26. select的实现原理(channel的)
- skip
27.go语言为什么没有选择使用 分代回收 以及标记压缩来优化GC。
28.slot可以简单的理解为老指针对象吗?ptr就是新指向的对象。 slot字面上理解是内存上的槽。。举个例子:A=&B,曹大能说一下哪个是slot哪个是ptr吗。
- slot = 老指针,*slot = 指向的老对象,ptr 新的指针/对象
- A = slot,&B = ptr
29.能简单描述下多个gc线程跑的时候是怎么解决不同gc
30.线程冲突的问题吗?不会同时两个gc扫描同一个内存吗?
- 对象根遍历起始的时候用 atomic + 1 避免标到同一个根
- 理论上应该有可能,需要看一下代码,问答区见
31.混合屏障相对 Yuasa屏障的优势就是 不需要GC开始时的STW对吧?那为什么 Yuasa的删除写屏障则需要在GC开始时STW扫描堆栈来记录初始快照?
32.混合屏障相对于Dijsktra屏障的优势是不需要Rescan,而Rescan是因为在栈上创建的对象为白色造成的,所以混合屏障中创建的对象都为黑色。那么Dijsktra+栈上对象标黑就能完成,为什么还需要Yuasa屏障。
33.混合写屏障是所有栈、堆新创建的对象都会全部标黑吗?既然堆上的对象都是有写屏障,那创建时为什么还要标黑呢?
- GC 期间创建的对象如果是白色的,那 GC mark 完成后,还需要对这些新对象做扫描
- 标黑为了让这个对象,这个周期不要参与 GC,延迟到下一个 GC 周期扫描和回收
- 简化算法
34.全局变量是不是永远不会被gc回收?
- 是的
- 全局对象也是根对象的一种
35.之前面试被问 无锁队列和有锁数据结构的实现,面试官说 无锁队列 对 CPU 不友好,是真的嘛
36.是的,大部分要自旋
- for {} runqput,runqget
37.以下这个问题这样回答可以吗?有没有错误或修正的地方?
怎样保证Cache和DB的数据的一致性?
- 数据不一致的情况举例:先读Cache, CacheMiss, 再读DB,准备要构建Cache时,DB被更新,并更新Cache,然后才执行前面的构建Cache,导致Cache中数据为旧数据
如果是普通缓存(如in-process localcache):延迟双删 + 消息队列
- DB被更新时,先删除Cache,再更新DB
- DB(MySQL)使用canal订阅binlog并推送到消息队列
- 再删除Cache
- 等待超过 读业务读Cache的处理时间 后,消费消息队列数据并重新更新Cache
如果是Redis作为缓存:SetEX/NX + 消息队列
- 也可以使用延迟双删,但Redis提供了锁的命令可用,即:DB主动更新时,更新缓存用SETEX命令,即使存在也刷新;CacheMiss构建缓存时,使用SETNX命令,不存在才更新
- 上述不一致场景中,先读Cache, CacheMiss, 再读DB,准备要构建Cache时,DB被更新,并使用SETEX更新Cache,然后才执行使用SETNX构建Cache,因为已经存在不执行,Cache中即为新数据
- DB被更新还是要使用消息队列做兜底,因为更新Cache的命令也可能执行不成功
38.有人说stw可以完全去除可信吗?
- 不太确定。。。。
39.gc线程和用户线程是并发的话,那么gc对用户线程的影响只是在stw时才能让用户感知到吗?
- 用户 goroutine 分配内存会做协助标记assist,这部分会对你的延迟产生影响
40.我用dlv调试的时候 发现runtime.g0和runtime.m在一开始就有值了 那这个是什么时候复值的?刚开始的g0主要负责什么呀?
- m0.g0 -> runtime 里的代码
- m0 赋值去问答区吧
41. m0上只跑g0,那g0上运行的main.main里面如果执行了 time. sleep 那这个m0也只会阻塞在这么 而不是运行其他的g么
- m0 上不是只跑 g0,main.main 有单独的 goroutine
- m0 不会执行其它的 goroutine,有一个 LockOsThread 的过程,详情问答区
42.gc在什么时候讲标记的对象复原。是不是每次gc周期结束就会讲标记的颜色清空。
- 找一下 gcmarkbits 修改位置,代码位置去问答区问
- 下一轮 gc 标记开始前,要保证 gcmarkbits 都是空的
43.曹大线上调试工具分享下呀
- pprof,+ 日志,ebpf(坑)
58.线上可以开 pprof 嘛
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 lihuanjie113@gmail.com