首页 > 其他分享 >Go简介

Go简介

时间:2024-09-13 15:46:51浏览次数:1  
标签:编程 简介 Goroutine C++ 并发 Go Channel

一. Go语言简介

Go(Golang) 是由谷歌开发的一种开源编程语言,于2009年首次发布。Go 结合了 C 语言的简洁性和现代编程语言的高效性,具有并发性强、编译速度快、内存管理自动化等特点。
它最初是为了解决谷歌在处理大规模服务器软件上的编程问题而设计的,目标是让工程师能够快速开发、部署并维护大型分布式系统。

Go 的设计目标

  • 简洁性:语言语法简单,容易上手,减少了程序员在开发中的复杂操作。
  • 高效并发:Go 内置对并发的支持,提供了 Goroutine 和 Channel 来简化并发编程。
  • 快速编译:Go 是编译型语言,具有接近 C/C++ 的编译速度,但其编译流程经过优化,使得编译时间非常快。
  • 垃圾回收:Go 提供自动的内存管理,通过垃圾回收机制避免了手动管理内存的复杂性。
  • 跨平台支持:Go 可以直接编译为适用于不同操作系统的二进制文件,支持跨平台开发。

Go 语言的核心特性

1. 并发模型(Goroutines 和 Channels)

Go 的并发模型是它的核心特性之一。

  • Goroutines 是 Go 中的轻量级线程,具有极小的内存消耗,可以在程序中创建数以万计的 Goroutine 来处理并发任务。
  • Channels 是 Goroutine 之间进行通信的方式。通过 Channel,可以实现 Goroutine 之间的数据传递和同步,避免了传统并发编程中常见的共享内存和锁管理问题。

2. 垃圾回收(Garbage Collection, GC)

Go 提供自动垃圾回收,程序员不需要像 C++ 中那样手动管理内存(如 mallocfree)。Go 的 GC 会自动回收不再使用的对象,极大地简化了内存管理,避免了内存泄漏问题。

3. 静态类型和动态内存管理

Go 是 静态类型语言,类型在编译时确定,这为程序的性能和安全性提供了保证。虽然静态类型,但 Go 的语法设计极简化,使其在开发体验上接近动态语言(如 Python 和 JavaScript),这得益于自动类型推断等功能。

4. 简洁的语法

Go 的语法极其简洁,避免了很多复杂的语言特性。例如:

  • 没有头文件,所有代码组织在包(package)中。
  • 没有类和继承,Go 使用接口和结构体实现多态。
  • Go 强制使用大写字母来区分公共(可导出)和私有(不可导出)函数、变量和类型。

5. 编译与跨平台支持

Go 是一门编译型语言,编译速度非常快,并且编译后的程序是静态链接的可执行文件,可以直接运行在目标操作系统上,而不需要依赖外部库。Go 支持跨平台开发,使用 Go 可以轻松地编译出适用于不同平台的二进制文件。


Go 和 C++ 的区别

1. 并发模型

  • Go:Go 内置并发支持,提供了 Goroutines 和 Channels,使得并发编程变得简单直观。Go 使用基于消息传递的并发模型(通过 Channel 传递消息来实现协作),避免了显式锁的使用。
  • C++:C++ 支持多线程并发编程,但程序员需要使用 std::threadstd::mutexstd::condition_variable 等工具显式地管理线程、锁和同步,容易导致数据竞争、死锁等问题。

2. 内存管理

  • Go:Go 语言提供了自动的垃圾回收机制,程序员不需要手动管理内存。这使得开发者可以专注于业务逻辑,减少了内存泄漏和悬空指针等问题。
  • C++:C++ 没有自动垃圾回收,内存管理由程序员负责,需要使用 newdelete(或 mallocfree)手动分配和释放内存。C++ 11 后引入了智能指针(std::unique_ptrstd::shared_ptr)来简化内存管理,但程序员仍然需要理解并手动控制资源生命周期。

3. 编程复杂度

  • Go:Go 的设计目标是简洁性,避免了很多复杂的编程概念。它没有 C++ 的多继承、模板元编程等复杂特性,重点在于易读、易用和高效的并发支持。Go 的包管理和模块系统也使得依赖管理更加方便。
  • C++:C++ 是一门强大的语言,提供了丰富的特性和编程范式(如面向对象、泛型编程、函数式编程等)。然而,C++ 的复杂性使得它的学习曲线非常陡峭,编写、调试和维护 C++ 代码需要更高的技能和时间成本。

4. 错误处理

  • Go:Go 不支持异常机制,而是采用显式的错误处理模式。函数返回值中包含错误信息,调用方需要显式检查错误并处理。这种机制虽然增加了一些代码量,但它简化了错误处理流程,减少了隐藏错误的机会。
  • C++:C++ 支持异常机制(trycatch),可以通过抛出异常来处理错误,但异常处理有时会隐藏错误的复杂性,增加了程序的不可控性。异常机制也可能带来性能开销。

5. 编译时间和可执行文件

  • Go:Go 的编译速度非常快,并且它生成的二进制文件是独立的,不依赖于外部库。这使得 Go 程序容易部署,尤其是在云服务和容器环境下。
  • C++:C++ 的编译时间通常比 Go 更长,尤其是在大型项目中。C++ 的可执行文件可以是动态链接的,依赖外部库,因此部署时可能需要处理依赖问题。

6. 面向对象支持

  • Go:Go 没有传统意义上的面向对象编程概念(没有类和继承)。它使用 结构体(struct)接口(interface) 来实现多态。Go 通过接口实现了灵活的多态性,接口是一组方法的集合,结构体可以隐式地实现这些接口。
  • C++:C++ 是一门面向对象语言,支持类、继承、多态、封装等概念。C++ 的类系统非常复杂,允许多继承、模板类等高级特性。

7. 泛型编程

  • Go:Go 1.18 引入了 泛型,但其泛型支持相对简单,旨在解决常见的重复代码问题,并保持语言的简洁性。
  • C++:C++ 是泛型编程的强者,C++ 的模板机制非常强大,支持复杂的模板元编程,但同时也增加了代码复杂性和编译时间。

二. Goroutines和Channels

Go 语言中,GoroutinesChannels 是并发编程的核心概念,它们通过结合使用,使得 Go 提供了一个简单且高效的并发编程模型。接下来,我将详细介绍 GoroutinesChannels 的工作原理、使用场景、以及它们在解决并发问题中的作用。

1. 什么是 Goroutine?

  • Goroutine 是 Go 语言中的轻量级线程。它是由 Go runtime 调度和管理的并发执行单元,类似于线程,但比操作系统级的线程更加轻量和高效。
  • 启动 Goroutine 很简单,只需要在函数调用前加上 go 关键字,例如 go doSomething()。与传统线程不同,Goroutine 的启动开销非常小,可以轻松启动成千上万的 Goroutine。

2. Goroutine 的特点

  • 轻量级:Goroutine 的启动成本非常低,通常每个 Goroutine 只占用几 KB 的内存,而系统线程的开销通常要大得多。
  • 由 Go runtime 调度:Go 使用 M:N 的调度模型,意味着多个 Goroutine 会被映射到少量的操作系统线程上,由 Go 的调度器管理。调度器会负责分配 Goroutine 给不同的 CPU 核心,确保它们高效运行。
  • 独立的执行:每个 Goroutine 可以独立执行,彼此之间不共享执行上下文,且运行在相同的地址空间中。这种设计降低了内存消耗,同时保证了高并发任务的执行效率。

3. Goroutine 示例

package main

import (
    "fmt"
    "time"
)

func printNumbers() {
    for i := 1; i <= 5; i++ {
        fmt.Println(i)
        time.Sleep(time.Millisecond * 500)
    }
}

func main() {
    // 启动一个 Goroutine 执行 printNumbers 函数
    go printNumbers()

    // 主 Goroutine 继续执行
    fmt.Println("Main Goroutine running")

    // 主 Goroutine 等待其他 Goroutines 完成
    time.Sleep(time.Second * 3)
    fmt.Println("Main Goroutine ends")
}

在这个例子中,printNumbers() 函数通过 go 关键字被启动为一个 Goroutine,主程序继续执行而不等待该 Goroutine 完成。

4. Goroutine 的优势

  • 并发执行:Goroutines 使得 Go 语言可以轻松处理并发任务。通过 Goroutines,可以同时处理大量任务(如网络请求、I/O 操作),从而提高程序的效率和响应速度。
  • 简单的 API:相比于传统的多线程编程,Goroutine 的 API 更加简洁,不需要显式管理线程的创建、销毁和同步等复杂操作。

5. 什么是 Channel?

  • Channel 是 Go 语言中 Goroutines 之间传递数据的通信机制。它是 Go 语言并发编程模型的核心部分,用于在多个 Goroutines 之间安全、同步地传递数据。
  • Channel 是强类型的,意味着一个 Channel 只能传递特定类型的数据。例如,chan int 表示传递 int 类型的 Channel。

6. Channel 的特点

  • 类型安全:Channel 是强类型的,这意味着你只能向 Channel 发送与其声明类型一致的数据。
  • 自动同步:Channel 自带同步机制。发送方(Goroutine)会在 Channel 满时阻塞,直到接收方读取数据;接收方会在 Channel 为空时阻塞,直到发送方提供数据。这种机制确保了 Goroutine 之间的通信是同步且无锁的。
  • 双向通信:Channel 支持双向通信,Goroutines 既可以通过 Channel 发送数据,也可以通过 Channel 接收数据。

7. Channel 的使用方式

  • 创建 Channel 使用 make 函数:
    ch := make(chan int)  // 创建一个 int 类型的 Channel
    
  • 向 Channel 发送数据:
    ch <- 10  // 向 ch 发送数据 10
    
  • 从 Channel 接收数据:
    value := <- ch  // 从 ch 接收数据并赋值给 value
    

8. Channel 示例

package main

import (
    "fmt"
    "time"
)

func producer(ch chan int) {
    for i := 1; i <= 5; i++ {
        fmt.Println("Produced:", i)
        ch <- i  // 向 Channel 发送数据
        time.Sleep(time.Millisecond * 500)
    }
    close(ch)  // 关闭 Channel
}

func consumer(ch chan int) {
    for val := range ch {  // 从 Channel 接收数据
        fmt.Println("Consumed:", val)
    }
}

func main() {
    ch := make(chan int)  // 创建一个 int 类型的 Channel

    go producer(ch)  // 启动生产者 Goroutine
    go consumer(ch)  // 启动消费者 Goroutine

    time.Sleep(time.Second * 3)
    fmt.Println("Main ends")
}

在这个例子中:

  • 生产者 Goroutine 不断向 Channel 发送数据。
  • 消费者 Goroutine 从 Channel 接收数据并处理。
  • 当 Channel 被关闭时,for val := range ch 循环会自动退出。

9. 带缓冲的 Channel

Channel 可以设置缓冲区,从而允许在缓冲区未满时继续发送数据,而不会阻塞。

ch := make(chan int, 2)  // 创建一个缓冲大小为 2 的 Channel

在这种情况下,生产者可以发送 2 条数据而不阻塞,直到缓冲区满。

6. Select 语句

select 是 Go 中用于处理多个 Channel 操作的结构,类似于 switch,但它是专门用于 Channel 的操作。

package main

import (
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
        time.Sleep(time.Second * 1)
        ch1 <- "message from ch1"
    }()

    go func() {
        time.Sleep(time.Second * 2)
        ch2 <- "message from ch2"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-ch1:
            fmt.Println("Received:", msg1)
        case msg2 := <-ch2:
            fmt.Println("Received:", msg2)
        }
    }
}

select 会等待多个 Channel 的操作,并执行第一个可以进行的操作。在这个例子中,select 会选择先接收到的数据进行处理。

标签:编程,简介,Goroutine,C++,并发,Go,Channel
From: https://www.cnblogs.com/929code/p/18412324

相关文章

  • 第一章、HarmonyOS介绍简介
    1.前言欢迎来到鸿蒙应用开发系列教程的第一课,在本单元,你将学习HarmonyOS的基本概念,熟悉HarmonyOS核心技术理念、开发语言、UI框架开发和测试工具,了解应用的上架与分发能力。2.应用开发的机遇、挑战和趋势随着万物互联时代的开启,应用的设备底座将从几十亿手机扩展到数百亿的iot设......
  • django特定地区冷链物流信息调度系统-计算机毕业设计源码92919
    特定地区冷链物流信息调度系统研究与应用摘要本研究针对特定地区的冷链物流信息调度系统进行了深入探索与实践。冷链物流作为一种特殊的物流方式,对于保障食品、药品等易腐产品的新鲜度和质量至关重要。然而,在特定地区,由于地理环境、经济水平和物流资源的限制,冷链物流面临着......
  • 一、深度学习简介
    1、什么是神经网络  简单来说,深度学习(DeepLearning)就是更复杂的神经网络(NeuralNetwork)eg:从预测房价开始,自变量x:sizeofhouse,因变量y:price,根据这些输入输出来建立房价预测模型,来预测房价:y=f(x)。也许可以把这个房屋价格加一个拟合函数,看成是一个非常简单的神经网络。一般......
  • Google Earth Engine——对Landsat8图像进行归约分析和应用函数导出数据等流程
    目录加载和过滤图像集合利用图像波段组合减少图像集合隔离图像计算NDVI编写函数在集合上映射函数构建最环保的像素组合绘制NDVI随时间变化的图表导出RGB图像整理你的代码加载和过滤图像集合搜索“Landsat8TOA”并将结果添加到导入部分。将集合重命名为......
  • [EGOI2024] Infinite Race题解
    [EGOI2024]InfiniteRace妙妙题。我们设\(cnt[x]\)表示当Anika和第\(x\)位选手相遇时Anika至少几次经过终点线。设定初始状态\(cnt[x]=-1\)表示两种等价的情况:Anika还未和第\(x\)位选手相遇过Anika被第\(x\)位选手超越了因此只剩下Anika超越了第\(x\)位选手......
  • Spring Cloud全解析:服务调用之Feign简介
    Feign简介Feign是Netflix开发的一个声明式的HTTP客户端(远程服务调用组件),只需要接口+注解即可完成对于微服务的调用,不需要使用RestTemplate+Ribbon来对微服务进行访问,简化了编程,其是基于动态代理机制,目标是减少HTTP调用的复杂性依赖<!--feign--><dependency><groupId>......
  • ArgoWorkflow教程(四)---Workflow & 日志归档
    上一篇我们分析了argo-workflow中的artifact,包括artifact-repository配置以及Workflow中如何使用artifact。本篇主要分析流水线GC以及归档,防止无限占用集群中etcd的空间。1.概述因为ArgoWorkflow是用CRD方式实现的,不需要外部存储服务也可以正常运行:运行记录......
  • Python与Go语言中的哈希算法实现及对比分析
    哈希算法是一种将任意大小的数据输入转化为固定大小的输出(通常为一个散列值)的算法,在密码学、数据完整性验证以及数据索引等场景中广泛应用。本文将详细介绍Python和Go语言如何实现常见的哈希算法,包括MD5、SHA-1、SHA-256等。文章不仅提供代码示例,还会详细解释每个算法的特点、应用......
  • go语言内存泄漏的场景分析
    go本身自带的GC是自动触发的不需要我们人为干预但是在某些场景下还是会存在内存泄漏的问题1循环引用如果存在两个或多个变量形成环式的相互引用那么go的GC就无法通过三原色的方式来完成对应变量的垃圾回收这会是导致内存泄漏的场景之一处理方法:这种场景多发生......
  • 2024年9月中国数据库流行度排行榜:TiDB重回前三,GoldenDB问鼎前五
    9月墨天轮数据社区的中国数据库流行度排行榜如约而至。除了冠亚两位,排名第三至第五的数据库产品均经历了位次的变动。榜单之上,稳健的老牌强者、崛起的新兴产品、以及那些在背后默默积蓄力量、准备厚积薄发的竞争者,共同展现了中国数据库行业的多样性和活力。墨天轮数据社区也持续致......