后端与 Golang | 青训营笔记

45 阅读1分钟

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

1. 语言进阶

  • 并发VS并行

并发:多线程程序在一个核的cpu上运行

并行:多线程程序在多个核的cpu上运行

  • 线程VS协程

线程:用户态,轻量级线程,栈MB级别

协程:内核态,线程跑多个协程,栈KB级别

  • Goroutine快速打印hello goroutine
package main

import (
	"fmt"
	"time"
)

func hello(i int) {
	println("hello goroutine: " + fmt.Sprint(i))
}

func main() {
	for i := 0; i < 5; i++ {
		go func(j int) {
			hello(j)
		}(i)
	}
	time.Sleep(time.Second)
}

  • channel

    make(chan, 元素类型, [缓冲大小])

    • 无缓冲通道 make(chan, int)
    • 有缓存通道 make(chan, int, 3)

    代码示例

    A子协程发送数字0~9

    B子协程计算输入数字的平方

    主协程输出最后的平方数

    package main
    
    import "fmt"
    
    func test() {
        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 {
            fmt.Printf("i: %v\n", i)
    }
    }
    
    func main() {
        test()
    }
    
  • 并发安全lock

对变量进行2000次加1操作, 5个协程并发执行

package main

import (
    "fmt"
    "sync"
    "time"
)

var (
    x    int64
    lock sync.Mutex
)

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.Printf("x: %v\n", x)
    x = 0
    for i := 0; i < 5; i++ {
            go addWithoutLock()
    }
    time.Sleep(time.Second)
    fmt.Printf("x: %v\n", x)
}

func main() {
    add()
}

2. 模块管理

  • 工具 go mod

go mod init 初始化,创建go.mod文件

go mod download 下载模块到本地缓存

go mod tidy 增加需要的依赖,删除不需要的依赖

  • 依赖管理三要素
  1. 配置文件,描述依赖
  2. 中心仓库管理依赖库
  3. 本地工具

3. 测试

  • 单元测试-规则
  1. 所有测试文件以_test.go结尾
  2. func TestXxx(*testing.T)
  3. 初始化逻辑放到TestMain
  • 基准测试
  1. 优化代码,需要对当前代码分析
  2. 内置的测试框架提供了基准测试的能力