Die peinlichsten Fehler in meiner Programmierkarriere (bisher)

Die peinlichsten Fehler in meiner Programmierkarriere (bisher)
Wie man so schön sagt: Wenn man sich für seinen alten Code nicht schämt, wächst man als Programmierer nicht – und dieser Meinung stimme ich zu. Ich habe vor über 40 Jahren aus Spaß mit dem Programmieren begonnen, beruflich vor 30 Jahren, daher mache ich viele Fehler. sehr viel. Als Informatikprofessor bringe ich meinen Studenten bei, aus Fehlern zu lernen – ihren, meinen und denen anderer. Ich denke, es ist an der Zeit, über meine Fehler zu sprechen, um meine Bescheidenheit nicht zu verlieren. Ich hoffe, dass sie jemandem nützlich sein werden.

Dritter Platz - Microsoft C-Compiler

Mein Schullehrer glaubte, dass Romeo und Julia nicht als Tragödie angesehen werden könne, weil die Charaktere keine tragische Schuld hätten – sie benahmen sich einfach dumm, wie es Teenager tun sollten. Damals war ich nicht seiner Meinung, aber jetzt sehe ich in seiner Meinung ein Körnchen Rationalität, insbesondere im Zusammenhang mit der Programmierung.

Als ich mein zweites Jahr am MIT beendete, war ich jung und unerfahren, sowohl im Leben als auch im Programmieren. Im Sommer absolvierte ich ein Praktikum bei Microsoft im C-Compiler-Team. Zuerst erledigte ich Routineaufgaben wie die Profilerstellungsunterstützung, und dann wurde mir die Arbeit am (wie ich dachte) am meisten Spaß machenden Teil des Compilers anvertraut – der Backend-Optimierung. Insbesondere musste ich den x86-Code für Verzweigungsanweisungen verbessern.

Entschlossen, für jeden möglichen Fall den optimalen Maschinencode zu schreiben, stürzte ich mich kopfüber in den Pool. Wenn die Verteilungsdichte der Werte hoch war, habe ich sie eingegeben Übergangstabelle. Wenn sie einen gemeinsamen Teiler hatten, habe ich ihn verwendet, um die Tabelle enger zu machen (aber nur, wenn die Division mit durchgeführt werden konnte). Bitverschiebung). Als alle Werte Zweierpotenzen waren, habe ich eine weitere Optimierung durchgeführt. Wenn ein Wertesatz meine Bedingungen nicht erfüllte, habe ich ihn in mehrere optimierbare Fälle aufgeteilt und den bereits optimierten Code verwendet.

Es war ein Albtraum. Viele Jahre später wurde mir gesagt, dass der Programmierer, der meinen Code geerbt hatte, mich hasste.

Die peinlichsten Fehler in meiner Programmierkarriere (bisher)

Lektion gelernt

Wie David Patterson und John Hennessy in „Computer Architecture and Computer Systems Design“ schreiben, besteht eines der Hauptprinzipien von Architektur und Design darin, dafür zu sorgen, dass die Dinge im Allgemeinen so schnell wie möglich funktionieren.

Durch die Beschleunigung häufiger Fälle wird die Leistung effektiver verbessert als durch die Optimierung seltener Fälle. Ironischerweise sind häufige Fälle oft einfacher als seltene. Dieser logische Rat geht davon aus, dass Sie wissen, welcher Fall als häufig gilt – und dies ist nur durch sorgfältige Tests und Messungen möglich.

Zu meiner Verteidigung habe ich versucht herauszufinden, wie Verzweigungsanweisungen in der Praxis aussehen (z. B. wie viele Verzweigungen es gab und wie Konstanten verteilt waren), aber 1988 waren diese Informationen nicht verfügbar. Allerdings hätte ich keine Sonderfälle hinzufügen sollen, wenn der aktuelle Compiler keinen optimalen Code für das von mir erstellte künstliche Beispiel generieren konnte.

Ich musste einen erfahrenen Entwickler anrufen und gemeinsam mit ihm über die häufigsten Fälle nachdenken und sie gezielt bearbeiten. Ich würde weniger Code schreiben, aber das ist eine gute Sache. Wie Stack Overflow-Gründer Jeff Atwood schrieb, ist der schlimmste Feind eines Programmierers der Programmierer selbst:

Ich weiß, dass Sie die besten Absichten haben, genau wie wir alle. Wir erstellen Programme und lieben es, Code zu schreiben. So sind wir gemacht. Wir glauben, dass jedes Problem mit Klebeband, einer selbstgebauten Krücke und einer Prise Code gelöst werden kann. So sehr es Programmierern auch wehtut, es zuzugeben, der beste Code ist der Code, der nicht existiert. Jede neue Zeile benötigt Debugging und Unterstützung, sie muss verstanden werden. Wenn Sie neuen Code hinzufügen, sollten Sie dies mit Zurückhaltung und Abscheu tun, da alle anderen Möglichkeiten ausgeschöpft sind. Viele Programmierer schreiben zu viel Code, was ihn zu unserem Feind macht.

Wenn ich einfacheren Code geschrieben hätte, der häufige Fälle abdeckt, wäre es bei Bedarf viel einfacher gewesen, ihn zu aktualisieren. Ich habe ein Chaos hinterlassen, mit dem sich niemand befassen wollte.

Die peinlichsten Fehler in meiner Programmierkarriere (bisher)

Zweiter Platz: Werbung in sozialen Netzwerken

Als ich bei Google an Social-Media-Werbung arbeitete (erinnern Sie sich an Myspace?), habe ich in C++ so etwas geschrieben:

for (int i = 0; i < user->interests->length(); i++) {
  for (int j = 0; j < user->interests(i)->keywords.length(); j++) {
      keywords->add(user->interests(i)->keywords(i)) {
  }
}

Programmierer sehen möglicherweise sofort den Fehler: Das letzte Argument sollte j sein, nicht i. Unit-Tests haben den Fehler nicht aufgedeckt, und mein Rezensent auch nicht. Der Start erfolgte, und eines Nachts ging mein Code auf den Server und stürzte alle Computer im Rechenzentrum ab.

Es ist nichts schlimmes passiert. Bei niemandem ist etwas kaputt gegangen, denn vor der weltweiten Einführung wurde der Code in einem Rechenzentrum getestet. Es sei denn, die SRE-Ingenieure haben für eine Weile mit dem Billardspielen aufgehört und einen kleinen Rollback durchgeführt. Am nächsten Morgen erhielt ich eine E-Mail mit einem Crash-Dump, korrigierte den Code und fügte Unit-Tests hinzu, die den Fehler abfangen würden. Da ich mich an das Protokoll gehalten habe – andernfalls würde mein Code einfach nicht ausgeführt werden können – gab es keine weiteren Probleme.

Die peinlichsten Fehler in meiner Programmierkarriere (bisher)

Lektion gelernt

Viele sind sich sicher, dass ein so großer Fehler den Täter auf jeden Fall die Entlassung kosten wird, aber das ist nicht so: Erstens machen alle Programmierer Fehler, und zweitens machen sie selten denselben Fehler zweimal.

Tatsächlich habe ich einen befreundeten Programmierer, der ein brillanter Ingenieur war und wegen eines einzigen Fehlers entlassen wurde. Danach wurde er bei Google eingestellt (und bald befördert) – in einem Interview sprach er ehrlich über den Fehler, den er gemacht hatte, und er wurde nicht als fatal angesehen.

Das ist, was erzählen über Thomas Watson, den legendären Chef von IBM:

Eine staatliche Anordnung im Wert von rund einer Million Dollar wurde angekündigt. Die IBM Corporation – oder besser gesagt Thomas Watson Sr. persönlich – wollte es unbedingt haben. Leider war dies dem Vertriebsmitarbeiter nicht möglich und IBM verlor das Angebot. Am nächsten Tag kam dieser Angestellte in Mr. Watsons Büro und legte einen Umschlag auf seinen Schreibtisch. Mr. Watson machte sich nicht einmal die Mühe, es anzusehen – er wartete auf einen Mitarbeiter und wusste, dass es sich um ein Kündigungsschreiben handelte.

Watson fragte, was schief gelaufen sei.

Der Vertriebsmitarbeiter berichtete ausführlich über den Verlauf der Ausschreibung. Er nannte begangene Fehler, die hätten vermieden werden können. Schließlich sagte er: „Herr Watson, vielen Dank, dass Sie es mir erklären konnten. Ich weiß, wie sehr wir diese Bestellung brauchten. Ich weiß, wie wichtig er war“, und machte sich bereit zu gehen.

Watson ging an der Tür auf ihn zu, sah ihm in die Augen und gab den Umschlag mit den Worten zurück: „Wie kann ich dich gehen lassen?“ Ich habe gerade eine Million Dollar in Ihre Ausbildung investiert.

Ich habe ein T-Shirt mit der Aufschrift: „Wenn man wirklich aus Fehlern lernt, bin ich schon ein Meister.“ Wenn es um Fehler geht, bin ich tatsächlich ein Doktor der Naturwissenschaften.

Erster Platz: App Inventor API

Wirklich schreckliche Fehler betreffen eine große Anzahl von Benutzern, werden öffentlich bekannt, erfordern lange Zeit zur Korrektur und werden von denen gemacht, die sie nicht hätten machen können. Mein größter Fehler erfüllt alle diese Kriterien.

Je schlimmer desto besser

Ich habe gelesen Essay von Richard Gabriel Als Doktorand habe ich in den Neunzigerjahren über diesen Ansatz gesprochen, und er gefällt mir so gut, dass ich ihn meinen Studenten frage. Wenn Sie sich nicht gut daran erinnern, aktualisieren Sie Ihr Gedächtnis, es ist klein. Dieser Aufsatz stellt den Wunsch, „es richtig zu machen“, und den „Schlimmer ist besser“-Ansatz in vielerlei Hinsicht, einschließlich der Einfachheit, gegenüber.

Wie es sein sollte: Das Design sollte in der Implementierung und Schnittstelle einfach sein. Die Einfachheit der Schnittstelle ist wichtiger als die Einfachheit der Implementierung.

Je schlechter, desto besser: Das Design sollte in der Implementierung und Schnittstelle einfach sein. Die Einfachheit der Implementierung ist wichtiger als die Einfachheit der Schnittstelle.

Vergessen wir das für einen Moment. Leider habe ich es viele Jahre lang vergessen.

App Inventor

Während meiner Arbeit bei Google war ich Teil des Teams App Inventor, eine Drag-and-Drop-Online-Entwicklungsumgebung für angehende Android-Entwickler. Es war 2009 und wir hatten es eilig, die Alpha-Version rechtzeitig zu veröffentlichen, damit wir im Sommer Meisterkurse für Lehrer abhalten konnten, die die Umgebung beim Unterrichten im Herbst nutzen konnten. Ich habe mich freiwillig gemeldet, um Sprites zu implementieren, aus nostalgischer Erinnerung daran, wie ich früher Spiele auf dem TI-99/4 geschrieben habe. Für diejenigen, die es nicht wissen: Ein Sprite ist ein zweidimensionales grafisches Objekt, das sich bewegen und mit anderen Softwareelementen interagieren kann. Beispiele für Sprites sind Raumschiffe, Asteroiden, Murmeln und Schläger.

Wir haben den objektorientierten App Inventor in Java implementiert, daher gibt es dort nur eine Menge Objekte. Da sich Bälle und Sprites sehr ähnlich verhalten, habe ich eine abstrakte Sprite-Klasse mit den Eigenschaften (Feldern) X, Y, Speed ​​(Geschwindigkeit) und Heading (Richtung) erstellt. Sie verfügten über die gleichen Methoden zur Erkennung von Kollisionen, Abprallen vom Bildschirmrand usw.

Der Hauptunterschied zwischen einem Ball und einem Sprite besteht darin, was genau gezeichnet wird – ein gefüllter Kreis oder ein Raster. Da ich zuerst Sprites implementiert habe, war es logisch, die X- und Y-Koordinaten der oberen linken Ecke anzugeben, in der sich das Bild befand.

Die peinlichsten Fehler in meiner Programmierkarriere (bisher)
Nachdem die Sprites funktionierten, beschloss ich, dass ich Ballobjekte mit sehr wenig Code implementieren konnte. Das einzige Problem bestand darin, dass ich den einfachsten Weg gewählt habe (aus Sicht des Implementierers), indem ich die x- und y-Koordinaten der oberen linken Ecke der Kontur angegeben habe, die den Ball umrahmt.

Die peinlichsten Fehler in meiner Programmierkarriere (bisher)
Tatsächlich war es notwendig, die x- und y-Koordinaten des Mittelpunkts des Kreises anzugeben, wie es in jedem Mathematiklehrbuch und jeder anderen Quelle gelehrt wird, in der Kreise erwähnt werden.

Die peinlichsten Fehler in meiner Programmierkarriere (bisher)
Im Gegensatz zu meinen früheren Fehlern betraf dieser Fehler nicht nur meine Kollegen, sondern auch Millionen von App Inventor-Benutzern. Viele von ihnen waren Kinder oder völlig neu im Programmieren. Sie mussten bei jeder Anwendung, in der der Ball vorhanden war, viele unnötige Schritte durchführen. Wenn ich mich mit Lachen an meine anderen Fehler erinnere, dann bringt mich dieser noch heute zum Schwitzen.

Ich habe diesen Fehler erst vor Kurzem, zehn Jahre später, endlich behoben. „Gepatcht“, nicht „behoben“, denn wie Joshua Bloch sagt, sind APIs ewig. Da wir keine Änderungen vornehmen konnten, die sich auf bestehende Programme auswirken würden, haben wir die Eigenschaft OriginAtCenter mit dem Wert „false“ in alten Programmen und „true“ in allen zukünftigen Programmen hinzugefügt. Benutzer stellen möglicherweise eine logische Frage: Wer hat überhaupt daran gedacht, den Startpunkt irgendwo anders als in der Mitte zu platzieren? An wen? An einen Programmierer, der vor zehn Jahren zu faul war, eine normale API zu erstellen.

gewonnene Erkenntnisse

Wenn Sie an APIs arbeiten (was fast jeder Programmierer manchmal tun muss), sollten Sie die besten Ratschläge in Joshua Blochs Video befolgen.Wie man eine gute API erstellt und warum sie so wichtig ist"Oder in dieser kurzen Liste:

  • Eine API kann Ihnen sowohl großen Nutzen als auch großen Schaden bringen.. Eine gute API schafft Stammkunden. Der Böse wird zu deinem ewigen Albtraum.
  • Öffentliche APIs halten wie Diamanten ewig. Geben Sie alles: Es wird nie wieder eine Chance geben, alles richtig zu machen.
  • API-Umrisse sollten kurz sein – eine Seite mit Klassen- und Methodensignaturen und -beschreibungen, die nicht mehr als eine Zeile einnimmt. Auf diese Weise können Sie die API problemlos umstrukturieren, wenn sie beim ersten Mal nicht perfekt funktioniert.
  • Beschreiben Sie Anwendungsfällebevor Sie die API implementieren oder überhaupt an ihrer Spezifikation arbeiten. Auf diese Weise vermeiden Sie die Implementierung und Spezifikation einer völlig funktionslosen API.

Hätte ich auch nur eine kurze Zusammenfassung mit einem künstlichen Skript geschrieben, hätte ich den Fehler höchstwahrscheinlich erkannt und korrigiert. Wenn nicht, dann würde es auf jeden Fall einer meiner Kollegen tun. Jede Entscheidung, die weitreichende Folgen hat, muss mindestens einen Tag lang überlegt werden (dies gilt nicht nur für die Programmierung).

Der Titel von Richard Gabriels Essay „Schlimmer ist besser“ bezieht sich auf den Vorteil, der es hat, als Erster auf den Markt zu kommen – selbst mit einem unvollkommenen Produkt –, während jemand anderes eine Ewigkeit damit verbringt, nach dem perfekten Produkt zu suchen. Wenn ich über den Sprite-Code nachdenke, wird mir klar, dass ich nicht einmal mehr Code schreiben musste, um es richtig zu machen. Was auch immer man sagen mag, ich habe mich völlig geirrt.

Abschluss

Programmierer machen jeden Tag Fehler, egal ob sie fehlerhaften Code schreiben oder nicht etwas ausprobieren wollen, das ihre Fähigkeiten und Produktivität verbessert. Natürlich kann man Programmierer werden, ohne so schwerwiegende Fehler zu machen wie ich. Aber es ist unmöglich, ein guter Programmierer zu werden, ohne seine Fehler zu erkennen und daraus zu lernen.

Ich treffe ständig auf Studierende, die das Gefühl haben, dass sie zu viele Fehler machen und daher nicht für das Programmieren geeignet sind. Ich weiß, wie häufig das Hochstapler-Syndrom in der IT vorkommt. Ich hoffe, Sie lernen die Lektionen, die ich aufgelistet habe – aber denken Sie an die wichtigste: Jeder von uns macht Fehler – peinlich, lustig, schrecklich. Ich werde überrascht und verärgert sein, wenn ich in Zukunft nicht mehr genug Material habe, um den Artikel fortzusetzen.

Source: habr.com

Kommentar hinzufügen