面试题答案
一键面试defer语句的执行顺序
在Go语言中,defer语句会将其后面跟随的函数延迟到包含该defer语句的函数即将返回时才执行。多个defer语句的执行顺序是后进先出(LIFO),即最后定义的defer语句对应的函数最先执行。
举例说明使用场景
- 文件操作场景: 在对文件进行读写操作时,打开文件后需要在函数结束时关闭文件,以释放资源。使用defer可以确保无论函数如何返回(正常返回或因错误提前返回),文件都会被关闭。
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("test.txt")
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer file.Close()
// 在这里进行文件读取操作
// 函数结束时,无论是否发生错误,都会执行file.Close()
}
- 数据库连接场景: 与数据库建立连接后,在函数结束时需要关闭连接。
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq" // 以PostgreSQL为例
)
func main() {
db, err := sql.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")
if err != nil {
fmt.Println("Error opening database:", err)
return
}
defer db.Close()
// 执行数据库操作
// 函数结束时,会关闭数据库连接
}
- 解锁互斥锁场景: 当使用互斥锁(sync.Mutex)保护共享资源时,在函数结束时需要解锁互斥锁。
package main
import (
"fmt"
"sync"
)
var mu sync.Mutex
var count int
func increment() {
mu.Lock()
defer mu.Unlock()
count++
fmt.Println("Incremented count:", count)
}
在上述increment
函数中,defer mu.Unlock()
确保了无论函数如何返回,互斥锁都会被解锁,避免死锁的发生。