Go语言进阶与依赖管理
一、 语言进阶
-
并发VS并行
- 并发:多线程程序在一个核的CPU运行
- 并行:多线程程序在多个核的CPU运行
-
协程 线程 Goroutine
- 协程
-
func hello (i int){ println("hello goroutine:"+fmt.Sprint(i)) } fun HelloGoRoutine(){ for i :=0;i<5;i++{ go func(j int){ hello(J) }(i) time.Sleep(time.Second) } } -
提倡通过通信共享内存,而不是通过共享内存而实现通信
-
Channel
- A子协程发送0~9数字 B子协程计算输入数字的平方主协程输出最后的平方数
-
func CalSquare(){ src:= make(chan int) dest := make(chan int,3) go func(){ defer close(src) for i:=0;i<10;i++{ src<-i } }() go func(){ defer close(dest) for i := range src { dest <- i*i } }() for i := range dest{ // 复杂操作 println(i) } }
-
并发安全Lock
-
var( x int64 lock sync.Mutex) func addWithLock() {//加锁--输出期望结果 for i := 0;i<2000;i++{ lock.Lock() x+=1 lock.Unlock() } } fun addWithoutLock(){//不加锁-输出随机数--undefine for i := 0;i<2000;i++{ x+=1 } }
-
1.5 WaitGroup
-
- Add(delta int)——计数器+delta
- Done()——计数器-1
- Wait()——阻塞直到计数器为0
小结
- Goroutine
- Channel
- Sync
二、 依赖管理
2.1 Go依赖管理演进
GOPATH——> Go Vendor——> Go Module
2.1.1 GOPATH-弊端
2.1.2 Go Vendor
2.1.3 Go Module
- 通过 go.mod 文件管理依赖包版本
- 通过 go get/go mod 指令工具管理依赖包
2.2 依赖管理三要素
- 配置文件,描述依赖 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/go mod
2.3
2.3.1 依赖配置- go.mod
-
模块路径
module example/project/app -
原生库
go 1.16 -
单元依赖
require ( 单元依赖 example/lib1 v1.0.2 example/lib2 v1.0.0 l/ indirect example/lib3 v0.1.0-20190725025543-5a5fe074e612 example/lib4 v.0.0-20180306012644-bacd9c7ef1dd // indirectexample/lib5/v3 v3.0.2 example/lib6 v3.2.0+incompatible ) //依赖标识:[Module Path][Version/Pseude version]
2.3.2 以来配置-version
-
语义化版本
- {MINOR}.${PATCH}
- V1.3.0 V2.3.0
-
基于commit伪版本
- 版本前缀-时间戳-12位哈希码前缀
- vX.0.0-yyyymmddhhmmss-abcdefgh1234
2.3.3 依赖配置 - indirct(关键字)
A—>B—>C
- A—>B直接依赖
- A—>C间接依赖
2.3.4 依赖配置 - incompatible
-
主版本2+模块会在模块路径增加/vN后缀
-
对于没有go.mod文件并且主版本2+的依赖·会+incompatibkes:
-
依赖图
2.3.5 依赖来分发-回源
-
无法保证构建稳定性——增加/修改/删除软件版本
-
无法保证依赖可用性——删除软件
-
增加第三方压力——代码托管平台负载问题
-
Proxy
2.3.6 依赖分发-变量 GOPROXY
GOPROXY="proxy1.cn, proxy2.cn ,direct”
服务站点URL列表,“direct”表示源站
2.3.7 工具 - go get
2.8 工具- go mod
init 初始化,创建go.mod文件 download下载模块到本地缓存 tidy 增加需要的依赖,删除不需要的依赖