这是我参与「第五届青训营 」笔记创作活动的第1天
前言
本篇文章为Go语言进阶与依赖管理课程的学习笔记,按照课程设置分为4个Part,分别为:
- 语言进阶
- 依赖管理
- 测试
- 项目实战
并发编程
并发和并行区别
Go中实现高并发的的核心是“协程” 协程可以理解为轻量级的线程,由Go语言本身进行调用,一般栈KB级别,在用户态运行。 Go可以创建上万级别协程
调用方法:
go func(input){
statement;
}
CSP
Go提倡通过通信来共享内存而不是通过共享内存实现通信
Channel具体操作
创建:
make(chan elmentType, [buff_size])
对于buff_size == 0,则是无缓冲通道,对于buff_size != 0则是有缓冲通道。无缓冲通道又称为同步通道。具体操作系统基本都学过不过多赘述。
示例代码:
并发安全Lock
简单就是Go利用信号量机制实现临界区的互斥操作的具体代码
var(
x int64
lock sync.Mutex
)
func addWithLock(){
for i := 0; i < 2000; ++i {
lock.Lock()
x += 1
lock.Unlock()
}
WaitGroup
WaitGroup方法是内部维护了一个计数器,开启协程计数器+1,协程执行解除那么计数器-1,主协程阻塞直到计数器为0。
var wg sync.WaitGroup
wg.add(n int) //计数器+n
wg.Done() //计数器-1
wg.Wait() //阻塞直到0
依赖管理
GOPATH -> Go Vendor -> Go Module
GOPATH
- bin 存储项目编译的二进制文件
- pkg 项目编译的中间产物,加速编译
- src 项目源码
项目代码直接依赖src下的代码
问题:无法实现package的多版本控制
Go Vendor
- 项目目录下增加Vendor文件,所有依赖包副本形式放在$ProjectRoot/vendor内
- 寻址方式: Vendor => GOPATH
通过每个项目引入一份依赖的副本,解决了多个项目需要同一个Package依赖的冲突问题
问题
- 无法控制依赖的版本
- 更新项目又可能出现依赖冲突,导致编译出错
Go Module
- 通过go.mod文件管理依赖包版本
- 通过go get/go mod指令工具管理依赖包
依赖管理三要素
- 配置文件,描述依赖
- 中心仓库管理依赖库
- 本地工具
module hertz_demo //依赖管理基本单元
go 1.19 //原生库
require github.com/cloudwego/hertz v0.5.0
require ( //单元依赖
github.com/bytedance/go-tagexpr/v2 v2.9.2 // indirect
github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7 // indirect
github.com/bytedance/sonic v1.5.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06 // indirect
github.com/cloudwego/netpoll v0.3.1 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/golang/protobuf v1.5.0 // indirect
github.com/henrylee2cn/ameda v1.4.10 // indirect
github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/nyaruka/phonenumbers v1.0.55 // indirect
github.com/tidwall/gjson v1.13.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
google.golang.org/protobuf v1.27.1 // indirect
)
以本地的一个go.mod文件举例
v2.9.2 语义化版本
v0.0.0-20210923205945-b76863e36670 基于commit的伪版本
对于没有导入的模块,就使用//indirect 表示为间接依赖
Proxy
Go mod
Go mod
- init 初始化,创建go.mod文件
- download 下载模块到本地缓存
- tidy 增加需要的依赖,删除不需要的依赖
测试
回归测试 -> 集成测试 -> 单元测试 覆盖率逐层变大,但成本逐层降低