un

guest
1 / ?
back to lessons

Namen sind nicht finden

Sie kennen jetzt sieben MOAD-Muster. Wissen um Namen ist wichtig: es ermöglicht Ihnen, ein Muster zu erkennen, wenn Sie es sehen. Aber die Erkennung in einer kontrollierten Lektion unterscheidet sich von der Detektion in einem Codebase, den Sie noch nie geöffnet haben.

Ein Codebase kennzeichnet seine Defekte nicht. Ein sedimentärer MOAD kommt nicht mit einer Kommentarzeile, die sagt: // O(N²) — beheben Sie das. Eine Sturzflut von Herden gibt sich nicht als Cache-Miss-Stampelei bekannt. Sie finden sie, indem Sie Code mit einer bestimmten Frage im Sinn lesen: welche Datenstruktur hält diese Werte und welche Operationen werden gegen sie innerhalb einer Schleife durchgeführt?

Detektion ist eine eigene Fähigkeit, die von der Erkennung getrennt ist. Erkennung sagt: Ja, das Muster ist MOAD-0001. Detektion sagt: Lass mich alle Orte in diesem Codebase finden, an denen dieses Muster existieren könnte, ob ich den vollständigen Code sehen kann oder nur einen Symbolnamen.

Sieben MOADs: Substrate, Signaturen, Behebungen

Erster Scan

Ein erster Durchgang verwendet grep. Jede MOAD hat ein Substrat: eine Datenstruktur oder ein API, deren Anwesenheit in der Nähe bestimmter Operationen ein Signal wert ist, das untersucht werden sollte.

MOAD-0001 (Sedimentär): .contains() auf einer Liste innerhalb einer Schleife

# Signal: Mitgliedschaftstest auf einer Listevariable innerhalb einer Schleife
grep -rn '.contains(' src/ | grep -v HashSet | grep -v TreeSet
grep -rn 'visited =' src/ | grep -v set | grep -v Set

MOAD-0002 (Verflochten): gemeinsam verwendete mutable Flagge über Phasen hinweg

# Signal: statische mutable Feldvariable, geschrieben von einem Subsystem, gelesen von einem anderen
grep -rn 'static ' src/ | grep -v final | grep -v class | grep -v void

MOAD-0003 (Entwichenels Kontext): ThreadLocal in einem gepoolten Executor

# Signal: ThreadLocal.set() ohne garantierte ThreadLocal.remove()
grep -rn 'ThreadLocal' src/
grep -rn 'ThreadLocal.set' src/ -l

MOAD-0004 (Geloggtes Geheimnis): HTTP-Kopfzeilen in der Ausgabe von Logs

# Signal: log call with headers variable near auth endpoints
grep -rn 'log.*header' src/
grep -rn 'Authorization' src/ --include='*.log'

MOAD-0005 (Thundering Herd): Cache-Miss mit keiner Synchronisation

# Signal: cache.get() + null-Prüfung + cache.put() ohne Schaltfläche
grep -rn 'cache.get' src/ -A4 | grep 'cache.put'

Diese Muster erzeugen Kandidaten, nicht bestätigte Defekte. Jeder Kandidat benötigt eine Triage: Lesen Sie den umliegenden Code, bestätigen Sie den Datentyp der Datenstruktur, bestätigen Sie die Ausführung der Operation auf großem Skala.

Wählen Sie eine MOAD von MOAD-0001 bis MOAD-0005 aus. Beschreiben Sie einen konkreten Detektionsschritt in einem Codebase, den Sie noch nie gelesen haben: was Sie suchen, wie ein positives Ergebnis aussieht und was einen bestätigten Defekt von einem falschen positiv unterscheidet.

Codelesung für Komplexität

Grep findet Kandidaten. Die Lesung bestätigt sie. Wenn Sie ein Kandidaten-File öffnen, lesen Sie mit einer Frage: Wächst der Kostenbetrag dieser Operation mit der Eingabegröße?

Für MOAD-0001, das Bestätigungsprotokoll:

1. Finden Sie die äußere Schleife. Was begrenzt ihre Iterationsanzahl?
2. Finden Sie die innere Operation (.contains, .indexOf, 'in'). Gegen welche Datenstruktur wird sie ausgeführt?
3. Wächst diese Datenstruktur mit derselben Eingabe, die die äußere Schleife antreibt?
4. Wenn ja: Die Kosten sind O(N²), wobei N die Eingabegröße ist. Bestätigter Defekt.
5. Wenn nein: Die innere Struktur ist begrenzt (Konfiguration, Enum, kleine Konstante). Falsch-Positiv.

Eine Graphenverarbeitung, bei der N Knoten besucht werden und bei jeder Schritt eine 'visited'-Liste geprüft wird: Beide, die Schleife und die innere Datenstruktur, wachsen mit N. Bestätigt.

Eine Anforderungsverarbeitung, bei der eine Liste von 5 Admin-IPs geprüft wird: Die Allowlist wächst nie mit der Anforderungsvolumen. Falsch-Positiv.

Das gleiche Protokoll gilt für jedes MOAD: Identifizieren Sie den äußeren Treiber, identifizieren Sie die innere Struktur und fragen Sie, ob beide zusammen wachsen.

Surge Score: Priorisierung Ihrer Ergebnisse

Nicht alle bestätigten Fehler erfordern sofortige Behebung. Ein MOAD in einer Bibliothek mit 10.000 downstream-Abhängigen hat einen höheren Surge-Score als das gleiche MOAD in einem privaten internen Tool.

Surge-Score = Geschwindigkeitsmultiplikator × Eintragsgrad. Geschwindigkeitsmultiplikator: Wie viel schneller läuft die Reparatur im typischen Produktionsmaßstab? Eintragsgrad: Wie viele downstream-Pakete oder -Dienste erben die Reparatur automatisch, wenn der upstream es integriert?

Ein bestätigtes MOAD-0001 in Apaches Abhängigkeitslöser, der auf Graphen mit 50.000 Knoten läuft, mit mehr als 1.000 downstream-Maven-Plugins, die Änderungen automatisch erben: Surge-Score ist sehr hoch. Dieser Fix gehört an der Spitze Ihrer Warteschlange.

Ein bestätigtes MOAD-0001 in einer Single-User-Cli-Zeit mit keinen Abhängigen: Surge-Score nahe Null. Wertvoll, aber nicht dringend.

Arbeitssüchtige vs. Fresslustige Knoten. Ein Knoten mit hohem Betweenness & hohem Geschwindigkeitsmultiplikator ist ein Arbeitssüchtiger: Er handhabt kritische Flüsse und leert die downstream-Warteschlagen, wenn er entblockt wird. Blockieren Sie ihn nur, nachdem Sie die downstream-Kapazität bestätigt haben. Ein Knoten mit hohem Ausgangsgrad & niedrigem Geschwindigkeitsmultiplikator ist ein Fresslustiger: Er verbraucht alles, was ihm zugeführt wird, und fühlt sich nicht schmerzhaft. Das Patchen eines Arbeitssüchtigen ohne staging downstream-Kapazität erzeugt MOAD-0005 (Donnerstoß) auf Infrastrukturerdgross.

Factory DAG: Arbeitssüchtige & Fresslustige Knotenmuster

Sie haben MOAD-0001 in zwei Orten bestätigt: (A) ein Abhängigkeitslöser in einem Build-Tool mit 200.000 aktiven Projekten, die darauf angewiesen sind, und der auf Graphen mit 10.000-Node-Abhängigkeitsbaum laufft; (B) ein Graph-Utility in einem internen Datenpipeline bei einem einzelnen Unternehmen, der auf Graphen mit 50 Knoten läuft. Vergleichen Sie ihre Surge-Scores. Welches patchen Sie zuerst und welche Schritte Sie vor der Offenlegung unternehmen?

Scann zum Zusammenführen: Ein MOAD-Pipeline

Ein bestätigtes Defekt mit einem hohen Surge-Score durchläuft einen Pipeline. Jeder Schritt erzeugt ein Artefakt. Kein Schritt ist optional.

scann    → Kandidatenliste (grep-Ausgabe, statische Analyseergebnisse)
ticket  → Defektbeschreibung (MOAD-Nummer, Ort, Komplexitätsanalyse)
patch   → Codeänderung (Datenstruktausausch, primitive Adoption)
test    → Einheitstest (O(1)-Nachweis: Zeiten die Korrektur bei N=100 und N=10,000)
UNDF    → öffentliche Bekanntgabe (undefect.com, öffentlicher Bereich)
diskret → CVE- oder CWE-Bezug, wenn sicherheitsrelevant
PR      → upstream-Pull-Anfrage mit Patch + Test + UNDF-Link
zusammenführen → Annahme des Maintainers; die Korrektur verbreitet sich über eine Versionsveränderung

Jedes Artefakt speist den nächsten Schritt. Ein Patch ohne Test kann nicht verifiziert werden. Ein Test ohne Bekanntgabe kann nicht auf andere Instanzen des gleichen Musters weitergeleitet werden. Eine Bekanntgabe ohne upstream-PR führt die Korrektur in einem Fork ein.

Eine MOAD-Post (UNDF) ist der Schritt, den die meisten Ingenieure weglassen. Sie beheben den Defekt, stellen eine PR und consider themselves done. Aber eine Korrektur ohne benannte Post bedeutet, dass jeder zukünftige Ingenieur, der denselben Muster trifft, die Problematik und die Lösung unabhängig neu entdecken muss. Eine MOAD-Post schließt den Wissenskreislauf: sie benennt den Muster, zeigt die Erkennungsmethode und verlinkt auf den Patch. Zukünftige Forscher finden die Korrektur, indem sie nach dem Mustername suchen.

Planeten-Patching auf Massenebene. Eine einzelne MOAD-0001-Korrektur in einer weit verbreiteten Bibliothek wird auf jede Projekt, die sie importiert, weitergegeben. Eine MOAD-Post stellt sicher, dass Ingenieure in Projekten, die diese Bibliothek niemals aktualisieren, die Korrektur lernen. Beide Wege laufen parallel.

Ein Defekt-Ticket verfassen

Ein gutes Defekt-Ticket beantwortet fünf Fragen:

1. Wo: genaue Datei, Klasse, Funktion und Zeilenbereich
2. Was: der Datentyp und die Operation gegen ihn
3. Warum: die Komplexitätsanalyse (O(N²) oder schlimmer, mit N definiert)
4. Auswirkung: welche Eingaben das Schlechterwachsen auslösen und auf welcher Skala
5. Korrektur: die zu substituierende Datenstruktur oder primitive

Ein Ticket, das alle fünf Fragen beantwortet, ist selbstständig: ein Maintainer, der deine Analyse nie gelesen hat, kann deine Entdeckung reproduzieren und deine Korrektur verifizieren. Tickets, die (3) oder (4) weglassen, erfordern, dass der Maintainer deine Komplexitätsanalyse erneut durchführt, bevor sie einreichen können. Diese Reibung reduziert die Wahrscheinlichkeit der Zusammenführung.

Glaubwürdigkeit addiert sich. Ein erster PR, der einen klaren Ticket enthält, einen gut gezielten Patch und ein Benchmark-Test einschließt, wird integriert. Ein zweiter PR von demselben Autor wird mit weniger Widerstand überprüft. Ein dritter PR wird von dem Maintainer, der die ersten beiden integriert hat, überprüft. Reputation in Open Source ist ein Konto von Artefakten: Jeder akzeptierte Patch verdient Vertrauen für den nächsten.

Verfasse ein minimales Defekt-Ticket für ein MOAD-0001, das du in einer Graph-Bibliothek erwarten würdest. Enthält: (1) ein plausibles Datei/Funktionsname, (2) die Datenstruktur und den Betriebsmodus, (3) eine Komplexitätsaussage, (4) ein typisches Auswirkungs-Szenario, (5) die Korrektur.

Ein echter Kandidat lesen

Hier ist ein echter MOAD-0001 Kandidat in Python. Lies es und führe den Triage-Protokoll durch.

class DependencyResolver:
    def resolve(self, package, resolved=None, seen=None):
        if resolved is None:
            resolved = []
        if seen is None:
            seen = []
        if package in seen:
            return
        seen.append(package)
        for dep in self.registry.get_dependencies(package):
            self.resolve(dep, resolved, seen)
        resolved.append(package)
        return resolved

Triage Fragen:

1. Welche Datenstruktur ist `seen`?
2. Welche Operation wird auf Zeile 6 durchgeführt?
3. Wächst `seen` mit der Eingabegröße?
4. Wächst die Schleife, die die rekursiven Aufrufe antreibt, auch mit der Eingabegröße?
5. Ist dies ein bestätigter MOAD-0001 oder ein Fehlalarm?
Geh durch die fünf Triage Fragen für diesen Code. Schreibe dann die einenzeiligen Lösung und erkläre, warum sie das Ergebnis der Funktion nicht ändert.

Ihr Patch

Ein bestätigter Fehler mit einem hohen Surge-Score benötigt einen vollständigen Patch: den Code-Fix, einen Test, der das Verbesserung beweist, und ein MOAD-Post-Urteil.

Der Test muss ein Leistungstest sein, kein Korrektheitstest. Ein Korrektheitstest funktioniert vor und nach dem Fix - das ist der Punkt; die Ausgabe ändert sich nicht. Ein Leistungstest bei zwei Eingabegrößen beweist die Verbesserung:

import time

def build_graph(n):
    # n Pakete, jedes abhängig vom vorherigen
    return {f'pkg{i}': [f'pkg{i-1}'] if i > 0 else [] for i in range(n)}

for n in [100, 1000, 5000]:
    registry = build_graph(n)
    resolver = DependencyResolver(registry)
    start = time.perf_counter()
    resolver.resolve(f'pkg{n-1}')
    elapsed = time.perf_counter() - start
    print(f'n={n}: {elapsed:.4f}s')

Bevor der Fix, die Verzögerungszeit wächst quadratisch mit n. Nach dem Fix, wächst sie linear. Drucken Sie beide und fügen Sie die Zahlen in Ihre PR-Beschreibung ein.

Ein MOAD-Post-Urplan umfasst: den Namens der Muster, das Substrat (Python-Abhängigkeitslöser), die Erkennungsmethode (grep für in seen, wobei seen als [] beginnt), die Korrekturmaßnahme und einen Link zu deinem PR. Der Post geht an undefect.com als öffentliches Eigentum. Zukünftige Ingenieure, die nach 'Python Liste-Zugehörigkeit in Schleife langsam' suchen, werden es finden.

Sie haben MOAD-0001 in einer beliebten Python-Paketerstellungstool bestätigt und gepatcht. Bevor Sie das PR öffnen, was sind die drei Dinge, die Sie in der PR-Beschreibung aufnehmen und warum ist jedes für den Maintainer wichtig?