MST

星途 面试题库

面试题:Go错误处理与并发编程的结合

在Go的并发编程中,多个goroutine可能同时发生错误。请设计一个方案,能够有效地收集和处理这些并发错误,确保在出现错误时整个程序能够做出正确的响应,同时保证程序的性能和资源利用效率。请给出详细的代码实现,并解释关键设计点。
11.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
    "sync"
)

// ErrorCollector 用于收集并发错误
type ErrorCollector struct {
    mu    sync.Mutex
    errors []error
}

// AddError 添加错误到收集器
func (ec *ErrorCollector) AddError(err error) {
    ec.mu.Lock()
    ec.errors = append(ec.errors, err)
    ec.mu.Unlock()
}

// GetErrors 获取所有收集到的错误
func (ec *ErrorCollector) GetErrors() []error {
    ec.mu.Lock()
    defer ec.mu.Unlock()
    return ec.errors
}

func main() {
    var wg sync.WaitGroup
    errorCollector := ErrorCollector{}

    // 模拟多个goroutine执行任务
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            // 模拟可能出现错误的任务
            if id == 1 {
                errorCollector.AddError(fmt.Errorf("goroutine %d has an error", id))
            }
        }(i)
    }

    wg.Wait()

    // 处理收集到的错误
    errors := errorCollector.GetErrors()
    if len(errors) > 0 {
        fmt.Println("Encountered errors:")
        for _, err := range errors {
            fmt.Println(err)
        }
    } else {
        fmt.Println("No errors occurred")
    }
}

关键设计点解释

  1. ErrorCollector结构体

    • 使用sync.Mutex来确保在多个goroutine并发添加错误时数据的一致性。
    • errors切片用于存储收集到的所有错误。
  2. AddError方法

    • 该方法负责将错误添加到errors切片中。
    • 通过加锁和解锁操作,保证在并发环境下添加错误的线程安全性。
  3. GetErrors方法

    • 用于获取所有收集到的错误。
    • 同样通过加锁和解锁操作,保证在读取错误列表时的线程安全性。
  4. 主函数中的并发操作

    • 使用sync.WaitGroup来等待所有goroutine完成任务。
    • 每个goroutine模拟执行可能出错的任务,一旦出错,调用AddError方法将错误添加到收集器中。
    • 最后,通过GetErrors方法获取所有错误并进行统一处理。这样可以确保在出现错误时整个程序能够做出正确的响应,同时利用Go语言的并发特性保证程序的性能和资源利用效率。