Go并发编程
并发和并行:
- 并发是程序在一个核的cpu上运行,切换速度快,看起来像并发一样
- 并行是多线程程序在多个核cpu上运行
协程和线程:
-
协程:用户态,轻量级线程,栈KB级别
-
线程:内核态,线程跑多个协程,栈MB级别
- go提倡通过通信共享内存而不是通过共享内存实现通信
缓冲和无缓冲
- 一般来说,我们要保证顺序的有效性,可以使用无缓冲队列
Go依赖管理
Go Path
- GoPath弊端:
项目源码都放在一块,会导致不同项目在调用不同版本的包时,无法实现多版本控制
Go Vendor-弊端
-
通过不同项目包内的不同vendor可以去解决包间的依赖冲突问题
-
如果一个project A依赖projectB 和projectC, 但是他们之间又各自两个版本的Package,这个时候又会出现依赖冲突
Go Mod
-
三要素:
-
1、配置文件,描述依赖 go.mod
-
2、中心仓库管理依赖库 Proxy
-
3、本地工具 go get / mod
-
依赖配置:
-
version:版本号
- Indirect:直接依赖和间接依赖
- incompatible
- 在编译的时候会默认选择一个最低满足要求的依赖(B)
- 为了解决上述问题,就出现了Proxy,通过中心仓库管理依赖库 ,直接循序渐进
- go get
- go mod
测试
- 常见问题:
- 测试种类:
-
回归测试:一般是手动通过终端来回归一些固定的主流程场景
-
集成测试:对系统功能维度做测试
-
单元测试:在测试开发阶段,对单独的函数、模块做功能验证
-
测试单元:
- 测试规则
- 覆盖率:通过测试的代码行数 / 总的代码行数
go test xx_test.go xx.go --cover
- Tip:
- 稳定:单元测试能够相互隔离
- 幂等:多次查询得到的结果一致
解决方案:
- 由于本地文件(修改、删除)会影响到我们的最终结果
- 我们通过使用Monkey打桩可以减少对于...的依赖
项目需求:
需求用例:
ER图的划分:
分层结构:
项目搭建:
-
搭建流程:
-
需求描述
-
需求用例---->数据库实体
-
ER图的构建以及划分
-
项目分层模型
-
项目组件的确定--->技术栈
-
数据库的建立
-
服务实体
-
参数校验(判断某些字段是否有效)
-
数据准备 (从仓库/数据库中获取数据)
-
组装实体 (将拿到的数据输出)
- Repositor:
初始化话题数据索引:
高并发下只执行一行代码,:
Service:
由于话题和回帖之间是没有依赖的,所以可以并行处理:
控制器:
处理Router:
执行:
收获:
-
在查询数据的时候,一般我们都全扫描,但是效率低下。 我们可以用map来实现内存索引,利用文件元数据初始化全局内存索引, 可以实现O(1)的时间复杂度操作
-
在创建实体的时候,我们需要使用锁操作,避免被抢占
var userDao *UserDao var userOnce sync.Once func NewUserDaoInstance() *UserDao { userOnce.Do( func() { userDao = &UserDao{} }) return userDao } -
在做项目开发时,要思考流程是否可以并行,通过压榨CPU,降低接口耗时,不要一昧的串行实现浪费多核cpu资源
type QueryPageInfoFlow struct { topicId int64 pageInfo *PageInfo topic *repository.Topic posts []*repository.Post userMap map[int64]*repository.User } func (f *QueryPageInfoFlow) prepareInfo() error { //获取topic信息 var wg sync.WaitGroup wg.Add(2) var topicErr, postErr error go func() { defer wg.Done() topic, err := repository.NewTopicDaoInstance().QueryTopicById(f.topicId) if err != nil { topicErr = err return } f.topic = topic }() //获取post列表 go func() { defer wg.Done() posts, err := repository.NewPostDaoInstance().QueryPostByParentId(f.topicId) if err != nil { postErr = err return } f.posts = posts }()
\