这是我参与「第三届青训营 -后端场」笔记创作活动的第一篇笔记
Go语言进阶
1.并发和并行
并发:多线程程序在一个核的cpu上运行
并行:多线程程序在多个核的cpu上运行
Goroutine
协程:用户态,轻量级线程,栈MB级别。切换调用由Go语言本身完成,较线程轻量许多。
线程:内核态,线程跑多个协程,栈KB级别。线程的创建,切换,停止都属于很重的系统操作,较消耗资源。
实际开发过程中开启协程:
for i := 0; i < 5; i++ {
go func(j int) {
println("hello goroutine : " + fmt.Sprint(j))
}(i)
}
time.Sleep(time.Second)
输出结果
![JK8H3QXO86OW]3ZIG(0WM%I.png](p6-juejin.byteimg.com/tos-cn-i-k3…?)
简单来说就是同时跑,先跑完的先输出
Channel
make(chan 元素类型, [缓冲大小])
有缓冲通道 make(chan int)
无缓冲通道 make(chan int,2)
![)YV{R_`2[%~1(X(9_({E.png
channel的简单使用:
func main() {
var src chan int
src = make(chan int)//不带缓冲
dest := make(chan int, 3)//带缓冲
go func() {
defer close(src)
for i := 0; i < 10; i++ {
src <- i//生产
}
}()
go func() {
defer close(dest)
for i := range src {//消费者1
dest <- i * i
}
}()
for i := range dest {//消费者2
println(i)
}
}
使用channel可使得生产效率高于消费效率,防止因等待消费而产生阻塞。
并发安全
互斥锁:go 语言中保留了通过共享内存实现通信的机制,这种情况会存在多个 goroutine 同时操作同一块内存资源的情况,可能导致并发安全的问题。
这种情况需要通过加锁的方式解决并发安全问题。
Go语言标准库中可以用sync.Mutex实现。
计数器WaitGroup:代替time.Sleep(),保证所有线程运行完,且不会浪费时间。
依赖管理
Go Module
现在普遍用Go Module进行项目管理
一般在创建的项目文件夹下用cmd输入go mod init (项目名)来创建一个go.mod文件,以此进行依赖管理。
依赖分发-Proxy
go.mod中的许多依赖都来自多版本代码仓库管理系统。
Go Proxy是一个服务站点,会缓存源站中的软件内容,使用Go Proxy以后,构建时会直接从站点拉取依赖。
![][G6`(3KUPL4]}FX4TF%6HS.png](p3-juejin.byteimg.com/tos-cn-i-k3…?)
Go Proxy的使用:Go语言通过设置环境变量GOPROXY来设置具体的服务站点。可以通过逗号设置多个Proxy站点,最后如果这几个都没有找到,那么会通过direct进行回源,也就是回到本来的请求站点,而不是代理站。
go mod:注意go mod init使用时后面加哥项目名,如go mod init haha,项目名为haha,然后在每次引用库时可以直接使用go mod tidy来更新依赖。
![1VSQ5Z]CM}LTHO)DZWXF2EG.png](p6-juejin.byteimg.com/tos-cn-i-k3…?)
测试
测试可以保证运行质量,提升运行效率,避免事故,是十分重要的
单元测试
测试文件以_test.go结尾,若是goland会自动识别是否为测试文件(vscode未试过)
func TestXxx(*testing.T)
初始化逻辑放入TestMain中
![RQH}$B2]AXHSKJ9JX5R65P.png
Mock测试
如果程序有外部依赖,在不同的测试环境,外部依赖信息可能会发生变化。比如程序需要打开某个文件,如果把相同的程序放在不同的环境测试,该文件的路径可能不一致。这就不符合稳定和幂等两个条件。
通过打桩(Mock)可以解决这个问题。打桩后,就不再依赖本地文件。
利用monkey库可以快速实现打桩:
![XSILEBGE{445YK_PRK1)NW.png
基准测试
基准测试是指测试一段程序的运行性能及耗费 CPU 的程度。而我们在实际项目开发中,经常会遇到代码性能瓶颈,为了定位问题经常要对代码做性能分析,这就用到了基准测试。使用方法类似于单元测试。
基准测试优化:
利用字节跳动开发的fastrand库进行优化,性能可以提升很多倍,在大多数情况都适用。
课后作业
课后作业的话基本上是照着示例代码写,这里主要讲讲怎么测试。
首先肯定是开启server.go
开启后,可以用apifox或者postman去测试,我是用apifox。
如果是用apifox的话,有客户端或者网页端,我是在网页端测试的,在网页端首先打开示例项目,然后新建一个快捷请求。接下来只需要发送GET请求和POST请求就行了。
GET请求的话不带参数,然后注意格式,最后一个数字2是topic_id,也就是本地文件data/topic里的,成功的话会返回以下内容,即输出topic里的内容。
然后是POST请求,主要得带content参数,即评论内容,成功的话会返回以下内容,id是由雪花算法生成的。
再回到goland看里会看到接受的请求,并且POST请求会将评论内容写入本地的post文件里。