这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记。
1.并发和并行
并发:多线程程序在一个核的cpu上通过时间片划分来实现同时运行。
并行:多线程程序直接利用多个核的cpu实现同时运行。
2.Goroutine
协程(Goroutine):用户态,轻量级线程,栈KB级别
线程:内核态,线程跑多个协程,栈MB级别
3.CSP(communicating Sequential Processes)
提倡通过通信共享内存而不是通过内存共享通信
4.Channel
make(chan type[bufferSize])//缓冲大小为可选项
make(chan int) //无缓冲通道
make(chan char, 2) //有缓冲通道
无缓冲通道会使发送同步,也被称为同步通道;
有缓冲通道中有bufferSize组数据时被阻塞,直至数据被取走,否则不能放入。
5.并发安全
通过sync.Mutex类型的锁来对临界区保护
lock.Lock()
x++
lock.Unlock()
6.WaitGroup
var wg sync.WaitGroup //声明
wg.add(n) //计数器增加n
wg.Done() //计数器减1
wg.Wait() //阻塞直至计数器为0
7.依赖
GOPATH:无法实现package的多版本控制,容易发生版本不兼容。
Go Vendor:项目目录下增加vendor文件存放依赖副本,解决了多个项目需要同一个package依赖的冲突。但无法控制依赖的版本,更新项目又可能出现依赖冲突。
Go Module:通过go.mod文件管理依赖包版本,通过go get/go mod指令管理依赖包。
//indirect表示非直接依赖。
主版本2+模块会在模块路径增加/vN后缀。
没有go.mod文件并且主版本2+的依赖,会+incompatible。
当依赖多个版本时选择最低的兼容版本
8.Proxy
实现对依赖版本的稳定可靠的依赖分发。
9.工具
go get example.org/pkg
后缀:
| 后缀: | 作用 |
|---|---|
| @update | 默认 |
| @none | 删除依赖 |
| @v1.2.3 | tag版本,语义版本 |
| @123abcd | commit版本 |
| @master | 分支的最新commit版本 |
go mod
| 后缀: | 作用 |
|---|---|
| init | 初始化go.mod文件 |
| download | 下载模块到本地缓存 |
| tidy | 增加需要的依赖,删除不需要的依赖 |
10.测试
-
回归测试
-
集成测试
-
单元测试
从上往下,覆盖率逐级变大,成本逐级降低
11.单元测试
单元测试用代码覆盖率来评估。
测试规则:
-
测试文件以_test.go结尾,与被测试文件相邻
-
测试函数
func TestXxx(t *testing.T){
}
- Go语言提供了一个TestMain函数,初始化逻辑放到TestMain中。
func TestMain(m *testing.M){
//测试前准备,初始化等
code := m.Run()
//测试后释放资源等收尾
os.Exit(code)
}
12.Mock测试
测试时调用的是打桩函数,不再依赖本地文件。
13.基准测试
对性能的测试和评估。
func XxxxSelect(b *testing.B){
}
14.项目分层
- 数据层:数据Model,外部数据的增删改查
- 逻辑层:业务Entity,处理核心业务逻辑输出
- 视图层:视图view,处理和外部的交互逻辑