Chapitre 21
21 - Livres Recommandés
21 - Livres Recommandés
Chapitre 21 : Livres Fondamentaux pour l'Ingénieur Backend
Introduction
Ce chapitre présente des résumés détaillés des livres essentiels pour tout ingénieur backend. Chaque résumé couvre les concepts clés, les exemples pratiques, et comment appliquer ces connaissances dans vos projets.
1. Designing Data-Intensive Applications
Auteur : Martin Kleppmann Éditeur : O'Reilly Media Année : 2017 Pages : 616 Difficulté : Avancée Note : ★★★★★ (4.8/5)
Pourquoi lire ce livre
"Designing Data-Intensive Applications" (DDIA) est considéré comme la bible des systèmes distribués. Il couvre les fondations de la fiabilité, de la scalabilité et de la maintenabilité des systèmes de données. Indispensable pour tout ingénieur backend travaillant sur des systèmes à grande échelle.
Partie I : Fondations des Systèmes de Données
Chapitre 1 : Fiabilité, Scalabilité, Maintenabilité
Fiabilité : Le système continue de fonctionner correctement même en cas de panne.
- Pannes hardware : Disques, RAM, réseau (redondance, RAID, replication)
- Pannes software : Bugs, processus zombies, cascading failures (isolation)
- Erreurs humaines : La cause la plus fréquente (tests, déploiements progressifs, sandbox)
Scalabilité : Le système peut faire face à l'augmentation de la charge.
- Latence vs débit : Percentiles (p50, p95, p99, p999) pour mesurer l'expérience utilisateur
- Head-of-line blocking : Un appel lent peut bloquer d'autres appels
- Approches : Scaling vertical (plus gros serveur) vs horizontal (plus de serveurs)
Maintenabilité : Le système est facile à faire évoluer et à opérer.
- Operability : Facilité d'exploitation
- Simplicity : Complexité accidentelle vs essentielle
- Evolvability : Facilité de changement
Chapitre 2 : Modèles de Données et Langages de Requêtes
SQL vs NoSQL : Le grand débat.
- SQL : Schéma rigide, jointures, transactions ACID, maturité
- Document (MongoDB) : Schéma flexible, relations limitées, aggrégation
- Graphe (Neo4j) : Relations complexes, traversées, recommandations
- Key-Value (Redis) : Cache, sessions, compteurs
Normalisation vs Dénormalisation :
- Normalisé : Évite la duplication, jointures coûteuses
- Dénormalisé : Lectures rapides, écritures complexes (maintenir les copies)
Le problème de l'Object-Relational Mismatch : Les ORMs tentent de combler le fossé entre le modèle objet et le modèle relationnel, mais avec des compromis.
Chapitre 3 : Stockage et Récupération
Index : Structures pour accélérer les lectures.
B-Trees :
- Structure d'arbre équilibré
- Insertion/suppression sans réorganisation complète
- Adapté aux workloads mixtes (lecture + écriture)
- Utilisé par PostgreSQL, MySQL, SQLite
LSM-Trees (Log-Structured Merge-Tree) :
- Écritures séquentielles rapides
- Compaction asynchrone en arrière-plan
- Meilleur pour les écritures intensives
- Utilisé par Cassandra, RocksDB, LevelDB
Stockage en colonnes :
- Pour les workloads analytiques (OLAP)
- Compression efficace (colonnes similaires)
- Agrégations rapides sans charger les colonnes inutiles
Chapitre 4 : Encodage et Évolution
Sérialisation : Comment représenter les données en mémoire et sur le réseau.
Formats :
- JSON/XML : Lisibles, sans schéma, volumineux
- Avro : Schéma requis, compact, évolution forward/backward
- Protocol Buffers : Schéma requis, très compact, champs optionnels
- Thrift : Similaire à Protobuf, Facebook origin
Compatibilité :
- Backward : Le nouveau code lit les anciennes données
- Forward : L'ancien code lit les nouvelles données
- Databased schema evolution avec migrations
Partie II : Données Distribuées
Chapitre 5 : Réplication
Pourquoi répliquer : Haute disponibilité, latence réduite, tolérance aux pannes.
Modes de réplication :
- Synchrone : Tous les nœuds confirment avant de répondre au client. Forte cohérence, latence élevée.
- Asynchrone : Le leader répond immédiatement, les followers rattrapent. Performant, perte possible de données.
- Semi-synchrone : Un follower doit confirmer (quorum write).
Modèles de réplication :
- Leader-based (single-leader) : Un leader accepte les écritures
- Multi-leader : Plusieurs leaders (conflits de write-write)
- Leaderless (Dynamo-style) : Tous les nœuds acceptent les écritures
Problèmes de cohérence :
- Read-after-write : Lire ses propres écritures
- Monotonic read : Ne pas voir les données régresser
- Consistent prefix read : Voir les données dans l'ordre
Chapitre 6 : Partitionnement (Sharding)
Pourquoi partitionner : Scalabilité horizontale, distribuer la charge.
Stratégies de partitionnement :
- Par plage de clés : Simple, mais hotspots possibles
- Par hash de clé : Distribution uniforme, mais perte du tri
- Par hash consistent : Ajout/suppression de nœuds minimal
Index secondaires :
- Local index : Chaque partition a son index (scatter/gather)
- Global index : Index partitionné séparément (écritures plus lentes)
Rebalancing : Ajouter/supprimer des nœuds sans downtime.
- Fixed number of partitions : Plusieurs partitions par nœud
- Dynamic partitioning : Les partitions se divisent/fusionnent
- Consistent hashing : Anneau de hachage
Chapitre 7 : Transactions
ACID revisité :
- Atomicité : Tout ou rien, même en cas de crash
- Cohérence : Les invariants sont respectés
- Isolation : Les transactions concurrentes sont isolées
- Durabilité : Les données persistent après un crash
Anomalies d'isolation :
- Dirty read : Lire des données non commitées
- Dirty write : Écrire par-dessus des données non commitées
- Non-repeatable read : Lire deux fois, résultats différents
- Phantom read : Nouvelles lignes apparaissent entre deux lectures
Niveaux d'isolation :
- Read Uncommitted : Aucune protection
- Read Committed : Pas de dirty read (la plupart des bases)
- Repeatable Read : Pas de non-repeatable read (PostgreSQL, MySQL InnoDB)
- Serializable : Transaction comme si séquentielle (plus lent)
MVCC (Multi-Version Concurrency Control) :
- Chaque transaction voit un snapshot cohérent
- Permet lecture sans bloquer écriture
- Garbage collection des vieilles versions
Transactions distribuées :
- Two-Phase Commit (2PC) : Phase prepare + phase commit, protocole coûteux
- SAGA pattern : Séquence de transactions locales avec compensation
- TCC (Try-Confirm/Cancel) : Phase de réservation puis confirmation
Chapitre 8 : Le Problème de la Cohérence Distribuée
Théorème CAP :
- Cohérence, Disponibilité, Partition tolerance
- On ne peut avoir que 2 des 3 en cas de partition réseau
- CP : C + P (sacrifie la disponibilité)
- AP : A + P (sacrifie la cohérence stricte)
- CA : C + A (ne gère pas les partitions, impraticable en pratique)
Modèles de cohérence :
- Strong consistency : Tous les nœuds voient la même chose
- Eventual consistency : Convergence à terme
- Causal consistency : Liens de causalité respectés
- Read-your-writes : Lire ses écritures
Clock skew et NTP : Les horloges des machines ne sont jamais parfaitement synchronisées. Utiliser des logical clocks (Lamport, vector clocks) pour ordonner les événements.
Partie III : Traitement Dérivé
Chapitre 9 : Batch Processing
MapReduce : Paradigme de traitement batch distribué.
- Map : Filtrer et transformer chaque enregistrement
- Shuffle : Regrouper par clé
- Reduce : Agréger les résultats groupés
Aspects importants :
- Data locality : Déplacer le code vers les données plutôt que l'inverse
- Input immutability : Les entrées ne sont pas modifiées
- Determinism : Même entrée = même sortie
- Fault tolerance : Rejouer les tâches échouées
Outils modernes : Apache Spark, Apache Flink, Google Dataflow
Chapitre 10 : Stream Processing
Différences avec le batch :
- Temps réel vs différé
- Événements vs lots
- Stateful vs stateless
Modèles de messagerie :
- Direct messaging : UDP, HTTP, RPC
- Message broker : Kafka, RabbitMQ, Amazon SQS
- Log-based : Kafka (log segmenté, répliqué)
Problèmes de stream :
- Late arriving events : Comment gérer des événements en retard ?
- Windowing : Tumbling, sliding, session windows
- Out-of-order events : Gérer le désordre (watermarks)
Exactly-once semantics :
- At-most-once : Au plus une fois (perte possible)
- At-least-once : Au moins une fois (doublons possibles)
- Exactly-once : Exactement une fois (idempotent, transactionnel)
Chapitre 11 : The Future of Data Systems
- Data Integration : Unifier batch et stream (Kappa architecture)
- Dataflow : Gérer le flux de données de bout en bout
- Weaving together : Composition de systèmes de données
- Ethics : Responsabilité des ingénieurs sur les données
Leçons Clés pour le Backend
- Connaître ses bases de données : Comprendre les trade-offs entre les modèles
- Les transactions simplifient la vie : Mais elles ont un coût en performance
- La cohérence distributive est un spectre : Pas seulement "cohérent" ou "pas cohérent"
- Les pannes arrivent : Concevoir pour la résilience, pas pour le cas parfait
- L'évolution du schéma est inévitable : Planifier les migrations dès le départ
- La mesure des performances est complexe : Percentiles, pas moyennes
2. Clean Architecture
Auteur : Robert C. Martin (Uncle Bob) Éditeur : Prentice Hall Année : 2017 Pages : 432 Difficulté : Intermédiaire Note : ★★★★★ (4.5/5)
Pourquoi lire ce livre
"Clean Architecture" étend les principes de "Clean Code" à l'architecture logicielle. Il montre comment structurer une application pour qu'elle reste maintenable, testable, et flexible face au changement.
Partie I : Introduction
Le Paradigme de la Programmation
- Structured programming : Contrôle direct (séquences, boucles, conditions)
- Object-oriented programming : Polymorphisme, encapsulation
- Functional programming : Immutabilité, aucune side effect
L'Objectif de l'Architecture
Une bonne architecture :
- Maximise le nombre de décisions non faites (options ouvertes)
- Rend le système facile à comprendre, déployer, opérer
- Permet de retarder les décisions d'infrastructure
- Protège le code métier des détails techniques
Partie II : Les Principes SOLID
Single Responsibility Principle (SRP)
Une classe ne devrait avoir qu'une seule raison de changer.
- Raison de changer = acteur qui demande le changement
- Séparer les responsabilités par acteur métier
- Ne pas mélanger UI, business logic, persistance dans la même classe
Open-Closed Principle (OCP)
Ouvert à l'extension, fermé à la modification.
- Ajouter du comportement sans modifier le code existant
- Utiliser l'héritage, le polymorphisme, les interfaces
- Exemple : Strategy pattern, Decorator pattern
Liskov Substitution Principle (LSP)
Une sous-classe doit pouvoir remplacer sa classe de base.
- Le contrat de la classe parent doit être respecté
- Ne pas affaiblir les préconditions
- Ne pas renforcer les postconditions
- Exemple : Square héritant de Rectangle est une violation LSP
Interface Segregation Principle (ISP)
Les interfaces ne devraient pas imposer des méthodes inutilisées.
- Préférer plusieurs interfaces spécifiques
- Éviter les "fat interfaces"
- Les clients ne dépendent pas de méthodes qu'ils n'utilisent pas
Dependency Inversion Principle (DIP)
Dépendre des abstractions, pas des concrétions.
- Les modules de haut niveau ne dépendent pas des modules de bas niveau
- Les deux dépendent d'abstractions
- Les abstractions ne dépendent pas des détails
Partie III : Les Composants
Cohésion des Composants
- REP : Reuse/Release Equivalence Principle
- CCP : Common Closure Principle (changements liés ensemble)
- CRP : Common Reuse Principle (ne pas forcer à dépendre de choses inutilisées)
Couplage des Composants
- ADP : Acyclic Dependencies Principle (pas de cycles dans le graphe de dépendances)
- SDP : Stable Dependencies Principle (dépendre dans la direction de la stabilité)
- SAP : Stable Abstractions Principle (la stabilité doit aller avec l'abstraction)
Partie IV : L'Architecture
L'Architecture Hexagonale (Ports & Adapters)
┌─────────────┐
│ Domain │
│ (Use Cases)│
└──────┬──────┘
│
┌──────────┼──────────┐
│ │ │
┌───▼───┐ ┌───▼───┐ ┌───▼───┐
│ Web │ │ DB │ │ API │
│(Input)│ │(Output)│ │(Third)│
└───────┘ └───────┘ └───────┘
- Le domaine est le centre : Pas de dépendance vers l'extérieur
- Les ports : Interfaces définies par le domaine
- Les adapteurs : Implémentations techniques (HTTP, SQL, etc.)
- Dependency Rule : Les dépendances pointent vers l'intérieur
Screaming Architecture
L'architecture devrait "crier" son intension : un système de santé n'a pas la même architecture qu'un système e-commerce, même s'ils utilisent les mêmes frameworks.
The Clean Architecture
Controllers → Use Cases → Entities
↓ ↓ ↓
Presenters Gateways Data Access
Règle de dépendance : Les cercles extérieurs peuvent dépendre des cercles intérieurs, jamais l'inverse.
Partie V : Détails
La Base de Données est un Détail
- La base de données n'est pas le modèle métier
- Le schéma relationnel n'est pas le modèle objet
- L'ORM est un détail d'implémentation
- Le stockage peut changer sans impacter le business logic
Le Web est un Détail
- HTTP, REST, GraphQL sont des détails de transport
- L'architecture ne devrait pas dépendre du framework web
- Le routing et la sérialisation sont périphériques
Les Frameworks sont des Détails
- Les frameworks sont des outils, pas des fondations
- S'appuyer sur les frameworks rend dépendant de leurs mises à jour
- Isoler le code métier des frameworks
Application Pratique
Structure de projet Clean Architecture :
src/
domain/ # Entités, value objects, aggregates
entities/
value-objects/
events/
application/ # Use cases, ports
use-cases/
ports/
in/ # Input ports (controllers appellent)
out/ # Output ports (repositories)
infrastructure/ # Adapters, frameworks
persistence/
web/
messaging/
Leçons Clés
- Le code métier est le plus important : Protégez-le des détails techniques
- Les frameworks sont des serviteurs, pas des maîtres
- La testabilité est une propriété architecturale
- Les dépendances doivent toutes pointer vers l'intérieur
- Une bonne architecture permet de retarder les décisions
- Les use cases sont le squelette de l'application
3. Building Microservices
Auteur : Sam Newman Éditeur : O'Reilly Media Année : 2021 (2ème édition) Pages : 612 Difficulté : Intermédiaire-avancé Note : ★★★★★ (4.6/5)
Pourquoi lire ce livre
"Building Microservices" de Sam Newman est le guide de référence pour concevoir, construire et opérer des microservices. Cette seconde édition intègre les retours d'expérience d'une décennie d'adoption des microservices.
Partie I : Fondations
Chapitre 1 : Qu'est-ce qu'un Microservice ?
Définition :
Les microservices sont des services autonomes, indépendamment déployables, qui collaborent entre eux, chacun possédant son propre modèle de données.
Caractéristiques :
- Indépendance de déploiement : Déployer sans impacter les autres
- Modelisation par domaine : Chaque service couvre un bounded context
- Ownership : Une équipe possède un service de bout en bout
- Isolation des données : Chaque service a sa propre base
- Réseau comme frontière : Communication via le réseau
Chapitre 2 : Le Modèle Technologique
Quand utiliser les microservices ?
- Équipes nombreuses (>2 pizza teams)
- Domaines complexes (DDD)
- Cycles de déploiement indépendants
- Exigences de scalabilité différentes par service
Quand éviter les microservices ?
- Projet simple/débutant
- Petite équipe (<5 personnes)
- Domaines transactionnels complexes
- Phase d'exploration (pivot rapide)
Partie II : Construction
Chapitre 3 : Communication Inter-Services
Sync vs Async :
- Synchrone (HTTP, gRPC) : Simple, familier, mais couplage temporel
- Asynchrone (Messaging) : Découplé, résilient, mais complexe
Patterns de communication :
- Request/Response : Appel direct
- Event-driven : Publier des événements
- CQRS : Séparer lectures et écritures
- Saga : Transactions distribuées
API Design :
- REST : Hypermédia, idempotence, statut codes
- gRPC : Performant, streaming, protobuf
- GraphQL : Requêtes flexibles, surcharge possible
Chapitre 4 : Implémentation
Choix technologiques :
- Langage approprié au service
- Base de données adaptée au besoin
- Framework consistant au sein du service
External Configuration :
- Variables d'environnement
- Service de configuration (Consul, etcd)
- Feature flags
Health checking :
- Liveness probe (est-ce vivant ?)
- Readiness probe (est-ce prêt à servir ?)
- Health endpoint exhaustif
Partie III : Opérations
Chapitre 5 : Déploiement
Stratégies :
- Blue/Green : Deux environnements, bascule instantanée
- Canary : Progression graduelle du trafic
- Rolling update : Mise à jour progressive des instances
Containerisation :
- Docker pour la standardisation
- Orchestration (Kubernetes)
- Images immutables
Chapitre 6 : Testing
Pyramide de test des microservices :
╱ E2E ╲
╱ Integration ╲
╱ Contract Tests ╲
╱ Component Tests ╲
╱ Unit Tests (base) ╲
- Unit tests : Logique métier, rapides et fiables
- Component tests : Service isolé, dépendances mockées
- Contract tests : Accords entre services (Pact)
- Integration tests : Service + dépendances réelles
- E2E tests : Flux complets, lents et fragiles
Chapitre 7 : Monitoring
- Logs centralisés : ELK, Loki
- Métriques : RED (Rate, Errors, Duration) / USE (Utilization, Saturation, Errors)
- Tracing distribué : OpenTelemetry, Jaeger, Zipkin
- Alerting : Basé sur SLO/SLI
Chapitre 8 : Sécurité
- API Gateway : Point d'entrée unique, auth centralisée
- JWT : Tokens porteurs d'identité
- Service mesh : mTLS, autorisation par service
- OAuth2 / OpenID Connect : Délégation d'authentification
- Secrets management : Vault, sealed secrets
Partie IV : Organisation
Chapitre 9 : Ownership et Couplage
- Bounded Context (DDD) : Frontière naturelle des services
- Team Topologies : Conway's Law en action
- Service boundaries : Ne pas partager de base de données
Types de services :
- Business domain services : Cœur métier
- Infrastructure services : Techniques (messaging, monitoring)
- Edge services : API Gateway, BFF
Chapitre 10 : Évolution
- Strangler Fig Pattern : Remplacer progressivement un monolithe
- Feature branches vs Trunk-based development
- Internal Open Source : Contribution cross-équipe
Leçons Clés
- Ne commencez pas par des microservices : Commencez monolithe, extrayez progressivement
- L'indépendance de déploiement est l'objectif principal
- La communication asynchrone augmente la résilience
- Chaque service doit posséder sa propre base de données
- Les contrats doivent être testés (Pact)
- L'observabilité est cruciale : Logs, métriques, traces
- Les équipes doivent être alignées sur les services
4. The Pragmatic Programmer
Auteurs : Andrew Hunt, David Thomas Éditeur : Addison-Wesley Année : 1999 (2ème édition: 2019) Pages : 352 Difficulté : Débutant-intermédiaire Note : ★★★★☆ (4.4/5)
Pourquoi lire ce livre
"The Pragmatic Programmer" est un classique qui transcende les technologies. Il enseigne une philosophie de développement : être pragmatique signifie prendre des décisions éclairées, responsables, et toujours chercher à améliorer sa pratique.
Philosophie : Le Programneur Pragmatique
Caractéristiques :
- Early adopter : Tester les nouvelles technologies
- Questionneur : Remettre en question les choix
- Penseur critique : Peser les pour et les contre
- Réaliste : Comprendre les compromis
Section 1 : Une Approche Pragmatique
The Cat Ate My Source Code
Responsabilité personnelle : Assumez la responsabilité de votre travail. Si vous faites une erreur, admettez-la et proposez des solutions, pas des excuses.
Software Entropy
La fenêtre brisée : Ne laissez pas le "désordre" s'installer. Réparez les petites choses qui ne vont pas dès que vous les voyez. Un code mal entretenu attire plus de code mal entretenu.
Stone Soup and Boiled Frogs
Le changement incrémental : Plutôt que de demander une révolution, montrez un petit résultat convaincant (Stone Soup). Méfiez-vous du changement graduel qui empire la situation (Boiled Frog).
Good Enough Software
Savoir s'arrêter : La perfection n'est pas atteignable. Savoir quand "assez bien" est vraiment assez bien pour le client. Ne sacrifiez pas la qualité pour la perfection.
Your Knowledge Portfolio
Investir dans sa connaissance : Traitez vos compétences comme un portefeuille d'investissement.
- Investir régulièrement (lecture, side projects)
- Diversifier (plusieurs langages, domaines)
- Équilibrer risque et sécurité (learning vs earning)
- Réévaluer périodiquement
Communicate!
La communication est une compétence : Savoir documenter, présenter, écouter. Adapter le message à l'audience. Connaître le "pourquoi" avant le "comment".
Section 2 : Une Approche Pragmatique
The Evils of Duplication
DRY (Don't Repeat Yourself) : Chaque connaissance doit avoir une représentation unique et non ambiguë dans le système.
Types de duplication :
- Imposée : Documentation qui répète le code
- Involontaire : Copier-coller ignorant
- Impatiente : Solution rapide qui duplique
- Inter-développeurs : Communication insuffisante
Orthogonality
L'orthogonalité : Des changements indépendants doivent être indépendants.
Avantages :
- Changements localisés
- Testabilité améliorée
- Réutilisabilité
- Moins de risques de régression
Application :
- Séparation des couches
- Pas de dépendances circulaires
- Modules faiblement couplés
Reversibility
Gardez les options ouvertes : Rien n'est permanent. Les choix technologiques (framework, base de données, cloud) ne devraient pas être irréversibles.
Tracer Bullets
Le code traceur : Au lieu de spécifier tout le système avant de coder, construisez un squelette fonctionnel de bout en bout.
Avantages :
- Feedback immédiat
- Découverte précoce des problèmes
- Démo utilisateur rapide
- Base pour ajouter des fonctionnalités
Prototypes and Post-it Notes
Prototyper pour apprendre : Un prototype répond à une question à moindre coût. Jetez-le après usage.
Ce qu'on peut prototyper :
- Architecture
- Nouvelles fonctionnalités
- UX / UI flows
- Modèles de données
Domain Languages
Parler le langage du domaine : Créez des mini-langages (DSL) qui reflètent le vocabulaire métier.
Estimating
Estimer n'est pas promettre : L'estimation est une approximation. Un ordre de grandeur (x2, x4, x8) est souvent plus utile qu'une fausse précision.
Section 3 : Le Processus
The Power of Plain Text
Le texte brut comme format de stockage : Utilisez des formats lisibles (JSON, YAML, CSV) pour la persistance. Ils survivent aux outils et plateformes.
Shell Games
Maîtrisez votre shell : L'investissement dans la maîtrise du terminal (scripting, pipes, automation) rapporte énormément.
Source Code Control
Le contrôle de version comme filet de sécurité : Tout doit être versionné (code, config, scripts, documentation). Commitez tôt, commitez souvent.
Debugging
Debugger est un art :
- Ne paniquez pas, analysez
- Reproduisez le bug avant de le corriger
- Cherchez la cause racine, pas les symptômes
- Changez une variable à la fois
- Rubber duck debugging
Text Manipulation
Apprenez un langage de manipulation de texte : Perl, Python, awk, ou même bash. Utile pour transformer des données, générer du code, analyser des logs.
Code Generators
Générez du code répétitif : Templates, codegen, scaffolding. Évitez la duplication.
Section 4 : Le Code
Design by Contract
Les contrats définissent les responsabilités :
- Préconditions : Ce que la fonction attend
- Postconditions : Ce que la fonction garantit
- Invariants : Ce qui ne change pas
Dead Programs Tell No Lies
Échouer tôt : Détecter et signaler les erreurs le plus tôt possible, idéalement à la compilation.
Assertive Programming
Les assertions ne remplacent pas les tests : Utilisez des assertions pour documenter les invariants et détecter les bugs.
How to Balance Resources
Acquérir puis libérer : Toute ressource (mémoire, fichier, lock, connexion) doit être libérée. Utilisez RAII en C++,
usingen C#,finallyen Java, oudeferen Go.
Don't Outrun Your Headlights
Ne dépassez pas la portée de vos phares : Allez à la vitesse où vous pouvez prendre des décisions éclairées. Le refactoring est plus rapide que le big design up front.
Section 5 : Les Outils
Version Control
Git, mais aussi la connaissance des workflows (merge vs rebase, branching strategies)
Debuggers
Savoir utiliser son debugger en conditions réelles : breakpoints conditionnels, expression evaluation, remote debugging.
Profilers
Performance Driven Development : Profiler avant d'optimiser. Les hotspots sont rarement où on les imagine.
Test Harnesses
Tester n'est pas optionnel : Tests unitaires, intégration, acceptation. L'automation est clé.
Leçons Clés
- Soyez responsable de votre code : Ne rejetez pas la faute
- DRY, mais pas trop : L'abstraction intempestive est aussi nuisible
- Investissez dans votre boîte à outils : Shell, éditeur, debugger
- Le code traceur pour l'exploration, les prototypes pour l'apprentissage
- Estimer est difficile : Prévoyez des marges
- La communication est aussi importante que le code
- Le changement est inévitable : Concevez pour le changement
5. System Design Interview
Auteur : Alex Xu Éditeur : Independently published Année : 2021 Pages : 280 Difficulté : Intermédiaire Note : ★★★★☆ (4.5/5)
Pourquoi lire ce livre
"System Design Interview" prépare aux entretiens de conception de systèmes des grandes entreprises (FAANG). Chaque chapitre présente un problème classique d'architecture et le résout étape par étape.
Framework Système
Les 4 étapes
1. Comprendre le problème et définir le scope
- Poser des questions clarifiant le périmètre
- Ne pas présumer des besoins
- Identifier les features clés vs nice-to-have
2. Proposer une architecture de haut niveau
- Dessiner le diagramme (whiteboard)
- Identifier les composants principaux
- Discuter des trade-offs
3. Approfondir la conception
- Détail des composants clés
- Data flow
- APIs et interfaces
4. Discussion sur la scalabilité
- Goulots d'étranglement
- Optimisations possibles
- Compromis retenus
Études de Cas
1. Conception d'un URL Shortener (bit.ly)
Exigences :
- 100M URLs créées par mois
- Redirections rapides (< 10ms)
- URLs courtes (6-7 caractères)
- Analytics (clics par URL)
- Disponibilité > 99.9%
Solution :
Diagramme en cours de génération...
Data model :
CREATE TABLE urls (
id BIGSERIAL PRIMARY KEY,
short_key VARCHAR(7) UNIQUE NOT NULL,
original_url TEXT NOT NULL,
user_id BIGINT REFERENCES users(id),
created_at TIMESTAMP DEFAULT NOW(),
expires_at TIMESTAMP,
clicks BIGINT DEFAULT 0
);
CREATE INDEX idx_short_key ON urls(short_key);
ID Generation : Base62 encoding (62^7 = 3.5 trillion combinaisons)
- Snowflake ID pattern
- Pre-generated keys en cache
Redirection :
- CDN pour short_key → original_url
- Redis cache (TTL: 1 hour)
- 301 redirect permanent vs 302 temporary
- Analytics async via Kafka
Scalabilité :
- Read replicas PostgreSQL
- Cache Redis cluster
- CDN pour redirections
- Sharding par hash de short_key
2. Conception d'un Chat System (WhatsApp)
Exigences :
- 1-to-1 et group chat
- Messages temps réel
- 100M DAU
- Messages persistants (history)
- Chiffrement de bout en bout
Architecture :
Client ←WebSocket→ Chat Service (Session)
│
┌─────────┼─────────┐
│ │ │
Message Presence Notification
Service Service Service
│ │
Message Online
Store Store
(Cassandra) (Redis)
WebSocket Management :
- Persistent connection manager
- Session store (Redis)
- Heartbeat pour détecter les déconnexions
Message Flow :
- Client envoie message via WebSocket
- Chat Service ajoute message_id (seq local)
- Message Service stocke (Cassandra, partitionné par conversation)
- Presence Service vérifie l'état du destinataire
- Si online, message immédiat via WebSocket
- Si offline, push notification (APNS/FCM)
- Sync des messages manquants à la reconnexion
Data Model Cassandra :
CREATE TABLE messages (
conversation_id UUID,
created_at TIMESTAMP,
message_id TIMEUUID,
sender_id UUID,
content TEXT,
message_type INT,
PRIMARY KEY (conversation_id, created_at, message_id)
) WITH CLUSTERING ORDER BY (created_at DESC);
3. Conception d'un News Feed (Facebook)
Exigences :
- 500M DAU
- Feed personnalisé
- Posts, photos, vidéos
- Real-time updates
- Scroll infini
Stratégies :
- Fan-out on write : Pré-calculer le feed pour chaque follower
- Fan-out on read : Calculer à la demande
- Hybrid : Pour les célébrités (read), pour les amis (write)
Architecture Feed :
Post Service → Queue → Fanout Service → Feed Cache (Redis)
│
Client ←→ Feed Service ←── Feed Cache
Feed Ranking :
- Relevancy score (ML model)
- Recency (décroissance temporelle)
- Affinity (fréquence d'interaction)
- Content type (video > photo > text)
- Diversity (éviter domination)
ML Model Features :
- User engagement history
- Post interactions rate
- Time since post
- Relationship strength
- Content category preference
Scalabilité :
- Feed cache Redis Cluster (sharding par user_id)
- Batch pre-computation aux heures creuses
- Load shedding en pic
- Personalized ranking via ML service
4. Conception d'un Système de Paiement (Stripe)
Exigences :
- Traitement de paiements
- Gestion des échecs et retours
- Idempotence (ne pas débiter deux fois)
- Conformité PCI DSS
- Reporting et analytics
Architecture :
Client → API Gateway → Payment Service
│
┌──────┴──────┐
│ │
Payment Provider Accounting
(Stripe, Adyen) Service
│
Ledger DB
(Immutable)
Idempotency :
- Clé d'idempotence dans le header
- Stockée dans Redis avec TTL
- Même clé = même résultat, pas de charge
État d'une transaction :
Initiated → Processing → Completed
│ │
▼ ▼
Failed Refunded → Refunded
Saga Pattern :
1. Reserve funds (Payment Service)
2. Update inventory (Inventory Service)
3. Confirm payment
4. Send confirmation email
Si échec à l'étape 2 : Release funds (compensation)
5. Conception d'un Système de Notification
Types : Push (mobile), SMS, Email, In-app
Architecture :
Notification Service
│
├──→ Template Service
├──→ Rate Limiter (Redis)
├──→ Priority Queue
│
└──→ Channel Gateways
├── APNS (iOS)
├── FCM (Android)
├── Twilio (SMS)
├── SES/SendGrid (Email)
└── WebSocket (In-app)
Rate Limiting par canal :
- Redis sorted set (sliding window)
- Limites configurables par type et priorité
- Priority levels (critical, high, normal, low)
Leçons Clés
- Framework structuré : Scope → High-level → Deep-dive → Scale
- Les trade-offs sont importants : Montrez que vous comprenez les compromis
- Chiffres de dimensionnement : QPS, storage, bandwidth, cache size
- Designs résilients : SPOF, circuit breaker, retry, fallback
- Data consistency : CAP theorem, eventual vs strong consistency
- Always be ready to discuss trade-offs : Il n'y a pas de solution parfaite
Conclusion : Plan de Lecture
Par ordre de priorité
- Designing Data-Intensive Applications — Systèmes distribués (fondations)
- Clean Architecture — Architecture logicielle (structure)
- Building Microservices — Microservices (pratique)
- The Pragmatic Programmer — Philosophie (fondations du métier)
- System Design Interview — Préparation entretiens (cas concrets)
Par niveau
| Niveau | Livre | Pourquoi |
|---|---|---|
| Débutant | The Pragmatic Programmer | Fondations du métier |
| Intermédiaire | Clean Architecture | Architecture et design |
| Intermédiaire | Building Microservices | Architecture distribuée |
| Avancé | Designing Data-Intensive Applications | Systèmes distribués |
| Entretiens | System Design Interview | Pratique et cas concrets |