Rust : un langage qui vous fait penser autrement
\n\nVous avez décidé de conquérir Rust. Parfait. Ce n'est pas simplement un autre langage — c'est un défi. Rust brise les schémas auxquels nous sommes habitués en Python, JavaScript ou même C++. Il vous oblige à réfléchir à la mémoire, à la sécurité et à la concurrence à un nouveau niveau.
\n\nUn entretien Rust n'est pas un examen de syntaxe. C'est une vérification de votre façon de penser. Les recruteurs veulent voir que vous comprenez la philosophie du langage : ownership, borrowing, lifetimes. Dans cet article, nous analyserons les sujets et questions réels qui vous seront posés, et montrerons des exemples de code qui vous aideront à réussir l'entretien.
\n\nPrêt ? C'est parti.
\n\n1. Ownership — le fondement indispensable
\n\nLe premier et le plus important bloc. Si vous ne comprenez pas l'ownership, vous ne comprenez pas Rust. Lors de l'entretien, on vous demandera certainement d'expliquer comment fonctionne le transfert d'ownership et d'écrire du code qui le démontre.
\n\nRègles clés de l'ownership :
\n- \n
- Chaque valeur en Rust a exactement un propriétaire. \n
- Lorsque le propriétaire sort de la portée, la valeur est supprimée. \n
- L'ownership peut être transféré (move) ou temporairement prêté (borrow). \n
Exemple : que produit ce code ?
\nfn main() {\n let s1 = String::from("hello");\n let s2 = s1;\n println!("{}", s1); // Erreur !\n}\n\nBonne réponse : erreur de compilation. s1 a été déplacé vers s2, et s1 n'est plus valide. Le recruteur veut entendre que vous comprenez la sémantique de déplacement et pourquoi Rust est si strict à ce sujet.
2. Borrowing et références
\n\nAprès l'ownership — le borrowing. Comment prendre une référence sans prendre l'ownership ? Et surtout, comment ne pas enfreindre les règles du compilateur.
\n\nRègles du borrowing :
\n- \n
- Il peut y avoir un nombre illimité de références immuables (&T). \n
- Il ne peut y avoir qu'une seule référence mutable (&mut T). \n
- On ne peut pas avoir simultanément &T et &mut T sur une même valeur. \n
Exemple : trouver l'erreur
\nfn main() {\n let mut s = String::from("hello");\n let r1 = &s;\n let r2 = &mut s;\n println!("{} {}", r1, r2);\n}\n\nErreur : nous avons créé une référence immuable r1, puis une référence mutable r2. Le compilateur ne le permettra pas. Explication : c'est une protection contre les courses de données (data races) à la compilation.
3. Lifetimes — le sujet qui fait peur à tout le monde
\n\nLes lifetimes ne sont pas de la magie. Ce sont des annotations qui aident le compilateur à comprendre combien de temps les références restent valides. Lors de l'entretien, on vous demandera d'expliquer à quoi elles servent et d'écrire une fonction avec des paramètres de lifetime explicites.
\n\nQuestion typique :
\nÉcrivez une fonction qui retourne la chaîne la plus longue parmi deux. Comment spécifiez-vous les lifetimes ?
\n\nfn longest<'a>(x: &'a str, y: &'a str) -> &'a str {\n if x.len() > y.len() { x } else { y }\n}\n\nIci, 'a est une durée de vie commune qui garantit que la référence retournée sera valide tant que les deux références d'entrée sont valides. Le recruteur appréciera si vous mentionnez l'élision de durée de vie (lifetime elision) — lorsque Rust déduit lui-même les lifetimes pour les cas simples.
4. Enums et Pattern Matching — la force de Rust
\n\nRust n'a pas de null. À la place, il utilise Option<T> et Result<T, E>. Lors de l'entretien, on vous demandera d'écrire une gestion d'erreurs en utilisant match.
Exemple : division sécurisée
\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!("Résultat : {}", result),\n None => println!("Impossible de diviser par zéro"),\n }\n}\n\nMontrez