Robuste Programmierung – Weniger Bugs + Stabile Software

Robuste Software

Du möchtest robust programmieren?

Dieser Guide gibt Dir eine Einführung in die Thematik!

Beginnen wir!

Was ist robuste Programmierung

Eine robuste Programmierung erzeugt stabile Programme, …

  • die jegliche Eingaben verarbeiten können,
  • in Randfällen immer noch stabil laufen und
  • kaum Wartung brauchen.

Eine robuste Programmierung versucht präventiv unvorhergesehene Fehlerfälle zu vermeiden, welche bei der Ausführung eines Programms entstehen.

Die Informatiker kämpfen mit dem Halteproblem:

Kein Algorithmus kann überprüfen, ob eine Eingabe dazu führt, dass das Programm in der Mitte stehen bleibt, eine sinnlose Ausgabe erstellt oder flüssig durchläuft. Nur mit der Ausführung des zu prüfenden Programm selbst können wir testen, ob das Programm funktioniert oder nicht.

Das Halteproblem

Trotz der mathematischen Schwierigkeiten können wir Menschen sehr viel dazu beitragen, dass ein Programm stabil läuft und die Anwendung nicht bei der ersten Aufgabe Schluckauf bekommt.

Eigenschaften labiles Programmieren

Was ist das Gegenteil zum robusten Programmieren? Das labile Programmieren!

Der Entwickler beim labilen Programmieren versucht möglichst schnell viele Features in eine Software zu integrieren, sodass diese in den meisten Fällen rund läuft.

Schnelle Ergebnisse

Features sind genial.

Jeder Kunde und Manager liebt neue Features, welche das Produkt besser machen. Du schaffst mehr Funktionen mit dem labilen Programmieren. Statt viele Stunden an Aufwand in ein einziges Feature zu investieren, schreibst Du einen einigermaßen stabilen Prototyp, welcher Dein Manager später in „Produkt“ umbenennt.

Schnell wandelnd

Viele Start-ups und Unternehmenskonzepte (kostenlose Internetangebote) basieren auf dem labilen Programmieren, weil 95 % gute Features für den Verwendungszweck ausreichen.

Crash-Is-Normal Mentaltität

Heutzutage ist es nicht mehr so gravierend, wenn eine Software abstürzt. Die Software Kubernetes verwaltet Docker-Container, in denen die Programme separiert und gekapselt laufen können.

Ein Docker-Container stellt ein leichtgewichtiger und virtualisierte „Computer“ in einem Computer dar, welcher eine parallele Ausführung von mehreren Instanzen ermöglicht. Stürzt ein Container ab, dann sind noch X weitere verfügbar, worauf Kunden zu greifen können.

Vorteile von robuster Programmierung

Wieso soll ich jetzt robust programmieren? Labiles Programmieren funktioniert doch auch? Hier sind die Top 4 Gründe:

#1 Weniger Bugs und einfache Fehlersuche

Wer sich im Detail darüber Gedanken macht, wie das Programm auszusehen hat, der muss in den folgenden Jahren weniger Fehler bearbeiten. Gut durchdachte Software beugt Bugs vor. Jede Software hat Bugs, nur die Dichte lässt sich durch eine robuste Programmierung reduzieren.

#2 Hacker hassen es – Weniger Zero-Days

Zu einer guten Planung gehören die Attack-Persona hinzu. Zukünftige Angreifer versuchen auf verschiedenen Wegen sich Zugang zu der Software zu verschaffen. Wenn Du diese Aspekte am Anfang direkt berücksichtigst, dann gibt es unwahrscheinlicher ein böses Erwachen am Tag X.

#3 Weniger Angriffsfläche

Eine robuste Software bietet eine geringe Angriffsfläche. Alle möglichen Option des Angriffs sind auf ein Minimum reduziert, sodass die Hacker weniger Spielraum haben.

#4 Leichter Erweiterbar und Modular

Robuste Software kannst Du gut erweitern.

Du kannst mit dieser Art der Programmierung, schneller neue Klassen hinzufügen und Methoden richtig platzieren. Standardaufgaben wie die Authentifizierung oder Nutzerverwaltung kannst Du aus den neuen Methoden einfach abrufen.

Welche Programmiersprache zum robusten Programmieren?

Prinzipiell kannst Du mit jeder Programmiersprache robust programmieren. Einige Programmiersprachen bzw. Compiler achten auf viele Kleinigkeiten, welche die meisten Programmierer links liegen lassen:

Rust – Die Programmiersprache legt Wert auf feste Typen, achtet auf die Variablen im Hauptspeicher und vermeidet Race Conditions Probleme bei der Nutzung von Parallelität. Rust erlaubt keine Null-Pointer, die Fehler Nr. 1 in Java sind. Die Programmiersprache verwendet keine automatische Garbage-Collection (Löschung von alten Variablen), sondern der Programmierer muss sich um diese Aufgabe kümmern.

Erlang – Wenn ein Erlang-Programm crasht, dann ist das nicht schlimm. Ein Subprozess ist einfach wieder aufsetzbar und das typische Erorr-Handeling wird hier nicht angewandt. Prozesse, die gecrasht sind, kann das Programm einfach monitoren. Erlang kann von sich aus Aufgaben parallelisieren, ohne andere Klassen / Bibliotheken zu nutzen.

Anleitung für das robustes Programmieren

Das Wichtigste bei der robusten Programmierung ist es, den Feature-Zeitdruck rauszunehmen und mehr Aspekte zu prüfen:

1. Planung ist die halbe Miete

Wer detailliert Anforderungen definiert, ist schon halb fertig.

Auf Hackathons programmieren Coder in unter 24 Stunden eine App. Genial!

Das Produkt ist aber instabil. Eine detaillierte Planung vom Groben ins Feine hilft Dir, die App auf ein stabiles Fundament zu stellen.

Die Anforderungsanalyse ist dabei der wichtigste Schritt. Agile Methoden nutzen Iterationen, um eine Software zu programmieren und zu verbessern. Dieser Ansatz eignet sich für einige Anwendungsfälle, aber nicht für jede Software! Ein typisches Beispiel ist Software für Raketen. Wenn die Rakete startet, hat der Entwickler keine Chance „schnell mal was zu fixen“. Die Software muss alle Aspekte und Fehlerfälle behandeln können.

2. Streiche die 50 % der Features

Programmierer (bzw. die Manager) überschätzen sich gerne.

Programmierung braucht Zeit.

Wenn Du ein Feature in 1 Woche programmieren kannst, braucht es mindesten eine weitere Woche, um alles zu testen, Edge-Cases zu implementieren und eine Hacker-Sichere Implementierung vorzunehmen. Die Mathematiker müssen sehr wichtige infrastrukturelle Software formal verifizieren. Dazu brauchst Du ein Menge (Aussagen)logik.

3. Überlege Dir einen Test

Bevor Du die erste Zeile in Deiner Methode schreibst, solltest Du erst den Test formulieren.

Was ist die Eingabe? Was ist die gewünschte Ausgabe?

Beim Test-Driven-Development schreibst Du immer erst den Test, bevor Du den Code schreibst. Die Hard-Core Variante von Test-Driven-Development löscht Dir Deine bisherige Funktion, wenn der Code scheitert!

Wenn man es übertreibt!

4. Schreibe den Code für den Test

Schreibe die Funktion und beginne direkt nach den ersten Zeilen den Test zu starten.

5. Verifiziere und Teste weiter

Erstelle weitere Tests, um Ausnahmefälle und Angriffsszenarien zu testen.

Treten Fehler auf, kannst Du den Code direkt an Ort und Stelle nach schärfen und nicht warten bis ein dritter Tester oder Hacker diese findet. Schnell kann der Testcode auf die 3 bis X-Fache Menge im Vergleich zu eigentlich Codebasis anwachsen. Das erscheint absurd, ist aber eine große Zeitersparnis:

Wenn ein menschlicher Nutzer einen Testfall testet, braucht dieser Sekunden bis Minuten, um einen Test auszuführen. Der Computer kann den Test in wenigen Millisekunden erledigen und das vollautomatisch, bei jedem Commit.

6. Optimiere

Manche Programmabschnitte durchläuft Dein Programm Millionenfach. Hier lohnt es sich, die Laufzeit zu optimieren. Bei großen Big Data Projekten und langen Listen / Datenmengen ist das ein Muss. Lese dazu den Beitrag über die Big O-Notation durch. Kleine, geschickt gesetzte Optimierungen können den Zeitaufwand halbieren oder vierteln.


Jeden Monat teile ich mit Mitgliedern
4 neue praxisnahe Tutorials (je 1000+ Wörter).


Trage Deine Mail, damit Du
Deine Coding + Hacking Skills erweitern kannst!

Die Webseite nutzt nur technisch notwendige Cookies.