Werden komplexe Algorithmen und Datenstrukturen bei der alltäglichen Programmierung benutzt?
Ein Computerprogramm ist nichts anderes als eine Datenstruktur, in Form von Wörtern einer Sprache, welche einen Prozessor steuern, um Daten zu lesen und zu schreiben. Jedes Computerprogramm ist also ein Algorithmus, nur ist nicht immer ganz klar, was er genau tut. Auf jeden Fall arbeitet das Programm mit Daten, die zum Zweck der Interpretierbarkeit auf bestimmte Weisen strukturiert sind, schlussendlich damit Menschen damit arbeiten können. In jedem Fall ist unsere Welt aber auch irgendwie strukturiert, und eine Sprache für Datenverarbeitung muss diese unterschiedlichen Strukturen eben abbilden können, wenn sie Daten aus der echten Welt in neue Daten über die Welt umformen möchte. Diese Umformung geschieht durch Algorithmen. Genauer gesagt, der Prozessor benutzt intern, feste Elektronik, welche feste Algorithmen implementieren, und zwar genau die Algorithmen, die es möglich machen, alles zu berechnen, was berechenbar
ist, indem man sie einfach immer wieder unter unterschiedlichen Vorraussetzungen anwendet. Prozessor + RAM wird also praktisch gesagt "Führ dieses Programm aus" *geht zu der Speicheradresse des Programms* "Hallo ich bin Programm echo, lies jetzt erstmal die Eingabeargumente die der Benutzer hier (legt Speicheradresse in Prozessorregister) gespeichert hat. ;)" *liest 'H'* "Sehr gut, schreib das was du dort gelesen hast, jetzt hier hin (legt Speicheradresse zum Standardoutput in Prozessorregister) … "vergleiche die beiden zahlen und schreib den unterschied dort rein" - "addiere die beiden zahlen" - "gehe zu diesem Teil des Programms und mach da weiter" - "wenn das was hier steht 0 ist, gehe dahin, sonst mach einfach weiter"
Als Programmierer gibst du im Grunde genommen genau solche Algorithmen vor, nur nicht unbedingt bewusst. Denn wenn wir sagen "gehe zu Teil X des Programms", dann wissen wir nicht unbedingt was Teil X genau macht. Wie alles andere auch ist X ein Algorithmus, der Daten in unserem Speicher liest und verändert. Wir arbeiten meistens mit Hochsprachen, also Sprachen die deutlich über den Prozessor und Speicher abstrahieren, und automatisch, nach festen Regeln, eine Textdatei in Binärcode übersetzen, der dann von einem Prozessor ausgeführt werden kann. Die Sprache gibt also vor, welche Befehle grammatikalisch "korrekt" sind, also die von dem Compiler eindeutig in alle exakten Teilbefehle übersetzt werden können. Dabei benutzt der Compiler bzw. die Sprache Datenstrukturen, um dem Compiler erklären zu können, wie der code für einen Speicherblock mit einer bestimmten "Datenstruktur" auszusehen hat. Das wäre also soetwas wie "Datenstruktur A sieht so aus: erst eine Zahl, dann ein Text, dann eine Datenstruktur B, …" .. dann gibt es irgendwelche Operationen die man für diese Datenstrukturen definieren kann, wie zum beispiel "addieren" oder "länge_von", die bestimmte Eingabeargumente nehmen, die eine bestimmte Datenstruktur haben. "Zahl + Zahl", "länge_von Liste". Wenn dann eine konkrete Liste gelesen wird, wird einfach der selbe Algorithmus auf dem Speicher ausgeführt, welcher sich hoffentlich auch an die Regeln gehalten hat, die Vorraussetzung dafür sind, eine Liste zu sein. Sonst ruft "länge_von" undefiniertes Verhalten hervor, weil die Funktion etwas macht was nicht definiert wurde und auch kaum hervorsehbar ist. Die Compiler können aber garantieren, dass Daten in der Regel die korrekte Struktur haben, und sich nicht spontan ändern. Ich finde die Vorstellung, beliebige Konzepte aus der Realität in einer Menge von Datenstrukturen zu repräsentieren, über diese Datenstrukturen dann Operationen zu definieren, und diese dann zu Algorithmen zu verketten, die zu gegebenen Instanzen der definierten Strukturen dir neue Informationen berechnen können, unheimlich spannend.
Die heutige Programmierung besteht leider immernoch viel aus technischen Details, die nichts mit dem tatsächlichen Problem zu tun haben, sondern mit den Werkzeugen selbst. Im Alltag beschäftige ich mich zumindest zunehmends nurnoch mit dem Lernen von neuen Werkzeugkästen, welche praktisch nur dazu dienen, um mit anderen Werkzeugen auf eine bestimmte Art zusammenzuarbeiten. Manchmal ist es sinnvoll, manchmal fragt man sich warum das so kompliziert sein muss, obwohl das Problem doch schon tausend mal gelöst wurde. Ja, ich würde auch sagen, Algorithmen und Datenstrukturen liegen allem in der Softwaretechnik zugrunde, und es wird immer komplexer. Eine wichtige Frage ist, was genau diese Komplexität erzeugt und wann sie wirklich notwendig ist, und wann nicht.
Eine fundamentale Aufgabe eines Programmierers ist es, eine Spezifikation zu formulieren. Die Spezifikation beschreibt möglichst eindeutig, aber trotzdem noch abstrakt, also ohne auf letzte Details einzugehen, was das Programm, der Algorithmus, der geschrieben werden soll, aus gewissen Daten machen soll, die ihm in den Speicher geladen werden. Wir haben also eine abstrakte Beschreibung der Eingaben, und der gewünschten Ausgaben. Leider sind die Eingaben schon so komplex zu spezifizieren, dass sie fast nie eindeutig formalisiert werden. Es ist also für keinen Algorithmus der heute benutzt wird genau definiert, was er in jedem möglichen Zustand für Effekte hat. Das ist dann die Quelle von Bugs, welche Programmierer und Nutzer immer wieder dazu zwingen, sich mit der Komplexität der tieferliegenden Software auseinanderzusetzen, weil die Software nicht den Effekt hatte der angenommen war, wahrscheinlich weil der Zustand nicht der war, wie er angenommen wurde.
Das heißt um immer nachvollziehen zu können, warum welches Verhalten entsteht, und um somit auch wohldefinierte, zielführende und nachvollziehbare Software schreiben zu können, müssten wir genau beschreiben können, in welchem Zustand sich das gesamte System zu einem Zeitpunkt befindet. Das tun wir aber nicht, weil es zu kompliziert ist. Es gibt unterschiedliche Hardware, unterschiedliche Softwareversionen, unterschiedliche Programmiersprachen, unterschiedliche Betriebssysteme, und und und. Das alles zu formalisieren und eine eindeutige Abbildung auf alle möglichen Computerzustände zu haben, ist so komplex, dass noch niemand eine Lösung gefunden hat, die es für Menschen einfacher machen könnte, ein Computersystem zu verstehen. Wir werfen einfach kleine Teile zusammen und beobachten was passiert, so lernen die meisten Programmierer heutzutage.
Ich hoffe auf jeden Fall, dass wir es noch schaffen, eine universelle Sprache für Computer zu entwickeln, die für Menschen einfach nachzuvollziehen ist und eindeutig alle Zustände und Operationen eines Computers abbilden kann. Das was wir heute haben gleicht eher einer Buchstabensuppe.