Rust: Eine Sprache, die zum Umdenken zwingt
\n\nSie haben sich entschieden, Rust zu erobern. Ausgezeichnet. Dies ist nicht nur eine weitere Sprache – es ist eine Herausforderung. Rust bricht mit den Mustern, die wir von Python, JavaScript oder sogar C++ gewohnt sind. Es zwingt Sie dazu, auf einer neuen Ebene über Speicher, Sicherheit und Nebenläufigkeit nachzudenken.
\n\nEin Rust-Vorstellungsgespräch ist keine Prüfung der Syntax. Es ist eine Überprüfung Ihrer Denkweise. Die Interviewer möchten sehen, dass Sie die Philosophie der Sprache verstehen: Ownership, Borrowing, Lifetimes. In diesem Artikel behandeln wir echte Themen und Fragen, die Ihnen gestellt werden, und zeigen Code-Beispiele, die Ihnen helfen, das Vorstellungsgespräch zu bestehen.
\n\nBereit? Los geht's.
\n\n1. Ownership – das Fundament, ohne das nichts geht
\n\nDer erste und wichtigste Block. Wenn Sie Ownership nicht verstehen, verstehen Sie Rust nicht. Im Vorstellungsgespräch werden Sie auf jeden Fall gebeten zu erklären, wie die Übertragung von Ownership funktioniert, und Code zu schreiben, der dies demonstriert.
\n\nWichtige Ownership-Regeln:
\n- \n
- Jeder Wert in Rust hat genau einen Besitzer. \n
- Wenn der Besitzer den Gültigkeitsbereich verlässt, wird der Wert gelöscht. \n
- Ownership kann übertragen (move) oder vorübergehend ausgeliehen (borrow) werden. \n
Beispiel: Was gibt dieser Code aus?
\nfn main() {\n let s1 = String::from("hello");\n let s2 = s1;\n println!("{}", s1); // Fehler!\n}\n\nDie richtige Antwort: Kompilierungsfehler. s1 wurde nach s2 verschoben, und s1 ist nicht mehr gültig. Der Interviewer möchte hören, dass Sie Move-Semantik verstehen und warum Rust hier so streng ist.
2. Borrowing und Referenzen
\n\nNach Ownership kommt Borrowing. Wie nimmt man eine Referenz, ohne das Ownership zu übernehmen? Und vor allem – wie verletzt man nicht die Regeln des Compilers.
\n\nBorrowing-Regeln:
\n- \n
- Es kann beliebig viele unveränderliche Referenzen (&T) geben. \n
- Es kann nur eine veränderliche Referenz (&mut T) geben. \n
- Man kann nicht gleichzeitig &T und &mut T auf denselben Wert haben. \n
Beispiel: Fehler finden
\nfn main() {\n let mut s = String::from("hello");\n let r1 = &s;\n let r2 = &mut s;\n println!("{} {}", r1, r2);\n}\n\nFehler: Wir haben eine unveränderliche Referenz r1 erstellt und dann eine veränderliche r2. Der Compiler erlaubt dies nicht. Erklärung: Dies ist ein Schutz vor Datenrennen (data races) zur Kompilierzeit.
3. Lifetimes – das Thema, das alle erschreckt
\n\nLifetimes sind keine Magie. Es sind Annotationen, die dem Compiler helfen zu verstehen, wie lange Referenzen gültig bleiben. Im Vorstellungsgespräch werden Sie gebeten zu erklären, wozu sie dienen, und eine Funktion mit expliziten Lifetime-Parametern zu schreiben.
\n\nTypische Frage:
\nSchreiben Sie eine Funktion, die den längeren von zwei Strings zurückgibt. Wie geben Sie die Lifetimes an?
\n\nfn longest<'a>(x: &'a str, y: &'a str) -> &'a str {\n if x.len() > y.len() { x } else { y }\n}\n\nHier ist 'a die gemeinsame Lebensdauer, die garantiert, dass die zurückgegebene Referenz gültig ist, solange beide Eingabereferenzen gültig sind. Der Interviewer wird es schätzen, wenn Sie die Lifetime-Elision erwähnen – wenn Rust Lifetimes für einfache Fälle selbst ableitet.
4. Enums und Pattern Matching – die Stärke von Rust
\n\nRust hat kein null. Stattdessen gibt es Option<T> und Result<T, E>. Im Vorstellungsgespräch werden Sie gebeten, eine Fehlerbehandlung mit match zu schreiben.
Beispiel: Sicheres Dividieren
\nfn safe_divide(a: f64, b: f64) -> Option<f64> {\n if b == 0.0 { None } else { Some(a / b) }\n}\n\nfn main() {\n match safe_divide(10.0, 0.0) {\n Some(result) => println!("Ergebnis: {}", result),\n None => println!("Division durch Null nicht möglich"),\n }\n}\n\nZeigen Sie