这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记」
1 语言进阶
并发编程,go高性能的本质
1、并发vs并行 并发:多线程程序在一个核cpu上运行,时间片切换 并行:多线程程序在多核上运行 go可充分发挥多核优势 -为什么go可以充分利用多核的优势,而其他语言像java,无法充分利用
go中的重要概念-协程
(goroutine) 协程:用户级线程,比线程更加轻量,用户态,轻量级线程,栈MB级别 线程:内核态,线程跑多个协程,栈KB级别
go 如何开启协程?
go func(参数){
func
}(参数)
CSP(communicating sequential processes)协程间的通信
通过”通信共享内存“实现,channel(通道)-队列、有序 共享内存-临界区-加锁,影响性能
Channel
无缓冲通道-同步通道 make(chan int)
有缓冲通道(解决同步问题,典型的生产消费者模型 确保生产一个-》使用一个)make(chan int,2)
小例子1 channel
src、dest 两个channel,
dest用的是有缓冲的队列,消费者的消费速度可能会慢些,生产者逻辑比较简单可以快速。
defer close 延迟的资源关闭
并发安全 Lock
lock sync.Mutex
lock.Lock()
临界区代码
lock.Unlock()
WaitGroup 同步
用sleep比较暴力,go中用WaitGroup实现并发同步,维护一个计数器
计数器:Add(delta)开启协程+1(delta-开几个协程),Done()执行子协程后结束-1,Wait()主协程阻塞直到计数器为0
2 依赖管理
演进:gopath -> go vender -> go mod 实现对不同环境依赖的版本的不同,控制依赖版本
依赖配置 配置文件go.mod
版本选择算法:选最低的兼容版本
中心仓库管理依赖库Proxy
依赖分发:表示去哪下载依赖,如何下载
proxy-服务站点,缓存软件版本
项目设计:加适配器proxy,加1层解决不了 加2层 等等
项目查找依赖的路径,proxy1中找不到-》去2,再找不到-》去direct
类比模式:redis缓存找不到-》数据库缓存
本地工具-go get, go mod
3 测试
单元测试
mock测试
单元测试需要满足:
稳定:相互隔离,能在任何时间任何环境运行测试。
幂等:每一次测试运行都应该产生与之前一样的结果。
采用mock机制实现。
代码有依赖,修改后单元测试可能不能运行了
eg:单元测试需要依赖本地文件A,A修改或删除后,测试失效
为了保证测试case的稳定性,对读取文件函数进行mock,屏蔽对于文件的依赖。
target-原函数,replacement-打桩函数
patch打桩,unpatch卸桩
举例:打桩函数内设计类似功能和处理结果,原函数依赖本地log文件内容,如果log文件修改,测试失效。
基准测试
对代码进行性能分析,从而优化代码
4 项目实战
需求拆分、逻辑设计(⚠️)
vscode最好直接从git仓库拷贝创建项目,不在cmd里git clone-vscode没有加path import会报错??
git branch -a
git checkout origin/V0
go mod init
go get gopkg.in/gin-gonic/gin.v1@v1.3.0
go run server.go
运行结果:
curl 或者浏览器查看