MST

星途 面试题库

面试题:Go语言多返回值在并发编程中的优化实践

在Go语言的并发编程场景下,假设你有多个goroutine并发执行不同的任务,每个任务都可能返回多个结果。请设计一个方案,高效地收集这些多返回值,并处理可能出现的错误,同时阐述如何确保程序的并发安全。
39.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 使用sync.WaitGroupchan收集结果和处理错误
    • sync.WaitGroup用于等待所有goroutine完成。
    • 使用带缓冲的通道(chan)来收集每个goroutine的结果和错误。
    • 示例代码如下:
package main

import (
    "fmt"
    "sync"
)

// 定义一个函数,模拟任务,返回多个结果和可能的错误
func task(id int) (int, string, error) {
    if id == 2 {
        return 0, "", fmt.Errorf("task %d failed", id)
    }
    return id * 10, fmt.Sprintf("result from task %d", id), nil
}

func main() {
    var wg sync.WaitGroup
    resultChan := make(chan struct {
        id    int
        num   int
        str   string
        error error
    }, 10)

    // 启动多个goroutine
    for i := 1; i <= 3; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            num, str, err := task(id)
            resultChan <- struct {
                id    int
                num   int
                str   string
                error error
            }{id, num, str, err}
        }(i)
    }

    go func() {
        wg.Wait()
        close(resultChan)
    }()

    // 处理结果和错误
    for res := range resultChan {
        if res.error != nil {
            fmt.Printf("Task %d error: %v\n", res.id, res.error)
        } else {
            fmt.Printf("Task %d result: num=%d, str=%s\n", res.id, res.num, res.str)
        }
    }
}
  1. 并发安全阐述
    • 通道(chan)的并发安全:在Go语言中,通道本身是线程安全的。多个goroutine可以安全地向通道发送数据和从通道接收数据,不需要额外的锁机制。在上述代码中,多个goroutineresultChan发送结果和错误,不会出现数据竞争问题。
    • sync.WaitGroup的使用sync.WaitGroup用于同步goroutine,确保所有goroutine完成任务后再关闭通道。wg.Add(1)用于增加等待组的计数,wg.Done()用于减少计数,wg.Wait()用于阻塞当前goroutine,直到所有goroutine调用wg.Done(),这样保证了在关闭通道前所有goroutine都有机会将结果发送到通道中,避免了提前关闭通道导致数据丢失的问题。