Go 语言学习(四) 工程实践_青训营笔记
这是我参与「第三届青训营 -后端场」笔记创作活动的的第 4 篇笔记。
一、语言进阶
1. 并发 VS 并行
Go 可以充分发挥多核优势,高效运行。我们从并发角度理解 Go 高性能本质。
- 并发
多线程程序在一个核的 cpu 上运行。
- 并行
多线程程序在多个核的 cpu 上运行。
2. Goroutine 协程
Golang 推荐协程而不是线程,两者的区别如下:
- 协程:用户态,轻量级线程、栈 KB 级别
- 线程:内核态、线程跑多个协程,栈 MB 级别
3. CSP (Communicating Sequential Processes) 通信顺序进程
Golang 提倡通信共享内存而不是通过共享内存实现通信。
4. Channel 通道
make(chan 元素类型,[缓冲大小])
- 无缓冲通道 make(chan int)
- 有缓冲通道 make(chan int,2)
5. WaitGroup 任务队列
当一个协程需要等待多个协程运行结束后才能进行下一步操作的时候,Golang 标准库 sync 包中提供了任务队列 WaitGroup,用于阻塞当前协程,直到等待任务数清零。
主要函数:
- WaitGroup.Add(n int):添加数字,标识需要等待的任务数。
- WaitGroup.Done():调用表示一个被等待的任务已经执行完毕。
- WaitGroup.Wait():调用者会阻塞等待当前 WaitGroup 中任务数清零再开始下一步操作。
二、依赖管理
Go 的依赖管理,到 1.18 版本,已经经历了三次变更分别是 Go Path、Go Vendor、Go Module。
1. GOPATH
Golang 提供了配置在环境变量中的属性,项目中的依赖直接下载到该 path 下中的 src 文件夹中,弊端是没有版本的管理概念,如果引用了不同的依赖版本没有办法管理,无法实现 package 的多版本控制。
2. Go Vender
Golang 提供了在项目目录下增加 vendor 文件夹,可以把所有的依赖包以副本的形式放进该文件解决了多个项目引用同一个包出现的各种冲突问题,但是仍然没有解决同一个项目依赖不同版本的问题,导致无去空制依赖的版本,更新项目又可能出现依赖中突,导致编译出错。
3. Go Module
Golang 推出了的最新的依赖管理方案,解决了同一个项目引用不同依赖同一个包不同版本的问题,
也满足了市面上主流依赖管理工具的绝大多数功能,以后学习管理依赖的工具直接使用 Go Module 即可。
- 通过 go.mod 文件管理依赖包版本。
- 通过 go get/go mod 指令工具管理依赖包。
4. 依赖管理三要素
- go.mod:配置文件,描述依赖。
- Proxy:代理镜像地址,存储着中心仓库的副本,如果没有会从中心仓库下载。
- go get/mod:本地工具,用于获取需要的依赖。
5. 常用配置项
-
version:支持语义化版本(如 v1.3.0),支持 commit 伪版本(如 v0.0.0-20220401081311-c38fb59326b7)。
-
indirect:表示该依赖没有被直接依赖,而是间接依赖。
三、测试
Golang 标准库提供了 testing 包,可以支持单元测试,基准测试同时为了减少测试对实际资源的影响,我们还可以使用第三方库对调用资源进行 mock(比如开源的 monkey 包)。