Go语言上手(二) | 青训营笔记

本堂课重点内容:

  • GO的并发
  • GO的依赖管理
  • Go的测试
  • GO的包管理
  • Go的web项目

知识点

GO的并发编程

Go语言的优势与特点

简单的协程示例

package main

import (
	"fmt"
	"time"
)

func hello(i int) {
	fmt.Println("hello go:", i)
}
func main() {  
	for i := 0; i < 5; i++ {
		go func(j int) {
			hello(j)
		}(i)
	}
	time.Sleep(time.Second)
}

Channel

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

Lock

就是一把锁,可以解决多线程下资源的同步问题

//Mutex 是互斥锁, 零值是解锁的互斥锁, 首次使用后不得复制互斥锁。也就是题目中的锁

如果对一个已经上锁的对象再次上锁,那么就会导致该锁定操作被阻塞,直到该互斥锁回到被解锁状态

基本使用如下

xxx.lock()

代码

xxx.unlock()

Go语言还有读写锁,用途更加专业

而其实当我们对一个固定的资源只做“读”操作的话,是不存在资源竞争的问题的,也就不会引发竞态。因为数据是不变的,不管怎么读取,多少goroutine同时读取都没有问题。

package main

import (
    "fmt"
    "sync"
    "time"
)

//全局变量
var end int
var rLock sync.RWMutex

func Read(i int) {
    rLock.RLock()
    fmt.Printf("读 goroutine%d 结果:%d\n", i, end)
    defer rLock.RUnlock()
}

func Write(i int) {
    rLock.Lock()
    end = end + i
    fmt.Printf("写 goroutine%d 结果:%d\n", i, end)
    defer rLock.Unlock()
}

func main() {
    for i := 0; i < 5; i++ {
        go Write(i)
    }
    for i := 0; i < 5; i++ {
        go Read(i)
    }
    time.Sleep(time.Second * 120)
}

结果如下

写 goroutine0 结果:0
读 goroutine1 结果:0
读 goroutine0 结果:0
读 goroutine2 结果:0
读 goroutine3 结果:0
读 goroutine4 结果:0
写 goroutine2 结果:2
写 goroutine1 结果:3
写 goroutine3 结果:6
写 goroutine4 结果:10

可以看出当所有的读取之后才会进入写的状态

第一个写入是因为程序还未运行读的线程

WaitGroup

Go语言中除了可以使用**通道(channel)**和互斥锁进行两个并发程序间的同步外,还可以使用等待组进行多个任务的同步,等待组可以保证在并发环境中完成指定数量的任务

WaitGroup的用途是使得主线程一直阻塞等待直到所有相关的子goroutine都已经完成了任务。

在 sync.WaitGroup(等待组)类型中,每个 sync.WaitGroup 值在内部维护着一个计数,此计数的初始默认值为零。

等待组有下面几个方法可用,如下表所示。

func main() {
    var wg sync.WaitGroup
    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            println("hello")
        }()
    }
    wg.Wait()
}

使用 Add 添加需要等待的个数,使用 Done 来通知 WaitGroup 任务已完成,使用 Wait 来等待所有 goroutine 结束。

包管理

Go的包管理非常依靠网络,我看视频的基本都是从github上自动导入

包。

目前使用主流使用GoMod管理依赖

使用go mod管理依赖

go mod init

初始化gomod文件

go mod downlaod 下载模块到本地

go mod tidy 添加依赖,删除不用的依赖

Go的测试

规则:

  • 所有测试文件以xxx_test.go结尾
  • fun TestXxx(*tesing.T)
  • 初始化逻辑放在TestMain中

代码覆盖率是指在测试中运行过的行数/总行数

理想情况下为100%

*go test 命令,会自动读取源码目录下面名为 _test.go 的文件,生成并运行测试用的可执行文件。

基准测试可以测试一段程序的运行性能及耗费 CPU 的程度。

参数如下

go test -v go_test.go -timeout=20m -count=1

  • -v 打印详情测试信息
  • -timeout 默认10分钟超时
  • -count 函数运行几次

go get 参数

参数介绍:

  • -d 只下载不安装
  • -f 只有在你包含了 -u 参数的时候才有效,不让 -u 去验证 import 中的每一个都已经获取了,这对于本地 fork 的包特别有用
  • -fix 在获取源码之后先运行 fix,然后再去做其他的事情
  • -t 同时也下载需要为运行测试所需要的包
  • -u 强制使用网络去更新包和它的依赖包
  • -v 显示执行的命令

示例

go get -u github.com/gin-gonic/gin

课后总结

Go的并发具有很大的优势,比java简单的多了,工具也比java快得多。

但是包管理不如java

web开发简单,容易上手

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值