这是我参与「第五届青训营 」笔记创作活动的第1天
一、本堂课重点内容:
- 语言进阶
- 依赖管理
- 测试
- 项目实战
二、详细知识点介绍:
1 语言进阶
- 进程与线程
多进程的出现是为了解决CPU利用率问题,线程是为了减少上下文切换时的开销。
-
协程
- 协程是用户视角的一种抽象,操作系统并没有协程的概念。
- 协程运行在线程之上,协程的主要思想是在用户态实现调度算法,用少量线程完成大量任务的调度。
- goroutine是golang中对协程的实现
-
协程之间的通信:
Go语言提倡通过通信共享内存而不是通过共享内存而实现通信
- 通过通信共享内存
- 通过通道对协程进行一个连接,先入先出
- 通过共享内存实现通信
- 通过互斥量对内存进行加锁,需要获取临界区的权限
- 缺点:不同的goroutine之间容易发生数据竞赛的问题,一定程度影响程序性能
- 通过通信共享内存
4.Channel
- 无缓冲通道
- 缺点:发送接收goroutine同步化
- 有缓存通道
- 可以解决生产消费不均衡带来的执行效率问题
5.WaitGroup
前面用了sleep来阻塞,不知道子协程时间,Go用waitGroup实现协程同步
- 开启协程+1;执行结束-1;主协程阻塞直到计数器为0
func ManyGoWait() {
var wg sync.WaitGroup
wg.Add(5)
for i := 0; i < 5; i++ {
go func(j int) {
defer wg.Done()
// 这里的hello是goroutine.go里的函数
hello(j)
}(i) //相当于调用这个函数
}
wg.Wait()
}
2 依赖管理
- GOPATH无法实现package的多版本控制
- GOVender通过每个项目引入一份依赖的副本vendor文件,解决多个项目需要同一个package依赖的冲突问题
- 无法控制依赖的版本
- 更新项目又可能出现依赖冲突,导致编译出错
- Go Module解决项目无法依赖同一个库多个版本问题
- 通过go.mod 文件管理依赖包版本
- 通过 go get/go mod 指令工具管理依赖包
2 依赖管理三要素
- 配置文件,描述依赖 go.mod文件
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod 类比java里的maven
三、实践练习例子:
1 语言进阶
-
理解channel:
题目:
-
并发安全Lock
题目:对变量执行2000次的+1操作,5个协程并发执行
PS:在本地运行是对的,不清楚为什么在掘金上结果错误
五、引用参考:
- 总结:协程与线程