青训营笔记Day2

66 阅读4分钟

前言

主要对项目的编写设计上进行介绍和教学。

介绍了在项目开发过程中比较重要的几点,包括对于并发性设计的考虑。

也包括了在实际应用过程中使用依赖包的注意事项,都进行了较为详细的介绍。

并发性

并发vs并行

  1. 多线程序在单核cpu运行

_L9QI(UGMJB@K%HY5J{W354.png

  1. 多线程序在多核上运行

YU2Z$9F})CQZM~ULP%Y19LP.png

goroutine

分为两个部分

用户态和内核态

协程:用户态,是轻量级的线程,栈是kb级别的 线程:属于系统,线程跑多个协程,MB级别

快速打印问题

go func 其实就是在前面加上关键字go

Csp 通讯共享内存

提倡通过通信共享内存而不是通过共享内存而实现通讯

Channel

分为有缓冲通道和无缓冲通道两种 make(chan int) make(chan int,2)

有缓冲会让通道暂时的存储,可以保证一个顺序性。 在设计通道的时候要注意生产和消费的过程,缓冲就会解决一个生产和消费的效率不统一的问题

并发安全lock

比如对变量执行2000次操作,五个协程并发进行

这个协程其实可以在循环中对于funcgo

对于需要操作的变量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地址