这是我参与「第五届青训营」伴学笔记创作活动的第 2 天
今日内容
学习完了青训营课程 后端入门 - Go 语言原理与实践 中的 Go 语言进阶与依赖管理 和 Go 语言工程实践之测试 之后的一些总结。
课程内容
- 语言进阶
- 依赖管理
- 测试
1. 语言进阶
1.1 Goroutine
-
并发和并行:
并发:早期计算机的 CPU 基本为单核,一个 CPU 在同一时刻只能执行一个线程/进程,当系统中有多个线程/进程在执行时,其实就是时间片轮转表现出这些线程/进程在同时运行。并发也就是使用算法将 CPU 的资源合理分配给多个任务,当其中一个任务阻塞时,CPU 可以执行其他的任务。这样会造成的问题就是线程/进程上下文切换的开销比较大。
并行:并发是针对单核 CPU 提出的,并行针对的是多核 CPU。多核 CPU 每个核心都可以独立运行一个任务,且不同核心之间不会互相干扰。
-
线程和协程:
线程:线程是存在于内核态的概念,创建销毁和切换都由操作系统控制,会一定程度上占用系统资源。
协程:协程运行在线程之上,通过分时复用的方式在线程上运行多个协程,减少操作系统的部分开销
1.2 CSP(Communicating Sequential Processes)
-
不同线程/进程之间的通信在其他语言中通常以全局变量(共享内存)实现,少有管道的便捷操作
-
而 go 提倡通过通信共享内存而不是通过共享内存实现通信
1.3 Channel
go 创建 Channel 的方式
var channelName chan channelType无缓冲管道- 使用
func make(t Type, size ...IntegerType) Type函数channelName := make(chan channelType, channelSize)创建指定缓冲区大小的 Channel
1.4 并发安全 Lock
go 支持互斥量(sync.Mutex)和读写锁(sync.RWMutex),读写锁额外支持 RLock() 和 RUnlock()
1.5 WaitGroup
上一篇文章中讲到过,可能会出现主线程结束了但是协程还没有结束的情况,sync.WaitGroup 相当于是一个计数器,每创建一个协程计数器 +1(Add(delta int)),每一个协程结束计数器 -1(Done()),主线阻塞(Wait())直到计数器为 0
2. 依赖管理
2.1 Go 依赖管理演进
2.1.1 GOPATH
2.1.2 Go Vender
2.1.3 Go Module
- 通过
go.mod文件管理依赖包版本 - 通过
go get/go mod指令工具管理依赖包
2.2 依赖管理三要素
- 配置文件,描述依赖
go.mod - 中心仓库管理依赖库
proxy - 本地工具
go get/mod
go get example.org/pkg用于添加依赖go mod init初始化,创建go.mod文件go mod download下载模块到本地缓存go mod tidy添加需要的依赖,删除不需要的依赖
3. 测试
3.1 单元测试
- 测试文件以
_test.go结尾 func TestXxx(*testing.T)- 初始化逻辑放在
func TestMain(*testing.M)中
go test fileName.go --cover 可以得到测试覆盖率
3.2 单元测试 - Mock
golang/mock: GoMock is a mocking framework for the Go programming language. (github.com)
3.3 基准测试
具体方法细节建议翻阅文档