Komplexität ist der Feind

Fefe bringt in seinem Beitrag zu Mozillas Vorstoß, in Firefox DNS over HTTPS zu nutzen und dafür ausschließlich über Cloudflare zu gehen, die übergeordnete Problematik auf den Punkt:

Komplexität ist der Feind. Die Anzahl der Bugs steigt mit der Codegröße. Die Leute stöpseln heute nur noch Komponenten aus Libraries zusammen. Das ist Schönwetter-Programmieren! Ein Programm, das nur beherrschbar ist, wenn es zufällig gerade gut funktioniert, ist wertlos. Wir brauchen Programme, die überschaubar wenig Dinge tun, und dafür vollständig beherrschbar sind. Am besten nicht nur vom Programmierer, sondern auch vom Benutzer. Die Geschwindigkeit, mit der wir uns mit unbeherrschten und unbeherrschbaren Technologien umzingeln, ist aus meiner Sicht ein Vorbote der Apokalypse.

Das ist die Anwendung der Maxime Weniger ist mehr auf die Software- und allgemein die Technik-Welt. Im Angelsächsischen ist dafür auch die Bezeichnung KISS principle verbreitet.

Zur Veranschaulichung der Codegröße schaut einfach mal auf How Many Millions of Lines of Code Does It Take?

“Die Geschwindigkeit, mit der wir uns mit unbeherrschten und unbeherrschbaren Technologien umzingeln” hängt dabei vielleicht schlicht mit der patriarchal-kapitalistischen Geisteshaltung zusammen, also dem ganzen Gegenteil obigen Prinzips: “Mehr ist mehr”.

Und ich erinnere in diesem Zusammenhang noch mal daran, dass es eine schlechte Entscheidung der Linux-Community war, nahezu geschlossen zu systemd als Initsystem zu wechseln.

Nachtrag vom 27.08.: Ebenfalls von Fefe verlinkt, ein Artikel über “Ridiculously Complicated Algorithms”.

We don’t want an optimal algorithm. We want one simple enough that an expert can look at it and say nothing crazy is happening here.

Nachtrag vom 24.05.2019: Unbedingt sehenswerter Vortrag zum Thema:

Damals im Informatik-Grundstudium wurde uns gesagt, ein Kern des Informatiker-Denkens sei, wenn ich ein spezifisches Problem zu lösen habe, dann am besten gleich die ganze Problemklasse zu lösen; Abstraktion als Allheilmittel sozusagen. Genau dieses Denken hat uns in den Schlamassel überhaupt erst hineingeführt! Es lässt nämlich eine Sache ausser Acht:

Auf jeder Abstraktionsschicht kann etwas schiefgehen.

Wenn ich also eine zusätzliche Abstraktionsschicht einziehe, dann kann ich damit zwar tatsächlich mehr machen als vorher, es kann aber eben auch mehr schiefgehen als vorher.

Dabei kommt es, wie auch Jonathan Blow in seinem Vortrag betont, auf das gesunde Maß an. Natürlich ist es unter dem Strich sinnvoll, dass wir heutzutage nicht mehr alles in Assembler programmieren. Docker-Container für einzelne Programme schiessen allerdings deutlich über das Ziel hinaus.

Dabei ist zu beachten, dass die möglichen Seiteneffekte zwischen den Abstraktionsschichten kombinatorisch ansteigen, weil diese Schichten eben auch miteinander interagieren (direkt oder indirekt).

Nachtrag vom 29.05.2019: Ein Fragensteller nach dem Vortrag weist auf den Artikel The Humble Programmer aus dem Jahr 1972 (!!!) von Edsger Dijkstra hin, in dem dieser vorschlägt:

I now suggest that we confine ourselves to the design and implementation of intellectually manageable programs.

Er führt dazu aus:

The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.

Na, bei wem kommen da keinerlei Schuldgefühle auf? Ausserdem wünscht er sich auch beherrschbare Programmiersprachen:

Another lesson we should have learned from the recent past is that the development of “richer” or “more powerful” programming languages was a mistake in the sense that these baroque monstrosities, these conglomerations of idiosyncrasies, are really unmanageable, both mechanically and mentally. I see a great future for very systematic and very modest programming languages.

Weiterer Nachtrag vom 29.05.2019: Docker: Lücke erlaubt Root-Zugriff auf Dateien. Merke: Wer dir Virtualisierung als Sicherheitsfeature verkauft, lügt! Qubes OS erfreut sich drum auch nicht gerade flächendeckender Verbreitung…

Nachtrag vom 07.06.2019: Mehr von Fefe, auf der Seite zu seiner dietlibc findet ihr Vortragsfolien zu einem Vortrag Wie man kleine und schnelle Software schreibt. Darin widerspricht er direkt dem, was ich an der Uni über Abstraktion gelernt habe:

Nur generalisieren, wenn es nichts kostet

Und weiter:

Shared Libraries sind die eine Technologie, die am stärksten für den Bloat in der Software-Industrie verantwortlich ist. Denn der Programmierer sieht nicht mehr die tatsächliche Code-Größe.

Nachtrag vom 12.08.2019: Kubernetes-Audit hält System für zu kompliziert:

Interessant an der Auswertung ist vor allem die Einordnung von Kubernetes durch die Prüfer unabhängig von den gefundenen Lücken selbst. So wird Kubernetes als System mit “erheblicher Komplexität” bezeichnet. Ebenso seien die Konfiguration und das Deployment nicht trivial. Das wieder liege an “verwirrenden Standardeinstellungen, fehlenden Steuerungselementen und nur implizit definierten Security-Kontrollelementen”.

Die Kritik geht aber noch weiter: So habe die riesige Codebasis große Teile mit nur “minimaler Dokumentation” sowie zahlreiche externe Abhängigkeiten. Außerdem gebe es viele Stellen, an denen bestimmte Programmlogik einfach reimplementiert wird. Hier wäre es besser, diese in zentrale Helferbibliotheken auszulagern.

Nachtrag vom 13.08.2019: Stack Overflow-Gründer Joel Spolsky sagt im Interview mit c’t:

Wenn ich auf vierzig Jahre als Programmierer (oder so was Ähnliches) zurückschaue, kann ich nur sagen: Produktivität verbessert man am besten, indem man Komplexität verringert. Man beginnt mit einer simplen Sprache, dann findet man eine Bibliothek, mit der man ein paar Zeilen Code einsparen oder ein neues Feature umsetzen kann. Dadurch hat sich aber die Zahl der Dinge, die der Programmierer im Kopf behalten muss, um eins vergrößert – und die Zahl der Interaktionen um N oder N2.

Letztens habe ich versucht, ein GPS-Gerät auszulesen, das einen String zurückgibt. Heute nimmt man für das Parsen eine Library. Ich lud mir eine Bibliothek herunter und fand sie buggy. Schließlich habe ich den Code selbst geschrieben – das Ergebnis passt in ein paar Zeilen, läuft sehr schnell und ich verstehe den Code. Dieser Erkenntnisgewinn macht dich effizient als Programmierer, statt deine Zeit damit zu vergeuden, alle möglichen Bibliotheken verstehen zu müssen und dich um Abhängigkeiten und Updates zu kümmern.

Und weiter:

Aber das ist der Grund, warum Stack Overflow so wichtig geworden ist: Man arbeitet in einem Ökosystem, das man nicht wirklich verstehen kann. Man programmiert auf Grundlage von Code anderer Leute.

Nachtrag vom 14.08.2019: Fefe über HTTP/2:

Ich hab ja vor einer Weile herumgerantet, dass ich HTTP/2 für einen Rückschritt halte. Meine Hauptbeschwerde bei neuen tollen Framework-Standards ist ja die explodierende Komplexität, die zu kaputten Implementationen führen wird. Und tatsächlich ist ein aktueller Feldversuch etwa so vernichtend, wie man sich das denken würde.

Und weiter:

Das Protokoll ist schlicht ein Clusterfuck, und die einzige Implementation, die ich überhaupt erwägen würde, ist eine großflächig lobotomierte.

Nachtrag vom 27.08.2019: Es gibt sogar einen Verein, der sich auf die Fahnen geschrieben hat, software that sucks less zu entwickeln, den suckless.org e.V..

Nachtrag vom 01.01.2020: Schon an anderer Stelle hatte ich Dan Bernstein & seine Software empfohlen (the djb way), nun habe ich Jonathan de Boyne Pollard entdeckt, der sich auch viel mit djb-Software befasst. Zum einen hat er djb-Software in praktische Pakete gepackt, zum anderen auch eine Seite The known problems with Dan Bernstein’s djbdns. Schaut euch auch sonst auf seiner Seite um, die ist sehr lehrreich.

Nachtrag vom 24.01.2020: Diesen Rant von Fefe über kritische Infrastruktur will ich euch nicht vorenthalten.

Das, meine Damen und Herren, ist der Grund, wieso es in der IT keine Satire gibt. Die hat keine Chance gegen die Realität.

Auf der anderen Seite:

Ich weiß ja nicht, wie es euch geht, aber ich mache mir immer weniger Sorgen vor einem 3. Weltkrieg. Die werden ihre Flugzeuge gar nicht hochkriegen im Ernstfall, weil die Gegenseite das so timen wird, dass gerade Active Directory wegen eines Citrix-Patches abgeschaltet ist.

Nachtrag vom 27.01.2020: Fefe vertreibt sich die dunkle Jahreszeit mit Komplexitäts-Galgenhumor.

Nachtrag vom 29.02.2020: Schönes neues Monsterwort: Komplexitätsverstärkertechnologie

Nachtrag vom 29.06.2020: Fefes vorläufiges Fazit des Komplexitäts-Desasters im Softwarebereich.

Nachtrag vom 16.12.2021: Die log4j-Lücke gehört natürlich auch hier hin. Kris Köhntopp hat aus diesem Anlass einen epischen Java-Rant bei Heise geschrieben. Kostprobe daraus:

Das ist so, weil in Java nichts jemals simpel ist. Java Code ist unstrukturierter trockener Staub von Codefragmenten in Klassendateien, die inert in keiner Weise miteinander interagieren. Erst mit den passenden Factories, Delegates, Generators und ClassLoaders werden sie instanziiert und zusammengesetzt. Der entstehende Haufen an Querverweisen führt dann nur zufällig irgendwann einmal tatsächlich wirksamen Code aus.

Und weiter:

Und das ist das eigentliche Problem hier. Viele rufen jetzt nach “Mehr Kontrolle!”, “Mehr Review!”, “Mehr Funding!”, “Mehr Augen auf den Code!”. Was wirklich helfen würde, wäre weniger Code, weniger Indirektion und Boilerplate, und einfach mehr… Einfachheit.

Fefe ergänzt noch etwas:

Oh und lasst mich bei der Gelegenheit einen kleinen Schwank erzählen. Kris macht sich in dem Artikel darüber lustig, dass Java-“Anwendungen” heutzutage immer mit der genauen JRE-Version im Paket ausgeliefert werden, die man braucht, um sie auszuführen. Ich hatte mal bei einem Kunde die Gelegenheit, in eine als “Appliance” ausgelieferte Enterprise-Java-“Anwendung” reinzugucken, und die kam mit drei verschiedenen JREs für verschiedene Teile der “Anwendung”. Es ist da draußen also noch krasser verkackt als Kris es hier ausspricht.

Nachtrag vom 29.03.2022: Gerade habe ich noch einen schönen Rant zum Thema gefunden, Is the madness ever going to end?. Kostprobe:

In the past IT people, whether we’re talking about programmers or something else, were very clever people. People with a high level of intelligence that took serious pride in doing things in a meaningful and pragmatic way.

In the so-called modern day it’s like everyone - except a few - has dropped their brain on the floor. They keep inventing “revolutionary new ways” of doing the same thing that could be done in a dozen ways already. And they do that by coating more and more and more unnecessary complexity on top of existing technology stacks.

Electron and React Native Desktop are supposed to be a revolutionary new way of making desktop applications. Except they are not, and they eat up all the memory you have and still ask for more. They constantly crash and have no value over a native desktop application what so ever - well, perhaps with the only exception that now a 2 year old baby can make something shiny that you can click on with your mouse.

Sein Fazit will ich euch nicht vorenthalten:

Why in the world has this idiotic trend of abstracting everything away by layers upon layers of complexity gained such a strong foothold in the industry? Has everyone except the “unix greybeards” gone mad!?

The situation is really bad for the industry. And it is a real shame that the younger generations who grow up not knowing anything else, thinking that these so-called “modern ways of doing things” are the correct and best ways, will have to suffer when everything starts to crumble (which it already is).

The entry barrier to programming needs to be high! Programming is engineering; it’s not something where you throw stuff at the wall and see what sticks and just assume that programming languages, browsers, and operating systems are made of magical dust.

Nachtrag vom 10.08.2022: Dieser Vortrag von May Contain Hackers liefert einen neuen Datenpunkt zum Thema – 5G-Netzwerke sind offensichtlich eine Komplexitäts-Hölle:

To make building blocks interoperable, OpenRAN comes with new interfaces, with often unclear security properties. OpenRAN also adds complex IT technologies, which come with their own hacking issues. Many components are run on Linux in Docker containers on top of Kubernetes, adding multiple layers of possible hacking interference.

Nachtrag vom 25.03.2023: Anlässlich des kürzlichen Reddit-Ausfalls hat Fefe einen epischen Rant darüber verfasst. Kleine Kostprobe:

Da fehlte die institutionelle Erfahrung. Die hatten lauter Leute, die wussten, wie sie in ihrem Admin-Interface Dinge klickt. Aber was man tut, wenn das Admin-Interface nicht geht, weil das Netz dazwischen braun ist, das wusste keiner mehr, und inzwischen war die Komplexität so krass gewachsen, dass das wahrscheinlich generell niemand mehr von Hand gucken konnte. Sie haben da tolle selbstreparierende Prozesse gehabt, aber das lief halt wie bei Asimov. Wenn du selbstwartende Dinge baust, geht das Wissen verloren, wie man sie baut und wartet, weil das ja nicht mehr gebraucht wird, und wenn die dann irgendwann doch kaputt gehen, hast du dann halt komplett verloren. So war das auch hier. Sie haben den Pod mit dem Netzwerkmanagement-Kram gekillt und gelöscht und der versuchte sich dann neu zu installieren, aber die Installation hatte halt dasselbe Problem wie die davor.

Nachtrag vom 02.03.2024: Im Artikel The ever-growing problem of ever-growing codebases von Liam Proven wurde ich auf einen kurzen Text von Niklaus Wirth (Gott hab ihn selig!) aufmerksam, der die Sache auf den Punkt bringt: A Plea For Lean Software. Hier noch ein Zitat aus dem Artikel von Liam Proven:

Nobody can read the source code of Chrome. Not alone, not as a team. Humans don’t live long enough. Any group that claims to have gone through the code and de-Googlized it is lying: all that’s possible to do is some searches, and try to measure what traffic it emits. A thousand people working for a decade couldn’t read the entire thing.

This is the sort of size of codebase that we are building the internet from these days.

These projects are so incomprehensibly vast that no human mind can comprehend even one small isolated subset of the entire thing.

Nachtrag vom 03.03.2024: Heute habe ich mir den Artikel von Niklaus Wirth ganz durchgelesen & einen Satz darin angestrichen, der zeigt, wie weit wir auf dem Weg in die Hölle schon gekommen sind:

A system that is not understood in its entirety, or at least to a significant degree of detail by a single individual, should probably not be built.