Go语言进阶 | 青训营笔记

57 阅读2分钟

Go语言进阶 | 青训营笔记

01. 语言进阶

协程vs线程

  • 协程:用户态,轻量级线程,栈KB级别
  • 线程:内核态,线程跑多个协程,栈MB级别

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

  • 当然,也支持共享内存,但是需要互斥量

Channel

make(chan 元素类型, [缓冲大小])

  • 无缓冲通道 make(chan int)

    能实现通道连接的两个协程同步,因此也叫同步通道

  • 有缓冲通道 make(chan int, 2)

可以通过协程之间的通道通信实现有序性

  • 如下图例程通过A与B之间的通信实现了0~9数字的有序性

2.1.png

通过加锁能够实现协程安全的问题,加锁之后能够保证并发安全问题

WaitGroup

通过WaitGroup和其暴露的三个方法来实现协程的阻塞

定义:var wg sync.WaitGroup

三个方法:

  • Add(delta int) 计数器+delta
  • Done() 计数器-1
  • Wait() 阻塞直到计数器为0

开启协程+1;执行结束-1;主协程阻塞直到计数器为0

使用三个方法的简单示例:

 func ManyGoWait() {
     var wg sync.WaitGroup
     wg.Add(5)
     for i := 0; i < 5; i++ {
         go func(j int){
             defer wg.Done()
             hello(j)
         }(i)
     }
     wg.Wait()
 }

02. 依赖管理

利用其他人开发好获得验证的工具来进行开发,工程项目不可能基于标准库0~1编码搭建,因此要管理依赖库

Go依赖管理演进

三个阶段:

  • GOPATH
  • Go Vendor
  • Go Module:广泛应用

不同环境(项目)依赖的版本不同,控制依赖库的版本

GOPATH

  • 环境变量 $GOPATH

    会有三个文件

     .
     |
     |——bin  //项目编译的二进制文件
     |——pkg  //项目编译的中间产物,加速编译
     |——src  //项目源码
    
  • 项目代码直接依赖src下的代码

  • go get下载最新版本的包到src目录下

GOPATH弊端:在场景Project A和Project B依赖于某一package的不同版本时,无法实现package的多版本控制

Go Vendor

  • 项目目录下增加vendor文件,所有依赖包副本形式放在 $ProjectRoot/vendor
  • 依赖寻址方式:vendor=>GOPATH

通过每个项目引入一份依赖的副本,解决了多个项目需要同一个package依赖的冲突问题

Go Vendor弊端:

  • 无法控制依赖的版本
  • 更新项目有可能出现依赖冲突,导致编译出错

Go Module

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

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

依赖管理三要素:

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

依赖配置——go.mod

2.2.png 依赖配置——version

  • 语义化版本

    ${MAJOR}.${MINOR}.${PATCH}

    V1.3.0 V2.3.0

  • 基于commit伪版本

    vX.0.0-yyyymmddhhmmss-abcdefgh1234

    v.0.0.0-20220401081311-c38fd59326b7

    v1.0.0-20201130134442-10cb98267c6c

依赖配置——indirect

2.3.png

假设有A->B->C,那么A->B是直接依赖,A->C是间接依赖

依赖配置——incompatible

2.4.png

  • 主版本2+模块会在模块路径增加/vN后缀
  • 对于没有go.mod文件并且主版本2+的依赖,会+incompatible

依赖分发——Proxy

2.5.png

通过在依赖存在的代码托管平台与开发者之间添加一个Proxy,能够实现稳定可靠的依赖分发的功能

依赖分发-变量——GOPROXY

  • GOPROXY="https://proxy1.cn, https://proxy2.cn ,direct"
  • 服务站点URL列表,"direct"表示源站
  • Proxy 1 --> Proxy 2 --> Direct

工具——go get

2.6.png

工具——go mod

2.7.png

03. 测试

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

回归测试->集成测试->单元测试,覆盖率逐渐变大,成本逐渐降低

单元测试

2.8.png

规则:

  • 所有测试文件以_test.go结尾
  • func TestXxx(*testing.T)
  • 初始化逻辑放到TestMain
Mock测试
基准测试
  • 优化代码,需要对当前代码分析
  • 内置的测试框架提供了基准测试的能力

04. 项目实战

2.9.png

需求设计
代码开发
测试运行