这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
go语言的进阶
1.并发和并行
go可以充分发挥多核优势,高效运行
1.1 Goroutine
协程:用户态,轻量级线程,栈MB级别
线程:内核态,线程跑多个协程,栈kb级别
在函数前加 go 关键字开启协程
1.2 CSP
提倡通过通信共享内存而不是通过共享内存而实现通信
1.3 Channel
使用:make(chan 元素类型,[缓冲大小])
通道分为有缓冲通道和无缓冲通道(不设置缓冲大小),后者也被称为共享通道
1.4 并发安全LOCK
并发执行不加锁时输出未知的结果(小于等于预期值),造成安全问题
1.5 WaitGroup
Add(delta int) 计数器+delta
Done() 计数器-1
Wait() 阻塞直到计数器为0
2.依赖管理
原因:项目不可能只基于标准库去搭建
2.1 依赖管理演进(GOPATH >> GO Vendor >> Go Module)
2.1.1 GOPATH
bin 项目编译的二进制文件
pkg 项目编译的中间产物,加速编译
src 项目源码
弊端:无法实现package的多版本控制
2.1.2 Go Vender
增加vender文件。建立依赖的副本,解决冲突问题
弊端:无法控制依赖的版本,项目更新可能导致编译出错
2.1.3 Go Module
通过 go.mod 文件管理依赖包版本, go get/go mod 指令工具管理依赖工具
2.2 依赖管理三要素
1.配置文件,描述依赖 go.mod
2.中心仓库管理依赖库 Proxy
3.本地工具 go get/mod
2.3 依赖配置
2.3.1 go.mod
module example/project/app 依赖基本单元
go 1.16 原生库
require(
example/lib1 v1.0.2 单元依赖
)
2.3.2 version
语义化版本(${MAJOR}.${MINOR}.${PATCH})
V1.3.0
V1.3.1
基于commit 伪版本(vX.0.0-yyyymmddhhmmss-abcdefgh1234(十二位哈希前缀))
v0.0.0-20220401081311-c38fb59326b7
v1.0.0-20200306012644-bacd9c7ef1dd
2.3.3 indirect
用于标识直接依赖
2.3.4 incompatible
对于没有go.mod文件且主版本2+的依赖,会+imcompatible
2.3.5 依赖分发
回源:
无法保证构建稳定性
无法保证依赖可用性
增加第三方压力
Proxy(稳定可靠)
建立之后相当于有了一个中转站
2.3.6 GOPROXY
goproxy = "https://proxy1.cn,https://proxy2.cn,direct";
2.3.7 工具
go get
@update 默认
@none 删除依赖
@v1.1.2 tag版本,语义版本
@23dfdd5 特定的commit
@master 分支的最新commit
go mod
init 初始化,创建go.mod
download 下载模块到本地缓存
tidy 增加需要的依赖,删除不需要的依赖
3.测试
3.1 单元测试(主要对函数和模块进行测试)
目的:保证质量,提升效率
规则:
所有测试文件以 _test.go结尾
fun TestXxx(*testing.T)
初始化逻辑放到 TestMain 中
覆盖率:测试语句的数量
3.2 单元测试-依赖
测试的目标:
稳定(测试相互隔离,任何时间任何函数独立运行)
幂等(重复运行一个测试用例结果一致)
3.3 单元测试-文件处理
3.4 单元测试-Mock
monkey:https:
3.5 基准测试(测试一段程序运行时的性能和cpu的损耗)