MST

星途 面试题库

面试题:Go并发编程中如何避免因错误处理不当导致的资源泄漏

在一个涉及数据库连接的Go并发程序中,每个goroutine会获取数据库连接执行操作,操作过程中可能出现错误。如果错误处理不当,可能导致数据库连接没有正确关闭从而造成资源泄漏。请设计一个方案,确保无论在何种错误情况下,数据库连接都能被正确关闭,同时保证程序的并发性能不受太大影响。
32.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 使用defer关键字:在获取数据库连接后,立即使用defer语句来确保连接在函数结束时关闭。这能保证即使函数执行过程中出现错误,连接也会被关闭。
package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/test")
    if err != nil {
        panic(err.Error())
    }
    defer db.Close()

    // 执行数据库操作
    rows, err := db.Query("SELECT * FROM your_table")
    if err != nil {
        fmt.Println("Query error:", err)
        return
    }
    defer rows.Close()

    for rows.Next() {
        // 处理结果
    }
    if err := rows.Err(); err != nil {
        fmt.Println("Rows error:", err)
    }
}
  1. 错误处理:在每个可能返回错误的数据库操作后,及时检查错误。如果出现错误,通过return或者break等方式提前结束当前函数的执行,这样defer语句会确保连接关闭。
  2. 连接池:使用连接池来管理数据库连接,如database/sql包自带的连接池机制。这可以复用连接,减少创建和关闭连接的开销,提升并发性能。
// 配置连接池参数
db.SetMaxIdleConns(10)
db.SetMaxOpenConns(100)
  1. 使用上下文(Context):在QueryExec等操作中传入context.Context,当外部需要取消操作时(如超时等情况),可以通过上下文来优雅地关闭连接。
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

rows, err := db.QueryContext(ctx, "SELECT * FROM your_table")
if err != nil {
    fmt.Println("Query error:", err)
    return
}
defer rows.Close()