Mit Einfachheit wird man nicht befördert
(terriblesoftware.org)- In der Software-Engineering-Kultur hält sich eine Struktur, in der Menschen, die komplexe Systeme bauen, mehr Anerkennung bekommen, während diejenigen, die einfache Lösungen wählen, kaum gewürdigt werden
- Bei Beförderungsbewertungen, Interviews und Design-Reviews wird Komplexität oft mit „Impact“ verwechselt, was die Tendenz verstärkt, unnötige Abstraktionen und Erweiterbarkeit hinzuzufügen
- Eine einfache Implementierung bleibt als „unsichtbare Leistung“ zurück, während sich komplexe Strukturen mit glänzenden Beschreibungen und Dokumentation leichter in Beförderungsunterlagen darstellen lassen
- Wahre Kompetenz zeigt sich nicht darin, mehr Tools einzusetzen, sondern in Urteilsvermögen und Selbstvertrauen, zu wissen, wann Komplexität ausgeschlossen werden sollte
- Sowohl Engineers als auch Führungskräfte müssen Einfachheit sichtbar machen und Bewertungs- und Belohnungssysteme schaffen, die sie offiziell anerkennen
Einfachheit vs. Komplexität: die Asymmetrie der Beförderungsnarrative
- Beispiel von zwei Engineers im selben Team: Engineer A liefert ein Feature in wenigen Tagen mit 50 Zeilen prägnantem Code aus, Engineer B führt eine neue Abstraktionsschicht, ein pub/sub-System und ein Konfigurations-Framework ein und ist nach 3 Wochen fertig
- Die Arbeit von Engineer B lässt sich in einem Beförderungspaket als „Entwurf einer skalierbaren ereignisgesteuerten Architektur, Einführung einer wiederverwendbaren Abstraktionsschicht, Aufbau eines Konfigurations-Frameworks“ beschreiben
- Die Arbeit von Engineer A lässt sich dagegen nur mit drei Worten beschreiben: „Feature X implementiert“
- Tatsächlich war es die bessere Arbeit, aber gerade weil sie schlicht wirkte, wurde sie zu einem unsichtbaren Beitrag
- Für „vermiedene Komplexität“ wird niemand befördert — Komplexität wirkt deshalb klug, weil Bewertungssysteme so aufgebaut sind, dass sie sie belohnen
Wie Komplexität in Interviews und Design-Reviews verstärkt wird
- Wenn man in einem System-Design-Interview eine einfache Lösung vorschlägt (eine einzelne Datenbank, eine intuitive API, eine Caching-Schicht), drängt der Interviewer mit „Was, wenn 10 Millionen Nutzer kommen?“
- Je mehr Services, Queues und Sharding man hinzufügt, desto eher hat man die Erfahrung, dass der Interviewer zufriedener wirkt
- Die Lektion, die Kandidaten daraus lernen: „Die einfache Antwort hat nicht gereicht“
- Dass Interviewer Druck machen, kann nachvollziehbare Gründe haben (Denken unter Druck, Prüfung des Verständnisses verteilter Systeme), aber die Botschaft, die bei Kandidaten ankommt, lautet: „Komplexität beeindruckt“
- Auch in Design-Reviews wiederholt sich das Muster, dass auf die Frage „Sollten wir das nicht future-proof machen?“ hin unnötige Schichten und Abstraktionen ergänzt werden
- Nicht weil das Problem es erfordert, sondern weil der Besprechungsraum es erwartet
- Es gibt viele Fälle, in denen eine Abstraktion, die nur ein paar Zeilen doppelten Code vermeiden sollte, das Verständnis und die Wartung am Ende erschwert
- Der Code wirkte zwar „professioneller“, aber die Nutzer bekamen das Feature nicht schneller, und der nächste Engineer verbrachte vor einer Änderung einen halben Tag damit, die Abstraktion zu verstehen
Angemessene Komplexität vs. unnötige Komplexität (Unearned Complexity)
- Komplexität an sich ist nicht das Problem — für die Verarbeitung von Millionen Transaktionen braucht es verteilte Systeme, und wenn 10 Teams am selben Produkt arbeiten, braucht es Service-Grenzen
- Das Problem ist unnötige Komplexität: der Unterschied zwischen „Wir brauchen Sharding, weil wir an die Grenzen der Datenbank gestoßen sind“ und „Wir könnten in 3 Jahren an diese Grenze stoßen, also machen wir jetzt schon Sharding“
- Der Code und die Architektur von Engineers, die das verstanden haben, fühlen sich an wie „na klar“ — ohne Magie, ohne demonstrative Cleverness und ohne das Gefühl, dumm zu sein, weil man es nicht versteht
- Der eigentliche Weg zum Senior-Level besteht nicht darin, mehr Tools und Muster zu lernen, sondern zu wissen, wann man sie nicht einsetzt — Komplexität hinzufügen kann jeder, aber sie wegzulassen erfordert Erfahrung und Selbstvertrauen
Konkrete Ansätze für Engineers
- Einfachheit muss sichtbar gemacht werden — die Arbeit spricht nicht für sich selbst, weil Bewertungssysteme nicht darauf ausgelegt sind, sie zu hören
- Statt „Feature X implementiert“ lieber „Drei Ansätze evaluiert, darunter eine ereignisgesteuerte Architektur und eine benutzerdefinierte Abstraktionsschicht; entschieden, dass eine einfache Implementierung die aktuellen und erwarteten Anforderungen erfüllt; in 2 Tagen ausgerollt und 6 Monate störungsfrei betrieben“
- Sich bewusst dagegen zu entscheiden, etwas zu bauen, ist ebenfalls eine Entscheidung — und eine wichtige; entsprechend sollte sie dokumentiert werden
- In Design-Reviews auf die Frage „Sollten wir das nicht future-proof machen?“ nicht einfach nachgeben, sondern sagen: „So viel Aufwand wäre nötig, um es später hinzuzufügen, so hoch sind die Kosten, wenn wir es jetzt einbauen, und deshalb ist Warten besser“
- Es geht nicht um Widerspruch, sondern darum zu zeigen, dass die Abwägung bereits erfolgt ist
- Das Gespräch mit dem Manager direkt suchen: „Ich möchte, dass die Art, wie ich meine Arbeit dokumentiere, nicht nur den Code, sondern auch die von mir getroffenen Entscheidungen widerspiegelt“
- Aus Sicht des Managers liefert das zugleich die Sprache, mit der sich diese Arbeit vertreten lässt
- Wenn trotz all dieser Bemühungen in einem Team nur die Person befördert wird, die das ausgefeilteste System gebaut hat, dann ist auch das eine nützliche Information — manche Organisationen schätzen Einfachheit wirklich, andere behaupten das nur und belohnen in Wahrheit das Gegenteil
Konkrete Ansätze für Engineering-Führungskräfte
- Anreize zu setzen, ist Aufgabe von Führungskräften — die meisten Beförderungskriterien sind so gestaltet, dass sie Komplexität belohnen, und „Impact“ wird oft an Größe und Umfang dessen gemessen, was gebaut wurde
- Bewertet werden sollte nicht nur, was gebaut wurde, sondern auch, was vermieden wurde
- In Design-Reviews statt „Habt ihr Skalierbarkeit berücksichtigt?“ lieber fragen: „Was ist die einfachste Version, die wir ausliefern können, und welche konkreten Signale würden zeigen, dass wir etwas Komplexeres brauchen?“
- Diese eine Frage verändert das Spiel: Einfachheit wird zum Standard, Komplexität muss sich erst rechtfertigen
- In Beförderungsdiskussionen sollte man bei Paketen, die aus Listen beeindruckender Systeme bestehen, zurückfragen: „War das alles wirklich nötig? Brauchten wir das pub/sub-System tatsächlich, oder sah es nur auf dem Papier gut aus?“
- Wenn ein Teammitglied etwas Sauberes und Einfaches ausliefert, sollte man helfen, das Narrativ dazu zu formulieren — „mehrere Ansätze bewertet und den einfachsten gewählt, der das Problem löst“ wird nur dann zu einem überzeugenden Beförderungsbeispiel, wenn Führungskräfte es auch so behandeln
- Führungskräfte sollten darauf achten, wem sie in Team-Channels öffentlich gratulieren — wenn nur große, komplexe Projekte gelobt werden, optimieren sich Menschen genau darauf
- Anerkennung verdienen auch Engineers, die Code gelöscht haben, und diejenigen, die gesagt haben „Das brauchen wir noch nicht“ und damit richtig lagen
10 Kommentare
lebenslaufgetriebenes Design...
Hacker-News-Kommentare
In einer Interviewfrage wurde ein Szenario beschrieben, in dem zwei Personen Tabellen per E-Mail austauschen
Ich antwortete, dass ich zu Google Sheets wechseln würde, aber der Interviewer wollte offenbar, dass ich das Tool selbst entwerfe
Damals war es unangenehm, und bis heute bin ich nicht sicher, welche Lehre ich daraus ziehen sollte
Man hätte eine gute Antwort anerkennen und dann weiterleiten sollen mit: „Das ist eine hypothetische Situation zur Bewertung von Technical Design, also lass uns ein neues System entwerfen“
Wenn der Bewerber auf diese Prämisse nicht eingeht, kann man das als anderes Signal bewerten
Ich würde in so einem Fall fragen: „Sollen wir annehmen, dass es keine bestehende Lösung gibt, und etwas Neues entwerfen?“
Das ist wie die System-Design-Version der Algorithmusdebatte, bei der der Interviewer nur die Antwort hören will, die er erwartet
Das war tatsächlich die richtige Entscheidung, aber Patrick Collison rief ihn persönlich an und fragte: „Du hast das Interview nicht bestanden, aber verstehst du, worum es ging?“
Am Ende absolvierte er das Interview noch einmal und bestand
Eine Anekdote, die zeigt, wie wichtig es ist, den Zweck des Interviews zu verstehen
Eine große Fährgesellschaft verwaltet Schiffspositionen und Personaleinsatz mit Google Sheets, und mein Freund sagte: „So etwas sollte ein Großunternehmen nicht machen“
Ich hingegen fand es großartig, dass ein Problem mit einem bereits bewährten Tool gelöst wurde
Dadurch war der Betrieb ohne internes Entwicklungsteam oder teure externe Dienstleister möglich
Das war eine Erfahrung, die mich dazu brachte, meine Arroganz tief zu begraben
Man sollte die andere Seite konkret erklären lassen, was genau nicht passt, und erst dann mit dem technischen Design beginnen
Es gibt viele Gründe, warum Sheets nicht nutzbar sein könnte — Funktionsgrenzen, eingeschränkter Zugang in China, Unternehmensrichtlinien, Netzwerkprobleme usw.
Der Kunde könnte gerade aus solchen Gründen bereits eine Custom-Lösung wollen
Die Aufgabe des Entwicklers ist also nicht einfach zu sagen: „Verwendet Google Sheets“, sondern den Kontext des Kunden zu verstehen
AI-Coding-Tools verschlimmern das Problem auf subtilere Weise
Heute kann man komplexe Architekturen in fünf Minuten erzeugen, aber die Wartungskosten bleiben gleich
Dadurch entstehen schneller noch auffälligere Strukturen, und auch Dokumente für Beförderungen sind rasch fertig
In Wirklichkeit versteht aber niemand den Code vollständig
Der wahre Maßstab für Einfachheit ist, ob „die nächste Person ihn ohne Fragen verstehen kann“, und AI-generierter Code besteht diesen Test nicht wirklich
Jetzt wird das nur noch schlimmer
Deshalb ist für mich die Kultur des Codeverständnisses in einer Organisation ein Kriterium bei der Karrierewahl
Eine Situation, in der niemand das System versteht, möchte ich nicht noch einmal erleben
Wenn Problemlösung das Ziel ist, muss am Ende sowohl ein mit AI gebautes Tool als auch ein gekauftes Tool das Problem lösen
Wenn ein Standardprodukt aber nicht passt, wird es am Ende mehr individuell erzeugte Custom-Lösungen geben
Wenn die dann wieder niemand versteht, baut die nächste Person eben erneut etwas Neues
Trotzdem könnte es eine Verbesserung sein, weil Nutzer und Ersteller enger zusammenrücken
Wenn man zum Beispiel in
AGENTS.mdRichtlinien wie „KISS“ oder „YAGNI“ festhält, hilft dasDas Problem ist, dass die „nächste Person“ am Ende ich selbst in sechs Monaten bin
Auch AI stößt wegen der Grenzen des context window auf dasselbe Problem
Viele Entwickler jagen nur populären Stacks hinterher und berücksichtigen die Betriebsfreundlichkeit nicht
AI sagt einem auch nicht: „Das ist Overengineering“
Wenn man Kubernetes und ElasticSearch will, baut sie es einfach genauso
Aus der Perspektive von jemandem, der sowohl FAANG als auch Startups erlebt hat, ist die Balance zwischen Komplexität und Einfachheit entscheidend
In Großunternehmen kann ein provisorischer Hack die Produktivität von Tausenden beeinträchtigen,
in Startups kann übermäßige Infrastruktur ein Unternehmen ruinieren
Ein wirklich erfahrener Engineer ist jemand, der diese beiden Situationen unterscheiden und aufgrund seiner Erfahrung die passenden Trade-offs wählen kann
Als ich von 2005 bis 2008 bei Amazon arbeitete, gab es zwei Auszeichnungen, die sinnbildlich für die Unternehmenskultur standen
Der „Just Do It“-Award stand für eigeninitiierte Problemlösung, der „Door Desk“-Award für Sparsamkeit und Einfachheit
Tatsächlich bekam einmal ein Mitarbeiter einen Preis, weil er einen nutzlosen Fernseher entfernt hatte, und als Belohnung erhielt er genau diesen Fernseher
Einfachheit als Metapher war in der Realität etwas uneindeutig
Wer für Einfachheit argumentieren will, muss sie in der Sprache des Business ausdrücken
Etwa als „80 % weniger Incidents“, „40 % geringere Kosten“ oder „33 % bessere Performance“
Einfachheit an sich wird nicht bewertet, aber ihre Ergebnisse werden hoch geschätzt
Ich habe Refactoring in ein Kostenmodell übersetzt, KPIs gemessen und die MTTR um 60 % reduziert
Solche Zahlen muss man selbst sichtbar machen, um Anerkennung zu bekommen
Als Manager habe ich einfachen Code bevorzugt
Das lag aber auch daran, dass mein Team aus erfahrenen Leuten bestand
In weniger erfahrenen Teams passieren Dinge wie in The Parable of The Toaster
Je älter ich werde, desto stärker wehrt sich alles in mir gegen Komplexität
Führungskräfte missverstehen das jedoch oft als „Er lehnt es ab, weil er es nicht versteht“
Die Projekte, die am längsten überlebt haben, waren die einfachen und leicht austauschbaren
AI-Tools machen diesen Ansatz leichter — man experimentiert mit Komponenten in isolierten Sample-Projekten und integriert verifizierten Code in das eigentliche Projekt
In einer internen Netzwerkumgebung binde ich AI zwar nicht direkt an, aber diese Arbeitsweise ist sehr nützlich
Deshalb schlage ich vor: „Wir können auch etwas Komplexes bauen, aber lasst uns zuerst mit einer einfachen Version anfangen“
Meist wird genau diese einfache Version am Ende zu Produktionscode, der jahrelang läuft
Entwickler, die schnell eine einfache Lösung liefern, können in der verbleibenden Zeit noch mehrere Features umsetzen
Wer sich dagegen an einer komplexen Lösung festbeißt, steckt oft Wochen in ein einziges Feature
In den Produktivitätsmetriken wirkt der einfache Ansatz deshalb am Ende attraktiver
Auch ich habe meine Karriere eher als jemand aufgebaut, der kontinuierlich Ergebnisse liefert, als mit „großen Ideen“
Eines unserer Unternehmensinterviews ist eine System-Design-Aufgabe für ein öffentliches Bibliothekssystem
Sie beginnt im Maßstab einer kleinen Stadtbibliothek und erweitert das Szenario bis auf landesweite Größe
Die beste Antwort war: „Selbst im größten Maßstab reichen ein mittelgroßer Server und Postgres vollkommen aus“
In der Praxis gibt es zwischen 10 und 10.000 oft keinen großen Unterschied, aber häufig lesen unerfahrene Interviewer nur das Prompt ab
Später haben übermäßige Infrastruktur und lebenslauforientierte Entwicklung das Problem verschärft
Ich denke, AI ist letztlich ein Werkzeug, das die Fähigkeiten des Nutzers verstärkt
Für erfahrene Entwickler steigert sie die Produktivität, für unerfahrene wird sie zu einem Werkzeug, das Verwirrung schneller verbreitet
Im Gegenteil, sie neigt dazu, unnötige Wrapper-Funktionen und Typkonvertierungen hinzuzufügen
Mein Eindruck ist, dass AI eher „mehr Code hinzufügt“
Trotzdem finde ich die Zunahme von oberflächlichem „vibe coding“ besorgniserregend
Ich halte die in diesem Artikel gemachten Vorschläge nicht für bedeutungslos, aber ich denke, dass sie es sehr schwer haben, gegen „Big Design“ zu gewinnen. Das lässt sich einfach viel, viel leichter erklären :(
Die Interviewer, die ich getroffen habe, schienen ebenfalls Komplexität zu bevorzugen.
Ich erwarte noch nicht einmal, dass Schlichtheit positiv bewertet wird. In der Realität wird man ja manchmal sogar befördert, weil man etwas unnötig komplex gemacht, damit einen Vorfall verursacht und ihn anschließend wieder bereinigt hat.
Überengineering, das nicht dem Service dient, sondern nur dazu, die eigenen Fähigkeiten aufzublasen, ist allgegenwärtig.
Ich denke, die beurteilende Person muss ein gutes Verständnis haben.
Es stimmt auch, dass sie sich die Erklärungen ausreichend anhören muss.
Wenn jemand in einer höheren Position wäre, der so etwas beurteilen kann, wäre alles in Ordnung. Aber genau das klappt von vornherein nicht, deshalb wird so etwas nicht fair bewertet, und deshalb können solche Leute nicht nach oben kommen...
Das ist ein Teufelskreis...
Aus Sicht des Unternehmens scheint es wichtig zu sein, dass man als ausgewogener Engineer erfolgreich ist und nach oben kommt, damit auch gute Engineer-/Engineering-Prinzipien gewahrt werden können.
Ist die Realität nicht meistens eher: Man kann nur schlicht Funktionen implementieren vs. man kann skalierbar entwerfen und ist auch gut darin, Trade-offs abzuwägen?
Selbst wenn die Arbeit komplex war, kann man es letztlich als die Implementierung von Funktion X bezeichnen.
Der Unterschied liegt darin, auf welche Weise man das dem Bewertenden vermittelt.