go 进阶与依赖管理 | 青训营笔记

89 阅读5分钟

01.并发编程

1.1.线程和协程

并发:多线程在一个核CPU上运行,通过时间点的切换来实现同时运行的状态

并行:多线程在多个核的CPU上运行,并行可以理解成实现并发的一个方式

go语言实现了并发性能提高的一个高效调度模型,通过高效的调度,可以最大限度的利用计算资源,充分发挥多核计算机的优势,可以说go语言就是为并发而生的.

线程:内核态,线程跑多个协程,栈为MB级别

协程:用户态,轻量级线程,栈为KB级别

go语言一次可以跑上万个协程,线程上可以运行多个协程

image-20230115110753334

1.2.CSP(Communicating Sequential Processes)

image-20230115105937622

提倡通过通信共享内存而不是通过共享内存而实现通信

1.3.channel

管道可以让协程间相互通信,管道分为有缓冲通道和无缓冲通道。无缓冲通道也叫做同步通道,有缓冲通道可以为其make容量,channel是典型的生产-消费模型。

1.4并发安全Lock

当多个goroutine同时使用共享内存时,需要对共享内存加锁,来避免并发安全问题,我们可以使用go标准库中的sync包下的Mutex,它的Lock()和Unlock()可以实现开关锁。

1.5WaitGroup

前面学习的例子中,为了阻塞主线程,使用的都是sleep来阻塞,这样并不优雅,我们也无法预测sleep的准确时间,我们可以使用sync包中的WaitGroup,其内部维护了一个计数器,开启一个协程就调用Add()方法,计数器加1,协程Done()了计数器就减一,当计数器为零时,阻塞Wait()就结束了。

02.依赖管理

2.1GO 依赖管理更迭

2.1.1 GOPATH

GOPATH的目录如下,项目的代码会直接依赖src下的代码,go get下载最新版本的包也会下到src目录下。

image-20230115160453118

GOPATH弊端:无法实现多版本控制的版本依赖

2.2.2 GO Vendor

在项目目录下增加了vendor文件夹,所有依赖包的副本存放在vendor目录下,依赖的寻址方式也发生了改变,优先从vendor中寻找依赖,没找到再从GOPATH寻找。

通过每个项目引入一份依赖的副本,解决了多项目需要同一个package依赖的冲突问题。

Go Vendor弊端:1.无法控制依赖的版本

2.更新项目又可能出现依赖冲突,导致编译出错。

image-20230115161222803

2.2.3 Go Module
  • 通过go.mod文件管理依赖包版本
  • 通过go get/go mod 指令工具管理依赖包

终极目标:定义版本规则和管理项目依赖关系。

2.2依赖管理三要素

  1. 配置文件,描述依赖 go.mod
  2. 中心仓库管理依赖库 Proxy
  3. 本地工具 go get/go mod
2.2.1依赖配置-go.mod

image-20230115161611499

依赖标识:[Module Path][Version/Pseudo-version]

2.2.2 依赖配置-Version

image-20230115162455677

MAJOR:是属于一个大版本,不同MAJOR之间不兼容。

MINOR:小版本更迭,在同一个MAJOR下是兼容的。

PATCH:一般做一些代码块修复。

而基于commit的伪版本,第一部分就是语义化版本,第二部分是时间戳,第三部分是每次提交的哈希值

2.2.3 依赖配置 - indirect

不包含indirect关键字的依赖就是直接依赖,包含indirect关键字的就是间接依赖

2.2.4 依赖配置 - incompatible

主版本为2或者以上的模块会在模块路径后面增加/vN后缀

对于没有go.mod文件并且主版本为2或以上的依赖,会在后面加上incompatible,表示存在不兼容

image-20230115164521150

2.2.5 依赖配置 - 依赖图

image-20230115164703171

2.2.6 依赖分发 - 回源

直接使用版本管理仓库下载依赖会存在一些问题:

  1. 无法保证构建稳定性:代码平台如果增加/修改/删除软件版本,我们可能会找不到之前所依赖的版本
  2. 无法保证依赖可用性:代码平台或者软件仓库可以对他的依赖进行删除,会导致我们想要的依赖不可用
  3. 增加第三方仓库的压力:代码托管平台会产生负载问题
2.2.7 依赖分发 - Proxy

go proxy 会缓存原站中的软件内容,就算原站对依赖进行了删除修改等操作,也不影响,实现了稳定和可靠的依赖分发,我们的依赖都是从Proxy来实现分发。

image-20230115165751094

2.2.8 依赖分发 - 变量 GRPROXY

下面是GOPROXY的配置,以及依赖寻找的顺序。

image-20230115165906256

2.2.9 工具 go get

image-20230115172959292

2.2.10 工具 - go mod

image-20230115173033789