这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
今天学习了golang并发,依赖管理,测试的内容
并发
首先了解了什么是协程
- 协程:用户态,轻量级线程,栈KB级别
- 线程:内核态,一个线程能跑多个协程,栈MB级别
go语言能同时跑上万个协程
了解了Channel
在golang中提倡通过通信共享内存,而不是通过共享内存实现通信
Go提供了一种称为通道的机制,用于在goroutine之间共享数据。当您作为goroutine执行并发活动时,需要在goroutine 之间共享资源或数据,通道充当goroutine之间的管道(管道)并提供一种机制来保证同步交换。
从接收与发送分为三种通道
chan T // 可以接收和发送类型为 T 的数据
chan<- float64 // 只可以用来发送 float64 类型的数据
<-chan int // 只可以用来接收 int 类型的数据
缓存方面通道分为有缓存通道与无缓冲通道
//无缓存
ch := make(chan int, 100)
//有缓存
ch = make(chan int, 100)
sync.WaitGroup Go语言中可以使用sync.WaitGroup来实现并发任务的同步。sync.WaitGroup内部维护着一个计数器,计数器的值可以增加和减少。例如当我们启动了N 个并发任务时,就将计数器值增加N。每个任务完成时通过调用Done()方法将计数器减1。通过调用Wait()来等待并发任务执行完,当计数器值为0时,表示所有并发任务已经完成。
var wp sync.WaitGroup
func showMsg(i int) {
// defer wp.Add(-1)
defer wp.Done()
fmt.Printf("i: %v\n", i)
}
func main() {
for i := 0; i < 10; i++ {
//启动一个协程
go showMsg(i)
//任务开始的时候+1
wp.Add(1)
}
//阻塞直到计数器变为0
wp.Wait()
//主协程
fmt.Println("end...")
}
测试
单元测试
- 所有测试文件以_test.go结尾
- 测试函数命名规范 func TestXxx(*testing.T)
- 单元测试提供一个TestMain,单元测试的初始化逻辑都放到TestMain中
例如
待测试函数
package Service
func HelloTom() string {
return "Tom"
}
测试函数
package Service
import "testing"
func TestTomHi(t *testing.T) {
output := HelloTom()
expectOutPut := "Jam"
if output != expectOutPut {
t.Errorf("Exceptd %s do not match %s", expectOutPut, output)
}
}
也可以使用开源的组件assert进行判断
package MyMath
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestCompare(t *testing.T) {
res := Compare(70)
except := true
assert.Equal(t, except, res)
}
覆盖率
- 一般覆盖率:50%~60%,较高覆盖率80%
- 测试分支相互独立,全面覆盖
- 测试单元粒度足够小,函数单一职能
基准测试
基准测试是测量一个程序在固定工作负载下的性能。
其中ns/op表示每次操作所消耗的纳秒