这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
1. 语言进阶
1.1 并发VS并行
1.1.1 Goroutine协程
协程:用户态,轻量级线程,栈MB级别
线程:内核态,线程跑多个协程,栈KB级别
Go可以充分发挥多核优势
创建协程:在函数前加一个go
1.1.2 CSP(Communicating Sequential Processes)
提倡通过通信共享内存而不是通过共享内存实现通信(Go仍然保留,需要添加互斥量,影响性能)
1.1.3 Channel
make(chan 元素类型,[缓冲大小]) ·无缓冲通道(同步通道) make(chan int) ·有缓冲通道 make(chan int, 2)
1.1.4 并发安全 Lock
避免对共享内存进行非安全的并发操作
1.1.5 WaitGroup
Add(delta int) 计数器+delta
Done() 计数器减1
Wait() 阻塞知道计数器为0
2. 依赖管理
学会站在巨人的肩膀上。
2.1 Go依赖管理演进
GOPATH --> Go Vendor --> Go Module
· 不同环境依赖的版本不同
· 控制依赖哭的版本
2.1.1 GOPATH
-bin 项目编译的二进制文件
-pkg 项目编译的中间产物,加速编译
-src 项目源码
· 项目代码直接依赖src下的代码
· go get下载最新版本的包到src目录下
弊端: 无法实现package的多版本控制
2.1.2 Go Vendor
· 项目目录下增加vendor文件,所有依赖包副本形式放在$ProjectRoot/vendor
· 依赖殉职方式:vendor => GOPATH
通过每个项目引入一份依赖的副本,解决了多个项目需要同一个package依赖的冲突问题。
弊端:
· 无法控制依赖的版本。
· 更新项目又可能出现依赖冲突,导致编译出错。
2.1.3 Go Module
· 通过go.mod文件管理依赖包版本
· 通过go get/go mod指令工具管理依赖包
终极目标:定义版本规则和管理项目依赖关系
2.2 依赖管理三要素
- 配置文件,描述依赖 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod
2.3.1 依赖配置-go.mod
2.3.2 依赖配置-version
· 语义化版本
· 给予commit伪版本
2.3.3 依赖配置-indirect
2.3.4 依赖配置- incompatible
· 主版本2+模块会在模块路径增加/vN后缀
· 对于没有go.mod文件并且主版本2+的依赖,会+incompatible
选择最低的兼容版本
2.3.5 依赖分发-回源-Proxy
2.3.6 依赖分发-变量 GOPROXY
GOPROXY="proxy1.cn, proxy2.cn, direct"
服务站点URL列表,“direct”表示源站
2.3.7 工具-go get
2.3.8 工具-go mod
init 初始化,创建go.mod文件
download 下载模块到本地缓存
tidy 增加需要的依赖,删除不需要的依赖
3. 测试
· 回归测试
· 集成测试
· 单元测试
从上到下,覆盖率逐层变大,成本却逐层降低
3.1 单元测试
3.1.1 单元测试-规则
· 所有测试文件以_test.go结尾
· func TestXxx(*testing.T)
· 初始化逻辑放到TestMain中
3.1.5 覆盖率
· 一般覆盖率:50%~60%,较高覆盖率80%+
· 测试分支相互独立、全面覆盖
· 测试单元粒度足够小,函数单一职责
3.2 单元测试-依赖
外部依赖 => 幂等&稳定
3.4 单元测试- Mock
快速Mock函数
· 为函数打桩
· 为方法打桩
如果有外部依赖可以用Mock实现
3.5 基准测试
· 优化代码,需要对当前代码分析
· 内置的测试框架提供了基准测试的能力
4. 项目管理
4.1 需求描述
4.2 需求用例
4.3 ER图-Entity Relationship Diagram
4.4 分层结构
· 数据层:数据Model,外部数据的增删改查
· 逻辑层:业务Entity,处理核心业务逻辑输出
· 视图层:视图View,处理外部的交互逻辑(对上层负责)
组件工具
· Gin高性能go web框架 · Go Mod