So bestehst du das Rust-Vorstellungsgespräch: Top-Fragen
Rust ist eine der gefragtesten Programmiersprachen im Jahr 2025. Sie kombiniert die Leistung von C/C++ mit Speichersicherheit, was sie zur idealen Wahl für Systemprogrammierung, WebAssembly und Blockchain-Projekte macht. Allerdings schreckt das Rust-Vorstellungsgespräch Kandidaten oft aufgrund des strengen Systems von Ownership, Borrowing und Lifetimes ab. In diesem Artikel analysieren wir die Top-10 Fragen, die dir garantiert gestellt werden, und zeigen die richtigen Antworten mit Codebeispielen.
1. Was ist Ownership (Eigentümerschaft) und wie funktioniert es?
Ownership ist die Grundlage von Rust. Jeder Wert in Rust hat genau einen Besitzer (Owner). Wenn der Besitzer den Gültigkeitsbereich verlässt, wird der Wert automatisch gelöscht.
fn main() { let s = String::from("hello"); // s ist der Besitzer des Strings let t = s; // Ownership wird an t verschoben (move) // println!("{}", s); // FEHLER: s besitzt den Wert nicht mehr println!("{}", t); // OK}Was im Vorstellungsgespräch gefragt wird: Erkläre den Unterschied zwischen Move und Copy. Typen, die das Copy-Trait implementieren (z.B. i32, bool), werden kopiert, nicht verschoben.
2. Wie funktioniert Borrowing (Ausleihen)?
Borrowing erlaubt die temporäre Nutzung eines Wertes ohne Übertragung des Ownership. Es gibt zwei Arten von Borrowing: unveränderlich (&T) und veränderlich (&mut T).
fn main() { let mut s = String::from("hello"); let r1 = &s; // unveränderliches Borrowing let r2 = &s; // mehrere unveränderliche sind erlaubt // let r3 = &mut s; // FEHLER: gleichzeitig veränderlich und unveränderlich nicht erlaubt println!("{} {}", r1, r2); let r3 = &mut s; // OK: nachdem r1 und r2 den Gültigkeitsbereich verlassen haben r3.push_str(" world"); println!("{}", r3);}Schlüsselregel: Zu jedem Zeitpunkt kann es entweder genau ein veränderliches Borrowing oder beliebig viele unveränderliche Borrowings geben.
3. Was sind Lifetimes (Lebenszeiten)?
Lifetimes sind Annotationen, die der Rust-Compiler benötigt, um zu überprüfen, dass Referenzen nicht zu hängenden Zeigern werden. Sie werden am häufigsten in Funktionen verwendet, die Referenzen zurückgeben.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y }}
fn main() { let s1 = String::from("langes"); let s2 = "kurzes"; let result = longest(&s1, s2); println!("Längster String: {}", result);}Lifehack: In den meisten Fällen leitet der Compiler die Lifetimes selbst ab (Elision). Annotationen werden nur für komplexe Fälle benötigt.
4. Was sind Traits und wie verwendet man sie?
Traits sind das Äquivalent zu Interfaces in anderen Sprachen. Sie definieren gemeinsames Verhalten für verschiedene Typen.
trait Summary { fn summarize(&self) -> String;}
struct Article { title: String, content: String,}
impl Summary for Article { fn summarize(&self) -> String { format!("{}: {}...", self.title, &self.content[..20]) }}
fn main() { let article = Article { title: String::from("Rust"), content: String::from("Rust ist eine sichere und schnelle Sprache"), }; println!("{}", article.summarize());}Wichtig: Traits können Standardimplementierungen haben und parametrisiert werden (generische Traits).
5. Was ist der Unterschied zwischen String und &str?
Dies ist eine der häufigsten Fragen. String ist ein veränderlicher, besitzender String, der auf dem Heap gespeichert wird. &str ist ein unveränderliches Borrowing eines String-Slices, das auf einen String, ein String-Literal oder einen Teil eines Strings verweisen kann.
fn main() { let s1 = String::from("hello"); // String let s2: &st