MST

星途 面试题库

面试题:Go 中通道(Channel)作为原语的特性及应用

请阐述 Go 语言中通道(Channel)作为基本原语的主要特性,包括但不限于缓冲与非缓冲通道的区别。并举例说明如何利用通道实现两个 goroutine 之间的数据传递与同步。
40.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

Go语言中通道(Channel)的主要特性

  1. 数据传递:通道是Go语言中用于在多个goroutine之间进行数据传递的核心机制。通过通道,一个goroutine可以发送数据,另一个goroutine可以接收数据,实现不同goroutine之间的通信。
  2. 同步:通道不仅可以传递数据,还能用于同步goroutine的执行。例如,当一个goroutine向通道发送数据时,如果没有其他goroutine在接收,该发送操作会阻塞,直到有接收者准备好接收数据。同样,接收操作也会阻塞,直到有数据发送到通道。
  3. 类型相关:通道是类型化的,创建通道时需要指定通道传递的数据类型,例如 chan int 表示该通道只能传递整数类型的数据。
  4. 缓冲与非缓冲通道
    • 非缓冲通道:也叫无缓冲通道,在创建时没有指定缓冲区大小,例如 make(chan int)。这种通道的发送和接收操作是同步的,发送操作会阻塞直到有接收者准备好接收数据,接收操作也会阻塞直到有数据发送到通道。它常用于实现goroutine之间的精确同步。
    • 缓冲通道:在创建时指定了缓冲区大小,例如 make(chan int, 5) 表示该通道的缓冲区大小为5。缓冲通道在缓冲区未满时,发送操作不会阻塞,直到缓冲区满;在缓冲区不为空时,接收操作不会阻塞,直到缓冲区为空。

利用通道实现两个goroutine之间的数据传递与同步示例

package main

import (
    "fmt"
)

func main() {
    // 创建一个非缓冲通道
    ch := make(chan int)

    // 启动第一个goroutine
    go func() {
        data := 42
        fmt.Println("Sending data:", data)
        ch <- data // 发送数据到通道
    }()

    // 启动第二个goroutine
    go func() {
        received := <-ch // 从通道接收数据
        fmt.Println("Received data:", received)
    }()

    // 防止主goroutine提前退出
    select {}
}

在上述示例中,第一个goroutine发送数据 42 到通道 ch,第二个goroutine从通道 ch 接收数据,实现了两个goroutine之间的数据传递与同步。如果将通道改为缓冲通道 ch := make(chan int, 1),在发送数据时,只要缓冲区未满,发送操作不会阻塞。但这里为了展示同步效果,使用的是非缓冲通道。