Golang·探索工程| 青训营笔记

104 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记

并发和并行

  • 并发:多线程程序在一个核的 cpu 上运行(轮流执行)
  • 并行:多线程程序在多个核心的 cpu 上运行(同步进行),可以理解为实现并发的一个手段
  • Goroutine
    • 协程:用户态,轻量级线程,栈 KB 级别
      • 创建一个协程:在调用函数的时候,在函数的前面加上一个 go 关键字
    • 线程:内核态,线程跑多个协程,栈 ,MB 级别
      • 创建、切换、停止都属于很重的系统操作,占用是兆级别
    • CSP:提倡通过通信共享内存而不是通过共享内存实现通信
      • 通信共享内存image.png
      • 共享内存实现通信image.png影响程序的性能
  • channel
    • make(chan 元素类型,[缓冲大小])
    • 无缓冲通道(同步通道),发送和接收同步
    • 有缓冲通道,需要有人生产和消费,如果没人消费(缓冲区填满了)那么就会阻塞生产。因此当消费比生产慢的时候,可以考虑使用有缓冲通道进行同步
  • 并发安全
    • 可以使用 sync.Mutex 获取到锁
    • 在执行需要考虑并发安全的函数的时候,可以考虑使用sync.Mutex.Lock()为其加锁,在函数执行结束后,使用 sync.Mutex.Unlock()为其解锁
  • WaitGroup
    • Add(delta int) 表示给计数器加上delta的数量
    • Done() 表示计数器-1
    • Wait() 表示会一直阻塞结束后续的进行直到计数器为 0

依赖管理

  • GOPATH

    • 项目代码会直接依赖于 src 下的代码
    • 导致的弊端:无法实现 package 的多版本控制,由于都是依赖于同一个 src 文件夹下的源码,可能会导致过去版本的一些函数由于升级被删除或修改
  • Go Vendor

    • 项目目录下增加 vendor 文件夹,所有依赖包副本形式放在 $Project/vendor
    • 寻址方式为:vendor=>GOPATH
    • 此时每个项目引入一份依赖的副本
    • 弊端:如果依赖之间互相不兼容,那么就可能导致依赖冲突进而导致编译出错
  • Go Module

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

    1. 配置文件,描述依赖:go.mod
      • 依赖标识:[Module Path][Version/Pseudo-version]
      • 语义化版本:${MAJOR}.${MINOR}.${PATCH}
        • MAJOR 表示大版本,不同的 MAJOR 间版本是隔离的
        • MINOR 表示新增功能,MINOR 彼此之间代码是可以兼容的
        • PATCH 负责代码块的修复
      • 基于 commit 伪版本:版本号-时间戳(yyyymmddhhmmss)-hashcode
      • indirect 表示非直接依赖
      • incompatible 表示可能存在不兼容的代码
      • 在选择版本的时候,会选择可以兼容的最低版本进行编译
    2. 中心仓库管理依赖库:Proxy
      • 使用版本管理工具下载依赖存在的问题
        • 无法保证构建稳定性
        • 无法保证依赖可用性
        • 增加第三方压力
      • Proxy 可以保证稳定和可靠
    3. 本地工具:go get/mod

测试

  • 回归测试
    • 通过终端回归一些特定的场景测试
  • 集成测试
    • 功能的测试
  • 单元测试
    • 开发者对函数的单个模块进行测试
    • 一般覆盖率50%-60%,较高覆盖率80%+
    • 测试分支相互独立全面覆盖
    • 测试单元粒度足够小
    • 函数单一职责
    • MOCK:
      • 幂等:重复测试结果应该是一样的
      • 稳定:单元测试之间相互隔离
      • 打桩测试:使得不需要对文件产生强依赖,打桩的主要原理是通过替换原本的测试集,使得需要测试的函数
  • 所有测试文件以 _test.go结尾,函数以 func TestXXX(*testing.T) 作为方法签名,初始化逻辑放到 TestMain 中