Go语言入门学习整理 (二)| 青训营笔记

130 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

一、重点内容:

1.1 知识要点有哪些?

  • Go语言进阶
  • Go依赖管理
  • Go工程测试

二、详细知识点介绍:

2.1 Goroutine

Goroutine是Go编程语言中的轻量级执行线程。它是一个独立运行并与其他goroutines同时运行的函数,允许高效和可扩展的程序设计。Goroutines被大量使用以同时处理许多任务,从而充分利用多核系统。Go 程序会智能地将 goroutine 中的任务合理地分配给每个 CPU。Go 程序从 main 包的 main() 函数开始,在程序启动时,Go 程序就会为 main() 函数创建一个默认的 goroutine。

2.2 CSP

Go语言的CSP (Communicating Sequential Processes)是一种通信为主体的编程模型,其中每个进程独立运行,通过通道来进行通信。CSP在Go语言中是通过使用goroutine和channel来实现的,是Go语言中并发编程的一种重要技术。CSP模型有助于开发者在开发并发应用时保持代码的简洁性和可读性。

2.3 Channel

Channel是Go语言中的一个重要特性,它允许在不同的Goroutine之间进行同步和通信。通过将数据发送到Channel,并从Channel接收数据,Goroutine可以在运行时进行安全的通信。使用Channel可以轻松地实现多线程程序中的数据共享和同步。除此之外:

  • Channels是类型安全的,只能传递特定类型的数据,这样可以避免类型不匹配的错误。
  • Channels可以是阻塞的或非阻塞的,以控制Goroutine的行为。
  • Channels可以是双向的,允许Goroutine在两个方向上进行通信。
  • Channels可以是带缓存的,可以在Goroutine之间进行异步通信。

2.4 Lock

Lock是Go语言中用于解决并发安全问题的一种同步机制。它通过在代码执行期间锁定临界资源,从而防止多个Goroutine同时对该资源进行读写操作,从而保证线程安全。Go语言中提供了sync包,其中提供了很多用于处理并发安全问题的函数和类型,其中最常用的是Mutex类型。通过使用Mutex,可以在多个Goroutine之间进行同步,从而避免竞争条件和数据不一致问题。通常使用sync包中的互斥锁(Mutex)实现Lock功能,例如:

var mu sync.Mutex 

func main() { 
    mu.Lock() 
    // 访问共享资源 
    mu.Unlock() 
}

2.5 WaitGroup

WaitGroup是Go语言中的一种同步机制,用于在多个Goroutine完成工作之前阻塞主Goroutine的执行。它可以简化多个Goroutine间的同步问题。例如:

var wg sync.WaitGroup

func worker(id int) {
    defer wg.Done()
    fmt.Printf("Worker %d starting\n", id)
    time.Sleep(time.Second)
    fmt.Printf("Worker %d done\n", id)
}

func main() {
    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go worker(i)
    }
    wg.Wait()
    fmt.Println("All workers done")
}

WaitGroup的Add方法用于增加计数器,Done方法用于减少计数器,Wait方法用于阻塞主Goroutine直到计数器归零。这样可以保证主Goroutine在所有工作Goroutine完成后再继续执行。

2.6 Go语言依赖管理

依赖管理的三个阶段:GOPATH、GOVENDOR、go mod

  • GOPATH工作模式就是把所有依赖包都放在GOPATH下的src中。
  • GOVENDOR工作模式是指在每个项目下创建vendor文件夹用来存放不同版本的依赖包,这样每个项目都会使用自己vendor下的依赖包,就解决了每个项目使用的依赖包版本不同的问题。
  • Go modules是Go语言的依赖解决方案

2.7 Go工程测试

Golang拥有一套单元测试和性能测试系统,仅需要添加很少的代码就可以快速测试一段需求代码。包括单元测试、Mock测试 和基准测试。

  • 单元测试主要包括:输入、测试单元、输出、期望以及与期望的校对。通过单元测试,可以一方面保证质量,例如在覆盖率足够的情况下,如果在旧代码中添加了新的代码,通过单元测试可以验证新的代码是否破坏了功能正确性。
  • mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。
  • 基准测试是指通过设计科学的测试方法、测试工具和测试系统,实现对一类测试对象的某项性能指标进行定量的和可对比的测试。

三、实践练习例子:

对以上概念编写相关代码,执行并进行测试。

四、个人总结:

学习一段时间后,来说说Go和Java的相似之处:

Go和Java都是面向对象编程语言,它们都具有多态性、封装性和继承性等诸多面向对象特性。它们之间的另一个相似之处是,它们都属于动态类型的程序设计语言,即程序员可以在运行时动态调整变量的类型。此外,Go和Java的语法结构也非常类似,而Java通常使用内存分配、回收和垃圾收集来实现内存管理,而Go则是使用显式内存管理机制。除此之外,Go和Java在许多其他方面也非常类似。例如,它们都支持和使用了模块化的代码结构,以及类、接口、迭代器等多种面向对象的概念。它们还共同支持许多编程范式,例如面向对象编程、函数式编程、泛型编程等。

五、引用参考:

Go语言的依赖管理
后端入门 - Go 语言原理与实践