Go语言高级应用 / 工程实践相关 | 青训营笔记

126 阅读3分钟

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

1.本堂课重点内容

  • Go并发编程技术
  • Go项目测试技术
  • Go第三方库的管理
  • Go后端开发流程简述

2.详细知识点介绍

main包 / main函数

main包比较特殊。它定义了一个独立可执行的程序,而不是一个库。在main里的main 函数 也很特殊,它是整个程序执行时的入口

系统向程序传递参数时,使用 os.Args 读取

func main() {
    if len(os.Args) != 2 {
        // ...
    }
    word := os.Args[1]
}
​

Go并发编程

Go的并发多使用协程而非线程

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

并发协程间的数据通信

声明通道

无缓冲通道也称同步通道

有缓冲通道也称异步通道

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

使用通道时,协程间会互相等待

WaitGroup 计数器

Add(delta int) Done() Wait()

Go第三方库的管理

依赖包管理方案

GOPATH 直接依赖GOPATH目录下的源码。无法实现package的多版本控制

Go Vender 优先依赖项目目录下的vender文件,内含依赖包的副本。无法控制依赖版本,更新项目可能导致依赖冲突。

Go Module 通过go.mod文件管理依赖包版本,定义版本规则和管理项目依赖关系。

依赖管理三要素:配置文件,描述依赖 / 中心仓库管理依赖库 / 本地工具

version - go.mod文件

语义化版本MAJOR.{MAJOR}.{MINOR}.${PATCH}

基于commit伪版本vx.0.0-yyyymmddhhmmss-xxxxxxxxxxxx

间接依赖会增加 // indirect 后缀

主版本2+模块会在路径后增加 /vN 后缀

没有go.mod文件并且主版本2+的依赖会增加 +incompatible 后缀

如果项目依赖某个组件的两个版本,则系统选择满足构建的最低兼容版本。

其他

依赖分发代理 GOPROXY="URL1, URL2, direct"

工具 go get / go mod

项目测试

测试:回归测试 / 集成测试 / 单元测试

在包目录内,所有以_test.go结尾的源文件是go test测试的一部分。

单元测试函数 func TestXxx(t *testing.T) {}

基准测试函数 func BenchmarkXxx(b *testing.B) {}

并行基准测试逻辑

func BenchmarkXxx(b *testing.B) {
    // 初始化
    b.ResetTimer()
    b.RunParallel(func(pb *testing.PB) {
        for pb.Next() {
            // 被测函数
        }
    })
}

初始化逻辑 (可选)

func TestMain(m *testing.M) {
    // 数据装配、配置初始化
    code := m.Run()
    // 释放资源,收尾
    os.Exit(code)
}

单元测试第三方包 - assert

github.com/stretchr/testify/assert

go test [flags] [package]

go test [flags] [package] --cover 单元测试 - 覆盖率

go test -bench= 基准测试

单元测试技巧

测试分支相互独立、全面覆盖

测试单元粒度足够小、函数单一职责

单元测试 - Mock:monkey

github.com/bouk/monkey

为函数/方法打桩:避免测试环境的改变。比如B函数使用A函数的返回值,但如果A函数改变则测试环境改变,因此使用其他函数替换A函数。

rand和fastrand

fastrand在并发环境中有更高的效率,但随机性会下降

3.实践联系例子

项目分层结构

数据层 / 逻辑层 / 视图层

Cookie / Session 和 token

cookie和session:涉及到数据的解密和存储

token:不太涉及到数据的存储

Scanner

Scanner提供了一个用于读取数据的简单接口,例如以换行符分隔的文本。对Scan方法的连续调用将逐步遍历文件中的‘标记’,并跳过标记之间的字节。