Go语言进阶

Go语言进阶

Go充分发挥多核优势,高效运行

协程 Goroutine

协程:用户态,轻量级线程
线程:内核态,线程跑多个协程

func hello(i int) {
	println("hello goroutine : " + fmt.Sprint(i))
}
func HelloGoRountine() {
	for i := 0; i < 5; i++ {
		go func(j int) {
			hello(j)
		}(i)
	}
	time.Sleep(time.Second) // 阻塞 保证子协程完成之前主线程不退出
}

CSP 协程间通信

提倡通过通信共享内存而不是通过共享内存而实现通信(后者是互斥访问临界资源实现

Channel

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

  • 无缓冲通道 又称为同步通道
  • 有缓冲通道 存在缓冲大小
func CalSquare() {
	src := make(chan int)
	dest := make(chan int, 3) // 不会因为消费者的消费速度问题影响生产者的执行效率

	go func() { // A子协程发送 0 ~ 9
		defer close(src)
		for i := 0; i < 10; i++ {
			src <- i
		}
	}()
	go func() { // B子协程计算输入数字的平方
		defer close(dest)
		for i := range src {
			dest <- i * i
		}
	}()
	for i := range dest { // 主协程输出最后的平方数
		println(i)
	}
}

并发安全 Lock

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 addWithoutLock()
	}
	time.Sleep(time.Second)
	println(x)
	x = 0
	for i := 0; i < 5; i++ {
		go addWithLock()
	}
	time.Sleep(time.Second)
	println(x)
}

WaitGroup

目的:优化time.sleep
Add(delta int) Done() Wait()
计数器
开启协程+1; 执行结束-1; 主协程阻塞直到计数器为0.

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依赖管理

演进:GOPATH -> GO Vendir -> Go Module
目的:

  • 不同环境(项目)依赖的版本不同
  • 控制依赖库的版本

go get

默认拉取最新版本的提交

  • @none 删除依赖
  • @1.1.2 拉取特定版本
  • @23sdf 拉取commit提交
  • master 分支最新的commit

go mod

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

测试

回归测试、集成测试、单元测试

单元测试

测试文件名为原文件末尾换成_test.go
print.go

func HelloTom() string {
	return "Tom"
}

print_test.go

import (
	"github.com/stretchr/testify/assert"
	// 导入包报错 如下解决
	// settings -> Go -> GoModule -> Eable Go modules intergration
	// go mod init mod'name
	// go get "github.com/stretchr/testify/assert"
	"testing"
)

func TestHelloTom(t *testing.T) {
	output := HelloTom()
	expectOutput := "Tom"
	assert.Equal(t, expectOutput, output)
}

两个文件同时选择后运行即可得到结果

覆盖率

go test judge.go judge_test.go --cover查看覆盖率

Mock测试

github.com/bouk/monkey

基准测试

pkg.go.dev/testing#hdr…

泛型

anycomparable

  • any:表示go里面所有的内置基本类型 等价于interface{}
  • comparable:表示go里面所有内置的可比较类型
func main() {
	str_arr := []string{"HHH", "ZZZ", "UUU"}
	int_arr := []int{1, 2, 3}
	printArray(str_arr)
	printArray(int_arr)
}

// func printArray[T string | int | float64](arr []T) {
func printArray[T any](arr []T) {
	for _, i := range arr {
		println(i)
	}
}

HTTP

HTTP协议

概念:超文本传输协议(Hypertext Transfer Protocol
协议:需要明确边界、能够携带信息
协议包括:请求行、请求头、请求体、响应行、响应头、响应体

HTTP框架的设计与实现

  • 应用层设计:提供合理的API
  • 中间件设计:日志记录、性能统计、安全控制、事务处理、异常处理
  • 路由设计:为URL匹配对应的处理函数(Handlers
  • 协议层:抽象出合适的接口
  • 传输层

未完待续~

posted @ 2023-10-13 16:57  Jannan  阅读(132)  评论(0)    收藏  举报