这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
1、Go语言进阶与依赖管理
1.1并发vs并行
go语言的并发和并行
Goroutine
协程:用户态,轻量级线程,栈MB级别
线程:内核态,线程跑多个协程,栈KB级别
快速打印hello goroutine:0~hello goroutine:4
func hello(i int){
println("hello goroutine:"+fmt.Sprint(i))
}
func HelloGoRoutine(){
for i:=0;i<5;i++{
go func(j int){ //实现协程在函数前加go、
hello(j);
}(i)
}
}
输出:
hello goroutine:4
hello goroutine:1
hello goroutine:0
hello goroutine:2
hello goroutine:3
乱序输出
CSP
提倡通过通信共享内存而不是通过共享内存而实现通信
Channel
make(chan 元素类型,[缓冲大小])
无缓冲通道 make(chan int)
有缓冲通道 make(chan int,2)
WaitGroup
计数器
开启协程+1;执行结束-1;主协程阻塞直到计数器为0
Add(delta int)
Done()
Wait()
快速打印hello goroutine的优化
func ManyGoWait(){
var wg sync.WaitGroup
wg.Add(delta:5)
for i:=0;i<5;i++{
go func(j int){
defer eg.Done()
hello(j)
}(i)
}
wg.Wait()
}
1.2依赖管理
GOPATH
bin 项目编译的二进制文件
pkg 项目编译的中间产物,加速编译
src 项目原码
弊端:A和B依赖于某一package的不同版本,无法实现package的多版本控制
Go Vendor
增加vendor文件,所有依赖包副本形式放在$ProjectRoot/vendor
通过每个项目引入一份依赖的副本,解决了多个项目需要同一个package依赖的冲突问题
弊端:无法控制依赖的版本,更新项目又可能出现依赖冲突,导致编译出错
Go Module
通过go.mod文件管理依赖包版本
通过go get/go mod指令工具管理依赖包
终极目标:定义版本规则和管理项目依赖的关系
————————————————————————————————
不同环境(项目)依赖的版本不同
控制依赖库的版本
依赖管理三要素
(1)配置文件,描述依赖 go.mod
(2)中心仓库管理依赖库 Proxy
(3)本地工具 go get/mod
2、Go语言工程实践之测试
2.1测试
回归测试 集成测试 单元测试
单元测试-规则
- 所有测试文件以_test.go结尾
- func TestXxx(*testing.T)
- 初始化逻辑放到TestMain中
例子:
func HelloTom() string{
return "Jerry"
}
func TestHelloTom(t *testing.T){
output:=HelloTom()
expectOutput:="Tom"
if output ≠expectOutput{
t.Errorf(format:"Expected %s do not match actual %s",expectOutput,output)
}
}
(2)分层结构
数据层:数据Model,外部数据的增删改查
逻辑层:业务Entity,处理核心业务逻辑输出
视图层:视图view,处理和外部的交互逻辑
3、总结:
Goroutine 协程,实现高并发的操作
Channel 通过通信实现共享内存
Sync 并发安全操作和协程之间的同步