这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记
Go工程实践
并发编程
并发和并行的
- 并发:多线程在单核cpu运行时,通过时间片切换
- 并行:多个线程在多个cpu上执行
- Go语言可以充分发挥多核的优势
goroutine
开启多个协程打印数字:
```
func hello(i int) {
println("hello goroutine : " + fmt.Sprint(i))
}
func HelloGoRoutine() {
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
time.Sleep(time.Second)
}
```
执行结果:
可以看到并没有按顺序打印,而是几乎同时不按顺序打印的5个
CSP
- go语言提倡通过通信共享内存而不是共享内存通信
channel
- 无缓存channel:同步通道
- 有缓存channel:生产、消费模型,解决生产和消费不均衡带来的效率问题
- 一个channel的例子:构造一个src channel,一个dest channel, 向src channel里存数据i,取出后平方存入dest channel,取出dest中的数据并打印
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) }
sync
-
并发安全:不加锁会产生未知结果
-
WaitGroup 同步:这个例子中,用了waitGroup,使得主函数等待各个线程都执行完毕后才终止。
func ManyGoWait() { 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 Module 广泛应用于go依赖管理
- 通过 go.mod文件管理依赖包版本
- 通过go get/go mod指令工具管理依赖包
依赖管理三要素:
- 配置文件,描述依赖 go.mod
- 中心仓库管理依赖库 proxy
- 本地工具 go get/mod
在存在多个依赖版本的时候,go会选择最低兼容版本
可以设置一个1proxy,用来依赖分发:当proxy不可用时,才会用direct
测试
分为:
- 单元测试
- mock测试
- 基准测试
测试是避免事故的最后一道屏障
单元测试
所有单元测试的文件都以_test.go结尾
调用assert库执行assert方法,可以知道单元测试覆盖率。 一般覆盖率:50%-60% 较高覆盖率:大于80%
mock测试
导入github上的monkey。 mock函数可以:
- 为一个函数打桩
- 为一个方法打桩
进行打桩测试,不再依赖本地文件
基准测试
项目实战:
分层结构
- 数据层: 数据model,外部数据的增删改查
- 逻辑层:业务Entity,处理核心业务逻辑输出
- 视图层:视图view,处理和外部的交互逻辑
我的报错:
把单引号去掉就可以正常打印出json字符串了