Archiv der Kategorie: Programmieren

Photo by Alexandru Acea on Unsplash

Was ich in 101 Stunden programmieren gelernt habe

Zu Beginn des Jahres 2018 habe ich mir vorgenommen einen neuen Hardskill zu lernen. Die Gründe dafür waren zahlreich, aber vor allem wollte ich wieder etwas machen in das man sich über längere Zeit richtig vertiefen kann. Ich wollte wieder dieses Gefühl haben, etwas zu lernen was wirklich schwierig ist und lange Zeit braucht um gelernt zu werden, aber auch das gute Gefühl, welches man hat, wenn man diese Fähigkeit zum Einsatz bringt und damit etwas produziert, etwas macht.

Die ersten drei Monate vergingen natürlich wie im Flug, ohne dass ich auch nur einen weiteren Gedanken daran verschwendet hätte. Gut, dass ich mir solche Dinge aufschreibe und regelmäßig zu Gemüte führe (wer schreibt, der bleibt). Ende März habe ich mich dann nach etwas Überlegung dazu entschieden wieder mit dem Programmieren anzufangen. Wieso wieder und wieso gerade Programmieren? Als ich noch in der Schule war, habe ich mich eine kurze Zeit damit beschäftigt und bereits ein paar kleine „Progrämmchen“ geschrieben. Nachdem meine Entscheidung dann gegen das Informatik Studium fiel, habe ich die Sache wieder fallen gelassen, was ich seither bereits einige male bereut habe. Die Faszination über das Coding hat mich nie so wirklich losgelassen und nachdem ich eher zufällig auf den Blog von Paul Graham (www.paulgraham.com) gestoßen bin, war ich wieder Feuer und Flamme dafür [1].

Vor ein paar Tagen habe ich die 100 Stunden Marke geknackt. Insgesamt habe ich jetzt an 52 Tagen programmiert und mich in Summe ca. 101 Stunden damit beschäftigt. Ich dachte mir es könnte sich lohnen zusammen zu fassen, was ich bisher auf dieser interessanten Reise gelernt habe.

Ohne weitere Umschweife hier also meine „lessons learned“, in keiner besonderen Reihenfolge:

Probleme lösen:

Eine Problemstellung herunter zu brechen in viele kleinst mögliche Probleme und diese dann Schritt für Schritt zu lösen. Oft schaut man auf eine Aufgabe oder ein Problem und ist zunächst überwältigt. Man weiß gar nicht so recht wo oder wie man anfangen soll. Programmieren hat eigentlich weniger damit zu tun irgendeinen Code einzuhacken, sondern ein Problem in viele kleinst mögliche Teilstücke herunter zu brechen, diese zu lösen und in eine formalisierte Sprache zu überführen damit der „dumme“ Computer auch versteht, was man von ihm eigentlich will, solange bis das große Hauptproblem gelöst ist. Programmieren hat mich auch wieder daran erinnert, dass diese Vorgehensweise auf ganz „normale“ Probleme im Alltag zutrifft. Man kann jedes Problem in eine Untermenge von Teilproblemen unterteilen und diese separat lösen. Schritt für Schritt.

Geduld:

Wenn man in seine alten Denkmuster verfällt („Wieso funktioniert das nicht?“), sich aktiv „zurücknehmen“ und dazu zwingen logisch Schritt für Schritt den Quellcode zu analysieren. Ich merke wie ich oft „faul“ werde und mir denke: „Das könnte so ungefähr funktionieren. Wird schon passen“ ohne es wirklich durchzudenken. Das rächt sich immer. Wenn man sein Programm nicht mit ausreichender Präzision im Kopf halten kann und genau weiß was das Programm wann macht, wird es unweigerlich zu einem „Bug“ kommen.

Langsam Denken:

„Langsames“ Denken [2] liegt mir und es ist absolut nicht schlimm, wenn man das Bedürfnis hat mehr über ein bestimmtes Konzept oder Programmierparadigma herauszufinden und sich auch dafür die Zeit nimmt. Man muss sich aktiv zwingen einen Gang runter zu schalten und langsam zu denken, denn oft ist man geneigt bestimmte Konzepte einfach schnell überfliegen zu wollen. Das sollte man nicht machen. Außerdem bedeutet langsames Denken auch, dass wenn man auf ein Konzept stößt, dieses gleich aus mehreren Perspektiven betrachtet, sich immer weiter hinunter in den Kaninchenbau begibt und mehr zu diesem Thema und dessen Hintergrund herausfindet. Natürlich muss man auch aufpassen, dass man sich in dem Kaninchenbau verirrt, irgendwann muss man auch wieder zurück zum Ausgangspunkt finden.

Freude über das Einfache:

Die unerwartete Freude ein auf den ersten Blick simples Konzept zu recherchieren und über seine Schönheit und Ästhetik zu staunen. Manchmal sind es die einfachen Dinge im Leben, die einen am meisten erfreuen und sich diese Fähigkeit mit steigendem Alter zu bewahren ist schwierig aber auch essentiell für ein erfülltes Leben.

Loslassen vom Perfektionismus:

Beim Programmieren gibt es immer mehrere Lösungen die zum Erfolg führen. Es gibt die komplizierte Lösung, die schnelle Lösung, die einfache Lösung und die elegante Lösung. Als Anfänger fällt man automatisch irgendwo zwischen die einfache und die komplizierte Lösung, da man noch nicht alle Funktionen und Arten der Lösung (oder auch Denkparadigmen) kennt (= einfach), formuliert man eine Lösung die unter Umständen sehr klobig und umständlich ist (=kompliziert). Das wichtigste am Anfang ist aber, dass man das Problem überhaupt löst und a) zu einem funktionierenden Programm kommt und b) versteht wieso das Programm genau das tut was es tun soll [3]. Erst danach kann man sich damit beschäftigen das Programm eleganter (= kleiner und schneller) zu machen.

Sich sauber und klar ausdrücken:

Beim Programmieren ist es wichtig den Code so zu schreiben, dass ein Mensch ihn möglichst leicht lesen und verstehen kann. Dem Computer (bzw. Compiler) ist es z.B. egal wie man seine Variablen benennt, aber wenn andere das Programm möglichst schnell begreifen können sollen, dann muss man sich klar und deutlich ausdrücken. Dieser andere Mensch kann man auch selbst zu einem späteren Zeitpunkt sein. Nichts ist schlimmer als nach ein paar Wochen nicht mehr zu wissen was man mit einer bestimmten Funktion in einem Programm machen wollte, weil man „quick and dirty“ Code geschrieben hat. Diese Lektion hat mich daran erinnert, dass dies auch für allgemeine Kommunikation gilt, egal ob schriftlich oder mündlich. Sich sauber, klar und präzise ausdrücken zu können ist ein essentieller Skill.

Programmieren ist letztlich auch eine Art der Kommunikation. Ich sehe es als eine Kommunikation auf drei Ebenen.

1.) Mit der Maschine

2.) mit anderen Programmierern

3.) mit dem Anwender

Dabei ist Punkt 3.) der wichtigste. Schließlich ist Programmieren ein Werkzeug um Probleme von Menschen (=Anwendern) zu lösen.

Mathematik , Algorithmen und Programmiersprachen besitzen die gleiche Schönheit und Eleganz wie Kunst:

Wenn ich mir Code von erfahrenen Programmierern anschaue, dann kann ich nicht anders, als über die Eleganz und Schönheit zu staunen. Es ist vergleichbar mit der  Erfahrung sich ein Kunstobjekt oder ein gut designtes Produkt anzuschauen, was in einem eine Resonanz auslöst und zu welchem man sich hingezogen fühlt. Natur- und Computerwissenschaften sind mindestens genauso schön und ästhetisch wie Kunst, Design und Geisteswissenschaften. Da Programmieren zum größten Teil aus dem Lesen von Code besteht, lernt man eleganten Code sehr zu schätzen. Schließlich schaue ich mir auch lieber den ganzen Tag das hier an:

anstatt diese Ausgeburt an Hässlichkeit:

Ehrlich, ich bin davon überzeugt, dass man Augenkrebs bekommen kann wenn man zu lange auf sowas schaut.

Sich auf fremden Code einlassen:

Gerade hatte ich erwähnt, dass programmieren zum Großteil aus dem Lesen von Code besteht. In diesem Zusammenhang ist es extrem wichtig sich auch wirklich auf den Code und damit auf die Denkweise von anderen Leuten einzulassen. Am Anfang ist es so, dass man beim Erstkontakt mit fremden Code denkt: „Hä? Was soll das denn? Wieso macht er das denn so? Das ist doch viel zu kompliziert?“ oder man versteht nicht sofort was der Code soll (siehe auch nächster Punkt) und verfällt in seine eigenen Denkmuster und Problemlösungstechniken. Man kann neue Arten Probleme zu lösen und seinen Werkzeugkasten zu erweitern nur dadurch erlernen, dass man offen gegenüber fremden Code ist, sich voll auf diesen einlässt und ihm eine „faire“ Chance gibt. Dies trifft im Übrigen auch auf andere Lebensbereiche zu. Es ist von Vorteil sich auf die Denkweise seines Gegenübers einzulassen und unvoreingenommen zu versuchen seine Sicht der Dinge nachzuvollziehen. Das erweitert den eigenen Horizont.

Mehr durch weniger:

Die Eleganz und Schönheit liegt meistens darin, Dinge weg zu lassen, zu vereinfachen und zu kürzen, gleichzeitig aber die Lesbarkeit und Verständlichkeit für den menschlichen Leser zu bewahren. Es gibt einen „sweet spot“ zwischen Kürze und Lesbarkeit. Es gibt Möglichkeiten mit denen man ganze Funktionen in eine Zeile schreiben kann. Das Problem dabei: sowas versteht kein Mensch mehr. Wenn man dann nicht exzessiv kommentiert um die Funktion in aller Fülle zu beschreiben ist das ein verlorener Fall, sollte sich jemals jemand den Code zu Gemüte führen. Das wäre über das Ziel hinausgeschossen. Ich bin ein Fan von sich selbst beschreibendem Code geworden, mit so wenig Kommentaren wie möglich. Der Code sollte so klar strukturiert und lesbar sein, dass er sich selbst erklärt, aber eben nicht zu aufgeblasen. Der Informatiker Hoare sagte folgendes: „There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.“

Die Freude ein Problem zu lösen:

Die unglaublichen Glücksgefühle die einem beschert werden, wenn man ein relativ schwieriges Problem selbst gelöst hat und das Programm tatsächlich das tut was es tun soll (Stichwort Semantik). Im alltäglichen Arbeitsleben kann man sich glücklich schätzen, wenn man dieses Gefühl sporadisch erleben darf. Deshalb ist es gerade am Anfang wie ein Rausch, wenn man sieht wie die eigenen Programme nach stundenlangem „basteln“ genau das tun, was sie tun sollen. Ein Gefühl, welches man danach nicht mehr missen will.

Der „Kampf“ mit dem Schwierigen ist lohnenswert:

Die Schinderei und das Ringen mit einem schwierigen Problem ist auf mehreren Ebenen lohnenswert. Man lernt sich zu fokussieren, es gibt einem Selbstvertrauen, es nährt einen mental, es gibt einem eine neue bzw. andere Perspektive. Es ist nicht leicht sich durch ein kniffliges Problem durchzubeißen. Wenn man es aber schafft zu lernen sich durchzubeißen und am anderen Ende als Sieger herauskommt, sind die Vorteile gegen nichts aufzuwiegen. Man wird um so vieles bereichert.

Und das ist erst der Anfang…

Anmerkungen:

[1] Paul Graham ist der Gründer von Viaweb und Y Combinator. Viaweb war einer der allerersten Web-basierten Shopsysteme im Internet, mit dem die Benutzer sich einen eigenen Onlineshop erstellen und konfigurieren konnten. Die Firma hat er zusammen mit einem Freund gegründet und 1998 an Yahoo! für ca. 50 Millionen US-$ verkauft. Anschließend gründete er mit dem gleichen Freund und seiner Frau im Jahr 2005 Y Combinator, was ein sogenannter „seed accelerator“ für Startups ist. Es werden kleinere Summen Geld, Unterstützung und Beratung im Anfangsstadium für vielversprechende Startups geleistet. Firmen die von Y Combinator „gepusht“ wurden sind u.a. AirBnB, Dropbox, Stripe, Reddit u.v.m. Der geschätzte Wert von Y Combinator liegt irgendwo zwischen 500 Millionen und 1 Milliarde US-$.

[2] Zu diesem Thema siehe auch das absolut fabelhafte, augenöffnende Buch von Daniel Kahnemann „Schnelles Denken, langsames Denken“.

[3] Ein Programm zum Funktionieren zu bringen besteht darin es syntaktisch und semantisch korrekt aufzubauen. Syntax bedeutet, dass man es in der jeweiligen Programmiersprache korrekt formalisiert, so dass es vom Compiler verstanden und korrekt in Maschinensprache übersetzt werden kann. Korrekte Semantik bedeutet, dass das Programm auch genau das tut, was man von ihm will. Man kann zwar ein auf den ersten Blick korrekt laufendes Programm haben, in dem Sinne dass es ohne Fehler ausgeführt wird, aber das bedeutet noch nicht, dass es auch logisch korrekt ist.