And the winner is … Robin 🙂
Robin hat bei der Code Competition 02/2016 mit seinem “Parallelen Webserver” den ersten Platz gemacht. Herzlichen Glückwunsch!
IT-Talents: Robin, herzlichen Glückwunsch zum 1. Platz und damit dem Sieg bei der Code Competition 02/2016 zum Thema „Paralleler Webserver“. Stell Dich den anderen IT-Talenten doch kurz vor.
Robin: Ja hallo, ich bin Robin, 24 Jahre und studiere an der TU Dortmund im 2. Master-Semester Physik. Außerdem bin ich seit 4 Semestern in Angewandter Informatik mit Anwendungsfach Robotik eingeschrieben, da ich seit ein paar Jahren immer mehr Interesse an dem Gebiet gefunden habe. Auch in meinem Physik-Studium reizen mich die Richtungen „Computational Physics“ oder auch „Quantum-Computing“ sehr, wobei tiefergehende Kenntnisse über Algorithmen und auch den Aufbau und die Funktionsweise klassischer Computer von Belang sind. Seit etwas mehr als 6 Monaten arbeite ich übrigens auch für die Materna GmbH als studentischer Mitarbeiter.
IT-Talents: Was hat Dich motiviert, an der Competition teilzunehmen?
Robin: Natürlich zum einen die Preise. Ich habe mir schon oft selber Problemstellungen ausgedacht, aber oft ging dann irgendwann die Motivation verloren – aus den verschiedensten Gründen. Mit der Möglichkeit einen Preis zu gewinnen und einer Deadline hält sich die Motivation deutlich länger und ich bin auch akribischer was z.B. das Testen und die Dokumentation angeht. Außerdem war natürlich die Aufgabenstellung ein wichtiger Faktor. Zum einen habe ich schon mit Sockets und Threads gearbeitet, allerdings habe ich noch nie einen Webserver programmiert. Es war also auch gewissermaßen ein bisschen Neuland für mich. Außerdem habe ich schon viele Webanwendungen selber geschrieben und hatte so schon von Anfang an einige Ideen, welche Features ich zusätzlich machen könnte, wie z.B. eine .htaccess-Unterstützung und einen PHP-Parser.
IT-Talents: Und wie bist Du auf die Code Competition aufmerksam geworden?
Robin: Das ist einfach: Google. Ich hatte aus den eben genannten Gründen nach Code-Competitions gesucht. Man findet natürlich viel, allerdings muss die Aufgabe ja für mich auch realistisch machbar sein. Da bin ich irgendwann auf eure Seite gestoßen.
IT-Talents: Wie bist Du an die Lösung der Aufgabenstellung heran gegangen, und wieso hast Du Dich für die Programmierung in Java entschieden?
Robin: Ich habe vor einiger Zeit schon einmal für ein Uni-Fach ein bisschen mit Sockets arbeiten müssen. Das Programm hatte ich noch und habe mir dort noch einmal die „Basics“ angeschaut. Das war mein Startpunkt. Dann habe ich mir paar Gedanken gemacht, wie das Programm nachher aussehen sollte. Und das ist ja eigentlich klar: ein Webserver bekommt Anfragen (Requests) und sendet je nach Request eine Antwort (Response). Deshalb benötigt man noch einen Request-Handler, der die Anfragen bearbeitet und man hat schon eine Grundstruktur der Klassen. Damit habe ich dann auch angefangen. Wichtig war mir zunächst, dass ich ein Kern-Programm habe, das wirklich funktioniert, aber auch so strukturiert ist, dass ich darauf aufbauen kann (was bei Programmen im Idealfall ja immer so sein sollte). Darauf habe ich geachtet und es hat scheinbar ja ganz gut geklappt.
Zu Java: da könnte ich jetzt sehr viel zu sagen, aber die Hauptgründe sind, dass ich Java von den Sprachen die ich beherrsche einfach am besten kann und die Tatsache, dass ich schon mit Java-Sockets und -Threads gearbeitet habe.
IT-Talents: Welche Probleme sind bei der Entwicklung der Software aufgekommen? Wie lange hat die Entwicklung gedauert?
Robin: Bei der Grundstruktur sind erstaunlicherweise keine größeren Probleme aufgetreten, also bei der eigentlichen Aufgabenstellung ein Directory-Listing zu bekommen. Zwischenzeitlich sind kleinere Dinge aufgetreten, die ich aber doch relativ schnell debuggen konnte. Als es dann ins Detail ging, wurde es schon schwieriger. Das schlimmste war aber die PHP-Parser-Implementierung. Das eigentliche Parsen war überhaupt kein Problem, da Java sehr einfache Möglichkeiten bietet, Konsolenbefehle durchzuführen und der Output der Konsole kann dann einfach über einen Input-Stream in Java eingelesen werden. Allerdings ist es mir bis zum Schluss nicht gelungen, die „Superglobals“, die für PHP-Web-Entwicklung ja eigentlich sehr wichtig sind, zu implementieren. Nur das $_SERVER-Array, für das man nur temporär Umgebungsvariablen setzen muss, habe ich hinbekommen. Ich habe dann nach stundenlangem Suchen in Foren irgendwann aufgegeben, da ich auch auf Einträge gestoßen bin, die besagten, dass diese Funktionalität ganz tief im PHP-Kern vergraben ist und nicht so ohne weiteres implementiert werden kann.
Was weniger schwierig, sondern vor allem sehr nervig war, war die unendliche Landschaft an MIME-Typen und HTTP-Headern und herauszufinden, welche Dateitypen welchen Header und welchen MIME-Typ benötigen, da es leider nicht ansatzweise einheitlich oder intuitiv ist. So haben z.B. Bilder (also z.B. .jpg, .png usw.) nicht funktioniert, wenn ich ihren MIME-Typ angegeben habe. Manche Header brauchten doppelte, manche einzelne und manche auch gar keine Leerzeile nach dem HTTP-Header, um nur zwei Dinge zu nennen. Kurz gesagt: die Feinheiten haben den meisten Ärger gemacht.
Alles in allem habe ich dann auch deutlich mehr Zeit investiert als eigentlich geplant, wobei – zumindest gefühlt – das Programmieren und Dokumentieren weniger Zeit gekostet hat als das Lesen von Foreneinträgen und Recherchieren. Eine Stundenanzahl kann ich nicht schätzen, aber sagen wir mal so: die 200€ durch die Stunden zu teilen, die ich gebraucht habe, würde keinen guten Stundenlohn ergeben. Spaß gemacht hat es trotzdem.
IT-Talents: Sehr interessant, was hast Du durch die Entwicklung gelernt?
Robin: Hauptsächlich, dass es sehr aufwändig ist, einen Webserver zu programmieren der nur ansatzweise die Funktionalität z.B. eines Apache-Webservers hat.
IT-Talents: Kannst Du uns kurz erklären, wie Du die Parallelisierung implementiert hast?
Robin: Das ist in Java zum Glück relativ simpel durch Threads und, wie gesagt, Sockets. Man benötigt im Prinzip nur zwei Klassen, die von der Thread-Klasse erben: einen Server-Thread und einen Client-Thread. Der Server-Thread hat allein die Aufgabe, auf dem gewünschten Port zu lauschen, ob Anfragen herein kommen, was durch die „accept“-Methode der ServerSocket-Klasse aus Java in einer Zeile implementiert werden kann. Kommt eine Anfrage herein, gibt diese Methode einen Socket zurück, welche den „Client“ repräsentiert. Für jeden neuen Client erstellt man einen Client-Thread, an welchen man den erhaltenen Socket übergibt. Da Threads vom Computer ja quasi „gleichzeitig“ bearbeitet werden, kann nach dem Erstellen des Client-Threads der Server-Thread wieder nach neuen Anfragen lauschen, während der Client-Thread die Anfrage parallel bearbeitet.
Da der Prozessor ja eigentlich nicht gleichzeitig – sondern relativ willkürlich abwechselnd – Threads bearbeitet und so z.B. ein Schreibprozess von Daten noch nicht abgeschlossen sein könnte, während ein anderer Thread genau diese Daten lesen will, müssen gewisse Prozesse noch synchronisiert werden. Stichwort Thread-Safety, wie ihr ja auch in der Aufgabenstellung geschrieben habt. Das war bei mir hauptsächlich bei Dateien so, die ich eingelesen habe. Diese Problematik lässt sich aber sehr einfach mit dem „synchronized“-Schlüsselwort von Java umsetzen.
IT-Talents: Was würdest Du Dir thematisch gerne einmal als Code Competition wünschen?
Robin: Ich fände es interessant, Programme gegeneinander antreten zu lassen. Da würde mir spontan künstliche Intelligenz einfallen, oder auch ein Rennen, welches Programm am effizientesten ist, z.B. große Datenmengen zu analysieren.