一、语言进阶
并发与并行
并发:多线程在单核CPU上运行
并行:多线程程序在多核程序上运行
1、Goroutine
协程:用户态,轻量级线程,栈MB级别
线程:内核态,线程跑多个协程,栈KB级别
创建协程代码:
1 | func hello(i int) { |
2、CSP(Communicating Sequential Processes)
提倡通过通信共享内存而不是通过共享内存实现通信
3、Channel
通过make(chan 元素类型,, [缓冲大小])
- 有缓冲通道
- 无缓冲通道
代码示例:
A协程发送0~9数字;B协程计算输入数字的平方;主协程输出最后的平方数
1 | func CalSquare() { |
4、并发安全Lock
5、WaitGroup
计数器,开启协程+1;执行结束-1;主协程阻塞直到计数器为0
6、小结
- Goroutine
- Channel
- Sync
二、依赖管理
1、Go依赖管理演进
GOPATH -> Go Vender -> Go Module
(1)GOPATH
- 项目代码直接依赖src下的代码
- go get下载最新的代码到src目录下
无法实现package的多版本控制
(2)Go Vender
- 增加vender文件,存放所有的依赖包副本
- 为每一个项目引入一份依赖副本
无法控制依赖版本
(3)Go Module
- 通过
go.mod
文件管理依赖包版本 - 通过
go get/go mod
指令工具管理依赖包
定义版本规则和管理项目依赖关系
2、依赖管理
- 配置文件:go.mod
- 中心仓库管理依赖库:Proxy
- 本地工具:go get/mod
(1)依赖配置-go.mod
也就是编写go.mod
1 | // 依赖管理基本单元 |
(2)依赖配置-version
- 语义化版本
- 基于commit伪版本
(3)依赖配置-indirect
直接依赖和间接依赖
(4)依赖配置-incompatible
主版本2+模块会在模块路径增加/vN后缀
对于没有go.mod文件并且主版本2+的依赖,会加上该关键字
(5)工具
go get
go mod (init / download / tidy)
3、小结
- Go依赖管理演进
- Go Module依赖管理方案
三、测试
回归测试 -> 集成测试 -> 单元测试(测试成本逐渐降低)
1、单元测试
(1)规则
- 所有测试文件以
_test.go
结尾 - func TestXxx(*testing.T)
- 初始化逻辑放到TestMain中
(2)单元测试-assert
待测试函数:
1 | func HelloTom() string { |
测试代码:
1 | func TestHelloTom(t *testing.T) { |
2、单元测试-依赖
外部依赖 => 稳定&幂等
3、单元测试-Mock
monkey:https://github.com/bouk/monkey
- 为一个函数打桩
- 为一个方法打桩
不依赖于本地文件
4、基准测试
- 优化代码
- 内置的测试框架提供了基准测试能力
5、小结
- 单元测试
- Mock测试
- 基准测试
四、项目实战
1、分层结构
数据层
数据Model,外部数据的增删改查
逻辑层
业务Entity,处理核心业务逻辑的输出
视图层
视图View,处理和外部交互逻辑
2、组件工具
Gin高性能go web框架
Go mod
go mod init