这是我参与「第五届青训营 」伴学笔记创作活动的第2天。
1语言进阶
并发
1多线程程序在一个核的cpu上运行
并行
2多线程程序在多个核的cpu上运行
Go可以充分发挥多核优势高效运行
1.1Goroutine
协程:用户态,轻量级线程,栈KB级别
线程:内核态,线程跑多个协程,栈MB级别
快速 打印 快速提示用多协程
在调用函数前加go关键字
为函数创建协程来运行
time.Sleep()保证子协程执行完之前主协程不退出
乱序输出
1.2 CSP
提倡通过通信共享内存而不是通过共享内存实现通信
通道Channel 队列 提倡
获取临界区 权限 影响程序性能
1.3Channel
引用类型
make(chan 元素类型,[缓冲大小])
分为有无缓冲通道
无缓冲 也称为同步通道
带缓冲解决 子协程 生产快 消费慢 不均衡带来的执行效率问题
defer 延迟资源关闭
通信实现共享内存
1.4 并发安全Lock
多个goroutine同时操作内存资源
lock sync.Mutex
+1前用lock.Lock()获取临界区资源
计算完将临界区权限释放
并发安全问题概率出现 难定位 避免对共享内存进行非并发安全读写操作
1.5WaitGroup
三个方法 Add(delta int) 计数器+delta Done() 计数器-1 Wait() 阻塞直到计数器为0
实现并发任务同步
小结
Goroutine 协程 高并发操作
Channel 通过通信共享内存
Sync包下关键字 并发安全操作 协程同步
2依赖管理
2.0背景
工程项目不肯基于标准库0~1编码搭建
管理依赖库
2.1Go依赖管理演进
GOPATH Go Vendor Go Module
不同环境项目依赖版本不同
控制依赖库的版本
2.1.1GOPATH
环境变量$GOPATH
bin 项目编译的二进制文件 pkg 项目编译中间产物,加速编译 src 项目源码
项目代码直接依赖src下的代码
go get下载最新版本的包到src目录下(1.17不能安装可执行文件 可管理依赖)
GOPATH弊端
A/B依赖某package不同版本 无法实现package的多版本控制
2.1.2 Go Vendor
项目目录下增加vendor文件,所有依赖包副本形式放在$ProjectRoot/vendor
项目依赖寻址方式:vendor=>GOPATH
通过每个项目引入一份依赖的副本 解决了多个项目需要同一个package依赖的冲突问题
问题:无法控制依赖的版本
更新项目又可能出现依赖冲突,导致编译出错
2.1.3 Go Module
通过go.mod文件管理依赖包版本
通过go get/go mod 指令工具管理依赖包
终极目标:定义版本规则和管理项目依赖关系
1.配置文件,描述依赖 go.mod 2.中心仓库管理依赖库 Proxy 3.本地工具 go get/mod
2.3.1依赖配置 go.mod
模块路径 依赖管理基本单元
原生库
单元依赖
-version
语义化版本
MAJOR 大版本 不兼容
MINOR 新增函数功能在MAGOR下兼容
PATCH 代码bug修复
基于commit伪版本 版本前缀 时间戳 哈希码前缀
-indirect
A->B->C
A->B直接依赖
A->C间接依赖 没有直接导入会标识为非直接依赖
-incompatible
主版本2+模块会在模块会在模块路径加/vN后缀
对于没有go.mod文件并且主版本2+的依赖 会+incompatible
2.3.5 依赖分发-回源
依赖分发-Proxy
-变量GOPROXY
PROXY1 ->Proxy2 ->Direct
2.3.工具-go get
go get example.org/pkg
@update 默认 @none 删除依赖 @v1.1.2 tag版本,语义版本 @23dfdd5 特定commit @master 分支最新commit
2.3.8 go mod
init 初始化,创建go.mod文件 download 下载模块到本地缓存 tidy 增加需要的依赖,删除不需要的依赖
依赖管理三要素
1配置文件,描述依赖 go.mod
2中心仓库管理依赖库 Proxy
3本地工具 go get/mod
3测试
回归测试
集成测试
单元测试
3.1单元测试
3.1.1单元测试-规则
测试文件以_test.go结尾
func TestXxx(*testing.T)
初始化逻辑放到Testmain中 测试前:数据装载、配置初始化等前置工作 测试后:释放资源等收尾工作
3.1.2单元测试-例子
-运行
-assert
-覆盖率
-tips
一般覆盖率50~60% 较高80%+
测试分支相互独立、全面覆盖
测试单元粒度足够小,函数单一职责
-依赖
外部依赖=>稳定&幂等
-文件处理
-mock
开源包monkey
快速Mock函数 为一个函数打桩 为一个方法打桩
3.5基准测试
优化代码,需要对当前代码分析
内置测试框架提供基准测试能力
fastrand
4项目实战
4.1需求描述
Entity Relationship Diagram
4.4分层结构
数据层Repository:数据Model,外部数据增删改查
逻辑层Service:业务Entity,处理核心业务逻辑输出
视图层:视图view,处理和外部的交互逻辑
4.5组件工具
Gin高性能go web框架
Go Mod
go mod init
go get
4.6Repository
-index
4.7Service
4.8Controller
4.9Router
4.10运行
小结
项目拆解
代码设计
测试运行