这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
今天课程的主要内容如下:
1、语言进阶
1.1 并行和并发
- 并行是指两个或者多个事件在同一时刻发生。
- 并发是指两个或多个事件在同一时间间隔发生。
1.2 Goroutine
线程:用户态,轻量级线程,栈MB级别。
协程:内核态,线程跑多个协程,栈KB级别。
1.3 CSP (Communicating Sequential Processes)
提倡通过通信共享内存而不是通过共享内存而实现通信
1.4 Channel
make(chan元素类型,[缓冲大小])
- 无缓冲通道make(chan int)
- 有缓冲通道make(chan int,2)
- 可以解决生产者的生产速度快于消费者的消费速度时,生产者的执行效率问题。
1.5 并发安全Lock
对变量执行2000次+1操作,5个协程并发执行
1.6 WaitGroup
WaitGroup用来判断协程任务是否完成,之前使用sleep不够优雅,因为我们无法预知协程任务的完成时间。
使用WaitGroup每增加一个协程任务就调用Add方法使计数器+1,每完成一个任务,调用Done方法使计数器减1,最后计数器为0表示所有任务执行完成。
1.7 小结
go并发编程主要涉及3个方面:
- 一个是协程Goroutine,通过高效的调度模型实现高并发操作;
- 一个是通道channel,通过通信实现共享内存;
- 最后sync相关关键字,实现并发安全操作和协程间的同步。
2、依赖管理
2.1 Go依赖管理演进
Go的依赖管理主要经历了3个阶段,分别是GOPATH-->Go Vendor-->Go Module。
到目前被广泛应用的go module,整个演进路线主要围绕实现两个目标来迭代发展的。
2.1.1 GOPATH
GOPATH是Go语言支持的一个环境变量,value是GO项目的工作区。 目录有以下结构:
- bin:存放Go项目编译生成的二进制文件。
- pkg:存放编译的中间产物,加快编译速度。
- src:存放Go项目的源码。
GOPATH弊端
如图,同一个pkg,有2个版本,A->A0,B->B0,而src下只能有一个版本存在, 那AB项目无法保证都能编译通过。也就是在gopath管理模式下, 如果多个项目依赖同一个库, 则依赖该库是同一份代码,所以不同项目不能依赖同一一个库的不同版本,这很显然不能满足我们的项目依赖需求。为了解决这问题,govender出现了 。
2.1.2 Go Vendor
Vendor是当前项目中的一一个目录,其中存放了当前项目依赖的副本。在Vendor机制下, 如果当前项目存在Vendor目录,会优先使用该目录下的依赖,如果依赖不存在,会从GOPATH中寻找; 但vendor无法很好解决依赖包的版本变动问题和一个项目依赖同一个包的不同版本的问题。
2.1.3 Go Module
- 通过go.mod文件管理依赖包版本
- 通过goget/gomod指令工具管理依赖包
GO Modules是Go语言言方推出的依赖管理系统,解决了之前依赖管理系统存在的诸如无法依赖同一个库的多 个版本等问题,go moule从Go 1.11开始实验性引入,Go 1.16默认开启;我们般都读为g mod,我们也先统下名称
3、单元测试
在实际工程开发中,另一个重要概念就是单元测试,这里我们主要讲解go测试相关的内容,包括单元测试 、Mock测试以及基准测试。
3.1 单元测试
单元测试主要包括,输入,测试单元,输出,以及校对,单元的概念比较广,包括接口,函数,模块等;用最后的校对来保证代码的功能与我们的预期相符;
单侧一方面可以保证质量,在整体覆盖率足够的情况下,一定程度上既保证了新功能本身的正确性,又未破坏原有代码的正确性。
另一方面可以提升效率,在代码有bug的情况下,通过编写单测,可以在一个较短周期内定位和修复问题。
3.2 基准测试
Go语言还提供了基准测试框架,基准测试是指测试一段程序的运行性能及耗费CPU的程度。而我们在实际项目开发中,经常会遇到代码性能瓶颈,为了定位问题经常要对代码做性能分析,这就用到了基准测试。使用方法类似于单元测试.
4、项目实践
4.1需求描述
社区话题页面
- 展示话题(标题,文字描述)和回帖列表
- 暂不考虑前端页面实现,仅仅实现一个本地web服务
- 话题和回帖数据用文件存储
4.2需求用例
主要涉及功能点,用户浏览消费,涉及页面的展示,包括话题内容和回帖的列表,其实从图中我们应该会抽出2个实体的,而实体的属性有哪些,他们之间的联系
4.3 ER图-Entity Relationship Diagram
结构设计。E-R国,用来典型的分层结构设计模型。 有了模型实体,属性以及之间的联系,对我们后续做开发就提供了比较清晰的思路。回到需求。两个个实体主要包括,实体的属性,有了实体模型,下一步就是思考代码
4.4分层结构
整体分为三层,repository数据层, service逻辑层, controoler视图层。
数据层关联底层数据模型,也就是这里的model,封装外部数据的增删改查,我们的数据存储在本地文件, 通过文件操作拉取话题, 帖子数据;数据层面向逻辑层,对service层透明, 屏蔽下游数据差异,也就是不管下游是文件,还是数据库,还是微服务等,对service层的接模型是不变的。
Servcie逻辑层处理核心业务逻辑,计算打包业务实体entiy,对应我们的需求,就是话题页面,包括话题和回帖列表,并上送给视图层;
Cortroller视图层负责处理和外部的交互逻辑,以view视图的形式返回给客户端,对于我们需求,我们封装json格式化的请求结果,api形式访问就好。
5、总结
今天学习了GO语言的进阶内容,包括并发编程、依赖管理、单元测试等。
最后还做了一个实战项目,收获满满。