Tous les parcours
Rust, depuis les bases
Pourquoi le ramasse-miettes comme la mémoire manuelle ont un coût, puis l'ownership, les collections, les traits, les closures, la concurrence et la performance : le Rust qu'il faut pour lire et écrire du vrai code.
59 articles · environ 517 min de lecture
0 sur 59 lus
Pourquoi Rust ?
- Étape 1: Partie 1 : GC Pauses et Latence: Le coût caché des langages de haut niveauJava, Python et JavaScript offrent de la commodité, mais le garbage collector introduit une latence imprévisible.6 min
- Étape 2: Partie 2 : Les langages comme C/C++ ou Zig permettent de contrôler la mémoire mais à quel prix ?C évite le besoin d'avoir un garbage collector et donne un contrôle manuel de la mémoire, mais ouvre la porte à des bugs dangereux.8 min
- Étape 3: Partie 3 : Rust: Memory safety sans garabe collectorRust a des performances équivalentes à C/C++ avec en plus la sécurité mémoire vérifée dès la compilation. Cela grâce à deux mécanismes: borrowing et ownership.10 min
Premiers pas
- Étape 4: Débuter avec RustIntroduction à Rust, couvrant l'installation, la syntaxe de base, et un premier projet.15 min
- Étape 5: Qu'est-ce que `clamp` en Rust, et quand l'utiliser ?Ce que fait clamp, pourquoi il panique sur un min et un max inversés, et en quoi il diffère de l'arithmétique saturante à laquelle on le confond.7 min
Ownership et mémoire
- Étape 6: Comment Rust assure la sécurité mémoire sans garbage collector ?Ownership, borrowing et lifetimes donnent à Rust la sécurité mémoire à la compilation, sans collecteur et sans pauses à budgéter.6 min
- Étape 7: Stack vs. Heap en Rust: Où Vivent tes Données ?Ce qui décide réellement qu'une valeur atterrit sur la stack ou sur le heap en Rust, et ce que chaque choix coûte à l'exécution.5 min
- Étape 8: Comment l'ownership prévient-il les memory leaks et data races ?Comment les règles d'ownership ferment la porte aux fuites mémoire et aux data races avant même l'exécution — et où elles s'arrêtent.5 min
- Étape 9: Emprunts mutables et immutables : les deux règlesLes deux règles d'emprunt, pourquoi l'exclusivité est celle qui compte, et ce que le borrow checker rejette réellement.6 min
- Étape 10: Qu'est-ce qu'un dangling pointer, et comment Rust le prévient-il au moment de la compilation ?Pourquoi un dangling pointer est une erreur de compilation en Rust plutôt qu'un crash en production, et comment les lifetimes rendent ce contrôle possible.6 min
- Étape 11: Qu'est-ce que &mut *x (réemprunt) en Rust, et pourquoi gèle-t-il la référence originale ?Un réemprunt duplique la référence, pas les données, et gèle l'originale le temps de sa durée de vie. Ce que fait vraiment &mut *x.8 min
- Étape 12: String vs. &str – Lequel Utiliser et Quand ?String vs str en Rust, couvrant gestion mémoire, ownership, et quand utiliser chaque type.6 min
- Étape 13: Comment Rust gère-t-il les string literals (&str) en termes d'allocation mémoire ? Où vivent-elles ?Les string literals vivent dans les données en lecture seule du binaire avec une lifetime 'static — ce que ça implique pour l'allocation et la copie.7 min
- Étape 14: Pourquoi &str Ne Rentre Pas dans &String en Rust: Fixes Sympas pour les String Mismatches !Pourquoi passer un &str là où un &String est attendu ne compile pas, ce que la coercition de déréférencement fait — et ne fait pas.6 min
- Étape 15: Quel est le but de Box<T> en Rust ?À quoi sert Box<T>, ce que coûte l'indirection supplémentaire, et quand l'allocation sur le heap est un vrai choix plutôt qu'un réflexe.6 min
- Étape 16: Comment fonctionne Cow<'a, B> (Copy-on-Write) en Rust ? Quand l'utiliser ?Cow<'a, B> permet d'emprunter quand c'est possible et d'allouer seulement quand il le faut. Comment marche le copy-on-write et quand il est rentable.6 min
- Étape 17: Comprendre le Trait Drop en RustComment fonctionne le trait Drop, quand le destructeur s'exécute, et pourquoi l'implémenter à la main est plus rare qu'il n'y paraît.6 min
Collections et itérateurs
- Étape 18: Rust Vec::new() vs. with_capacity() : Quand utiliser chacuneVec::new() alloue à la première insertion, with_capacity(n) alloue une fois pour n éléments. Quand la différence compte vraiment.6 min
- Étape 19: Quelle est la différence entre Box<[T]> et Vec<T> ?Comparaison des différences entre Box<[T]> et Vec<T> concernant la mutabilité, la surcharge mémoire et les implications de performance pour différents cas d'usage5 min
- Étape 20: Quelles sont les différences entre into_iter(), iter() et iter_mut() ?into_iter(), iter() et iter_mut() diffèrent par ce qu'ils cèdent : la valeur, une référence partagée ou une référence exclusive.7 min
- Étape 21: Implications d'itérer sur un Vec avec .into_iter() au lieu de .iter()Comprendre les différences entre .into_iter() et .iter() lors de l'itération sur Vec, couvrant les implications d'ownership et considérations de performance6 min
- Étape 22: Opérateurs & Itérateurs RustOpérateurs Rust essentiels, différences d'itérateurs et gestion Unicode à connaître.4 min
- Étape 23: La magie de collect() en Rust : Transformer des itérateurs en Vecs, HashMaps et Strings !Collections (comme Vec), itérateurs (into_iter, collect), et concepts associés6 min
- Étape 24: Comment supprimer efficacement les doublons d'un Vec<T> où T: Eq + Hash ?Approches efficaces pour supprimer les doublons d'un Vec<T> où T: Eq + Hash, comparant les méthodes basées sur HashSet et le tri avec analyse de performance6 min
- Étape 25: Vec::retain() vs filtrage avec iter().filter().collect() ?Comparaison du filtrage en place avec Vec::retain() et iter().filter().collect() pour différents scénarios de filtrage et implications sur les performances7 min
- Étape 26: Vec::drain() vs Vec::truncate() ou Vec::clear() ?Comprendre le fonctionnement de Vec::drain() et le comparer avec Vec::truncate() et Vec::clear() pour différents scénarios de suppression d'éléments6 min
- Étape 27: Aplatir un Vec<Vec<T>> en Vec<T> avec des itérateursComparaison entre l'aplatissement de Vec<Vec<T>> avec des itérateurs et la concaténation manuelle, avec analyse des implications sur les performances6 min
Traits et génériques
- Étape 28: Rust Traits vs. Interfaces Java/C# : Comportement partagé bien faitDiscussion sur les traits Rust vs les interfaces Java/C#, couvrant les mécanismes de dispatch, le comportement pendant la compilation, et les optimisations de performance.7 min
- Étape 29: Trait BoundsUtilisation des trait bounds en Rust pour la sécurité de type et les performances dans les calculs mathématiques7 min
- Étape 30: Borne de trait ou dyn Trait ? Dispatch statique et dynamique comparésLes génériques avec borne de trait compilent en dispatch statique ; dyn Trait compile en lookup de vtable. Ce que chacun coûte, et comment trancher.8 min
- Étape 31: Rendre les Traits Object-Safe pour dyn Trait de Rust dans les Systèmes de PluginsComprendre l'object safety en Rust et refactoriser les traits pour le dispatch dynamique8 min
- Étape 32: Le mot-clé `dyn` : Origines, Signification et LimitationsExploration approfondie du mot-clé `dyn` en Rust, son origine, son opposé statique, et pourquoi Vec<dyn Trait> n'est pas possible5 min
- Étape 33: Les supertraits : imposer une hiérarchie de comportementsExploiter les supertraits pour établir des hiérarchies de comportements et les combiner avec des clauses where pour optimiser des algorithmes génériques complexes pour la performance et la sécurité de type8 min
- Étape 34: ?Sized : une seule fonction pour les types sized et unsizedComprendre le rôle des bounds ?Sized dans les définitions de traits Rust et les exploiter pour créer des fonctions flexibles qui fonctionnent efficacement avec des types sized et unsized8 min
- Étape 35: Types associés ou génériques dans une API de driver I/OUtiliser les types associés dans les traits Rust pour concevoir des APIs flexibles et type-safe pour les drivers I/O bas niveau et comparer les avantages par rapport aux paramètres de type génériques9 min
- Étape 36: Les blanket implementations : une seule impl pour tous les types qui qualifientEmployer les blanket implementations en Rust pour minimiser la duplication de code tout en adressant les pièges de cohérence de trait pour une conception de bibliothèque robuste et maintenable9 min
Closures
- Étape 37: Functions ou Closures en Rust ?Functions vs closures en Rust, couvrant ownership, traits, lifetimes, et implications de performance.10 min
- Étape 38: Quelle est la différence entre Fn, FnMut, et FnOnce ?Fn, FnMut et FnOnce ne sont pas des traits qu'on choisit — le compilateur les déduit de la façon dont la closure utilise ce qu'elle a capturé.11 min
- Étape 39: Que sont les move closures (move || { ... }) ? Quand sont-elles nécessaires et comment interagissent-elles avec l'ownership ?Ce que move déplace réellement, quand on en a vraiment besoin (threads, closures retournées, blocs async), et son interaction avec l'ownership.13 min
- Étape 40: Comprendre les Move Closures en Rust : Guide pour les Développeurs JavaScriptApprends comment fonctionnent les move closures en Rust comparé aux closures JavaScript - ownership, threading et quand utiliser le mot-clé move8 min
- Étape 41: Comment spécifier une closure comme paramètre de function ou type de retour ?Prendre et retourner des closures : quand impl Fn suffit, quand il faut Box<dyn Fn>, et ce que chaque choix coûte au point d'appel.12 min
- Étape 42: Closures avec État en Rust: Passer et Muter à Travers Plusieurs AppelsGérer les closures avec état en Rust pour des appels de fonction répétés14 min
- Étape 43: Higher-Order Functions de Rust: Alimenter des Closures FlexiblesExplorer les higher-order functions en Rust pour des patterns de programmation fonctionnelle15 min
- Étape 44: Comment stocker une closure dans une struct ?Stocker des closures dans des structs en utilisant des paramètres génériques, trait objects, et annotations de lifetime avec les bounds Fn, FnMut, et FnOnce15 min
- Étape 45: Comment gérer les lifetimes lors du retour d'une closure qui capture des variables de son environnement ?Gérer les lifetimes lors du retour de closures qui capturent des variables, couvrant le transfert d'ownership, les annotations de lifetime, et éviter les dangling references en Rust15 min
- Étape 46: impl Fn() vs. Box<dyn Fn()>: Le Duel du Dispatch des Closures en RustComparaison du static et dynamic dispatch pour les closures en Rust, focus sur performance et cas d'usage11 min
- Étape 47: Closures ou fonctions : ce que coûte vraiment une closureAnalyser l'overhead de performance des closures versus les functions régulières en Rust, couvrant static dispatch, heap allocation, et scénarios d'optimisation14 min
Concurrence
- Étape 48: Comment les mécanismes d'Ownership et de Borrowing Assurent une Concurrence SûreOwnership et borrowing excluent les data races à la compilation. Ce qu'ajoutent Send et Sync, et pourquoi Rc ne franchit pas un thread.7 min
- Étape 49: Deadlocks en C vs Rust : Que garantit vraiment Rust ?Les deadlocks ne sont pas évités par le compilateur, mais Rust offre des garanties de sécurité qui rendent leur apparition plus difficile qu'en C. Comparaison détaillée.7 min
Performance
- Étape 50: Vec::push() dans une boucle vs. pré-allouer avec Vec::with_capacity() ?Comparaison des performances de Vec::push() dans les boucles versus pré-allouer avec Vec::with_capacity(), analysant les coûts de réallocation mémoire et stratégies d'optimisation13 min
- Étape 51: Abstractions Zéro-Coût : Comment Rust Optimise les Chaînes d'ItérateursOptimisation bas niveau en Rust, se concentrant sur les chaînes d'itérateurs et les abstractions zéro-coût11 min
- Étape 52: Éviter l'allocation heap sur un chemin temps réelExploiter les fonctionnalités stack-based de Rust comme les tableaux de taille fixe et Option pour éliminer les allocations heap dans les systèmes temps réel pour une exécution prévisible et faible latence15 min
- Étape 53: Rust repr : Optimiser la Mémoire des Structs pour l'Efficacité CacheOptimisation mémoire bas niveau en Rust, couvrant les attributs repr, l'efficacité cache, et les compromis de performance10 min
- Étape 54: Aligner les structures de données aux lignes de cacheConception de structures de données alignées sur le cache dans les applications Rust multi-threadées pour éviter le faux partage et optimiser les performances lors du traitement de grands ensembles de données8 min
- Étape 55: Booster les Boucles Chaudes Rust : Réduire les Branch MispredictionsOptimisation bas niveau en Rust, se concentrant sur la minimisation des branch mispredictions dans les boucles critiques en performance15 min
- Étape 56: Optimisation au niveau des instructions : #[inline(always)]Application stratégique de l'attribut #[inline(always)] de Rust pour l'optimisation au niveau des instructions, couvrant les modèles d'utilisation efficaces et les risques de surutilisation7 min
- Étape 57: SIMD en Rust : Optimiser la Multiplication de MatricesExploiter le support SIMD de Rust pour accélérer la multiplication de matrices avec des considérations pour la portabilité et la justesse14 min
- Étape 58: Maîtriser l'Inline Assembly en Rust : Quand et Comment Optimiser en SécuritéOptimisation bas niveau en Rust, se concentrant sur l'utilisation d'inline assembly pour les tâches critiques en performance15 min
- Étape 59: Profiling Rust : Résoudre les L1 Cache Misses avec perf, Flamegraph et CriterionOptimisation bas niveau en Rust, se concentrant sur les outils de profiling pour identifier et corriger les goulots d'étranglement de performance comme les L1 cache misses10 min