Golang 进阶 | 青训营笔记

93 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

今天的课程主要讲解了四个方面

  • 并发编程
  • 依赖管理
  • 单元测试
  • 项目实战

并发编程

并发编程中,讲解了协程 Goroutine、通道 Channel、锁 Lock、线程同步(通过 WaitGroup 实现),并通过一些例子展示了它们的作用,并了解到了 Golang 提倡通过通信共享内存而不是通过共享内存而实现通信

依赖管理

依赖管理讲述了 Golang 依赖管理演进的过程,从 Gopath 到 Go Vendor,再从 Go Vendor 到 Go Module,并分别讲述了它们的优点与缺点

单元测试

单元测试部分讲解了 Golang 中单元测试的规则,并以一个例子讲解了单元测试的运行,接着讲解了单元测试的覆盖率,以及在实际开发中会保证 50 - 60% 的覆盖率,同时以 monkey 为例,讲解了 Mock 对函数打桩(本质是利用了 Golang 的反射机制),最后还讲解了基准测试,在讲解基准测试的时候,说明了 rand 函数因为持有一把全局锁,在并发场景会存在性能问题,最后使用了开源库中的 fastrand 函数替代了 rand 函数,可以看到在基准测试的并行测试中性能取得百倍的提升效果

项目实战

在项目实战中,以青训营话题页为例,讲解了需求用例、E-R 图、分层结构和一些组件工具,同时讲解了 Golang 中单例模式的实现

var topicDao *TopicDao
var topicOnce sync.Once

func NewTopicDaoInstance() *TopicDao {
	topicOnce.Do(
		func() {
			topicDao = &TopicDao{}
		})
	return topicDao
}

并讲解了可以通过建立内存索引的方式提升性能,具体方式为通过 ID 为键,利用 Golang 的 map 来实现 ID 与实体的对应,这里需要注意 ID 要唯一

在 Service 层中,讲解了 Service 的一般流程,即:参数校验 -> 准备数据 -> 组装实体,具体代码类似于

func (f *QueryPageInfoFlow) Do() (*PageInfo, error) {
	if err := f.checkParam(); err != nil {
		return nil, err
	}
	if err := f.prepareInfo(); err != nil {
		return nil, err
	}
	if err := f.packPageInfo(); err != nil {
		return nil, err
	}
	return f.pageInfo, nil
}

回顾本次项目实战,发现和抖音 APP 的评论功能十分类似,因此在实现大项目时,可以参考此处的设计