Go进阶 | 青训营笔记
这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
文章简介
- 语言进阶
- 依赖管理
- 测试
语言进阶
并发和并行
- 两个及以上的线程在同一个时间段内运行
- 两个及以上的线程在同一时刻运行
协程
协程,英文名Coroutine。但在 Go 语言中,协程的英文名是:gorutine。它常常被用于进行多任务,即并发作业。没错,就是多线程作业的那个作业。
协程的特点:
- 多个协程可由一个或多个线程管理,协程的调度发生在其所在的线程中。
- 可以被调度,调度策略由应用层代码定义,即可被高度自定义实现。
- 执行效率高。
- 占用内存少。
线程和协程的对比:
| 比较的点 | 线程 | 协程 |
|---|---|---|
| 数据存储 | 内核态的内存空间 | 一般是线程提供的用户态内存空间 |
| 切换操作 | 操作最终在内核层完成,应用层需要调用内核层提供的 syscall 底层函数 | 应用层使用代码进行简单的现场保存和恢复即可 |
| 任务调度 | 由内核实现,抢占方式,依赖各种锁 | 由用户态的实现的具体调度器进行。例如 go 协程的调度器 |
| 语音支持程度 | 绝大部分编程语言 | 部分语言:Lua,Go,Python … |
| 实现规范 | 按照现代操作系统规范实现 | 无统一规范。在应用层由开发者实现,高度自定义,比如只支持单线程的线程。不同的调度策略,等等 |
协程的使用:
func TestGorutine(t *testing.T) {
// 控制等待所有协程都执行完再退出程序
wg := sync.WaitGroup{}
wg.Add(2)
// 运行一个协程
go func() {
fmt.Println(1)
wg.Done()
}()
// 运行第二个协程
go func() {
fmt.Println(65)
wg.Done()
}()
// 协程没有运行结束则不会停止
wg.Wait()}
协程之间的通信:
协程之间是通过通信而不是共享内存来实现通信的。
通道:
// 无缓冲通道
make (chan 数据类型)
// 有缓冲通道
make (chan 数据类型, 2)
并发安全lock(相当于Java里面的Lock,需要自己手动释放)
var (
lock sync.Mutex
)
func test() {
for i:= 0; i < 200; i++ {
lock.Lock()
i += 1
lock.UnLock()
}
依赖管理
依赖管理的演变路线
GOPATH→Go Vender→Go Module
GOPATH
- 项目代码直接依赖src下的代码
- go get下载最新版本的依赖包到src下面
缺点:
- 无法实现包的多版本控制
Go Vender
- 项目目录下增加vender文件,所有依赖包副本形式放在vender目录下
- 依赖寻址的方式:vender→GOPATH
缺点:
- 无法控制依赖的版本
- 更新项目又可能出现依赖冲突,导致编译出错
Go Module
- 通过go.mod文件管理依赖包版本
- 通过go get/go mod指令管理依赖包
测试
单元测试
测试最细小的部分,可用于测试某个功能函数是否会出问题。同时成本最高。
- 测试规则
- 所有的测试文件以
_test.go结尾 - 测试函数的命名方式:func TestXxxxx(t * testing.T)
- 初始化逻辑放到TestMain中
func TestMain(m *testing.M) {
// 测试前需要初始化的工作
code := m.Run()
// 测试后所需要做的工作
}
- assert
用于判断测试结果是否与预期值一样
assert.Equal(t, exceptOutput, outPut)
- 覆盖率
查看本次测试代码运行整段代码的多少行.
在运行代码的后面加上—cover参数就会显示代码覆盖率
一般覆盖率:50%~60%,较高覆盖率80%
- 单元测试-Mock
Mock测试使得测试程序不在依赖本地文件或者数据库数据
快读Mock函数
// 为一个函数打桩
func Patch(target, replacement interface {}) *PatchGuard {
t := reflect.ValueOf(target)
r := reflect.ValueOf(replacement)
patchValue(t, r)
return &PatchGuard(t, r)
}
// func Unpatch(target interface{}) bool {
return unpatchValue(reflect.VAlueOf(target)
}
基准测试
- 优化代码,需要对当前代码分析
- 内置的测试框架提供了基准测试能力