Template de Réponse pour un Entretien System Design
La plupart des gens échouent aux entretiens de system design non pas par manque de connaissances techniques, mais par manque de structure. Ils connaissent les load balancers, les couches de cache et les files de messages — mais quand l’intervieweur dit « Conçois Twitter », leur cerveau déverse tout en même temps, sans ordre particulier.
Ce template vous donne la structure. C’est un framework à remplir que vous pouvez utiliser pour n’importe quelle question de system design. Je l’ai construit après avoir affiné le framework URDGE au fil de dizaines d’entretiens blancs. Le framework vous dit quelles étapes suivre. Ce template vous dit exactement quoi écrire au tableau à chaque étape.
Le Template (35 à 45 minutes au total)
Étape 1 : Clarifier les exigences (5 minutes)
Écrivez ces en-têtes sur votre tableau blanc ou document partagé :
EXIGENCES FONCTIONNELLES
-------------------------
1. [Fonctionnalité principale que le système DOIT réaliser]
2. [Deuxième fonctionnalité la plus importante]
3. [Troisième fonctionnalité]
(Limitez à 3-5. Plus = dérive du périmètre.)
EXIGENCES NON FONCTIONNELLES
------------------------------
- Objectif de disponibilité : [99,9 % ? 99,99 % ?]
- Objectif de latence : [< 200ms ? < 1s ?]
- Modèle de cohérence : [Forte ? Éventuelle ?]
- Échelle : [DAU ? QPS ? Volume de données ?]
HORS PÉRIMÈTRE
----------------
- [Fonctionnalité que vous ne concevez explicitement PAS]
- [Autre élément hors périmètre]
Ce qu’il faut dire : « Avant de commencer à concevoir, je veux m’assurer de bien comprendre les exigences. Voici ce que j’ai compris — corrigez-moi si je me trompe. »
Pourquoi ça marche : Cela montre à l’intervieweur que vous réfléchissez avant de construire. Cela verrouille aussi le périmètre pour éviter de perdre du temps sur des fonctionnalités que personne n’a demandées.
Étape 2 : Estimation rapide (3 minutes)
ESTIMATIONS D'ÉCHELLE
----------------------
Utilisateurs : [___] DAU
QPS en lecture : [___] requêtes/sec
QPS en écriture : [___] requêtes/sec
Stockage : [___] Go/jour → [___] To sur 5 ans
Bande passante : [___] Mo/s
RATIO CLÉ : Lecture:Écriture = [___:___]
Ce qu’il faut dire : « Laissez-moi faire un calcul rapide pour comprendre l’échelle à laquelle nous concevons. Cela va orienter nos décisions d’architecture. »
Formules à retenir :
- QPS = DAU × requêtes moyennes par utilisateur / 86 400
- QPS en pointe ≈ 2-5× le QPS moyen
- Stockage = nouveaux enregistrements par jour × taille d’un enregistrement × période de rétention
Quand sauter cette étape : Si l’intervieweur dit « ne vous souciez pas des chiffres » ou si vous manquez de temps. Certains intervieweurs y tiennent, d’autres non. Lisez la situation.
Étape 3 : Conception de haut niveau (10-15 minutes)
Dessinez ces composants. Tout system design en contient la plupart :
ARCHITECTURE DE HAUT NIVEAU
=============================
[Client] → [Load Balancer] → [API Gateway / Serveurs Web]
↓
[Service(s) Applicatif(s)]
↓ ↓
[Base de données] [Couche de Cache]
↓
[Stockage Objet] (si médias/fichiers)
ENDPOINTS API
--------------
POST /api/v1/[ressource] → Créer [chose]
GET /api/v1/[ressource]/:id → Lire [chose]
GET /api/v1/[ressource] → Lister [choses] (paginé)
DELETE /api/v1/[ressource]/:id → Supprimer [chose]
MODÈLE DE DONNÉES
------------------
Table : [entite_principale]
- id : UUID (clé primaire)
- [champ_1] : [type]
- [champ_2] : [type]
- created_at : timestamp
- updated_at : timestamp
- INDEX sur [champ] pour [pattern de requête]
Table : [entite_liee]
- id : UUID (clé primaire)
- [champ_fk] : UUID (clé étrangère → entite_principale)
- [champ] : [type]
Ce qu’il faut dire : « Voici mon architecture de haut niveau. Laissez-moi vous guider à travers le flux de requête pour le cas d’utilisation principal. »
Astuce : Déroulez UN flux de requête complet du client à la base de données et retour. « Un utilisateur crée un [objet] : la requête arrive au load balancer, est routée vers un serveur web, le service valide les données, écrit en base, invalide le cache et retourne un 201 avec la ressource créée. »
Étape 4 : Approfondissement des composants clés (10-15 minutes)
Choisissez 2 à 3 composants à approfondir. Sélectionnez-les en fonction des défis les plus intéressants pour CE système spécifique.
APPROFONDISSEMENT : [Nom du Composant]
========================================
Défi : [Qu'est-ce qui rend cela difficile à grande échelle ?]
Approche : [Votre solution]
Alternatives envisagées :
- [Option A] : [Avantage] / [Inconvénient]
- [Option B] : [Avantage] / [Inconvénient]
- [Approche choisie] : [Pourquoi celle-ci gagne pour nos exigences]
Détail d'implémentation :
[Détail technique spécifique montrant votre profondeur]
Sujets d’approfondissement courants et quand les utiliser :
| Sujet | À utiliser quand le système a besoin de… |
|---|---|
| Partitionnement de base de données | Débit élevé en écriture ou volume massif de données |
| Stratégie de cache | Lectures à faible latence, ratio lecture:écriture élevé |
| File de messages / traitement asynchrone | Services découplés, cohérence éventuelle acceptable |
| Limitation de débit | API publique, prévention des abus |
| Recherche / indexation | Recherche plein texte, recommandations |
| Système de notifications | Mises à jour en temps réel, diffusion massive |
| CDN / stockage média | Diffusion d’images/vidéos, distribution mondiale |
| Protocole de cohérence | Transactions financières, gestion des stocks |
Ce qu’il faut dire : « Je pense que le défi le plus intéressant dans ce système est [X]. Laissez-moi approfondir la manière dont je gérerais cela. »
Étape 5 : Goulots d’étranglement et compromis (5 minutes)
GOULOTS D'ÉTRANGLEMENT ET ATTÉNUATIONS
=========================================
1. Point de défaillance unique : [composant]
→ Atténuation : [stratégie de redondance]
2. Partition chaude / clé chaude : [scénario]
→ Atténuation : [stratégie de distribution]
3. Cohérence des données : [où c'est critique]
→ Atténuation : [approche de cohérence]
COMPROMIS EFFECTUÉS
=====================
- Choisi [A] plutôt que [B] parce que [l'exigence X compte plus que Y]
- Accepté [limitation] en échange de [bénéfice]
- Réévaluerait [décision] si [condition change]
Ce qu’il faut dire : « Aucune conception n’est parfaite. Laissez-moi vous présenter les compromis que j’ai faits et les modes de défaillance potentiels. »
C’est ici que les candidats seniors se démarquent. Les juniors présentent leur conception comme si elle était sans défaut. Les seniors identifient proactivement les faiblesses et expliquent pourquoi elles sont acceptables au regard des exigences.
Exemple rempli : Concevoir un raccourcisseur d’URL
Exigences
EXIGENCES FONCTIONNELLES
- Les utilisateurs peuvent créer une URL courte à partir d'une URL longue
- Les utilisateurs peuvent visiter une URL courte et être redirigés
- Les URL courtes expirent après un TTL configurable
EXIGENCES NON FONCTIONNELLES
- Objectif de disponibilité : 99,99 % (les lectures doivent toujours fonctionner)
- Latence : < 50ms pour les redirections
- Cohérence : éventuelle acceptable (un léger délai avant qu'une nouvelle URL fonctionne est OK)
- Échelle : 100M DAU, 1 milliard de redirections/jour
HORS PÉRIMÈTRE
- Tableau de bord analytique
- URL personnalisées (vanity URLs)
- Comptes utilisateurs
Estimation
QPS en lecture : 1Md / 86 400 ≈ ~12 000/sec (pointe : ~36 000/sec)
QPS en écriture : 100M / 86 400 ≈ ~1 200/sec (pointe : ~3 600/sec)
Lecture:Écriture = 10:1
Stockage : 100M URL/jour × 500 octets ≈ 50 Go/jour → ~90 To sur 5 ans
Conception de haut niveau
[Client] → [Load Balancer] → [Serveurs API]
↓
[Cache Redis] ← [Service URL] → [PostgreSQL]
POST /api/v1/urls {long_url, ttl} → Retourne {short_url}
GET /:short_code → Redirection 301 vers long_url
Table : urls
- short_code : VARCHAR(7) PRIMARY KEY
- long_url : TEXT
- created_at : TIMESTAMP
- expires_at : TIMESTAMP
- INDEX sur expires_at pour le nettoyage
Approfondissement : Génération du code court
Défi : Générer des codes uniques de 7 caractères à 3 600/sec sans collision.
Approche : Encodage Base62 d'un compteur issu d'un générateur d'identifiants distribué (type Snowflake).
Alternatives :
- Hash MD5 + troncature : Simple mais risque de collision à grande échelle
- Génération aléatoire + vérification en base : Fonctionne mais ajoute de la latence en écriture
- Basé sur un compteur (choisi) : Garanti unique, prévisible, rapide
Détail : Utiliser un identifiant de type Snowflake (timestamp + ID du worker + séquence).
Encoder en Base62 pour obtenir une chaîne de 7 caractères. Aucune collision possible par construction.
Compromis
- Choisi la cohérence éventuelle : les nouvelles URL peuvent mettre 1 à 2 secondes à se propager
sur tous les nœuds de cache. Acceptable car les utilisateurs ne partagent pas une URL
dans la première milliseconde.
- Choisi PostgreSQL plutôt que DynamoDB : opérations plus simples, et notre QPS en écriture
(3 600/sec) est largement dans les capacités de PostgreSQL avec du connection pooling.
- Accepté que les codes basés sur un compteur sont devinables : si la confidentialité des URL
est nécessaire, on passerait à une génération aléatoire avec retry en cas de collision.
Comment s’entraîner avec ce template
- Choisissez une question de system design (raccourcisseur d’URL, messagerie, fil d’actualité, système de parking).
- Lancez un minuteur de 40 minutes.
- Remplissez chaque section du template sur papier ou au tableau blanc.
- Chronométrez chaque section. Si vous passez plus de 5 minutes sur les exigences, vous élargissez trop le périmètre.
- Entraînez-vous à expliquer chaque section à voix haute, comme si un intervieweur vous observait.
Répétez avec une question différente tous les deux ou trois jours. Après cinq séances d’entraînement, le template devient automatique et vous pouvez vous concentrer entièrement sur le contenu technique au lieu de vous demander « qu’est-ce que je dis ensuite ? ».
La structure est le filet de sécurité. Vos connaissances sont la performance. Ce template garantit que le filet est toujours là pour que vous puissiez prendre des risques dans vos choix de conception sans sombrer dans le chaos.