{"id":1261,"date":"2026-08-21T14:31:39","date_gmt":"2026-08-21T14:31:39","guid":{"rendered":"https:\/\/matforge.org\/?p=1261","raw":"https:\/\/matforge.org\/?p=1261"},"modified":"2026-08-21T14:31:39","modified_gmt":"2026-08-21T14:31:39","slug":"case-studies-of-resolved-technical-issues","status":"publish","type":"post","link":"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/","title":{"rendered":"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus","raw":"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus"},"content":{"rendered":"<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 9<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span><p>Les probl\u00e8mes techniques sont plus faciles \u00e0 comprendre lorsque nous les \u00e9tudions en tant que situations r\u00e9elles, non seulement en tant que d\u00e9finitions abstraites. Un d\u00e9butant peut en savoir plus sur le d\u00e9bogage, les journaux, les erreurs d&rsquo;ex\u00e9cution ou les requ\u00eates de base de donn\u00e9es, mais la le\u00e7on compl\u00e8te devient plus claire lorsque ces id\u00e9es apparaissent dans un cas pratique.<\/p>\n<p>Un probl\u00e8me technique r\u00e9solu suit g\u00e9n\u00e9ralement un mod\u00e8le. Quelqu&rsquo;un remarque un sympt\u00f4me. L&rsquo;\u00e9quipe enqu\u00eate. Les premi\u00e8res hypoth\u00e8ses peuvent \u00eatre erron\u00e9es. Les journaux, les tests, la surveillance ou les rapports d&rsquo;utilisateurs r\u00e9v\u00e8lent plus de d\u00e9tails. Enfin, la cause r\u00e9elle est trouv\u00e9e, corrig\u00e9e, test\u00e9e et document\u00e9e.<\/p>\n<p>Cet article pr\u00e9sente plusieurs \u00e9tudes de cas r\u00e9alistes de probl\u00e8mes techniques r\u00e9solus. Ils ne sont pas li\u00e9s \u00e0 une entreprise ou \u00e0 un projet sp\u00e9cifique. Au lieu de cela, ils montrent des mod\u00e8les courants auxquels les d\u00e9veloppeurs sont souvent confront\u00e9s dans les applications Web, les API, les bases de donn\u00e9es, les t\u00e2ches d&rsquo;arri\u00e8re-plan, les d\u00e9ploiements et les syst\u00e8mes de configuration.<\/p>\n<h2>Qu&rsquo;est-ce qui fait qu&rsquo;un probl\u00e8me technique est r\u00e9solu&nbsp;?<\/h2>\n<p>Un probl\u00e8me technique n&rsquo;est pas vraiment r\u00e9solu simplement parce que le probl\u00e8me visible dispara\u00eet. Parfois, un bogue ne semble corrig\u00e9 que parce que le syst\u00e8me a \u00e9t\u00e9 red\u00e9marr\u00e9, le trafic a \u00e9t\u00e9 supprim\u00e9 ou une solution de contournement temporaire a cach\u00e9 le sympt\u00f4me.<\/p>\n<p>Un probl\u00e8me correctement r\u00e9solu comprend g\u00e9n\u00e9ralement plusieurs \u00e9tapes. L&rsquo;\u00e9quipe identifie la cause profonde, applique un correctif, v\u00e9rifie le r\u00e9sultat, v\u00e9rifie la r\u00e9gression et ajoute une forme de pr\u00e9vention. La pr\u00e9vention peut inclure un test, une alerte de surveillance, une meilleure documentation, un message d&rsquo;erreur plus clair ou un processus de d\u00e9ploiement plus s\u00fbr.<\/p>\n<p>Par exemple, si une page se charge lentement et qu&rsquo;un d\u00e9veloppeur red\u00e9marre le serveur, la page peut devenir plus rapide pendant une courte p\u00e9riode. Mais si la cause r\u00e9elle est une requ\u00eate de base de donn\u00e9es inefficace, le probl\u00e8me reviendra. Un v\u00e9ritable correctif doit adresser la requ\u00eate, pas seulement le sympt\u00f4me.<\/p>\n<h2>Un cadre simple pour lire des \u00e9tudes de cas techniques<\/h2>\n<p>Lors de la lecture ou de la r\u00e9daction d&rsquo;une \u00e9tude de cas technique, il est utile de suivre une structure claire. Cela rend le probl\u00e8me plus facile \u00e0 comprendre et emp\u00eache l&rsquo;explication de devenir une liste al\u00e9atoire d&rsquo;\u00e9v\u00e9nements.<\/p>\n<table class=\"custom-table\">\n<tbody>\n<tr>\n<th>\u00c9tape<\/th>\n<th>Question<\/th>\n<th>Pourquoi c&rsquo;est important<\/th>\n<\/tr>\n<tr>\n<td>Sympt\u00f4me<\/td>\n<td>Qu&rsquo;est-ce qui semblait faux&nbsp;?<\/td>\n<td>D\u00e9finit le probl\u00e8me visible<\/td>\n<\/tr>\n<tr>\n<td>impact<\/td>\n<td>Qui ou quoi a \u00e9t\u00e9 affect\u00e9 ?<\/td>\n<td>Montre la gravit\u00e9 et la priorit\u00e9<\/td>\n<\/tr>\n<tr>\n<td>Enqu\u00eate<\/td>\n<td>Qu&rsquo;est-ce qui a \u00e9t\u00e9 v\u00e9rifi\u00e9&nbsp;?<\/td>\n<td>Montre comment l&rsquo;\u00e9quipe est pass\u00e9e de la devinette \u00e0 la preuve<\/td>\n<\/tr>\n<tr>\n<td>cause profonde<\/td>\n<td>Pourquoi est-ce arriv\u00e9 ?<\/td>\n<td>Emp\u00eache les correctifs peu profonds<\/td>\n<\/tr>\n<tr>\n<td>R\u00e9parer<\/td>\n<td>Qu&rsquo;est-ce qui a chang\u00e9&nbsp;?<\/td>\n<td>explique la solution<\/td>\n<\/tr>\n<tr>\n<td>V\u00e9rification<\/td>\n<td>Comment le correctif a-t-il \u00e9t\u00e9 test\u00e9&nbsp;?<\/td>\n<td>R\u00e9duit le risque de r\u00e9gression<\/td>\n<\/tr>\n<tr>\n<td>Pr\u00e9vention<\/td>\n<td>Qu&rsquo;est-ce qui a \u00e9t\u00e9 am\u00e9lior\u00e9 pour la prochaine fois&nbsp;?<\/td>\n<td>Transforme un bug en apprentissage \u00e0 long terme<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>\u00c9tude de cas&nbsp;1&nbsp;: chargement lent de la page caus\u00e9e par une requ\u00eate non optimis\u00e9e<\/h2>\n<p>Le premier probl\u00e8me a commenc\u00e9 comme une simple plainte d&rsquo;utilisateur&nbsp;: une page de rapport prenait six \u00e0 huit&nbsp;secondes \u00e0 charger. Au d\u00e9but, l&rsquo;\u00e9quipe soup\u00e7onnait un probl\u00e8me de front-end car le retard \u00e9tait visible dans le navigateur. Cependant, la synchronisation du navigateur a montr\u00e9 que la majeure partie du d\u00e9lai s&rsquo;est produit avant que la page ne re\u00e7oive les donn\u00e9es du serveur.<\/p>\n<p>Les journaux de backend ont montr\u00e9 qu&rsquo;une requ\u00eate de base de donn\u00e9es \u00e9tait beaucoup plus lente que pr\u00e9vu. Au cours du d\u00e9veloppement, la requ\u00eate a fonctionn\u00e9 rapidement car la base de donn\u00e9es ne contenait qu&rsquo;une petite quantit\u00e9 de donn\u00e9es de test. En production, la m\u00eame requ\u00eate a recherch\u00e9 dans une table beaucoup plus grande et a renvoy\u00e9 plus d&rsquo;enregistrements que la page r\u00e9ellement n\u00e9cessaire.<\/p>\n<p>La cause profonde n&rsquo;\u00e9tait pas le front-end. Il s&rsquo;agissait d&rsquo;une requ\u00eate de base de donn\u00e9es inefficace combin\u00e9e \u00e0 un index manquant. Le correctif comprenait l&rsquo;ajout de l&rsquo;index correct, la limitation des champs s\u00e9lectionn\u00e9s et la r\u00e9duction des jointures inutiles.<\/p>\n<p>Apr\u00e8s le correctif, l&rsquo;\u00e9quipe a compar\u00e9 les temps de r\u00e9ponse avant et apr\u00e8s le d\u00e9ploiement. La page qui prenait auparavant plusieurs secondes est maintenant charg\u00e9e en moins d&rsquo;une seconde dans des conditions normales. Pour emp\u00eacher une r\u00e9p\u00e9tition, l&rsquo;\u00e9quipe a ajout\u00e9 une surveillance lente des requ\u00eates et examin\u00e9 d&rsquo;autres pages \u00e0 fort trafic pour des mod\u00e8les similaires.<\/p>\n<h2>\u00c9tude de cas&nbsp;2&nbsp;: l&rsquo;API renvoie des donn\u00e9es vides en raison d&rsquo;une incompatibilit\u00e9 de param\u00e8tres<\/h2>\n<p>Dans un autre cas, une page frontale affichait \u00ab\u00a0Aucun r\u00e9sultat trouv\u00e9\u00a0\u00bb, m\u00eame si la base de donn\u00e9es contenait clairement des enregistrements correspondants. La premi\u00e8re hypoth\u00e8se \u00e9tait que le point de terminaison de l&rsquo;API avait un bogue.<\/p>\n<p>Le d\u00e9veloppeur a ouvert le panneau de r\u00e9seau du navigateur et inspect\u00e9 la demande. Le frontend envoyait un param\u00e8tre nomm\u00e9 <code>userId<\/code>. Le backend attendu <code>user_id<\/code>. \u00c9tant donn\u00e9 que le backend n&rsquo;a pas re\u00e7u le param\u00e8tre attendu, il a trait\u00e9 la demande comme incompl\u00e8te et a renvoy\u00e9 un r\u00e9sultat vide.<\/p>\n<p>La cause profonde \u00e9tait une inad\u00e9quation du contrat entre le frontend et le backend. Les deux parties fonctionnaient correctement selon leurs propres hypoth\u00e8ses, mais ces hypoth\u00e8ses ne correspondaient pas.<\/p>\n<p>Le correctif \u00e9tait simple&nbsp;: alignez le nom du param\u00e8tre et mettez \u00e0 jour la documentation de l&rsquo;API partag\u00e9e. L&rsquo;\u00e9quipe a \u00e9galement ajout\u00e9 des tests pour les param\u00e8tres valides, manquants et incorrects.<\/p>\n<p>La le\u00e7on est importante pour les d\u00e9butants. De nombreux bogues se produisent \u00e0 la fronti\u00e8re entre les syst\u00e8mes. Le probl\u00e8me peut ne pas \u00eatre \u00e0 l&rsquo;int\u00e9rieur d&rsquo;une seule fonction. Il peut appara\u00eetre lorsque deux parties de l&rsquo;application sont en d\u00e9saccord sur les noms, les formats ou les valeurs attendues.<\/p>\n<h2>\u00c9tude de cas&nbsp;3&nbsp;: erreur d&rsquo;ex\u00e9cution apr\u00e8s le d\u00e9ploiement<\/h2>\n<p>Une fonctionnalit\u00e9 a fonctionn\u00e9 correctement sur la machine du d\u00e9veloppeur mais a \u00e9chou\u00e9 apr\u00e8s le d\u00e9ploiement. Les utilisateurs ont vu un message d&rsquo;erreur g\u00e9n\u00e9rique, tandis que les journaux ont montr\u00e9 une erreur d&rsquo;ex\u00e9cution li\u00e9e \u00e0 une valeur de configuration manquante.<\/p>\n<p>Le code avait besoin d&rsquo;une variable d&rsquo;environnement qui existait localement mais qui n&rsquo;\u00e9tait pas d\u00e9finie en production. Au cours du d\u00e9veloppement local, la valeur provenait d&rsquo;un fichier de configuration local. En production, le syst\u00e8me de d\u00e9ploiement s&rsquo;attendait \u00e0 ce que la valeur soit ajout\u00e9e manuellement.<\/p>\n<p>La cause principale n&rsquo;\u00e9tait pas une erreur de syntaxe ou une fonction cass\u00e9e. C&rsquo;\u00e9tait une diff\u00e9rence d&rsquo;environnement. Le code d&rsquo;application d\u00e9pendait d&rsquo;un param\u00e8tre pr\u00e9sent dans un environnement et manquant dans un autre.<\/p>\n<p>Le correctif consistait \u00e0 ajouter la variable d&rsquo;environnement manquante \u00e0 la configuration de d\u00e9ploiement de production. L&rsquo;\u00e9quipe a \u00e9galement ajout\u00e9 une validation de d\u00e9marrage afin que l&rsquo;application signale une configuration requise manquante avant de diffuser le trafic.<\/p>\n<p>Ce cas montre pourquoi \u00ab\u00a0\u00e7a marche sur ma machine\u00a0\u00bb n&rsquo;est pas suffisant. Les applications r\u00e9elles d\u00e9pendent du code, de la configuration, des d\u00e9pendances, des chemins de fichiers, des secrets, des autorisations et des environnements d&rsquo;ex\u00e9cution.<\/p>\n<h2>\u00c9tude de cas&nbsp;4&nbsp;: calcul incorrect \u00e0 partir d&rsquo;une erreur logique<\/h2>\n<p>Certains des bogues les plus dangereux ne plantent pas l&rsquo;application. Ils produisent des r\u00e9sultats erron\u00e9s alors que tout semble stable.<\/p>\n<p>Dans ce cas, les utilisateurs ont remarqu\u00e9 que le prix final d&rsquo;un r\u00e9capitulatif de commande ne correspondait pas au montant attendu. L&rsquo;application n&rsquo;a pas montr\u00e9 d&rsquo;erreur. Le flux de paiement a \u00e9t\u00e9 effectu\u00e9 avec succ\u00e8s. Cependant, le total \u00e9tait parfois erron\u00e9 lorsqu&rsquo;un escompte et une taxe \u00e9taient appliqu\u00e9s ensemble.<\/p>\n<p>L&rsquo;enqu\u00eate a compar\u00e9 les valeurs attendues avec les valeurs r\u00e9elles en utilisant plusieurs exemples de commandes. La cause profonde \u00e9tait l&rsquo;ordre des op\u00e9rations. Le syst\u00e8me s&rsquo;appliquait \u00e0 la taxe avant la remise, tandis que la r\u00e8gle commerciale exigeait que la remise soit appliqu\u00e9e en premier.<\/p>\n<p>Le correctif a modifi\u00e9 la s\u00e9quence de calculs et ajout\u00e9 des tests unitaires pour plusieurs cas&nbsp;: pas de remise, de remise fixe, de pourcentage de remise, de taxe uniquement et de remise avec taxe.<\/p>\n<p>La principale le\u00e7on est que les erreurs logiques peuvent \u00eatre plus difficiles \u00e0 d\u00e9tecter que les erreurs d&rsquo;ex\u00e9cution. Le programme s&rsquo;ex\u00e9cute, mais il fait la mauvaise chose. C&rsquo;est pourquoi les r\u00e8gles de calcul doivent \u00eatre document\u00e9es et test\u00e9es avec des cas de bord r\u00e9alistes.<\/p>\n<h2>\u00c9tude de cas&nbsp;5&nbsp;: l&rsquo;utilisation de la m\u00e9moire augmente avec le temps<\/h2>\n<p>Un autre probl\u00e8me n&rsquo;est apparu qu&rsquo;apr\u00e8s que le service \u00e9tait en cours depuis plusieurs heures. Au d\u00e9but, l&rsquo;application fonctionnait normalement. Plus tard, il est devenu plus lent. Finalement, le serveur a red\u00e9marr\u00e9 parce que l&rsquo;utilisation de la m\u00e9moire est devenue trop \u00e9lev\u00e9e.<\/p>\n<p>L&rsquo;\u00e9quipe a v\u00e9rifi\u00e9 les mesures de m\u00e9moire et a remarqu\u00e9 une augmentation constante au fil du temps. Les journaux ont montr\u00e9 qu&rsquo;un travail planifi\u00e9 s&rsquo;ex\u00e9cutait toutes les quelques minutes et chargeait un grand nombre d&rsquo;enregistrements en m\u00e9moire. Le travail a stock\u00e9 des r\u00e9sultats dans un cache, mais les anciens r\u00e9sultats n&rsquo;ont jamais \u00e9t\u00e9 supprim\u00e9s.<\/p>\n<p>La cause profonde \u00e9tait la croissance incontr\u00f4l\u00e9e de la m\u00e9moire. L&rsquo;application conservait les donn\u00e9es qui n&rsquo;\u00e9taient plus n\u00e9cessaires.<\/p>\n<p>Le correctif a ajout\u00e9 une limite de taille au cache et a effac\u00e9 les anciennes entr\u00e9es apr\u00e8s chaque cycle de travail. L&rsquo;\u00e9quipe a \u00e9galement ajout\u00e9 des alertes de m\u00e9moire et effectu\u00e9 un test plus long pour confirmer que l&rsquo;utilisation de la m\u00e9moire est rest\u00e9e stable.<\/p>\n<p>Ce cas montre que certains bogues n&rsquo;apparaissent pas imm\u00e9diatement. Ils ont besoin de temps, de charge, de r\u00e9p\u00e9tition ou de processus de longue dur\u00e9e avant que le sympt\u00f4me ne devienne visible.<\/p>\n<h2>\u00c9tude de cas&nbsp;6&nbsp;: le travail de base s&rsquo;ex\u00e9cute deux fois<\/h2>\n<p>Un utilisateur a d\u00e9clar\u00e9 avoir re\u00e7u le m\u00eame e-mail deux fois. Au d\u00e9but, le probl\u00e8me ressemblait \u00e0 un simple probl\u00e8me de service de messagerie. Mais les journaux ont montr\u00e9 que le travail d&rsquo;envoi par e-mail a \u00e9t\u00e9 ex\u00e9cut\u00e9 deux fois pour le m\u00eame \u00e9v\u00e9nement.<\/p>\n<p>Le travailleur en arri\u00e8re-plan avait une logique de nouvelle tentative. Si le travail n&rsquo;a pas re\u00e7u de confirmation assez rapidement, il a r\u00e9essay\u00e9 la t\u00e2che. Dans la plupart des cas, cela a \u00e9t\u00e9 utile. Cependant, l&rsquo;e-mail avait d\u00e9j\u00e0 \u00e9t\u00e9 envoy\u00e9 avant le d\u00e9lai d&rsquo;attente. La nouvelle tentative l&rsquo;a renvoy\u00e9.<\/p>\n<p>La cause profonde \u00e9tait un manque d&rsquo;idempoit\u00e9. Dans les logiciels, une op\u00e9ration idempotente peut s&rsquo;ex\u00e9cuter en toute s\u00e9curit\u00e9 plus d&rsquo;une fois sans cr\u00e9er de r\u00e9sultats en double.<\/p>\n<p>Le correctif a ajout\u00e9 un ID d&rsquo;\u00e9v\u00e9nement unique et une v\u00e9rification avant l&rsquo;envoi. Si l&rsquo;e-mail de cet \u00e9v\u00e9nement avait d\u00e9j\u00e0 \u00e9t\u00e9 envoy\u00e9, le travail s&rsquo;est arr\u00eat\u00e9 au lieu d&rsquo;envoyer un doublon.<\/p>\n<p>La le\u00e7on est que les emplois en arri\u00e8re-plan doivent \u00eatre con\u00e7us en tenant compte des tentatives. Dans les syst\u00e8mes distribu\u00e9s, \u00ab\u00a0Ex\u00e9cuter exactement une fois\u00a0\u00bb est souvent plus difficile qu&rsquo;il n&rsquo;y para\u00eet.<\/p>\n<h2>\u00c9tude de cas&nbsp;7&nbsp;: fonctionnalit\u00e9 cass\u00e9e caus\u00e9e par un changement de configuration<\/h2>\n<p>Dans ce cas, une fonction de t\u00e9l\u00e9chargement de fichiers a cess\u00e9 de fonctionner apr\u00e8s une version. Le code li\u00e9 au t\u00e9l\u00e9chargement de fichiers n&rsquo;avait pas chang\u00e9, de sorte que l&rsquo;\u00e9quipe avait initialement sembl\u00e9 au mauvais endroit.<\/p>\n<p>Apr\u00e8s avoir compar\u00e9 les modifications r\u00e9centes du d\u00e9ploiement, ils ont constat\u00e9 qu&rsquo;une valeur de configuration pour le point de terminaison de stockage avait \u00e9t\u00e9 mise \u00e0 jour. La nouvelle valeur pointait vers le mauvais emplacement. L&rsquo;application essayait de t\u00e9l\u00e9charger des fichiers vers un point de terminaison qui ne les avait pas accept\u00e9s.<\/p>\n<p>La cause principale \u00e9tait un changement de configuration incorrect, et non un changement de code.<\/p>\n<p>Le correctif a restaur\u00e9 le bon point de terminaison et ajout\u00e9 une v\u00e9rification de l&rsquo;\u00e9tat de base de la connexion de stockage. L&rsquo;\u00e9quipe a \u00e9galement d\u00e9plac\u00e9 les modifications de configuration dans le contr\u00f4le de version et ajout\u00e9 des \u00e9tapes de r\u00e9vision pour les param\u00e8tres de production.<\/p>\n<p>Ce cas est un rappel que le comportement du logiciel peut changer m\u00eame lorsque le code source ne le change pas. La configuration fait partie du syst\u00e8me et doit \u00eatre trait\u00e9e avec soin.<\/p>\n<h2>\u00c9tude de cas&nbsp;8&nbsp;: condition de la race dans les actions de l&rsquo;utilisateur<\/h2>\n<p>Certains probl\u00e8mes ne surviennent que lorsque des actions se produisent \u00e0 peu pr\u00e8s au m\u00eame moment. Ces bogues sont difficiles car ils peuvent ne pas appara\u00eetre lors des tests normaux.<\/p>\n<p>Dans un cas, le nombre de stocks est devenu incorrect lorsque deux utilisateurs ont achet\u00e9 le dernier article disponible \u00e0 peu pr\u00e8s au m\u00eame moment. Chaque demande a v\u00e9rifi\u00e9 l&rsquo;inventaire et a vu un article disponible. Les deux demandes se sont poursuivies et le syst\u00e8me a accept\u00e9 deux commandes m\u00eame si un seul \u00e9l\u00e9ment existait.<\/p>\n<p>La cause profonde \u00e9tait une condition de race. L&rsquo;application a v\u00e9rifi\u00e9 l&rsquo;inventaire et mis \u00e0 jour l&rsquo;inventaire comme \u00e9tapes distinctes sans verrouillage ou contr\u00f4le des transactions.<\/p>\n<p>Le correctif a d\u00e9plac\u00e9 la v\u00e9rification de l&rsquo;inventaire et la mise \u00e0 jour dans une transaction de base de donn\u00e9es. Le syst\u00e8me a \u00e9galement ajout\u00e9 une r\u00e8gle pour rejeter le deuxi\u00e8me achat si l&rsquo;article avait d\u00e9j\u00e0 \u00e9t\u00e9 r\u00e9serv\u00e9.<\/p>\n<p>Pour v\u00e9rifier le correctif, l&rsquo;\u00e9quipe a simul\u00e9 des demandes simultan\u00e9es. Cela a permis de confirmer qu&rsquo;une seule commande pouvait r\u00e9server l&rsquo;article final.<\/p>\n<p>La le\u00e7on est que les bogues intermittents n\u00e9cessitent souvent une r\u00e9flexion sur le timing, pas seulement sur la syntaxe ou la logique des fonctions.<\/p>\n<h2>Mod\u00e8les communs pour les probl\u00e8mes r\u00e9solus<\/h2>\n<p>Bien que ces \u00e9tudes de cas impliquent des probl\u00e8mes diff\u00e9rents, elles partagent plusieurs mod\u00e8les. Premi\u00e8rement, le sympt\u00f4me visible n&rsquo;est pas toujours la cause premi\u00e8re. Une page lente peut \u00eatre caus\u00e9e par une requ\u00eate de base de donn\u00e9es. Une fonction cass\u00e9e peut \u00eatre caus\u00e9e par la configuration. Une interface utilisateur vide peut \u00eatre caus\u00e9e par une incompatibilit\u00e9 de contrat d&rsquo;API.<\/p>\n<p>Deuxi\u00e8mement, les changements r\u00e9cents sont importants. Les d\u00e9ploiements, les mises \u00e0 jour des d\u00e9pendances, la croissance des donn\u00e9es, les modifications de configuration et les pics de trafic peuvent tous r\u00e9v\u00e9ler des probl\u00e8mes cach\u00e9s.<\/p>\n<p>Troisi\u00e8mement, les journaux et les mesures sont plus fiables que les suppositions. Un bon d\u00e9bogage d\u00e9pend des preuves. Les d\u00e9veloppeurs doivent inspecter les demandes, les erreurs, les mesures, le comportement de la base de donn\u00e9es et l&rsquo;\u00e9tat du syst\u00e8me avant de changer de code.<\/p>\n<p>Enfin, une bonne solution doit \u00eatre v\u00e9rifi\u00e9e. Sans test, l&rsquo;\u00e9quipe peut seulement esp\u00e9rer que le probl\u00e8me est r\u00e9solu.<\/p>\n<h2>Comment les d\u00e9veloppeurs documentent les probl\u00e8mes r\u00e9solus<\/h2>\n<p>La documentation transforme un bug corrig\u00e9 en connaissance de l&rsquo;\u00e9quipe. Il n&rsquo;est pas n\u00e9cessaire que ce soit long, mais cela devrait \u00eatre clair.<\/p>\n<p>Une note de probl\u00e8me utile ou post mortem peut inclure&nbsp;:<\/p>\n<ul>\n<li>Ce qui s&rsquo;est pass\u00e9&nbsp;;<\/li>\n<li>qui ou quoi a \u00e9t\u00e9 affect\u00e9&nbsp;;<\/li>\n<li>Lorsque le probl\u00e8me a commenc\u00e9&nbsp;;<\/li>\n<li>quelle \u00e9tait la cause profonde&nbsp;;<\/li>\n<li>quel correctif a \u00e9t\u00e9 appliqu\u00e9&nbsp;;<\/li>\n<li>Comment le correctif a \u00e9t\u00e9 v\u00e9rifi\u00e9&nbsp;;<\/li>\n<li>Quelle \u00e9tape de pr\u00e9vention a \u00e9t\u00e9 ajout\u00e9e&nbsp;;<\/li>\n<li>quelle demande d&rsquo;extraction ou d\u00e9ploiement l&rsquo;a r\u00e9solu.<\/li>\n<\/ul>\n<p>Ce type de documentation aide les futurs d\u00e9veloppeurs \u00e0 comprendre le syst\u00e8me plus rapidement. Cela emp\u00eache \u00e9galement le m\u00eame probl\u00e8me d&rsquo;\u00eatre red\u00e9couvert plus tard.<\/p>\n<h2>Comment les d\u00e9butants peuvent s&rsquo;entra\u00eener avec des \u00e9tudes de cas<\/h2>\n<p>Les d\u00e9butants peuvent devenir meilleurs au d\u00e9bogage en \u00e9tudiant les probl\u00e8mes r\u00e9solus. L&rsquo;objectif n&rsquo;est pas seulement de lire le correctif final, mais de comprendre le chemin d&rsquo;un sympt\u00f4me \u00e0 l&rsquo;autre.<\/p>\n<p>Un bon exercice consiste \u00e0 prendre un rapport de bogue et \u00e0 le r\u00e9\u00e9crire \u00e0 l&rsquo;aide du cadre de cet article. Quel \u00e9tait le sympt\u00f4me ? Quelle \u00e9tait la premi\u00e8re hypoth\u00e8se ? Quelles preuves ont chang\u00e9 cette hypoth\u00e8se ? Quelle \u00e9tait la cause profonde ? Comment le correctif a-t-il \u00e9t\u00e9 v\u00e9rifi\u00e9&nbsp;?<\/p>\n<p>Les d\u00e9butants peuvent \u00e9galement recr\u00e9er localement de petits insectes. Par exemple, ils peuvent cr\u00e9er un nom de param\u00e8tre incorrect dans une API de test, \u00e9crire un calcul avec le mauvais ordre d&rsquo;op\u00e9rations ou simuler une valeur de configuration manquante. Ensuite, ils peuvent s&rsquo;entra\u00eener \u00e0 lire des erreurs, \u00e0 v\u00e9rifier les journaux et \u00e0 \u00e9crire un correctif.<\/p>\n<p>Ce type de pratique d\u00e9veloppe une v\u00e9ritable comp\u00e9tence de d\u00e9bogage. La connaissance de la syntaxe est importante, mais les d\u00e9veloppeurs ont \u00e9galement besoin d&rsquo;habitudes d&rsquo;enqu\u00eate.<\/p>\n<h2>Chaque bug fixe peut devenir une le\u00e7on<\/h2>\n<p>Des \u00e9tudes de cas de probl\u00e8mes techniques montrent comment les d\u00e9veloppeurs passent de la confusion \u00e0 la clart\u00e9. Un probl\u00e8me r\u00e9solu n&rsquo;est pas seulement un patch. Il comprend une enqu\u00eate, une analyse des causes profondes, une solution test\u00e9e et une \u00e9tape de pr\u00e9vention.<\/p>\n<p>Les d\u00e9veloppeurs les plus forts font plus que faire dispara\u00eetre les bogues. Ils apprennent d&rsquo;eux. Ils am\u00e9liorent les tests, la surveillance, la documentation, la configuration et les habitudes d&rsquo;\u00e9quipe. Au fil du temps, cela rend le logiciel plus facile \u00e0 comprendre, plus s\u00fbr \u00e0 changer et plus fiable pour les utilisateurs.<\/p>\n<p>Pour les d\u00e9butants, la le\u00e7on principale est simple : le d\u00e9bogage n&rsquo;est pas de deviner. Il s&rsquo;agit d&rsquo;un processus structur\u00e9 d&rsquo;observation, de test, de raisonnement, de fixation et d&rsquo;apprentissage.<\/p>\n","protected":false,"raw":"<p>Les probl\u00e8mes techniques sont plus faciles \u00e0 comprendre lorsque nous les \u00e9tudions en tant que situations r\u00e9elles, non seulement en tant que d\u00e9finitions abstraites. Un d\u00e9butant peut en savoir plus sur le d\u00e9bogage, les journaux, les erreurs d'ex\u00e9cution ou les requ\u00eates de base de donn\u00e9es, mais la le\u00e7on compl\u00e8te devient plus claire lorsque ces id\u00e9es apparaissent dans un cas pratique.<\/p>\n<p>Un probl\u00e8me technique r\u00e9solu suit g\u00e9n\u00e9ralement un mod\u00e8le. Quelqu'un remarque un sympt\u00f4me. L'\u00e9quipe enqu\u00eate. Les premi\u00e8res hypoth\u00e8ses peuvent \u00eatre erron\u00e9es. Les journaux, les tests, la surveillance ou les rapports d'utilisateurs r\u00e9v\u00e8lent plus de d\u00e9tails. Enfin, la cause r\u00e9elle est trouv\u00e9e, corrig\u00e9e, test\u00e9e et document\u00e9e.<\/p>\n<p>Cet article pr\u00e9sente plusieurs \u00e9tudes de cas r\u00e9alistes de probl\u00e8mes techniques r\u00e9solus. Ils ne sont pas li\u00e9s \u00e0 une entreprise ou \u00e0 un projet sp\u00e9cifique. Au lieu de cela, ils montrent des mod\u00e8les courants auxquels les d\u00e9veloppeurs sont souvent confront\u00e9s dans les applications Web, les API, les bases de donn\u00e9es, les t\u00e2ches d'arri\u00e8re-plan, les d\u00e9ploiements et les syst\u00e8mes de configuration.<\/p>\n<h2>Qu'est-ce qui fait qu'un probl\u00e8me technique est r\u00e9solu&nbsp;?<\/h2>\n<p>Un probl\u00e8me technique n'est pas vraiment r\u00e9solu simplement parce que le probl\u00e8me visible dispara\u00eet. Parfois, un bogue ne semble corrig\u00e9 que parce que le syst\u00e8me a \u00e9t\u00e9 red\u00e9marr\u00e9, le trafic a \u00e9t\u00e9 supprim\u00e9 ou une solution de contournement temporaire a cach\u00e9 le sympt\u00f4me.<\/p>\n<p>Un probl\u00e8me correctement r\u00e9solu comprend g\u00e9n\u00e9ralement plusieurs \u00e9tapes. L'\u00e9quipe identifie la cause profonde, applique un correctif, v\u00e9rifie le r\u00e9sultat, v\u00e9rifie la r\u00e9gression et ajoute une forme de pr\u00e9vention. La pr\u00e9vention peut inclure un test, une alerte de surveillance, une meilleure documentation, un message d'erreur plus clair ou un processus de d\u00e9ploiement plus s\u00fbr.<\/p>\n<p>Par exemple, si une page se charge lentement et qu'un d\u00e9veloppeur red\u00e9marre le serveur, la page peut devenir plus rapide pendant une courte p\u00e9riode. Mais si la cause r\u00e9elle est une requ\u00eate de base de donn\u00e9es inefficace, le probl\u00e8me reviendra. Un v\u00e9ritable correctif doit adresser la requ\u00eate, pas seulement le sympt\u00f4me.<\/p>\n<h2>Un cadre simple pour lire des \u00e9tudes de cas techniques<\/h2>\n<p>Lors de la lecture ou de la r\u00e9daction d'une \u00e9tude de cas technique, il est utile de suivre une structure claire. Cela rend le probl\u00e8me plus facile \u00e0 comprendre et emp\u00eache l'explication de devenir une liste al\u00e9atoire d'\u00e9v\u00e9nements.<\/p>\n<table class=\"custom-table\">\n<tbody><tr>\n<th>\u00c9tape<\/th>\n<th>Question<\/th>\n<th>Pourquoi c'est important<\/th>\n<\/tr>\n<tr>\n<td>Sympt\u00f4me<\/td>\n<td>Qu'est-ce qui semblait faux&nbsp;?<\/td>\n<td>D\u00e9finit le probl\u00e8me visible<\/td>\n<\/tr>\n<tr>\n<td>impact<\/td>\n<td>Qui ou quoi a \u00e9t\u00e9 affect\u00e9 ?<\/td>\n<td>Montre la gravit\u00e9 et la priorit\u00e9<\/td>\n<\/tr>\n<tr>\n<td>Enqu\u00eate<\/td>\n<td>Qu'est-ce qui a \u00e9t\u00e9 v\u00e9rifi\u00e9&nbsp;?<\/td>\n<td>Montre comment l'\u00e9quipe est pass\u00e9e de la devinette \u00e0 la preuve<\/td>\n<\/tr>\n<tr>\n<td>cause profonde<\/td>\n<td>Pourquoi est-ce arriv\u00e9 ?<\/td>\n<td>Emp\u00eache les correctifs peu profonds<\/td>\n<\/tr>\n<tr>\n<td>R\u00e9parer<\/td>\n<td>Qu'est-ce qui a chang\u00e9&nbsp;?<\/td>\n<td>explique la solution<\/td>\n<\/tr>\n<tr>\n<td>V\u00e9rification<\/td>\n<td>Comment le correctif a-t-il \u00e9t\u00e9 test\u00e9&nbsp;?<\/td>\n<td>R\u00e9duit le risque de r\u00e9gression<\/td>\n<\/tr>\n<tr>\n<td>Pr\u00e9vention<\/td>\n<td>Qu'est-ce qui a \u00e9t\u00e9 am\u00e9lior\u00e9 pour la prochaine fois&nbsp;?<\/td>\n<td>Transforme un bug en apprentissage \u00e0 long terme<\/td>\n<\/tr>\n<\/tbody><\/table>\n<h2>\u00c9tude de cas&nbsp;1&nbsp;: chargement lent de la page caus\u00e9e par une requ\u00eate non optimis\u00e9e<\/h2>\n<p>Le premier probl\u00e8me a commenc\u00e9 comme une simple plainte d'utilisateur&nbsp;: une page de rapport prenait six \u00e0 huit&nbsp;secondes \u00e0 charger. Au d\u00e9but, l'\u00e9quipe soup\u00e7onnait un probl\u00e8me de front-end car le retard \u00e9tait visible dans le navigateur. Cependant, la synchronisation du navigateur a montr\u00e9 que la majeure partie du d\u00e9lai s'est produit avant que la page ne re\u00e7oive les donn\u00e9es du serveur.<\/p>\n<p>Les journaux de backend ont montr\u00e9 qu'une requ\u00eate de base de donn\u00e9es \u00e9tait beaucoup plus lente que pr\u00e9vu. Au cours du d\u00e9veloppement, la requ\u00eate a fonctionn\u00e9 rapidement car la base de donn\u00e9es ne contenait qu'une petite quantit\u00e9 de donn\u00e9es de test. En production, la m\u00eame requ\u00eate a recherch\u00e9 dans une table beaucoup plus grande et a renvoy\u00e9 plus d'enregistrements que la page r\u00e9ellement n\u00e9cessaire.<\/p>\n<p>La cause profonde n'\u00e9tait pas le front-end. Il s'agissait d'une requ\u00eate de base de donn\u00e9es inefficace combin\u00e9e \u00e0 un index manquant. Le correctif comprenait l'ajout de l'index correct, la limitation des champs s\u00e9lectionn\u00e9s et la r\u00e9duction des jointures inutiles.<\/p>\n<p>Apr\u00e8s le correctif, l'\u00e9quipe a compar\u00e9 les temps de r\u00e9ponse avant et apr\u00e8s le d\u00e9ploiement. La page qui prenait auparavant plusieurs secondes est maintenant charg\u00e9e en moins d'une seconde dans des conditions normales. Pour emp\u00eacher une r\u00e9p\u00e9tition, l'\u00e9quipe a ajout\u00e9 une surveillance lente des requ\u00eates et examin\u00e9 d'autres pages \u00e0 fort trafic pour des mod\u00e8les similaires.<\/p>\n<h2>\u00c9tude de cas&nbsp;2&nbsp;: l'API renvoie des donn\u00e9es vides en raison d'une incompatibilit\u00e9 de param\u00e8tres<\/h2>\n<p>Dans un autre cas, une page frontale affichait \"Aucun r\u00e9sultat trouv\u00e9\", m\u00eame si la base de donn\u00e9es contenait clairement des enregistrements correspondants. La premi\u00e8re hypoth\u00e8se \u00e9tait que le point de terminaison de l'API avait un bogue.<\/p>\n<p>Le d\u00e9veloppeur a ouvert le panneau de r\u00e9seau du navigateur et inspect\u00e9 la demande. Le frontend envoyait un param\u00e8tre nomm\u00e9 <code>userId<\/code>. Le backend attendu <code>user_id<\/code>. \u00c9tant donn\u00e9 que le backend n'a pas re\u00e7u le param\u00e8tre attendu, il a trait\u00e9 la demande comme incompl\u00e8te et a renvoy\u00e9 un r\u00e9sultat vide.<\/p>\n<p>La cause profonde \u00e9tait une inad\u00e9quation du contrat entre le frontend et le backend. Les deux parties fonctionnaient correctement selon leurs propres hypoth\u00e8ses, mais ces hypoth\u00e8ses ne correspondaient pas.<\/p>\n<p>Le correctif \u00e9tait simple&nbsp;: alignez le nom du param\u00e8tre et mettez \u00e0 jour la documentation de l'API partag\u00e9e. L'\u00e9quipe a \u00e9galement ajout\u00e9 des tests pour les param\u00e8tres valides, manquants et incorrects.<\/p>\n<p>La le\u00e7on est importante pour les d\u00e9butants. De nombreux bogues se produisent \u00e0 la fronti\u00e8re entre les syst\u00e8mes. Le probl\u00e8me peut ne pas \u00eatre \u00e0 l'int\u00e9rieur d'une seule fonction. Il peut appara\u00eetre lorsque deux parties de l'application sont en d\u00e9saccord sur les noms, les formats ou les valeurs attendues.<\/p>\n<h2>\u00c9tude de cas&nbsp;3&nbsp;: erreur d'ex\u00e9cution apr\u00e8s le d\u00e9ploiement<\/h2>\n<p>Une fonctionnalit\u00e9 a fonctionn\u00e9 correctement sur la machine du d\u00e9veloppeur mais a \u00e9chou\u00e9 apr\u00e8s le d\u00e9ploiement. Les utilisateurs ont vu un message d'erreur g\u00e9n\u00e9rique, tandis que les journaux ont montr\u00e9 une erreur d'ex\u00e9cution li\u00e9e \u00e0 une valeur de configuration manquante.<\/p>\n<p>Le code avait besoin d'une variable d'environnement qui existait localement mais qui n'\u00e9tait pas d\u00e9finie en production. Au cours du d\u00e9veloppement local, la valeur provenait d'un fichier de configuration local. En production, le syst\u00e8me de d\u00e9ploiement s'attendait \u00e0 ce que la valeur soit ajout\u00e9e manuellement.<\/p>\n<p>La cause principale n'\u00e9tait pas une erreur de syntaxe ou une fonction cass\u00e9e. C'\u00e9tait une diff\u00e9rence d'environnement. Le code d'application d\u00e9pendait d'un param\u00e8tre pr\u00e9sent dans un environnement et manquant dans un autre.<\/p>\n<p>Le correctif consistait \u00e0 ajouter la variable d'environnement manquante \u00e0 la configuration de d\u00e9ploiement de production. L'\u00e9quipe a \u00e9galement ajout\u00e9 une validation de d\u00e9marrage afin que l'application signale une configuration requise manquante avant de diffuser le trafic.<\/p>\n<p>Ce cas montre pourquoi \"\u00e7a marche sur ma machine\" n'est pas suffisant. Les applications r\u00e9elles d\u00e9pendent du code, de la configuration, des d\u00e9pendances, des chemins de fichiers, des secrets, des autorisations et des environnements d'ex\u00e9cution.<\/p>\n<h2>\u00c9tude de cas&nbsp;4&nbsp;: calcul incorrect \u00e0 partir d'une erreur logique<\/h2>\n<p>Certains des bogues les plus dangereux ne plantent pas l'application. Ils produisent des r\u00e9sultats erron\u00e9s alors que tout semble stable.<\/p>\n<p>Dans ce cas, les utilisateurs ont remarqu\u00e9 que le prix final d'un r\u00e9capitulatif de commande ne correspondait pas au montant attendu. L'application n'a pas montr\u00e9 d'erreur. Le flux de paiement a \u00e9t\u00e9 effectu\u00e9 avec succ\u00e8s. Cependant, le total \u00e9tait parfois erron\u00e9 lorsqu'un escompte et une taxe \u00e9taient appliqu\u00e9s ensemble.<\/p>\n<p>L'enqu\u00eate a compar\u00e9 les valeurs attendues avec les valeurs r\u00e9elles en utilisant plusieurs exemples de commandes. La cause profonde \u00e9tait l'ordre des op\u00e9rations. Le syst\u00e8me s'appliquait \u00e0 la taxe avant la remise, tandis que la r\u00e8gle commerciale exigeait que la remise soit appliqu\u00e9e en premier.<\/p>\n<p>Le correctif a modifi\u00e9 la s\u00e9quence de calculs et ajout\u00e9 des tests unitaires pour plusieurs cas&nbsp;: pas de remise, de remise fixe, de pourcentage de remise, de taxe uniquement et de remise avec taxe.<\/p>\n<p>La principale le\u00e7on est que les erreurs logiques peuvent \u00eatre plus difficiles \u00e0 d\u00e9tecter que les erreurs d'ex\u00e9cution. Le programme s'ex\u00e9cute, mais il fait la mauvaise chose. C'est pourquoi les r\u00e8gles de calcul doivent \u00eatre document\u00e9es et test\u00e9es avec des cas de bord r\u00e9alistes.<\/p>\n<h2>\u00c9tude de cas&nbsp;5&nbsp;: l'utilisation de la m\u00e9moire augmente avec le temps<\/h2>\n<p>Un autre probl\u00e8me n'est apparu qu'apr\u00e8s que le service \u00e9tait en cours depuis plusieurs heures. Au d\u00e9but, l'application fonctionnait normalement. Plus tard, il est devenu plus lent. Finalement, le serveur a red\u00e9marr\u00e9 parce que l'utilisation de la m\u00e9moire est devenue trop \u00e9lev\u00e9e.<\/p>\n<p>L'\u00e9quipe a v\u00e9rifi\u00e9 les mesures de m\u00e9moire et a remarqu\u00e9 une augmentation constante au fil du temps. Les journaux ont montr\u00e9 qu'un travail planifi\u00e9 s'ex\u00e9cutait toutes les quelques minutes et chargeait un grand nombre d'enregistrements en m\u00e9moire. Le travail a stock\u00e9 des r\u00e9sultats dans un cache, mais les anciens r\u00e9sultats n'ont jamais \u00e9t\u00e9 supprim\u00e9s.<\/p>\n<p>La cause profonde \u00e9tait la croissance incontr\u00f4l\u00e9e de la m\u00e9moire. L'application conservait les donn\u00e9es qui n'\u00e9taient plus n\u00e9cessaires.<\/p>\n<p>Le correctif a ajout\u00e9 une limite de taille au cache et a effac\u00e9 les anciennes entr\u00e9es apr\u00e8s chaque cycle de travail. L'\u00e9quipe a \u00e9galement ajout\u00e9 des alertes de m\u00e9moire et effectu\u00e9 un test plus long pour confirmer que l'utilisation de la m\u00e9moire est rest\u00e9e stable.<\/p>\n<p>Ce cas montre que certains bogues n'apparaissent pas imm\u00e9diatement. Ils ont besoin de temps, de charge, de r\u00e9p\u00e9tition ou de processus de longue dur\u00e9e avant que le sympt\u00f4me ne devienne visible.<\/p>\n<h2>\u00c9tude de cas&nbsp;6&nbsp;: le travail de base s'ex\u00e9cute deux fois<\/h2>\n<p>Un utilisateur a d\u00e9clar\u00e9 avoir re\u00e7u le m\u00eame e-mail deux fois. Au d\u00e9but, le probl\u00e8me ressemblait \u00e0 un simple probl\u00e8me de service de messagerie. Mais les journaux ont montr\u00e9 que le travail d'envoi par e-mail a \u00e9t\u00e9 ex\u00e9cut\u00e9 deux fois pour le m\u00eame \u00e9v\u00e9nement.<\/p>\n<p>Le travailleur en arri\u00e8re-plan avait une logique de nouvelle tentative. Si le travail n'a pas re\u00e7u de confirmation assez rapidement, il a r\u00e9essay\u00e9 la t\u00e2che. Dans la plupart des cas, cela a \u00e9t\u00e9 utile. Cependant, l'e-mail avait d\u00e9j\u00e0 \u00e9t\u00e9 envoy\u00e9 avant le d\u00e9lai d'attente. La nouvelle tentative l'a renvoy\u00e9.<\/p>\n<p>La cause profonde \u00e9tait un manque d'idempoit\u00e9. Dans les logiciels, une op\u00e9ration idempotente peut s'ex\u00e9cuter en toute s\u00e9curit\u00e9 plus d'une fois sans cr\u00e9er de r\u00e9sultats en double.<\/p>\n<p>Le correctif a ajout\u00e9 un ID d'\u00e9v\u00e9nement unique et une v\u00e9rification avant l'envoi. Si l'e-mail de cet \u00e9v\u00e9nement avait d\u00e9j\u00e0 \u00e9t\u00e9 envoy\u00e9, le travail s'est arr\u00eat\u00e9 au lieu d'envoyer un doublon.<\/p>\n<p>La le\u00e7on est que les emplois en arri\u00e8re-plan doivent \u00eatre con\u00e7us en tenant compte des tentatives. Dans les syst\u00e8mes distribu\u00e9s, \"Ex\u00e9cuter exactement une fois\" est souvent plus difficile qu'il n'y para\u00eet.<\/p>\n<h2>\u00c9tude de cas&nbsp;7&nbsp;: fonctionnalit\u00e9 cass\u00e9e caus\u00e9e par un changement de configuration<\/h2>\n<p>Dans ce cas, une fonction de t\u00e9l\u00e9chargement de fichiers a cess\u00e9 de fonctionner apr\u00e8s une version. Le code li\u00e9 au t\u00e9l\u00e9chargement de fichiers n'avait pas chang\u00e9, de sorte que l'\u00e9quipe avait initialement sembl\u00e9 au mauvais endroit.<\/p>\n<p>Apr\u00e8s avoir compar\u00e9 les modifications r\u00e9centes du d\u00e9ploiement, ils ont constat\u00e9 qu'une valeur de configuration pour le point de terminaison de stockage avait \u00e9t\u00e9 mise \u00e0 jour. La nouvelle valeur pointait vers le mauvais emplacement. L'application essayait de t\u00e9l\u00e9charger des fichiers vers un point de terminaison qui ne les avait pas accept\u00e9s.<\/p>\n<p>La cause principale \u00e9tait un changement de configuration incorrect, et non un changement de code.<\/p>\n<p>Le correctif a restaur\u00e9 le bon point de terminaison et ajout\u00e9 une v\u00e9rification de l'\u00e9tat de base de la connexion de stockage. L'\u00e9quipe a \u00e9galement d\u00e9plac\u00e9 les modifications de configuration dans le contr\u00f4le de version et ajout\u00e9 des \u00e9tapes de r\u00e9vision pour les param\u00e8tres de production.<\/p>\n<p>Ce cas est un rappel que le comportement du logiciel peut changer m\u00eame lorsque le code source ne le change pas. La configuration fait partie du syst\u00e8me et doit \u00eatre trait\u00e9e avec soin.<\/p>\n<h2>\u00c9tude de cas&nbsp;8&nbsp;: condition de la race dans les actions de l'utilisateur<\/h2>\n<p>Certains probl\u00e8mes ne surviennent que lorsque des actions se produisent \u00e0 peu pr\u00e8s au m\u00eame moment. Ces bogues sont difficiles car ils peuvent ne pas appara\u00eetre lors des tests normaux.<\/p>\n<p>Dans un cas, le nombre de stocks est devenu incorrect lorsque deux utilisateurs ont achet\u00e9 le dernier article disponible \u00e0 peu pr\u00e8s au m\u00eame moment. Chaque demande a v\u00e9rifi\u00e9 l'inventaire et a vu un article disponible. Les deux demandes se sont poursuivies et le syst\u00e8me a accept\u00e9 deux commandes m\u00eame si un seul \u00e9l\u00e9ment existait.<\/p>\n<p>La cause profonde \u00e9tait une condition de race. L'application a v\u00e9rifi\u00e9 l'inventaire et mis \u00e0 jour l'inventaire comme \u00e9tapes distinctes sans verrouillage ou contr\u00f4le des transactions.<\/p>\n<p>Le correctif a d\u00e9plac\u00e9 la v\u00e9rification de l'inventaire et la mise \u00e0 jour dans une transaction de base de donn\u00e9es. Le syst\u00e8me a \u00e9galement ajout\u00e9 une r\u00e8gle pour rejeter le deuxi\u00e8me achat si l'article avait d\u00e9j\u00e0 \u00e9t\u00e9 r\u00e9serv\u00e9.<\/p>\n<p>Pour v\u00e9rifier le correctif, l'\u00e9quipe a simul\u00e9 des demandes simultan\u00e9es. Cela a permis de confirmer qu'une seule commande pouvait r\u00e9server l'article final.<\/p>\n<p>La le\u00e7on est que les bogues intermittents n\u00e9cessitent souvent une r\u00e9flexion sur le timing, pas seulement sur la syntaxe ou la logique des fonctions.<\/p>\n<h2>Mod\u00e8les communs pour les probl\u00e8mes r\u00e9solus<\/h2>\n<p>Bien que ces \u00e9tudes de cas impliquent des probl\u00e8mes diff\u00e9rents, elles partagent plusieurs mod\u00e8les. Premi\u00e8rement, le sympt\u00f4me visible n'est pas toujours la cause premi\u00e8re. Une page lente peut \u00eatre caus\u00e9e par une requ\u00eate de base de donn\u00e9es. Une fonction cass\u00e9e peut \u00eatre caus\u00e9e par la configuration. Une interface utilisateur vide peut \u00eatre caus\u00e9e par une incompatibilit\u00e9 de contrat d'API.<\/p>\n<p>Deuxi\u00e8mement, les changements r\u00e9cents sont importants. Les d\u00e9ploiements, les mises \u00e0 jour des d\u00e9pendances, la croissance des donn\u00e9es, les modifications de configuration et les pics de trafic peuvent tous r\u00e9v\u00e9ler des probl\u00e8mes cach\u00e9s.<\/p>\n<p>Troisi\u00e8mement, les journaux et les mesures sont plus fiables que les suppositions. Un bon d\u00e9bogage d\u00e9pend des preuves. Les d\u00e9veloppeurs doivent inspecter les demandes, les erreurs, les mesures, le comportement de la base de donn\u00e9es et l'\u00e9tat du syst\u00e8me avant de changer de code.<\/p>\n<p>Enfin, une bonne solution doit \u00eatre v\u00e9rifi\u00e9e. Sans test, l'\u00e9quipe peut seulement esp\u00e9rer que le probl\u00e8me est r\u00e9solu.<\/p>\n<h2>Comment les d\u00e9veloppeurs documentent les probl\u00e8mes r\u00e9solus<\/h2>\n<p>La documentation transforme un bug corrig\u00e9 en connaissance de l'\u00e9quipe. Il n'est pas n\u00e9cessaire que ce soit long, mais cela devrait \u00eatre clair.<\/p>\n<p>Une note de probl\u00e8me utile ou post mortem peut inclure&nbsp;:<\/p>\n<ul>\n<li>Ce qui s'est pass\u00e9&nbsp;;<\/li>\n<li>qui ou quoi a \u00e9t\u00e9 affect\u00e9&nbsp;;<\/li>\n<li>Lorsque le probl\u00e8me a commenc\u00e9&nbsp;;<\/li>\n<li>quelle \u00e9tait la cause profonde&nbsp;;<\/li>\n<li>quel correctif a \u00e9t\u00e9 appliqu\u00e9&nbsp;;<\/li>\n<li>Comment le correctif a \u00e9t\u00e9 v\u00e9rifi\u00e9&nbsp;;<\/li>\n<li>Quelle \u00e9tape de pr\u00e9vention a \u00e9t\u00e9 ajout\u00e9e&nbsp;;<\/li>\n<li>quelle demande d'extraction ou d\u00e9ploiement l'a r\u00e9solu.<\/li>\n<\/ul>\n<p>Ce type de documentation aide les futurs d\u00e9veloppeurs \u00e0 comprendre le syst\u00e8me plus rapidement. Cela emp\u00eache \u00e9galement le m\u00eame probl\u00e8me d'\u00eatre red\u00e9couvert plus tard.<\/p>\n<h2>Comment les d\u00e9butants peuvent s'entra\u00eener avec des \u00e9tudes de cas<\/h2>\n<p>Les d\u00e9butants peuvent devenir meilleurs au d\u00e9bogage en \u00e9tudiant les probl\u00e8mes r\u00e9solus. L'objectif n'est pas seulement de lire le correctif final, mais de comprendre le chemin d'un sympt\u00f4me \u00e0 l'autre.<\/p>\n<p>Un bon exercice consiste \u00e0 prendre un rapport de bogue et \u00e0 le r\u00e9\u00e9crire \u00e0 l'aide du cadre de cet article. Quel \u00e9tait le sympt\u00f4me ? Quelle \u00e9tait la premi\u00e8re hypoth\u00e8se ? Quelles preuves ont chang\u00e9 cette hypoth\u00e8se ? Quelle \u00e9tait la cause profonde ? Comment le correctif a-t-il \u00e9t\u00e9 v\u00e9rifi\u00e9&nbsp;?<\/p>\n<p>Les d\u00e9butants peuvent \u00e9galement recr\u00e9er localement de petits insectes. Par exemple, ils peuvent cr\u00e9er un nom de param\u00e8tre incorrect dans une API de test, \u00e9crire un calcul avec le mauvais ordre d'op\u00e9rations ou simuler une valeur de configuration manquante. Ensuite, ils peuvent s'entra\u00eener \u00e0 lire des erreurs, \u00e0 v\u00e9rifier les journaux et \u00e0 \u00e9crire un correctif.<\/p>\n<p>Ce type de pratique d\u00e9veloppe une v\u00e9ritable comp\u00e9tence de d\u00e9bogage. La connaissance de la syntaxe est importante, mais les d\u00e9veloppeurs ont \u00e9galement besoin d'habitudes d'enqu\u00eate.<\/p>\n<h2>Chaque bug fixe peut devenir une le\u00e7on<\/h2>\n<p>Des \u00e9tudes de cas de probl\u00e8mes techniques montrent comment les d\u00e9veloppeurs passent de la confusion \u00e0 la clart\u00e9. Un probl\u00e8me r\u00e9solu n'est pas seulement un patch. Il comprend une enqu\u00eate, une analyse des causes profondes, une solution test\u00e9e et une \u00e9tape de pr\u00e9vention.<\/p>\n<p>Les d\u00e9veloppeurs les plus forts font plus que faire dispara\u00eetre les bogues. Ils apprennent d'eux. Ils am\u00e9liorent les tests, la surveillance, la documentation, la configuration et les habitudes d'\u00e9quipe. Au fil du temps, cela rend le logiciel plus facile \u00e0 comprendre, plus s\u00fbr \u00e0 changer et plus fiable pour les utilisateurs.<\/p>\n<p>Pour les d\u00e9butants, la le\u00e7on principale est simple : le d\u00e9bogage n'est pas de deviner. Il s'agit d'un processus structur\u00e9 d'observation, de test, de raisonnement, de fixation et d'apprentissage.<\/p>\n"},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 9<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>Les probl\u00e8mes techniques sont plus faciles \u00e0 comprendre lorsque nous les \u00e9tudions en tant que situations r\u00e9elles, non seulement en tant que d\u00e9finitions abstraites. Un d\u00e9butant peut en savoir plus sur le d\u00e9bogage, les journaux, les erreurs d&rsquo;ex\u00e9cution ou les requ\u00eates de base de donn\u00e9es, mais la le\u00e7on compl\u00e8te devient plus claire lorsque ces id\u00e9es [&hellip;]<\/p>\n","protected":false,"raw":""},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"fr_FR","_original_post":"https:\/\/matforge.org\/?p=332","iawp_total_views":2,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1261","post","type-post","status-publish","format-standard","hentry","category-issue-tracking-tickets-technical-requests","fr-FR"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus<\/title>\n<meta name=\"description\" content=\"Apprenez \u00e0 partir d&#039;\u00e9tudes de cas techniques de style r\u00e9el\u00a0: comment les d\u00e9veloppeurs \u00e9tudient les bogues, recherchent des causes profondes, testent les correctifs et \u00e9vitent des probl\u00e8mes similaires.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus\" \/>\n<meta property=\"og:description\" content=\"Apprenez \u00e0 partir d&#039;\u00e9tudes de cas techniques de style r\u00e9el\u00a0: comment les d\u00e9veloppeurs \u00e9tudient les bogues, recherchent des causes profondes, testent les correctifs et \u00e9vitent des probl\u00e8mes similaires.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/\" \/>\n<meta property=\"og:site_name\" content=\"matforge.org\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-21T14:31:39+00:00\" \/>\n<meta name=\"author\" content=\"Priya Nair\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"Priya Nair\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/case-studies-of-resolved-technical-issues\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/case-studies-of-resolved-technical-issues\\\/\"},\"author\":{\"name\":\"Priya Nair\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/2effd7bc155a5e6357f31dac970c5795\"},\"headline\":\"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus\",\"datePublished\":\"2026-08-21T14:31:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/case-studies-of-resolved-technical-issues\\\/\"},\"wordCount\":3219,\"commentCount\":0,\"articleSection\":[\"Suivi des probl\u00e8mes, billets &amp; Demandes techniques\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/matforge.org\\\/fr\\\/case-studies-of-resolved-technical-issues\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/case-studies-of-resolved-technical-issues\\\/\",\"url\":\"https:\\\/\\\/matforge.org\\\/fr\\\/case-studies-of-resolved-technical-issues\\\/\",\"name\":\"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/#website\"},\"datePublished\":\"2026-08-21T14:31:39+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/2effd7bc155a5e6357f31dac970c5795\"},\"description\":\"Apprenez \u00e0 partir d'\u00e9tudes de cas techniques de style r\u00e9el\u00a0: comment les d\u00e9veloppeurs \u00e9tudient les bogues, recherchent des causes profondes, testent les correctifs et \u00e9vitent des probl\u00e8mes similaires.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/case-studies-of-resolved-technical-issues\\\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/matforge.org\\\/fr\\\/case-studies-of-resolved-technical-issues\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/matforge.org\\\/fr\\\/case-studies-of-resolved-technical-issues\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/matforge.org\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#website\",\"url\":\"https:\\\/\\\/matforge.org\\\/\",\"name\":\"matforge.org\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/matforge.org\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/2effd7bc155a5e6357f31dac970c5795\",\"name\":\"Priya Nair\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g\",\"caption\":\"Priya Nair\"},\"sameAs\":[\"http:\\\/\\\/matforge.org\"],\"url\":\"https:\\\/\\\/matforge.org\\\/author\\\/priya-nair\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus","description":"Apprenez \u00e0 partir d'\u00e9tudes de cas techniques de style r\u00e9el\u00a0: comment les d\u00e9veloppeurs \u00e9tudient les bogues, recherchent des causes profondes, testent les correctifs et \u00e9vitent des probl\u00e8mes similaires.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/","og_locale":"fr_FR","og_type":"article","og_title":"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus","og_description":"Apprenez \u00e0 partir d'\u00e9tudes de cas techniques de style r\u00e9el\u00a0: comment les d\u00e9veloppeurs \u00e9tudient les bogues, recherchent des causes profondes, testent les correctifs et \u00e9vitent des probl\u00e8mes similaires.","og_url":"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/","og_site_name":"matforge.org","article_published_time":"2026-08-21T14:31:39+00:00","author":"Priya Nair","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"Priya Nair","Dur\u00e9e de lecture estim\u00e9e":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/#article","isPartOf":{"@id":"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/"},"author":{"name":"Priya Nair","@id":"https:\/\/matforge.org\/#\/schema\/person\/2effd7bc155a5e6357f31dac970c5795"},"headline":"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus","datePublished":"2026-08-21T14:31:39+00:00","mainEntityOfPage":{"@id":"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/"},"wordCount":3219,"commentCount":0,"articleSection":["Suivi des probl\u00e8mes, billets &amp; Demandes techniques"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/","url":"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/","name":"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus","isPartOf":{"@id":"https:\/\/matforge.org\/#website"},"datePublished":"2026-08-21T14:31:39+00:00","author":{"@id":"https:\/\/matforge.org\/#\/schema\/person\/2effd7bc155a5e6357f31dac970c5795"},"description":"Apprenez \u00e0 partir d'\u00e9tudes de cas techniques de style r\u00e9el\u00a0: comment les d\u00e9veloppeurs \u00e9tudient les bogues, recherchent des causes profondes, testent les correctifs et \u00e9vitent des probl\u00e8mes similaires.","breadcrumb":{"@id":"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/matforge.org\/fr\/case-studies-of-resolved-technical-issues\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/matforge.org\/"},{"@type":"ListItem","position":2,"name":"\u00c9tudes de cas de probl\u00e8mes techniques r\u00e9solus"}]},{"@type":"WebSite","@id":"https:\/\/matforge.org\/#website","url":"https:\/\/matforge.org\/","name":"matforge.org","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/matforge.org\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Person","@id":"https:\/\/matforge.org\/#\/schema\/person\/2effd7bc155a5e6357f31dac970c5795","name":"Priya Nair","image":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/secure.gravatar.com\/avatar\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g","caption":"Priya Nair"},"sameAs":["http:\/\/matforge.org"],"url":"https:\/\/matforge.org\/author\/priya-nair\/"}]}},"_links":{"self":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/1261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/comments?post=1261"}],"version-history":[{"count":1,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/1261\/revisions"}],"predecessor-version":[{"id":1429,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/1261\/revisions\/1429"}],"wp:attachment":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/media?parent=1261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/categories?post=1261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/tags?post=1261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}