这是我参与「第五届青训营 」伴学笔记创作活动的第2天
并发VS并行
并发
单核CPU通过时间片切换
并行
多核CPU同时运行多个任务
广义的高并发包括并发和并行
Goroutine
线程在内核态,协程在用户态,使用协程不需要内核用户态切换省去开销
通过go关键字开启一个携程
go func() {
if err := http.ListenAndServe(":6060", nil); err != nil {
log.Fatal(err)
}
os.Exit(0)
}()
Channel
通过channel进行通信
分为有缓冲channel 和无缓冲channel,有缓冲channel主要用于消费者速度慢时
并发安全Lock
通过加锁保证并发临界区安全
lock sync.Mutex
lock.Lock()
x += 1
lock.Unlock()
WaitGroup
通过waitgroup实现协程同步,等待所有并发任务执行完
var wg sync.WaitGroup
wg.Add(5)
go func(j int){
defer wg.Done()
hello(j)
}
wg.Wait()
依赖管理
gomod依赖管理
三要素1 go.mod 2Proxy 3go get/mod
module example/project/ //app依赖管理基本单元
go 1.16 //原生库
require ( //单元依赖
example/lib1 v1.0.2
example/lib2 v1.0.0 // indirect
example/lib3 v0.1.0-20190725025543-5a5fe074e612
example/lib4 v0.0.0-20180306012644-bacd9c7ef1dd//indirect
example/lib5/v3 v3.0.2
example/lib6 v3.2.0+incompatible
)
非直接依赖用indirect标识
版本冲突,选择满足本次构建的最低兼容版本
通过Proxy缓存实现稳定可靠的依赖分发
go get工具
@update 默认
@none 删除依赖
@v1.1.2 tag版本,语义版本
@23dfdd5 特定的commit
@master 分支的最新commit
go mod
init 初始化,创建go.mod文件 download 下载模块到本地缓存 tidy 增加需要的依赖,删除不需要的依赖
测试
分为回归测试 集成测试 单元测试
测试代码
assert包可以实现测试结果比较
代码覆盖率 执行代码的行数与整个行数之比 一般覆盖率50%-60%,较高80%
测试分支相互独立、全面覆盖
测试单元粒度足够小,函数单一职责
Mock不对文件强依赖
benchmark进行基准测试,测试程序运行性能
rand有锁降低并发性能,高并发场景可以用fastrand
社区话题案例
实体Topic和Post一对多关系
三层分层结构
通过map实现内存索引快速查找数据