这是我参加「第五届青训营」笔记创作活动的第一天
概要
1、并发编程
2、依赖管理
3、测试
4、实战
一、并发编程
1、协程
协程是轻量级线程,一个线程可以拥有多个协程
相比于线程,协程的优势在于协程的切换发生在用户态,大大减少了切换所带来的开销
使用goroutine创建协程
可以使用go关键字创建协程,如下
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
2、协程间通信
使用通信共享内存
channel 是Go语言提供的协程间的通信方式,我们可以使用 channel 在两个或多个 goroutine 之间传递消息。
channel需要使用make函数进行初始化
var chan0 chan int //声明一个channel
chan1 := make(chan int) //声明一个不带缓冲区的channel
chan2 := make(chan int, 3) //声明一个缓冲区大小为3的channel
chan3 := make(chan int, 0) //声明一个不带缓冲区的channel
channel函数有两个参数,第一个参数指传递的值的类型,第二个参数为通道缓冲区的大小,为0和不加参数时,将创建一个不带缓存区的channel
chan1 <- 1 //发送数据
x := <- chan1 //接收数据
使用不带缓冲区的channel,发送数据后发送方将阻塞,直到接收方接收通道内的数据
使用带有缓冲区的channel时,当缓冲区被填满后,发送方才会阻塞
使用共享内存进行通信
使用锁对临界区加锁以保证并发安全
var lock sync.Mutex //声明一个锁
lock.Lock() //加锁
lock.Unlock //解锁
WaitGroup计数器
WaitGroup对开启的协程计数,每开启一个协程计数器加一,关闭一个协程计数器减一,主协程将阻塞直到计数器归零
var waitgroup sync.WaitGroup //声明一个计数器
waitgroup.Add() //计数器加一
waitgroup.Done() //计数器减一
waitgroup.Wait() //主协程阻塞直到计数器归零
二、依赖管理
使用go modules进行依赖管理
依赖管理三要素:
1、配置文件 ---- go.mod
2、中心仓库 ---- Proxy
3、本地工具 ---- go get/mod
初始化配置文件:
go mod init
执行该命令将会生成go.mod文件
配置中心仓库:
GOPROXY="https://goproxy.cn,direct"
使用go get 获取依赖
go get xxxxx(目标依赖地址)
三、项目测试
测试类型分为三种:回归测试、集成测试、单元测试
1、单元测试
测试文件需要以_test.go结尾
测试函数声明应满足以下格式,否则编译器无法识别
func TestXxx(*testing.T)
测试初始化逻辑放在TestMain下
启动测试文件命令不再是go run xxx.go而是go test xxx.go
使用覆盖率来衡量项目的测试水准,测试覆盖率应该至少保持在50%以上,尽量全面的覆盖测试分支
Mock机制
为了避免在测试过程中,被测函数中特定的操作对测试代码或测试数据的依赖,可以使用Mock替换掉被依赖的代码或数据
使用Mock函数进行打桩
mock.Patch(target,replacement) //target为目标函数,replacement为替代函数
在代码执行过程中,replacement函数将替代target函数
mock.Unpatch(target) //解除
基准测试
主要测试当前代码的性能以及CPU的损耗
与单元测试类似,测试函数需要满足以下形式
func Benchmarkxxx(*testing.B)
项目实战
项目主要基于gin框架,分为三层结构
数据层:主要实现数据的读取,以及索引的组建
逻辑层:对传入数据的验证以及拼装传出数据的拼装
视图层:对客户端交付数据
需要注意的是,使用c.JSON()函数交付数据时,需要保证结构体内各成员变量的首字母大写
小写字母属于私有变量,无法被包外方法访问,此时客户端无法接收到值!!!