Go高并发、依赖管理和测试 | 青训营笔记

67 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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 指令工具管理依赖包

依赖管理三要素:

  1. 配置文件 go.mod
  2. 中心仓库管理依赖库 Proxy
  3. 本地工具 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%,一般覆盖主要流程即可;
  • 开发过程中要注意那些地方可以实现并发,并且要考虑并发的安全问题。

引用参考