English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

invité
1 / ?
retour aux leçons

Lire le code pour les taux de croissance

Examen du code pour la correction par rapport à l'examen du code pour la complexité

L'examen du code pour la correction détecte les erreurs de logique : conditions erronées, index décalés d'un cran, vérifications null manquantes. L'examen du code tenant compte de la complexité détecte une classe différente de défaut : code qui fonctionne correctement à N = 100 mais croît de façon catastrophique à N = 100 000.

Modèle MOAD-0001 : list seen O(N²) vs set seen O(N) — correction d'une ligne


Cette leçon se connecte à une investigation plus profonde dans le cours unhamming : Le chapitre manquant : complexité algorithmique couvre Big O dans le contexte des défauts de production, & MOAD-0001 : le défaut sédimentaire mappe le modèle dans 60+ écosystèmes logiciels.


Deux heuristiques d'examen


Les boucles imbriquées multiplient la complexité. Deux boucles imbriquées sur N éléments produisent O(N²). Trois produisent O(N³). Lors de l'examen : comptez d'abord la profondeur d'imbrication des boucles.


Conteneur séquentiel à l'intérieur d'une boucle chaude. Toute vérification .contains(), .includes(), .find(), ou in list à l'intérieur d'une boucle coûte O(N) par vérification. Sur N itérations : O(N²) au total. Ce modèle apparaît dans le code de production dans des dizaines d'écosystèmes — le compilateur GHC Haskell, Python pip, Apache Maven, Rust Cargo, TypeScript, Godot. Même erreur, bases de code différentes.

Examen : find_duplicates

Examinez la fonction Python suivante pour la complexité :


def find_duplicates(items):
    seen = []
    duplicates = []
    for item in items:
        if item in seen:
            duplicates.append(item)
        else:
            seen.append(item)
    return duplicates
Effectuez un examen du code tenant compte de la complexité : (a) Quelle est la complexité en temps de cette fonction ? (b) Pourquoi ? Identifiez la ligne exacte responsable. (c) Réécrivez-la en O(N).

MOAD-0001 : le défaut sédimentaire

Le même défaut, soixante écosystèmes

Le modèle if x not in list: list.append(x) à l'intérieur d'une boucle apparaît — a apparu — dans le code de production dans des dizaines d'écosystèmes logiciels :


- GHC (compilateur Haskell) : solveur de dépendances, O(N²) à N = 50 000 paquets, 17 minutes de compilation

- Python pip : résolution des conflits de dépendances

- Apache Maven : déduplication du classpath

- Rust Cargo : unification des fonctionnalités

- Compilateur TypeScript : résolution des modules

- Moteur Godot / Redot : traversée du graphique des nœuds


Aucune de ces équipes n'a fait une erreur. Elles ont écrit du code correct à petit N. N a grandi. Le code s'est calcifié. Le modèle a un nom : MOAD-0001, le défaut sédimentaire. Sédiment : correct, inoffensif en couches minces. Avec le temps, les couches s'accumulent et se durcissent.


Le correctif

Dans tous les cas : remplacez le conteneur séquentiel par un conteneur de hachage. Une ligne. Aucun changement comportemental aux entrées correctes. Accélération 100–1 000× à N réel.


Le correctif fonctionne parce que deux opérations doivent rester rapides :

1. Vérification d'appartenance : cet élément a-t-il déjà été vu ?

2. Sortie ordonnée : retourner les éléments dans l'ordre où ils ont été trouvés (parfois requis, parfois non).


Un ensemble gère (1) en O(1). Si (2) compte aussi, conservez une liste séparée pour la sortie ordonnée et un ensemble pour la vérification d'appartenance. Deux structures de données, chacune faisant un travail.

Répondre à un examinateur

Une demande de tirage corrige MOAD-0001 dans la fonction de traversée du graphique d'un projet. Un examinateur commente :


> "Les ensembles ne préservent pas l'ordre d'insertion — cela change le comportement."

Comment répondez-vous ? Expliquez quand la préoccupation de l'examinateur s'applique et quand elle ne s'applique pas. Proposez une solution qui satisfasse les deux préoccupations lorsqu'elles entrent en conflit.

Le modèle d'analyse d'entretien

Le format attendu

L'analyse de la complexité algorithmique apparaît dans les entretiens d'ingénierie logicielle. Une réponse forte suit un modèle en quatre parties :


1. Énoncez la complexité actuelle — O(?) pour le temps, O(?) pour l'espace.

2. Expliquez pourquoi — identifiez la construction spécifique responsable (boucle imbriquée, analyse linéaire dans une boucle, branchement récursif).

3. Proposez une optimisation — nommez la modification et la structure de données ou l'algorithme qu'elle introduit.

4. Énoncez la nouvelle complexité — après le correctif, quelle est la complexité en temps et en espace ?


Exemple :

Code: [fonction qui vérifie l'appartenance dans une liste à l'intérieur d'une boucle]
Actuel : O(N²) — `item in seen_list` est O(N) par vérification × N itérations
Optimisation : remplacer seen_list par seen_set (ensemble de hachage)
Après : O(N) — la vérification d'appartenance d'ensemble est O(1)

Cette compétence s'étend au-delà des entretiens : examen du code tenant compte de la complexité, conception d'architecture, débogage de performance, audits de sécurité. Tout système qui traite des entrées de taille variable en bénéficie.


Cette leçon se connecte en avant au cours unhamming, qui applique ce exact modèle à l'investigation des défauts de production dans 60+ projets open source.

Entretien : analyser has_common_element

Appliquez le format d'entretien en quatre parties à cette fonction :


def has_common_element(list_a, list_b):
    for item in list_a:
        for other in list_b:
            if item == other:
                return True
    return False
Énoncez la complexité actuelle, expliquez pourquoi, proposez une optimisation, énoncez la nouvelle complexité.