Go 语言工程进阶| 青训营笔记
这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
1.并发编程
go语言具有充分发挥多核优势,高效运行的作用,通过轻量级协程的方式,处理高并发
在go中,创建一个协程也非常简单,使用 go 关键字,就可创建一个进程
```go
//创建了五个进程
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
```
go中支持从两种进程间的联系:
-
通过通信共享内存
go中提倡使用通信共享内存,使用关键字 chan(通道) 来连接
src := make(chan int) //创建无缓冲通道 dest := make(chan int, 3) //创建缓冲空间为3的通道 go func() { defer close(src) for i := 0; i < 10; i++ { src <- i //将i的值送入src通道 } }() go func() { defer close(dest) for i := range src { dest <- i * i //从src中拿值,并送入dest通道 } }() for i := range dest { println(i) }src为无缓冲通道,dest为有缓冲通道,会缓和两个进程间的关系减少等待时长
-
通过共享内存实现通信
直接通过获取共享内存数据来通信,但是这种方法有风险,在多进程的情况下,可能不同进程的指令对同一个数据进行相同的操作,最后导致结果发生错误,采用这种方式,需要使用一些办法避免
func addWithLock() { for i := 0; i < 2000; i++ { lock.Lock() //使用锁机制,保护取出的数据 x += 1 lock.Unlock() //关闭锁 } } func addWithoutLock() { for i := 0; i < 2000; i++ { x += 1 //直接改变全局变量 } } func Add() { x = 0 for i := 0; i < 5; i++ { go addWithLock() } time.Sleep(time.Second) fmt.Println("WithLock: ", x) x = 0 for i := 0; i < 5; i++ { go addWithoutLock() } time.Sleep(time.Second) fmt.Println("WithoutLock: ", x) }结果没有锁保护机制的x未能满足要求,其中的加和可能发生了重叠,一定要注意对公共内存数据的保护
-
WaitGroup在go中对进程进行管理
var wg sync.WaitGroup //定义WaitGroup变量 for i := 0; i < 5; i++ { wg.Add(1) //每创建一个进程,WaitGroup计数器加一 go func(j int) { defer wg.Done() //当进程完成时,计数器减一 hello(j) }(i) } wg.Wait() //等待所有进程执行完成,即计数器为0WaitGroup是较为良好的管理进程,同步进程的方法
2.依赖管理
go语言的依赖管理
经历了从GOPATH到GO Vendor,两个版本都存在依赖包版本不能兼容的问题,最后确定使用 Go Module 来进行依赖管理
-
Go Module的三要素
- 配置文件,描述依赖 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod
go.mod采取的是选择最低的兼容版本依赖
-
go mod 的使用
- init 初始化,创建go.mod文件
- download 下载模块到本地缓存
- tidy 增加需要的依赖,删除不需要的依赖
3.测试
- 单元测试
4.基于MVC的http请求响应
总结
-
讲的都是关键的部分,容易让我们抓住重点
-
得到很多启发,通过项目学习,结合自己所学,处理数据库和http之间的联系
-
太多知识点需要记忆,感觉收获满满
-
快速转变角色,走进开发者的状态