Zum Inhalt springen

Skills

nach unten zum Inhaltsverzeichnis

Übersicht

Hier ein Überblick über die wesentlichen Techniken, die ich beherrsche, und wann und wie intensiv ich sie angewendet habe:


nach oben zur Übersicht

Informatik-Studium

Von 2000 bis 2005 habe ich an der heutigen Hochschule München Informatik studiert (Studienrichtung Informatik in der Technik) und sehr erfolgreich als Dipl.-Inf. (FH) abgeschlossen.

Studienfächer

Hier ein Auszug aus meinen Studienfächern:

  • Programmieren (Java, C++)
  • Maschinennahe Programmierung (Assembler)
  • Systemprogrammierung (Windows, Linux, Scheduler, Asynchrone Dateioperationen, Synchronisationsmechanismen)
  • Echtzeitsysteme (Scheduling-Algorithmen)
  • Softwareengineering (Softwareentstehungsprozesse, Designpattern)
  • Algorithmen und Datenstrukturen (Standardalgorithmen, Komplexitätstheorie)
  • Datenverarbeitung in der Technik (Finite-Elemente-Methode, schwingende Membrane)
  • Datenverarbeitungssysteme
  • Datenbanken (Aufbau und Implementierung von Datenbanksystemen, SQL, Anwendung)
  • Betriebssysteme (Windows, Linux, Scheduler, Asynchrone Dateioperationen)
  • Rechnertechnik (Rechner-Architektur, Halbleitertechnik)
  • Compilerbau
  • Technische Physik (Optik)
  • Echtzeit-3d-Computergrafik (Open-GL)
  • Bilddatencodierung (u.a. JPEG-Format, mpeg-Formate)
  • Logik
  • Statistik
  • Mathematik (Algebra, Analysis, numerische Mathematik)
  • Deterministisches und stochastisches Optimieren
  • Management und Entscheidungstheorie
  • Englisch und Englisch für internationale Wirtschaftsbeziehungen
  • Datenkommunikation (Netzwerk, Protokolle)
  • Volks- und Betriebswirtschaftslehre

Praktika

Im Rahmen meines Studiums habe ich auch zwei Praktikumssemester (je sechsmonatige Praktika) in der Industrie absolviert.

Mein erstes Praktikum war bei der Mikotron GmbH. Dort habe ich im Bereich Echtzeit-Hochgeschwindigkeitskamerasysteme gearbeitet. Meine Tätigkeitsbereiche: Konzeption und Realisierung von Softwarekomponenten, Inbetriebnahme, Test und Fehlersuche/-behebung in Gerätetreibern (für Framegrabber) sowie Erstellung und Pflege von Softwaredokumentation. In enger Zusammenarbeit mit der Geschäftsleitung und der technischen Leitung durfte ich zudem eine neue Funktion für die Kamerasysteme entwickeln.

Das zweite praktische Studiensemester absolvierte ich bei der BMW Group in München im Bereich der Getriebeentwicklung. Die Tätigkeitsbeschreibung war: Pilothafte Erarbeitung und Dokumentation eines neuen Verfahrens zur Echtzeit-Visualisierung einer 3d-CAD-Animation inkl. wirkender Kräfte an den Bauteilen eines IVT-Getriebes an einem HiL-Prüfstand (MATLAB/Simulink, CAE-Bereich technische Simulationen).

Diplomarbeit

Mit großem Erfolg konnte ich auch meine Diplomarbeit „Ansteuerung von Schaltelementen eines automatisierten Getriebes“ bei der BMW Group in München absolvieren.

zur Übersicht oder zum Inhaltsverzeichnis

Entwickler bei PfeifferControl

Seit 2005 bin ich bei PfeifferControl als Entwickler angestellt. Dort bin ich schwerpunktmäßig für die Softwareentwicklung verantwortlich und trage interne fachliche Verantwortung für zentrale Softwareprojekte. Zu meinen Aufgaben gehören fachliche Projektplanung, technische Leitung der Softwareentwicklung, Softwaredesign, Planung und Verteilung von Aufgaben auf Mitarbeiter und Externe, Implementierung, Test, Dokumentation, Kundenkontakt, Kundenzufriedenheit und -akquise.

Bei PfeifferControl werden flache hierarchische Strukturen und agile Arbeitsweise gepflegt. Zufriedenheit – für Mitarbeiter und Kunden – sowie Qualität der Arbeitsergebnisse stehen im Mittelpunkt.

zur Übersicht oder zum Inhaltsverzeichnis

QBasic, VB5.0/6.0, Pascal, meine ersten Programme

Oder wie ich mir bereits als Kind das Programmieren beigebracht habe…

Alles begann bei mir mit QBasic, als ich noch Schüler war. MS-DOS 6.2 und MS-Windows 3.11 waren das modernste, was es auf dem PC-Markt zu bekommen gab. Als einfache Programmiersprache wurde standardmäßig QBasic 1.1 mitgeliefert. Das weckte mein Interesse, und schon bald habe ich durch Herumprobieren kleinere und größere 16-Bit-Programme entworfen. Um mich dort weiterzuentwickeln, kam zunächst noch QuickBASIC 4.5 auf den Rechner. Bis dahin war alles noch ziemlich unprofessionell, aber immerhin konnte ich mir einen Taschenrechner und ein paar Spiele programmieren. Der Hilfedatei zum Dank konnte ich schnell den gesamten QBasis-Befehlssatz auswendig (dieser ist aber auch sehr begrenzt). Als ich im Prinzip schon alle Befehle kannte, habe ich mich dann in der 7. Klasse für das Wahlpflichtfach Informatik entschieden. Dort wurde uns auch QBasic beigebracht (neben einigen Grundlagen der Informatik). Das Thema war allerdings auch für unsere Lehrerin neu, so dass ich sie manchmal im Unterricht unterstützen musste. Wenn sie sich nicht sicher war, fragte sie bei mir nach. Pascal lernten wir als alternative Programmiersprache dann auch noch. Das war tatsächlich neu für mich, und die zusätzlichen Möglichkeiten waren sehr vielversprechend. Allerdings habe ich das nie allzu sehr vertieft.

Multiplayer-Erweiterung für Nibbles

Das mit MS-DOS mitgelieferte QBasic-Spiel Nibbles gefiel mir sehr. Der 2-Spieler-Modus war auch ganz lustig, das reichte mir aber nicht. Wir hatten ca. 1996 einen zweiten PC gekauft, und so habe ich einen 4-Spieler-Modus auf 2 PCs mit RS-232-Verbindung implementiert, um auch in größerer Runde spielen zu können. Auf jedem PC konnten mit jeweils einer gemeinsamen Tastatur zwei Spieler spielen. Mit meinen damals 15 Jahren und wenig Ahnung von Software musste ich mich erstmal in den originalen Source-Code einarbeiten und die passenden Schnittstellen finden. Nachdem ich etwas experimentiert hatte, fand ich dann eine Lösung. Diese würde ich aber heute nicht mehr so umsetzen, da die Programme auf den beiden PCs nicht immer 100 % synchron liefen. Wobei ich auch heute nicht wüsste, wie man rein mit QBasic asynchrone Aufrufe machen könnte. Threads gab es nicht, nur kooperatives Multitasking, und in QBasic gab es schon gar keine eingebauten Synchronisationsmechanismen.

Für eine kleine Firma habe ich auch um die Zeit eine einfache Kundenkartei mit QuickBASIC implementiert. Aus heutiger Sicht (Datenschutz, Integrität, Sicherheit usw.) würde so etwas nicht mehr möglich sein, aber damals interessierte sich keiner so richtig dafür.

Analysen von Dateiformaten und meine eine erste echte Automatisierung

Visual Basic kam danach. Zwar habe ich mit Version 4.0 angefangen, aber erst mit 5.0 und später 6.0 konnte ich so richtig damit umgehen. Damit konnte ich einige einfache Anwendungen grafisch schön umsetzen. Aber Spiele programmierte ich weiterhin in QuickBASIC. Hier konnte ich immerhin im VGA-Modus (Nummer 12, mit 640×480 px) auch grafische Programme schreiben. Sogar die Maus konnte ich integrieren (irgendwie über Interrupts, es ist lange her). Einzig schöne Grafiken (Bilder, gezeichnet in Windows-Paint oder gescannt von Freunden, da ich selber noch keinen Scanner hatte) konnte ich noch nicht verwenden. Schwierig war es, da ich noch keinen Zugriff auf das Internet und auf Dokumentationen hatte. Doch auch hierfür fand ich eine Lösung. Ich habe mit Paint systematisch Bitmap-Dateien erstellt (in verschiednenen Größen, Farben und Bit-Tiefen). Diese habe ich dann mit Visual Basic im Binärmodus geöffnet und analysiert (u.a. per Debug-Ausgaben). Schnell konnte ich Paletten- und RGB-Werte identifizieren, die Bitmap-Headerstruktur weitgehend entschlüsseln und die Run-Length-Codierung (RLE) versehen (zugegeben, letzteres hat etwas gedauert, so rein durch Analyse und ohne Dokumentationen). Auch das Auffüllen der Bilddaten jeweils am Zeilenende war für mich nicht sofort offensichtlich, aber auch da kam ich schließlich dahinter. Als ich dann alles verstanden hatte, habe ich die Bilddaten mit Visual Basic in einem einheitlichen Zwischenformat (4-Bit-Bilddaten mit Palette) binär abgespeichert und mit QickBasic wieder geladen. Angezeigt wurden nun schöne Bilder, aber diese wurden viel zu langsam Pixel für Pixel aufgebaut (QickBasic ist eine Schnecke mit zusammengebundenen Schnürbändern ;-), zumindest war das mein Eindruck). Also habe ich weiter recherchiert und mich mit Speichersegmenten beschäftigt. Schell war klar, wo die Daten für die Grafikkarte im Speicher stehen. Also habe ich mir in QuickBasic einen Konverter geschrieben, der erst die Daten aus der Binärdatei langsam zeichnet und dann den VGA-Speicher als Block in eine andere Binärdatei schreibt. Von nun an musste ich, um das Bild darzustellen, nur noch den Speicherblock aus der neuen Binärdatei laden und an die richtige Stelle im Speicher schreiben. Um den Workflow zu verbessern – schließlich hatte ich mehr als zwei Grafiken pro Woche zu verarbeiten 😉 – habe ich den Konverter direkt aus Visual Basic heraus aufgerufen, nachdem ich dort die Bitmap-Datei geladen und im Zwischenformat gespeichert hatte. Das war auch gleichzeitig meine erste echte Automatisierung.

So schnell wird man zum Hacker

Meine Erfahrungen konnte ich mir schnell zunutze machen, um bei dem Spiel SimCity mit unendlich viel Geld sofort große Städte bauen zu können oder später in Need for Speed II andere Fahrzeuge als den Rennwägen zu fahren. Highlight war sicherlich im Multiplayer-Modus die Mitspieler mit einem Schulbus mit 372 (km/h?) zu überholen. Einem HEX-Editor sei Dank, konnte ich später z.B. auch Beschränkungen in Softwareprodukten aufheben. Heute mache ich solche Dinge nicht mehr, jedoch hilft es mir hier und da, um Probleme in kompilierten Software-Produkten selbst zu beheben, wenn mir das Warten auf einen Patch zu lange dauert.

zur Übersicht oder zum Inhaltsverzeichnis

x86 Assembler

Noch zu Schulzeiten, aber dann schon in der 11. und 12. Klasse habe ich mich mit dem Thema x86-Assembler beschäftigt. Ich habe mir eine ca. tausend Seiten lange Dokumentation von Intel zu den Assemblerbefehlen (80386-Befehlssatz) ausgedruckt und weitgehend durchgearbeitet. Im Wahlfach Assembler in der 12. Klasse konnte ich meine Kenntnisse nochmals vertiefen. Mir machte es immer viel Spaß, die CPU und den gesamten Rechner zu verstehen und damit Dinge tun zu können, die andere für unmöglich hielten.

Und aus dieser Zeit kommt eine Überzeugung von mir, zu dessen Kern ich immer noch stehe:

Wer niemals Assembler programmiert hat, der kann auch aus einer höheren Sprache nicht das Optimum herausholen.

Ich gebe zu, die Compiler leisten heutzutage so viel, dass sich dieser Spruch teilweise überholt hat. Aber rein das Verständnis, wie eine CPU funktioniert, fördert ein anderes Denken. Man versteht besser, wie sich Befehle im höheren Sprachen auswirken und kann somit schneller und besser programmieren lernen.

Später (im Studium) habe ich dann auch noch 64-Bit-Assembler gelernt. Interessant ist, dass es von 16 auf 32 und von 32 auf 64 Bit jeweils einfacher wird. Von 16 auf 32 Bit fallen die Speichersegmente weg, von 32 auf 64 Bit die Stack-basierte Floatingpoint-Architektur (stattdessen können MMX Register unabhängig verwendet werden).

zur Übersicht oder zum Inhaltsverzeichnis

Java

Im Rahmen meines Studiums durfte ich als erste Programmiersprache Java lernen. Java wurde gelehrt, weil es Objekt-orientiert, Plattform-unabhängig, gut strukturiert, kostenlos und mit vielen Bibliotheken ausgestattet war. Das integrierte Dokumentationswerkzeug Javadoc war ein weiterer Grund, Java zu verwenden. Zwar waren die Sprachelemente für mich nichts neues, dennoch lernte ich dabei zum ersten Mal professionell programmieren. Meine bisherigen Programme kamen mir im Anschluss ziemlich schlecht vor.

Auch damals faszinierten mich Datenstrukturen bereits. Die Vorteile von Arrays und HashMaps waren aber in keiner Java-Datenstruktur optimal vereint. So entwickelte und dokumentierte ich eine neue Datenstruktur HashArray, die in Qualität und Funktion den Bibliotheksfunktionen in nichts nachstand.

Als Übungsprojekt habe ich einen kleinen Webserver erstellt, der in mehreren Threads verschiedene einfache Anfragen beantworten konnte.

Später spielte Java für mich eine untergeordnete Rolle. Da ich mich auf das effiziente Berechnen komplexer Probleme spezialisiert habe, war mir Java zu langsam. Als Alternative kam hier C++ zum Einsatz.

zur Übersicht oder zum Inhaltsverzeichnis

C++ / C++11 / C++14 / C++17 / C++20

Während meines Studiums habe ich Bereits professionell C++ programmiert werden. Damals war noch der Standard C++99 aktuell, der für mich mittlerweile als überholt gilt. Im Rahmen meiner Arbeit bei PfeifferControl habe ich nach und nach alle kommenden Standards gelernt, bis hin zu C++20. Die heutigen Möglichkeiten von C++ bieten eine Kombination aus der Möglichkeit, Maschinennah, aber auch auf sehr hoher Ebene zu programmieren. Somit ist es den meisten anderen Sprachen für rechenintensive Aufgaben deutlich überlegen. Als Ausnahmen für diesbezüglich vielleicht noch bessere Sprachen seien derzeit Rust und Go genannt.

C++ fasziniert mich besonders, weil man damit noch sehr direkt programmieren Und sich vorstellen kann, wie der Compiler den Code in Maschinencode umsetzt – zumindest, wenn man die Compileroptimierungen mal außer Acht lässt. Leider bietet C++ auch viele Fallstricke, sodass es aus meiner Sicht nur von wirklich professionellen Programmierern verwendet werden sollte.

Mein größtes C++-Projekt, für das ich vollständig verantwortlich war, umfasst mehrere hunderttausend Zeilen Code und sehr viele sehr komplexe Algorithmen. Es handelt sich um ein High-Performance-Computing-Projekt (HPC), Bei dem es besonders auf Rechenzeit ankommen. Aufgrund der Struktur der Berechnungen, die mit diesem Programm durchgeführt werden, müssen nicht nur einzelne Codeteile Laufzeit-optimiert werden, sondern nahezu das gesamte Programm. Gleichzeitig dürfen quasi keine Fehler auftreten, da aufeinander aufbauende Berechnungen bis zu mehreren Monaten laufen und ein Abbruch aufgrund eines Fehlers sehr teuer wäre. Durch hohe Investitionen in Konzept, Stabilität Und Nachverfolgbarkeit Ist es schließlich auch gelungen, dieses Ziel zu erreichen. Hier ein Auszug aus den verwendeten Techniken und erreichten Zielen des Projekts:

  • Höchste Stabilität der Algorithmen durch eigens entwickelte Fehlerbehandlungsmechanismen und erweitertes Exception-Handling auf höchster Ebene.
  • Erzeugung von Maschinen-Code zur Laufzeit, um in Laufzeit-kritischen Kernkomponenten teure Entscheidungen zu vermeiden, die bereits bei Programmstart durch die Benutzereingabe feststehen.
  • Cache-Ausnutzung von Verwendung von Bitmasken und Bitmasken-Operationen für viele Algorithmen.
  • Nutzung von Profiling.
  • Algorithmen zur Reduzierung der Zeitkomplexität.
  • Verteiltes Rechnen.
  • Die Rechengeschwindigkeit wurde im Vergleich zu ursprünglichen Varianten mit fremden Bibliotheken und vergleichbaren Algorithmen um mehr als den Faktor 100 gesteigert, sodass statt der Berechnung in Rechenzentren und in der Cloud für dieselben Aufgaben teilweise einfache Bürorechner ausreichen.
  • Verfahren zur Wiederaufnahme von komplexen Berechnungen, um bei Abbrüchen nicht alle Ergebnisse neu erzeugen zu müssen.
  • Optimierung der Debug-Fähigkeit der Algorithmen, z.B. mit automatischen Haltepunkten an den Auslösepunkten von Exceptions, Visualisierungsbeschreibungen für zentrale Datentypen und Verwenden von Speziellen Klassen für Bitmasken im Debug-Modus.
  • Warnungsfreies Kompilieren mit höchster Warnstufe (alle Warnungen aktivieren und Warnungen als Fehler behandeln). Warnungen dürfen nur explizit (mit konkreten Warnungsnummern) für eingebundene Bibliotheken unterdrückt werden. Für eigenen Code gilt: Warnungen müssen behoben werden. Falls das nicht möglich ist, muss eine Warnung lokal unterdrückt werden und eine ausführliche Begründung als Kommentar erfolgen.

zur Übersicht oder zum Inhaltsverzeichnis

Rapid-Prototyping / Embedded

Bereits während meines zweiten praktischen Studiensemesters und meiner Diplomarbeit kam ich in den Genuss, im Embedded-Bereich programmieren zu dürfen. Hier ist eine andere Denkweise nötig, die so manchem Kollegen Probleme bereitete. Insb. bei den Echtzeit-Anforderungen und den zyklischen Tasks braucht man eine etwas andere Sichtweise.

Auch die Abhängigkeit von einer funktionierenden Hardware stellte mich vor Herausforderungen. Bei PCs geht man meist davon aus, dass alle Hardware-Komponenten korrekt arbeiten und man sich nur um die logische Ebene seiner Programme kümmern muss. Im Embedded-Bereich muss man sich dagegen mit der Hardware bis ins Detail auseinandersetzen. Sowohl Steuergeräte wie auch Sensoren und Aktuatoren können fehlerhaft sein oder Daten fehlerhaft verarbeiten.

Test und Fehlersuche sind weitere Themen, die im Embedded-Bereich schwieriger sein können, da die Software i.d.R. Ereignisgesteuert ist und auf einer anderen Hardware-Architektur läuft. Hier konnte ich im Rahmen mehrere Projekte über ca. 10 Jahre ausführliche Erfahrungen gesammelt.

zur Übersicht oder zum Inhaltsverzeichnis

.NET (C#, VB)

Stichpunkt(e): XAML, WinForms. Detaillierte Informationen folgen.

zur Übersicht oder zum Inhaltsverzeichnis

QT

Stichpunkt(e): GUI-Entwicklung. Detaillierte Informationen folgen.

zur Übersicht oder zum Inhaltsverzeichnis

HTML5 / CSS3 / JavaScript

Stichpunkt(e): Homepages, qss (QT). Detaillierte Informationen folgen.

zur Übersicht oder zum Inhaltsverzeichnis

PHP 7

Stichpunkt(e): Homepages für Schulen, Vereine, Firmen, privat, eigenes CMS. Detaillierte Informationen folgen.

zur Übersicht oder zum Inhaltsverzeichnis

High-Performance-Computing / Algorithmenentwicklung

Stichpunkt(e): OpenMP, Maschinencode-Generierung. Detaillierte Informationen folgen.

zur Übersicht oder zum Inhaltsverzeichnis

Cloud-Computing

Stichpunkt(e): AZURE, verteiltes Rechnen. Detaillierte Informationen folgen.

zur Übersicht oder zum Inhaltsverzeichnis

Automatisierung

Detaillierte Informationen folgen.

zur Übersicht oder zum Inhaltsverzeichnis

Analysefunktionen und Optimierungsalgorithmen

Detaillierte Informationen folgen.

zur Übersicht oder zum Inhaltsverzeichnis

Test-Automatisierung, HiL / SiL

Stichpunkt(e): Test-Driven-Development (TDD), automatisierte Komponententest (Hardware). Detaillierte Informationen folgen.

zur Übersicht oder zum Inhaltsverzeichnis

Weiteres

Privatprojekte (z.B. Büchereisoftware), ImageViewer-OCX, Datenschutz, KI, Datenanaylse, Rust. Detaillierte Informationen folgen.

zur Übersicht oder zum Inhaltsverzeichnis