这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记
基础概念
-
并发与并行:并发指多线程运行, 而并行强调同时运行,也就是需要在多个CPU核心同时运行
-
线程与协程:线程切换属于内核态操作,相对更加耗费资源;协程切换属于用户态,轻量级;一个线程能跑多个协程。
协程是Go实现高并发特征的关键所在
- Go语言协程的通信、内存共享
协程通过通信共享内存,而不是通过共享内存实现通信
通过使用通道Channel通信实现共享内存
通过共享内存实现通信,需要通过信号量加互斥锁
Channel是一种饮用类型,通过make创建,make(chan TYPE, [SIZE])带SIZE大小的创建方式创建的为有缓冲通道,否则为无缓冲通道
使用无缓冲通道,会使两侧同步阻塞;使用有缓冲通道,可视为生产消费模型
-
使用
sync.WaitGroup完成并发任务的同步,可以将主协程阻塞至计数器为0;Add(delta int)计数器加deltaDone()计数器减1Wait()阻塞至计数器为0;需要注意:开启协程计数器加一,执行结束计数器减一
依赖管理
- 依赖管理演进 GOPATH -> Go Vendor -> Go Module
不同环境、项目依赖的版本不同
需要控制依赖库的版本
-
GOPATH 无法实现package的多版本控制管理
-
Go Vendor,通过每个项目引入一份依赖副本,不同项目可以引入不同版本的依赖副本,能够解决不同版本的依赖冲突。但是无法解决一个项目依赖两个package
A和B,但是A和B同时依赖于另一个包C的不同版本的问题 -
Go Module:通过
go.mod文件管理依赖包管理
go get
go mod
-
依赖管理三要素
- 配置文件,描述依赖
go.mod - 中心仓库管理依赖库
Proxy - 本地工具
go get/mod
- 配置文件,描述依赖
-
indirect间接依赖A->B->C
A->B 直接依赖 A->C 间接依赖 -
incompatible:对于没有go.mod文件并且主版本2+的依赖,需要+incompatible,标识可能存在不兼容 -
编译时,依赖包的选择为:最低的兼容版本,当Major版本号一致,那么认为是兼容的
-
依赖分发 Proxy
测试
回归测试 集成测试 单元测试
单元测试
-
测试单元:函数、接口、模块、聚合大的函数
-
基本编码规则
- 所有测试文件以
_test.go结尾 - 测试函数定义为
func TestXxxx(*testing T) - 测试的初始化逻辑放到
TestMain中
- 所有测试文件以
-
覆盖率
执行测试时,被测试代码中执行的部分占总量的比率
-
目标
一般覆盖率:
50%~60%, 较高覆盖率80%+测试分支相互独立,全面覆盖
测试单元粒度足够小, 函数单一职责
-
依赖
外部依赖 -> 幂等、稳定
Mock测试
为了避免外部依赖对测试幂等、稳定性的影响
基准测试
主要用于优化代码、性能分析
使用方法类似单元测试