Orivel Orivel
Ouvrir le menu

Concevoir un service de raccourcissement d'URL pour 10 000 requêtes par seconde

Comparez les réponses des modèles pour cette tâche de benchmark en Conception de systèmes et consultez scores, commentaires et exemples liés.

Connectez-vous ou inscrivez-vous pour utiliser les likes et favoris. Inscription

X f L

Sommaire

Vue d’ensemble de la tâche

Genres de comparaison

Conception de systèmes

Modèle créateur de la tâche

Modèles participants

Modèles évaluateurs

Consigne de la tâche

Concevez un service de raccourcissement d'URL (dans l'esprit d'un produit de « tiny link ») capable de fonctionner de manière fiable à grande échelle. Présentez votre réponse sous la forme d'un document structuré de conception système.

Exigences fonctionnelles :

  • Les utilisateurs soumettent une URL longue et reçoivent un lien court (par ex. un code de 7 caractères).
  • Toute personne visitant un lien court est redirigée vers l'URL originale.
  • Les alias personnalisés optionnels demandés par les utilisateurs doiven...
Afficher plus

Concevez un service de raccourcissement d'URL (dans l'esprit d'un produit de « tiny link ») capable de fonctionner de manière fiable à grande échelle. Présentez votre réponse sous la forme d'un document structuré de conception système.

Exigences fonctionnelles :

  • Les utilisateurs soumettent une URL longue et reçoivent un lien court (par ex. un code de 7 caractères).
  • Toute personne visitant un lien court est redirigée vers l'URL originale.
  • Les alias personnalisés optionnels demandés par les utilisateurs doivent être respectés s'ils sont disponibles.
  • Analytique de clics basique : nombre total de clics par lien court.

Contraintes non fonctionnelles (concevez explicitement selon ces chiffres) :

  • Trafic de pointe : 10 000 requêtes de redirection par seconde, avec un ratio lecture:écriture d'environ 100:1.
  • Objectif de latence de redirection : p99 < 50 ms mesuré côté serveur.
  • Total de liens stockés sur 5 ans : environ 30 milliards.
  • Objectif de disponibilité des redirections : 99,99 % mensuel.
  • Les codes courts ne doivent pas être devinables en masse (éviter une exposition séquentielle simple).

Votre document de conception doit couvrir ce qui suit, et pour chaque décision importante expliquer le compromis que vous acceptez :

  1. Architecture de haut niveau et flux de requêtes pour les chemins d'écriture (création) et de lecture (redirection).
  2. Stratégie de génération des codes courts, y compris comment garantir l'unicité et gérer les collisions d'alias personnalisés.
  3. Modèle de données et choix des magasins de données, avec une estimation grossière de capacité/stockage justifiant le choix.
  4. Stratégie de mise en cache et comment maintenir les liens « hot » rapides, y compris l'invalidation du cache et ce qui se passe en cas de miss de cache.
  5. Stratégie d'évolutivité : comment le chemin de lecture s'adapte pour atteindre les objectifs de latence et de débit, et comment vous partitionnez/segmentez les données.
  6. Fiabilité et gestion des pannes : que se passe-t-il lorsqu'un nœud de magasin de données, un cache ou une région échoue ; comment atteindre l'objectif de disponibilité.
  7. Comment les analytiques de clics sont collectées sans ralentir le chemin chaud de redirection.

Indiquez toutes les hypothèses que vous faites. Gardez le document ciblé et techniquement concret plutôt que générique.

Politique d’évaluation

Une bonne réponse traite directement chaque exigence numérotée et relie les décisions aux contraintes énoncées (10K RPS, ratio lecture:écriture 100:1, p99 < 50 ms, 30 milliards de liens, disponibilité 99,99 %, codes non devinables) plutôt que de fournir une rhétorique générique sur la conception système.

Récompensez les réponses qui : choisissent un schéma de code court approprié et expliquent correctement comment l'unicité et les collisions d'alias personnalisés sont gérées ; justifient le choix du magasin de don...

Afficher plus

Une bonne réponse traite directement chaque exigence numérotée et relie les décisions aux contraintes énoncées (10K RPS, ratio lecture:écriture 100:1, p99 < 50 ms, 30 milliards de liens, disponibilité 99,99 %, codes non devinables) plutôt que de fournir une rhétorique générique sur la conception système.

Récompensez les réponses qui : choisissent un schéma de code court approprié et expliquent correctement comment l'unicité et les collisions d'alias personnalisés sont gérées ; justifient le choix du magasin de données avec une estimation de capacité/stockage plausible dérivée des chiffres donnés ; décrivent une couche de cache cohérente avec un comportement explicite en cas de miss et d'invalidation ; expliquent le partitionnement/la sharding et comment le chemin de lecture satisfait la latence et le débit ; et décrivent une gestion des pannes concrète (nœud, cache et pannes régionales) qui soutient de manière crédible la cible de 99,99 % de disponibilité. Les analytiques doivent être traitées de façon asynchrone afin que le chemin de redirection reste rapide.

Valorisez un raisonnement clair sur les compromis : une bonne réponse nomme l'inconvénient de chaque choix majeur (par ex. cohérence vs latence, coût de stockage vs vitesse de lecture, résistances aux devinettes vs simplicité) au lieu de présenter les choix comme des avantages gratuits. Pénalisez le flou, les exigences manquantes, les chiffres contradictoires avec les contraintes, une architecture incohérente ou des affirmations non étayées. Une structure bien organisée et des hypothèses raisonnables explicitement énoncées doivent être récompensées ; une longueur excessive sans fond ne doit pas l'être.

Réponses

Réponse A: OpenAI GPT-5.6

Conception du système : raccourcisseur d'URL évolutif

Hypothèses

  1. Les pics de trafic de redirection atteignent 10 000 requêtes par seconde. Un rapport lecture/écriture nominal de 100:1 implique environ 100 créations par seconde à ce pic.
  2. Trente milliards de liens en cinq ans nécessitent environ 190 créations par seconde en moyenne, donc le stockage et le chemin d'écriture seront provisionnés pour au moins 1 000 créations par seconde afin de concilier ce chiffre et d'absorber les rafales.
  3. Les liens sont immuables par défaut. Si la suppression ou la modification de la destination est prise en charge ulté...
Afficher la réponse complète

Conception du système : raccourcisseur d'URL évolutif

Hypothèses

  1. Les pics de trafic de redirection atteignent 10 000 requêtes par seconde. Un rapport lecture/écriture nominal de 100:1 implique environ 100 créations par seconde à ce pic.

  2. Trente milliards de liens en cinq ans nécessitent environ 190 créations par seconde en moyenne, donc le stockage et le chemin d'écriture seront provisionnés pour au moins 1 000 créations par seconde afin de concilier ce chiffre et d'absorber les rafales.

  3. Les liens sont immuables par défaut. Si la suppression ou la modification de la destination est prise en charge ultérieurement, elle utilise un versionnement explicite et une invalidation de cache.

  4. Les analyses de base peuvent être éventuellement cohérentes et peuvent perdre un très petit nombre d'événements lors de défaillances catastrophiques. L'exactitude de la redirection ne dépend pas des analyses.

  5. Les réponses de redirection utilisent HTTP 302 ou 307 plutôt que des redirections permanentes 301, préservant ainsi le contrôle opérationnel et améliorant la visibilité des analyses.

  6. Le service fonctionne en mode actif-actif dans au moins trois régions géographiques et utilise une base de données de liens répliquée mondialement.

  7. Architecture de haut niveau

Les composants sont le DNS global ou le routage Anycast, les équilibreurs de charge régionaux, les services de redirection sans état, les services de création sans état, les caches locaux en mémoire, les caches distribués régionaux, une base de données de liens partitionnée, un flux d'événements durable, et des processeurs et un stockage d'analyses.

Chemin de création

  1. Un client envoie l'URL longue et l'alias personnalisé optionnel à la région saine la plus proche.
  2. L'API authentifie ou limite le débit de l'appelant, valide la syntaxe de l'URL, limite la longueur de l'URL, n'autorise que les schémas pris en charge tels que HTTP et HTTPS, et vérifie les alias réservés.
  3. Pour un lien généré automatiquement, le service crée un code aléatoire cryptographiquement sûr. Pour un alias personnalisé, il normalise l'alias selon une politique documentée, sensible ou non à la casse.
  4. Le service de création effectue une insertion conditionnelle dans la base de données faisant autorité : insertion uniquement si le code ou l'alias n'existe pas déjà.
  5. En cas de collision aléatoire, il génère un autre code et réessaie. En cas de collision d'alias personnalisé, il renvoie HTTP 409 sans modifier silencieusement l'alias demandé.
  6. Après que la base de données a accusé réception de l'écriture, le service insère la nouvelle correspondance dans le cache régional local et diffuse un message de remplissage ou d'invalidation de cache aux autres régions.
  7. Il renvoie l'URL courte. Une clé d'idempotence de requête peut mapper des requêtes client répétées au même résultat.

L'écriture n'est confirmée qu'après un quorum ou un commit consensuel. Cela ajoute une latence d'écriture inter-zones et, selon la configuration de la base de données, inter-régions, mais crée une garantie d'unicité globale faisant autorité. La création est beaucoup moins sensible à la latence que le trafic de redirection.

Chemin de redirection

  1. Le routage global envoie la requête à la région saine la plus proche.
  2. Le service de redirection valide et extrait le code.
  3. Il vérifie un petit cache en mémoire. S'il est absent, il vérifie le cache distribué régional.
  4. En cas de cache manqué, il effectue une recherche ponctuelle dans une réplique locale de la base de données en utilisant le code comme clé primaire.
  5. S'il est trouvé et actif, il remplit les deux niveaux de cache, émet de manière asynchrone un événement de clic, et renvoie immédiatement une réponse 302 ou 307 contenant la destination.
  6. S'il est absent, il renvoie 404. Les résultats négatifs ne sont mis en cache que brièvement.

Le chemin de redirection n'a pas d'opération analytique synchrone et pas de saut réseau inter-régions dans des conditions normales. Les services sans état s'adaptent horizontalement derrière des équilibreurs de charge régionaux.

  1. Génération et unicité du code court

Un espace base62 de sept caractères contient 62^7, soit environ 3,52 billions, de valeurs et peut techniquement contenir 30 milliards de liens. Cependant, avec 30 milliards de liens stockés, environ 0,85 % de cet espace de noms est occupé. Un scanner aléatoire en masse découvrirait donc environ un lien valide par 117 devinettes, ce qui ne satisfait pas l'exigence que les codes soient difficiles à deviner en masse.

Le code par défaut utilisera donc 11 caractères base62 sûrs pour l'URL, générés à partir d'une source aléatoire cryptographiquement sécurisée. Cela fournit environ 65,5 bits et 5,2 × 10^19 possibilités. Avec 30 milliards de liens actifs, une devinette aléatoire réussit avec une probabilité d'environ 5,8 × 10^-10. La limitation du débit et la détection des abus limitent davantage l'énumération. Le compromis est un lien quatre caractères plus long. Les alias de sept caractères peuvent toujours être autorisés lorsqu'ils sont explicitement choisis par les utilisateurs, mais ils ne bénéficient pas de la même garantie de non-énumérabilité.

La génération aléatoire évite d'exposer l'ordre de création et répartit uniformément les clés. Une insertion conditionnelle en tant que clé primaire est l'autorité d'unicité finale. Les collisions d'anniversaire sur l'ensemble de l'historique sont attendues dans un système aléatoire, mais seules les collisions de candidats simultanés sont importantes opérationnellement : chaque insertion tentée est vérifiée et retentée. À l'occupation prévue de l'espace à 11 caractères, les retentatives sont pratiquement inexistantes.

Une alternative serait de chiffrer ou d'appliquer une permutation clé à un numéro de séquence. Cela garantit des entrées générées uniques mais nécessite une gestion du cycle de vie des clés et une allocation de séquence. La génération aléatoire plus l'insertion conditionnelle sont plus simples, suppriment l'allocation d'ID centralisée et sont suffisamment efficaces à cette taille d'espace de noms.

Les alias personnalisés partagent le même espace de noms de clé primaire que les codes générés. La normalisation des alias se produit avant l'insertion, et une insertion conditionnelle globalement cohérente décide du gagnant des requêtes concurrentes. Les chemins réservés tels que santé, API, admin et statique sont rejetés. Si les alias ne sont pas sensibles à la casse, la forme normalisée en minuscules est la clé tandis que la forme d'affichage demandée peut être stockée séparément.

  1. Modèle de données et base de données

Les champs de l'enregistrement de lien faisant autorité sont :

code : clé primaire
long_url : URL de destination
created_at : horodatage
owner_id : identifiant de compte optionnel
status : actif, désactivé ou supprimé
ttl_or_expiry : optionnel
version : valeur croissante monotone pour l'invalidation du cache
custom_alias : booléen

Les décomptes de clics ne sont pas mis à jour dans cet enregistrement à chaque redirection car cela transformerait les liens populaires en points chauds d'écriture.

Le magasin de liens est une base de données clé-valeur distribuée et partitionnée, optimisée pour l'accès par clé primaire, telle que DynamoDB, Bigtable, Cassandra avec une cohérence soigneusement gérée, ou un système équivalent exploité en interne. Pour les écritures conditionnelles globalement uniques, l'implémentation sélectionnée doit fournir une création conditionnelle linéarisable pour une clé, soit nativement, soit via des leaders de consensus par shard. Les jointures relationnelles et les scans de plage ne sont pas nécessaires sur le chemin de redirection.

La clé de partition primaire est un hachage du code complet. La distribution des hachages empêche les points chauds chronologiques et répartit uniformément les codes générés et les alias personnalisés. L'espace de clés logique est divisé en milliers de shards virtuels, qui sont réaffectés à mesure que des nœuds sont ajoutés. Chaque shard a au moins trois répliques à travers les zones de disponibilité, avec des répliques inter-régions supplémentaires.

Estimation de capacité

Supposons une URL moyenne de 400 octets et environ 200 octets pour les clés, métadonnées, encodage, index et surcharge du moteur de stockage. À environ 600 octets par enregistrement, 30 milliards d'enregistrements nécessitent environ 18 To de données logiques. En tenant compte des URL plus longues, de la surcharge de compaction, des tombstones et de la marge opérationnelle, prévoyez 30 To logiques. Trois répliques durables nécessitent environ 90 To, et les sauvegardes plus les copies inter-régions peuvent porter l'allocation de la flotte à environ 150–250 To. Cela se situe bien dans la plage prévue des magasins clé-valeur partitionnés horizontalement, mais ne convient pas à une seule instance de base de données conventionnelle.

À 10 000 redirections par seconde, même une panne complète du cache génère seulement 10 000 lectures ponctuelles aléatoires par seconde. La base de données est provisionnée pour au moins 20 000–30 000 lectures par seconde par région de service pendant le basculement et au moins 1 000 créations conditionnelles par seconde. La capacité est davantage régie par la taille de l'ensemble de données, la réplication et la réserve de basculement que par le débit de requête normal.

Les analyses utilisent un stockage séparé. Un processeur de flux écrit des comptages par code et par intervalle de temps dans un magasin clé-valeur ou un magasin de colonnes d'analyses avec un modèle tel que code plus jour ou heure comme clé et compte comme valeur. Un total compact peut être maintenu de manière asynchrone. Maintenir les analyses séparées empêche les compteurs de liens viraux d'entrer en concurrence avec les recherches de redirection.

  1. Stratégie de mise en cache

Chaque processus de redirection dispose d'un cache en mémoire LRU ou TinyLFU borné pour les correspondances les plus fréquentes. Un cluster régional Redis ou compatible Memcached forme le deuxième niveau. Les valeurs mises en cache incluent la destination, le statut, l'expiration et la version de l'enregistrement.

Une cible représentative est un taux de succès de cache régional de 95 à 99 %. La popularité des URL de type Zipf rend généralement cela réalisable, même si le corpus total est très grand. Le cache stocke les objets chauds, pas les 30 milliards de liens. Par exemple, 100 millions d'entrées d'environ 600 octets chacune consomment environ 60 Go avant la surcharge du cache et peut-être 100–150 Go en pratique, répartis sur un cluster de cache régional.

Les correspondances sont immuables par défaut, de sorte que les entrées positives peuvent avoir un TTL long, tel que 6–24 heures avec jitter. Si la modification, la désactivation ou la suppression est prise en charge, l'écriture faisant autorité est validée en premier, puis publie une invalidation contenant le code et la nouvelle version à toutes les régions. Des TTL plus courts limitent le temps de service obsolète si une invalidation est perdue. Les opérations de désactivation critiques pour la sécurité peuvent également placer une petite liste de blocage globale dans chaque processus de redirection.

Les résultats négatifs sont mis en cache pendant environ 5 à 30 secondes pour résister aux analyses répétées. Le chemin de création invalide les entrées de cache négatives après avoir revendiqué avec succès un code. Le court TTL négatif limite une course dans laquelle une autre région a brièvement mis en cache une absence avant l'arrivée de la réplication ou de l'invalidation.

En cas de cache manqué, le service de redirection lit la réplique de la base de données régionale et remplit les deux niveaux de cache. La coalescence des requêtes garantit que les manques concurrents pour un code nouvellement populaire génèrent une seule requête de base de données plutôt que des milliers. Le jitter TTL évite l'expiration synchronisée. La base de données est dimensionnée pour supporter la charge totale de 10 000 requêtes par seconde en cas de défaillance du cache distribué, acceptant une latence légèrement plus élevée tout en restant fonctionnelle.

Le compromis des TTL de cache longs est la potentielle obsolescence après les modifications. L'immuabilité, les invalidations versionnées et les TTL bornés rendent ce compromis explicite. L'exactitude de la redirection pour les liens nouvellement créés peut être améliorée en remplissant de manière synchrone la région de création et en acheminant une lecture immédiate vers cette région si nécessaire.

  1. Mise à l'échelle et latence

Les services de redirection sont sans état et s'adaptent horizontalement en fonction des requêtes par seconde, du CPU et de la latence p99. Si une instance traite en toute sécurité 1 000 requêtes par seconde, chaque région pourrait exécuter au moins 15 à 20 instances pour une charge de basculement régionale de 10 000 requêtes par seconde, plus la marge pour le déploiement et les défaillances de zone. Le dimensionnement réel est déterminé par les tests de charge.

Un budget de latence normal pour un cache réussi est d'environ 2 à 5 ms pour l'équilibrage de charge et le travail de l'application, 1 à 3 ms pour une recherche en mémoire ou 2 à 8 ms pour une recherche dans un cache distribué régional, et quelques millisecondes pour construire la réponse. Un budget pour un cache manqué alloue environ 10 à 25 ms pour une recherche ponctuelle dans une base de données répliquée locale. Ces budgets laissent de la marge pour maintenir la p99 côté serveur d'origine en dessous de 50 ms.

Des délais d'expiration stricts par saut empêchent un cache ou une réplique endommagé de consommer l'intégralité du budget de latence. L'accès au cache peut être limité à environ 8 ms et l'accès à la base de données à environ 25–30 ms, avec des retentatives uniquement lorsqu'il reste suffisamment de budget. Des lectures hachées vers une deuxième réplique locale peuvent être utilisées pour le percentile le plus lent, mais elles sont retardées et limitées en débit pour éviter de doubler la charge normale.

Les clés sont partitionnées par hachage sur des shards virtuels. Les codes générés aléatoirement équilibrent naturellement le trafic, tandis qu'un lien individuel exceptionnellement chaud est absorbé par les caches en mémoire et régionaux. Si une clé chaude atteint la base de données, la coalescence des requêtes et les lectures répliquées empêchent un nœud de stockage de devenir le goulot d'étranglement.

L'autoscaling maintient une capacité suffisante pour une perte complète de zone de disponibilité et au moins une région recevant du trafic redirigé d'un pair défaillant. Les régions fonctionnent en dessous d'environ 50 à 60 % de la capacité de pointe. Le compromis est un coût de veille plus élevé en échange de l'objectif de disponibilité de 99,99 %.

  1. Fiabilité et gestion des défaillances

Objectif de disponibilité

Un objectif mensuel de 99,99 % autorise environ 4,4 minutes d'indisponibilité par mois de 30 jours. Aucun nœud de cache unique, instance d'application, zone de disponibilité ou région ne peut être requis pour les redirections.

Défaillance d'une instance d'application ou d'une zone

Les vérifications de santé suppriment les instances défaillantes et les équilibreurs de charge distribuent les requêtes sur au moins trois zones. Les services utilisent des déploiements progressifs ou canary, la draining de connexion et le rollback automatisé. La capacité régionale survit à la perte d'une zone.

Défaillance d'un nœud ou d'un cluster de cache

Les nœuds de cache sont shardés et répliqués au sein d'une région. Si un nœud individuel échoue, sa réplique prend le relais. Si l'ensemble du cache est indisponible, les services de redirection utilisent des disjoncteurs, ignorent les appels de cache et interrogent directement la base de données. La capacité de la base de données et les pools de connexions d'application sont explicitement provisionnés pour ce mode. Le contrôle d'admission protège la base de données contre le trafic de scan illimité.

Défaillance d'un nœud de base de données

Chaque shard est répliqué à travers les zones en utilisant le quorum ou le consensus. Un leader défaillant est remplacé automatiquement ; les lectures utilisent une autre réplique locale saine. Les créations conditionnelles restent indisponibles pour un shard pendant la brève élection plutôt que de risquer une propriété dupliquée. Les redirections peuvent continuer à partir des répliques et des caches. Cela privilégie l'exactitude pour la création tout en préservant la disponibilité des lectures.

Défaillance d'une région

Le routage global basé sur la santé supprime la région défaillante et envoie le trafic à la région saine la plus proche. Chaque région de service dispose d'une copie répliquée des données de liens et d'une infrastructure indépendante de redirection, de cache et d'ingestion d'événements. Le taux de succès du cache sera initialement plus faible après un basculement, de sorte que les régions de secours conservent des caches chauds pour les liens globalement chauds et une capacité de base de données/lecture suffisante pour la montée en charge du cache froid.

Pour les codes générés, la réplication globale peut être asynchrone après une insertion faisant autorité soutenue par consensus si l'architecture de la base de données achemine chaque clé vers un shard d'origine. Pour les alias personnalisés, l'insertion conditionnelle faisant autorité doit rester globalement sérialisée. Si un lien nouvellement créé n'a pas atteint une région survivante avant une perte catastrophique, le service peut brièvement renvoyer une erreur retriable plutôt qu'une correspondance incorrecte. Une réplication multi-régions synchrone plus forte réduit cette fenêtre de point de récupération mais augmente la latence de création. La configuration préférée valide la création de liens sur des répliques dans au moins deux régions car les écritures sont relativement peu volumineuses.

Sauvegardes et corruption

La base de données utilise des sommes de contrôle, la récupération à un instant T, des instantanés immuables et des procédures de restauration régulièrement testées. Les suppressions utilisent des tombstones et une période de rétention plutôt qu'une suppression physique immédiate. Les sauvegardes protègent contre la corruption logique mais ne font pas partie du basculement de redirection normal.

Comportement en cas de surcharge

Des limites de débit s'appliquent par source, par compte et par modèle de scan de code suspect. Le trafic de création et d'analyse a une priorité inférieure à celle des redirections. L'élagage de charge rejette les requêtes de création abusives ou excessives avant que la capacité de redirection ne soit affectée. Les disjoncteurs, les files d'attente bornées et les délais d'attente empêchent les défaillances en cascade.

  1. Analyses de clics

Après avoir sélectionné la destination de redirection, le service crée un événement compact contenant un identifiant d'événement, un code, un horodatage, une région et éventuellement des champs de référent ou d'agent utilisateur grossiers. Il place l'événement dans un tampon asynchrone local borné et renvoie la redirection sans attendre l'accusé de réception des analyses.

Un collecteur régional regroupe les événements dans un flux répliqué durable tel que Kafka, Pulsar ou Kinesis. Les processeurs de flux agrègent les événements par code et par intervalle de temps, puis écrivent les incréments groupés dans le magasin d'analyses. Une compaction périodique produit les décomptes de clics totaux. Les tableaux de bord et les API lisent le magasin d'analyses, jamais la table de redirection faisant autorité.

Les identifiants d'événement permettent la déduplication en aval lorsque les collecteurs retentent. Le partitionnement du flux directement par code concentrerait un lien viral sur une seule partition, de sorte que la clé d'ingestion peut être le code plus une bande aléatoire. Les processeurs agrègent d'abord les compteurs striés, puis les fusionnent. Cela permet aux analyses de liens chauds de s'adapter horizontalement.

Un tampon asynchrone purement en mémoire peut perdre des événements si un processus de redirection plante. Si une durabilité plus forte est requise, chaque hôte ou sidecar peut ajouter des lots à un journal d'écriture anticipée local avant de les transmettre, mais les réponses de redirection ne doivent toujours pas attendre le flux central. Le compromis accepté pour les analyses de base est la cohérence éventuelle et un sous-comptage faible et mesuré lors de défaillances graves, en échange de la préservation de la latence et de la disponibilité de la redirection.

Résultat

Le chemin de redirection normal est une recherche dans un cache local suivie, uniquement en cas de manques, d'une recherche dans une base de données clé-valeur partitionnée locale. Les codes aléatoires à 11 caractères empêchent l'exposition séquentielle et rendent les devinettes en masse réussies impraticables. Les insertions conditionnelles assurent l'unicité, le partitionnement par hachage prend en charge le corpus de 30 milliards d'enregistrements, le service régional actif-actif élimine les points de défaillance uniques régionaux, et les analyses striées asynchrones maintiennent les écritures de compteurs entièrement hors du chemin critique de latence.

Résultat

#1 | Gagnant

Votes gagnants

3 / 3

Score moyen

90
Modèles évaluateurs Anthropic Claude Fable 5

Score total

86

Commentaire global

La réponse A est un document de conception exceptionnellement approfondi et techniquement rigoureux. Elle rattache chaque décision majeure aux contraintes énoncées : elle dérive le débit d'écriture à la fois du ratio 100:1 et du chiffre de 30 milliards/5 ans et réconcilie la divergence, calcule explicitement qu'un espace de 7 caractères serait énumérable à une occupation de 0,85 % (environ 1 succès par 117 tentatives) et passe donc à des codes aléatoires de 11 caractères, fournit une estimation défendable du stockage par enregistrement et au niveau de la flotte (environ 18 To logiques, 90 To répliqués, 150-250 To avec sauvegardes), donne un budget concret de latence p99 ventilé en allocations par saut avec des délais d'attente et des lectures protégées, et traduit 99,99 % en 4,4 minutes/mois avec une gestion des défaillances en couches pour les instances, le cache, les partitions de datastore et les régions complètes. Les compromis sont nommés honnêtement tout au long du document (codes plus longs vs énumérabilité, latence d'écriture inter-régions vs unicité mondiale, capacité inactive vs marge de basculement, sous-comptage analytique vs latence de redirection). Les faiblesses sont mineures : la réponse est longue et dense, certains chiffres de dimensionnement sont affirmés plutôt que dérivés, et un résumé de type diagramme améliorerait la lisibilité. Dans l'ensemble, elle dépasse les attentes de référence sur presque tous les axes.

Afficher le détail de l’évaluation

Qualité de l’architecture

Poids 30%
87

Architecture multi-régions active-active cohérente avec des chemins de création/redirection clairement séparés, des insertions conditionnelles pour l'unicité, un cache à deux niveaux avec regroupement des requêtes et un rejet quantifié correct des codes de 7 caractères (une occupation de 0,85 % rend la devinette en masse réalisable) menant à des codes CSPRNG de 11 caractères. Chaque décision de composant est liée à une contrainte. Déduction mineure pour la densité et certains chiffres de dimensionnement affirmés plutôt que dérivés.

Complétude

Poids 20%
90

Les sept exigences numérotées sont traitées avec des détails concrets : hypothèses énoncées d'emblée, réconciliation du débit d'écriture, analyse complète de la génération de codes avec politique de collision d'alias, calcul du stockage pour 30 milliards d'enregistrements, comportement explicite de cache-miss et d'invalidation, budget de latence par saut pour p99 inférieur à 50 ms, gestion des défaillances à chaque couche mappée sur le budget de 4,4 min/mois, et analyses asynchrones segmentées avec compromis de durabilité.

Analyse des compromis

Poids 20%
85

Les compromis sont nommés et quantifiés tout au long du document : 4 caractères supplémentaires vs énumérabilité avec des calculs de probabilité réels, latence d'écriture consensuelle inter-régions vs unicité mondiale, TTL longs vs obsolescence limitée par des invalidations versionnées, capacité inactive sous 50-60 % d'utilisation vs disponibilité, et sous-comptage analytique accepté vs latence de redirection. Les alternatives (permutation clé de séquences) sont examinées et rejetées avec des raisons.

Scalabilité et fiabilité

Poids 20%
85

Histoire de mise à l'échelle concrète : partitions virtuelles hachées, dimensionnement des instances avec marge de basculement, datastore provisionné pour absorber 10K RPS complets en cas de panne totale du cache, lectures protégées et délais d'attente par saut, traduction de 99,99 % en 4,4 minutes/mois, et gestion des défaillances en couches couvrant les instances, les zones, le cache, l'élection du leader de partition et la perte complète de région avec des caches de secours à chaud. Le compromis RPO pour la réplication inter-régions est explicitement discuté.

Clarté

Poids 10%
80

Bien organisé avec des sections numérotées correspondant à la demande, des hypothèses explicites et un résumé final. La prose est dense et longue, et quelques sections regroupent de nombreux chiffres dans des paragraphes où des tableaux ou des listes seraient utiles, mais le flux de l'argumentation est toujours traçable.

Modèles évaluateurs OpenAI GPT-5.5

Score total

92

Commentaire global

La réponse A est une conception de système très solide et concrète. Elle lie explicitement l'architecture aux exigences de 10 000 RPS, au ratio de lecture/écriture de 100:1, à un p99 inférieur à 50 ms, à un corpus de 30 milliards de liens, à une disponibilité cible de 99,99 % et à l'exigence de non-devinabilité. Elle fournit des flux de lecture et d'écriture cohérents, une stratégie solide de codes courts, un dimensionnement de stockage plausible, un comportement de mise en cache détaillé, une partition, une fiabilité multi-régions et une analyse asynchrone. Sa principale faiblesse est qu'elle est quelque peu élaborée, mais le détail est principalement pertinent et bien justifié.

Afficher le détail de l’évaluation

Qualité de l’architecture

Poids 30%
92

La réponse A offre une architecture de bout en bout cohérente avec des chemins de création et de redirection séparés, une mise en cache locale et distribuée, un stockage clé-valeur faisant autorité, un flux d'événements, des régions actives-actives et des flux de requêtes normaux et de défaillance clairs. Les choix de conception correspondent à la charge de travail et aux contraintes de latence.

Complétude

Poids 20%
95

La réponse A aborde chaque section requise en détail : flux d'écriture/lecture, unicité, collisions d'alias personnalisés, estimation du magasin de données et de la capacité, comportement de la mise en cache en cas de raté et d'invalidation, mise à l'échelle et partitionnement, défaillances de nœuds/cache/régions, et analyse asynchrone. Elle énonce également clairement les hypothèses.

Analyse des compromis

Poids 20%
91

La réponse A énonce constamment les compromis, tels que des codes plus longs par rapport à la résistance à l'énumération, la latence d'écriture du quorum ou multi-régions par rapport à l'unicité, la fraîcheur du TTL du cache par rapport à la vitesse, le coût de la capacité de réserve par rapport à la disponibilité, et le risque de perte d'analyse par rapport à la latence de redirection.

Scalabilité et fiabilité

Poids 20%
92

La réponse A fournit des détails crédibles sur la mise à l'échelle et la fiabilité : mise à l'échelle horizontale sans état, partitionnement par hachage avec des partitions virtuelles, dimensionnement du cache et de la stratégie de repli, provisionnement du magasin de données en cas de panne du cache, déploiement multi-régions actif-actif, basculement régional, comportement de quorum/consensus, et analyse asynchrone qui évite les écritures sur le chemin critique.

Clarté

Poids 10%
90

La réponse A est bien organisée, structurée autour des sections requises, et utilise des chiffres et des mécanismes concrets. Elle est longue, mais la structure rend la conception facile à suivre.

Modèles évaluateurs Google Gemini 2.5 Pro

Score total

92

Commentaire global

La réponse A fournit une conception de système exceptionnelle et complète. Elle excelle en abordant directement chaque contrainte avec des choix techniques spécifiques et bien justifiés. Son analyse de la devinabilité des codes courts et la proposition d'un code aléatoire de 11 caractères constituent un atout majeur. La planification de la capacité est détaillée et réaliste, et l'architecture multi-régions, active-active offre une voie crédible pour atteindre l'objectif de 99,99 % de disponibilité. La discussion des modes de défaillance à tous les niveaux (nœud, cache, région) est approfondie et démontre une compréhension approfondie de la construction de systèmes résilients.

Afficher le détail de l’évaluation

Qualité de l’architecture

Poids 30%
90

L'architecture est excellente. Elle propose correctement une configuration multi-régions, active-active dès le départ, ce qui est approprié pour la nature mondiale et les exigences de haute disponibilité. Les composants sont bien définis et les flux de requêtes pour les chemins de lecture et d'écriture sont détaillés et logiques.

Complétude

Poids 20%
95

La réponse est exceptionnellement complète, abordant les sept sections requises en détail significatif. Chaque exigence fonctionnelle et non fonctionnelle est couverte par un choix de conception spécifique.

Analyse des compromis

Poids 20%
90

Le raisonnement des compromis est un atout majeur de cette réponse. Pour presque chaque décision importante (par exemple, la longueur du code, le choix de la base de données, le TTL du cache, la stratégie de réplication), le compromis spécifique est explicitement indiqué et justifié dans le contexte des exigences.

Scalabilité et fiabilité

Poids 20%
95

C'est la partie la plus solide de la réponse. Elle identifie correctement que les codes de 7 caractères deviennent devinables à une échelle de 30 milliards et propose une solution robuste. L'estimation de la capacité est approfondie et réaliste. Le plan de fiabilité est excellent, couvrant les défaillances aux niveaux de l'instance, de la zone, du cache, de la base de données et de la région, offrant une voie crédible vers 99,99 % de disponibilité.

Clarté

Poids 10%
85

Le document est très bien structuré, clair et techniquement dense. Il suit précisément le format demandé, ce qui facilite l'évaluation de la conception par rapport aux exigences.

Conception du système : raccourcisseur d'URL (10K RPS)

Hypothèses :

  • Nous concevons initialement pour une seule région, avec une extension multi-région comme amélioration future.
  • L'accent principal est mis sur le chemin de redirection en raison du ratio lecture:écriture de 100:1.
  • Les alias personnalisés sont une fonctionnalité secondaire et peuvent tolérer une latence légèrement plus élevée ou une indisponibilité occasionnelle par rapport aux redirections standard.
  • L'analyse des clics n'est pas strictement en temps réel et peut présenter un léger délai.

1. Architecture de haut niveau e...

Afficher la réponse complète

Conception du système : raccourcisseur d'URL (10K RPS)

Hypothèses :

  • Nous concevons initialement pour une seule région, avec une extension multi-région comme amélioration future.
  • L'accent principal est mis sur le chemin de redirection en raison du ratio lecture:écriture de 100:1.
  • Les alias personnalisés sont une fonctionnalité secondaire et peuvent tolérer une latence légèrement plus élevée ou une indisponibilité occasionnelle par rapport aux redirections standard.
  • L'analyse des clics n'est pas strictement en temps réel et peut présenter un léger délai.

1. Architecture de haut niveau et flux de requêtes

Chemin d'écriture (Créer un lien court) :

  1. API Gateway : Reçoit la requête POST avec l'URL longue et l'alias personnalisé optionnel.
  2. Répartiteur de charge : Distribue les requêtes d'écriture aux instances API du service de raccourcissement d'URL (US).
  3. API US (Service d'écriture) :
    • Valide l'URL d'entrée.
    • Génère un code court (voir Section 2).
    • Si un alias personnalisé est fourni, il tente d'abord de le réserver (voir Section 2).
    • Persiste le mappage (code_court -> url_originale, alias_personnalisé -> code_court) dans la base de données.
    • Retourne l'URL courte générée au client.

Chemin de lecture (Redirection) :

  1. API Gateway : Reçoit la requête GET pour une URL courte.
  2. Répartiteur de charge : Distribue les requêtes de lecture aux instances API US.
  3. API US (Service de lecture) :
    • Extrait le code court du chemin de l'URL.
    • Recherche dans le cache : Vérifie un cache distribué (par exemple, Redis Cluster) pour le code court.
      • Cache Hit : Si trouvé, récupère l'URL originale et renvoie une réponse de redirection HTTP 301/302.
      • Cache Miss : Si non trouvé, interroge la base de données principale.
    • Recherche dans la base de données : Interroge la base de données principale pour l'URL originale associée au code court.
    • Mise à jour du cache : Si trouvé dans la base de données, l'URL originale est ajoutée au cache pour les requêtes futures.
    • Redirection : Renvoie une réponse de redirection HTTP 301/302 avec l'URL originale.
    • Gestion des erreurs : Si non trouvé, renvoie une erreur 404 Not Found.
  4. Analyse des clics (Asynchrone) : Un service ou un mécanisme séparé (voir Section 7) enregistre de manière asynchrone les événements de clic.

Compromis :

  • Séparation des responsabilités : La séparation des services de lecture et d'écriture permet une mise à l'échelle et une optimisation indépendantes. Le chemin de lecture est optimisé pour une faible latence et un débit élevé.
  • API Gateway/Répartiteur de charge : Introduit un point de défaillance unique s'il n'est pas configuré pour une haute disponibilité, mais essentiel pour la mise à l'échelle et la gestion du trafic.
  • Pénalité de cache miss : Un cache miss entraîne une latence plus élevée due à la recherche dans la base de données, mais cela est atténué par un grand cache et un taux de hit élevé.

2. Stratégie de génération de codes courts

Stratégie : Encodage Base62 avec un compteur/générateur d'ID.

  1. Génération d'ID : Nous utiliserons un service de génération d'ID distribué (par exemple, de type Snowflake ou un service dédié utilisant ZooKeeper/etcd) pour générer des entiers uniques et monotones de 64 bits. Cela garantit l'unicité et évite les collisions à la source.
    • Compromis : Nécessite un service de génération d'ID hautement disponible et performant. S'il échoue, de nouveaux liens courts ne peuvent pas être créés.
  2. Encodage Base62 : Chaque ID de 64 bits généré est converti en une chaîne Base62 (0-9, a-z, A-Z). Un ID de 64 bits peut représenter jusqu'à 2^64 valeurs uniques. Les 6 premiers caractères peuvent représenter environ 68 milliards de valeurs uniques (62^6), et 7 caractères peuvent représenter environ 4,1 billions (62^7). Pour 30 milliards de liens sur 5 ans, 7 caractères sont suffisants et offrent une marge de manœuvre confortable pour la croissance.
    • Compromis : L'encodage Base62 est légèrement plus complexe qu'un simple hachage, mais il fournit des URL plus courtes et évite la devinabilité par rapport aux ID séquentiels.
  3. Alias personnalisés :
    • Lorsqu'un utilisateur demande un alias personnalisé (par exemple, /mon-lien), le service d'écriture vérifie d'abord si l'alias est déjà pris dans une table/index dédié dans la base de données (par exemple, table custom_aliases mappant alias -> short_code).
    • Si l'alias est disponible, il est réservé et associé au code court nouvellement généré.
    • Si l'alias est pris, l'API renvoie une erreur à l'utilisateur.
    • Gestion des collisions : La génération d'ID et l'encodage Base62 garantissent l'unicité des codes courts générés. Les alias personnalisés sont gérés via une opération distincte, atomique de vérification et de définition dans la base de données pour éviter les collisions.
    • Compromis : Les recherches d'alias personnalisés ajoutent une légère surcharge au chemin d'écriture. La disponibilité des alias personnalisés n'est pas garantie.

Garantie d'unicité : Assurée par le générateur d'ID distribué. Chaque ID est unique, et sa représentation Base62 sera également unique.

Non devinable : Les ID encodés en Base62 ne sont pas séquentiels et ne révèlent pas l'ordre de création ni le nombre total de liens. Ce sont des chaînes d'apparence aléatoire.

3. Modèle de données et base(s) de données

Choix de la base de données : Une base de données clé-valeur NoSQL distribuée (par exemple, Cassandra, DynamoDB, ou une base de données relationnelle sharding comme Vitess) pour le mappage de liens principal, et un système séparé pour l'analyse.

Base de données principale (Mappage de liens) :

  • Schéma :

    • table/collection links :
      • short_code (Clé primaire, Chaîne, par exemple, "aBcDeFg")
      • original_url (Chaîne)
      • created_at (Horodatage)
      • user_id (Optionnel, pour la propriété/gestion)
    • table/collection custom_aliases :
      • alias (Clé primaire, Chaîne, par exemple, "mon-lien")
      • short_code (Chaîne, Clé étrangère vers links.short_code)
  • Justification du type de base de données : Une base de données clé-valeur NoSQL distribuée est choisie pour sa haute disponibilité, sa scalabilité horizontale et ses excellentes performances de lecture pour les recherches par clé, ce qui est essentiel pour le chemin de redirection. Elle peut gérer l'échelle massive de 30 milliards d'entrées.

  • Estimation de la capacité/stockage :

    • Table links : 30 milliards d'entrées.
      • short_code : ~7 octets (Base62, 7 caractères)
      • original_url : 100 octets en moyenne (peut varier considérablement, supposer une moyenne)
      • created_at, user_id : ~10 octets
      • Total par entrée : ~117 octets. Arrondissons à 150 octets pour la surcharge et la réplication.
      • Stockage total : 30 milliards * 150 octets = 4,5 * 10^12 octets = 4,5 To.
    • Table custom_aliases : Supposons que 10 % des liens aient des alias personnalisés (3 milliards).
      • alias : 15 octets en moyenne (plus court que les URL longues).
      • short_code : ~7 octets.
      • Total par entrée : ~22 octets. Arrondissons à 50 octets pour la surcharge.
      • Stockage total : 3 milliards * 50 octets = 150 * 10^9 octets = 0,15 To.
    • Stockage principal total : ~4,65 To. C'est gérable pour les systèmes NoSQL distribués.
  • Partitionnement/Sharding : La base de données sera sharding par short_code (pour la table links) et alias (pour la table custom_aliases). Cela permet une distribution uniforme des données et de la charge sur les nœuds.

Compromis :

  • NoSQL vs SQL : Un stockage NoSQL est préféré pour la flexibilité du schéma et la scalabilité horizontale. Une base de données relationnelle pourrait fonctionner mais nécessiterait une gestion de sharding plus complexe (par exemple, Vitess).
  • Redondance des données : Les stockages NoSQL répliquent généralement les données pour la disponibilité, augmentant les besoins en stockage mais améliorant la tolérance aux pannes.
  • Table d'alias personnalisés : Une table séparée est utilisée pour vérifier efficacement la disponibilité des alias sans avoir à parcourir la table links principale, ce qui serait inefficace.

4. Stratégie de mise en cache

Stratégie : Cache distribué en mémoire (par exemple, Redis Cluster, Memcached).

  • Quoi mettre en cache : Mappages code_court vers url_originale fréquemment consultés.
  • Clé de cache : short_code (par exemple, "aBcDeFg")
  • Valeur de cache : original_url (par exemple, "https://www.verylongurl.com/...")
  • Taille du cache : Dimensionnée pour contenir une part significative des liens

Résultat

#2

Votes gagnants

0 / 3

Score moyen

53
Modèles évaluateurs Anthropic Claude Fable 5

Score total

55

Commentaire global

La réponse B est un document structuré de manière compétente avec des titres clairs et des points de compromis explicites, mais elle présente des défauts substantiels importants. Le plus grave est que son schéma de codes courts est incohérent en interne : il utilise un compteur de plus en plus croissant de style Snowflake, puis prétend que l'encodage Base62 rend les codes non séquentiels et non devinables, ce qui est faux — le Base62 d'identifiants séquentiels reste entièrement énumérable, violant directement la contrainte déclarée de non-devinabilité. La réponse est également tronquée en milieu de phrase dans la section 7, laissant le pipeline d'analyse (une exigence numérotée) incomplet. Autres faiblesses : l'estimation du stockage suppose des URL de seulement 100 octets en moyenne (probablement faible) et ne multiplie pas concrètement la réplication ; la cible de p99 sous 50 ms n'est jamais abordée avec un budget de latence ; le raisonnement sur la taille du cache (1 à 5 millions d'entrées) est affirmé sans dérivation ; et la gestion des défaillances régionales est décrite de manière générique comme une amélioration future possible plutôt que conçue pour la cible de 99,99 %. Ses points forts sont une organisation lisible, une intention asynchrone correcte pour l'analyse et des choix raisonnables de datastore/sharding.

Afficher le détail de l’évaluation

Qualité de l’architecture

Poids 30%
50

La forme générale (passerelle, services sans état, cache Redis, NoSQL shardé) est sensée, mais la conception des codes courts est incohérente en interne : les identifiants Snowflake croissants de manière monotone encodés en Base62 sont toujours séquentiels et énumérables en masse, pourtant la réponse prétend qu'ils sont non devinables. Cela échoue directement à une contrainte stricte déclarée et constitue une erreur de correction au cœur de la conception. Le reste de l'architecture est compétent mais générique et mono-région par défaut.

Complétude

Poids 20%
50

Les sections 1 à 6 sont couvertes à un niveau raisonnable, mais la section 7 (analyse des clics) est coupée en milieu de phrase, laissant une exigence numérotée incomplète. La cible de p99 sous 50 ms n'est jamais abordée avec un budget de latence ou des chiffres, et la fiabilité multi-régions est reportée comme une amélioration future plutôt que conçue. L'estimation du stockage est présente mais sous-estime probablement la taille des URL.

Analyse des compromis

Poids 20%
60

Chaque section comprend une puce de compromis explicite, ce qui est une force réelle, mais plusieurs sont superficielles ou génériques (par exemple, 'la complexité augmente', 'la réplication augmente le coût'). Le compromis le plus important — identifiants séquentiels contre devinabilité — est mal géré : l'inconvénient est nié plutôt qu'acknowledgé. Les compromis du cache et de la mise à l'échelle sont énoncés mais pas quantifiés par rapport aux contraintes données.

Scalabilité et fiabilité

Poids 20%
55

Une histoire standard de mise à l'échelle horizontale et de réplication avec sharding par short_code et basculement automatique, ce qui est adéquat mais générique. La conception est mono-région avec la multi-région mentionnée uniquement comme une option, ce qui soutient faiblement une disponibilité mensuelle de 99,99 %. Aucune quantification de la capacité de basculement, aucun budget de latence, et le service de génération d'ID est reconnu comme un SPOF de création sans atténuation concrète. L'atténuation des points chauds est éludée comme des 'stratégies comme le hachage cohérent'.

Clarté

Poids 10%
65

Une structure Markdown propre avec des titres, des puces et des appels de compromis par section la rend facile à parcourir. Cependant, le document se termine brusquement en milieu de phrase dans la section 7, ce qui nuit matériellement à l'expérience de lecture et laisse l'exigence finale non résolue.

Modèles évaluateurs OpenAI GPT-5.5

Score total

49

Commentaire global

La réponse B présente une architecture reconnaissable de raccourcisseur d'URL avec des serveurs API, un cache, une base de données, un sharding et une intention d'analyse asynchrone, mais elle est beaucoup plus faible par rapport aux exigences du benchmark. Elle suppose initialement une seule région malgré un objectif de disponibilité de 99,99%, affirme à tort que les identifiants générés de manière monotone et encodés en Base62 ne sont pas devinables, offre une analyse de latence limitée pour l'objectif de 50 ms p99, a une estimation de stockage discutable, et la section d'analyse est incomplète/tronquée. Ses compromis sont présents mais souvent génériques.

Afficher le détail de l’évaluation

Qualité de l’architecture

Poids 30%
52

La réponse B possède les composants de base d'un raccourcisseur d'URL, y compris une passerelle API, des équilibreurs de charge, un cache, une base de données et un concept d'analyse asynchrone. Cependant, l'architecture est générique, initialement mono-région, manque d'une budgétisation détaillée de la latence et utilise une approche de génération de code discutable pour l'exigence de non-devinabilité.

Complétude

Poids 20%
41

La réponse B couvre de nombreux titres superficiellement, mais plusieurs exigences sont incomplètes ou sous-développées. Elle ne satisfait pas correctement l'exigence de code non devinable, ne conçoit pas explicitement pour p99 sous 50 ms, traite la multi-région comme un travail futur, et sa section d'analyse est coupée avant que le mécanisme réel ne soit décrit.

Analyse des compromis

Poids 20%
50

La réponse B inclut des listes de compromis, mais beaucoup sont génériques et pas profondément liés aux contraintes. Elle manque le compromis critique selon lequel les codes dérivés d'ID séquentiels ou monotones sont plus faciles à énumérer, et elle sous-estime les implications de disponibilité d'un démarrage avec une conception mono-région.

Scalabilité et fiabilité

Poids 20%
44

La réponse B décrit la mise à l'échelle horizontale, le cache shardé, la base de données shardée et les nœuds répliqués, mais l'histoire de la fiabilité n'est pas suffisante pour 99,99% car elle suppose initialement une seule région et laisse la multi-région comme une amélioration. Elle ne montre pas non plus comment le chemin de lecture maintient p99 sous 50 ms lors des échecs ou des misses de cache.

Clarté

Poids 10%
62

La réponse B est généralement lisible et organisée selon les sections demandées, mais elle est moins précise, contient des affirmations inexactes et la section finale d'analyse est visiblement tronquée, ce qui réduit la clarté et l'exhaustivité.

Modèles évaluateurs Google Gemini 2.5 Pro

Score total

57

Commentaire global

La réponse B présente une conception standard mais imparfaite et incomplète. Sa principale faiblesse réside dans le choix d'un générateur d'ID séquentiel pour les codes courts, ce qui contredit directement l'exigence de non-devinabilité. L'hypothèse initiale de concevoir pour une seule région est inappropriée pour l'objectif de disponibilité de 99,99 %. De plus, l'estimation de la capacité est trop optimiste et la section finale sur l'analytique est tronquée, rendant la réponse incomplète. Bien que les composants de base soient corrects, la conception ne répond pas à plusieurs contraintes clés de la consigne.

Afficher le détail de l’évaluation

Qualité de l’architecture

Poids 30%
65

L'architecture est standard et généralement correcte pour un raccourcisseur d'URL de base. Cependant, l'hypothèse initiale d'une conception mono-région est une faiblesse significative étant donné l'exigence de disponibilité de 99,99 %, très difficile à atteindre sans capacités multi-régions ou au moins multi-AZ robustes.

Complétude

Poids 20%
40

La réponse est incomplète. La section finale sur l'analytique des clics est tronquée en plein milieu d'une phrase. De plus, la discussion sur la défaillance régionale, un élément clé de l'exigence de fiabilité, est traitée comme une amélioration future plutôt que comme un élément central de la conception.

Analyse des compromis

Poids 20%
60

La réponse inclut un certain raisonnement sur les compromis, mais il est souvent générique (par exemple, "NoSQL vs SQL", "Le cache peut être coûteux"). Il manque la profondeur et la spécificité de la réponse A, qui lie ses compromis directement aux contraintes de la consigne.

Scalabilité et fiabilité

Poids 20%
50

Ce domaine présente des faiblesses importantes. La stratégie de génération de codes proposée (Base62 d'un compteur) est devinable, violant une exigence fondamentale. L'estimation de la capacité est optimiste. Le plan de fiabilité est sous-développé, en particulier concernant la défaillance régionale, ce qui rend l'objectif de disponibilité de 99,99 % irréalisable avec la conception proposée.

Clarté

Poids 10%
70

La réponse est clairement rédigée et bien structurée avec des titres. Cependant, le contenu manque de la profondeur de la réponse A, et la section finale incomplète nuit à sa clarté générale.

Résumé comparatif

Pour chaque tâche et discussion, le classement final est déterminé par agrégation des rangs par évaluateur (rang moyen + départage Borda). Le score moyen est affiché à titre indicatif.

Évaluateurs: 3

Votes gagnants

3 / 3

Score moyen

90
Voir cette réponse

Votes gagnants

0 / 3

Score moyen

53
Voir cette réponse

Résultats de l’évaluation

Modèles évaluateurs Google Gemini 2.5 Pro

Raison du gagnant

La réponse A est la gagnante incontestable car elle fournit une conception nettement plus robuste, détaillée et correcte, qui correspond entièrement aux contraintes de l'invite. La supériorité de la réponse A est la plus évidente dans les critères fortement pondérés : son architecture est globale et conçue pour une haute disponibilité, son plan de fiabilité est complet (incluant un basculement régional crucial), et son raisonnement est directement lié aux chiffres fournis. En revanche, la réponse B commet une erreur critique en proposant une stratégie de codes courts devinables, fonde sa conception sur une hypothèse faible de région unique et est incomplète.

Modèles évaluateurs OpenAI GPT-5.5

Raison du gagnant

La réponse A l'emporte car ses forces pondérées sont concentrées sur les critères les plus importants : qualité de l'architecture, exhaustivité, raisonnement sur les compromis, et évolutivité/fiabilité. Elle aborde directement toutes les exigences numérotées et les contraintes énoncées avec des mécanismes concrets, tandis que la réponse B manque ou gère faiblement plusieurs exigences fondamentales, en particulier la génération de code non devinable, la disponibilité multi-régions, la planification explicite de la latence et la conception complète de l'analytique.

Modèles évaluateurs Anthropic Claude Fable 5

Raison du gagnant

La réponse A l'emporte de manière décisive sur les critères fortement pondérés. Concernant la Qualité de l'Architecture (pondération 30), A présente une conception cohérente et correcte qui satisfait explicitement la contrainte de non-devinabilité avec un raisonnement quantifié, tandis que le schéma de génération de code principal de B (identifiants Snowflake séquentiels encodés en base62, prétendument non devinables) contredit l'exigence énoncée. Concernant la Complétude (20), A aborde les sept exigences avec des chiffres concrets, tandis que B est tronqué en milieu de phrase dans la section analytique et n'aborde jamais la cible de 50 ms pour le p99 avec un budget de latence. Concernant le Raisonnement sur les Compromis (20) et la Scalabilité/Fiabilité (20), A nomme de réels inconvénients et fournit une bascule régionale, des calculs de marge de capacité et une provision en cas de panne de cache, tandis que B reste plus proche d'un texte générique avec une conception principale dans une seule région. A devance également B en termes de Clarté malgré sa longueur. Le résultat pondéré favorise fortement A sur tous les critères.

X f L