ITSkillsCenter
Carrière & Entretien

System design en entretien : concevoir un raccourcisseur d’URL scalable pas à pas

14 دقائق للقراءة
Guide principal : Réussir les entretiens techniques : algorithmes, complexité et system design. Ce tutoriel approfondit une compétence précise du parcours.

On vous tend un marqueur, on vous montre un tableau blanc, et on lâche une phrase qui glace le sang : « concevez-moi un service de raccourcissement d’URL, comme ceux qui transforment une longue adresse en un lien court. » Pas d’énoncé précis, pas de bonne réponse unique, quarante-cinq minutes pour mener une discussion d’architecture. C’est l’épreuve de system design, et elle déroute parce qu’elle ne récompense pas une solution apprise, mais une méthode de raisonnement. La bonne nouvelle : cette méthode est rigoureusement la même d’un sujet à l’autre.

Dans ce tutoriel, vous allez dérouler cette méthode de bout en bout sur un cas que les recruteurs adorent, le raccourcisseur d’URL. Vous clarifierez le besoin, estimerez la charge, dessinerez l’interface, modéliserez les données, concevrez le cœur du système, puis le ferez passer à l’échelle. À la fin, vous tiendrez un canevas réutilisable pour n’importe quel sujet de system design.

Ce que vous allez apprendre

  • Mener un exercice de system design selon une séquence d’étapes reproductible.
  • Estimer un ordre de grandeur de trafic et de stockage à partir d’hypothèses simples.
  • Concevoir la génération de codes courts sans collision, et justifier ce choix.
  • Identifier les points de rupture d’une architecture et proposer des parades : cache, réplication, partitionnement.

Ce que vous allez construire

Vous produirez, étape après étape, le schéma complet d’un service de raccourcissement d’URL capable d’encaisser une forte charge en lecture : son interface, son modèle de données, son mécanisme de génération de codes, sa stratégie de cache et son plan de mise à l’échelle. Le livrable réel est la démarche, transposable à un fil d’actualité, une messagerie ou tout autre système qu’on vous soumettra.

Prérequis

  • Comprendre ce qu’est une base de données, un cache et une requête HTTP.
  • Avoir une intuition des ordres de grandeur (millions, milliards, téraoctets).
  • Aucun code lourd : le system design se discute surtout en schémas et en compromis.
  • Temps estimé : environ 45 minutes.

Étape 1 — Clarifier le besoin avant tout

La pire erreur consiste à se jeter sur l’architecture sans savoir ce qu’on construit. Un examinateur teste précisément votre capacité à poser les bonnes questions. Séparez d’abord les besoins fonctionnels — ce que le système fait — des besoins non fonctionnels — la qualité avec laquelle il le fait. Côté fonctionnel, notre service doit faire deux choses : créer un code court à partir d’une longue URL, et rediriger un visiteur du code court vers l’URL d’origine. On peut ajouter des options : expiration des liens, codes personnalisés, statistiques de clics.

Côté non fonctionnel, posez les questions qui dimensionnent tout le reste. Quelle disponibilité vise-t-on ? Une redirection cassée est très visible, donc on veut une haute disponibilité. Quelle latence ? La redirection doit être quasi instantanée. Quel profil de trafic ? Ici un point capital se dégage : on lit un lien court bien plus souvent qu’on n’en crée. Le système est massivement orienté lecture, et cette asymétrie guidera nos choix d’optimisation. Énoncer cette observation à voix haute marque des points immédiatement.

Étape 2 — Estimer l’ordre de grandeur

On ne conçoit pas dans le vide : quelques calculs d’enveloppe fixent les contraintes. Posons une hypothèse de travail, à valider avec l’examinateur : cent millions de nouvelles URL créées par mois. Un mois compte environ deux millions six cent mille secondes, ce qui donne autour de quarante créations par seconde en moyenne. Avec un ratio de lecture sur écriture de cent pour un — cohérent avec un service de redirection — on atteint de l’ordre de quatre mille lectures par seconde. Ces chiffres modestes en écriture mais élevés en lecture confirment qu’il faut surtout optimiser la lecture.

Passons au stockage. Cent millions d’URL par mois, sur cinq ans, font six milliards d’enregistrements. En comptant généreusement cinq cents octets par enregistrement — l’URL longue, le code, des métadonnées — on arrive autour de trois téraoctets de données sur cinq ans. C’est tout à fait gérable par une base de données moderne, éventuellement répartie. Ces estimations ne visent pas la précision comptable ; elles donnent l’échelle, et c’est l’échelle qui dicte l’architecture.

Étape 3 — Définir l’interface

Une fois le besoin cadré, exposez l’interface du service. Deux points d’entrée suffisent au cœur du système. Le premier crée un lien, le second le résout. Présenter cette interface tôt montre que vous savez délimiter un contrat clair avant de plonger dans l’implémentation.

Opération Méthode Entrée Sortie
Créer un lien POST URL longue, expiration optionnelle URL courte
Résoudre un lien GET Code court Redirection vers l’URL longue

La résolution renvoie une redirection HTTP. On préfère généralement une redirection temporaire à une redirection permanente, car la première laisse passer chaque requête par le service et permet ainsi de compter les clics, alors que la seconde serait mise en cache par le navigateur et masquerait le trafic réel. Ce genre de détail, mentionné spontanément, témoigne d’une vraie compréhension du fonctionnement du web.

Étape 4 — Modéliser les données

Le modèle de données est d’une simplicité trompeuse. On a besoin d’une correspondance entre un code court et une URL longue, plus quelques métadonnées. Un enregistrement contient un identifiant interne, le code court, l’URL d’origine, une date de création et une éventuelle date d’expiration. Le code court est l’élément sur lequel on cherche le plus souvent : il doit donc être indexé pour une recherche en temps quasi constant.

Quel type de base choisir ? Le profil d’accès est élémentaire : on cherche par clé, on ne fait pas de requêtes analytiques complexes. Une base relationnelle classique convient parfaitement à cette échelle, et une base clé-valeur conviendrait tout aussi bien, voire mieux pour la lecture pure. L’important n’est pas de réciter un nom de produit, mais de justifier le choix par le profil d’accès — recherche par clé, faible complexité relationnelle, fort volume de lecture.

Étape 5 — Générer le code court sans collision

C’est le cœur technique de l’exercice. Comment fabriquer un code court, unique, et le plus bref possible ? Deux familles d’approches existent, et savoir les comparer fait toute la différence.

La première consiste à hacher l’URL longue et à garder les premiers caractères du résultat. Simple, mais deux URL différentes peuvent produire le même préfixe : c’est une collision, qu’il faut détecter et corriger, ce qui complique le code. La seconde approche, plus propre, attribue à chaque nouvelle URL un identifiant numérique qui s’incrémente, puis convertit ce nombre en une chaîne courte. Comme chaque identifiant est unique par construction, aucune collision n’est possible. La conversion utilise un alphabet de soixante-deux caractères — les chiffres, les minuscules et les majuscules — d’où le nom de base 62.

ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
BASE = len(ALPHABET)

def encoder_base62(nombre):
    if nombre == 0:
        return ALPHABET[0]
    code = []
    while nombre > 0:
        nombre, reste = divmod(nombre, BASE)
        code.append(ALPHABET[reste])
    return "".join(reversed(code))

print(encoder_base62(125))  # '21'

La fonction divise le nombre par soixante-deux à répétition et accumule les restes, comme une conversion en base classique ; le résultat pour cent vingt-cinq est '21'. L’intérêt de la base 62 est sa densité : avec seulement sept caractères, on code soixante-deux puissance sept combinaisons, soit environ trois mille cinq cents milliards de codes distincts — largement de quoi couvrir les six milliards d’URL estimées sur cinq ans, avec une marge confortable. Six caractères suffiraient déjà pour cet horizon, mais sept offrent de la réserve pour la croissance.

Reste une subtilité d’architecture : si plusieurs serveurs créent des liens en parallèle, ils ne doivent pas attribuer le même identifiant. On confie alors la distribution des identifiants à un service dédié, qui remet à chaque serveur une plage de numéros à consommer. Évoquer ce point montre que vous anticipez les problèmes de concurrence d’un système distribué.

Étape 6 — Optimiser la lecture : le cache

Souvenez-vous de l’asymétrie repérée à l’étape un : le système lit cent fois plus qu’il n’écrit. C’est ici qu’on en tire parti. Une petite fraction des liens concentre l’essentiel du trafic — un lien viral peut être cliqué des millions de fois. Plutôt que d’interroger la base à chaque redirection, on place devant elle un cache en mémoire qui garde les codes les plus demandés. Une requête trouve alors sa réponse en mémoire, en quelques fractions de milliseconde, sans toucher la base.

La stratégie habituelle est de conserver dans le cache les entrées les plus récemment utilisées et d’évincer les plus anciennes quand la place manque. Ce comportement, dit du moindre récemment utilisé, épouse parfaitement le profil d’un service de liens où la popularité est très concentrée. En entretien, précisez le critère d’éviction et estimez le taux de succès du cache : un cache qui sert quatre-vingt-dix pour cent des lectures soulage massivement la base.

Étape 7 — Passer à l’échelle

Une fois le cœur posé, on le rend robuste à la charge. Plusieurs leviers se combinent. D’abord, on place un répartiteur de charge devant plusieurs serveurs applicatifs identiques, de sorte qu’aucune machine ne soit un point unique de défaillance et que le trafic se distribue. Ces serveurs sont sans état — toute la mémoire durable est dans la base et le cache — ce qui permet d’en ajouter ou d’en retirer librement.

Ensuite, on réplique la base de données : une copie principale reçoit les écritures, et plusieurs copies secondaires servent les lectures, ce qui colle à notre profil orienté lecture. Si le volume dépasse ce qu’une seule base encaisse, on partitionne les données — on parle de sharding — en répartissant les enregistrements sur plusieurs bases selon le code court. Enfin, pour un public mondial, un réseau de diffusion de contenu rapproche les redirections des utilisateurs géographiquement.

C’est aussi le moment d’évoquer un compromis fondamental des systèmes distribués, souvent attendu par l’examinateur : en cas de partition du réseau entre les copies de la base, il faut choisir entre garder une cohérence stricte des données et préserver la disponibilité du service. Pour un raccourcisseur d’URL, on privilégie en général la disponibilité — mieux vaut une redirection qui fonctionne, quitte à ce qu’un lien tout juste créé mette une seconde à se propager partout.

Étape 8 — Récapituler l’architecture à voix haute

Terminez toujours par une synthèse : redessinez le flux complet en une phrase. Une requête de création arrive par le répartiteur, atteint un serveur applicatif qui obtient un identifiant, l’encode en base 62, enregistre la correspondance et renvoie le lien court. Une requête de redirection arrive par le répartiteur, consulte d’abord le cache, retombe sur la base répliquée en cas d’absence, et renvoie la redirection. Cette récapitulation prouve que vous tenez le système dans son ensemble et que chaque composant a sa raison d’être. C’est sur cette vue d’ensemble maîtrisée que se joue la note finale.

Pièges fréquents

Symptôme Cause probable Correctif
Architecture hors-sol, surdimensionnée On a conçu sans estimer la charge Toujours chiffrer le trafic et le stockage d’abord
Codes courts en collision Génération par hachage tronqué Préférer un identifiant unique encodé en base 62
Base saturée en lecture Pas de cache devant la base Ajouter un cache en mémoire des liens populaires
Identifiants dupliqués entre serveurs Génération concurrente non coordonnée Distribuer des plages d’identifiants par un service dédié
Point unique de défaillance Un seul serveur ou une seule base Répartiteur de charge, serveurs sans état, réplication

S’adapter au contexte ouest-africain

Les exercices de system design se discutent à voix haute sur un tableau blanc partagé en visioconférence. Préparez-vous à dessiner clairement même avec un outil de schéma rudimentaire et une connexion qui peut hoqueter : entraînez-vous à décrire votre architecture en mots, de façon que l’examinateur suive même si votre partage d’écran se fige une seconde. Sur le fond, gardez en tête que les contraintes locales — bande passante limitée, latence vers des serveurs lointains — rendent le cache et un réseau de diffusion encore plus pertinents qu’ailleurs : un service pensé pour rapprocher les données des utilisateurs est précisément ce qui rend une application fluide depuis Dakar, Abidjan ou Lomé. Mentionner cette sensibilité à la latence réelle des utilisateurs est un atout en entretien.

Récapitulatif

Vous venez de mener un exercice de system design complet selon une séquence claire : clarifier, estimer, exposer l’interface, modéliser, concevoir le cœur, optimiser la lecture, passer à l’échelle, synthétiser. Le raccourcisseur d’URL n’était qu’un support ; la vraie acquisition est cette méthode en huit temps, qui s’applique à presque tous les sujets. Face à un nouvel énoncé, déroulez les mêmes étapes : elles vous éviteront le pire écueil, foncer dans l’architecture sans avoir compris le problème.

Aide-mémoire

Étape Question clé
Clarifier Que fait le système, et avec quelle qualité ?
Estimer Quel trafic, quel stockage en ordre de grandeur ?
Interface Quel contrat minimal exposer ?
Données Quel modèle, quelle base selon le profil d’accès ?
Cœur Quel est le point technique central à résoudre ?
Cache Comment tirer parti de l’asymétrie lecture/écriture ?
Échelle Où sont les points de rupture, quelles parades ?

À vous de jouer

Un défi de réflexion, sans code : on vous demande d’ajouter aux liens une fonction de statistiques — compter et dater chaque clic. Quel composant ajoutez-vous, et pourquoi évitez-vous d’écrire dans la base principale à chaque clic ? Réfléchissez avant de déplier.

Voir une piste

Écrire en base à chaque clic surchargerait la copie principale et ralentirait les redirections. On préfère émettre un événement de clic vers une file de messages, qu’un service de traitement consomme en arrière-plan pour agréger les statistiques sans bloquer la redirection. Ce découplage, qui sépare le chemin critique de la lecture du traitement annexe, est un schéma récurrent en system design.

Tutoriels frères

Pour aller plus loin

Foire aux questions

Faut-il écrire du code en system design ?
Rarement, et jamais beaucoup. On attend surtout des schémas, des compromis justifiés et des estimations. Un court extrait, comme l’encodage en base 62, peut illustrer un point précis, mais le gros de l’épreuve se joue à l’oral et au tableau.

Comment réagir si je ne connais pas un composant cité ?
Restez sur les principes plutôt que sur les noms de produits. Décrire ce que fait un cache ou une réplication, et pourquoi, vaut mieux que de citer une marque sans en maîtriser le fonctionnement. L’examinateur teste votre raisonnement, pas votre catalogue.

Le system design tombe-t-il pour un premier emploi ?
Rarement en profondeur, mais une version allégée peut apparaître. Maîtriser la méthode en huit étapes, même appliquée à un cas simple, vous distingue nettement des autres candidats juniors.

Combien de temps consacrer à l’estimation ?
Quelques minutes suffisent. L’objectif est de fixer l’échelle, pas de produire un budget précis. Posez vos hypothèses clairement, faites un calcul d’enveloppe, et passez à la conception en gardant ces chiffres en tête.

مشاركة
Service ITSkillsCenter

Application mobile Android et iOS

Création d'application mobile Android et iOS. À partir de 350 000 FCFA.

Démarrer mon projet
Publicité