【青训营】第二节课笔记|青训营笔记

135 阅读4分钟

第二节课

1. 并发和并行

并发:一个盒时间切片 并发:多个盒运行不同 go语言为并发而生

1.1 携程

重要概念:携程

携程:用户态 轻量级线程 栈KB级别 线程:内核态 线程跑多个携程 栈MB级别。创建切换停止都是比较重的系统操作

1.2 通信

重要概念:携程之间的通信 CSP (Communicating Sequential Processes) go提倡通过通信共享内存(第一种)

image.png

共享内存:通过互斥量实现内存加速,一定程度上会出现数据静态?的问题,影响程序性能

1.3 Chanel

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

image.png

无缓冲会让发送和接收的gorountine同步化

1.4 并发安全 block

image.png

1.5 wait group

维护了一个计数器。

  • 启动n个并发任务,那+n
  • 每完成一个任务,就-1
  • wait到所有并发任务完成

image.png

总结

  • goroutine:携程高并发
  • channel:通信实现共享内存
  • sync:lock和waitgroup等内容,用于安全并发和携程同步

2. 依赖管理

2.1 go的依赖管理

go的依赖管理经历了三个阶段 image.png

  • gopath
  • go vender
  • go module 广泛应用

目的是围绕版本的控制

2.1.1 gopath

image.png

存在弊端:在依赖同一个pkg的时候,如果pkg升级到v2后没有v1中的A功能了,那就会导致project A运行不了

image.png

2.1.2 govendor

在项目目录下增加vendor文件夹,存在当前项目依赖的副本。 优先vender的依赖,如果这里没有就去gopath下 image.png

可能存在的问题,这个是真离谱

image.png

2.1.3 gomodule

使用go.mod管理依赖包版本 通过 go get/go mod指令工具管理依赖包

2.2 依赖管理三要素

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

2.3.1 依赖配置 go.mod

example可以是github

如果项目很复杂,每个包都要单独引用的话,那每个包的文件夹下都要有go.mod

原声库:不同项目的go版本可能不一样

单元依赖:分成module path版本号两部分,可以定位某一仓库的一次提交

image.png

2.3.2 依赖配置 version

版本号的规则定义,主要分成以下两种类型

语义化:

  • major 大版本。不同major不兼容
  • minor 新增函数功能,保证相同major是兼容的
  • patch 做代码bug修复

基于commit伪版本

  • 版本前缀:和语义化的major意义相同
  • 时间戳:提交commit的时间戳
  • hash码:对于本次提交的校验

image.png

2.3.3 indirect 间接依赖

image.png

2.3.4 incompatible

gomod是最近才有的,为了兼容之前打错了的版本号,需要用incompatible

这个建议自己再去查查

image.png

选择满足本次构建的最低版本,如果有1.5的话不会选择的

image.png

2.3.5 依赖分发

如果依赖都基于如github等第三方平台的话,可能会因为作者的更改等问题,导致后面用不了这个依赖了 image.png

因此提出了proxy的概念,会缓存依赖的所有版本,实现可靠的依赖分发

image.png

2.3.6 变量 goproxy

如果proxy1没有,就去proxy2搜,如果还没有就去原始站点搜 image.png

2.3.7 工具 go get

image.png

2.3.8 go mod工具

image.png

总结

  • go.mod 配置文件,描述依赖
  • proxy 中心仓库
  • go get/mod 本地工具

3. 测试

  • 回归测试:终端刷刷抖音
  • 集成测试:对服务暴露的接口进行自动化测试
  • 单元测试:开发阶段对单独函数验证

image.png

将函数和模块等内容,整合成测试单元,通过比较输入输出和期望的差异,进行校对。 image.png

3.1.1 单元测试规则

用_test.go结尾,可以区分源代码和测试代码

func TextXxx(*testing.T) 如果函数命名有问题,那么在ide中就不会显示运行的标志

初始化逻辑放到testmain中

image.png

image.png

image.png

3.1.4 assert

image.png 外部包已经帮忙实现equal了,不用自己写等不等于

3.1.5 代码覆盖率

image.png

image.png

开发的时候,应该保证函数的粒度足够小,也就是单一职责 image.png

3.2 单元测试的依赖

单元测试每次的结果都应该是一样的(迷瞪),且能够独立运行的(稳定)

image.png

打桩就是用一个函数替代另一个函数

unpatch就是卸载桩子

image.png

打桩后,就不用依赖文件了,直接返回

image.png

3.5 基准测试

负载均衡测试 看看别人的博客吧www.cnblogs.com/ssgeek/p/15…

4. 项目实践

定义topic(话题)和postlist(帖子)的结构体

image.png

E-R图模型实体,一对多,一个topic对应多个post

image.png

4.4 通用的分层结构

数据层关联底层数据模型,封装外部数据增删改查,通过本地操作拉取话题和帖子数据

业务层不关心底层数据存储,进行数据处理吧

controller封装数据

image.png

使用开源web框架

image.png

要根据id实现查询操作

image.png

id直接用map就行了 image.png

service层取值的逻辑

image.png

第二步准备数据的逻辑

image.png