go进阶与依赖管理
7-26
go充分的实现高并发
go可以在用户态上开很多个协程,协程是在KB级别的
在go中创建协程
在调用协程函数的前面添加go
go func(j int) {
hello(j)
}(i)
go func(){
}()
Channel
make(chan 元素类型,[缓冲大小])
无缓冲通道 make(i int)
有缓冲通道 make(i int ,2)
通常提倡通过通道来实现数据的共享
通过通道来实现数据的共享
func CalSquare(){
src := make(chan int)
dest :=make(chan ine,3)
go func(){
defer closs(src)
for i:=0;i<9;i++{
src<-i
}
}()
go func(){
defer close(dast){
for i:=range src{
i<-i*i
}
}
}()
fot i:=range dest{
println(i)
}
}
并发安全
使用锁来进行数据的共享
var(
x int64
lock sync.Mutex
)
func addWithLock(){
for i:=0;i<2000;i++{
lock.Lock()
x += i
lock.Unlock()
}
}
func addWithoutLock(){
for i := 0 ; i < 2000 ; i++ {
x+=i
}
}
func Add(){
x=0
for i:=0;i<5;i++{
go addWithLock()
}
time.Sleep(time.Second)
println("WithLock",x)
x=0
for i:=0;i<5;i++{
go addWithoutLock()
}
time.Sleep(time.Second)
println("WithoutLock",x)
}
会出现计算的错误
WaitGroup
是创建多个子协程的写法
通过计数来进行操作
func main(){
var wg sync.W
}func ManyGoWait() {
var wg sync.WaitGroup
wg.Add(5) //创建5个字协程
for i := 0; i < 5; i++ {
go func(j int) {
defer wg.Done() //子协程完成,数量减1
hello(j)
}(i)
}
wg.Wait() //协程等待运行完
}
Goroutine
Channel使用通道来实现协程的共享
依赖管理
依赖:各种的开发包
版本
GOPATH->Go Vendor->Go Module
GOPATH
是go 的一个环境变量
bin
pkg
src
弊端:会出现版本的不同,所以实现的函数是不一样的
不能实现多版本控制
Go Vendo
会引入一个依赖的副本,先在统一的副本中找依赖,完了再去path中找依赖
同样的也会出现版本的不同,出现依赖的冲突
Go Module
可以通过管理工具来控制版本和管理文件
依赖管理三要素
1.配置文件,描述依赖 go.mod
2.中心仓库管理依赖库 Proxy
3.本地工具 go get/mod
java中也有类似的东西
go.mod
mod的组成
indirect 非直接依赖,
依赖配置—version
管理规则
语义化版本 {MINOR}.${PATCH} V1.3.0 V2.3.0 基于 commit 伪版本 go都会自动生产 vx.0.0–yyyymmddhhmmss-abcdefgh1234 v0.0.0-20220401081311-c38fb59326b7 v1.0.0-20201130134442-10cb98267c6c
版本前缀 提交时的时间戳 时间戳的hs值
在go中会使用算法来自动选择版本中最低且兼容的版本
依赖分发
Proxy可以保障依赖的稳定性,
可以很好的控制版本依赖
GOPROXY
init在项目开始的时候可以创建依赖包
tidy可以在项目的最后进行版本的整理,减少不用的版本依赖
测试
单元测试
回归测试 黑盒测试
集成测试
单元测试 对于开发阶段,对某个函数的测试
规则
代码覆盖率是看单元测试是否及格的标准
覆盖率
使用对范围的测试,来计算测试范围的大小
使用第三方的方法来对代码的区域进行输入输出的结果测试,还有执行代码区域的大小进行覆盖率的计算