Können wir garantieren, dass ein Programm niemals schief geht?

10

Wir haben hier ein System. In letzter Zeit gibt es eine falsche Berechnung in einer der Zahlen im vom System generierten Bericht. Aufgrund unserer Erfahrung sind wir seit einigen Jahren nie mehr auf Probleme / Fehler in diesem System gestoßen.

Da der Schreiber dieses Systems bereits gegangen war, können wir die Programme kaum verfolgen. Wir haben jedoch die Eingabedaten und die Einstellungen überprüft und sie sind richtig.

Meine Frage ist nun, wird ein Computerprogramm plötzlich ohne logischen Grund schief gehen? Wenn ich auf dem Server-Computer zuschlage, wird eine der vom Computer berechneten Zahlen zu einer anderen Zahl und macht die Berechnung falsch?

Ich stimme zu, dass meine Idee dort ziemlich verrückt ist, aber ich möchte nur wissen, wie können wir wissen, dass das Problem nicht durch das Programm und die Eingabe verursacht wird, sondern durch einige andere Faktoren?

PS Dieses verrückte System hat kein Protokoll.

lamwaiman1988
quelle
8
Eines der RAM-Module in meinem PC hatte genau ein Fehlerbit, sodass ein Programm, das unglücklicherweise dieses Bit verwendet, möglicherweise ein falsches Ergebnis liefert. Das Ausführen von memtest86 auf Ihrem Computer ist möglicherweise eine einfache Möglichkeit, solche Probleme auszuschließen.
user281377
16
Ja, durch Löschen
Steven A. Lowe
6
Einige Hardware-Teile weisen tatsächlich Fehler auf. Es ist ein Beweis für die damaligen Chiphersteller, dass sie so wenige sind. Ich würde die Software zuerst vermuten.
Es gibt immer einen logischen Grund, warum ein Programm schief geht. Ein Slam ist ein logischer Grund.
Mouviciel
2
Sie können eine statistische Bombe oder einen böswilligen Compiler oder einen fehlerhaften RAM, eine Festplatte oder einen Virus haben, der in Ihren RAM schreiben oder das Betriebssystem oder den Betriebssystemfehler oder einen Fehler in einer Bibliothek irgendwo oder den berühmten Fehler beim Zusammenführen von Sortierungen ändern kann. oder ...
Job

Antworten:

8

Ich würde nein sagen!

Theoretisch lautet die Antwort nein, wir können nur testen auf:

  • eine begrenzte Anzahl von Umgebungen.
  • eine begrenzte Anzahl von Zeitskalen.
  • eine begrenzte Anzahl von Testfällen.

Dies ist erheblich weniger als die insgesamt mögliche Anzahl von Umgebungen, Zeiten und Fällen, auf die das Programm in seiner Lebensdauer stoßen kann. Wir haben auch wenig Wissen über die Zukunft. Sollten Sie mit einer Inflation von 10.000% programmieren, sollte Ihr Programm mit einer neuen Super-Super-31-Bit-Architektur fertig werden?

Die Theorie wird durch Erfahrungen gestützt, die ich persönlich gemacht habe:

  • Programme brechen ab, wenn sie in ein anderes Gebietsschema verschoben werden. Nach "MAI" suchen, wenn der Monat "MAI" war.
  • Programme, bei denen Tests für eine neue Version des Compilers fehlgeschlagen sind. Ein Fehler in der vorherigen Version in Verbindung mit einem Fehler im Programm führte zum korrekten Ergebnis.
  • Programme, die auf einer neuen Version des Betriebssystems brechen. Wenn Solaris die Standardanzahl der Verzeichniseinträge erhöhte, gab der von ftok () zurückgegebene SMALLINT für die erste Datei im Verzeichnis immer Null zurück.
  • Programme brechen ab, weil es das erste Mal war, dass sie auf eine bestimmte Kombination von Eingaben stießen, die sowohl gültig als auch unerwartet waren und niemals auf negative Zinssätze für Einlagen, zu versendende Nullgewichtsartikel und Artikel von so geringem Wert getestet worden wären Die Mehrwertsteuer konnte nicht berechnet werden usw. usw.
James Anderson
quelle
Ich sage ja, mit einer Bestimmung - Wenn Sie ein Multithreading haben. Schon mal was von "Race Condition" gehört.
Mattnz
6

Wenn Sie mit einem identischen Zustand beginnen, ist das Ergebnis theoretisch identisch. In der Realität ist es so gut wie unmöglich, einen identischen Ausgangszustand in Geräten mit "Servergröße" sicherzustellen.

Nehmen Sie nicht initialisierte Variablen. Schauen Sie sich diesen Code an:

  short i;

  if(i==-1)
  {
        //do something special
  }
  else
  {
        i=0;
        //do something else
  }

Dies führt in 65536 Läufen zu unerwarteten Ergebnissen. Und wenn Sie nicht sicherstellen, dass sich der Speicher vor jedem Lauf im selben Zustand befindet, iist er völlig zufällig.

Es gibt Hunderte ähnlicher Möglichkeiten, wie Fehler auftreten können, wenn unvorhersehbare Elemente des Anfangszustands, die jemand vergessen hat, zu überschreiben, oder Grenzfälle, die selten auftreten - Race-Bedingungen in einer Umgebung mit mehreren Threads, Zugriff außerhalb der Grenzen des Arrays, Festplatten-E / A auf einem beschädigten Dateisystem und demnächst.

Wenn Sie beweisen können, dass das Programm fehlerfrei ist, gibt es nur die kosmischen Strahlen, die es brechen können. Der mathematische Beweis der Richtigkeit von etwas Komplexerem als zwei verschachtelten Schleifen geht jedoch weit über den Rahmen der größten Systeme hinaus (und kostet ein kleines Vermögen), und im Übrigen kann man nur hoffen.

SF.
quelle
6

Meine Frage ist nun, wird ein Computerprogramm plötzlich ohne logischen Grund schief gehen?

Wenn Sie genau dieselbe Computerumgebung haben, führt eine Eingabe X für ein Programm immer zu demselben Ergebnis R. In der Praxis ist es selten, dass ein einzelnes Programm isoliert ausgeführt wird. Die einfachste Anwendung läuft heute unter einem Betriebssystem und teilt den Speicher mit anderen Programmen, die möglicherweise gleichzeitig in den Speicher geladen werden. Diese Programme können den Speicher so verändern, dass ein bestimmtes Programm fehlerhaft funktioniert. Dies ist beispielsweise ein bekanntes Problem bei Variablen vom Typ 'Zeiger'. Normalerweise verursachen solche Fehler ein abnormales Systemverhalten und keine falschen Berechnungsergebnisse.

In Ihrem Fall gehe ich davon aus, dass das Problem möglicherweise nicht das ist, was ich oben beschrieben habe (und normalerweise auch nicht). Das Problem kann sein, dass:

  • Das Programm hat die falschen Datentypen verwendet, um das Ergebnis zu berechnen. Dieser Fehler tritt nur dann auf, wenn spezielle Werte verwendet werden.
  • Das Programm hat einen Berechnungsfehler (aufgrund einer logischen Bedingung) festgestellt, den Fehler jedoch nicht behandelt und trotzdem das Ergebnis erstellt. (zB Mischen von Float und Integer-Arithmetik)
  • Eine Geschäftsregel oder eine logische Bedingung wurde nicht korrekt codiert. Die eingegebenen Daten stellen diese Bedingung dar, es wurde jedoch die falsche Berechnung verwendet. (z. B. Betrag vom Kontobetrag abziehen, bevor zuerst der Betrag auf dem Konto überprüft wird).
  • Verwenden von Formeln, die nur für bestimmte Zahlenbereiche gelten, die Daten jedoch unterschiedliche Bereiche enthalten. (zB Berechnung eines Zinssatzes anhand eines Wertebereichs)

Aus den oben genannten und vielen anderen Gründen geben Software-Leute so viel Ressourcen aus, um korrekte Software zu erstellen. Es treten jedoch immer noch Softwarefehler auf, aber die Fehler sind "logisch" und haben einen Grund. Der Grund ist nur nicht offensichtlich zu einigen ohne gute Forschung. Im Allgemeinen ist getestete Software vorhersehbar und führt nicht zu zufälligen Ergebnissen. Aufgrund der Komplexität einiger Programme und anderer Faktoren können sogar getestete Programme schief gehen. In diesem Fall sind Fehler jedoch logisch.

Wenn ich auf dem Server-Computer zuschlage, wird eine der vom Computer berechneten Zahlen zu einer anderen Zahl und macht die Berechnung falsch?

Die Antwort lautet im Allgemeinen Nein, Software ist in diesem Sinne nicht fragil.

Sie können die Fälle isolieren, in denen der Fehler auftritt, die Ähnlichkeit zwischen diesen Datensätzen ermitteln, die den Fehler verursachen, und den Unterschied zwischen diesen Sätzen und den anderen Sätzen ermitteln, die das richtige Ergebnis liefern. Möglicherweise können Sie die spezifischen Werte identifizieren, die das Problem verursachen. Beispielsweise stellen Sie möglicherweise fest, dass jedes Mal, wenn eine Variable einen negativen Wert hat, das Ergebnis falsch ist.

Aktualisierte Informationen zu Speicherbeschädigungsfehlern: Weitere Informationen finden Sie unter Speicherbeschädigung

Keine Chance
quelle
Ich habe selbst über zusammengesetzte Rundungsfehler als Ursache für solche Probleme nachgedacht. Sie werden möglicherweise lange Zeit nicht angezeigt, bis genau die richtige (oder falsche) Kombination von Eingaben dazu führt, dass sie alle zusammen ein Ergebnis erzielen, das nicht dem entspricht, was es sein sollte.
Jwenting
3
Moderne Betriebssysteme erlauben es Programmen nicht, den Speicher anderer Programme zu ändern (oder sogar zu lesen).
Péter Török
Ja, moderne Betriebssysteme erlauben nichts dergleichen.
DeadMG
"Wenn Sie genau dieselbe Computerumgebung haben, führt eine Eingabe X für ein Programm immer zum gleichen Ergebnis R" Ich bin mir nicht sicher, ob dies wahr ist. Was ist, wenn einer der SR-Latches in den Speicherkomponenten aufgrund einer früheren Beschädigung zwei Einsen erhält? en.wikipedia.org/wiki/…
Yam Marcovic
@DeadMG und Péter Török bedanken sich für Ihr Feedback. Ich habe die Nachricht bearbeitet und einen Verweis auf eine Seite hinzugefügt, auf der beschrieben wird, dass das Problem weiterhin auftreten kann (ich weiß, wie im Text erwähnt, dass es höchst unwahrscheinlich ist).
NoChance
5

Können Sie garantieren, dass ein Programm keine Fehler aufweist und niemals schief gehen wird? Nein, leider nicht.

Können Sie nachweisen, dass ein Programm eine ausreichend geringe Anzahl von Fehlern aufweist, sodass die Kosten für das Auffinden und Beheben dieser Fehler den Nutzen dieser Aktion bei weitem übersteigen? Es klingt für mich so, als hättest du es schon getan.

Um eine alte Statistikmaxime zu paraphrasieren, sind alle Programme falsch, aber einige Programme sind nützlich.

John N.
quelle
1
+1 für "Alle Programme sind falsch, aber einige Programme sind nützlich"
ein CVn
Ich denke nicht, dass diese Antwort tatsächlich relevant ist. Es scheint, als würde er fragen, ob ein korrektes Programm aufgrund eines Umweltfehlers manchmal unerwartet funktioniert.
Yam Marcovic
Mein ganzer Punkt ist, dass kein Programm jemals "korrekt" ist. Alles ist immer in Arbeit und immer nur richtig, bis es falsch ist. Informatik ist schließlich eine Wissenschaft . Ich verstehe, was Sie sagen, und das könnte mehr sein, wo der Fokus seiner Frage liegt. Ich denke jedoch, dass meine Antwort umso relevanter ist, als weniger.
John N
@ Hallainzil: Ich glaube, ich habe erfolgreich richtig geschrieben "Hallo Welt!" Programme und dergleichen. Ich habe sogar korrekte nützliche Programme geschrieben (obwohl keine großen).
David Thornley
2

Ich neige dazu, nein zu sagen . Sie können nicht beweisen, dass ein Programm niemals schief gehen oder ein falsches Ergebnis liefern wird, selbst wenn Sie von einer perfekten Eingabe ausgehen können.

Raku erwähnte den formalen Beweis der Richtigkeit. Das ist eine Sache, die zu beachten ist, aber wenn ich mich nicht völlig irre, muss dies immer noch eine perfekte Ausführungsumgebung voraussetzen. Mit etwas Zeit und Mühe können Sie vielleicht beweisen, dass das Programm korrekt ist , aber das beweist nicht unbedingt, dass es auch bei perfekter Eingabe immer die richtigen Ergebnisse liefert. Die Ausführungsumgebung ist wichtig. Und ich würde vorsichtig sein anzunehmen, dass die Eingabe auch immer perfekt ist.

Aus diesem Grund werden in bestimmten Hochverfügbarkeitssituationen mehrere völlig unabhängige Implementierungen und Ausführungsumgebungen verwendet und die Ergebnisse verglichen, um sicherzustellen, dass sie innerhalb einer akzeptablen Fehlergrenze voneinander liegen. In einigen Situationen kann dieser Spielraum durchaus Null sein. Bereits in den 1960er Jahren wurde dies als wichtig genug erachtet, um separate Sätze von Computerhardware in Raumfahrzeuge einzubeziehen. Selbst wenn eine fehlerhafte statische Entladung, kosmische Strahlung oder was auch immer beide Computer gleichzeitig beeinflussen würde, ist die Wahrscheinlichkeit, dass beide auf die gleiche Weise betroffen sind (insbesondere wenn beide noch funktionieren und gültige Ergebnisse liefern), gering. Die Wahrscheinlichkeit, dass sich derselbe Fehler in zwei völlig getrennte Implementierungen einschleicht, ist ebenfalls äußerst gering. Und so weiter.

ein CVn
quelle
1

Das meiste (Standard-) Computing ist deterministisch, würde ich denken.

Richten Sie es nach Möglichkeit so ein, dass ein Stapel von 1000 oder 10000 usw. Iterationen mit denselben Eingabedaten ausgeführt wird, und stellen Sie sicher, dass die Ergebnisse gleich sind.

Stellen Sie sicher, dass die aktuellen Werte, die in die Berechnung einfließen, irgendwo einen Über- oder Unterlauf verursachen (wenn es sich um ein älteres System handelt, war es möglicherweise nicht für eine so lange Verwendung vorgesehen).

Y2K11 jemand?

jonsca
quelle
N Iterationen durchzuführen und die Ergebnisse zu überprüfen, beweist keine Richtigkeit. Bestenfalls zeigt es, dass innerhalb des Beispielsatzes kein Fehler vorliegt, und selbst dies setzt voraus, dass Ihr Testfall (und dessen Implementierung sowie dessen Ausführung) absolut korrekt ist. Das Testen ist zwar sehr nützlich, geht jedoch nicht auf die Bedenken des OP ein.
Ein CVn
@Michael Vielleicht sollte ich klarstellen, ich schlage nicht vor, irgendetwas mit diesem Ansatz zu "beweisen", aber wenn es unzählige weitere Iterationen gibt, ohne den Fehler jemals wieder zu zeigen, würde ich an Sonnenflecken denken und nicht an einen ganzzahligen Überlauf. Es gibt Ihnen immer noch mehr Einblick als nicht, IMHO.
Jonsca
1

Wenn Sie nicht jedes einzelne Bit in der Maschine und jeden durch die Schaltung fließenden elektrischen Impuls steuern können, können Sie nicht mit absoluter Sicherheit garantieren, dass mit Ihrem Programm nichts schief geht. Speichermodule fallen aus, CPUs können überhitzen und Fehler verursachen, Festplatten können Daten verschlüsseln und Netzteile können Rauschen in das System einbringen. Je teurer die Hardware und je redundanter die Hardware ist, desto unwahrscheinlicher ist es, dass diese Dinge auftreten, aber irgendwann kann die Hardware ausfallen.

Dann haben Sie das Betriebssystem mit Fehlern, die mit den arkansten Mitteln gekitzelt werden können, die man sich vorstellen kann. Compiler haben möglicherweise auch obskure Fehler, die nur darauf warten, Ihren makellosen Code geschickt in schwer zu verfolgende Fehler umzuwandeln. Es ist ein Dschungel da draußen, und Ihre schlechte Software ist für all dies anfällig. ACHTUNG!

Und meiner Erfahrung nach müssen wir meistens, wenn es einen Fehler in einer Berechnung gibt, nie annähernd so weit graben, um den Schuldigen zu finden. Im Allgemeinen lassen sich fast alle Fehler, die ich in der Unternehmenswelt gesehen habe, mit den richtigen Debugging-Tools und etwas Ellbogenfett leicht finden.

Mit anderen Worten, obwohl die Hardware und das Betriebssystem möglicherweise nicht perfekt sind, müssen Sie sich wahrscheinlich nie um diese Detailgenauigkeit kümmern. Finden Sie einfach jemanden, der die Sprache kennt und mit einem Debugger vertraut ist, und vertiefen Sie sich.

"Einfachere Erklärungen sind bei sonst gleichen Bedingungen im Allgemeinen besser als komplexere." - Zusammenfassung von Occams Rasiermesser.

Craig Maloney
quelle
0

Ja, wenn Sie auf ein System treffen, können Teile so weit gebogen und / oder bewegt werden, dass ein vorübergehender Leerlauf (oder möglicherweise ein Kurzschluss, obwohl dies wahrscheinlich weniger wahrscheinlich ist) verursacht wird.

Jerry Sarg
quelle
0

Der erste Computer, den ich besaß, war ein Altair 8080 mit 256 Byte Speicher. Die Eingabe erfolgte über Konsolenschalter und die Ausgabe über einige blinkende Lichter. Wenn Sie kosmische Strahlung und Hardwarefehler nicht zulassen, könnte ich meiner Meinung nach beweisen, dass einige Programme, die ich darauf ausgeführt habe, immer die gleichen Ergebnisse liefern.

Seitdem nein.

ddyer
quelle
0

Tests zeigen das Vorhandensein und nicht das Fehlen von Fehlern (Edsger W. Dijkstra)

Wenn Sie durch Testen beweisen möchten, dass Ihr Programm ordnungsgemäß funktioniert, funktioniert es nicht.

Es gibt jedoch einige Ansätze in der theoretischen Informatik, bei denen Sie einen formalen Beweis für die von Ihnen geschriebene Software entwickeln. Abhängig von der Komplexität Ihres Systems kann dies jedoch ein langwieriger Prozess sein. Wenn Ihr System jedoch mit einem eingeschränkten Befehlssatz arbeitet, können Sie mit diesem Ansatz erfolgreich sein.

Raku
quelle
Hast du die Frage gelesen?
Winston Ewert
Ich habe es getan und ich sage, dass er keine Tests verwenden kann, um zu garantieren, dass ein Programm niemals schief gehen wird. Das sagt der Titel seiner Frage, oder?
Raku
Ja, der Titel scheint das zu sagen. Der Körper tut dies eindeutig nicht.
Winston Ewert
0

Hardware- und Softwareumgebungen sind in ständigem Wandel. Beispiele für Änderungen an beweglichen Teilen, Elektrizität, Temperatur, Staub und Betriebssystemcode sind Beispiele.

Daher halte ich es nicht einmal für wahrscheinlich oder zu erwarten, dass sich ein Computersoftwareprogramm immer gleich verhält, da sich die Umgebung ständig ändert.

Die Software kann erwartungsgemäß lange laufen, aber irgendwann ändert sich entweder eine kleine Änderung an der Host-Betriebssystemsoftware, die sich auf das betreffende Programm auswirkt, oder die Hardware wird einen Wert haben.

Ich spreche über aktuelle Computer.

SoftwareCarpenter
quelle
0

Meine Frage ist nun, wird ein Computerprogramm plötzlich ohne logischen Grund schief gehen? Wenn ich auf dem Server-Computer zuschlage, wird eine der vom Computer berechneten Zahlen zu einer anderen Zahl und macht die Berechnung falsch?

Die Antwort auf diese Frage ist nicht bekannt. Es ist unmöglich zu beweisen, dass für das Universum, in dem wir gerade leben, immer etwas zutrifft. Stattdessen machen wir Annahmen und beweisen, dass, wenn die Annahmen zutreffen, auch eine komplizierte Eigenschaft gilt. Dies garantieren formal verifizierte Programme. Die meisten Programme werden jedoch nicht offiziell überprüft, sondern versuchen, durch die Bereitstellung von Tests Vertrauen aufzubauen. Diese Tests geben Ihnen die Gewissheit, dass das von Ihnen verwendete Programm zumindest zeitweise funktioniert, sofern die Tests das tun, wofür sie entwickelt wurden, und dass die von Ihnen getroffenen Annahmen zutreffen.

dan_waterworth
quelle
-1

Es ist kaum möglich, dass das Problem durch einen RAM-Fehler verursacht wird, dies ist jedoch relativ (sehr) unwahrscheinlich. Führen Sie einen Speichertest durch, aber seien Sie bereit, den Code zu durchsuchen.

James McLeod
quelle
An den Downvoter - ich habe gesehen, dass dies passiert ist. Einmal.
James McLeod