Go语言进阶|青训营笔记

37 阅读2分钟

1.1 语言进阶

1.1.1 并发VS并行

image.png 并行:直接利用多核,实现多线程的同时运行。

并发:多线程在一个核的CPU上运行,主要是通过时间片的切换来实现同时运行的状态。

Go可以充分发挥多核优势,高效运行。

1.1.2 Goroutine

协程:用户态,轻量级线程,栈KB级别

线程:内核态,线程跑多个协程,栈MB级别

1.1.3 CSP

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

image.png

1.1.4 Channel

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

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

image.png

//主协程输出最后的平方数

func CalSqare() {
    src :=make(chan int) //无缓冲队列
    dest := make(chan int, 3) //有缓冲通道
    go func() {
        //A子协程发送0-9数字
        defer close(src)
        for i := 0; i < 10; i++ {
            src ← i  //把生产的数字发送到src的channel
        }
    }()
    go func() {
        //B子协程计算输入数字的平方
        defer close(dest)  //延迟关闭
        for i := range src {  //通过range遍历src里面的数据,通过src的channel就实现了A协程和B协程的通信
            dest ← i * i      //把i*i结果发送到desc的channel
        }
    }()
    for i := range dest {  //遍历dest的channel
        //复杂操作
        println(i)
    }
}
//输出结果:0-9的平方
1.1.5 并发安全Lock

2.1 依赖管理

2.1.1 GOPATH

GO语言支持的一个环境变量。

image.png 弊端:project A和project B依赖于同一package的不同版本,前后不兼容,无法实现多版本控制。

2.1.2 Go Vendor
  • 解决的GOPATH的弊端:通过每个项目引入一份依赖的副本
  • 依赖寻址方式:vendor=>GOPATH

image.png 弊端:无法控制依赖的版本;更新的项目可能出现依赖冲突,导致编译出错。

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

依赖配置:go.mod

image.png

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

3.1单元测试

3.1.1 单元测试-规则
  • 所有测试以_test.go结尾
  • func TestXxx(*testing.T)
  • 初始化逻辑放到TestMain中

image.png

例子:

func HelloTom() string {
    return "Jerry"
}

func TestHelloTom(t *testing.T) {
    output := HelloTom()
    expectOutput := "Tom"
    if output ≠ expectOutput {
        t.Errorf("Expected %s do not match actual %s", exprctOutput, output)
    }
}

3.2 单元测试-assert

image.png

3.3 单元测试-覆盖率

第一个函数对于isPass的判断是true,第二个函数对于isPass的判断是false,所以函数覆盖率上升为100% image.png

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

3.4 单元测试-依赖

3.4.1 单元测试-文件处理
3.4.2 单元测试-Mock

快速Mock函数

  • 为一个函数打桩
  • 为一个方法打桩 用一个函数A去替换函数B,那B就是原函数,A就是打桩函数。

3.4 基准测试

内置的测试框架提供了基准测试的能力。

//随机选择执行服务器
import (
    "math/rand"
)

var ServerIndex [10]int

func InitServerIndex() {
    for i :=0;i<10;i++ {
        ServerIndex[i] = i+100
    }
}

func Select() int {
    return ServerIndex[rand,Intn(10)]
}

基准测试运行

func BenchmarkSelect(b *testing.B) {
    InitServerIndex()
    b.ResetTimer()
    for :=0;i<b.N;i++ {
        Select()
    }
}

func BenchmarkSelectParallel(b *testing.B) {
    InitServerIndex()
    b.ResetTimer()
    b.RunParallrl(func(pb *testing.PB) {
        for pb.Next() {
            Select()
        }
    }
}

运行结果: BenchmarkSelect-12为18.77 ns/op BenchmarkSelectParallel为79.42 ns/op

个人总结(想法)

go语言其实跟我学的第一门语言C++还是很像的,虽然学起来知识量很多,但是脑子不会像初学一样炸炸的,加油!!!