编程后端开发工程师

解释一下 Rust 中的所有权(ownership)系统是如何工作的,以及它如何在没有垃圾收集器的情况下确保内存安全?

用 Hintsage AI 助手通过面试

回答

所有权系统(ownership)是 Rust 确保编译时内存安全的基本概念。每个变量都有一个拥有者。在任何时刻,只能有一个资源的拥有者存在。

在赋值或传递给函数时,所有权会被转移(move)。在转移后,之前的拥有者不能再使用该值:

let s = String::from("hello"); let t = s; // s 不再可用

Rust 还区分借用(借助引用)。

  • &T — 只读引用(borrow)。
  • &mut T — 可变引用(mutable borrow),但同一时间只能有一个可变引用。

通过这些规则,Rust 确保不会发生数据竞争、使用已释放内存后的错误和其他资源管理错误。

刁钻的问题

一个值是否可以同时有多个可变引用(&mut T)?为什么?

回答:不可以,在任何时刻只能有任意数量的不可变引用,或仅有一个可变引用。这防止了数据竞争。错误代码示例:

let mut s = String::from("hi"); let r1 = &mut s; let r2 = &mut s; // 编译错误!

由于对此主题细微差别的不了解而导致的实际错误示例


故事

在一个多线程项目中,开发人员试图在不使用所有权的情况下存储对可变缓冲区的引用,导致在缓冲区被释放后仍使用后出现崩溃(use-after-free)。Rust 不允许编译这样的代码,因此不得不修改架构。


故事

在一个大型 Rust 项目启动时,程序员将代码从 C++ 迁移过来。他们试图结合与 "原始" 指针工作的过时习惯,导致资源所有权错误和借用检查器的持续恐慌,直到解决了所有权架构问题。


故事

在字符串解析库中,只能通过 Rust 的严格所有权系统避免内存双重释放的错误。类似的 C++ 库导致了难以捕捉的错误和内存泄漏。