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

104 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记。

1语言进阶

1.1   Goroutine

Go可以充分发挥多核优势。

1.2 CSP(Communicating Sequential Processes)

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

1.3 Channel

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

无缓冲通道 make(chan int)

有缓冲通道 make(chan int,2)

1.4 并发安全Lock

      lock sync.Mutex

      lcok.Lock()

      …

      lock.Unlock()

1.5 WaitGroup

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

      Add(delta int)    //计数器+delta

      Done()  //计数器-1

      Wait()   //阻塞直到计数器为0

 

2依赖管理

2.1 依赖管理演进

2.1.1 GOPATH

      1.环境变量 $GOPATH

            bin : 存放Go项目编译产生的二进制文件

            pkg : 存放编译的中间产物,加快编译速度

            src : 存放Go项目的源码

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

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

      弊端:无法实现package的多版本控制

2.1.2 Go Vendor

1.项目目录下增加vendor文件,依赖包以副本形式放在$ProjectRoot/vendor。通过每个项目引入一份依赖的副本,解决了多个项目需要同一个package依赖的冲突问题。

2.依赖寻址方式:vendor->GOPATH

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

2.1.3 Go Module

      1.通过go.mod文件管理依赖包版本

      2.通过go get/go mod指令工具管理依赖包

      终极目标:定义版本规则和管理项目依赖关系

2.2 依赖管理三要素

      1.配置文件,描述依赖   2.中心仓库管理依赖库   3.本地工具

2.3.1 依赖配置-go.mod

      1.依赖管理基本单元      2.原生库     3.单元依赖

      依赖标识:[Module Path] [Version/Pseudo-version]

2.3.2 依赖配置-version

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

      2.基于commit伪版本 vX.0.0-yyyymmddhhmmss-abcdefgh1234

2.3.3 依赖配置-indirect

      //Indirect后缀标识间接依赖

2.3.4 依赖配置-incompatible

      +incompatible后缀兼容依赖

2.3.5 依赖分发

      1.回源:无法保证构建稳定性—增加/修改/删除软件版本;无法保证依赖可用性—删除软件;增加第三方压力—代码托管平台负载问题。

      2.Proxy:服务站点,缓存的软件版本不会改变

2.3.6 变量GOPROXY

      Go Modules通过GOPROXY环境变量控制如何使用Go Proxy;GOPROXY是一个Go Proxy 站点URL列表,可使用"direct“表示源站。对于示例配置,整体的依赖寻址路径,优先从proxy1下载依赖,如果proxy1不存在,后下钻proxy2寻找,如果proxy2中不存在则会回源到源站直接下载依赖,缓存到proxy站点中。

2.3.7 工具go get

      @update 默认  @none 删除依赖    @v1.1.2 tag版本,语义版本

@23dfdd5 特定的commit  @master 分支的最新commit

2.3.8 工具go mod

      Init 初始化,创建go.mod文件

download 下载模块到本地缓存

tidy 增加需要的依赖,删除不需要的依赖

 

3 测试

3.1 单元测试

      单元测试主要包括,输入,测试单元,输出,以及校对,单元的概念比较广,包括接口,函数,模块等;用最后的校对来保证代码的功能与我们的预期相符;单侧一方面可以保证质量,在整体覆盖率足够的情况下,一定程度上既保证了新功能本身的正确性,又未破坏原有代码的正确性。另一方面可以提升效率,在代码有bug的情况下,通过编写单测,可以在一个较短周期内定位和修复问题。

      单元测试规则:所有测试文件以_test.go结尾;func TestXxx(*testing.T);初始化逻辑放到TestMain中。

      单元测试需要保证稳定性和幂等性。稳定是指相互隔离,能在任何时间,任何环境,运行测试。幂等是指每一次测试运行都应该产生与之前一样的结果。而要实现这一目的就要用到mock机制。

3.2 Mock测试

      monkey是一个开源的mock测试库,可以对method,或者实例的方法进行mock,反射,指针赋值。Mockey Patch的作用域在Runtime,在运行时通过Go的unsafe包,能够将内存中函数的地址替换为运行时函数的地址。

3.3 基准测试

      基准测试是指测试一段程序的运行性能及耗费CPU的程度。在实际项目开发中,经常会遇到代码性能瓶颈,为了定位问题经常要对代码做性能分析,这就用到了基准测试。

 

4项目实践

      1.需求背景:掘金社区话题页面

      2.需求描述:展示话题(标题,文字描述)和回帖列表;实现本地web服务;话题和回帖数据用文件存储。

      3.需求用例:浏览消费用户

      4.ER图:话题、帖子。

      5.分层结构:

数据层:数据 Model,外部数据的增删改查

逻辑层:业务Entity,处理核心业务逻辑输出

视图层:视图view,处理和外部的交互逻辑

      6.组件工具:gin、go mod init、go get

      7.Repository层:用map实现内存索引

      8.Service层:实体;流程

      9.Controller层:构建View对象;业务错误码

      10.Router:初始化数据索引、引擎配置,构建路由,启动服务

      11.运行