资料
1 - 语言进阶
1.1 - 并发与并行

并发:在一个CPU核心上通过分时处理达到一起运行的效果
并行:CPU有多个核心,不需要划分
1.2 - Goroutine
协程:用户态,轻量级的线程,栈MB级别
线程:内核态,线程可以跑满多个协程,栈KB级别
开启协程语法:
go funcName() // 将函数交给 gorouine 处理1.3 - CSP(Communication Sequential Process)

通道(channel):让 goroutine 发送特定值到另一个 goroutine 的机制,保证数据的先入先出。
后者,共享内存实现通信的话需要加锁,产生数据竞争的问题
1.4 - Channel

创建方式:
// 创建语法
make(chan 元素类型, [缓冲大小])
// 无缓冲,也被称为同步通道
make(chan int)
// 有缓冲。典型生产消费模型
make(chan int, 2)Example
package main
import "fmt"
func CalSquare() {
src := make(chan int)
// B 和 M 之间的执行效率差距,M可能很复杂,需要缓冲区
dest := make(chan int, 3)
go func() {
// A, 生产数字并将数字发送到 src channel
defer close(src)
for i := 0; i < 10; i++ {
src <- i
}
}()
go func() {
// B, 从 A 协程读取,计算 i*i 并传到 dest channel
defer close(dest)
for i := range src {
dest <- i * i
}
}()
for i := range dest {
// M
// 复杂的逻辑
fmt.Println(i)
}
}
func main() {
CalSquare()
}1.5 - 并发安全Lock
TODO
2 - 依赖管理
工程项目不能完全基于标准库从零搭建,需要管理依赖库
2.1 - Go 依赖管理演进
GOPATH → Go Vendor → Go Module
GOPATH
所有项目放到 GOPATH 下面的 src 目录下面
缺点:不利于多版本管理

Go Vendor
- 为了解决多版本依赖,在项目文件下新增 vendor 文件夹,将项目依赖以副本形式放到里面
- 每个项目引入一个依赖的副本
但是vendor还是依赖源码,还是会出现问题

Go Mod
- 通过 go.mod 文件管理依赖包版本
- 通过
go get XXX指令管理依赖包 - 可以定义版本规则和依赖关系
2.2 - 依赖管理三要素
- 配置文件:go.mod
- 中心仓库:Proxy
- 本地工具:go get

Indirect 关键字:不是直接依赖的库,是依赖的依赖
incompatible关键字:没有gomod文件且主版本2+的依赖
go在处理不同依赖时会选择最低兼容版本
依赖分发:
goproxy会缓存源站点的内容,goproxy保证不会修改软件源代码,降低了github等平台的压力。
配置 GOPROXY:
$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,directGomod命令行


3 - 测试

回归测试:比如人工刷一下抖音,看看相关功能
集成测试:通过暴露的某个接口做自动化的测试
单元测试:开发者对单独函数模块做验证
3.1 - 单元测试

通过一个个的单元测试,保证代码的可用性
单元测试规则
- 测试文件以
***_test.go命名 - 测试函数以
func TestXXX(*testing.T)命名 - 测试初始化放到
TestMain中 - 使用
go test [flags] [packages]运行测试
单元测试覆盖率
覆盖率越完备,那么代表程序越稳定

上面的代码只执行了3个语句中的两行,所以代码覆盖率为 66.7%,如果新增测试使得返回 false,覆盖率就是100%了
Tips
- 一般覆盖率:50%-60%,较高覆盖率80%
- 测试分支相互独立、全面覆盖
- 单元测试粒度足够小,意味着函数的职责单一
单元测试依赖

如果单元测试需要mysql、redis或者文件等的输入,因此单元测试的结果和mysql、redis相关了。
我们需要测试在任何时间,任何地点都可靠。这时需要使用mock机制,使用预先设置的假数据
常用的mock库是monkey:https://github.com/vektra/mockery
example:

patch可以篡改原来的函数,实现mock功能
3.2 - 基准测试
语法:
BenchmarkXXX(*testing.B)函数b.ResetTimer()重置时间,表示忽略函数之前的动作耗时b.RunParallel(func)并行运算
4 - 项目实战
一个社区话题页面