Go 语言进阶
1. 并发 VS 并行
并发:指多个线程交替执行,每个线程执行一部分任务,通过调度器在一个CPU核上切换。Go语言中的goroutine是并发的基本单元。
并行:指多个线程同时执行,每个线程在不同的CPU核上执行独立的任务,实现更高效的计算。Go语言通过goroutine实现并行运算。
2. Goroutine
Goroutine是Go语言中的协程,它是一种轻量级的线程,运行在用户态,栈的大小通常在KB级别,相比操作系统的线程(MB级别)更加高效。
在Go语言中,创建goroutine非常简单,使用 go 关键字即可:
3. CSP(Communicating Sequential Processes)
CSP是一种并发模型,Go语言采用了CSP模型。它鼓励通过通信来共享内存,而不是通过共享内存来实现通信。
在Go语言中,Channel是实现CSP模型的重要机制,可以用于在goroutine之间传递数据。
4. Channel
Channel是一种类型安全的通信机制,用于在多个goroutine之间传递数据。可以通过make函数创建Channel,语法为:
// 无缓冲通道
ch := make(chan 数据类型)
// 有缓冲通道
ch := make(chan 数据类型, 缓冲大小)
5. 并发安全
在多个goroutine并发执行时,访问共享的资源可能导致数据竞争和并发安全问题。为了保证并发安全,可以使用互斥锁(sync.Mutex)对共享资源进行加锁。
var lock sync.Mutex
lock.Lock()
// 对共享资源进行读写操作
lock.Unlock()
6. WaitGroup
WaitGroup是Go语言提供的一种等待机制,用于等待一组goroutine执行完成。它通过计数器实现。 计数器: 开启协程:计数器+1, 关闭协程:计数器-1 主进程阻塞直到计数器为0.
var wg sync.WaitGroup
// 启动goroutine时,计数器+1
wg.Add(1)
go func() {
// goroutine执行的代码
wg.Done() // 执行完成后,计数器-1
}()
// 主goroutine等待,直到计数器变为0
wg.Wait()
7. 依赖管理
这部分与Java的Maven;Python的pip|Conda类似,都是管理项目依赖工具。
7.1 发展
GOPATH->GOVENDOR->GOMODULE【最后一个是目前应用最广的】 各版本依赖工具具有的问题:
- Go path:存在多版本依赖冲突问题;
- Go vendor:添加vendor文件夹管理依赖,但是在多级依赖下,底层依赖依然会出现版本冲突问题。
- Go module:通过go.mod文件管理依赖包。通过
go get或go mod指令实现管理。
8. 测试
8.1 单元测试
单元测试覆盖范围最广,基本是开发人员对函数、接口等内容的基础测试。
在单元测试中,文件名固定,都是在功能文件基础上补充“_test”结尾拼接成新文件。函数结构如下:
func TestXxx(* testing.T)
8.2 Mock测试
可以使用Mock函数【monkey.Patch;monkey.Unpatch】进行测试。为一个函数/方法打桩。
8.3 基准测试
主要针对性能方面。 函数以BenchmarkSelect开头
优化测试性能,可以使用fastrand,高并发场景可能会有一定的性能问题。