MST
星途 面试题库

面试题:Go Future模式下的资源管理与异常处理

在使用Go的Future模式进行并发任务处理时,如何有效地管理资源(如文件句柄、数据库连接等)以避免资源泄漏?同时,当并发任务中出现异常时,怎样在Future模式的框架下进行合理的异常捕获与处理,保证程序的健壮性,请详细阐述并给出示例代码。
33.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

管理资源避免泄漏

  1. 使用defer关键字:在Go语言中,defer语句用于注册在函数返回时执行的延迟调用。对于需要管理的资源(如文件句柄、数据库连接),可以在获取资源后立即使用defer来确保在函数结束时正确关闭资源。
  2. 使用context.Contextcontext.Context用于在不同的goroutine之间传递截止时间、取消信号等信息。在并发任务中,通过传递context.Context,可以在任务被取消或者超时时,及时关闭相关资源。

异常捕获与处理

  1. 使用sync.WaitGroup和错误通道:在Future模式中,可以结合sync.WaitGroup来等待所有goroutine完成,并通过一个错误通道来收集每个goroutine中的异常。
  2. recover机制:在goroutine内部,可以使用recover来捕获panic,并将其转换为普通错误进行处理。

示例代码

package main

import (
    "context"
    "fmt"
    "io/ioutil"
    "sync"
)

// Future 结构体模拟Future模式中的结果容器
type Future struct {
    result interface{}
    err    error
}

// worker 函数模拟一个并发任务
func worker(ctx context.Context, wg *sync.WaitGroup, futureChan chan Future) {
    defer wg.Done()
    var future Future

    // 模拟打开文件
    file, err := ioutil.TempFile("", "example")
    if err != nil {
        future.err = err
        futureChan <- future
        return
    }
    defer file.Close()

    // 模拟任务逻辑
    select {
    case <-ctx.Done():
        future.err = ctx.Err()
    default:
        // 假设这里有实际的任务逻辑,设置result
        future.result = "Task completed successfully"
    }

    futureChan <- future
}

func main() {
    var wg sync.WaitGroup
    futureChan := make(chan Future)
    ctx, cancel := context.WithCancel(context.Background())

    wg.Add(1)
    go worker(ctx, &wg, futureChan)

    go func() {
        // 模拟在某个条件下取消任务
        // 这里简单地在1秒后取消
        select {
        case <-ctx.Done():
        case <-make(chan struct{}, 1):
            cancel()
        }
    }()

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

    for future := range futureChan {
        if future.err != nil {
            fmt.Printf("Error occurred: %v\n", future.err)
        } else {
            fmt.Printf("Result: %v\n", future.result)
        }
    }
}

在上述代码中:

  1. 资源管理:在worker函数中,使用defer file.Close()来确保打开的临时文件在函数结束时被关闭。
  2. 异常处理:通过context.Context来模拟任务取消,并将取消的错误或者任务执行中的错误通过futureChan传递到主函数进行处理。同时,主函数通过sync.WaitGroup等待所有任务完成,并从futureChan通道中获取每个任务的结果或者错误进行相应处理。