Go语言工程进阶| 青训营笔记

78 阅读2分钟

Go 语言工程进阶| 青训营笔记

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

1.并发编程

go语言具有充分发挥多核优势,高效运行的作用,通过轻量级协程的方式,处理高并发

在go中,创建一个协程也非常简单,使用 go 关键字,就可创建一个进程

```go
    //创建了五个进程
    for i := 0; i < 5; i++ {
        go func(j int) {
                hello(j)
        }(i)
    }
```

go中支持从两种进程间的联系:

  • 通过通信共享内存

    go中提倡使用通信共享内存,使用关键字 chan(通道) 来连接

          src := make(chan int)    //创建无缓冲通道
          dest := make(chan int, 3) //创建缓冲空间为3的通道
          go func() {
                 defer close(src)
                 for i := 0; i < 10; i++ {
                         src <- i          //将i的值送入src通道
                 }
         }()
         go func() {
                 defer close(dest)
                 for i := range src {
                         dest <- i * i     //从src中拿值,并送入dest通道
                 }
         }()
         for i := range dest {
                 println(i)
         }
    

    src为无缓冲通道,dest为有缓冲通道,会缓和两个进程间的关系减少等待时长

  • 通过共享内存实现通信

    直接通过获取共享内存数据来通信,但是这种方法有风险,在多进程的情况下,可能不同进程的指令对同一个数据进行相同的操作,最后导致结果发生错误,采用这种方式,需要使用一些办法避免

    func addWithLock() {
        for i := 0; i < 2000; i++ {
                lock.Lock()          //使用锁机制,保护取出的数据
                x += 1
                lock.Unlock()        //关闭锁
        }
    }
    
    func addWithoutLock() {
        for i := 0; i < 2000; i++ {
                x += 1              //直接改变全局变量
        }
    }
    
    func Add() {
        x = 0
        for i := 0; i < 5; i++ {
                go addWithLock()
        }
        time.Sleep(time.Second)
        fmt.Println("WithLock: ", x)
        x = 0
        for i := 0; i < 5; i++ {
                go addWithoutLock()
        }
        time.Sleep(time.Second)
        fmt.Println("WithoutLock: ", x)
    }
    
    

    结果没有锁保护机制的x未能满足要求,其中的加和可能发生了重叠,一定要注意对公共内存数据的保护

  • WaitGroup在go中对进程进行管理

            var wg sync.WaitGroup     //定义WaitGroup变量
            for i := 0; i < 5; i++ {
                    wg.Add(1)         //每创建一个进程,WaitGroup计数器加一
                    go func(j int) {
                            defer wg.Done()      //当进程完成时,计数器减一
                            hello(j)
                    }(i)
            }
            wg.Wait()              //等待所有进程执行完成,即计数器为0
    

    WaitGroup是较为良好的管理进程,同步进程的方法

2.依赖管理

go语言的依赖管理

image.png

经历了从GOPATH到GO Vendor,两个版本都存在依赖包版本不能兼容的问题,最后确定使用 Go Module 来进行依赖管理

  • Go Module的三要素

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

    go.mod采取的是选择最低的兼容版本依赖

  • go mod 的使用

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

3.测试

  • 单元测试

4.基于MVC的http请求响应

总结

  • 讲的都是关键的部分,容易让我们抓住重点

  • 得到很多启发,通过项目学习,结合自己所学,处理数据库和http之间的联系

  • 太多知识点需要记忆,感觉收获满满

  • 快速转变角色,走进开发者的状态