go项目实战|青训营笔记

49 阅读3分钟

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

一、本堂课重点内容:

  • 并发编程
  • 依赖管理
  • 单元测试
  • 项目实战

二、详细知识点介绍:

并发编程

goroutine

Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。

goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的,高效利用多核。(基于CPS并发模型)

goroutine 语法格式:

go 函数名( 参数列表 )

例如:

go f(x, y, z)

开启一个新的 goroutine:

f(x, y, z)

Go 允许使用 go 语句开启一个新的运行期线程, 即 goroutine,以一个不同的、新创建的 goroutine 来执行一个函数。 同一个程序中的所有 goroutine 共享同一个地址空间。

package main
​
import (
        "fmt"
        "time"
)
​
func say(s string) {
        for i := 0; i < 5; i++ {
                time.Sleep(100 * time.Millisecond)
                fmt.Println(s)
        }
}
​
func main() {
        go say("world")
        say("hello")
}

注:函数的线程的执行顺序一定程度上依赖与函数定义和导入的顺序,导入>先定义>后定义,当主线程执行完成后,其余线程无论是否执行完成都会结束(可以通过通道阻塞线程来防止在其余线程执行结束前主线程结束

package main
​
import (
    "fmt"
    "test/src/test"
    "time"
)func say2(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s, i+1, "say2")
    }
}
​
func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(150 * time.Millisecond)
        fmt.Println(s, i+1, "say")
    }
}
​
func main() {
    go say("world")
    test.Say3("ok")
    //say2("hello")
​
    //go say2("world")
    //say2("hello")
​
    //ch := make(chan int)
    //go say2("world", ch)
    
    //say("hello")
    //fmt.Println(<-ch)
​
}
package test
​
import (
    "fmt"
    "time"
)
​
func test() {
    fmt.Println("hello world")
​
    for i := 0; i > 1; i++ {
        fmt.Println(i)
    }
}
​
func Say3(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s, i+1, "say3")
    }
}

chanel

通过通信共享内存(通道)而非通过共享内存而通信(临界区,加锁)

make(chan 元素类型,[缓冲大小])
//无缓冲通道(同步通道)
make(chan int)
//有缓冲通道(生产消费)
make(chan int, 2)

Mutex

Mutex 是最简单的一种锁类型,同时也比较暴力,当一个 goroutine 获得了 Mutex 后,其他 goroutine 就只能乖乖等到这个 goroutine 释放该 Mutex。

RWMutex

RWMutex 相对友好些,是经典的单写多读模型。在读锁占用的情况下,会阻止写,但不阻止读,也就是多个 goroutine 可同时获取读锁(调用 RLock() 方法;而写锁(调用 Lock() 方法)会阻止任何其他 goroutine(无论读和写)进来,整个锁相当于由该 goroutine 独占。

依赖管理

不同模式的命令区别

1. gopath模式

在工程经过go build、go install或 go get等指令后,会将拉取的第三方xxx依赖包放在GOPATH/src目录下

2. go vendor模式

go build 时的应用路径搜索调整成为 优先搜当前工程路径/vendor目录

2. go module模式

  • 拉取依赖路径
    Go Modules 模式下,下载的包是存在 $GOPATH/pkg/mod 目录下的
  • 拉取指定版本
    GoModules 模式下,可以下载指定版本的包

单元测试

基础认识:

  • 单元测试是比较底层的,关注代码的局部而不是整体。
  • 单元测试是开发人员在写代码时候写的。
  • 单元测试需要比其他测试模块先运行。

实例

func TestAbs(t *testing.T) {
    got := Abs(-1)
    if got != 1 {
        t.Errorf("Abs(-1) = %d; want 1", got)
    }
}

Mock

在写单测过程中,常会遇到有些不容易构造或者不容易获取的对象,这时候我们要创建一个虚拟的对象以便测试。

基准测试

项目实战

开发一个简易论坛后端

三、引用参考: