这是我参与「第五届青训营」笔记创作活动的第2天。
今天的课程主要讲了以下几个部分
-
go并发编程
- goroutine
- channel
- Lock
- WaitGroup
-
go的依赖管理模式
- GO PATH
- GO Vendor
- GO MODULE
-
go的测试
- 单元测试
- 基准测试
-
工程实践
golang并发编程
goroutine
在其他语言中一般并发是在线程级别的并发,但是在golang中,则是协程,协程是运行在用户态的一种并发,也就是任务的执行调度不用再一直切换到内核态去了,减轻了切换上下文的成本。
在go中,使用goroutine的语法是go + 函数名(形参b){}(实参a)后面的括号是代表函数执行
比如go func(num int){}(10)
channel
协程间的通信主要依靠channel来进行,在任何时候,只能有一个goroutine来访问通道,进行写入或者读取数据
如果无缓存区,则必须生产完被消费才能继续生产,即如果消费能力不够,就变成阻塞模型了
所以为了应对消费能力弱的情况,应当合理设置channel缓冲区,比如设置为3,就可以存放3个该类型的数据
定义channel的方法有两种
var ch1 = make(chan int)var ch2 = make(chan in, 3),后面跟上的数字代表缓冲区大小的意思
Lock
声明锁var lock sync.Mutex
加锁函数为lock.Lock()
解锁函数为lock.Unlock()
WaitGroup
WaitGroup类似Java中的CountDownLatch类,即内置一个计数器
主要使用方法如下
var countLock sync.WaitGroup,声明WaitGroup
countLock.Add(6),设置任务数量
countLock.Done(),完成一个任务
countLock.wait(),阻塞等待所有任务结束
依赖管理
目前主要使用的就是GO MODULE,其余的两个已经基本上被淘汰了,1.16版本以后是默认开启GO MODULE,文件是go.mod
这个没什么好说的
go单元测试
单元测试主要有3个规则
-
所有的测试文件都以_test.go结尾
-
测试函数命名规范
func TestXxx(t *testing.T){} -
测试主函数基本规范
func TestMain(m *testing.M){ //进行数据装载,配置初始化等前置操作 code := m.Run()//跑所有单测 //执行释放资源等收尾工作 os.Exit(code)//退出 }
go基准测试
主要是测试CPU的损耗,老师举了rand生成随机数中,需要持有一把全局锁,导致性能下降的场景