【青训营】go语言工程进阶

52 阅读2分钟

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

一、本堂课重点内容:

本节课程主要分为四个方面:

  1. 并发编程
  2. 依赖管理
  3. 单元测试
  4. 项目实战

二、详细知识点介绍:

并发编程

go在并发中更多采用的是协程,相比进程,协程在用户态运行,是轻量级线程,这也是go语言更多在高并发场景中使用的原因。

通信

在协程中的通信,更提倡使用通信共享内存而不是通过共享内存实现通信 image.png

Channel

Channel创建

image.png

Channel使用实例

func CalSquare() {
	src := make(chan int)
	dest := make(chan int, 3)
        //A
	go func() {
		defer close(src)
		for i := 0; i < 10; i++ {
			src <- i
		}
	}()
        //B
	go func() {
		defer close(dest)
		for i := range src {
			dest <- i * i
		}
	}()
	for i := range dest {
		//复杂操作
		println(i)
	}
}

并发安全 在项目的开发中,应该避免对项目的内存进行并发的读写操作,否则可能会出现错误

image.png

在go语言中,可以使用WaitGroup进行并发安全的同步

image.png

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()
}

依赖管理

常用命令

image.png image.png

依赖管理三要素

image.png

项目测试

单元测试

image.png 单元测试规则

image.png

测试样例

print.go

package test

func HelloTom() string {
	return "Tom"
}

print_test.go

package test

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

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

测试结果

image.png

覆盖率

  • 一般覆盖率:50%~60%,较高覆盖率80%+
  • 测试分支之间相互独立、全面覆盖。
  • 测试单元粒度足够小,函数单一职责 image.png

Mock测试

测试桩,解决测试文件的过程中由于依赖本地文件导致的测试失败

测试样例

mock.go

package test

import (
	"bufio"
	"os"
	"strings"
)

func ReadFirstLine() string {
	open, err := os.Open("log")
	defer open.Close()
	if err != nil {
		return ""
	}
	scanner := bufio.NewScanner(open)
	for scanner.Scan() {
		return scanner.Text()
	}
	return ""
}

func ProcessFirstLine() string {
	line := ReadFirstLine()
	destLine := strings.ReplaceAll(line, "11", "00")
	return destLine
}

mock_test.go

package test

import (
	"bou.ke/monkey"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestProcessFirstLine(t *testing.T) {
	firstLine := ProcessFirstLine()
	assert.Equal(t, "line00", firstLine)
}

func TestProcessFirstLineWithMock(t *testing.T) {
	monkey.Patch(ReadFirstLine, func() string {
		return "line110"
	})
	defer monkey.Unpatch(ReadFirstLine)
	line := ProcessFirstLine()
	assert.Equal(t, "line000", line)
}

基准测试

  • 优化代码,需要对当前代码分析
  • 内置的测试框架提供了基准测试的能力

实战项目

分层结构设计

image.png

三、课后个人总结:

相比起上节课的内容,这节课的难度明显增加了很多,很多知识点也需要自己去慢慢理解和领悟。在看课程的同时也需要自己一边打代码一边查找资料。课程才刚刚开始便已经感觉到有点力不从心了,还是自己了解的知识太少了,需要自己慢慢去增强自己的学习能力和知识积累,才能有更强的竞争力。