Suche
Programmieren mit gesundem Menschenverstand

10 Tipps: So werden Sie zum richtig guten Programmierer

Lukas Eder
© Shutterstock / studiostoks

Talent ist wichtig, gesunder Menschenverstand ist noch wichtiger, um zu einem guten Programmierer zu werden. Java Champion Lukas Eder teilt in diesem Artikel seine besten Tipps für richtig gute Programmierer mit uns.

Dieser Artikel wurde zuerst auf jooq.org veröffentlicht, einem Blog, das sich mit allen Fragen rund um Open Source, Java and Software-Entwicklung aus der Perspektive von jOOQ befasst.

Ich wurde kürzlich in einem Interview gefragt, wie man meiner Meinung nach zu einem richtig guten Programmierer wird. Das ist eine interessante Frage und ich glaube, dass wir alle super Entwickler werden können, unabhängig vom Talent. Dafür müssen wir nur ein paar Regeln befolgen, die sich aber –das glaube ich zumindest – eigentlich aus dem gesunden Menschenverstand ergeben. Tatsächlich ist es sogar so, dass manche dieser Regeln nicht nur für Programmierer wichtig sind, sondern für jeden Profi.

Nicht alles in dieser Liste ist absolut ernst gemeint; manches gibt nur meine Meinung wieder, die niemand teilen muss. Und nicht alle Beschreibungen der Persönlichkeiten von Programmierern entsprechen vollständig den Situationen, die mir im realen Leben begegnet sind. Im Zweifel also bitte nicht angegriffen fühlen – Dich meine ich ja gar nicht 🙂

Los geht’s:

1. Gute Fragen stellen

Im Wesentlichen gibt es die folgenden Typen von Programmierern, wenn es darum geht, Fragen zu stellen:

  • Der Perfektionist. Vor allem wenn er eine Frage zu einem Open Source Tool stellt, hat der Perfektionist sich zuvor bereits einmal quer durch den Code debugged und die wahre Ursache seines Problems identifiziert. Selbst wenn er das nicht getan hat, schreibt der Perfektionist aber mit Sicherheit eine Einführung zum Problem, benennt die Schritte, die man zur Reproduktion braucht und schlägt tendenziell ein Workaround vor. Möglicherweise, wie schon gesagt, macht er noch einen Vorschlag zur Lösung. Der Perfektionist hat tatsächlich keine Fragen. Nur Antworten.
  • Die Quasselstrippe: Dieser Mensch stellt nicht wirklich Fragen; eigentlich sortiert er seine Gedanken nur öffentlich und fügt gelegentlich hier oder da ein rhetorisches Fragezeichen ein. Was wie eine Frage wirkt, ist eigentlich nur eine Reihe von Gedanken. Wenn man mit der Antwort wartet, findet die Quasselstrippe sie entweder von selbst oder stellt die eigentliche Frage dann in E-Mail 37. Oder auch nicht. Oder vielleicht doch, wenn wir es mal so versuchen. Und weißt du was? Es hat sich herausgestellt, dass die Anforderung total falsch war, das habe ich jetzt anders gelöst. Oh, ach ja, die Bibliotheken habe ich komplett geändert. Hehe. Keine Fragen mehr.
  • Der Drückeberger: Hier ist der Code. Was stimmt damit nicht? Halp plz!
  • Der Manager: Für diesen Typus von Entwickler ist Zeit Geld. Die Frage muss kurz sein, die Antwort ASAP gegeben werden. In diesem Ansatz steckt eine gewisse Ironie, da durch die besonders kurz formulierte Frage (sprich: unvollständig, nicht präzise) meist eine Reihe wichtiger Details fehlen, was Nachfragen nach sich zieht. Der Manager, natürlich enttäuscht davon, dass die Reaktion keine Antwort enthält, sondern eine neue Frage, schreibt nun allerdings eine weitere kurze Nachricht und verlangt noch dringlicher nach einer Antwort. Das kann dann durchaus eine Weile so hin und her gehen. Am Ende können schon ein bis zwei Wochen vergehen, bis die eigentliche Antwort endlich da ist.
  • Der Kläger: Er stellt keine Fragen. Er beschwert sich. Bis die Frage verschwindet. Vielleicht. Und wenn nicht? Umso besser – mehr Gründe, um sich zu beschweren!

Inzwischen sollte wohl klar sein, dass eine gut vorbereitete Frage (präzise, einfach, kurz, aber mit genug Details) zu deutlich besseren Antworten führt. Wenn man genau weiß, was man durch eine Frage lernen möchte, stehen die Chancen gut, dass man genau das auch bekommt.

Lesen Sie auch: 10 SQL-Tricks, die du nicht für möglich gehalten hättest

2. Keine Fragen stellen

Eigentlich ist es meistens aber besser zu versuchen, gar nicht erst eine Frage zu stellen. Vielleicht kriegt man die Antwort ja auch alleine raus? Natürlich nicht immer; manches kann man einfach nicht wissen. Einen Experten für das Gebiet zu fragen, ist dann der schnellste und effizienteste Weg zum Erfolg. Oft hat es aber Vorteile, etwas selbst herauszufinden:

  • Man lernt es auf die harte Tour. Dadurch bleibt es besser im Gedächtnis – wir erinnern uns an das, was wir gelernt haben
  • Es fühlt sich besser an, Dinge selbst herauszufinden
  • Man verursacht keinen „Lärm“. Erinnert ihr euch an die Quasselstrippe? Wenn der Befragte wenig Erfahrung damit hat, Fragen zu beantworten (und somit nicht weiß, dass er seine Antwort nicht sofort geben sollte),  könnte er jede unvollständige Teilfrage einzeln beantworten wollen. Er erkennt den Gedankengang dahinter einfach nicht. Das hilft keinem.
  • Durch das Aufschieben einer Frage (zumindest für eine gewisse Zeit) kann man mehr relevante Informationen sammeln, die man dann an denjenigen weitergibt, der die Frage beantworten soll. Man denke an den Perfektionisten. Erst die Details herausfinden, dann Fragen stellen.
  • Wenn man sich darin übt, gute Fragen zu stellen, wird man auch besser darin. Aber dafür muss man sich etwas mehr Zeit nehmen.

3. Keine Scherben hinterlassen

Auf Reddit gab es kürzlich einen spannenden Artikel dazu, dass man keine Scherben zurücklassen sollte. Im Kern geht es darum, nicht die Qualität auf Spiel zu setzen und zum Drückeberger zu werden. Einfach nie… die Scherben ignorieren sollte. Hier ist ein Zitat aus dem Artikel:

When we take certain shortcuts to deliver something in the shortest period of time, and our code reflects how careless we’ve been, developers coming after us (from the same team, a future team, and even ourselves!), will reach an important conclusion: it’s not important to pay enough attention to the code we produce. Little by little our application will start deteriorating in what it becomes an unstoppable process.

Dabei geht es gar nicht darum, zum Perfektionisten zu werden. Manchmal kann (oder muss) eine Reparatur natürlich verschoben werden; oft ist es aber doch so, dass wir uns selbst in Situationen bringen, mit denen niemand glücklich ist, wenn wir Scherben verursachen und nicht aufkehren. Wir Programmierer sind unzufrieden, unsere Kunden, die User und der Projektmanager. Das alles ist aber eine Sache der Einstellung und bildet somit den Kern der Professionalität. Wie schon Benjamin Franklin sagte:

The bitterness of poor quality remains long after the sweetness of low price is forgotten

Egal, worum es geht: Das stimmt. Der „niedrige Preis“ ist in diesem Fall der schnelle Sieg, den wir durch eine schlampige Programmierung davontragen.

4. Auf deterministische Software abzielen

In einer idealen Welt wäre jede Software „deterministisch“. Wir alle wären funktionale Programmierer, würden pure Funktionen ohne Nebenwirkungen schreiben. Wie String.contains(). Egal, wie oft man den folgenden Code ausführt, die Ergebnisse bleiben immer gleich:

assertTrue("abcde".contains("bc"));

Erwartbare Resultate. Das Universum und all seine Zustände haben absolut keinen Einfluss auf diese Berechnung. Das ist deterministisch.

Das können wir auch in unseren eigenen Programmen machen, nicht nur in Standard-Bibliotheken. Wir können versuchen, so oft wie möglich deterministische Module ohne weitere Effekte zu schreiben. Dabei geht es nicht um die Frage, welche Technologien wir wählen, deterministische Programmierung kann in jeder Sprache realisiert werden! Selbst funktionale Sprachen haben diverse Tools, um ungewollte Effekte durch die Verwendung von raffinierteren Typensystemen zu vermeiden. Das von mir gezeigte Beispiel ist allerdings in Java – Objektorientierung erlaubt aber ebenfalls Determinismus. Verdammt, sogar prozedurale Sprachen wie PL/SQL erlauben Determinismus! Wenn Funktionen in einem Index genutzt werden sollen, ist es dort sogar eine Voraussetzung, dass sie deterministisch sind:

 CREATE INDEX upper_first_name ON customer (upper (first_name));
-- Deterministic function here: -----------^^^^^^^^^^^^^^^^^^

Das ist also auch wieder eine Frage der Disziplin. Eine Methode, eine Funktion oder ein Prozess, der unerwünschte Effekte hervorruft, fällt durchaus unter „Scherben“, die wir hinterlassen. Möglicherweise war es halt leichter, diese unerwünschten Effekte mit zu pflegen, in der Hoffnung, dass sie schon irgendwann entfernt werden. Diese Hoffnung basiert aber in der Regel auf einer Lüge. Den Preis zahlt man einfach nur später, wenn der nicht-deterministische Stil plötzlich zurückschlägt. Und das wird er.

5. Das Unerwartete erwarten

Der letzte Link ist entscheidend. Murphys Gesetz ist etwas, das wir Programmierer jederzeit im Kopf behalten müssen. Alles kann kaputt gehen und alles wird kaputt gehen. Meine Güte, als Software-Ingenieure wissen wir doch, dass das definitiv passieren wird! Unsere Welt ist halt nicht deterministisch, auch die geschäftlichen Anforderungen, die wir implementieren, sind es nicht. Wir können Tipp 4 (Determinismus) nur so lange befolgen, wie wir es tatsächlich können. Danach betreten wir unabänderlich die Welt des nicht-deterministischen (also die „echte Welt“), wo Dinge schief gehen werden. Stellt euch also drauf ein! Erwartete das Unerwartete! Trainiert euren inneren Pessimisten darauf, alle Arten von Dingen vorherzusehen.

Wie man pessimistischen Code prägnant schreibt, ist natürlich eine ganz andere Geschichte. Und wie man erkennt, was auf definitiv versagen wird (also Aufmerksamkeit braucht) und was nur versagen könnte (und somit keine Aufmerksamkeit braucht), lernt man nur durch Übung.

6. Kein Cargo Kult. Keine Dogmen befolgen. Immer situativ arbeiten.

Alles, was ihr gelernt habt, ist potentiell falsch. Auch (oder sogar ganz besonders das) was die großen Namen sagen. Hier ist ein nettes Zitat:

In unserem Beruf gibt es viel zu viel Scheinheiligkeit. Wir halten uns selbst für Mathematiker, denen nur die pursten, reinsten Ideen genügen und die immer richtig liegen.

Das ist falsch. Unser Berufszweig baut auf Mathematik auf, aber wer sich nicht gerade auf die irre Welt der Kategorientheorie oder der relationalen Algebra spezialisiert (und selbst dort bezweifele ich, dass alles „richtig“ ist), befindet man sich in der pragmatischen Welt der realen geschäftlichen Anforderungen. Und die ist, um mal ganz offen zu sein, weit weg von perfekt. Lasst uns mal einen Blick auf die beliebtesten Programmiersprachen da draußen werfen:

  • C
  • Java
  • SQL

Glaubt ihr wirklich, dass diese Sprachen überhaupt noch was mit Mathematik gemeinsam haben? Wenn ja, dann sollten wir mal über Schutzverletzungen, Generics in Java, oder die dreiwertige Logik in SQL sprechen. All diese Sprachen sind pragmatisch erstellte Plattformen mit einem coolen theoretischen Hintergrund; am Ende müssen sie aber vor allem ihre Arbeit machen.

Das gleiche trifft auf alles zu, was auf diesen Sprachen aufbaut. Libraries. Frameworks. Verdammt, sogar Architekturen. Design Patterns. Nichts ist richtig oder falsch. Das alles sind nur  Tools, die in einem bestimmten Kontext entstanden sind. Denkt über das Tool in diesem Kontext nach und glaubt nicht, dass dem Tool eine alleinstehende raison d’être zukommt. Wir machen hier keine Kunst um der Kunst Willen.

Also: Lehnt folgendes ab, wenn es nicht hinterfragt wird:

  • XML
  • JSON
  • Funktionale Programmierung
  • Objektorientierte Programmierung
  • Design Patterns
  • Microservices
  • Three Tier Architectures
  • DDD
  • TDD
  • Eigentlich sogar: *DD

All das sind nette Tools in bestimmten Kontexten, aber definitiv nicht in jeder Situation. Indem man neugierig bleibt und über den Tellerrand hinaus denkt, wird man zu einem besseren Programmierer und weiß, welche Tools wann die beste Wahl sind.

7. Mach es einfach!

Es ist wahr: Es gibt Koryphäen, die alle anderen überflügeln.

Die meisten Entwickler sind aber einfach „gut“ oder haben das Potential dazu, „gut“ zu werden. Wie wird man also ein guter Programmierer? Indem man es macht. Großartige Software wurde nicht an einem einzelnen Tag geschrieben, und die bekannten Gesichter der Szene sind nicht die einzigen Helden unserer Zeit. Ich habe viele großartige Programmierer getroffen, die niemand kennt, weil sie sich im Privaten halten und Probleme kleiner Unternehmen genauso unsichtbar lösen.

Großartige Programmierer haben aber alle eine Sache gemeinsam: Sie machen es einfach. Sie üben. Sie arbeiten jeden Tag daran, besser und besser zu werden.

Willst du besser in SQL werden? Leg los! Versuch jeden Tag, ein SQL-Statement mit ein paar neuen Features zu schreiben. Nutze Window Functions. Grouping Sets. Recursion. Partitioned outer join. Die MODEL und/oder MATCH_RECOGNIZE Clauses. Das muss nicht immer gleich in die Produktion ausgeliefert werden; die Übung an sich ist den Aufwand bereits wert.

8. (Auf lange Sicht) Spezialisier dich!

Eigentlich gibt es da draußen nur ein paar wenige „gute“ Full-Stack-Entwickler. Die meisten Full-Stack-Entwickler sind eher Durchschnitt bei allem was sie tun. Klar, in einem kleinen Team reichen ein paar solcher Entwickler aus, um viele Fachbereiche abzudecken und schnell ein Stück neuer Software zusammen zu schustern. Dann ist allerdings alles irgendwie schludrig umgesetzt und funktioniert nur „irgendwie schon“. Das ist vielleicht gut solange es um ein Minimum Viable Product geht; auf lange Sicht wird genau das aber zu komplexeren Problemen führen. Und ein Full-Stack-Entwickler hat dann nicht die Zeit, um diese Probleme richtig zu analysieren (oder sie sogar vorauszusehen!).

Stattdessen sollte man sich primär auf eine Nische konzentrieren und richtig gut auf diesem Gebiet werden. Spezialisten werden immer gefragt sein, solange ihre spezifische Nische existiert und viele Nischen werden länger leben als wir (hallo, COBOL oder SQL!). Also, tut eurer Karriere einen Gefallen und macht irgendetwas wirklich gut, statt alles nur „ganz okay“ zu können.

9. Spielt!

Sich auf eine Sache zu konzentrieren, heißt nun aber auch nicht, dass man alles andere ganz vergessen kann. Man wird wohl nie richtig, richtig, richtig gut in allen Aspekten von SQL, Hochskalierung, Runterskalierung, Low Level Performance Tuning, CSS (wer ist darin überhaupt richtig gut!?), Objektorientierung, Requirements-Engineering, Architektur und allem anderen auf einmal sein (siehe Punkt 8). Das ist unmöglich.

Man sollte allerdings schon die Grundlagen von all dem verstehen. Wissen, wann SQL die richtige Wahl ist (und wann nicht). Wann ein Low Level Performance Tuning angebracht ist (und wann nicht). Wie CSS prinzipiell funktioniert. Die Vorteile der Objektorientierung und von FP verstehen und so weiter.

Du solltest etwas Zeit damit verbringen mit all diesen Konzepten und Technologien (und vielen anderen) zu spielen um ein Gefühl dafür zu kriegen, warum sie wichtig sind und wann man das jeweils benutzt. Und dann suchst du dir die Experten, die die eigentliche Arbeit machen.

Indem man mit neuen Paradigmen und Technologien herumspielt, öffnet man sich gleichzeitig auch für völlig andere Arten des Denkens. Und das ist im Arbeitsalltag doch auf die eine oder andere Weise nützlich.

10. Keep it simple, stupid

Albert Einstein hat folgendes gesagt:

Man muss die Dinge so einfach wie möglich machen. Aber nicht einfacher.

Niemand kann immense Komplexität handhaben. Nicht auf dem Gebiet der Software, nicht in irgendeinem anderen Lebensbereich. Komplexität tötet gute Software; Einfachheit ermöglicht sie also. Leicht zu verstehen – schwer zu implementieren. Einfachheit ist etwas, das viel Zeit und Erfahrung braucht, bis man sie erkennt und so programmieren kann. Allerdings gibt es natürlich auch diverse Regeln, die man befolgen kann.

Eine der einfachsten Regeln lautet, dass Methoden/Funktionen nur wenige Parameter haben sollten. Werfen wir einmal einen Blick darauf: Die zuvor benannte String.contains() Methode entspricht dem definitiv. "abcde".contains("bcd") ist verständlich, ohne dafür irgendeine Form von Dokumentation zu lesen; jeder wird sofort verstehen, was die Methode macht und warum. Die Methode tut eine Sache und nur diese, es gibt keine komplizierten Kontexte/Settings oder anderen Argumente, die an die Methode übergeben werden können. Es gibt keine „Sonderfälle“ und kein Kleingedrucktes.

Hier gilt erneut, dass Einfachheit leichter in einer Library zu erreichen ist als in einer Geschäftslogik. Können wir das also hinkriegen? Vielleicht. Durch Übung. Und Refactorings. Genau wie großartige Software wird aber auch Einfachheit nicht an einem einzigen Tag erreicht.

(Protipp: Hier gilt Conways Law. Es ist vollkommen unmöglich, gute, einfache Software in einer Umgebung zu schreiben, in der die geschäftliche Seite super komplex ist. Entweder man mag Komplexität und hässliche Legacys oder man macht sich besser aus dem Staub.)

Lesen Sie auch:

Top 10 der nützlichen, aber paranoiden Java-Programmiertechniken

Geschrieben von
Lukas Eder
Lukas Eder
Lukas Eder ist leidenschaftlicher Java- und SQL-Entwickler. Er ist Gründer und Leiter der Forschungs- und Entwicklungsabteilung der Data Geekery GmbH, dem Unternehmen hinter jOOQ - die einfachste Art, um SQL in Java zu schreiben.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.