Alle Beiträge

Feststecken ist der Sinn der Sache

Artikel anhören (experimentell) · 13:11

00:00 / 13:11

Ein Pfad in einem Feld aus Code überspringt zwei Wände auf geisterhaften Bögen und verknotet sich an einer dritten, in einem bernsteinfarbenen Leuchten mit grünem Ring, und tritt auf der anderen Seite heller aus

Programmieren habe ich in den Jahren gelernt, in denen Feststecken die einzige Option war. Ein Build, der nicht kompilieren wollte, und eine Fehlermeldung, die auf nichts Brauchbares zeigte. Ein Konzept, das einfach nicht klicken wollte, egal wie oft ich dieselbe Seite noch einmal las. Nicht, dass ich damit allein gewesen wäre. Es gab eine ganze Leiter, um wieder loszukommen: die Dokumentation noch einmal lesen, langsamer. Das abgegriffene Buch aus dem Regal ziehen. Ein älteres Projekt durchwühlen, das etwas Verwandtes gelöst hatte. Den Kollegen einen Schreibtisch weiter fragen, und wenn die Mauer das alles überlebte, das Problem sorgfältig aufschreiben und in ein Forum stellen, dann warten, manchmal tagelang, bis ein Fremder mit den passenden Narben antwortete.

Heute schreibe ich jeden Tag Code mit zwei Modellen an meiner Seite, und die ganze Leiter ist zu einer einzigen Sprosse zusammengefallen. Ich füge den Fehler ein, und die Antwort ist da, bevor ich meine eigene Vermutung zu Ende gedacht habe. Das ist echte Beschleunigung, und diesen Tausch nehme ich jederzeit an. Aber ich habe mehr als ein Jahrzehnt damit verbracht, die alte Leiter von Hand hochzuklettern, und ich spüre ziemlich genau, was in diesem Moment nicht mehr passiert. Früher lief etwas in meinem Kopf zwischen den Sprossen, und heute bekommt es keine Chance mehr anzulaufen. Auf dieses Etwas habe ich in früheren Essays gezeigt, immer nur im Vorbeigehen. Es verdient den vollen Blick.

Was die festgefahrenen Stunden geleistet haben

Feststecken war nie tote Zeit. Es war der Zustand, in dem mein Bild von der Maschine am schnellsten korrigiert wurde.

Das passiert im Inneren eines Bugs, der keinen Sinn ergibt. Du hast ein Bild im Kopf, wie das System funktioniert, und das System hat gerade etwas getan, das dein Bild für unmöglich erklärt. Also machst du Experimente. Du stellst eine Hypothese auf, testest sie, siehst sie scheitern, korrigierst. Jede gescheiterte Vermutung schließt eine weitere Art aus, wie die Maschine funktionieren könnte. Wenn du den Fix endlich findest, ist der Fix fast nebensächlich. Was du wirklich getan hast: Du hast die genaue Stelle gefunden, an der dein Bild falsch war, und es neu gezeichnet.

Selbst im besten Bug geht ein guter Teil der Zeit für Leerlauf drauf, fürs Neutippen, fürs Nachprüfen des Offensichtlichen. Das Lernen wohnt in den Momenten, in denen eine Vermutung auf die Maschine trifft und stirbt. Aber diese Momente passieren nur, wenn du für den Rest im Raum geblieben bist.

Deshalb erinnere ich mich Jahre später noch an den Bug, der eine Woche gefressen hat, und an kein einziges Feature, das reibungslos ausgeliefert wurde. Das reibungslose Feature hat mein Bild vom System nie berührt. Der Bug hat es neu gezeichnet.

Konzepte, die nicht klicken wollen, funktionieren genauso. Du umkreist sie, probierst eine Deutung, siehst sie einstürzen, probierst die nächste. Wenn die Idee endlich landet, landet sie in einer Struktur, die deine gescheiterten Versuche gebaut haben, und deshalb bleibt sie. Auch Lesen, Dokumentation und Review korrigieren ein Bild, und ich stütze mich auf alle drei. Aber eine Korrektur hält nur dort, wo ein Versuch ihr einen Platz geschaffen hat. Die Erklärung, die du bekommst, bevor du gerungen hast, rutscht ab. Dieselbe Erklärung nach zwanzig Minuten gescheiterter Vermutungen landet, und bleibt.

Die alte Leiter war langsam, und die Langsamkeit war nicht nur Verschwendung. Um den Kollegen oder das Forum zu fragen, musstest du das Problem erst zu einer Frage verdichten, die jemand anderes beantworten konnte, und die Verdichtung allein löste die Hälfte davon. Wer je eine sorgfältige Beschreibung fertig geschrieben und dann ungepostet gelöscht hat, die Antwort plötzlich in der Hand, kennt den Effekt. Auch das Buch hat dir nie eine nackte Antwort gereicht; es hat dich das Kapitel drumherum lesen lassen, und in dem Kapitel wurden die nächsten drei Bugs verhindert. Und während du auf eine Antwort gewartet hast, liefen deine eigenen Experimente weiter, weil Warten mit leeren Händen unerträglich war. Hilfe gab es auf jeder Sprosse. Sie kam nur langsam genug an, dass du in der Zwischenzeit weitergedacht hast.

Der Wegfall ist lautlos

Jetzt hol ein Modell in den Loop. Der Build bricht, du fügst den Fehler ein, der Fix kommt, du machst weiter. Gemessen am Output ist das in jeder Hinsicht besser, und ich werde nicht so tun, als wäre es anders. Das Problem ist, wie der Tausch von innen aussieht. Nichts an dem Moment markiert ihn. Das Diff ist identisch mit dem, das du nach drei Stunden Ringen geschrieben hättest. Die Commit-History von jemandem, der das System versteht, und von jemandem, der jede Mauer ausgelagert hat, sieht exakt gleich aus, bis zu dem Tag, an dem sie es nicht mehr tut.

Denn der Code war nie das Produkt dieser drei Stunden. Das korrigierte Bild war es, und der Code war seine Quittung. Nimm die Abkürzung, und du bekommst trotzdem die Quittung, während das Bild auf eine Weise falsch bleibt, die keine Test-Suite an die Oberfläche holt. Wer lernt, ohne je festzustecken, ist nicht auf einer schnelleren Straße zum selben Ziel. Er ist auf einer schnellen Straße zu einem anderen, flüssig darin, Software zu produzieren, von der er nur ein dünnes Bild hat, und die Dünnheit zeigt sich erst an dem Tag, an dem die AI an seiner Seite falsch liegt und nichts in ihm das bemerkt.

Die nostalgische Version ist falsch

Vieles, woran ich festgesteckt habe, hat mir nichts beigebracht, was die Stunden wert war. Die Jagd nach dem fehlenden Semikolon. Der Build, der wegen eines Zufalls in der Umgebung brach, den niemand hätte vorhersehen können. Das undokumentierte Flag, der Versionskonflikt, der Nachmittag, der an ein Werkzeug verloren ging, das einfach schlecht war. Diese Mauern haben mir etwas Tooling-Folklore beigebracht, und Tooling-Folklore ist genau die Fracht, die die Maschinen heute besser tragen, als ich es je getan habe. Diese Art Mauer sofort aufzulösen ist genau das, wofür die Werkzeuge da sind.

Die festgefahrenen Stunden, die mich aufgebaut haben, waren eine andere Sorte, und die beiden Sorten auseinanderzuhalten ist der ganze Essay. Es waren die Stunden, in denen das Hindernis mein eigenes falsches Bild war. Das System folgte seinen eigenen Regeln, meine Vorstellung von diesen Regeln tat es nicht, und das Ringen war der Prozess, das herauszufinden. Die eine Sorte war eine Steuer. Die andere war Lehrgeld.

Du kannst sie auseinanderhalten, bevor die Antwort kommt, nicht erst danach. Frag dich, ob die Mauer im Problem steckt oder daneben steht. Ein Versionskonflikt steht neben dem Problem: Ihn zu lösen ändert nichts daran, wie du das nächste Programm schreiben wirst. Eine Funktion, die einen Wert zurückgibt, den dein Bild für unmöglich erklärt, steckt mittendrin: Sie zu lösen ändert, was du weißt. Im Zweifel behandle die Mauer zwanzig Minuten lang so, als steckte sie im Problem, und schau, ob dein Verständnis sich bewegt.

Sich aussuchen, wo man feststeckt

Die Fähigkeit hat also die Form gewechselt. Früher war sie Ausdauer, weil Feststecken überall Pflicht war. Jetzt ist Feststecken überall optional, was daraus ein Budget macht, und die Fähigkeit ist die Verteilung.

Ich gebe meins gezielt aus. Wenn die Retrieval-Arbeit, die ich für den Rechts- und Gesundheitsbereich mache, sich auf eine Weise danebenbenimmt, die mich überrascht, gehe ich von Hand hinein, denn Überraschung heißt, dass mein Bild vom System falsch ist, und das ist die Sorte Feststecken, die sich auszahlt. Überraschung ist allerdings ein Signal, das man sich verdient. Sie feuert nur dort, wo ein detailliertes Bild existiert, dem die Realität widersprechen kann, und deshalb fragt der Test für Anfänger weiter oben nach der Mauer, nicht nach dem Gefühl. Wenn ein Agent, an den ich delegiert habe, an einer Stelle stolpert, die ich hätte vorhersagen können, lasse ich das vom Tooling auffangen, denn dort gibt es nichts mehr, was diese Reibung mich lehren könnte. Die Delegations-Pipeline, die ich gebaut habe, existiert genau dafür, dass ich die Mauern abgeben kann, aus denen ich schon alles gelernt habe. Die anderen erklimme ich nach wie vor selbst, mit Absicht, langsamer, als ich könnte.

Delegiere ohne Schuldgefühl. Der Entwickler, der sich jedes Mal vage schämt, wenn das Modell ihn aus einer Blockade holt, hat den falschen Rahmen im Kopf, als läge die Tugend in der Reibung selbst. Das tat sie nie. Die Reibung war immer nur das Mittel zum Bild. Gib sie dort aus, wo dein Bild noch dünn ist.

Und dieses Ausgeben ist keine Sentimentalität, es ist Ökonomie. Während Code generieren billig wird, ist die Arbeit, die ihren Preis behält, richtigen Output von falschem zu unterscheiden, und dieses Urteilsvermögen ist aus korrigierten Bildern gebaut. Die Gewohnheit überträgt sich auch. Jeder Bug, der eine Hypothese gegen ein laufendes System erzwingt, ist eine Wiederholung derselben Bewegung, die später einen falschen Vorschlag in Code erwischt, den du noch nie gesehen hast. Eine selbstsichere Behauptung kommt an, und etwas in dir weiß, dass sie getestet gehört.

Wenn du gerade lernst

Fahr dich mit Absicht fest, und fahr dich im Kleinen fest. Such dir Probleme in einer Größe, bei der Feststecken zwanzig Minuten echtes Nachdenken bedeutet, nicht ein verlorenes Wochenende. Was du willst, ist häufiger Kontakt mit deinem eigenen falschen Bild, in Stücken, die klein genug sind, um sie durchzuarbeiten.

Versuch es zuerst, immer. Schreib deine kaputte Version, bilde dir deine Vermutung zum Bug, und hol dann die AI dazu, und zwar als den Tutor, der deinen Versuch begutachtet, nicht als den Chauffeur, der dich am Problem vorbeifährt. Frag sie, wo dein Denken gescheitert ist, nicht nur, wie die Antwort lautet. Streite mit ihr. Die Korrektur des Tutors landet genau deshalb, weil dein Versuch den Platz gebaut hat, in den sie passt. Lass den Versuch weg, und dieselben Sätze lehren nichts.

Dann prüf dich selbst. Schalt die AI aus und bau das Ding noch einmal, und sag dabei, warum jedes Teil da ist, als säße ein Kollege neben dir und fragte nach. Das bloße Nachbauen lässt sich aus der Erinnerung an zugesehene Tastenanschläge fälschen. Das Warum nicht. Wenn beides standhält, haben die festgefahrenen Stunden ihre Arbeit getan, und das Verständnis gehört dir. Wenn nicht, hältst du eine Quittung für ein Lernen, das nie stattgefunden hat, und es ist besser, das jetzt herauszufinden, an etwas Kleinem, als in einem System mit deinem Namen darauf.

Die Maschinen werden dir für den Rest deiner Laufbahn an jeder Mauer einen Ausgang anbieten, und meistens solltest du ihn nehmen. Viele Mauern sind Rauschen, und Rauschen wegzuräumen ist das, wofür Werkzeuge da sind. Die richtigen Mauern sind der Ort, an dem dein Bild von der Maschine entsteht. Lern, sie auseinanderzuhalten, schlag den Ausgang dort aus, und lass die Mauer ihre Arbeit tun. An den richtigen Mauern festzustecken ist der Sinn der Sache.

Fragen, die dieser Artikel beantwortet

  • Lernt man beim Feststecken wirklich etwas oder ist das nur verlorene Zeit?

    Es ist der Zustand, in dem dein Bild von der Maschine am schnellsten korrigiert wird. Du hast ein Bild davon, wie das System funktioniert, das System tut etwas, das dieses Bild für unmöglich erklärt, und du stellst Hypothesen auf, bis eine auf die Maschine trifft und stirbt. Deshalb ist der Bug, der eine Woche gefressen hat, Jahre später noch da und das reibungslos ausgelieferte Feature nicht: Das reibungslose Feature hat das Bild nie berührt, der Bug hat es neu gezeichnet.

  • Ist das nicht bloß Nostalgie nach dem mühsamen Weg?

    Nein, und die nostalgische Fassung des Arguments ist falsch. Viele alte Mauern haben nichts beigebracht, was die Stunden wert war: das fehlende Semikolon, der Versionskonflikt, das undokumentierte Flag, der Nachmittag, der an ein einfach schlechtes Werkzeug verloren ging. Die haben Tooling-Folklore beigebracht, und genau diese Fracht tragen die Maschinen heute besser. Diese Art Mauer sofort aufzulösen ist das, wofür die Werkzeuge da sind.

  • Woran erkenne ich, welche Probleme ich selbst löse und welche ich an die AI abgebe?

    Frag dich, ob die Mauer im Problem steckt oder daneben steht. Ein Versionskonflikt steht daneben, denn ihn zu lösen ändert nichts daran, wie du das nächste Programm schreibst. Eine Funktion, die einen Wert zurückgibt, den dein Bild für unmöglich erklärt, steckt mittendrin, denn sie zu lösen ändert, was du weißt. Im Zweifel behandle die Mauer zwanzig Minuten lang so, als steckte sie im Problem, und schau, ob dein Verständnis sich bewegt.

  • Wie nutze ich beim Programmierenlernen die AI, ohne von ihr abhängig zu werden?

    Fahr dich mit Absicht fest und fahr dich im Kleinen fest, an Problemen in einer Größe, bei der Feststecken zwanzig Minuten echtes Nachdenken bedeutet und nicht ein verlorenes Wochenende. Versuch es zuerst selbst und hol die AI dann als den Tutor dazu, der deinen Versuch begutachtet, nicht als den Chauffeur, der dich am Problem vorbeifährt, und frag sie, wo dein Denken gescheitert ist, statt nur nach der Antwort. Schalt sie danach aus und bau das Ding noch einmal, und sag dabei, warum jedes Teil da ist, denn das bloße Nachbauen lässt sich aus der Erinnerung an zugesehene Tastenanschläge fälschen und das Warum nicht.