Go 语言入门-工程实践| 青训营笔记

94 阅读3分钟

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

一、本堂课重点内容:

本节课程主要分为四个方面:

  • 语言进阶
  • 依赖管理
  • 单元测试
  • 项目实战

二、详细知识点介绍:

语言进阶

Goroutine

协程:用户态,轻量级线程,栈KB级别

线程:内核态,线程跑多个协程,栈MB级别

  • CSP(Communicating Sequential Processes)

提倡通过通信共享内存而不是通过共享内存而实现通信

Channel

make(chan 元素类型,[缓存大小])

无缓冲通道 make(chan int)

有缓存通道make(chan int,2) 生产·消费问题

并发安全 Lock

var lock sync.Mutex

通过lock.Lock()和lock.Unlock()实现协程的互斥操作,达到并发安全

WaitGroup

计数器:开启协程+1;执行结束-1;主协程阻塞直到计数器为0

 //快速打印hello goroutine:0-4
 func hello(i int) {
     println("hello world : " + fmt.Sprint(i))
 }
 //不使用WaiGroup
 func HelloGoRoutine() {
     for i := 0; i < 5; i++ {
         go func(j int) {
             hello(j)
         }(i)
     }
     time.Sleep(time.Second)
 }
 //使用WaiGroup更优雅
 func ManyGoWait() {
     var wg sync.WaitGroup
     wg.Add(delta:5)
     for i := 0; i < 5; i++ {
         go func(j int) {
             defer wg.Done()
             hello(j)
         }(i)
     }
     wg.Wait()
 }

依赖管理

背景

工程项目不可能基于标准库0-1编码搭建,更加注重逻辑层面编码,因此要依赖管理

Go依赖管理演进

GOPATH->Go Vendor->Go Module

不同环境(项目)依赖的版本不同,要控制依赖库的版本

1.环境变量$GOPATH

 $GOPATH
 ├── bin //项目编译的二进制文件
 ├── pkg //项目编译的中间产物,加速编译
 └── src //项目源码

弊端:若场景A和B依赖于某一package的不同版本,无法实现package的多版本控制

项目代码直接依赖src下的代码

go get下载最新版本的包到src目录下

2.GoVender

弊端:无法控制依赖的版本。更新项目又可能出现依赖冲突,导致编译出错。

3.GoModule

可以定义规则管理关系。

Go Module实践

依赖管理三要素

  1. 配置文件,描述依赖 go.mod

version:

语义化版本${MAJOR}.${MINOR}.${PATCH}

基于commit伪版本vX.0.O-yyyymmddhhmmss-abcdefgh1234(时间戳+哈希码)

  1. 中心仓库管理依赖库 Proxy
  2. 本地工具 go get/mod

go mod:

init 初始化,创建go.mod文件 download 下载模块到本地缓存 tidy 增加需要的依赖,删除不需要的依赖

单元测试

规则:

  • 所有测试文件以_test.go 结尾
  • func TestXxx(*testing.T)
  • 初始化逻辑放到TestMain中

可以增加--cover参数来显示覆盖率

Mock

常用 monkey : github.com/bouk/monkey

基准测试

基准测试用于对代码进行性能分析。

以Benchmark开头,Resttimer重置计时器,runparallel是多协程并发测试。

在并发情况下rand为了保证并发安全和随机性有了全局锁,性能下降,可以使用fastrand提升性能。

三、实践练习例子:

青训营话题页开发

  1. 进行需求分析,画出需求用例和ER图
  2. 选择分层结构,这里选择数据-逻辑-视图的的结构
  3. 选择组件工具,使用go mod进行依赖管理,导入gin框架
  4. 设计Repository,主要有Topic结构和Post结构,使用map来进行索引
  5. 构建初始化数据索引函数
  6. 构建数据查询函数
  7. 设计构建Service实体
  8. 进行具体Service处理代码流程编排
  9. 构建View对象,返回最终信息

四、课后个人总结:

本次课程知识点较多,需要慢慢消化吸收。