这是我参与「第五届青训营」伴学笔记创作活动的第 2 天
并发
Goroutine
- 协程:用户态,轻量级线程,栈MB级别,可以轻松创建上万个
- 线程:内核态,线程跑多个携程,栈KB级别
- 使用:关键字
go,将自动创建协程并运行
CSP
- 提倡通过通信共享内存而不是通过 共享内存 来实现通信
Channel
- 声明:
make(chan 元素类型,[缓冲大小]) - 通道分为无缓冲通道,和有缓冲通道,通过声明时的缓冲大小的大小来决定
- 有缓冲通道通常用于消费者协程,因为生产者的逻辑一般比较简单,生产速度较快,如果使用无缓冲通道,则可能导致消费者速度慢阻塞生产者
- 通道是原子操作的
- 如果使用无缓冲通道,则必须先让创建协程接收就绪,再往通道发送消息,否则会死锁
- 注意要关闭通道,否则可能会导致阻塞
- 管道通信操作符:
<-
package main
func main() {
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
- 声明:
lock sync.Mutex - API:
lock.Lock()lock.Unlock()
WaitGroup
- 计数器:开启线程+1,执行结束-1,主线程阻塞直到计数器为0
- API:
Add(delta int)Done()Wait()
测试
单元测试
规则
- 测试文件以_test.go结尾
func TestXxx(*testing.T)- 初始化逻辑放 TestMain 中
Mock测试
- 打桩测试,不再依赖本地文件
基准测试
- 优化代码,需要对当前代码分析
- 内置的测试框架提供了基准测试的能力