Go语言入门-工程实践 | 青训营笔记

90 阅读2分钟
  1. Go并发编程
  2. 依赖管理
  3. 测试

1.并发编程

Goroutine

使用go 关键词就可以开启一个新的协程去执行另一部分代码

  • 协程是用户态的,线程是内核态的,线程可以为多个协程服务

image.png

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

image.png

Channel(通道)

channel可以很好的实现多个协程之间通信,从而达到通过通信共享内存的目的 channel是引用类型,用make创建 make(chan 元素类型 , [缓冲区大小])

  • 无缓冲的channel需要有人接收了数据才能再发送数据,所以也被称为同步channel

image.png

并发安全Lock

当多个协程对同一个变量进行大量操作时,可能会出现结果与预期不符的情况,这时候需要在操作的时候对变量加锁,防止此时被其他协程篡改

WaitGroup

让当前的协程阻塞,直到所有的协程完成任务

image.png

2.依赖管理库

Go依赖管理演进

  • 不同环境(项目)依赖的版本不同
  • 需要控制依赖的版本

目前应用广泛的主要是Go Module

image.png

GOPATH

GOPATH的弊端:无法实现package的多版本控制

Go Vendor

  • 项目目录下增加venfor文件夹,所有依赖包的副本形势放在文件夹内
  • 依赖寻址方式:vendor=>GOPATH

弊端:更新项目又可能出现依赖冲突,导致编译出错

image.png

Go Module

  • 通过go.mod文件管理依赖包版本
  • 通过go get/ go mod 指令工具管理依赖包
  • 终极目标:定义版本规则和惯例项目依赖关系

依赖管理三要素:

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

go get工具:

image.png

go mod工具:

image.png

3.测试

  • 单元测试
  • Mock测试
  • 基准测试

单元测试

image.png Go单元测试-规则

  • 所有测试文件以_test.go结尾
  • func TestXxx(* testing.T)
  • 初始化逻辑放到TeatMain中

举例

被测试的函数

func Hello(name string) string {
  return name
}

测试文件

package main
​
import "testing"func TestHello(t *testing.T) {
  type args struct {
    name string
  }
  tests := []struct {
    name string
    args args
    want string
  }{
    {name: "test1", want: "tom", args: args{name: "tom"}},//这是放入测试数据的地方
  }
  for _, tt := range tests {
    t.Run(tt.name, func(t *testing.T) {
      if got := Hello(tt.args.name); got != tt.want {
        t.Errorf("Hello() = %v, want %v", got, tt.want)
      }
    })
  }
}
​

覆盖率:希望测试数据尽可能覆盖更多的代码行数,提高可信度 image.png

Mock

外部依赖 =>稳定&幂等 image.png

快速Mock函数,使得测试函数不需要依赖外界的易丢失的数据

  • 为一个函数打桩
  • 为一个方法打桩

基准测试

  • 优化代码,需要对当前代码进行分析
  • 内置的测试框架提供了基准测试的能力