这是我参与「第五届青训营 」伴学笔记创作活动的第1天
本堂课重点内容
- 并发编程
- 协程Goroutine
- 通道Channel
- 锁Lock
- 线程同步WaitGroup
- 依赖管理
- Gopath
- Go Vendor
- Go Module
- 单元测试(略)
- 单元测试概念和规则
- Mock测试
- 基准测试
详细知识点介绍
并发编程
go语言运行时可以创建上万个协程,因此go语言开发适合高并发场景。
相关概念
- 线程:内核态,CPU调度和分派的基本单位,是比进程更小的能独立运行的基本单位,一个进程可以由多个称为线程的执行单元组成,多线程比多进程之间更容易共享数据,在上下文切换中线程一般比进程更高效。
- 协程:用户态下的线程,goroutine的调度开销远远小于线程调度开销,用户可以自行控制协程的创建于销毁,极大程度避免了系统级线程上下文切换造成的资源浪费
- 进程:进程是操作系统对一个正在运行的程序的一种抽象,进程是资源分配的最小单位
- CSP:go提倡通过通信共享内存方式(CSP)
- Channel:make(chan int, [cacheSize])有size参数的为有缓存通道,无参数为无缓存通道
依赖管理
依赖管理三要素
- go.mod 配置文件,依赖描述
- Proxy中心管理依赖库
- 本地文件 go get/mod
单元测试
实践练习例子
- 协程输出
package main
import "time"
func hello(i int) {
println("hello goroutine: ", i)
}
func main() {
println("hello test")
count := 5
for i := 0; i < count; i++ {
go func(j int) { // 在函数内调用函数时,在func关键字前加go关键字即可
hello(j)
}(i)
}
time.Sleep(time.Second)
}
- 并发锁
package main
import (
"sync"
"time"
)
var (
x int64 // 全局变量
lock sync.Mutex
)
func addWithLock() {
for i := 0; i < 2000; i++ {
lock.Lock() // 开启锁
x += 1
lock.Unlock() // 释放锁
}
}
func Add() {
x = 0
for i := 0; i < 5; i++ {
go addWithLock()
}
time.Sleep(time.Second)
println("result: ", x)
}
func main() {
Add()
}
result: 10000
- 生产消费模型
package main
func CalSquare() {
src := make(chan int)
dest := make(chan int, 3)
go func() {
defer close(src)
for i := 0; i < 10; i++ {
src <- i
}
}()
go func() {
defer close(dest)
for i := range src {
dest <- i * i
}
}()
for i := range dest {
println(i)
}
}
func main() {
CalSquare()
}
课后个人总结
本节课主要学习了并发编程的基本概念与依赖管理,由于时间关系,主要是根据视频课程,结合网上搜索到的一些资源进行学习。