这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
1.1Goroutine
协程:用户态,轻量级线程,栈MB级别。(每次创建都能有上万个协程,因此是go语言更适合高并发场景)
线程:内核态,线程跑多个协程,栈KB级别。
go语言中协程的初步使用
package main
import (
"time"
)
func hello(i int){
println("hello goroutine : %d",i)
}
func main(){
for i:=0;i<5;i++{
go func(j int){
hello(j)
}(i)
}
time.Sleep(time.Second)
}
1.2CSP(communicating Sequential Process)
推荐使用通过通信共享内存,而不是通过共享内存而实现通信。
1.3channel
make(chan,[缓冲大小])
make(chan int)
make(chan int,2)有缓冲通道
带有缓冲的通道可以解决生产者和消费者的速度问题,因为只要缓冲通道不为空,那么数据就可以一直发送,若没有缓冲通道,那么当消费者满时,将会阻塞无法发送。
1.4并发安全lock
有锁的协程能够不受其他协程影响正确执行操作,而没锁的协程执行结果将会被影响。
2.依赖管理
2.1.1GOPATH
bin:项目编译的二进制文件
pkg:项目编译的中间产物
src:项目源码
2.1.2 Go Vendor
- 项目目录下增加vendor文件,所有依赖包副本形式放在$ProjectRoot/vendor
- 依赖寻址方式:vendor=>GOPATH
- 通过每个项目引入一个依赖副本,解决了多个项目需要同一个package冲突的依赖问题
2.1.3 Go Module
- 通过go.mod文件管理依赖包版本
- 通过go get/go mod指令工具管理依赖包
2.2 依赖管理三要素
- 配置文件,描述以来 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod
2.2.1 依赖配置 go.mod
- 主版本2+模块会在模块路径增加/vN后缀。
- 对于没有go.mod 文件并且主版本2+的依赖,会+incompatible
gopath和govendor是源码副本方式依赖,没有版本规则概念,而gomod为了方便管理则定义了版本规则,不同的MAJOR版本表示是不兼容的API,所以即使是同一个库,MAJOR版本不同也会被为是不同的模块MINOR版本通常是新增函数或功能,向后兼容,而patch 版本一般是修复bug。基础版本前缀和语义化版本一样的。时间戳也就是最后提交的时间,最后是校验码(abcdefabcdef),包含12位的哈希前缀;每次提交commit后Go都会默认生成一个伪版本号。
当一个项目包含有多个依赖时,系统会选择最低版本进行兼容(v1.3和v1.4,选择v1.4)
2.2.3 依赖分发-Proxy
若没有proxy,则会有以下缺点
- 无法保证构建的稳定性(增加/删除/修改软件版本)
- 无法保证依赖可用性(删除软件)
- 增加第三方压力(代码托管平台负载问题)
2.2.4 依赖分发-变量GOPROXY
GOPROXY是一个go proxy站点URL列表,可以使用“direct”表示源站。对于示例配置,整体以来寻址路径,会优先从proxy1下载依赖,如果proxy1不存在,再从proxy2寻找,如不存在,会直接从源站中下载依赖。