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
Es war ein Albtraum. Viele Jahre später wurde mir gesagt, dass der Programmierer, der meinen Code geerbt hatte, mich hasste.
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.
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.
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
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
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
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.
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.
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.
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.
- 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