这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记
01语言进阶
1.并发vs并行:
- 并发指的是多线程程序在一个核的cpu上运行;并行指的是多线程程序在多个核的cpu上运行
2.Goroutine:
- 协程:用户态,轻量级线程,栈MB级别
- 线程:内核态,线程跑多个协程,栈KB级别
3.CSP(Communicating Sequential Processes):
- (提倡)通过通信共享内存:Gorountine1 ->通道->Gorountine2/Gorountine3
- 通过共享内存实现通信:Gorountine1->临界区<-Gorountine2/Gorountine3
4.Channel
- make(chan 元素类型,[缓冲大小])
- 无缓冲通道 make(chan int)
- 有缓冲通道 make(chan int,cap)
- 无缓冲通道示例:
Goroutine1
Goroutine2
- 有缓冲通道示例:
Goroutine1
缓冲区
Goroutine2
5.并发安全Lock
- 使用sync库里的 sync.Mutex
- 设置锁 例如 var lock sync.Mutex
- 上锁:lock.Lock() 开锁lock.Lock()
6.WaitGroup
- Add(delta int) 计数器+delta
- Done() 计数器-1
- Wait() 阻塞计时器为0
02依赖管理
依赖管理三要素
- 配置文件,描述依赖 go.mod
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod
依赖分发-回源
- 无法保证构建稳定性(增加/修改/删除软件版本)
- 无法保证依赖可用性(删除软件)
- 增加第三方压力(代码托管平台负载问题)
依赖分发-Proxy
Github/SVN/..
Proxy
Developer
依赖分发-变量GOPROXY GOPROXY="proxy1.cn,https://proxy2.cn,…" 服务站点URL列表,"direct"表示源站
Proxy1
Proxy2
Direct
工具-go get
- go get example.org/pkg + @update 默认
- go get example.org/pkg + @none 删除依赖
- go get example.org/pkg + @v1.1.2 tag版本,语义版本
- go get example.org/pkg + @23dfdd5 特定的commit
- go get example.org/pkg + @master 分支的最新commit
工具-go mod
- go mod + init 初始化,创建go.mod文件
- go mod + download 下载模块到本地缓存
- go mod + tidy 增加需要的依赖,删除不需要的依赖
03测试
回归测试->集成测试->单元测试
- 单元测试:输入->测试单元(函数、模块...)->输出|与期望进行校对
-
单元测试-规则:
- 所有测试文件以_test.go结尾
- func TestXxx(t *testing.T)
- 初始化逻辑放到TestMain中
-
单元测试-assert
- 引入包 go get -u github.com/stretchr/testify/assert
- 判断相等 assert.Equal(t,expectOutput,output)
-
单元测试-覆盖率
- 一般覆盖率:50%~60%,较高覆盖路80%+
- 测试分支相互独立、全面覆盖
- 测试单元粒度足够小,函数单一职责
-
单元测试-依赖
单元
File/DB/Cache
幂等&稳定
Mock
外部依赖
稳定&幂等
-
基准测试
- 优化代码,需要对当前代码分析
- 内置的测试框架提供了基准测试的能力
04项目实战
-
需求设计:
-
社区话题页面:
- 展示话题和回帖列表
- 暂不考虑前端页面实现,仅仅实现一个本地web服务
- 话题和回帖数据用文件存储
-
需求用例
- 用户->主题/回帖
- Topic:id,title,content,create_time
- Post :id,topic_id,content,create_time
-
TopicPostplaces
- 分层结构
File->Repository|Model|(数据层)->Service|Entity|(逻辑层)->Controller|View|(视图层)->Client
-
数据层:数据Model,外部数据的增删改查 复制代码 -
逻辑层:业务Entity,处理核心业务逻辑输出 复制代码 -
视图层:视图View,处理和外部的交互逻辑 复制代码 - 代码开发
- 测试运行