MST

星途 面试题库

面试题:Go defer与异常处理、资源管理的深度结合

假设你正在开发一个高并发的网络服务,使用Go语言的defer进行资源管理和异常处理。要求在处理每个客户端请求时,确保网络连接资源正确关闭,同时能有效处理可能发生的各种异常情况。请详细描述你的设计思路,并给出关键代码片段说明如何利用defer实现这一目标,尤其是如何在defer函数中处理不同类型的异常,保证程序的健壮性和资源的正确释放。
26.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 连接管理:在处理客户端请求时,首先建立网络连接。使用defer关键字确保无论函数如何结束(正常返回或发生异常),网络连接都能正确关闭。
  2. 异常处理:Go语言通过error类型来处理错误。在函数中,对可能发生错误的操作进行检查,并使用defer中的recover机制来捕获panic类型的异常。如果发生panic,可以在defer函数中进行适当处理,比如记录日志、关闭资源等,以保证程序的健壮性。

关键代码片段

package main

import (
    "fmt"
    "net"
)

func handleConnection(conn net.Conn) {
    // 确保连接在函数结束时关闭
    defer func() {
        if r := recover(); r != nil {
            // 处理panic异常,例如记录日志
            fmt.Printf("Panic occurred: %v\n", r)
        }
        conn.Close()
    }()

    // 处理客户端请求
    buf := make([]byte, 1024)
    n, err := conn.Read(buf)
    if err != nil {
        // 处理普通错误,例如记录日志
        fmt.Printf("Read error: %v\n", err)
        return
    }

    // 处理读取到的数据
    data := buf[:n]
    fmt.Printf("Received data: %s\n", data)

    // 模拟可能发生的panic
    // panic("Simulated panic")
}

func main() {
    ln, err := net.Listen("tcp", ":8080")
    if err != nil {
        fmt.Printf("Listen error: %v\n", err)
        return
    }
    defer ln.Close()

    for {
        conn, err := ln.Accept()
        if err != nil {
            fmt.Printf("Accept error: %v\n", err)
            continue
        }
        go handleConnection(conn)
    }
}

在上述代码中:

  • handleConnection函数处理每个客户端连接。defer语句确保在函数结束时,无论是否发生异常,连接都会关闭。
  • defer函数中,使用recover捕获可能发生的panic,并进行相应处理。
  • 对于普通的error,在发生错误的地方进行检查和处理,例如在conn.Read操作后检查err