Go进阶与依赖管理|青训营笔记

46 阅读1分钟

Golang进阶

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

1.1 Goroutine

  • 协程与线程的区别
    • 协程:用户态,轻量级线程,栈KB级别。
    • 线程:内核态,一个线程可以跑多个协程,栈MB级别。
  • 使用go关键字创建一个goroutine
  • 示例
    func main() {
        go func() {}
    }
    

1.2 channel

  • 创建一个channel make(chan 元素类型,缓冲大小)
    • 无缓冲管道:make(chan 元素类型)
    • 有缓冲管道:make(chan 元素类型,整数值)
package concurrence

func CalSquare() {
   src := make(chan int)
   dest := make(chan int, 3)
   go func() {
      defer close(src)
      for i := 0; i < 10; i++ {
         src <- i
      }
   }()
   go func() {
      defer close(dest)
      for i := range src {
         dest <- i * i
      }
   }()
   for i := range dest {
      println(i)
   }
}

1.3 并发安全Lock

  • 锁的作用:保护临界区代码执行的原子性,保证并发安全。
  • golang中的锁:读写锁和互斥锁
  • 死锁示例:
    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    var l sync.RWMutex
    
    func main() {
        go readAndRead()
    
        time.Sleep(1 * time.Second)
        l.Lock()
        fmt.Println("----------------- got lock")
        l.Unlock()
    
        time.Sleep(5 * time.Second)
    }
    
    func readAndRead() {
        l.RLock()
        fmt.Println("----------------- got rlock")
        time.Sleep(10 * time.Second)
        fmt.Println("----------------- 10s passed")
    
        l.RLock()
        fmt.Println("----------------- got 2nd rlock")
    
        l.RUnlock()
        l.RUnlock()
    }
    
    /* shell 执行 `go run main.go` 的结果为:
       ----------------- got rlock
       ----------------- 10s passed
       fatal error: all goroutines are asleep - deadlock!
       ...
    */
    

依赖管理

2.1 golang依赖管理严禁

  • GOPATH
    • 环境变量$GOPATH
    • 项目代码直接依赖src下的代码
    • go get 下载最新版本的包到src目录下
  • Go Vendor
    • 项目目录下增加vendor文件,所有依赖包副本形式放在$ProjectRoot/vendor
    • 依赖寻址方式:vendor => GOPATH
  • Go Module
    • 通过go.mod文件管理依赖包版本
    • 通过go/get/go mod指令工具管理依赖包

2.2 依赖管理三要素

  • 配置文件,描述依赖 --go.mod
    module xxx 依赖管理基本单元
    
    go 1.1x 原生库
    
    require ( 单元依赖
        example/lib1 v1.0.2
    )
    
  • 中心仓库管理依赖库 --proxy
  • 本地工具 --get/mod

测试

3.1 单元测试

  • 单元测试-规则
    • 所有测试文件以_test.go结尾
    • func TestXXX(*testing.T)
    • 初始化逻辑放到TestMain中
  • 单元测试-assert
    • "github.com/stretchr/testify/assert"
  • 单元测试-覆盖率
  • 单元测试-依赖
  • 单元测试-文件处理
  • 单元测试-Mock
  • 单元测试-基准测试