Blog

Lizenz des Textes: CC BY-SA 3.0
CC-BY-SA-Logo

Was macht einen guten Programmierer aus und wie wird man einer? Wie wichtig ist Mathematik?

Teilen

In diesem Artikel stelle ich vier Konzepte vor, die jeder gute Programmierer beherrschen sollte. Diese Konzepte sind auf alle höheren Programmiersprachen anwendbar. Für einen Programmierer ist es daher nicht so wichtig, wie viele Programmiersprachen er beherrscht.

Künstlerische Darstellung eines künstlichen neuronalen Netzes, welche im Bereich der künstlichen Intelligenz eine große Rolle spielen.
Künstlerische Darstellung eines künstlichen neuronalen Netzes, welche im Bereich der künstlichen Intelligenz eine große Rolle spielen.

Was macht einen guten Programmierer aus?

Immer wieder taucht die Frage auf, was einen guten Programmierer ausmacht und wie man einer wird? Der Markt und damit die Verdienstmöglichkeiten in der Technologiebranche sind unermesslich hoch. Im Jahr 2018 hat der Technologiesektor allein in Deutschland einen Umsatz von 231 Mrd. Euro erwirtschaftet, wobei der Bereich Software & Services zunehmend an Bedeutung gewinnt. Zum Vergleich: Die Ernährungsindustrie hat im Jahr 2018 „nur“ 179.6 Mrd. Euro umgesetzt. Dies lockt natürlich auch Coaches und Experten an, die Schulungen im Bereich der Programmierung anbieten. In letzter Zeit sehe ich allerdings vermehrt Schulungsangebote, die Ergebnisse versprechen, die völlig unrealistisch sind.

Nahaufnahme eines LED-Displays
Die gesellschaftliche Beduetung von Technologie ist mittlerweile enorm. Sie betrifft alle Bereiche unseres täglichen Lebens (→ Big Tech)

In den sozialen Medien wurden mir eine Zeit lang Werbung für verschiedene Programmierkurse angezeigt. Dort hieß es zum Beispiel: In 6 – 9 Monaten zum Full-Stack-Entwickler. Ein Full-Stack-Entwickler beherrscht mehrere Softwarekomponenten (Programmiersprachen, Entwicklungsumgebungen, Betriebssysteme etc.) sicher. Die Werbung ist natürlich sehr verführerisch, da man als Full-Stack-Entwickler ein relativ hohes Gehalt erwarten kann. Allerdings ist es nahezu unmöglich, in dieser kurzen Zeit ein Full-Stack-Entwickler zu werden. Dies wissen vor allem die Menschen im Unternehmen, die über eine Einstellung als Full-Stack-Entwickler entscheiden. Für Menschen, die in die Programmierung einsteigen möchten, ist es leider gar nicht so genau zu erkennen, wie der Einstieg oder die Weiterentwicklung im Bereich der Programmierung am besten erfolgt.

In diesem Artikel möchte ich vier Konzepte vorstellen, die meiner Meinung nach die wichtigsten Konzepte im Bereich der Programmierung sind. Außerdem möchte ich darauf eingehen, wie wichtig Mathematik in der Programmierung ist.

Konzepte, die ein guter Programmierer beherrschen sollte

Konzept der Objektorientierung

Das Konzept der Objektorientierung lernt man meist direkt beim Einstieg in die Programmierung kennen. Im Wesentlichen besteht die Objektorientierung aus Klassen, Vererbung und Polymorphie. Wenn man das Konzept der Objektorientierung verstanden hat, dann ist die nächste Hürde, die Objektorientierung auch praktisch anzuwenden. Hier können Entwickler dann ihre Kreativität ausleben und unter Beweis stellen.

#include <iostream>
 
int main()
{
  std::cout <<  "Hello World!" << std::endl;
  return 0;
}

Ein Hallo-Welt-Programm in der Programmiersprache C++. Einer der ersten im großen Umfang eingesetzte Programmiersprache, die das Konzept der Objektorientierung unterstützt.

Das Konzept der Objektorientierung wurde Mitte der 1980-er Jahre mit der Programmiersprache C++ populär und wurde seitdem in nahezu jeder modernen Programmiersprache umgesetzt. Dieser Sachverhalt verdeutlicht, wie wichtig das Konzept der Objektorientierung in der heutigen Programmierung ist. Mit diesem Konzept lässt sich Quellcode übersichtlicher schreiben, da viele Funktionen direkt in den Klassen implementiert werden (Datenkapselung). Mit der Datenkapselung, die im Rahmen der Objektorientierung einfacher umzusetzen ist, lassen sich Programme von vornherein schneller und mit weniger Fehlern umsetzen.

Historie der objektorientierten Programmiersprachen. Die objektorientierten Programmiersprachen sind über die Zeit immer stärker vertreten. (Stand der Grafik: 2008)
Historie der objektorientierten Programmiersprachen. Die objektorientierten Programmiersprachen sind über die Zeit immer stärker vertreten. (Stand der Grafik: 2008)

Konzept der Entwurfsmuster

Das Konzept der Entwurfsmuster ist eine Weiterentwicklung des Konzeptes der Objektorientierung. Entwurfsmuster beschreiben Lösungsstrategien für wiederkehrende Probleme bei der Programmierung. Sie beschreiben im Wesentlichen, wie man Klassen entwirft und zueinander in Beziehung setzt, um ein bestimmtes Problem zu lösen. Der entstehende Code ist dadurch für Entwickler leichter zu warten. Programmcode, der nach den Richtlinien von Entwurfsmustern konzipiert ist, lässt sich später leichter erweitern und hat in der Regel auch weniger Fehler.

XMLFileMgr*
XMLPlatformUtils::makeFileMgr(MemoryManager* const memmgr)
{
  XMLFileMgr* mgr = NULL;
  
  #if XERCES_USE_FILEMGR_POSIX
    mgr = new (memmgr) PosixFileMgr;
  #elif XERCES_USE_FILEMGR_WINDOWS
    mgr = new (memmgr) WindowsFileMgr;
  #else
    #error No File Manager configured for platform! You must configure it.
  #endif
  
  return mgr;
}

Beispiel der Implementierung der Fabrikmethode, einem Entwurfsmuster, mit dem man Objekte über eine Methode statt dem Konstruktor erzeugt. Hier wird eine Klasse, zum Manipulieren von Dateien, anhand des verwendeten Betriebssystems (Windows oder POSIX) erzeugt und zurückgegeben.

Ich habe oft Programme gesehen, die ohne ein Konzept aus Klassen und Entwurfsmustern konzipiert und umgesetzt worden sind und die meisten dieser Programme leiden an einem wesentlichen Problem. Wenn diese Programme weiterentwickelt werden, wird der Programmcode so umfangreich und unübersichtlich, dass Erweiterungen immer schwieriger umzusetzen sind. Dadurch entstehen vermehrt unerwartete Fehler, die dann den Wartungsaufwand der Software erhöhen. Außerdem leidet dann meist auch die Performance des Programms, da die Abhängigkeiten der Komponenten untereinander so groß geworden sind, dass sich diese nur noch schwer voneinander trennen lassen.

// Initialize the platform-specific mutex and file mgrs
  fgMutexMgr = makeMutexMgr(fgMemoryManager);
  fgFileMgr  = makeFileMgr(fgMemoryManager);

Aufruf der Fabrikmethode aus dem vorigen Beispiel. Der Quellcode wird dadurch sehr vereinfacht, da die Logik, welche Klasse zurückgegeben werden soll, in der Fabrikmethode implementiert ist.

Entwurfsmuster wurden durch das Buch Design Patterns: Elements of Reusable Object-Oriented Software einer breiteren Entwicklergemeinde bekannt und populär. Aufgrund des Erfolges der Entwurfsmuster im Bereich der Softwaretechnik wurden im Laufe der Zeit viele weitere Entwurfsmuster entwickelt und erfolgreich umgesetzt.

Konzept der Datenstrukturen

Das Konzept der Datenstrukturen umfasst ein Konzept zum Speichern von komplexen Daten auf der Grundlage von einfachen Daten. Die Programmiersprachen unterstützen in der Regel nur einfache Datentypen, wie zum Beispiel Booleans (wahr, falsch), Zahlen oder Zeichenketten. Diese einfachen Datentypen reichen in der Praxis nicht aus, um die verschiedenen Arten von Daten zu speichern. Mit dem Konzept der Datenstrukturen lassen sich komplexe Daten aus den einfachen Datentypen entwickeln.

<?php
$array = array(
    "Deutschland" => "de"
  , "Frankreich"  => "fr"
  , "Nepal"       => "np"
  , "Uruguay"     => "uy"
);

Ein assoziatives Datenfeld als Datenstruktur, welche jedem Wert (Land) einen entsprechenden Wert (Top-Level-Domain) zuordnet. Assoziative Arrays werden von einigen Programmiersprachen, wie zum Beispiel PHP, nativ unterstützt.

Die einfachsten Datenstrukturen haben eigenständige Namen, wie zum Beispiel Stapelspeicher (Stack), Liste oder Warteschlange und sind bereits sehr gut untersucht. In vielen Programmiersprachen existieren Programmbibliotheken, welche diese Datenstrukturen implementieren. In der Programmiersprache C++ ist dies etwa die Standard Template Library oder java.util in der Programmiersprache Java.

#include <glib.h>
int main(int argc, char** argv) {
 GSList* list = NULL;
 list = g_slist_append(list, "Eins");
 list = g_slist_append(list, "Zwei");
 list = g_slist_append(list, "Drei");
 printf("Die Liste hat %d Eintraege\n", g_slist_length(list));
 g_slist_free(list);
 return 0;
}

Beispiel einer Implementierung einer Liste in der nicht objektorientierten Programmiersprache C unter Zuhilfenahme der Bibliothek GLib.

Mit diesen einfachen Datenstrukturen lassen sich in der Praxis recht komplizierte Probleme lösen. So kann mithilfe der Datenstruktur des Stapelspeichers (Stacks) mathematische Ausdrücke, welche in der Regel als Zeichenkette vorliegen, unter Verwendung des Shunting-yard-Algorithmus ausgewertet werden. Viele der heutigen Compiler und Interpreter verwenden Varianten dieser Datenstrukturen, um Programmcode in Maschinensprache zu übersetzten oder die eingegebenen Anweisungen direkt auszuführen → Syntaxbaum.

Grafische Darstellung eines 3D-Objektes mithilfe von Triangulation. Datenstrukturen derart komplexer Objekte lassen sich aus einfacheren Datenstrukturen entwickeln.
Grafische Darstellung eines 3D-Objektes mithilfe von Triangulation. Datenstrukturen derart komplexer Objekte lassen sich aus einfacheren Datenstrukturen entwickeln.

Wenn man verstanden hat, wie man diese einfachen Datenstrukturen implementieren kann und wie diese funktionieren, so kann man fast jede beliebig komplexe Datenstruktur konzipieren und implementieren. Gerade bei technisch hochwertiger Software kommen komplexe Datenstrukturen zum Einsatz. Man denke nur daran Landkarten zu digitalisieren, um sie zum Beispiel in Navigationsgeräten zu nutzen. Ähnlich sieht es bei der Speicherung 3-dimensionaler Objekte aus, um diese zum Beispiel in einem 3D-Drucker auszudrucken.

Konzept der Architekturmuster

Eine Software besteht in der Regel aus vielen Klassen, Quelldateien, Daten und weiteren Programmbibliotheken. Je größer und umfangreicher die Software wird, desto schwieriger ist es, die einzelnen Komponenten der Software zu überblicken. Um die Arbeit mit umfangreicher Software möglichst einfach zu halten, ist es wichtig diese zu planen und die einzelnen Bestandteile geschickt und übersichtlich zu organisieren. Die Organisation der einzelnen Bestandteile einer Software nennt man Softwarearchitektur. Bestimmte Softwarearchitekturen haben sich dabei als besonders praktikabel herausgestellt. Diese Architekturen nennt man analog zu Entwurfsmustern Architekturmuster. Der Unterschied zwischen Entwurfsmustern und Architekturmustern besteht darin, dass Entwurfsmuster üblicherweise auf der Ebene von Klassen zu finden sind, während Architekturmuster auf der Ebene der Gesamtheit der Software (Klassen, Daten, Bibliotheken) zu finden sind.

Schematische Darstellung des Model View Controller Architekturmusters (MVC). Dieses Architekturmuster ist eines der einfachsten und bekanntesten.
Schematische Darstellung des Model View Controller Architekturmusters (MVC). Dieses Architekturmuster ist eines der einfachsten und bekanntesten.

Einer der bekanntesten Architekturmuster ist das Model View Controller Architekturmuster oft auch abgekürzt mit MVC. Wenn man anfängt zu programmieren, schreibt man Texte, Fehlermeldungen oder andere Daten direkt in den Quellcode hinein. Außerdem kommt es oft vor, dass man Quellcode mit einer ähnlichen Funktionalität mehrmals schreibt, was bei späteren Änderungen den Aufwand ins unermessliche steigen lässt. Das MVC legt nun fest, dass bestimmte Bestandteile einer Software strikt voneinander getrennt werden müssen. Beim MVC betrifft dies die Daten (Model), die Ansicht (View) und die Steuerung (Controller), die voneinander getrennt organisiert werden müssen.

Dadurch, dass in WordPress alle Daten in einer Datenbank hinterlegt sind, erleichtert dies auch den Zugriff und die Verwaltung dieser Daten. Mit dem Programm phpMyAdmin lassen sich solche Datenbanken komfortabel verwalten.
Dadurch, dass in WordPress alle Daten in einer Datenbank hinterlegt sind, erleichtert dies auch den Zugriff und die Verwaltung dieser Daten. Mit dem Programm phpMyAdmin lassen sich solche Datenbanken komfortabel verwalten.

Bekannte Beispiele von Programmen, die das MVC-Architekturmuster verwenden, sind WordPress einem Verwaltungssystem für Webseiten und MediaWiki das Verwaltungssystem der Wikipedia. Die Daten (Model), wie Bilder oder Texte, werden in einer Datenbank oder in einem bestimmten Ordner hinterlegt. Für das Aussehen (View) einer Webseite in WordPress ist ausschließlich das Theme zuständig und in MediaWiki das Skin, welche wiederum in einem separaten Ordner zu finden sind. Die Steuerung der Daten und der Ansicht erfolgt bei beiden Systemen über die Administrationsoberfläche, welche in diesem Fall die Rolle des Controllers einnimmt.

Für sehr große und umfangreiche Softwareprojekte werden komplett eigene Architekturen entwickelt, wie hier des Grafikstapels im Linux Kernel (→ Direct Rendering Infrastructure). Das Erstellen derartiger Softwarearchitekturen erfordert jahrelange Erfahrung in einem bestimmten Teilgebiet.
Für sehr große und umfangreiche Softwareprojekte werden komplett eigene Architekturen entwickelt, wie hier des Grafikstapels im Linux Kernel (→ Direct Rendering Infrastructure). Das Erstellen derartiger Softwarearchitekturen erfordert jahrelange Erfahrung in einem bestimmten Teilgebiet.

Warum sind diese Konzepte so wichtig?

Das Konzept der Entwurfsmuster erweitert das Konzept der Objektorientierung. Jede höhere Programmiersprache ist objektorientiert. Diese beiden Konzepte sind demnach auf jede moderne Programmiersprache anwendbar. Nahezu jede moderne Software wird auf Grundlage von Datenstrukturen und diesen beiden Konzepten entwickelt, sodass die verwendete Programmiersprache eine untergeordnete Rolle spielt. Dies ist einer der Gründe, warum es für einen Programmierer weniger wichtig ist möglichst viele Programmiersprachen zu beherrschen, sondern die oben beschriebenen Konzepte.

Der nicht ganz unumstrittene TIOBE-Index, ein Ranking von Programmiersprachen nach Popularität. Das Ranking wird anhand der Suchanfragen bei Suchmaschinen, die den Namen der Programmiersprache enthalten, ermittelt.
Der nicht ganz unumstrittene TIOBE-Index, ein Ranking von Programmiersprachen nach Popularität. Das Ranking wird anhand der Suchanfragen bei Suchmaschinen, die den Namen der Programmiersprache enthalten, ermittelt.

Zu den meisten höheren Programmiersprachen gibt es Bibliotheken, die die Funktionalitäten der einfachen Datenstrukturen zur Verfügung stellen. Das Konzept der Datenstruktur lässt sich somit ebenfalls recht einfach mit allen höheren Programmiersprachen nutzen. Größere Softwareprojekte bestehen ohnehin aus einer Vielzahl an Softwarebibliotheken und anderen Bestandteilen. Außerdem arbeiten bei großen Projekten, wie zum Beispiel an dem Linux Betriebssystem-Kern, sehr viele Menschen, sodass dies entsprechend organisiert werden muss. Hier kommt dann das Konzept der Architekturmuster zum Einsatz.

Was muss man als Programmierer wirklich beherrschen und wie kann man sich verbessern?

Nicht jeder Programmierer hat dieselben Fähigkeiten. Ein Programmierer, der Webseiten erstellt, hat andere Fähigkeiten, als ein Programmierer, der an Betriebssystemen programmiert. Auch das Level der Fähigkeiten eines Programmierers ist bei jedem anders. Ein Mensch, der gerade erst mit Programmieren anfängt, hat ein anderes Level, als ein Programmierer, der bereits Jahrzehnte Programmiererfahrungen hat. Das Gute ist, dass Programmierer mit jedem Fähigkeitenlevel gesucht werden. Auch ohne tiefere Kenntnisse in den oben beschriebenen Konzepten werden Programmierer dringend gesucht. Ich gehe ganz fest davon aus, dass dies auch in Zukunft so bleiben wird.

Eine Programmiererin bei der Arbeit.
Die Knappheit an qualifiziertem Personal im IT-Sektor ist das mit Abstand drängendste Problem für Personalentscheider in deutschen Unternehmen.

Wichtig für einen Programmierer ist, dass er sich selbst realistisch einschätzt, wo er gerade steht. Außerdem sollte er wissen, wo er in Zukunft hin möchte. Die oben beschriebenen Konzepte sind meiner Meinung nach ein guter Leitfaden, an den man sich orientieren kann, wenn man sich als Programmierer weiterentwickeln möchte. Wichtig ist, dass man sich weiterentwickelt und auch daran arbeitet, die oben beschriebenen Konzepte in der Praxis anzuwenden.

Wie lange benötigt man, bis man diese Konzepte verinnerlicht hat?

Von der ersten Berührung mit einer Programmiersprache bis zu dem Punkt, an dem man große Projekte selbstständig umsetzen kann, vergehen in der Regel Jahrzehnte. Jemand, der eine Programmiersprache aus eigenem Antrieb erlernt und sich selbst verbessern möchte, wird schneller, besser und insgesamt auch viel weiter kommen. Die oben beschriebenen Konzepte sind in der Regel Teil des Informatik- und Mathematikstudiums. Allerdings wird man diese Konzepte erst wirklich verstehen können, wenn man diese erfolgreich in der Praxis angewendet hat. Nach dem Studium gehen also noch einige Jahre ins Land, bis man diese Konzepte verinnerlicht hat und auch dann gibt es immer wieder neue Konzepte, die es lohnt, sich anzueignen.

Wie wichtig ist Mathematik für einen Programmierer?

Generell kann man nicht sagen, dass Mathematik wichtig oder unwichtig für einen Programmierer ist. Es gibt sehr viele Bereiche, in denen man mit der Schulmathematik beim Programmieren auskommt. Dies betrifft insbesondere die Entwicklung von grafischen Benutzeroberflächen. Zur Entwicklung von grafischen Benutzeroberflächen stehen bereits viele Bibliotheken zur Verfügung, die einem viel Mathematik abnehmen. Ein Beispiel ist die Bibliothek Qt für C++ oder Windows Forms für das .Net-Framework von Microsoft. Generell ist die meiste Mathematik, die man für das Programmieren benötigt, bereits in Softwarebibliotheken integriert, dies betrifft unter anderem das Speichern und Laden von Bildern oder das Generieren und Anzeigen von 3D-Objekten (→ OpenGL).

Für das Programmieren von grafischen Benutzeroberflächen reicht die Schulmathematik aus. Hier ist die Benutzeroberfläche des Betriebssystems von Android in der Version 3.0 zu sehen.
Für das Programmieren von grafischen Benutzeroberflächen reicht die Schulmathematik aus. Hier ist die Benutzeroberfläche des Betriebssystems von Android in der Version 3.0 zu sehen.

Allerdings gibt es auch viele Bereiche, wo man ohne höhere Mathematik nicht auskommt. Dies betrifft oft den Bereich der Spitzentechnologie, wo Technologien komplett neu entwickelt werden. Ein Beispiel dafür sind bestimmte Lernprozesse bei künstlicher Intelligenz, wo oft das BFGS-Verfahren zum Einsatz kommt. Ziel der Spitzentechnologie ist es, entsprechende Verfahren zu entwickeln und diese in Softwarebibliotheken umzusetzen, damit diese Funktionen auch anderen Programmieren ohne Kenntnisse in höherer Mathematik zur Verfügung stehen.

Die Künstlerin Amy Karle mit einer Skulptur eines menschlichen Herzens, welche im 3D-Druck-Verfahren erzeugt wurde. Beim 3D-Druck kommt man ohne höhere Mathematik nicht aus.
Die Künstlerin Amy Karle mit einer Skulptur eines menschlichen Herzens, welche im 3D-Druck-Verfahren erzeugt wurde. Beim 3D-Druck kommt man ohne höhere Mathematik nicht aus.

Weitere Beispiele, wo man höhere Mathematik in der Programmierung benötigt, habe ich in dem folgenden Artikel aufgelistet:

→ Anwendungsbeispiele der numerischen Mathematik

Mit welcher Programmiersprache sollte man beginnen, wenn man programmieren lernen möchte?

Ich habe in den 1990er-Jahren angefangen, programmieren zu lernen. Auf einem Lerncomputer konnte man kleine Programme in der Programmiersprache BASIC schreiben. Während des Abiturs habe ich dann angefangen C++ zu lernen. Hierfür benötigte man eine Integrierte Entwicklungsumgebung mit einem Compiler um eine ausführbare Datei (exe-Datei unter Windows) zu erstellen. Der Prozess des Erstellens von Programmen ist für einen geübten Programmierer relativ einfach, bei Einsteigern kann dies aber bereits zu Problemen führen, was den Einstieg ins Programmieren unnötig erschwert.

Screenshot der freien Entwicklungsumgebung Eclipse, die ursprünglich zur Entwicklung von Java-Anwendungen entwickelt wurde. Mittlerweile wird diese Entwicklungsumgebung auch für andere Programmiersprachen verwendet.
Screenshot der freien Entwicklungsumgebung Eclipse, die ursprünglich zur Entwicklung von Java-Anwendungen entwickelt wurde. Mittlerweile wird diese Entwicklungsumgebung auch für andere Programmiersprachen verwendet.

Ich persönlich würde jedem Einsteiger empfehlen, mit der Programmiersprache Python zu beginnen. Python ist so konzipiert, dass beim Entwickeln von Programmen ein gut lesbarer und knapper Programmierstil gefördert wird. Ein Einsteiger lernt somit nicht nur programmieren, sondern wird auch dazu gebracht sich gleich zu Beginn einen guten Programmierstil anzueignen. Quellcode, der in Python geschrieben ist, lässt sich direkt ausführen, ohne dass dieser vorher kompiliert werden muss. Zum Erstellen von Python-Programmen würde ich für Einsteiger den Texteditor Notepad++ empfehlen. Dieser Texteditor unterstützt eine Vielzahl von Funktionen, die gerade in der Programmierung nicht mehr wegzudenken sind.

Wer gerne mit dem Programmieren beginnen möchte und dazu passende Bücher sucht, dem empfehle ich die folgende Seite:

→ Free Ebook Foundation auf GitHub

Diese Seite enthält eine Liste mit im Internet kostenlos verfügbaren Büchern zum Programmieren lernen für die verschiedenen Programmiersprachen.

import os

def create_dir_if_not_exist(dir):
    if not os.path.isdir(dir):
        os.mkdir(dir)

Eine Funktionsdefinition in Python. Blöcke müssen immer am Anfang mit vier Leerzeichen zum vorherigen Block eingerückt werden. Dadurch wird ein gut lesbarer Programmierstil gefördert.

Hinweis

Dieser Artikel erschien ebenfalls auf der folgenden Webpräsenz:

→ thomas-krakow.de