GO语言学习:工程实践 | 青训营笔记

118 阅读2分钟

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

Go工程实践

并发编程

并发和并行的

  • 并发:多线程在单核cpu运行时,通过时间片切换
  • 并行:多个线程在多个cpu上执行
  • Go语言可以充分发挥多核的优势

goroutine

开启多个协程打印数字:

```
func hello(i int) {
println("hello goroutine : " + fmt.Sprint(i))
}
func HelloGoRoutine() {
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
time.Sleep(time.Second)
}
```

执行结果:

可以看到并没有按顺序打印,而是几乎同时不按顺序打印的5个

img.png

CSP

  • go语言提倡通过通信共享内存而不是共享内存通信

channel

  • 无缓存channel:同步通道
  • 有缓存channel:生产、消费模型,解决生产和消费不均衡带来的效率问题
  • 一个channel的例子:构造一个src channel,一个dest channel, 向src channel里存数据i,取出后平方存入dest channel,取出dest中的数据并打印
    src := make(chan int)
    dest := make(chan int, 3)
        go func() {
            defer close(src)
            for i := 0; i < 10; i++ {
                src <- i
            }
        }()
        go func() {
            defer close(dest)
            for i := range src {
                dest <- i * i
            }
        }()
        for i := range dest {
            //复杂操作
            println(i)
        }
    

sync

  • 并发安全:不加锁会产生未知结果

  • WaitGroup 同步:这个例子中,用了waitGroup,使得主函数等待各个线程都执行完毕后才终止。

    func ManyGoWait() {
      var wg sync.WaitGroup
      wg.Add(5)
      for i := 0; i < 5; i++ {
          go func(j int) {
              defer wg.Done()
              hello(j)
          }(i)
      }
      wg.Wait()
    }
    
    

依赖管理

Go Module 广泛应用于go依赖管理

  • 通过 go.mod文件管理依赖包版本
  • 通过go get/go mod指令工具管理依赖包

依赖管理三要素:

  • 配置文件,描述依赖 go.mod
  • 中心仓库管理依赖库 proxy
  • 本地工具 go get/mod

在存在多个依赖版本的时候,go会选择最低兼容版本

可以设置一个1proxy,用来依赖分发:当proxy不可用时,才会用direct

测试

分为:

  • 单元测试
  • mock测试
  • 基准测试

测试是避免事故的最后一道屏障

单元测试

所有单元测试的文件都以_test.go结尾

调用assert库执行assert方法,可以知道单元测试覆盖率。 一般覆盖率:50%-60% 较高覆盖率:大于80%

mock测试

导入github上的monkey。 mock函数可以:

  • 为一个函数打桩
  • 为一个方法打桩

进行打桩测试,不再依赖本地文件

基准测试

项目实战:

分层结构

  • 数据层: 数据model,外部数据的增删改查
  • 逻辑层:业务Entity,处理核心业务逻辑输出
  • 视图层:视图view,处理和外部的交互逻辑

我的报错:

报错记录_没有单引号.png 把单引号去掉就可以正常打印出json字符串了