Go Note¶
1. Go 语言进阶¶
1.1 并发 & 并行¶
- 协程:用户态,轻量级线程,栈 KB 级别
- 线程:内核态,线程跑多个协程,栈 MB 级别
1.2 协程间通信 CSP(Communicating Sequential Processes)¶
提倡通过通信共享内存而不是通过共享内存而实现通信。
1.3 Channel¶
make(chan 元素类型, [缓冲大小])
- 无缓冲通道:
make(chan int),同步通道 - 有缓冲通道:
make(chan int, 2),生产消费模型
1.4 并发安全 Lock¶
通过共享内存实现通信时,需要加锁以保证并发安全。
1.5 WaitGroup¶
计数器,开启协程 +1,执行结束 -1,主协程阻塞直到计数器为0。
2. 依赖管理¶
2.1 依赖管理演进¶
GOPATH -> Go Vendor -> Go Module
- GOPATH:无法实现 package 的多版本控制
- Go Vendor:
- 通过每个项目引入一份依赖的副本,解决了多个项目需要同一个 package 依赖的冲突问题
- 无法控制依赖的版本
- Go Module:
- 通过
go.mod文件管理依赖包版本 - 通过
go get/go mod指令工具管理依赖包
- 通过
2.2 依赖管理三要素¶
- 配置文件,描述依赖:
go.mod - 中心仓库管理依赖:
proxy - 本地工具:
go get / go mod
2.3 依赖配置 - Version¶
- 语义化版本
${MAJOR}.${MINOR}.${PATCH}
- 基于 commit 伪版本
- 版本选择:选择最低的兼容版本
2.4 依赖分发 - 回源¶
- 无法保证构建稳定性
- 无法保证依赖可用性
- 增加第三方压力
2.5 依赖分发 - Proxy¶
Go Mod 通过 GOPROXY 环境变量控制 Proxy,最后会 fallback 到源站中。
2.6 工具¶
- go get
- go mod
- init
- download
- tidy
3. 测试¶
3.1 单元测试¶
规则¶
- 所有测试文件以
_test.go结尾 func TestXxx(t *testing.T)- 初始化逻辑放到
TestMain中
覆盖率¶
go test judgment_test.go --cover
外部依赖¶
外部依赖需要稳定 & 幂等,因此需要 Mock 外部依赖。
3.2 Mock 测试¶
Mock 工具:Monkey
3.3 基准测试¶
func BenchmarkXxx(b *testing.B)go tes -bench=.
4. 性能优化建议¶
- 使用 Benchmark 衡量性能表现;
- Slice:
- 预分配内存;
- 陷阱:大内存未释放
- 场景:原 Slice 较大,代码在原 Slice 基础上新建小切片,导致原 Slice 在内存中有引用,得不到释放
- 解决方案:使用
copy代替re-slice
- Map 预分配内存;
- 使用
string.Builder处理字符串,而不是+拼接; - 使用空结构体节省内存:空结构体实例不占据任何内存空间,可作为占位符使用
- 场景:实现
set时可以用map代替,此时只需要用到key,可以把value设置为空结构体
- 场景:实现
- 使用
atomic包;







