MST

星途 面试题库

面试题:Go闭包性能优化中的资源管理

假设你在一个Go项目中,有一个频繁调用的闭包函数,该闭包函数内部使用了数据库连接资源。请描述如何进行性能优化,确保在高并发情况下既保证性能又合理管理数据库连接资源,给出具体的代码示例及说明。
16.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

优化思路

  1. 连接池管理:使用数据库连接池来管理数据库连接,避免频繁创建和销毁连接。
  2. 减少闭包内资源操作:尽量减少在闭包函数内部直接操作数据库连接资源,而是从连接池中获取连接,操作完成后归还连接。

代码示例

package main

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

// 创建数据库连接池
var db *sql.DB
var once sync.Once

func GetDB() *sql.DB {
    once.Do(func() {
        var err error
        db, err = sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/test")
        if err != nil {
            panic(err.Error())
        }
        // 设置最大空闲连接数
        db.SetMaxIdleConns(10)
        // 设置最大打开连接数
        db.SetMaxOpenConns(100)
    })
    return db
}

func main() {
    // 获取连接池中的连接
    conn := GetDB()
    defer conn.Close()

    // 定义闭包函数
    closure := func() {
        // 从连接池获取连接
        db := GetDB()
        var count int
        err := db.QueryRow("SELECT COUNT(*) FROM your_table").Scan(&count)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Println("Count:", count)
    }

    // 模拟高并发调用闭包函数
    var wg sync.WaitGroup
    for i := 0; i < 100; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            closure()
        }()
    }
    wg.Wait()
}

代码说明

  1. 连接池创建GetDB 函数使用 sync.Once 确保数据库连接只创建一次,并通过 db.SetMaxIdleConnsdb.SetMaxOpenConns 设置连接池的最大空闲连接数和最大打开连接数。
  2. 闭包函数:闭包函数 closure 内部从连接池获取连接 db,执行数据库查询操作,操作完成后无需手动关闭连接(连接会自动归还到连接池)。
  3. 高并发模拟:在 main 函数中,通过 sync.WaitGroup 模拟100个并发调用闭包函数,确保在高并发情况下连接池能够合理管理数据库连接资源,提高性能。