MST

星途 面试题库

面试题:Go recover在大规模并发系统中的实践

假设你正在开发一个高并发的大规模文件处理系统,使用Go语言的goroutine进行并行处理。在处理过程中,可能因为文件损坏等原因导致某个goroutine发生panic。请阐述如何在这种并发场景下,利用recover确保整个系统不会崩溃,并且能准确标识出发生panic的goroutine以及对应的文件。要求详细说明设计思路和可能用到的数据结构。
10.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 封装文件处理函数:将文件处理逻辑封装在一个函数中,在这个函数内部使用recover捕获panic
  2. 使用defer机制:在文件处理函数内部使用defer关键字,在defer函数中进行recover操作,这样无论函数正常结束还是因panic结束,defer函数都会被执行。
  3. 传递文件标识:在启动goroutine时,将文件的标识(如文件名、文件路径等)作为参数传递给文件处理函数,以便在panic时能准确标识出对应的文件。
  4. 集中处理结果:使用一个通道(channel)来收集每个goroutine的处理结果,包括正常结果和panic信息。

可能用到的数据结构

  1. 结构体:用于封装文件处理结果和panic信息。
type FileProcessResult struct {
    FilePath string
    Success  bool
    ErrMsg   string
}
  1. 通道(channel:用于在goroutine之间传递处理结果。
resultChan := make(chan FileProcessResult)

代码示例

package main

import (
    "fmt"
)

type FileProcessResult struct {
    FilePath string
    Success  bool
    ErrMsg   string
}

func processFile(filePath string, resultChan chan FileProcessResult) {
    defer func() {
        if r := recover(); r != nil {
            resultChan <- FileProcessResult{
                FilePath: filePath,
                Success:  false,
                ErrMsg:   fmt.Sprintf("panic occurred: %v", r),
            }
        }
    }()

    // 模拟文件处理逻辑,这里可能会发生panic
    if filePath == "corrupted_file.txt" {
        panic("file corrupted")
    }

    // 文件处理成功
    resultChan <- FileProcessResult{
        FilePath: filePath,
        Success:  true,
        ErrMsg:   "",
    }
}

func main() {
    filePaths := []string{"file1.txt", "corrupted_file.txt", "file2.txt"}
    resultChan := make(chan FileProcessResult)

    for _, filePath := range filePaths {
        go processFile(filePath, resultChan)
    }

    // 收集结果
    for i := 0; i < len(filePaths); i++ {
        result := <-resultChan
        if result.Success {
            fmt.Printf("File %s processed successfully\n", result.FilePath)
        } else {
            fmt.Printf("File %s processing failed: %s\n", result.FilePath, result.ErrMsg)
        }
    }

    close(resultChan)
}

在上述代码中:

  1. FileProcessResult结构体用于存储文件处理结果和panic信息。
  2. processFile函数封装了文件处理逻辑,使用deferrecover捕获panic,并将结果发送到resultChan通道。
  3. main函数启动多个goroutine处理文件,并从resultChan通道收集结果,根据结果判断文件处理是否成功。