1.1 语言进阶
1.1.1 并发VS并行
并行:直接利用多核,实现多线程的同时运行。
并发:多线程在一个核的CPU上运行,主要是通过时间片的切换来实现同时运行的状态。
Go可以充分发挥多核优势,高效运行。
1.1.2 Goroutine
协程:用户态,轻量级线程,栈KB级别
线程:内核态,线程跑多个协程,栈MB级别
1.1.3 CSP
提倡通过通信共享内存,而不是通过共享内存实现通信。
1.1.4 Channel
make(chan 元素类型,[缓冲大小])
- 无缓冲通道 make(chan int)
- 有缓冲通道 make(chan int,2)
//主协程输出最后的平方数
func CalSqare() {
src :=make(chan int) //无缓冲队列
dest := make(chan int, 3) //有缓冲通道
go func() {
//A子协程发送0-9数字
defer close(src)
for i := 0; i < 10; i++ {
src ← i //把生产的数字发送到src的channel
}
}()
go func() {
//B子协程计算输入数字的平方
defer close(dest) //延迟关闭
for i := range src { //通过range遍历src里面的数据,通过src的channel就实现了A协程和B协程的通信
dest ← i * i //把i*i结果发送到desc的channel
}
}()
for i := range dest { //遍历dest的channel
//复杂操作
println(i)
}
}
//输出结果:0-9的平方
1.1.5 并发安全Lock
2.1 依赖管理
2.1.1 GOPATH
GO语言支持的一个环境变量。
弊端:project A和project B依赖于同一package的不同版本,前后不兼容,无法实现多版本控制。
2.1.2 Go Vendor
- 解决的GOPATH的弊端:通过每个项目引入一份依赖的副本
- 依赖寻址方式:vendor=>GOPATH
弊端:无法控制依赖的版本;更新的项目可能出现依赖冲突,导致编译出错。
2.1.3 Go Module
- 通过go.mod文件管理依赖包版本
- 通过go get/go mod指令工具管理依赖包
依赖配置:go.mod
依赖管理三要素: 1、配置文件,描述依赖 go.mod 2、中心仓库管理依赖库 Proxy 3、本地工具 go get/mod
3.1单元测试
3.1.1 单元测试-规则
- 所有测试以_test.go结尾
- func TestXxx(*testing.T)
- 初始化逻辑放到TestMain中
例子:
func HelloTom() string {
return "Jerry"
}
func TestHelloTom(t *testing.T) {
output := HelloTom()
expectOutput := "Tom"
if output ≠ expectOutput {
t.Errorf("Expected %s do not match actual %s", exprctOutput, output)
}
}
3.2 单元测试-assert
3.3 单元测试-覆盖率
第一个函数对于isPass的判断是true,第二个函数对于isPass的判断是false,所以函数覆盖率上升为100%
- 一般覆盖率50%-60%,较高覆盖率80%+
- 测试分支相互独立、全面覆盖
- 测试单元粒度足够小,函数单一职责
3.4 单元测试-依赖
3.4.1 单元测试-文件处理
3.4.2 单元测试-Mock
快速Mock函数
- 为一个函数打桩
- 为一个方法打桩 用一个函数A去替换函数B,那B就是原函数,A就是打桩函数。
3.4 基准测试
内置的测试框架提供了基准测试的能力。
//随机选择执行服务器
import (
"math/rand"
)
var ServerIndex [10]int
func InitServerIndex() {
for i :=0;i<10;i++ {
ServerIndex[i] = i+100
}
}
func Select() int {
return ServerIndex[rand,Intn(10)]
}
基准测试运行
func BenchmarkSelect(b *testing.B) {
InitServerIndex()
b.ResetTimer()
for :=0;i<b.N;i++ {
Select()
}
}
func BenchmarkSelectParallel(b *testing.B) {
InitServerIndex()
b.ResetTimer()
b.RunParallrl(func(pb *testing.PB) {
for pb.Next() {
Select()
}
}
}
运行结果: BenchmarkSelect-12为18.77 ns/op BenchmarkSelectParallel为79.42 ns/op
个人总结(想法)
go语言其实跟我学的第一门语言C++还是很像的,虽然学起来知识量很多,但是脑子不会像初学一样炸炸的,加油!!!