学习笔记第一篇。总共第一篇。
一、本堂课重点内容:
「Go 语言工程实践」字节跳动青训营 - 后端专场
- 本堂课主要介绍了Go语言的进阶知识,Go依赖管理的演进、Go module管理依赖用法、测试、项目实战。
二、详细知识点介绍:
Golang依赖管理的演进
GO PATH -> GO VENDOR -> GO MODULE
GO PATH弊端:无法实现package的多版本控制。不同的项目A和B可能依赖某package的不同版本。
GO VENDOR:项目下增加vendor文件夹,先找vendor再找gopath。
GO VENDOR弊端:某个项目A可能依赖项目B和项目C,但项目B和C可能又依赖某一项目D的不同版本,项目A的控制住无法很好地控制项目B和项目C,当项目A去更新它的依赖B和C时,可能造成更底层的依赖D冲突。
Go MODULE:通过go.mod管理依赖。通过go get/go mod管理。Go1.16后默认开启。
依赖配置 - version
- 语义化版本
v${MARJOR}.$MINOR$.PATCH$$ - 伪版本
vx.0.0.yymmddhhmmss-commitid
go.mod中主版本2+需要加后缀/vN 对于没有go.mod并且主版本2+的依赖,要添加+incompatible
问题:如果X项目依赖了A、B两个项目,且A、B分别依赖了C项目的v1.3、v1.4两个版本,最终编译时所使用的C项目的版本为如下哪个选项?(单选)
A. v1.3
B. v1.4
C.A用到C时用v1.3编译,B用到C时用v1.4编译
答案:B。因为根据语义化版本,v1.3与v1.4同属于v1 major version,故v1.4应该兼容v1.3。
依赖分发 - GOPROXY
使用PROXY可以避免构建稳定性(防止源修改/删除版本)和依赖可用性(防止源删除软件)
GOPROXY="proxy1.cn,https://proxy2.cn,…" direct表示源站
go get(Module-Aware模式,不是GOPATH模式下的go get)
go get example.org/pkg
常用后缀:
@update 拉取最新版本(会更新之前已下载过的库到最新的Minor版本)
@none 删除依赖
@v1.1.2 拉取特定语义化版本
@23dfdd5 拉取特定commit版本
@master 拉取特定分支的最新版本
go mod
go mod init 初始化并创建go.mod go mod download 下载模块到本地缓存 go mod tidy 增加需要的依赖并删除不需要的依赖
回归测试、集成测试、单元测试
单元测试
- 测试文件以_test.go结尾
- 测试函数
func TestXXX(t *testing.T) - 测试初始化逻辑TestMain
func TestMain(m *testing.M) {
// init
m.Run()
// free
os.Exit(code)
}
一个assert包:github.com/stretchr/testify/assert stretchr/testify: A toolkit with common assertions and mocks that plays nicely with the standard library (github.com)
代码覆盖率:go test xxx.go --cover
一般覆盖率50~60%,较高覆盖率80%+
- 保证测试分支相互独立、全面覆盖
- 测试单元粒度足够小 ,单一职责。
mock
有时程序需要外部依赖DB、File、Cache,为了避免这些外部状态的变化对测试造成影响,需要mock来达成幂等 & 稳定
一个mock包: github.com/bouk/monkey
monkey.Patch(fff, func(){
/// ..
})
defer monkey.Unpatch(fff)
// our test code using function fff
基准测试
测试函数
func TestXXX(b *testing.B) {
init()
b.ResetTimer()
for i:=0; i<b.N; i++ {
CallToOurFunc()
}
}
如果有初始化逻辑不需要计入测试时间,可以在初始化后调用b.ResetTimer()
并行调用的压力测试
func TestXXX(b *testing.B) {
init()
b.ResetTimer()
b.RunParellel(func(pb *testing.PB){
for pb.Next(){ // pb.Next() 返回是否还需要更多调用
CallToOurFunc()
}
})
}
字节跳动的go工具库:bytedance/gopkg: Universal Utilities for Go (github.com)
bytedance/gopkg/lang/fastrand在并行中比rand表现更好,但不能设置seed。
三、实践练习例子:
- 数据层model
- 业务层entity
- 视图层view