进阶Go语言| 青训营笔记

50 阅读2分钟

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

并发

协程可以看作轻量级的线程。

Goroutine

go在创建协程只需要在调用函数时在函数前加go

  func hello(i int){  
   *******
   }  
  func HelloGoroutine(){
     for   ;  ;  {
     go func(j int){
          hello(j)
          }(i)
     }
   }

WaitGroup ,信道(channel),lock

常见的 3 种并发控制的方式

channel分为有缓存通道和无缓存通道make(chan,[缓存大小])

lock对协程临界区加一层保护,提供一个缓冲区保证程序在并行的时候不会出错。

lock.lock()
  *****
  lock.unlock()

如果并发启动了多个子协程,需要等待所有的子协程完成任务,WaitGroup 非常适合于这类场景wg.Wait() 会等待所有的子协程任务全部完成,所有子协程结束后,才会执行 wg.Wait() 后面的代码。waitGroup提供三种方法对协程进行控制。

  1. add(delta int ) 计数器加上delta的值
  2. Done() 计数器减一
  3. Wait() 阻塞直到计数器为0 WaitGroup 只能等待子协程结束,但是并不能主动通知子协程退出。

测试

单元测试

单元测试是一个优秀项目不可或缺的一部分,特别是在一些频繁变动和多人合作开发的项目中尤为重要。

规则

  1. 测试文件以 _test.go 结尾
  2. func TestXxxx(t *Testing.T)
  3. 初始化逻辑放在TestMain中 go test -v-v 参数会显示每个用例的测试结果,另外 -cover 参数可以查看覆盖率。一般覆盖率在50-60,高效覆盖率在80+。

Benchmark 基准测试

基准测试用例的定义如下:

func BenchmarkName(b *testing.B){
    // ...
}
```
1.   函数名必须以 `Benchmark` 开头,后面一般跟待测试的函数名
2.   参数为 `b *testing.B`。
3.   执行基准测试时,需要添加 `-bench` 参数。

基准测试报告每一列值对应的含义:
```
type BenchmarkResult struct {
    N         int           // 迭代次数
    T         time.Duration // 基准测试花费的时间
    Bytes     int64         // 一次迭代处理的字节数
    MemAllocs uint64        // 总的分配内存的次数
    MemBytes  uint64        // 总的分配内存的字节数
}
```