Partielles Verständnis ist kein Fehler: Warum du deine Codebase nicht komplett verstehen musst
Inhaltsverzeichnis
Vollständiges Codeverständnis gilt als Ideal. In Systemen mit Millionen Zeilen Code ist das eine Fantasie. Wer darauf wartet, alles zu verstehen, bevor er handelt, handelt nie.
Key Takeaways (TL;DR)
- Prüfe die Systemgröße, bevor du vollständiges Verständnis forderst: Was für kleine Codebases gilt, versagt bei Systemen, die um Größenordnungen größer sind.
- Behandle Rewrites als Serie von Änderungen, nicht als Neustart: Wer das bestehende System nicht ändern kann, kann es auch nicht ersetzen.
- Erschließe verlassene Codebases entlang eines Flows: Verstehe einen Pfad End-to-End und expandiere von dort nach außen.
- Akzeptiere unvollständige Theorie als Arbeitsbedingung: In großen Systemen operiert jeder mit einer inkorrekten Theorie. Die Fähigkeit, trotzdem fundierte Entscheidungen zu treffen, ist die zentrale Kompetenz.
- Behandle Codeverständnis als Trade-off, nicht als Moralfrage: Theory Building ist ein Wert unter vielen, manchmal der wichtigste, manchmal nicht.
Basiert auf „In defense of not understanding your codebase” von Sean Goedecke. Das Original findest du hier: seangoedecke.com
Zwei Programmierkulturen, die aneinander vorbeireden
Goedecke beobachtet eine Spaltung, die selten explizit benannt wird. Wer an Redis oder an einem Indie-Game wie The Witness arbeitet, sagt: Selbstverständlich muss man die eigene Codebase komplett verstehen. Alles andere ist unsauber. Wer am Google-Search-Backend oder an GitHub arbeitet, sagt: Das ist physisch unmöglich. Man macht das Beste aus dem eigenen lokalen Verständnis.
Beide Gruppen haben valide Methoden und Praktiken. Das Problem ist die Dominanz der ersten Gruppe in der öffentlichen Diskussion. Open-Source-Entwickler bloggen häufiger, ihre Arbeit ist technisch beeindruckender (weil Koordinationsprobleme in großen proprietären Systemen die eigentliche Herausforderung sind), und über interne Systeme lässt sich aus rechtlichen Gründen nichts schreiben. Selbst wenn man es dürfte: Das Erklären großer Systeme erfordert so viel spezifischen Kontext, dass kein Blogbeitrag das transportieren kann.
Das Ergebnis ist eine verzerrte Wahrnehmung. Die Kultur des vollständigen Verständnisses dominiert die Diskussion, obwohl die Mehrheit der professionellen Softwareentwicklung in der Kultur des partiellen Verständnisses stattfindet.
Naurs „Programming as Theory Building” und seine Grenzen
Peter Naurs Paper von 1985 ist die stärkste Formulierung der Position „vollständiges Verständnis ist essenziell”. Der Kernpunkt: Wenn Programmierer an einem Programm arbeiten, ist der Code nur ein Nebenprodukt. Das eigentliche Produkt ist ihre „Theorie des Programms”, also das intuitive Verständnis davon, was passiert und warum. Code und Dokumentation können diese Theorie nur teilweise erfassen.
Soweit ist das schlüssig. Wenn ein Team 100 Prozent Fluktuation erlebt, wird das neue Team tatsächlich Schwierigkeiten haben, den Code zu verstehen. Aber Naur geht einen Schritt weiter, der in der Praxis nicht hält. Er empfiehlt, den bestehenden Code komplett zu verwerfen und das Problem von Grund auf neu zu lösen:
„Die Rekonstruktion der Theorie eines Programms allein aus der Dokumentation ist strikt unmöglich. Daher sollte der vorhandene Programmcode verworfen und dem neu gebildeten Programmierteam die Möglichkeit gegeben werden, das Problem von Grund auf neu zu lösen.”
Goedecke widerspricht dem aus zwei konkreten Gründen.
Warum große Systeme nicht neu geschrieben werden können
Ausreichend große Systeme mit echten Nutzern enthalten tausende Sonderfälle und Eigenheiten, die sich nicht replizieren lassen. Selbst ein Team, das das System vollständig kennt, könnte es nicht von Grund auf nachbauen. Es gibt schlicht zu viele Details gleichzeitig im Kopf zu halten.
Erfolgreiche Rewrites funktionieren anders. Sie beginnen damit, die bestehende Codebase in kleine, isolierte Teile zu zerlegen und dann jeweils einen Teil neu zu schreiben. Ein Rewrite ist also eine Serie von Änderungen am alten System. Wer das alte System nicht ändern kann, kann es erst recht nicht ersetzen.
Verlassene Systeme werden regelmäßig wiederbelebt
Naur schreibt, dass die Notwendigkeit, ein „völlig totes” Programm wiederzubeleben, selten auftreten wird. In Unternehmen mit hunderten Millionen Zeilen Code und tausenden Entwicklern passiert genau das ständig. Es braucht nur ein paar Kündigungen zum falschen Zeitpunkt oder ein Jahr ohne Wartung, und niemand versteht den Code mehr.
Goedecke beschreibt aus eigener Erfahrung, wie er verlassene Codebases übernommen, sich eingearbeitet und produktiv damit gearbeitet hat. Die Methode ist immer dieselbe: Einen einzelnen Flow End-to-End verstehen, dann schrittweise von dort nach außen arbeiten und dabei vorsichtige Änderungen vornehmen. Das dauert, aber es funktioniert. Naurs These, dass die Rekonstruktion einer Theorie aus dem Code unmöglich sei, widerspricht der täglichen Praxis.
Jeder operiert mit einer falschen Theorie
In ausreichend großen Codebases hat jeder eine inkorrekte Theorie des Programms. Niemand versteht alles. Kein einzelner Entwickler und kein ganzes Team. Das definierende Merkmal moderner Softwaresysteme ist, dass sie zu groß sind, um komplett im Kopf gehalten zu werden.
Effektiv arbeiten bedeutet deshalb, mit einer nur teilweise korrekten Theorie zu arbeiten. Wer sich unsicher ist, kann nicht zurücklehnen und auf jemanden mit perfektem Verständnis warten. Wenn du ein kompetenter Engineer bist, bist du diese Person. Die Fähigkeit, auf Basis einer fundierten Einschätzung zu handeln und die Konsequenzen zu tragen, ist die zentrale Kompetenz in großen Systemen.
Das ist auch der Zusammenhang zur Cognitive Debt, die wir in einem früheren Beitrag analysiert haben. Teams produzieren mehr Code, als sie verstehen können. Die Lücke zwischen Output und Verständnis wächst. In Naurs Terminologie: Die Theorie des Programms erodiert, während das Programm selbst wächst.
Der historische Kontext: 1985 vs. heute
Naurs Empfehlung war für 1985 plausibel. Die durchschnittliche Programmgröße war um mehrere Größenordnungen kleiner als heute. Naurs Beispiele für „große Programme” sind ein industrielles Überwachungssystem mit 200.000 Zeilen und ein Compiler. 1987 hatte GCC etwa hunderttausend Zeilen Code. 2015 waren es über vierzehn Millionen.
Ein Rewrite von ein oder zwei hunderttausend Zeilen ist machbar, besonders mit bestehenden Tests. Ein Rewrite von ein oder zwei Millionen Zeilen ist es nicht. Naurs Empfehlung war für seine Zeit möglicherweise sinnvoll. Für die Realität heutiger Softwaresysteme ist sie es nicht mehr.
Theory Building als Trade-off
LLMs werden oft als schädlich für den Aufbau einer mentalen Theorie des Codes kritisiert. LLMs machen es schwieriger, eine detaillierte mentale Theorie aufzubauen. Gleichzeitig ermöglichen sie, eine partielle Theorie schnell zu konstruieren und effektiver zu nutzen. Ob der Nettoeffekt positiv oder negativ ist, bleibt eine offene Frage.
Unabhängig von LLMs ist die Behauptung, alles, was das Codeverständnis stört, sei schlecht, offensichtlich zu einfach. Weitere Faktoren erschweren das Aufrechterhalten einer Theorie:
- Andere Menschen dürfen Code in deiner Codebase schreiben
- Gesetzlich vorgeschriebene Features wie Barrierefreiheit und Datenschutz müssen umgesetzt werden
- Kollegen dürfen kündigen oder das Team wechseln
- Sicherheitsupdates für Abhängigkeiten müssen eingespielt werden
- Externe Libraries und Dependencies werden eingebunden
Jeder dieser Faktoren macht es schwerer, die Theorie der Codebase aufrechtzuerhalten. Trotzdem würde niemand ernsthaft fordern, sie zu eliminieren. Das Aufrechterhalten einer Theorie ist ein Wert unter vielen. Manchmal ist es der wichtigste. Manchmal wird er gegen Geschwindigkeit, regulatorische Anforderungen oder organisatorische Realitäten eingetauscht.
Die Präferenz für „reines” Engineering
Fast alle Engineers bevorzugen es, ein akkurates mentales Modell ihrer Software zu haben. Es macht mehr Spaß, ist weniger stressig und fühlt sich an wie „echtes Engineering”. Deshalb arbeiten viele Engineers in ihrer Freizeit an Open-Source-Projekten: um an kleinen Codebases allein zu arbeiten, wo eine vollständige Naur-Theorie möglich ist.
Daran ist nichts falsch. Aber im Job wirst du dafür bezahlt, eine Aufgabe zu erfüllen. Du übernimmst die Engineering-Werte deines Arbeitgebers. Wie sehr du persönlich auch Wert auf Performance legen magst, manchmal musst du langsamen Code schreiben, um einen Termin zu halten oder eine unbequeme Anforderung umzusetzen. Das Aufrechterhalten einer Theorie der Codebase ist derselbe Trade-off.
Das knüpft direkt an die Beobachtung an, die wir bei der Analyse von KI und den schweren Teilen des Software Engineerings gemacht haben. KI eliminiert die Routinearbeit. Was übrig bleibt, ist Entscheidungen unter Unsicherheit zu treffen. Partielles Verständnis ist keine Schwäche. Es ist die Arbeitsbedingung.
Checkliste: Effektiv arbeiten mit partiellem Verständnis
- Einen Flow End-to-End verstehen, bevor du expandierst. Versuche nicht, ein ganzes System auf einmal zu erfassen. Wähle einen konkreten Pfad durch das System, verstehe ihn vollständig und arbeite von dort nach außen.
- Änderungen als Lernmethode nutzen. Kleine, gezielte Änderungen am Code sind der schnellste Weg, eine Theorie aufzubauen. Lesen allein reicht nicht. Verändern und beobachten, was passiert, erzeugt tieferes Verständnis.
- Entscheidungen treffen, nicht aufschieben. In großen Systemen wartet niemand mit perfektem Verständnis. Triff eine fundierte Einschätzung, dokumentiere die Annahmen (z.B. in einem ADR) und handle. Korrigiere, wenn nötig.
- Lokales Reasoning vor globalem Verständnis. Investiere in Architekturmuster, die lokales Reasoning ermöglichen: klare Interfaces, geringe Kopplung, explizite Abhängigkeiten. Wer lokal korrekt arbeiten kann, braucht kein globales Verständnis.
- Theory Building als bewussten Trade-off behandeln. Codeverständnis ist ein Wert unter vielen. Manchmal ist es der wichtigste. Manchmal nicht. Die Entscheidung, welcher Wert gerade Vorrang hat, ist eine Engineering-Entscheidung, keine moralische.
Große Systeme belohnen nicht, wer alles versteht, sondern wer mit unvollständigem Verständnis entscheidet.
Häufig gestellte Fragen (FAQ)
Was ist 'Programming as Theory Building' von Peter Naur? ↓
Peter Naurs Paper von 1985 argumentiert, dass beim Programmieren nicht der Code das eigentliche Produkt ist, sondern die mentale Theorie des Programms. Diese Theorie umfasst das intuitive Verständnis darüber, was der Code tut und warum. Geht dieses Verständnis verloren, etwa durch Teamwechsel, lässt sich der Code laut Naur nur noch schwer sinnvoll ändern.
Warum funktioniert Naurs Empfehlung, Code komplett neu zu schreiben, in der Praxis nicht? ↓
Große Systeme mit Millionen Zeilen Code enthalten tausende Sonderfälle und Geschäftslogik, die nicht replizierbar sind. Erfolgreiche Rewrites beginnen immer mit der Isolierung einzelner Komponenten und deren schrittweiser Neuentwicklung. Ein kompletter Neustart ist bei ausreichender Systemgröße technisch und organisatorisch unmöglich.
Wie arbeitet man effektiv mit einer Codebase, die man nicht vollständig versteht? ↓
Einen einzelnen Flow End-to-End verstehen, von dort schrittweise nach außen arbeiten und dabei gezielte Änderungen vornehmen. Das erfordert die Bereitschaft, auf Basis einer fundierten Einschätzung zu handeln, auch wenn das vollständige Bild fehlt. In großen Systemen operiert jeder mit einer unvollständigen Theorie des Programms.
Senior Full-Stack Developer mit Fokus auf stabiler Software-Architektur, pragmatischem Engineering und der Realität von KI im Entwickler-Alltag. Seine Wurzeln liegen im praktischen Lösen komplexer Probleme unter realen Bedingungen.
github.com/hyretic-devÄhnliche Artikel
Cognitive Debt ist die neue technische Schuld: Was CTOs beim CTO Craft Dinner wirklich diskutieren
Beim CTO Craft Dinner in Toronto diskutierten Engineering-Leader über die Realität der KI-Adoption. Das Ergebnis: Die Phase des freien Experimentierens ist vorbei. Was bleibt, sind unkontrollierte Kosten, fehlende Karrierepfade und eine neue Art von Schulden, die niemand misst.
Fundamente statt Tools. Warum dein Klavierunterricht wichtiger ist als das neueste KI-Tool.
CS-Professor Tom Yeh lehrt KI per Hand auf Papier. Seine These: Wer zeitlose Fundamente besitzt, übersteht jeden Technologiewechsel. Wer nur Tools lernt, muss jedes Mal von vorne anfangen.
KI hat Software Engineering nicht einfacher gemacht. Sie hat die schweren Teile schwerer gemacht.
KI-Tools eliminieren die Routinearbeit. Was übrig bleibt, ist der anspruchsvollste Teil des Jobs. Und der menschliche Kopf hat kein Upgrade bekommen.
Vibe-Coding ohne Architektur: Warum 1.690 Zeilen Code im Müll gelandet sind
Ein Entwickler hat sieben Monate lang ein Kubernetes-Tool rein mit KI gebaut. Das Ergebnis ist ein Lehrstück über die Grenzen von Vibe-Coding ohne menschliche Architekturkontrolle.