持续更新中... 其中底层细节自行查阅,或联系作者免费解答哦,文末有作者微信
1. go如何排查数据竞争问题?
go run -race
2. go有哪些方式安全读写共享变量
channel sync.map sync.rwlock sync.lock 原子操作atomic.*
3. go cond 的实现原理
cond包含sync.newCond wait L锁 wait之前需要先加锁
4. go waitGroup实现原理
5. go有哪些并发同步原语
channel atomic.* sync.waitGroup sync.RWLock sync.lock sync.map select sync.cond context
6. go常用的并发模型
csp模型,GMP(goroutine,Mechine,processer)调度,main携程开启后启动G0 M0 P0,内核线程M关联调度器上下文P, 调度器P关联本地队列G。其中有两个策略hand off(当goroutine阻塞后M也会阻塞,会从M队列取出新M或新开启一个M处理其他G) 和worker stealing(本地队列没有G时从全局G队列或从其他P的本地G队列窃取)。
调度过程如图:
7. go如何查看GC信息
- GODEBUG=‘gotrace=1’
- go tool trace 需要再代码中写trace
8. go内存对齐机制
基本语言都一样,每次按照页申请内存
9. go内存逃逸
内存从stack栈上逃逸到堆上
10. go如何查看运行时调度信息
- GODEBUG=schedtrace=1000 ./main.go (每1000毫秒处理跟踪调用)
- go tool trace
11. go线程实现模型
12. go如何控制并发goroutine数量
- 无缓冲channel,通过for写死个数
- 有缓冲channel,容量数量控制make(chan int, 10)
13. go如何查看正在执行的goroutine数量
- go tool pprof -http:=8000
- go tool pprof
14. goroutine底层实现原理
15. go原子操作和锁的区别
16. go 数据和slice切片的区别
主要是长度和底层实现,数组长度固定申明时指定,分配在堆上。slice变长,有指向底层数组的ptr指针,length长度和cap容量,通过append加值。ptr分配栈上,底层数组分配堆上。小于1023成倍扩容,否则1.25倍。
17. go channel什么情况下会发生死锁
- 无缓冲channel只读不写,只写不读,读在写前
- 多个channel循环等待
- 有缓冲channel写数量超过容量,只读
18. goc 有无缓存channel区别
无缓冲channle同步,收发必须同时进行make(chan type)
有缓冲channel异步,缓冲满时阻塞make(chan type, capacity)
19. go map和sync.map谁的性能好
- 读多写少适合用sync.map 原因:read map 用空间换时间
- 写多读少适合用map, 原因:sync.map需要加锁,冲突变高
20. go map和slice是并发安全的吗?
不是 设计者考虑场景如此设计
21. go map遍历为啥是无序的?
22. go map如何扩容
23. go 抢占式调度
go 1.2版本中实现了基于协作的‘抢占式’调度,在函数调用时编译器插入rumtime.morestack抢占标记,超过10ms会抢占调度
go 1.4版本中实现了基于信号的‘抢占式’调度,操作系统M检测goroutine运行是否超过10ms通过线程发送信号异步抢占调度