这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
学习内容
语言进阶——高并发
Go 可以充分发挥多核优势,高效运行。
线程(MB级别)是内核态,协程(KB级别)是用户态,线程可以开多个协程,在程序中可以使用 go 关键字开协程。
Channel 通道,make(chan type[, size]),有size是有缓冲通道,无size是无缓冲通道。
defer close(src):Go语言的 defer 语句会将其后面跟随的语句进行延迟处理,在 defer 归属的函数即将返回时,将延迟处理的语句按 defer 的逆序进行执行,也就是说,先被 defer 的语句最后被执行,最后被 defer 的语句,最先被执行。
并发安全 Lock,可以通过加锁,lock.Lock(0) ... lock.Unlock()。
WaitGroup,用这个来完成阻塞。
var wg sync.WaitGroup
// 协程+n
wg.Add(n)
// 协程-1
defer wg.Done()
// 阻塞直到协程为0
wg.Wait()
依赖管理
依赖指的是各种开发包。
Go Module,
- 通过 go.mod 文件管理依赖包版本
- 通过 go get/m od 指令工具管理依赖包
依赖管理三要素:
- 配置文件 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod
version 版本:
语义化版本 ${MAJOR}.${MINOR}.${PATCH},major是指一个大版本,与之前的可以不兼容,minor是指新增一些方法之类,需要前后兼容,patch是指进行了一些修复之类。
基于 commit 伪版本,语义化+时间戳+hash码。
go get example.org/pkg [@update][@none][@version][@hashcode][@master]
update:默认
none:删除依赖
version:语义版本
hashcode:hash码,特定的commit
master:分支的最新commit
go mod [init][download][tidy]
init:初始化创建go.mod文件
download:下载模块到本地缓存
tidy:增加需要的依赖,删除不需要的依赖(提交代码之前可以使用这个命令整理一下依赖)
测试
单元测试
-
功能:对函数、模块等进行测试,覆盖面积最广。
-
单元测试规则:
-
所有测试文件以
_test.go结尾 -
方法名:
func TestXxx(name *testing.T) -
初始化逻辑放在
TestMain中
-
func TestMain(m *testing.M) {
// 测试前:初始化工作
code := m.Run()
// 测试后:释放资源等收尾工作
os.Exit(code)
}
-
单元测试 assert,用来取代验证过程中的判断。
-
单元测试 覆盖率,命令:
go test testfile file --cover,一般难以达到100%,一般覆盖率为50%~60%,较高覆盖率为80%。
基准测试:
- 功能:测试性能
func BenchmarkXxx(b *testing.B) {
...
b.ResetTimer()
...
}
项目实战
将大需求转化成小需求,如果两个功能没有依赖关系,就可以并发执行。
个人总结
- 关于并发那一部分,和操作系统的内容相似,理解生产者消费者问题,就可以很好的理解Go中的并发;
- 写完一个功能就可以测试一个功能,如果牵连到其他的模块,可以使用mock测试;
- 测试覆盖率不一定需要达到100%,一般覆盖主要流程即可;
- 开发过程中要注意那些地方可以实现并发,并且要考虑并发的安全问题。