Herzlich willkommen zur nächsten Vorlesung, zur zweiten Vorlesung,
Softwareentwicklung 2 in diesem Jahr.
Wir beschäftigen uns heute mit Korrektheit. Das heißt, wir
fangen an mit Fehlern. Das heutige Programm sieht so aus,
dass wir, wo schalte ich weiter hier,
dass wir zunächst erst mal darüber sprechen, wie können wir Fehlerwirkungen verringern.
Das ist im Wesentlichen möglich durch defensiven Programmierstil. Dann versuchen wir
da Fehler zu vermeiden. Dazu sprechen wir über das Vertragsmodell Searsions von Nachbedingungen,
das wirkt sich direkt in Java aus,
während das erste vor allen Dingen für das Konzeptionelle wichtig ist.
Und dann geht es zum Schluss, geht es im dritten Teil darum,
Fehler zu finden. Dabei sprechen wir über Reviews und Tests.
Wie immer haben wir das, gibt es solche Fragen zur Wiederholung.
Ihr könnt durchaus darin Altklausurfragen sehen. Wir fangen an,
damit Fehlerwirkungen zu verringern. Bei den Fehlerwirkungen verringern,
gehen wir davon aus, dass wir zunächst erstmal Menschen immer Fehler machen,
ja, aber wir wollen versuchen, Korrektheit zu von Software zu bekommen.
Korrektheit heißt erst mal, Korrektheit bezüglich der Anforderungen,
also wir sollen das machen, was die Software von uns will, was der Auftraggeber von uns will. Und wir wollen möglicherweise nachweisen,
wie es das Wort beweist,
das klingt nach Mathematik und tatsächlich ist das theoretische Informatiker notwendig,
weil wir beweisen, dass Software korrekt ist oder der zweite Punkt,
der da noch dazustößt, der dazugehört, ist,
dass wir nachweisen müssen, Ob die Anforderungen denn überhaupt das richtige drücken,
ausdrücken, was nützt es uns dazu, um zu sagen,
ja, wir setzen das alles korrekt um,
aber die Anforderungen sind nicht richtig verstanden wirken,
wo dann nicht richtig aufgeschrieben wurden.
Dass beides fließt ein in Korrektheit. Aus Anwendersicht ist das ganz,
ganz wichtig, ein Winter beschweren sich über verschiedene Sachen,
verschiedene Fehler, die ihnen schwer fallen.
Performance gehört auf jeden Fall dazu,
auch wenn in Software nicht das tut, was es soll,
nämlich inkorrekte Sachen machen, ist es schwierig.
Ja, Beispiel hier, wir hatten in der letzten Vorlesung
ja schon so ein paar Desaster
Eine Steuerung, eine Familie, eine Fammaschine soll verhindern,
dass in etwas Böses passiert. Zum Beispiel der Unfall
eines Arbeiters, Beschädigung der Maschine oder Beschädigung der Werkstücke.
Das soll die Steuerung einer Maschine verhindern, indem sie korrekt arbeitet.
Oder wenn wir einen Geschäftsprozess als Beispiel nehmen,
ein Kredit soll nur an jemanden vergeben werden,
von dem man auch erwarten, von dem die Bank auch erwarten kann,
erst in der Lage, das zurückzuzahlen, ohne ganz große Probleme.
Und natürlich soll das auch noch so laufen,
dass die Bank dabei keinen Minus macht
Soweit erst mal zu den Fragen, was ist Korrektheit?
Korrektheit bedeutet also, wir müssen das machen,
was die Software erwartet. Und wir können uns zunächst,
dass man nur darauf verlassen, was in der Anforderungsbeschreibung steht.
Das ist die Spezifikation, die Anforderungsbeschreibung. Kommt von
to specify etwas genau beschreiben. Und wir wollen natürlich,
das soll unter für alle Fälle funktionieren. Das heißt,
für jede mögliche Eingabe oder Folge von Eingaben erfolgt,
Die Reaktion der Software, so wie das der Anwender erwartet,
wie das gewinnt wird. Dabei ist natürlich die Frage,
inwiefern beschreibt die Spezifikation überhaupt das korrekt, was wir hier brauchen?
Ist denn alles tatsächlich jede dieser Eingaben, jede der Reaktionen
wirklich korrekt, widerspruchsfreie beschrieben? Wenn man natürliche Sprache hat,
gibt es genügend Fälle, wo man das,
wo die Aussage mehrdeutig ist, wo es davon abhängt,
was man dahinter versteht von der Interpretation, des Lesers.
Deswegen brauchen wir eine formale Spezifikation, eine Spezifikation,
die in einer formalen Syntax- und Semantik folgt.
Ja, also wir brauchen eine formale Semantik.
Und wenn wir überprüfen wollen, ob etwas Korrektes,
müssen wir das beweisen im Sinne der Mathematik.
Ja, und hier fallen Ihnen vermutlich verschiedene Sachen ein,
die Sie noch schon gehört haben oder parallel hören und dann noch hören werden.
In theoretischer Informatik, wie zum Beispiel zu Haare,
Kölkül oder formale Semantik-Partielle Korrektheit, all solche Sätze spielen dabei eine Rolle.
Und hierfür brauchen sie das. Deswegen ist das so
ein wichtiges Thema. Deswegen ist das im Informatikstudium in Deutschland
ist die theoretische Informatik relativ wichtig aufgehängt.
Bevor wir weiter mit Fehlern machen, möchte ich Sie darauf hinweisen,
dass das Wort Fehler im Deutschen mehrfach belegt ist.
In der englischen Sprache haben wir das ein bisschen besser sortiert.
Hier gibt es nämlich mehrere Begriffe im Bereich Fehler.
Zunächst gibt es den Begriff Miss Take.
Das ist eine menschliche Fehlhandlung. Ich habe etwas falsch getan
. Und das führt zu einem Fehler Fold
Fold, das ist der Fehler, zum Beispiel ein Fehler im Quelltext einer Software
, dann hat das der Entwickler etwas falsch gemacht.
Umgangssprachlich sagt man vielleicht auch manchmal Bug dazu,
dass dieser Bug ist Käfer, ja,
das kommt noch aus der Zeit,
als Rechner mechanisch funktionierten oder elektromechanisch mit Relais, da haben,
wenn da mal was Falsches rauskam oder das System hat nicht funktioniert,
dann haben die Entwickler gesagt,
there's a bug in the machine,
da sitzt ein Käfer oder eine Wanze oder sowas
da drin und die verhindert die richtige Kontaktgabe in dem Relais
Ich würde ja vermuten, dass damals schon manchmal was falsch
war und man hat es nur auf diese Tierchen geschoben.
Ja, aber auf jeden Fall funktioniert etwas nicht so, wie es sollte.
Failer ist ein weiterer Begriff und zwar geht es darum,
dass das System versagt, dass das System aufgrund von
solchen Fouls versagt und nicht das Richtige tut.
Zum Beispiel die Fahrstuhltür geht nicht auf oder die Waschmaschine lässt
so viel Wasser ein oder irgend sowas.
Und das ist dann mehr oder weniger
ein starkes Desaster
Arrow ist die Bezeichnung einfach nur, es entspricht nicht der
Forderung, es ist was Falsches. Also sie sehen,
im Englischen ist die Bezeichnung für Fehler sehr viel genauer möglich.
Im Deutschen müssen wir immer noch erklären, wenn wir das
Wort Fehler benutzen, was wir denn sagen. Hier steht,
wo das Ganze herkommt und noch ein weiterer Hinweis,
in Java finden Sie den Begriff Arrow auch,
aber da bedeutet er weder was anderes,
dabei da nicht das Fehlverhalten,
sondern dann steht er für eine Klasse von Fehlereignissen.
Dazu werden wir noch kommen. Wenn wir die Acceptions behandeln,
ja, da gibt es die Klasse Arror für solche Fehlerzustände,
von denen, bei denen man eigentlich als Entwickler nicht viel tun kann.
Ja, gehen wir weiter mit Fehlern. Ich hatte ja gesagt zu Anfang,
wir wollen erst mal die Wirkung von Fehlern verringern,
aber wir müssen davon ausgehen, dass Menschen immer Fehler machen.
Ja, das liegt in der Wesen der menschlichen Denk- und Arbeitsweise
und wir müssen davon ausgehen, das ist so eine langfristige Erkenntnis,
dass Menschen normalerweise drei Prozent Fehler machen.
Wenn sie sich ganz viel Mühe geben und gut motiviert sind,
gut qualifiziert sind, konzentriert sind,
nicht übermüdet,
dann machen sie
nur ein Prozent Fehler
So, jetzt möchte ich gar nicht drüber nachdenken,
was bei Operationen am Fließbein funktioniert.
Aber wir sind ja Programmierer. Und wenn wir sagen,
okay, so ein größeres System hat durchmals mal 100.000 Lines
auf Code, dann sind da 3.000 Fehler drin.
Wenn wir uns ganz viel Mühe geben und nur 1.000.
Aber das klingt erst mal viel. So,
und das ist also ein Punkt, der uns sehr stört.
Deswegen gibt es diese Aussage, fehlerfreie Softwaresysteme gibt es nicht.
Und zwar mit der Einschränkung, sobald wir einen gewissen Grad
an Komplexität,
an Umfang und Programmierzeilen haben
Also die Beispiele, die sie bei theoretischer Informatik
mit formaler Spezifikation haben, sind meistens ganz einfache Beispiele.
Da kann man die Korrektheit beweisen. Bei großen Systemen
fällt es sehr schwer. Es gibt tatsächlich Bereiche,
wo man das beweisen muss. Für Sicherheit,
für Systeme mit ganz hohen Sicherheitsanforderungen, ganz hohen Risiken,
dann versucht man die Einheiten sehr klein zu halten.
Wir gehen also davon aus, es sind Fehler da.
Das ist das, was diese Folie sagen soll.
Und wir versuchen, die Wirkung von Fehlern zu verringern.
Und dazu dient das, was ich hier als defensiven Programmierstil
erklären möchte
Die grundsätzliche, unsere grundsätzliche Herangehensweise sollte so sein,
wir sollten versuchen, Risiken zu vermeiden. Wir sollten immer davon ausgehen,
dass Fehler sind, wie die vergangene Folie und sagte.
Wir sollten immer so auf Fehler reagieren,
dass wir möglichst wenig Folgeschäden haben, minimale Auswirkungen.
Und diese Auswirkungen eben verringern oder gar vermeiden.
Das Gegenteil wäre das, was so die coolen Jungs machen.
Ja, man sucht schon mal das Risiko. Das ist cool. Ja,
das ist nett, das kann man alles machen,
das kann man dann machen, man in sicheren Umständen ist.
Also wenn da unten vielleicht schon der Rettungswagen steht oder der
Rettungshubschrauber in Handyreichweite, ist, wenn irgendwie mal was passiert.
Ja, das würde man wahrscheinlich nicht machen,
wenn man irgendwie im Yukon unterwegs ist, drei Wochen weg von der nächsten menschlichen Behausung.
Dann würde man vermutlich, sollte man als schlauer Mensch Risiken
vermeiden und das ist das, was wir hier tun.
Ein ähnlicher Begriff ist Robustheit, robust heißt unempfindlich gegenüber Störwirkungen. Ja,
Sie kennen das bei einem bei einem LKW,
ein robuster LKW, der geht halt nicht gleich kaputt,
wenn er mal da irgendwo von der Bottstein kann,
der Fehl fährt oder wenn da mal Sand und Staub ist.
Und was wir leider manchmal bei Anfängern oder bei Leuten,
die nicht richtig qualifiziert sind, hören, funktioniert doch, jedoch.
Ja, dann geht das nur in der speziellen Situation.
Wir sollten versuchen zu erreichen, dass es unter stabil
unter allen Situationen geht, insbesondere wenn Risiken sind.
Also mein Survival-Beispiel mit dem Yukon hatte ich genannt.
Okay, was bedeutet das konkret
Ich hatte die Grundsätze eben genannt und jetzt, wie gehen wir damit um?
Unten schon mal ein Beispiel aus der Literatur, es sieht aus,
als wäre es sehr alt, aber das ist sehr aktuell.
Zunächst sollten wir versuchen, Risiken zu vermeiden.
Das können wir so tun, indem wir Test-First machen.
Das ist das, was Sie hier bei uns lernen.
Ich sollte zuerst den Unitest schreiben, überlegen, was kann passieren,
was sind die möglichen Fehlerwelkungen und was sind für Reaktionen.
Und diese Reaktionen, dass sie sollte ich genau danach abstimmen.
Nicht einfach nur Programmabsturz oder Programm beenden.
Das ist die schlechtestmögliche Reaktion
Sondern wir sollten prüfen, was können wir denn sinnvoll tun,
Weiterarbeit im Fehlerarmen Zustand. Wir sollten immer denken,
dass Fehler da sind in den vorhergehenden Programmen.
Das sind so Parameter fehlerhaft sind,
dass unser Programm zum fehlerhaften Zeitpunkt aufgerufen wird.
Das heißt, wir sollten Vorbedingungen formulieren und diese Vorbedingungen auch prüfen.
Wir sollten immer versuchen, einen Fehlerarmen Zustand zu erreichen.
Der fehlerarme Zustand ist bei einer Maschine, alles anhalten.
Beim Fahrstuhl ins Erdgeschoss fahren,
die Türen aufmachen
Bei einer Maschine, die Wasser einlässt, Wasser zufuhrsperren.
Immer so den Fehlerärmsten Zustand annehmen. Und die Auswirkungen verringern,
dass man irgendwie versucht, die Weiterarbeit zu ermöglichen.
Beispiel eine Software, die in einer Bank eingesetzt wird,
vielleicht am Schalter. Oder da ist irgendein interner Berechnungsfehler,
dann wäre es ganz blöd, einfach nur Programmabbruch zu machen.
Dann gibt es irgendwie die Fehlermeldung internal error x, 433.
Damit kann keiner was anfangen. Eher noch,
wenn man sagt, also lieber Bediener,
es tut uns leid, diese Berechnung ist zurzeit nicht möglich.
Der Administrator wurde informiert
Ja, so, das ist doch besser und dann bin ich zurück in meiner vorhergehenden Funktion.
Da kann ich zwar nicht das machen,
was ich gerade wollte oder nicht mit korrekten Werten,
aber es geht erst mal weiter. Oder bei einer,
nehmen wir an, wir sind in so einem schicken Flugzeug,
wir fliegen gerade und irgendwas ist da so ein Sensor kaputt.
Ja, da wollen wir ja doch nicht,
dass das Flugzeug die Steuerung plötzlich nicht mehr geht,
sondern da wollen wir erreichen,
dass dann die Steuerung mit den Wertenden vorher oder mit einem Ersatzsensor oder mit auf Heimsteuerung oder irgendwas gemacht wird, jedenfalls fehlerarmer Zustand.
Ja, hier unten steht das nochmal ein bisschen konkret,
was hier dazugehört, jemand von den Leuten,
die diesen defensiven Programmstil vor Jahren schon umgesetzt haben auf konkrete Programmiersprache.
Das ist das also ein bisschen konkreter.
Soweit dazu und wir kommen als nächsten Schritt dann zum Vertragsmodell.
Das ist das nächste Video