MST

星途 面试题库

面试题:Rust中自定义panic类型及相应恢复策略的设计与实现

请设计并实现一种自定义的panic类型,用于特定业务场景下的错误处理。针对这种自定义panic,阐述如何设计相应的恢复策略,以确保程序在遇到此类panic时能以一种安全、高效且符合业务需求的方式继续运行。同时,详细说明该策略在多线程环境下的可行性及潜在问题。
22.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

1. 设计自定义 panic 类型

在 Go 语言中,可以通过定义结构体类型来创建自定义 panic 类型。例如,假设我们有一个处理用户认证的业务场景,当认证失败时触发自定义 panic。

package main

import "fmt"

// AuthFailedError 自定义认证失败 panic 类型
type AuthFailedError struct {
    Reason string
}

func (e *AuthFailedError) Error() string {
    return fmt.Sprintf("认证失败: %s", e.Reason)
}

2. 实现触发自定义 panic

func authenticateUser(username, password string) {
    if username != "admin" || password != "secret" {
        panic(&AuthFailedError{Reason: "用户名或密码错误"})
    }
    fmt.Println("认证成功")
}

3. 恢复策略设计

使用 recover 函数来捕获并处理自定义 panic。在捕获到 panic 后,根据业务需求进行相应处理,例如记录日志、返回特定错误信息给用户等。

func main() {
    defer func() {
        if r := recover(); r != nil {
            if err, ok := r.(*AuthFailedError); ok {
                fmt.Printf("捕获到认证失败 panic: %v\n", err)
                // 这里可以进行业务相关的恢复操作,比如提示用户重新输入
            } else {
                panic(r) // 不是我们定义的 panic 类型,重新抛出
            }
        }
    }()

    authenticateUser("test", "wrongpass")
}

4. 多线程环境下的可行性及潜在问题

  • 可行性
    • Go 语言的 deferrecover 机制在 goroutine (Go 语言的轻量级线程)中同样有效。每个 goroutine 都有自己独立的栈,因此在一个 goroutine 中发生的 panic 不会影响其他 goroutine,只要在每个 goroutine 中正确设置 defer 来捕获 panic,就可以实现安全的错误处理。
  • 潜在问题
    • 资源泄漏:如果在 panic 发生前有未关闭的资源(如文件句柄、数据库连接等),可能导致资源泄漏。需要确保在 panic 前正确关闭资源,或者在 recover 后进行资源清理。
    • 共享状态:如果多个 goroutine 共享某些状态,在一个 goroutine 中发生 panic 可能导致共享状态处于不一致的状态。在恢复时需要仔细处理共享状态,确保一致性。
    • 死锁风险:在 recover 过程中,如果操作不当,可能引入死锁。例如在持有锁的情况下发生 panic,恢复时又尝试获取同一个锁。需要注意锁的使用和释放策略。