Go 语言上手-工程实践|青训营笔记

86 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记。

1、相关知识

1.1 进程、线程与协程

  • 进程:程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。

  • 线程:又称轻量级进程,是进程的一个执行实例,是CPU调度和程序执行的最小单位。内核态,内存消耗是MB级别。

  • 协程:在线程中细分出的单位,调度不受操作系统内核所管理,完全由用户控制。用户态,内存消耗是KB级别。

image.png

1.2 并发与并行

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

image.png

2、goroutine

2.1、创建协程

goroutine是 Go 语言并行设计的核心,本质上就是协程。go内部实现了 goroutine 之间的内存共享,比thread更易用、更高效、更轻便。使用极其简单,只需在函数调⽤语句前添加 go 关键字,就可创建并发执⾏单元。

示例:快速打印hello goroutine:0 ~ hello goroutine:4

image.png

2.2、CSP

并发程序之间的通信,有通过通信共享内存,和通过共享内存实现通信两种。提倡通过通信共享内存而不是通过共享内存实现通信。

image.png

2.3、Channel

go使用make(chan 元素类型, [缓冲大小])来创建通道 通道分为两种:

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

image.png

使用通道示例:A子协程发送0-9数字,B子协程计算输入数字的平方,主协程输出最后的平方数

image.png

2.4、并发安全Lock

go 语言的互斥锁:sync.Mutex

示例:5个协程并发对变量执行2000次+1操作

加锁和不加锁的对比结果如下:

image.png

image.png

2.5、WaitGroup

WaitGroup 对象内部有一个计数器,最初从0开始,它有三个方法Add(), Done(), Wait() 来控制计数器的数量。Add(n) 把计数器设置为n ,Done() 每次把计数器-1 ,wait() 会阻塞代码的运行,直到计数器地值减为0

image.png 注意点:

1、计数器不能为负值

2、WaitGroup 对象不是一个引用类型,通过函数传值的时候需要使用地址,否则程序会进入死锁

3、依赖管理

3.1、GO依赖管理演进

由于不同环境(项目)依赖的版本不同,为了控制依赖库的版本,Go 依赖管理经历了从 GOPATH 到 Go Vendor 到 Go Module 的演进。 image.png

3.2、GOPATH

GOPATH 是 go 语言支持的环境变量,GOPATH下会生成以下三个文件夹:

  • bin:项目编译的二进制文件
  • pkg:项目编译的中间产物,加速编译
  • src:项目源码

项目直接依赖src下的代码,go get命令下载的软件包都会在src目录下。

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

image.png

3.3、GO Vendor

image.png

3.3、GO Module

Go Module是 Go 语言 1.11 版本推出的依赖管理系统,解决了之前的依赖管理存在的问题,实现了定义版本规则和管理项目依赖关系的功能。

  • 通过 go.mod 文件管理依赖包版本
  • 通过 go get / go mod 指令工具管理依赖包

3.4、本地工具

  • go get image.png
  • go mod

image.png

4、项目实践

4.1、需求描述

image.png

4.2、ER图

image.png

4.3、分层结构

项目结构整体分为三层:repository数据层,service逻辑层,controoler视图层

  • 数据层Repository:关联底层数据模型 Model ,封装外部数据的增删改查。数据层面向逻辑层,对service层透明,屏蔽下游数据差异。
  • 逻辑层Service:处理核心业务逻辑,计算打包业务实体Entity ,利用数据层得到封装好的数据再次封装并传到视图层。Service层不关心底层数据的存储形式,只关心核心业务输出。
  • 视图层Controller:处理和外部的交互逻辑,以 View 视图的形式返回给客户端。Controller层负责和客户端交互的过程,只关心返回给客户端的数据格式。

image.png