Go语言进阶 | 青训营

63 阅读2分钟

Go语言进阶

并发和并行

并发:多线程程序在一个核的cpu上运行;

并行:多线程程序在多个核的cpu上运行

协程和线程

协程:用户态,轻量级线程,栈的开辟大小为KB级别;

线程:内核态,一个线程可以跑多个协程,栈的开辟大小为MB级别;

协程的调用

调用协程时只需在函数前加上go关键字就可以。

fmt.Println("hello go :", i)  
}  
  
func main() {  
for i := 0; i < 5; i++ {  
go func(j int) {  
hello(j)  
}(i)  
}  
time.Sleep(time.Second)  
}

协程间的通信

(1)通过通信实现共享内存;(2)通过共享内存实现通信。但提倡通过通信共享内存而不是通过共享内存实现通信。原因是后者会存在资源的竞争,需要使用锁,但这样就会影响程序的性能。

Channel类型

需要通过make关键字进行构造。make(chan 元素类型,[缓冲大小]),通过缓冲大小分为无缓冲通道->make(chan int),有缓冲通道->make(chan int,2)。

并发安全Lock

在通过共享内存实现通信时,不可避免的就是要保证共享内存的数据安全,这里就要通过锁机制来进行保护。

WaitGroup

由于无法确定子协程结束的精确时间,在上述代码中都用到sleep,但这样做并不好,所以就需要WaitGroup。WaitGroup内部维护一个计数器,计数器个数代表运行的协程的个数,从而通过计数器来确定子协程是否还存在。

var wg sync.WaitGroup  
wg.Add(5)  
for i := 0; i < 5; i++ {  
go func(j int){  
defer wg.Done()  
hello(j)  
}(i)  
}  
wg.Wait()
}

Go依赖管理演进

GOPATH->Go Vendor->Go Module

不同环境依赖不同的版本

GOPATH下有三个文件bin(项目编译的二进制文件)、pkg(项目编译的中间产物,加速编译)、src(项目源码)

Go Vendor在项目目录下增加vendor文件,依赖寻址方式:vendor=>GOPATH

Go Module通过go.mod文件管理依赖包版本,通过go get/go mod指令工具管理依赖包

Go的依赖配置会选择最低的兼容版本,子项目分别依赖v1.3和v1.4,会选择v1.4版本

依赖分发->Proxy->可靠稳定

依赖分发-变量 GOPROXY="proxy1.cn,https://proxy2.cn,…" 服务站点URL列表,"direct"表示源站

测试

回归测试、集成测试、单元测试;从左往右覆盖率逐渐变大,成本逐渐降低

单元测试规则:(1)所有的测试文件以_test.go结尾;(2)测试函数->func TestXxx(* testing.T);(3)初始化逻辑放到TestMain中。