这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
一、本堂课重点内容:
- 并发编程
- 依赖管理
- 单元测试
- 项目实战
二、详细知识点介绍:
并发编程
- 并发:多线程程序在一个核的cpu上运行
- 并行:多线程程序在多个核的cpu上运行
- 协程:用户态,轻量级线程,栈KB级别
- 线程:内核态,线程跑多个协程,栈MB级别
- 提倡通过通信实现共享内存而不是通过共享内存实现通信
- Channel(并发安全)
make(chan 元素类型, [缓冲大小])
无缓冲通道 make(chan int)
有缓冲通道 make(chan int, 2)
- WaitGroup
Add(delta int) 计数器+delta
Done() 计数器-1
Wait() 阻塞直到计数器为0
依赖管理
- GOPATH
场景:A和B依赖于某一package的不同版本
问题:无法实现package的多版本控制
- Go Vendor
通过每个项目引入一份依赖的副本,解决了多个项目需要同一个package依赖的冲突问题
无法控制依赖的版本。
更新项目有可能出现依赖冲突,导致编译错误
- Go Module
通过 go.mod 文件管理依赖包版本
通过 go get/go mod 指令工具管理依赖包
终极目标:定义版本规则和管理项目依赖关系
- 依赖管理三要素
配置文件,描述依赖 go.mod
中心仓库管理依赖库 Proxy
本地工具 go get/mod
单元测试
- 规则
所有测试文件以 _test.go 结尾
func TestXxx(*testing.T)
初始化逻辑放到 TestMain 中
- 代码覆盖率
衡量代码是否经过了足够的测试
评价项目的测试水准
评估项目是否达到了高水准测试等级
- Tips
一般覆盖率 50%-60% ,较高覆盖率 80%+
测试分支相互独立、全面覆盖
测试单元粒度足够小,函数单一职责
-
Mock测试
-
基准测试
项目实践
分层结构
数据层:数据 Model,外部数据的增删改查
逻辑层:业务 Entity,处理核心业务逻辑输出
视图层:视图 View,处理和外部的交互逻辑
三、实践练习例子:
- channel(并发安全)
func CalSquare() {
src := make(chan int)
dest := make(chan int, 3)
go func() {
defer close(src)
for i := 0; i < 10; i++ {
src <- i
}
}()
go func() {
defer close(dest)
for i := range src {
dest <- i * i
}
}()
for i := range dest {
println(i)
}
}
- sycn.WaitGroup
func ManyGo() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(j int) {
defer wg.Done()
hello(j)
}(i)
}
wg.Wait()
}
四、课后个人总结:
- 单元测试第一次接触,仍然一知半解