这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
今天学习的内容包括Go并发编程,依赖管理,与单元测试
语言进阶
并发编程与并行编程
并发编程只多线程程序在单核上交替运行,并行编程多线程程序在多核上同时运行,goroutine为并发编程
线程
内核态,线程内有多个协程,栈内占用MB级别
协程
用户态,轻量级线程,栈空间KB级
gotoutine协程写法
func main() {
for i := 0; i < 5; i++ {
go func(j int) { // 括号部分为形参
fmt.Println(j)
}(i) // 括号部分为实参
}
time.Sleep(time.Second) // 由于Go协程异步执行,不sleep则程序会在协程输出结果前结束
}
/* 协程的执行结果为乱序输出
1
2
4
3
0
*/
协程间通信
go更倾向于使用通过通道实现协程间通信而不是使用临界区共享内存。
由于临界区访问存在竞争,一定程度上会影响程序性能
Channel
使用make(chan 元素类型,[缓冲大小])创建通道
- 无缓冲通道 make(chan int)
- 有缓冲通道 make(chan int, n)
有关Channel学习可以参考这篇博客
Go中的channel_go的channel_始梦的少年的博客-CSDN博客
依赖管理
演进历史
GOPATH -> Go Vendor -> Go Module
GOPATH
$GOPATH下默认包含bin,pgk,src三个路径
- bin 项目编译产生二进制文件
- pkg 存放编译中间产物,加速编译
- src 项目源码
缺点
无法实现package多版本控制
Go Vendor
项目下增加vendor目录,存放依赖副本,解决package冲突问题。
解决了多项目需要同一个package的依赖冲突问题
缺点
- 存放多个版本,占用存储空间
- 对依赖的版本管理能力不足
Go Module
三要素
- 配置文件,描述依赖 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod
Go Proxy
设置了多级依赖包缓存地址,加快依赖包访问速度
go get
- @update 默认
- @none 删除依赖
- @v1.1.2 指定版本
- @commit版本号 指定特定版本commit
- @master 指定分支最新commmit
go mod
- init 初始化,创建go.mod文件
- download 下载模块到本地缓存
- tidy 增删需要与不需要的依赖
单元测试
测试层级
回归测试->集成测试->单元测试
覆盖面从小到大,成本逐渐降低
- 回归测试:手动用实际体验去测试
- 集成测试:自动化对接口等功能进行测试
- 单元测试:开发者对功能模块进行测试
单元测试概念
对函数,模块等编写测试单元,查看指定输入是否能产生预期输出
单元测试规则
- 测试文件以_test.go结尾
- 测试函数写作 func TestXxx(*testing.T)
- 初始化逻辑放在TestMain中
单元测试-运行
使用test命令运行测试 go test [flags] [packages]
单元测试覆盖率
- 一般覆盖率50%-60%,较高覆盖80%
- 测试分支需要相互独立、全面覆盖
Mock
插桩替换原函数,便于测试
基准测试
根据运行时CPU耗时判断性能