tag: [GoLang, 青训营, 学习记录]
这是我参与「第五届青训营」伴学笔记创作活动的第 2 天
本文同步发布于博客(xblc.netlify.app),如果有更新博客会在第一时间更新
并发编程
并发vs并行
- 并行可以理解为实现(解决)并发的一个手段
- Go语言就是为并发而生的,可以充分发挥多核优势
协程 GoRoutine
区别
-
线程:昂贵下系统资源,占用很大,内核态
-
协程:轻量级的一个线程,用户级;Go可以创建上万个协程
-
开启协程的方法
go func(){ }()指令暂时未知 t1
-
子协程执行完,母协程不退出
t2 这里暂时不太懂
CSP
通信共享内存而不是反过来
- Channel:连接协程,进行值的通信
- 协程间通过共享内存进行内存交换
Channel
- 通过
make函数可以建立确定「缓冲通道」大小的 Channel - 缓冲通道和缓冲区的作用差不多
- 作用
- 顺序性,并发安全
- 有缓冲:生产-消费模型中,不会因为消费速度问题影响生产
复杂操作
并发安全 Lock
t3
- 不加锁可能引起错误结果
- 避免对共享内存做一些并发安全的读写操作
WaitGroup
三个主要计数方法:
- 协程 +d -1 阻塞直到零
优化
依赖管理
依赖管理演进
- GOPATH:
- 所有项目都从 src 目录下获取
- 问题:不同的项目分别对同一个包的不同版本有依赖的使用的时候,包升级了以后就控制不了就版本了,无法实现多版本的控制
- Go Vendor:
- 项目目录下增加 vendor 文件夹,存放依赖的副本,项目优先从 vender 获取依赖
- 分别使用依赖解决了不同项目解决了多版本控制的问题
- 问题:依赖版本不可控,容易不兼容
- Go Module:
- Go推出的一个依赖管理系统,最终目的是定义版本规则和管理项目的依赖关系
- 三要素
- 配置文件 go.mod 描述项目如何以来
- 中心仓库管理依赖库 proxy
- 本地工具
配置文件 go.mod
基本单元:
- 原生库(版本)
- 单元依赖
- module path
- 版本号 定位到某一个版本和提交
版本规则:
- 语义化版本
- commit 伪版本
- indirect 非直接依赖,没有导入的
- incompatible 没有 go.mod 和 「主版本」 v2+
依赖分发-回源 proxy:
解决远程仓库的依赖使用问题
直接同步的话:
- 无法保证构建稳定性
- 保证依赖可用性
- 仓库负载
解决:所有仓库都从 proxy 拉去依赖 GOPROXY环境变量:复制站列表,顺次去找,找不到就回到源站
本地工具使用
go get
- 默认
- 删除
- 拉取特定分支
go mod
init初始化,创建 go.mod 文件download下载模块到本地tidy修建,自动删除和增加
测试
测试种类
- 回归测试
- 集成测试
- 单元测试
单元测试
规则
t1 不太懂
- go test 运行测试
- 单元测试 assert
评价 —— 覆盖率
- 描述通过测试的代码覆盖程度
--cover- tips
- 50%+就过关
- 分支尽量独立、分别覆盖全
- 测试单元粒度小,测试目的明确
依赖
要测试的单元可能有很多依赖
两个目标
- 幂等:多次测试结果一样
- 稳定:单元测试是能够相互隔离的,不同测试函数能够独立运行
实现两个目标:Mock机制
- 文件处理:测试文件容易被篡改
- 打桩:用一个函数替换原函数
- 打桩测试:不依赖本地文件
基准测试
- 作用:对代码进行优化
- 写法
BenchmarkXxx()- 入参
*testing.B
- 听不懂 fast并性能更优
实战
步骤:
- 需求分析
- 代码开发
- 测试运行