前言
主要对项目的编写设计上进行介绍和教学。
介绍了在项目开发过程中比较重要的几点,包括对于并发性设计的考虑。
也包括了在实际应用过程中使用依赖包的注意事项,都进行了较为详细的介绍。
并发性
并发vs并行
- 多线程序在单核cpu运行
- 多线程序在多核上运行
goroutine
分为两个部分
用户态和内核态
协程:用户态,是轻量级的线程,栈是kb级别的 线程:属于系统,线程跑多个协程,MB级别
快速打印问题
go func
其实就是在前面加上关键字go
Csp 通讯共享内存
提倡通过通信共享内存而不是通过共享内存而实现通讯
Channel
分为有缓冲通道和无缓冲通道两种
make(chan int)
make(chan int,2)
有缓冲会让通道暂时的存储,可以保证一个顺序性。 在设计通道的时候要注意生产和消费的过程,缓冲就会解决一个生产和消费的效率不统一的问题
并发安全lock
比如对变量执行2000次操作,五个协程并发进行
这个协程其实可以在循环中对于func加go
对于需要操作的变量x添加一个lock sync.Mutex并发锁。可以在函数对x进行操作时通过加锁lock.Lock()和lock.Unlock()就可以实现对该变量的安全控制
waitGroup
计数器
开启协程+1;执行结束减一;主协程阻塞直到计数器为0。
var wg sync.WaitGroup
小结
- goroutine 协程
- channel 支持通过通讯实现共享内存
- sync 并发保护
依赖管理
背景
- 我们不可能从0-1来搭建项目
- 管理依赖库
演进
GoPATH->GO VENDOR -> Go Module
- 不同环境下依赖版本不同
- 可以控制依赖库版本
GOPATH
-bin -pkg -src
项目代码直接依赖src下的代码
弊端: A和B依赖于某一个package的不同版本 我们就不能实现package的多版本控制
GO vender
在项目下添加vender文件夹,所有的依赖包会以副本的方式存储在vendor,保证了每个项目依赖同一个包的情况
弊端: 无法控制依赖的版本;更新项目的话,又会出现依赖问题
Go mod
- 通过
go.mod文件管理依赖包版本 - 通过
go get/go mod指令或者工具管理依赖包
终极目标: 定义版本规则和管理项目依赖关系
go.mod 配置文件,描述依赖:module go require
proxy 中心仓库管理依赖
go get、mod 本地工具
依赖配置-version
语义化版本:{major}{minor}{patch} major之间是隔离的,minor前后兼容 patch修改bug
基于commit伪版本 vx.0.0-时间戳-12位哈希码
indirect
间接依赖
incompatible
对于版本2+的依赖,需要添加/vN后缀 对于没有gomod的,+incompatible。
依赖图
会选择最低的兼容版本
依赖分发 回源
可以直接从对应仓库进行下载,但是
- 无法保证构建稳定性
- 无法保证依赖可用性
- 增加第三方压力
就出现了proxy,缓存源站中的软件版本
GoProxy配置
其实是URL列表,最后是direct,找不到会回源到源站
工具
go get默认最新版本 @none 删除 @v1.1.2拉去特定版本 @23dfdd5 特定commit
gomod init 初始化go。mod文件 download下载模块到本地缓存 tidy增加需要的依赖,删除不需要的
测试
回归 集成 单元测试 三个类型,
从上到下、覆盖率逐层变大,成本逐渐降低
单元测试
输入 测试单元 输出 最后结果与期望校对 保证质量、也提升了效率
规则
- 以_test.go结尾
func TestXXX(t *testing t)- testMain函数
例子
"github.com/stretchr/testify/assert"
assert库
覆盖率
如何评价项目的测试效果
在运行之后添加--cover可以看出覆盖率
后面要完善添加test函数,使覆盖率靠近100% 50~60是一般情况,80是比较高
测试分支要相互独立,全面覆盖
测试单元粒度足够小,函数单一职责
依赖
外部依赖-》稳定&幂等 需要mock机制
mock测试
"https://github.com/bouk/monkey"
打桩测试
基准测试
对于随机函数的设计,可以优化的 fastrand.Init(n:10)
项目实践
需求设计
需求用例
浏览消费用户 设计实体struct
分层结构
数据层:数据model 外部数据的增删改查 逻辑层:业务entity 处理核心业务的逻辑输出 视图层:视图view 处理和外部的交互逻辑
组件工具
Gin 高性能 go web 框架 github.com/gin-gonic/g…
Gomod
go mod init
go get gopkg.in/gin-gonic/gin.v1@v1.3.0
代码开发
需要跟着项目来看 通过map来定位数据行。
service
参数校验-》准备数据-》组装实体
测试运行
主要就是得到json格式的输出格式,通过得到的response来暴露给http地址