这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
并发 VS 并行
- 多线程程序在一个核的 cpu 上运行
- 多线程程序在多个核的 cpu 上运行
协程(Goroutine)VS 线程
- 用户态,轻量级线程,栈 MB 级别
- 协程的创建:在函数前加上go
eg.go func(...){...}
- 协程的创建:在函数前加上go
- 内核态,线程跑多个协程,栈 KB 级别
- 通信(CSP):通过通信共享内存
- 通道(Channel):
- 通过通信共享内存
- 创建:
make(chan 元素类型,[缓冲大小]) - 无缓冲通道:
make(chan int) - 有缓冲通道:
make(chan int,2)
- 创建:
- 通过通信共享内存
- Sync:
- 通过共享内存实现:并发安全 Lock
eg.func xx (){lock.Lock() [要加锁的操作] lock.Unlock} - WaitGroup:
- 创建:
var xx sync.WaitGroup - 加入协程:
xx.Add([协程数]) - 对计数器减一:
defer xx.Done() - 阻塞:
wg.Wait()
- 创建:
- 通过共享内存实现:并发安全 Lock
依赖管理
- 实现目标:
- 不同环境(项目)依赖的版本不同
- 控制依赖库的版本
- GOPATH
- 项目代码直接依赖到 src 下的代码
- go get 下载最新版到 src 下
- 弊端:无法实现 package 的多版本控制
- 项目代码直接依赖到 src 下的代码
- GO Vendor
- 通过每个项目引入一份依赖的副本解决了多个项目需要同一个 package依赖的冲突问题
- 弊端:
① 无法控制依赖的版本
② 更新项目又可能出现依赖冲突,导致编译出错.
- GO Module
- 通过 go.mod 文件管理依赖包版本
- 通过 go get/go mod 指令工具管理依赖包
- 终极目标: 定义版本规则和管理项目依赖关系
- 依赖管理三要素:
- go.mod:配置文件,描述依赖
- 依赖配置-version
- 语义化版本
- 基于 commit 版本
- 语义化版本
- 依赖配置-indirect
对于没没有直接依赖的依赖标识为 indirect - 依赖配置-incompatible
- 主版本2+模块会在模块路径增加/N 后缀
- 对于没有 go.mod 文件并且主版本2+的依赖,会+ incompatible
- 依赖分发-回源
弊端:
- 无法保证构建稳定性:增加/修改/删除软件版本
- 无法保证依赖可用性:删除软件
- 增加第三方压力代码托管平台负载问题
- 依赖分发-Proxy
- 依赖分发-变量- GOPROXY
- GOPROXY="proxy1.cn, proxy2.cn,direct"
- direct'服务站点URL列表,“direct"表示源站
- 工具-go get
- 工具-go mod
- 依赖配置-version
- Proxy:中心仓库管理依赖库
- go get/mod:本地工具
- go.mod:配置文件,描述依赖
- 测试
- 单元测试
- 规则
- 所有测试文件以 test.go 结尾
- func TestXxx(*testing.T)
- 初始化逻辑放到 TestMain 中
- 规则
- 覆盖率
- 依赖
- Mock
- 基准测试
- 优化代码,需要对当前代码分析
- 单元测试
- 项目实践
- 分层结构
- 组件工具
- 分层结构