并发&依赖管理&测试|青训营笔记

26 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第2天

01 并发

协程( Goroutine)

用户态,轻量级,栈内存小。并发利器

  • 通过通信共享内存(通道实现)而不是共享内存而实现通信(临界区),Go保留了两种方式。

通道

引用类型

  • 无缓冲通道 make(chan int) ,也称同步通道。发送的goroutine和接收的goroutine同步化。
  • 有缓冲通道 make(chan int,2)典型的生产消费模型。
func callSquare(){
    src := make(chan int)
    dest := make(chan int, 3)
    // A子协程发送0~9数字
    go func(){
        defer close(src)
        for i:=0;i<10;i++{
            src<-i
        }
    }()
    // B子协程计算输入数字的平方
    go func(){
        defer close(dest)
        for i := range src{
            dest<-i*i
        }
    }()
    for i:=range dest{
        // 主协程输出最后的平方数。
        // 复杂操作。消费者消费速度比生产者速度慢,所以使用带缓冲区的channel
        fmt.Println(i)
    }
}
  • 临界区实现并发

  • sync包下,实现并发任务同步。

暴露三个方法Add、Done、Wait,内部是维护一个计数器。

02 依赖管理

依赖:各种开发包

背景

第三方依赖通过sdk方式引入

Go 依赖管理研究

Go PATH->Go Vendor->Go Module(当前广泛应用)

  • Go PATH

弊端:无法实现依赖包的多版本控制

  • Go Vendor

增加了vendor文件夹;解决了多个项目需要同一个依赖包的冲突问题。

Go Module实践

  • Go Module

终极目标:定义版本规则和管理项目依赖关系

Go1.16版本默认开启

    • 通过go.mod 文件管理依赖包版本
    • 通过go get/go mod 指令工具管理依赖包

依赖管理三要素

    • 配置文件,描述依赖 go.mod
    • 中心仓库管理依赖 Proxy
    • 本地工具 go get/mod

  • 依赖配置
    • indirect 在go mod没有直接导入的间接依赖
    • incompatible 主版本2+模块会在路径增加/vN后缀;对于没有go.mod文件并且主版本2+的依赖,会+incompatible
  • 依赖图

选B,原则选择最低的兼容版本。

  • 依赖分发

依赖去哪里下载

  • proxy

缓存了依赖的不同版本

go proxy解决了

先去proxy1下载依赖,如果不存在去go proxy2,如果还不在就去源仓库下载。这种设计了类似缓存,如果缓存中不存在数据,就去DB读数据。

  • 本地工具

每次提交代码前执行一次go tidy

03 单元测试

测试是避免事故的最后一道屏障

回归测试:点点点

集成测试:功能维度

单元测试:开发阶段,对开发功能的验证x 。

单元测试

  • 代码覆盖率

如何衡量代码是否已经经过了足够吧的测试?

如何评价项目的测试水准?

如何评估项目是否达到了高水准测试等级?

评估上述问题

整个函数,前两行代码被验证过,最后一行没验证过。所以覆盖率是:2/3=66.7%

Tips:

  • 一般的覆盖率:50%~60%。较高覆盖率80%+。
  • 测试分支相互独立、全面覆盖。
  • 测试单元粒度足够小,函数单一职责。

Mock测试

target是目标待测函数。repalcement是打桩函数

基准测试

  • 优化代码,需要对当前代码分析(测试一段程序CPU的性能)
  • 内置的测试框架提供了基础测试的能力

04 项目实践