Go 语言入门指南|青训营

55 阅读4分钟

go语言的一些特点:

只有for循环
不需要第三方库
switch 类似于 if else

socks5代理 原理:

截屏2023-08-24 16.23.13.png

协程

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

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

go语言一次可创建上万个协程

为函数创建协程,只需要在调用函数时在其前面加上go关键字:

Goroutine提倡通过通信共享内存而不是通过共享内存实现通信。

共享内存(互斥变量)方式的性能较低。

image.png

通道(channel)

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

•无缓冲通道(同步通道) make(chan int)

•有缓冲通道 make(chan int,2) 有“快递仓”,仓满时阻塞

image.png

同步(Sync)

解决并发安全问题:加锁

在go中也可以使用wait group来解决并发安全问题

依赖管理

GOPATH

GOPATH是Go语言支持的一个环境变量,value是GO项目的工作区。 目录有以下结构:

  1. bin:存放Go项目编译生成的二进制文件。
  2. pkg:存放编译的中间产物,加快编译速度。
  3. src:存放Go项目的源码:。

弊端:无法实现package多版本控制

image.png

解决:项目目录下增加vendor文件,所有依赖包以副本形式放在里面。每个项目引入一份依赖的副本。

vendor弊端:无法控制依赖的版本。更新项目有可能出现依赖冲突,导致编译出错。

Go Module

  • 通过go.mod 文件管理依赖包版本

  • 通过go get/go mod 指令工具管理依赖包

    终极目标:定义版本规则和管理项目依赖关系

依赖管理三要素:

  1. 配置文件,描述依赖 go.mod
  2. 中心仓库管理依赖库 Proxy
  3. 本地工具 go get/mod

依赖配置-go.mod

image.png

依赖配置-version

image.png

每次提交都会生成伪版本号

indirect 非直接依赖

incompatible

image.png

依赖分发-变量Proxy

image.png

本地工具-go get

image.png

本地工具-go mod

image.png

项目测试

测试是避免事故的最后一道屏障。

单元测试

单元测试-规则

image.png

评估测试:覆盖率。保证测试的完备性。

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

单元测试-依赖

image.png

幂等:重复运行一个case的结果是一样的。

稳定:单元测试相互隔离。

单元测试-文件处理

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

Mock测试

快速Mock函数

  • 为一个函数打桩
  • 为一个方法打桩

用一个函数替换一个函数

可以不再依赖本地文件

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

基准测试

  • 优化代码,需要对当前代码分析

  • 内置的测试框架提供了基准测试的能力

项目实践

需求描述

需求分析

ER图

分层结构:

image.png 整体分为三层,repository数据层, service逻辑层, controoler视图层。

数据层关联底层数据模型,也就是这里的model,封装外部数据的增删改查,我们的数据存储在本地文件, 通过文件操作拉取话题, 帖子数据;数据层面向逻辑层,对service层透明, 屏蔽下游数据差异,也就是不管下游是文件,还是数据库,还是微服务等,对service层的接模型是不变的。

Servcie逻辑层处理核心业务逻辑,计算打包业务实体entiy,对应我们的需求,就是话题页面,包括话题和回帖列表,并上送给视图层;

Cortroller视图层负责处理和外部的交互逻辑,以view视图的形式返回给客户端,对于我们需求,我们封装json格式化的请求结果,api形式访问就好。

  • 数据层:数据Model,外部数据的增删改查
  • 逻辑层:业务Entity,处理核心业务逻辑输出
  • V视图层:视图view,处理和外部的交互逻辑

组件工具:

  1. Gin 高性能go web框架 github.com/gin-gonic/g…

  2. Go Mod

    go mod init

    go get gopkg.in/gin-gonic/gin.v1@v1.3.0

gin, 高性能开源的go web框架,我们基于gin搭建web服务器,在课程手册应该提到了,这里我们只是简单的使用,主要涉及路由分发,不会涉及其他复杂的概念。

因为我们引入了web框架,所以就涉及go module依赖管理,如前面依赖管理课程内容讲解,我们首先通过go mod是初始化go mod管理配置文件,然后go get下载gin依赖,这里显示用了V1.3.0版本。

有了框架依赖,我们只需要关注业务本身的实现,从reposity --> service --> contoller我们一步步实现。希望大家能跟上我的节奏,从0~1 实现这个项目,如果时间问题,大家可以一步步copy一下,主要是走一半开发思路。