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

56 阅读3分钟

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

一、本堂课重点内容:

  1. 语言进阶
  2. 依赖管理
  3. 测试
  4. 项目实战

二、详细知识点介绍:

  • 语言进阶

    • 并发 Vs 并行
      • 两个任务队列,一个机器执行,是并发
      • 两个任务队列,两个机器执行,是并行
      • Go 语言通过编译器运行时(runtime),从语言上支持了并发的特性。Go 语言的并发通过 goroutine 特性完成。goroutine 类似于线程,但是可以根据需要创建多个 goroutine 并发工作。goroutine 是由 Go 语言的运行时调度完成,而线程是由操作系统调度完成。
        Go 语言还提供 channel 在多个 goroutine 间进行通信。goroutine 和 channel 是 Go 语言秉承的 CSP(Communicating Sequential Process)并发模式的重要实现基础。
    • Channal
      • 格式
      channal1 := make(chan int)        //无缓冲通道
      channal2 := make(chan int, 3)     //有缓冲通道
      
      • 通过它并发核心单元就可以发送或者接收数据进行通讯(communication)。

      • 它的操作符是箭头  <-

    • 并发安全 Lock
      • 格式
      var lock sync.Mutex
      
      func Test() {
         for i := 0; i < 5; i++ {
            go func(j int) {
               lock.Lock()
               //代码区
               lock.Unlock()
            }(i)
         }
      }
      
  • 依赖管理

    • 背景
      • 复杂项目不可能从0~1编码搭建
      • 管理依赖库
    • Go依赖管理演进
      • Go Path —> Go Vendor —> Go Module
    • 实践
  • 测试

    • 出现原因
      • 因为逻辑错误导致各种损失
      • 测试是避免事故的最后一道屏障
    • 单元测试
      • Go 语言测试文件以 _test.go 结尾。
      • 测试函数写法
      func TestXxx(t *testing.T) {
          //测试代码
      }
      
      • 初始化逻辑放到 TestMain 中
      func TestMain(m *testing.M) {
         //测试前:数据装载、配置初始化等前置工作
         code := m.Run()
         //测试后:释放资源等收尾工作
         os.Exit(code)
      }
      
      • 运行
        • go test [flag][packages]
    • Mock测试
      • mock 作用的是接口,因此将依赖抽象为接口,而不是直接依赖具体的类。
      • 不直接依赖的实例,而是使用依赖注入降低耦合性。
    • 基准测试
      • 基准测试类似单元测试,唯一的不同就是在测试函数中传的参数类型是  *testing.B,而非  *testing.T。这两个类型都实现了 testing.TB接口,该接口提供了常用的Errorf(),Fatalf()和FailNow()常用函数。

三、实践练习例子:

  • Gin:高性能Go Web框架
    • Gin 特性

      • 快速:路由不使用反射,基于Radix树,内存占用少。
      • 中间件:HTTP请求,可先经过一系列中间件处理,例如:Logger,Authorization,GZIP等。这个特性和 NodeJs 的 Koa 框架很像。中间件机制也极大地提高了框架的可扩展性。
      • 异常处理:服务始终可用,不会宕机。Gin 可以捕获 panic,并恢复。而且有极为便利的机制处理HTTP请求过程中发生的错误。
      • JSON:Gin可以解析并验证请求的JSON。这个特性对Restful API的开发尤其有用。
      • 路由分组:例如将需要授权和不需要授权的API分组,不同版本的API分组。而且分组可嵌套,且性能不受影响。
      • 渲染内置:原生支持JSON,XML和HTML的渲染。
  • 项目实战——话题页面
    • 框架结构分层
      • 数据层(Repository):数据Model,外部数据的增删改查
      • 逻辑层(Service):业务Entity,处理核心业务逻辑输出
      • 视图层(Controller):视图view,处理和外部的交互逻辑

四、课后个人总结:

  • 最近看起go lang,真的被go的goroutine(协程)惊艳到了,一句 go function(){#todo},即可完成一个并发的工作。
  • 我是主java语言的,所以我用spring boot和gin做了一个简单的比较
    • 内存上,gin比springboot 小30倍。这个差距是真有点大。
    • 包大小上,gin比springboot 小2.6倍。别看磁盘只是小了2.6倍,流水线持续部署时,磁盘大小和每次传包的时间,也是相当可观的节省。
    • CPU上,两者持平。
    • qps上,gin 比 springboot 高出1.3倍。别看只有1.3倍,如果公司现在有10000台服务器呢?

五、引用参考:
1.⁣Go 语言入门 - 工程实践
2.极客兔兔