プログラムが失敗しないことを保証できますか?


10

ここにシステムがあります。最近、システムによって生成されたレポートの数値の1つに誤った計算があります。私たちの経験では、このシステムで何年も問題やエラーに遭遇したことはありません。

このシステムの作成者はすでに行っているため、プログラムを追跡することはほとんどできません。しかし、入力データ、設定を確認し、それらが正しいことを確認しました。

今、私の質問は、論理的な理由なしにコンピュータプログラムが突然失敗するのでしょうか。サーバーマシンを叩くと、コンピューターが計算している数値の1つが別の数値になり、計算が間違ってしまいますか?

私はかなり狂っているという考えに同意しますが、知りたいのですが、問題がプログラムと入力ではなく、他のいくつかの要因によって引き起こされていることをどのようにして知ることができますか?

PSこの狂ったシステムにはログがありません。


8
PCのRAMモジュールの1つに欠陥ビットが1つだけあったため、そのビットを使用するのに不幸なプログラムは誤った結果をもたらす可能性があります。あなたのマシンでmemtest86を実行することは、その種の問題を排除する簡単な方法かもしれません。
user281377

16
はい、削除します
スティーブンA.ロウ

6
一部のハードウェアには実際にバグがあります。当時のチップメーカーが少数であることの証です。私は最初にソフトウェアを疑うでしょう。

プログラムが失敗するのには、常に論理的な理由があります。スラムは論理的な理由です。
mouviciel

2
統計爆弾、悪意のあるコンパイラ、RAM、ディスク、またはウイルスに感染して、RAMに書き込んだり、OSやOSのバグを修正したり、どこかライブラリのバグを修正したり、有名なマージソートバグを作成したりできます。または...
ジョブ

回答:


8

ノーだ!

理論的には答えは「いいえ」です。テストできるのは以下のみです。

  • 限られた数の環境。
  • いくつかの限られた数のタイムスケール。
  • いくつかの限られた数のテストケース。

これは、プログラムが存続期間中に遭遇する可能性のある環境、時間、およびケースの総数よりもかなり少ないです。また、プログラムで10,000%のインフレに対処する必要がある場合、プログラムが非常に大きな新しい31ビットアーキテクチャに対処する必要がある場合にも、将来についてほとんど知識がありません。

理論は私が個人的に遭遇した経験によってサポートされています-

  • 別のロケールに移動するとプログラムが壊れる。月が「MAI」のときに「MAY」を確認しています。
  • 新しいバージョンのコンパイラでテストに失敗したプログラム、以前のバージョンのバグとプログラムのバグの組み合わせにより、正しい結果が得られました。
  • OSの新しいリリースで動作するプログラム。Solarisがディレクトリエントリのデフォルト数を増やしたとき、ftok()によって返されたSMALLINTは、ディレクトリ内の最初のファイルに対して常にゼロを返しました。
  • 有効かつ予想外であり、テストされなかった特定の入力の組み合わせに出会ったのは初めてだったため、プログラムは壊れていました-預金のマイナス金利、出荷される重量ゼロの商品、そのような低い値の商品VATを計算できませんでした。

私はイエスと言いますが、規定があります-マルチスレッドを使用している場合。「レースコンディション」について聞いたことがある。
mattnz 2012

6

理論的には、同じ状態で開始すると、結果は同じになります。実際には、「サーバーサイズ」の機器で同一の初期状態を保証することはほとんど不可能です。

初期化されていない変数を取得します。このコードを見てください:

  short i;

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

これにより、65536回実行すると予期しない結果が生じます。そして、各実行の前にメモリが同じ状態になることを保証しない限り、i完全にランダムになります。

誰かがオーバーライドするのを忘れた初期状態の予測できない要素、またはまれに発生する境界ケースに続いてエラーがポップアップする数百の同様の方法があります-マルチスレッド環境での競合状態、境界外のアレイアクセス、破損したファイルシステムのディスクIO、など。

プログラムにバグがないことを証明できれば、それを壊すことができるのは宇宙線だけです。しかし、2つのネストされたループよりも複雑なものの数学的正しさの数学的証明は、最大のシステムの範囲をはるかに超えており(わずかなコストがかかります)、それ以外の場合は期待できます。


6

今、私の質問は、論理的な理由なしにコンピュータプログラムが突然失敗するのでしょうか。

まったく同じコンピューティング環境がある場合、プログラムへの入力Xを指定すると、常に同じ結果Rが生成されます。実際には、単一のプログラムを分離して実行することはほとんどありません。今日、最も単純なアプリケーションはオペレーティングシステムで実行され、同時にメモリに「ロード」される他のプログラムとメモリを共有します。これらのプログラムは、特定のプログラムを誤動作させるような方法でメモリを変更する可能性があります。これは、たとえば「ポインタ」型の変数の有名な問題です。通常、このようなエラーはシステムの異常な動作を引き起こし、間違った計算結果にはなりません。

あなたのケースでは、問題は私が上で説明したものではないかもしれません(そして通常はそうではありません)。問題は次のとおりです。

  • プログラムは誤ったデータ型を使用して結果を計算しました。そのエラーは、特別な値が使用された場合にのみ現れます。
  • プログラムは(論理条件が原因で)計算中にエラーを検出しましたが、エラーを処理せず、結果を生成しました。(例:浮動小数点と整数演算の混合)
  • ビジネスルールまたは論理条件が正しくコーディングされていない場合、入力されたデータはこの条件を表しますが、誤った計算が使用されました。(例えば、口座の金額を最初にチェックする前に、口座の金額から金額を引きます)。
  • 特定の範囲の数値にのみ適用される数式を使用するが、データに異なる範囲が含まれている。(例:値の範囲に基づいて金利を計算する)

上記およびその他多くの理由により、ソフトウェアの人々は正しいソフトウェアを作成するために多くのリソースを費やしますが、ソフトウェアエラーは引き続き発生しますが、エラーは「論理的」であり、理由があります。良い研究のない人にも。したがって、一般的にテスト済みのソフトウェアは予測可能であり、ランダムな結果を生成しません。一部のプログラムの複雑さやその他の要因により、テスト済みのプログラムでも問題が発生する可能性がありますが、それが発生した場合、エラーは論理的な理由によるものです。

サーバーマシンを叩くと、コンピューターが計算している数値の1つが別の数値になり、計算が間違ってしまいますか?

答えはノーです。ソフトウェアはその意味で壊れやすいものではありません。

あなたができることは、エラーが発生しているケースを分離し、エラーを引き起こしているこれらのデータセット間の類似性を見つけ、これらのセットと正しい結果を生成する他のセットとの違いを見つけることです。問題の原因となっている特定の値のセットを特定できる場合があります。たとえば、変数が負の値を持つたびに、結果が間違っていることがあります。

メモリ破損エラーに関する更新情報:メモリ破損を参照してください


私自身、そのような問題の原因として、複合丸め誤差について考えていました。入力の正しい(または間違った)組み合わせがすべて組み合わされて、本来あるべき状態から外れる結果になるまで、それらは長時間表示されない場合があります。
2010年

3
最近のオペレーティングシステムでは、プログラムが他のプログラムに属するメモリを変更(または読み取り)することはできません。
ペーテルTörök

はい、最近のOSではそのような性質は一切許可されていません。
DeadMG

「あなたが正確に同じコンピューティング環境を持っている場合、プログラムへの入力Xが与えられると、常に同じ結果Rが生成されます」これが本当かどうかはわかりません。以前の破損により、メモリコンポーネントのSRラッチの1つが2の1を取得した場合はどうなりますか?en.wikipedia.org/wiki/…–
Yam Marcovic、

@DeadMGとPéterTörökのフィードバックに感謝します。メッセージを編集し、問題が引き続き発生する可能性があることを説明するページへの参照を追加しました(テキストで言及されているように、ほとんどあり得ないことを知っています)。
NoChance、2011年

5

プログラムにバグがなく、問題が発生しないことを保証できますか?残念ながら、そうではありません。

プログラムに含まれるバグの数が十分に少ないため、それらを見つけて修正するコストがそのアクションの利点をはるかに超えることを実証できますか?すでにお持ちのようです。

古い統計の格言を言い換えると、すべてのプログラムは間違っていますが、いくつかのプログラムは便利です。


1
「すべてのプログラムは間違っていますが、一部のプログラムは有用です」の+1
CVn

この答えは実際には関係ないと思います。何らかの環境上の欠陥が原因で、正しいプログラムが予期せず動作することがあるかどうかを尋ねているようです。
Yam

私の要点は、「正しい」プログラムは決してないということです。すべては常に進行中の作業であり、それが間違っているまではいつまでも正しくありません。コンピュータサイエンスは、科学、すべての後に。私はあなたが何を言っているかを理解しています、そしてそれは彼の質問の焦点がより多くの場所であるかもしれません。ただし、そうすることで、私の回答はそれほど重要ではなく、より適切になります。
John N

@Hallainzil:正しい「Hello、World!」を正しく書いたと思います プログラムなど。私は正しい便利なプログラムも書いています(大きなプログラムではありません)。
David Thornley、2011年

2

私が言うことを傾けていいいえ、あなたはプログラムがすることを証明できない決してあなたは完璧な入力を想定することができたとしても、うまくいかなかったり、誤った結果を提供します。

楽は正しさの正式な証明に言及した。それは考慮すべきことの1つですが、私が完全に誤解しない限り、それでも完璧な実行環境を想定する必要があります。したがって、ある程度の時間と労力をかけて、プログラムが正しいことを証明できるかもしれませんが、完全な入力があっても、必ずしも正しい結果が得られるとは限りません。実行環境が重要です。また、入力も常に完全であると想定することにも注意が必要です。

これが、特定の高可用性状況で、複数の完全に独立した実装と実行環境が使用され、結果が比較されて、それらが互いに許容可能な誤差範囲内にあることを確認するためです。場合によっては、そのマージンがゼロになることもあります。1960年代にさかのぼって、これは宇宙船に個別のコンピューティングハードウェアセットを含めるのに十分重要であると考えられていました。誤った静電放電、宇宙線などが両方のコンピュータに同時に影響を与える場合でも、両方が同じように影響を受ける可能性(特に、両方がまだ機能しており、有効に見える結果を生成している場合)はごくわずかです。同じバグが2つの完全に異なる実装に忍び込む確率も非常に小さいです。等々。


1

ほとんどの(標準の)コンピューティングは決定論的だと思います。

可能であれば、同じ入力データで1000または10000などの反復を行うように設定し、結果が同じになることを確認します。

計算に使用される現在の値がオーバーフローまたはアンダーフローの原因となることを確認してください(古いシステムの場合、これほど長く使用することを意図していない可能性があります)。

Y2K11誰か?


N回の反復を実行して結果を検証しても、正確性は証明されません。せいぜい、サンプルセット内にエラーがないことを証明します。それでも、テストケース(およびその実装とその実行)が完全に正しいと想定しています。テストは非常に便利ですが、OPの懸念には対応していません。
CVn、2011年

@Michael多分私は明確にする必要があります、私はこのアプローチで何かを「証明」しようとすることを提案していませんが、それがエラーを再び表示することなく何度も繰り返す場合、私は黒点と整数オーバーフローを考えていません。それでもなお、私よりもより多くの洞察が得られます。
jonsca、2011年

1

マシン内のすべてのビット、および回路を流れるすべての電気インパルスを制御できない限り、プログラムに問題が発生しないことを確実に保証することはできません。メモリモジュールが故障し、CPUが過熱してエラーが発生したり、ハードドライブがデータをスクランブルしたり、電源装置がシステムにノイズを発生させたりする可能性があります。ハードウェアが高価で、ハードウェアの冗長性が高いほど、これらの事態が発生する可能性は低くなりますが、ハードウェアが故障する可能性があります。

それからあなたはオペレーティングシステムを持っています、想像できる最も不可解な手段によってくすぐられることができるバグで。コンパイラーは、手つかずのコードをトレースが困難なバグに巧みに変換するのを待っているだけのあいまいなバグを持っている場合もあります。そこはジャングルであり、貧弱なソフトウェアはこれらすべてに対して脆弱です。外を見る!

そして、私の経験では、たいていの場合、計算にバグがあるときはいつでも、犯人を見つけるためにその近くまで掘る必要はありません。一般的に言えば、私が企業の世界で見たほとんどすべてのバグは、適切なデバッグツールといくつかのエルボーグリースで簡単に見つけることができます。

つまり、ハードウェアとOSは完璧ではないかもしれませんが、その詳細レベルについて心配する必要はないでしょう。言語を知っていて、デバッガーに便利な人を見つけて、掘り下げてください。

「より単純な説明は、他のものは同等であり、一般により複雑な説明よりも優れています。」-Occamのかみそりの要約。


0

はい、システムにぶつかると、部品が曲がったり移動したりして、一時的に断線する可能性があります(または可能性は低いですが、短絡する可能性があります)。


0

私が最初に所有したコンピュータは、256バイトのメモリを備えたAltair 8080でした。入力はコンソールスイッチから、出力はいくつかの点滅するライトからでした。宇宙線とハードウェア障害を許可しない場合、私が実行したいくつかのプログラムが常に同じ結果を生成することを証明できると思います。

それ以来、いいえ。


0

テストはバグの欠如ではなく存在を示します(Edsger W. Dijkstra)

テストによってプログラムが正しく動作することを証明しようとしても、動作しません。

ただし、理論的なコンピュータサイエンスには、作成したソフトウェアの正式な証明を作成するいくつかのアプローチがあります。システムの複雑さによっては、これは面倒なプロセスになる場合があります。ただし、ご使用のシステムが制限されたコマンドセットで機能する場合は、このアプローチで成功する可能性があります。


質問を読みましたか?
Winston Ewert 2012年

私はそうしました、そして彼はテストを使ってプログラムが決して失敗しないことを保証することができないと言っています。それが彼の質問のタイトルが言っていることですよね?
Raku

はい、タイトルはそれを言っているようです。体は明らかにそうではありません。
Winston Ewert 2012年

0

ハードウェアとソフトウェアの環境は常に変化しています。可動部品、電気、温度、ほこり、OSコードの変更などがその例です。

したがって、環境は常に変化しているため、コンピュータソフトウェアプログラムが常に同じように動作する可能性は低く、予想もされていません。

ソフトウェアは期待どおりに長期間実行できますが、最終的にはホストOSソフトウェアへの小さな変更が変更され、問題のプログラムに影響するか、ハードウェアが重要になります。

私は今日のコンピュータについて話している。


0

今、私の質問は、論理的な理由なしにコンピュータプログラムが突然失敗するのでしょうか。サーバーマシンを叩くと、コンピューターが計算している数値の1つが別の数値になり、計算が間違ってしまいますか?

その質問に対する答えは不明です。私たちがたまたま住んでいる宇宙について常に何かが真実であることを証明することは不可能です。代わりに仮定を立て、仮定が成り立つ場合、いくつかの複雑な特性も成り立つことを証明します。これは正式に検証されたプログラムが保証するものです。ほとんどのプログラムは正式に検証されていませんが、代わりにテストを提供することで信頼を築こうとします。これらのテストは、テストが意図したとおりに実行され、使用したプログラムが少なくともある程度は機能することを保証します。


-1

RAMの障害が原因で問題が発生することはほとんどありませんが、これは比較的(非常に)起こりそうにありません。メモリテストを実行しますが、コードを確認する準備をしてください。


反対投票者へ-私はこれが起こるのを見てきました。一度。
James McLeod
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.