go工作方式
这是我参与【第五届青训营】伴学笔记创作活动的第2天。
go之间是通过协程来工作的,协程相比较线程,速度更快,充分发挥多核优势,开启协程只需要在调用函数前面加一个go即可。
协程之间通过通信共享内存,之间有一个通道,遵循先入先出规则,这样避免了加锁问题。Channel是一种引用类型,本质是一个队列,用make创建,有两种,一种是无缓冲通道:
make(chan int),之间数据同步;另一种是有缓冲通道:
make(chan int 2),之间有存储空间,通道的容量表示通道中能存放元素的数量。
通道的基本操作:
//声明通道
var ch chan int
//创建通道
ch=make(chan int)
//把10发送到ch中
ch<-10
//从通道中接受值
<-ch
//关闭通道
close(ch)
并发安全LOCK
当多个协程对一个对象同时执行操作时,结果是不确定了,为了保证并发执行时的安全性以及正确性,引进了LOCK操作。
var lock sync.Mutex //互斥锁
lock.Lock() //加锁
lock.Unlock() //解锁
WaitGroup(Add Done Wait)
WaitGroup可以实现并发等待,调用 WaitGroup 后,就能自动判断所有协程执行完毕,立马开始后续代码的执行,提高程序运行效率。有三个方法:
Add(delta int)、Done()、Wait()。
依赖管理
依赖管理演进
- gopath
- go Vender
- go Module
gopath
项目代码在src下面
缺点:不兼容多版本控制
go Vender
引入一个vender,依赖包的副本放到里面,解决了多个项目需要同一个package的依赖冲突问题。
缺点:依赖版本不清楚
go Module
- 通过go.mod文件管理依赖包版本
- 通过go get/go mod指令工具管理依赖包
测试
为了避免经济损失
单元测试
- 所有的测试文件以_test.go结尾
- func TestXxx(*testing.T)
- 初始化逻辑放到TestMain中