#[ 后端基础Day2 | 青训营笔记]

52 阅读1分钟

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

一、内容:

1.go的多线程编程

协程(coroutine) :又称微线程与子例程(或者称为函数)一样,协程(coroutine)也是一种程序组件。相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。

和线程类似,共享堆,不共享栈,协程的切换一般由程序员在代码中显式控制。它避免了上下文切换的额外耗费,兼顾了多线程的优点,简化了高并发程序的复杂。

package concurrence
​
import (
    "fmt"
    "sync"
)
​
func hello(i int) {
    println("hello world : " + fmt.Sprint(i))
}
​
func ManyGo() {
    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(j int) {
            defer wg.Done()
            hello(j)
        }(i)
    }
    wg.Wait()
}

CSP:

通信共享内存

通过make()创建通道,for range会使通道缓存中的值被取出

package concurrence
​
func CalSquare() {
   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)
   }
}
​

并发安全LOCK

背景:考虑一下count ++这样一个操作,看起来是一句代码,但其实底层经历了读取数据、更新cpu缓存、存入内存等一系列操作。所以我们代码的执行并不是原子性的,一旦多个协程并发执行就会可能出现严重的错误。

LOCK机制来保证操作的原子性

2.Go版本依赖管理

三要素:

配置文件 go.mod

与java 中pom.xml

module:用于定义当前项目的模块路径。

go:用于标识当前模块的 Go 语言版本,值为初始化模块时的版本,目前来看还只是个标识作用。

require:用于设置一个特定的模块版本。

exclude:排除一个特定的模块版本。

replace:用于将一个模块版本替换为另外一个模块版本。

​
module github.com/eddycjy/module-repo
​
go 1.13
require (
    example.com/apple v0.1.2
    example.com/banana v1.2.3
    example.com/banana/v2 v2.3.4
    example.com/pear // indirect    # indirect 标识表示该模块为间接依赖
    example.com/strawberry // incompatible
)
exclude example.com/banana v1.2.4
replace example.com/banana => example.com/fish
​

中心仓库管理依赖库 类比 java中的maven云仓库

本地工具 go get/mod 类比git

3.测试

单元测试: 软件中的最小可测试单元进行检查和验证,覆盖率越高越好

Mock: 减少对其他前置条件的依赖,自己生成

基准测试: 衡量代码性能

二、个人难点:

1.坑点

这次拉取项目,运行时报错了,通过日志发现是依赖包没有拉取成功的原因。

解决方法:

go env -w GOPROXY=https://goproxy.cn

三、课后个人总结:

本节课很好的从基础课又更深了一步,讲解了版本依赖管理和单元测试等,这些非常贴近实战开发的知识,为后期开发项目打下基础