MST

星途 面试题库

面试题:Go异步网络请求中的资源管理与错误处理

在一个使用Go进行异步网络请求的应用中,每个请求可能会占用一些系统资源(如文件描述符等)。当其中一个请求发生错误时,不仅要正确处理该错误,还要确保所有相关资源都能被正确释放,避免资源泄漏。请描述实现这一功能的思路,并给出关键代码片段。
31.7万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 资源管理:为每个异步请求分配的资源,如文件描述符,应使用合适的数据结构进行跟踪,例如一个map,键为请求标识,值为对应的资源。
  2. 错误处理:每个异步请求的goroutine应使用defer语句来确保无论是否发生错误,资源都能被释放。同时,通过channel来传递错误信息。
  3. 全局资源清理:当有请求发生错误时,主goroutine需要负责清理所有相关资源,这可能涉及遍历资源跟踪数据结构并释放所有资源。

关键代码片段

package main

import (
    "fmt"
    "sync"
)

// 假设这是一个模拟资源的结构体
type Resource struct {
    // 这里可以添加实际资源相关的字段,比如文件描述符等
}

func (r *Resource) Close() {
    // 实现释放资源的逻辑
    fmt.Println("Resource released")
}

func main() {
    var wg sync.WaitGroup
    resourceMap := make(map[int]*Resource)
    errorCh := make(chan int, 10) // 用于传递发生错误的请求标识

    // 模拟多个异步请求
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            res := &Resource{}
            resourceMap[id] = res
            defer func() {
                if res != nil {
                    res.Close()
                    delete(resourceMap, id)
                }
            }()
            // 模拟网络请求
            if id == 1 {
                errorCh <- id // 模拟请求1发生错误
                return
            }
            fmt.Printf("Request %d completed successfully\n", id)
        }(i)
    }

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

    // 处理错误并清理资源
    for errID := range errorCh {
        fmt.Printf("Error in request %d, cleaning up all resources\n", errID)
        for id, res := range resourceMap {
            res.Close()
            delete(resourceMap, id)
        }
    }
}

在上述代码中:

  1. Resource结构体模拟了请求可能占用的资源,Close方法用于释放资源。
  2. resourceMap用于跟踪每个请求对应的资源。
  3. 每个goroutine在执行请求前创建资源并添加到resourceMap,使用defer确保即使请求出错也能释放资源。
  4. 当某个请求发生错误时,通过errorCh传递错误标识,主goroutineerrorCh接收错误标识,并清理所有资源。