Softwareentwicklung gilt als langsam.
Ich verstehe den Gedanken aber in Wahrheit ist Softwareentwicklung extrem schnell. Ich kenne kein anderes Feld das bei ähnlicher Komplexität und technologischem Stand ähnlich schnell neue Produkte erzeugt.
So close. But they forgot at the end, that LLM “AI” is not a long-term viable business model, without delivering what it promised: obliterating the job/cost of developers.
The Zen of Programming:
The bad programmer writes a lot of spaghetti code that is impossible to debug or fix, so it has to be rewritten. The good programmer writes a few lines of efficient code and is done with the work. The enlightened programmer realizes this feature already exists somewhere else and doesn’t have to be rewritten. The enlightened programmer writes no code.
Das Problem war nie das Schreiben von Code, sondern wie man es schafft, mit möglichst wenig Code möglichst das zu haben, was man braucht. Frei nach Elon Musk: The best part is no part. Bedeutet, wenn es ohne geht, dann besser ohne.
Interessant, dass du hier Elon Musk zitierst, der ja bekannterweise nach der Twitter-Übernahme Leute auf Basis von “Lines of code written last year” gefeuert hat.
ja haha das war wohl etwas unglücklich zitiert.
Zeigt halt schön, welches gute Marketing der hatte. Dein Zitat wird irgendwer ihm geschrieben haben, er hat es ausgeplaudert, Leute haben ihn deswegen für klug gehalten. Und dann stellt sich nachher raus, dass er null Plan hat.
Ah ja, Elon Musk. Der Meister der Rationalisierung. /s
Er mag das von einem Ingenieur gestolen haben, aber wahr ist es trotzdem.
Weil’s dann eher Koten gleicht.
Das ist wirklich so, dass Softwareentwickler nur sehr wenig Zeit mit dem Eintippen von Code verbringen. Ich selber hatte zum Beispiel zwei Mal neue Projekte mit komplexen Anforderungen, wo ich jeweils in etwa 5 Jahren rund 50000 bis 60000 Zeilen Code geschrieben habe (und weit über 200 Seiten Dokumentation). Tatsächlich ist es extrem produktiv, in einem Jahr 10000 Zeilen gut funktionierenden, nahezu fehlerfreien, gut wartbaren, dokumentierten Code zu schreiben, und in einem größerem Projekt fast nicht möglich, da die Geschwindigkeit aufgrund der wachsenden Komplexität stark sinkt. Ein Projekt wie der Linux-Kernel mit vielen Millionen Zeilen komplexen Code repräsentiert einen unfassbar großen Wert an Arbeitszeit. (Schätzungen von 2018 geben 14 Milliarden Dollar Wert für “nur” 20 Millionen Zeilen Code an, d.h. die Erstellung und Pflege von einer Zeile Kernel-Code kostet aktuell rund 700 Dollar!).
Diese 10000 Zeilen sind, bei rund 250 Arbeitstagen im Jahr, 40 Zeilen Code pro Tag - deutlich weniger als eine Seite. Softwareentwickler tun halt zeitlich gesehen zu 90% (und bei Legacy Code zu 98%) andere Dinge, als Code zu schreiben - z.B. klären sie überhaupt erst mal, was der Code tun muss.
Eine gute Metrik für die Komplexität von Programmcode ist, die Zahl der darin enthaltenen Symbole zu vergleichen mit den Vokabular einer Fremdsprache. Einen fließenden Wortschatz von 5000 Worten wird man normalerweise erst nach Jahren steter Übung erwerben. Bei Programmcode ist es so, dass ein Programm von 50000 Zeilen Länge vielleicht so 5000 oder 6000 Symbole enthält - und deren Bedeutung muss man lernen, ganz wie eine Fremdsprache. Deswegen ist die Wartung von umfangreichem altem Code so zeitaufwendig und schwierig.
Deswegen könnte KI das auch selbst im besten Fall in Wirklichkeit nicht mehr als um ein paar Prozent beschleunigen - selbst wenn die Zeit für die Eingabe von Code auf Null sinken würde. Und eine Beschleunigung setzt ja noch voraus, dass die Beseitigung der Fehler (Debugging) nicht länger dauert als nach manueller Eingabe. Letzteres ist aber in der Praxis schon nicht der Fall.
Den Vergleich mit einem Fremdsprachen-Vokabular finde ich spannend, das merke ich mir :)
Eine Konsequenz der Tatsache, dass man den Zusammenhang und die Bedeutung der Namen in einer größeren Codebasis regelrecht erlernen muss, ist dass es wegen der Menge an Details nur durch häufige Wiederholung geht. (Ins Kurzzeitgedächtnis passen bekanntlich nur ca. sieben Dinge rein ).
Und dass es bei Legacy Code extrem hilfreich ist, sich auf Geschriebenes zu stützen, denn das vereinfacht die Wiederholung .
Ich sehe vor allem bei kleinen, klar abgegrenzten Projekten einen Vorteil - Dinge die man in 10-20k Code machen kann. Danach bekommt das LLM auch massiv Probleme, und macht zu viel Duplizierung von Code - ab der Schwelle etwas ist es fast immer schneller ein Problem selber zu beheben.
Auch um da hinzukommen braucht es recht viel Anleitung - das ist praktisch wie wenn man einen Berufsanfaenger anleitet der alle Patternbooks auswendig gelernt hat, aber nicht so richtig versteht wie man das in eine funktionierende Anwendung zusammensetzt. Wirklich gute Erbebnisse bekommt man auch nur wenn man von Anfang an so arbeitet dass die KI ihren Code testen kann (wer schon laenger dabei ist wird sich an “test driven development” erinnern - die Methodik ist ideal mit KI). Aber auch da gibt es Ausreden (“ich hab den Test nicht kaputtgemacht, der hat noch nie funktioniert”), und oft genug Probleme die sich mit Erfahrung schneller (und eventuell billiger) loesen lassen als mit KI. Man sieht da recht schoen dass der erzeugte Code am Anfang oft nicht compiliert - ohne dass die KI selber Compilieren kann scheitert das schon daran. Und bei Problemen werden so lange Variationen durchprobiert bis das tut - was sehr schoen zeigt dass eben keinerlei Codeverstaendnis vorhanden ist.
Gerade bei existierenden Projekten fuehrt das dann dazu dass die vorgeschlagenen Aenderungen deutlich groesser sind als noetig - was fuer die Nachvollziehbarkeit spaeter ein Problem ist.
Wir machen als Firma viel um CI und Testautomatisierung - und haben da immer wieder Bedarf an spezialisierten und relativ kleinen Tools. Fuer den Spezialfall ist das ideal - das ist so Groessenordnung 20 EUR API-Credits und ein Tag Anleitung, gefolgt von 3-4 Tagen Code saubermachen gegenueber 2-3 Wochen komplett selber machen.
Ich koennte mir denken dass man in einer reinen Microservicesumgebung (sofern man die einzelnen Services bei 10-20k LOC halten kann) damit die Entwicklung deutlich beschleunigen kann - das trifft aber eben nur auf einen Bruchteil der Software da draussen zu.
Ich koennte mir denken dass man in einer reinen Microservicesumgebung (sofern man die einzelnen Services bei 10-20k LOC halten kann) damit die Entwicklung deutlich beschleunigen kann - das trifft aber eben nur auf einen Bruchteil der Software da draussen zu.
Ich bin schon seit Jahren der Meinung dass jedes Projekt überhalb 30K LOC zerteilt werden muss in kleinere Teilprojekte, denn nur so bleibt ein Projekt wirklich übersichtlich. Darüber ist es praktisch nicht mehr möglich, zu durchschauen, was ein Programm überhaupt macht.
Code-Nachvollziehbarkeit hilft schon heute, und kleinere Projekte helfen mit der Code-Nachvollziehbarkeit. Leider ist es scheinbar ein Bedürfnis der menschlichen Psyche meiner Mitmenschen, ein gigantomanisches Monolith-Projekt zu bevorzugen. Denn das ist wie mit großen Autos: Hauptsache groß, dann fühlt man sich selber groß. Schlau ist das nicht.
Übrigens fällt dieser Beitrag (und einige weitere hier im Faden) exakt in das Muster, das ich erst heute morgen in meinem Kommentar auf c/[email protected] als eine weitere Marketing-Strategie unter einem Arsenal von Strategien beschrieben habe, mit der versucht wird GenAI unter Softwareentwicklern an den Mann, bzw an die Frau zu bringen:
- da wird erstens eingeräumt, dass GenAI unter bestimmten Bedingungen (Entwickleunerfahren / zu erfahren / Problem zu komplex / keine genaue Spezifikation / Lösungsstrategie schon klar usw.) keinen Vorteil bringt
- und dann wird behauptet, dass es aber unter anderen Bedingungen (Entwickler erfahrener / weniger erfahren / genaue Spezifikationen vorhanden / Problem nicht definiert / Problem einfach / “Boilerplate”) dann doch angeblich einen Vorteil hat.
Belege für diese angeblichen Vorteile gibt es nie.
Eindeutige Untersuchungen, die z.B. Vorteile für erfahrene Entwickler belegen, gibt es nicht.
Offizielle Angaben, wozu KI nun gut geeignet sein soll und wozu nicht, gibt es keine.
Das ist letztlich eine Variante von “moving the goal posts”.
Ich beschreibe hier lediglich meine eigenen Erfahrungen - ich halte nicht viel davon Dinge blind zu hassen ohne sich das naeher angeschaut zu haben. I spiele seit etwa drei Jahren mit LLMs, hauptsaechlich auf lokaler Hardware. Die letzten Monate kamen Claude credits dazu weil es fuer bestimmte Probleme tatsaechlich Sinn gemacht hat.
Mein Hauptproblem mit LLMs ist der massive Energieaufwand, vor allem fuer Training - da sollte reguliert werden dass das zwingend erneuerbare Energien sein muessen (und zwar dafuer neu gebaut, nicht bestehende), und entsprechende Strafzoelle auf Benutzung von LLMs ausserhalb von EU wo wir nicht regulieren koennen. Das naechste ist dass der aktuelle Hype zum einen eine unnoetige Investitionsblase ist, zum anderen dann ohne Nachzudenken ueberall LLMs eingebaut werden, ohne dass verstanden wird zu welchem Zweck, oder auch wie das Fehlerverhalten ist. Zu Fehlerverhalten bei Codegenerierung habe ich oben ja was geschrieben - ich hab bisher grob 100EUR an Claude Credits verbrannt einfach nur um zu beobachten wie das Ding versucht weiterzumachen wenn es steckenbleibt (tl;dr: in dem Fall ist es praktisch immer besser das von Hand zu machen - teilweise ist es klar billiger, und ansonsten wird ziemlich sicher der erzeugte Code scheisse sein, bzw, deutlich zu viel neu schreiben).
Ich gehe davon aus dass wir langfristig mit LLMs arbeiten werden - aber sicher >95% der aktuellen Einsatzzwecke ein Platzen der Investitionsblase nicht ueberleben werden, aus einer Kombination von “das war von Anfang an doof” und “nachdem die jetzt tatsaechliche Kosten bezahlt haben wollen ist das zu teuer”. Ich gehe auch nicht davon aus dass bei Bezug auf Code wir eine Verbesserung ueber die 10k-20k LOC sehen werden - auch um das zu erreichen steigt die Koordinationsarbeit vom Menschen um die relevanten Informationen im Context Window zu halten, und ein Vorhalten von nennenswert groesseren Context Windows wuerde das zu sehr verteuern.
Ich wuerde darauf tippen dass generell das Generieren von Code mit Ende der Blase deutlich weniger werden wird - das duerfte sich dann nur noch bei Modellen lohnen die man lokal laufen lassen kann. Bei Reverse Engineering und aehnlichen Analysen wuerde ich erwarten dass das weiterhin viel genutzt wird - da sind heute schon lokale Modelle recht nuetzlich.
Weiter so - lass dich nicht entmutigen :-)
Es gibt zu viele Menschen die blind KI haten weil es neu ist und Arbeitsplätze gefährdet. Der Weg in die Zukunft ist ein Bedingungsloses Grundeinkommen, nicht ein Festhalten an Jobs und einer damit einhergehenden Blindheit für die Potenziale von KI, die durchaus beachtlich sind.
Ich beschreibe hier lediglich meine eigenen Erfahrungen - ich halte nicht viel davon Dinge blind zu hassen ohne sich das naeher angeschaut zu haben.
Da gibt es bei mir zwei Aspekte:
- Ich halte meinerseits ganz sachlich nichts davon, so quasi das Wohlergehen der gesamten Wirtschaft auf eine angebliche Wundertechnologie zu wetten, bei der nicht ansatzweise belegt werden kann, dass die hält, was das Marketing verspricht. Extraordinary claims require extraordinary evidence.
Beim Ausgangspost ging es darum, dass ein genaues Verständnis des Codes in der Softwareentwicklung wesentlich ist, und dass der Zeitanteil für die Codeeingabe so gering ist, dass selbst eine völlig automatisierte Eingabe Softwareentwicklung gar nicht nennenswert beschleuniglen kann. Gibt es irgendwelche Evidenz, dass das nicht so ist?
- Ich hasse es allerdings in der Tat, ständig Bullshit erzählt zu bekommen und damit regelrecht vollgespammt zu werden. Da finde ich es auch angemessen, mal deutlich zu werden.
Gibt es irgendwelche Evidenz, dass das nicht so ist?
Hatte ich doch geschrieben - ich habe diverse Tools die mich etwa 2-3 Wochen Arbeit gekoestet haetten, und ich so in knapp unter einer Woche gebaut habe. Mit Aufarbeiten des Codes damit er wartbar ist - fuer Wegwerftools ist das etwa ein Tag. Weitere Entwicklung danach mach ich manuell, da taugt das nicht fuer, unter anderem wegen fehlendem Codeverstaendnis fuer das was er generiert hat. Hauptarbeit ist auch das so zu lenken dass wartbarer Code rauskommt.
Ergebnis haengt auch sehr stark von der Sprache ab - ich hatte mit Abstand die besten Ergebnisse mit elisp (und mir da auch diverse Sachen gebastelt fuer die ich sonst keine Zeit gehabt haette). Das hilft da deutlich dass es durch den lisp-interpreter gute Fehlermeldungen gibt, und die eingebaute Dokumentation exzellent ist. Da die Welt wohl leider nicht auf Emacs umsteigen wird ist das allerdings fuer die meisten Leute wohl eher nicht relevant.
Zu “test driven development” hat John Ousterhout einiges geschrieben in “A Philosophy of Software Design”.
tl;dr: “test driven development” ist kacke.
Ousterhout nennt das “debugging a system into existence”. Man erstellt erst ohne durchgängiges Konzept code mit beliebig vielen Fehlern. Dann testet man ein bisschen und beseitigt die Fehler, auf die man trifft. Fälle, die man nicht testet, werden logischerweise wahrscheinlich wieder in Fehler laufen. Weil dem Code kein solides Konzept zugrunde liegt. Weitere Änderungen macht man dann so, dass wieder mit minimalen Änderungen - kein Design, kein grundsätzliches Refactoring - die gewünschte Funktionalität zu sehen ist.
Und den Code durch ausgiebiges Testen und korrigieren einigermaßen Fehlerfrei zu machen, dauert länger als ihn gleich richtig zu designen.
So wie ich test driven development erlebt habe ging es darum die Tests vor der Implementation zu entwickeln - das hatte nichts mit unsolidem Konzept zu tun. Das war bei Programmierern eher ungeliebt weil das Gegenteil erforderlich war: Sie muessten sich darueber Gedanken machen wie der Code aussehen soll bevor sie den taetsaechlichen Code schreiben um dafuer sinnvolle Tests zu bauen. Das wurde oft als “das sollten doch Architekten machen” gesehen, “ich leg einfach los und das wird dann irgendwann”.
Cool. Ich habe selbst festgestellt, dass ich mit TDD den Code mehr rate als darüber nachzudenken. Schön zu wissen, dass ich nicht der einzige bin, der so fühlt.
Ousterhouts Buch ist wirklich super empfehlenswert, es ist nicht so dick!
Das entspricht so gar nicht meiner Vorstellung von TDD. Für mich ist TDD, dass man sich explizit vorher Gedanken macht und diese in einer Spezifikation niederschreibt. Die Spezifikation wird dabei in Form von Unit- und Integrationstests verfasst, damit automatisch geprüft werden kann, dass der Code der Spezifikation entspricht.
Echtes TTD, so wie ich es gelernt habe, erfordert, dass du immer nur die kleinstmögliche Änderung an den Unit-Tests machst. Der erste Test prüft z.B. nur, ob es eine Funktion gibt. Dann schreibst du den Code, der genau diese Anforderung umsetzt, also eine Methode, die nichts macht.
Danach fügst du die nächste kleine Anforderung zum Test hinzu und programmierst dann genau die.
Vielleicht gibt’s TTD in verschiedenen Geschmacksrichtungen. Dein Ansatz umgeht zumindest den Nachteil, dass durch das inkrementelle Hinzufügen winziger Funktionen kein „im Großen und Ganzen“ sauberes Modul dabei herausfällt.
Joa, habe TDD nie als Dogma gelernt, sondern aus der Praxis, also kann gut sein, dass das was ich kenne ein pragmatischerer Ansatz ist.
Für mich war immer der relevante Aspekt, dass man eben nicht einfach drauf loscodet, sondern sich vorher Gedanken macht, was die Anforderungen sind, was wiederum eine Grundvoraussetzung für sinnvolles Design ist, daher hat mich eure Beschwerde gerade etwas überrascht…
Echtes TTD, so wie ich es gelernt habe, erfordert, dass du immer nur die kleinstmögliche Änderung an den Unit-Tests machst. Der erste Test prüft z.B. nur, ob es eine Funktion gibt. Dann schreibst du den Code, der genau diese Anforderung umsetzt, also eine Methode, die nichts macht.
Das ist genauso, wie Robert “Bob” Martin das beschreibt, und worauf sich die Kritik von John Ousterhout ganz explizit bezieht.
Es gibt dann noch eine Beschreibung von Martin Fowler, dass in einem dritten Schritt im Anschluss daran, dass man den Test mit dem neuen Feature zum funktionieren gebracht hat, man Refactoring macht, bei dem man die Struktur des Codes wieder verbessert und etwas aufräumt.
Das ist natürlich besser als nichts! Aber Ousterhout argumentiert, dass sowohl die initiale Struktur des Codes, als auch spätere Änderungen des Codes vorab geplant und bedacht werden müssen, damit die Codebasis langfristig ihre Konsistenz behält. Viele ungerichtete, nicht geplante Änderungen an einer Codebasis führen halt früher oder später zu einem unrettbaren Durcheinander. Genauso wie es bei einer Bibliothek nicht fubktioniert, wenn man Bücher die zurück gegeben werden, einfach irgendwo in ein Regal stellt wo grad Platz ist - sie sind dann nicht mehr zu finden.
Und genau das, die Struktur des Code und seine Invarianten verstehen und diesen so ändern, dass diese implizite Struktur erhalten bleibt, kann die KI halt nicht, auch nicht bei einer mittelkleinen Codebasis. Die Struktur geht dann verloren, auch wenn die Tests vielleicht noch funktionieren.
Und das Problem ist gerade, dass funktionierende Tests eben nicht eine konsistente interne Struktur des Codes sicherstellen. Das können sie halt gar nicht.
Ich denke, da gibt es auch große Unterschiede in dem, was man programmiert. Im Web-Frontend habe ich festgestellt, dass die Aufgabe „Mach ein Formular, in das ein Nutzer x, y, z, v und falls q auch w eintragen kann” wahnsinnig viel Tipparbeit ist, weil sich die Formularfelder untereinander nicht viel (aber doch zu viel, um sie zu copy/pasten) unterscheiden.
Gleichzeitig können Formularfelder auch so individuell sein, dass es sich nicht lohnt, irgendwie ein wiederholbares Stück Code zu entwerfen (z.B. ein generisches Feld), weil das so viele Parameter entgegen nehmen müsste, dass man am Ende mehr Aufwand betreibt, als es wäre, das Feld einfach direkt zu schreiben.
In dem Punkt ist KI echt toll. Ich schreibe einmal ein Feld ins HTML, habe daneben die Datenstruktur offen und KI kann das Feld dann schlau mit den kleinen, nötigen Abweichungen kopieren.
Kürzlich hatte ich ein Formular zu produzieren, das ca. 20 Felder hatte, manche davon wiederholbar (d.h. „für jede Auswahl des Nutzers in Feld x, frage y, z und w ab). Das hätte mich geschätzt 2 Stunden gekostet. Ein Kollege hat den Fragebogen gegen ChatGPT geworfen und nach 10 Minuten ein brauchbares Gerüst geliefert, das ich nur noch 30 Minuten anpassen musste, weil in der Spezifikation das Domänenwissen fehlte.
Und zum Argument: „Ja, aber die Spezifikation aufzuschreiben, hat doch auch Zeit gekostet!” Ja – aber das hatte ich vorher schon gemacht, unabhängig davon, ob KI zum Einsatz gekommen wäre oder nicht. Ich muss ja auch wissen, was ich schreiben soll.
Zugegeben, „Programmiere ein Formular” ist nicht die hohe Kunst in der Informatik, aber ein großer Teil zumindest meines Berufs. Deshalb die Schlussfolgerung „es auch große Unterschiede in dem, was man programmiert“.
Erzähl das mal den KI Bros auf LinkedIn. Schön, mal eine realistische Meinung dazu zu lesen.
Der völlig überzogene Hype um generative KI zählt wohl zusammen mit der Verschleierung der realen Folgen des Rauchens zu einer der größten Desinformationskampagnen aller Zeiten.
Sehr viele der Blog Posts und YouTube-Videos die das hypen sind wohl bezahlt. Objektive Untersuchungen zur Produktivität gibt es fast keine - und die, die es gibt, fallen negativ aus.
du hast die Klimaleugnung vergessen
“clean, beautiful coal” - Trump, vor 2 Wochen
Objektive Untersuchungen zur Produktivität gibt es fast keine - und die, die es gibt, fallen negativ aus.
Das ist übrigens bei jeder neuen Technologie so und sagst daher nichts aus.
KI Coden hat bei mir zwei Anwendungen. Einmal schnelle Skripte die nicht in den Produktivcode kommen. Sowas wie “lade die sqlite und filtere alle Einträge mit Kriterium xy aus”. Sowas macht Copilot schneller als ich das runtertippen kann. Und eine bessere Autovervollständigung, was oft hilfreich ist aber manchmal auch totalen Müll produziert. Z.b. nicht existierende Variablen verwendet oder unreachable code erzeugt usw.
Edit: auch Doku bzw. Doxygen Kommentare gehen gut mit Copilot.
Wie kannst du die Query schneller einer KI beschreiben als sie eigenhändig in der effizientesten Sprache hierfür -> SQL <- zu schreiben?
Also um das Offensichtliche zu benennen: würdest du SQL Lernen wärst du schneller, du wärst unabhängiger und würdest weniger Ressourcen verschwenden.
Es geht mehr um den Gluecode wenn die Query eigentlich trivial ist. Sowas wie erstmal die Python Imports machen und ne main mit Argumentliste usw.
würdest du SQL Lernen wärst du schneller
Copilot macht das halt in 10sek. Ich kann schnell tippen, aber nicht so schnell.
würdest weniger Ressourcen verschwenden
100 Copilot Token sind 0,006Wh, ne durchschnittliche Anfrage liegt bei 0,4Wh. Wenn man dafür bloß 5min eher den Arbeitsrechner abschalten kann dürfte sich das lohnen.







