たとえば、Autodesk Mayaの規模や複雑さのコードである20〜30百万行以上のコードについて話している。
必要な限り開発をフリーズした場合、コンピュータでそのようなことが確認できれば、単一のバグがなくなるまですべてのバグを実際に修正できますか?バグのないシステムの存在に対する賛成論と反対論は何ですか?
あなたが行うすべての修正がより多くのバグを生み出すという考えがあるからですが、私はそれが本当だとは思いません。
バグとは、UIの最も単純なタイプミスから、回避策のないより深刻な予防的バグを意味します。たとえば、特定のスクリプト関数が法線を誤って計算します。また、回避策がある場合でも、問題を修正する必要があります。したがって、提供された関数を使用する代わりに、この特定のことを手動で行うことができますが、その関数はまだ修正する必要があります。
Mikeyが述べたように、バグのないコードを書くことは目標ではありません。それがあなたが目指しているものであるなら、私にはいくつかの非常に悪いニュースがあります。
重要な点は、ソフトウェアの複雑さを非常に過小評価しているということです。
まず最初に、プログラムの実行方法の全体像を無視しています。完璧なシステムでは、単独では動作しません。 「Hello World」プログラムの最も基本的なものでもオペレーティングシステム上で実行されるため、最も単純なプログラムでも、オペレーティングシステムに存在する可能性のあるバグの影響を受けやすくなっています。
ライブラリの存在はこれをより複雑にします。オペレーティングシステムはかなり安定している傾向がありますが、ライブラリは安定性に関しては混合されています。いくつかは素晴らしいです。その他...それほど多くない...コードを100%バグフリーにしたい場合は、実行するすべてのライブラリが完全にバグフリーであることを確認する必要があります。多くの場合、これは単純に不可能です。ソースコードがない可能性があります。
次に、考慮すべきスレッドがあります。ほとんどの大規模プログラムは、至る所でスレッドを使用します。スレッドは、競合状態やデッドロックが発生しないように注意して作成しますが、コードのあらゆる組み合わせをテストすることは不可能です。これを効果的にテストするには、CPUを通過するコマンドのすべての可能な順序を調べる必要があります。私はこれについては計算をしていませんが、チェスで可能なすべてのゲームを列挙する方が簡単だと思います。
マシン自体を見ると、状況は困難から不可能に変わります。 CPUは完璧ではありません。 RAMは完璧ではありません。ハードドライブは完璧ではありません。マシン内のコンポーネントはどれも完璧に設計されていません。「十分」に設計されています。完璧なプログラムでも、マシンのしゃっくりが原因で最終的には失敗します。
結論:「バグフリーソフトウェア」は書けますか?
そうでなければあなたに言う誰も無知です。
理解と保守が簡単なソフトウェアを書いてみてください。それが終わったら、それを1日と呼ぶことができます。
編集:何人かの人々は、私が完全に見過ごしていた優れた点、コンパイラについてコメントしました。
Assemblyで記述している場合を除いて、コンパイラーがコードをめちゃくちゃにする可能性があります(コードが「完全」であることを証明した場合でも)。
より一般的に使用されるコンパイラの1つであるGCCのバグのリスト: http://gcc.gnu.org/bugzilla/buglist.cgi?product=gcc&component=c%2B%2B&resolution=--- =
数学的には[〜#〜] might [〜#〜]「バグ」の定義方法に応じて、そのような複雑な「バグのない」ソフトウェアを作成することができます。証明[〜#〜] might [〜#〜]は、あらゆる可能な方法であらゆるコード行を実行するテストシステムを設計することにより、数学的にも可能です。しかし、私にはわかりません。複雑な計算を行うシステムを扱っている場合、「無限問題」に遭遇する可能性があります...
実際には、あなたが話しているサイズとスコープのシステムでは、これは[〜#〜] impossible [〜#〜]です。そのような「バグのない」システムを作成し、それが指数関数的により多くの時間を要することを証明するシステムを作成するには、1000年かかる可能性があります。 1つ-そして、私があなたが話しているサイズとスコープのシステムのすべてのユースケースを、妥当な時間に似た何かで実際にカバーしたと判断する方法があるとは思いません。
IMOあなたの質問は少し間違っています:開発者としての私たちの目標は「バグのない」ソフトウェアを書くことではありません。私たちの目標は、SABLE、FLEXIBLE、EASILY MAINTAINABLEソフトウェアを作成することです。
使用可能:システムは、設計された重要な要件を満たしています。バグがある可能性がありますが、それらは「エッジケース」にあります-システムの基本を損なうバグではなく、異常値または不快感-堅牢です。
保守可能:バグは簡単に分離および修正でき、新しいバグを作成しないでください。
Flexible:大幅な再設計やダウンタイムなしでシステムを簡単に変更および拡張できます。ほとんどの変更では、新しいクラスまたはすでにうまく設計されたパターンとフレームワークに適合するモジュール。
優れた設計手法、優れた制御手法、優れたチームワーク、良心的な開発者-これはGOOD SOFTWARE。(ない- [〜#〜]完璧[〜#〜]-しかし[〜#〜]良い[〜#〜])
この記事、 によると、スペースシャトルの搭載ソフトウェアは非常に近くなりました-420,000ラインプログラムの最後の3つのバージョンにはそれぞれ1つのエラーしかありませんでした。ソフトウェアは、男性と女性の260人のグループによって維持されました。これらの人々の多くは検証者であり、その唯一の目的はエラーを見つけることでした。
シャトルが全地球測位衛星で航行できるようにするソフトウェアのアップグレードは、プログラムのわずか1.5%、つまりコードの6,366行に影響を与えました。その1つの変更の仕様は2,500ページでした。プログラム全体の仕様は30巻に達し、40,000ページ、つまり仕様の1ページあたり平均10行のコードを実行しました。
予算は問題ではありませんでした-年間35ミリオンで、彼らは正しいことをする余裕があります。
基本的に、いいえ、とにかく最善を尽くすべきです。理由を説明します(十分な忍耐力がない場合は、結論にスキップしてください)。
バイナリサーチの実装と同じくらい些細な問題を考えてください。非常に人気のある実装 バグがあった 約20年間検出されなかった。 20行でバグフリーが広く使用され、さらには正しいと証明されるまでに20年かかる場合、巨大なプログラムがバグフリーであることを本当に期待できますか?
とにかく巨大なプログラムにはいくつのバグがあると思いますか?私が見つけた数字の1つは「1000行あたり10個の欠陥」でした(コードコンプリート第2版、517ページ-単なる例であり、データを引用していません)。幸いなことに、プログラムの品質を向上させる方法があります。ユニットテスト、コードレビュー、および通常の手動テストは、バグの数を減らすことが知られています。それでも、数はまだ高いでしょう。
すべてのバグの95%を解決できるとしたら、それは信じられないことです。それでも、ソフトウェアにはまだ10 000〜15,000のバグがあります。
幸いにも、ソフトウェアは広く使用されているため(したがって、広くテストされているため)、バグが見つかるでしょう。したがって、徐々にバグを減らすことになります。ただし、バグが少ないということは、残りのバグを見つけるのが難しいことも意味します。そのため、バグ修正で直線的な曲線を期待しないでください。最後のいくつかのバグは見つけるのが非常に難しく、数年間検出から逃れる可能性があります(それらがever見つかったと仮定)。
また、ソフトウェアが変更されない場合は、新しいバグは発生しないと誤って想定しているようです。ソフトウェアがサードパーティのライブラリに依存している場合、新しいバージョンでは一部の機能が無効になる可能性があります。アプリケーションのコードが同じであっても、新しいバグが発生します。新しいオペレーティングシステムは、以前は完全に機能していたアプリケーションを破壊する可能性もあります(一般的な例については、Windows Vistaを参照してください)。コンパイラのバグなども考慮してください。
コード証明ツールがバグのあるソフトウェアの問題を本当に解決できるかどうかは不明です。すべてのプログラムについて 停止問題 を解決することは確かに不可能ですが、プログラムが指定どおりに動作することを証明することは可能かもしれません...しかし、それではどうでしょうか?多分証明プログラムにバグがあります。仕様自体にバグがあるのかもしれません。
明らかに、バグの数を大幅に減らすことができますが、ゼロになることはほとんどありません。
every修正を行うとバグが増えるという概念があるためですが、それは本当ではないと思います。
(強調を追加)
あなたは正しいです。このステートメントは間違っています。次に例を示します。
int main() {
int x[10];
x[10] = 8; //Buffer overflow here
return 0;
}
今、このバグを修正しましょう:
int main() {
int x[11];
x[10] = 8; //No buffer overflow here
return 0;
}
見る?バグを修正し、新しいバグは導入していません。
ただし、バグを修正するたびに新しいバグを作成するリスクがあることは確かに正しいですが、このリスクは軽減できます(たとえば、ユニットテストを使用)。
私が修正する100個のバグごとに、誤って新しいバグを導入するとします。したがって、1万個のバグを修正すると、100個の新しいバグが導入されます。そして、これらの新しいバグを修正した場合、1つのバグを紹介します。しかし、何ですか?プログラムのバグは現在9 999少ないので、おそらくそれは以前よりも優れています(新しいバグが以前のものよりも10 000倍も最悪ではないと仮定すると)。
また、バグを修正すると、新しいバグがexposeされる可能性があります。しかし、それらのバグも修正することができます。順調に行けば、最終的にソフトウェアは最初よりも良い状態になります。
私はOPで述べた概念のため、多くのバグを修正しない方がよいと、何人かのトッププログラマーが年配でした。
この動作は無視されます。バグがあり、修正できる場合。やれ。もちろん、新しいバグの追加を防ぐために最善を尽くす必要がありますが、私が修正する深刻なバグ10件ごとに小さなバグを1つ導入しても、バグの修正を中止する正当な理由にはなりません。実際、バグを修正し続けるのは良い理由です。
修正するバグが少ないほど、将来あなたに戻ってくるバグは少なくなります
修正するバグが少ないほど、より多くのバグがソフトウェアに残り、ユーザーを困らせます。実際、彼らは「将来あなたに戻ってくる」ことはありません。彼らはそもそも離れなかったので、彼らは戻ってきません。 「カムバック」の概念は、回帰に関連しています。この場合も、リグレッションのリスクを減らすことができます。
広く使用されるようになり、人々がそれらに依存し始めたために修正できないバグもあります。バグを修正すると、それらのユーザーにとってプログラムが壊れてしまいます。それが起こります。ただし、その場合、それらは本当にバグと見なすことができますか?
「バグを修正し、バグを作成する」という考え方は、That Horrible Monsterに関連している可能性があります。コードを読み取るだけではなく、維持できないため、触れるだけでバグが発生します。コードベースにモンスターがある場合、何かを行う前に、まずモンスターをモンスター化解除する必要があるかもしれません。
最後に、あなたがひどいプログラマーであるなら、何かあなたのタッチが新しいバグを作成するリスクがあります。これは明らかに上級プログラマを緊張させるでしょう。しかし、「何もしないでください。何も触れないでください。呼吸さえしないでください。」おそらく、健康的な職場環境を作るための正しい方法ではありません。教育は良いです。
結論:
notのバグのないプログラムを作成する理由は、ほとんどが経済的です。
プログラムの正確さを証明するための数学的方法があります。質の高いコンピュータサイエンスコースでは、それらについて言及します。特にこの目的のために発明されたプログラミング言語があります。理論的には、バグのないプログラミングが可能です。
はい、不完全なハードウェアがあり、数百万年前の遠方の超新星から発射されたニュートリノがちょうど適切な場所でプロセッサに衝突したため、ビット値が変わる場合があります。さて、すべての理論にはその仮定と抽象化があります。ただし、プロセッサがアドバタイズされたとおりに動作すると仮定すると、プログラムが正しく動作することを確認するためのツールもあります。
このトピックの投票数の多い回答は誤解を招くものです。たとえば、ゲーデルの不完全性定理と停止問題は、たとえば、 anyプログラムの正誤を判断する自動化ツール。ただし、anyプログラムの正確性を判断する必要はありません。oneの正確性の証明のみが必要です特定のプログラム。
(アナロジー的に、any数学的定理の真理を自動的に決定するためのプログラムを作成できないからといって、証明できないことを意味しません特定の1つ数学的定理)
代わりに、問題はこれです:
理論的にはバグのないプログラムを書くことは可能ですが、そうすることは非常に高価です。コードが正しいことを証明するコードを書くことは、壁に何かを投げて貼り付けるかどうかを確認するよりも複雑です。 「こだわるかどうか」を単体テストで行っても、そして多くのプログラマーはそれをすることさえ気にしません。ほとんどのプログラマーは、それを行う方法すら知らないでしょう。つまり、会社として、より高価なものを雇わなければならないということです。
すべてのコストを考慮すると、一般的な顧客は、100%の確率で機能する1000倍の高価なソフトウェアよりも、99%の時間(および追加の更新プログラムをインストールした後の時間の99.9%)で機能する安価なソフトウェアに満足しています時間。また、顧客はこのソフトウェアを今にしたいと考えています。
したがって、人々はバグが発生する可能性のあるソフトウェアを意図的に作成し、バグの頻度が高すぎず、深刻すぎない最適な組み合わせを見つけようとします。実生活で最大の利益をもたらす組み合わせ。 (時には、競合他社が何かをリリースする前に、バグの多いソフトウェアをリリースし、競合他社が最初のまともなバージョンをリリースする準備ができたときに、よりまともなバージョン2.0をリリースすることさえ意味します。)
必要な限り開発をフリーズした場合、コンピュータでそのようなことが確認できれば、単一のバグがなくなるまですべてのバグを実際に修正できますか?
数学的に言えば、できます。経済的に言えば、なぜ誰もがそうするのでしょうか?それはおそらく20年と数百万ドルを費やすことを意味します。その間、顧客は新機能を望み、フリーズされたアプリケーションはそれらを提供できませんでした。したがって、完璧なバージョンの準備が整った時点で、市場は競合他社にすでに奪われています。
経済的に推論はOKです。私たちはお金と時間の問題がある世界に住んでいます。しかし、経済的な理由で何かをしないからといって、理論的にもそれがどうしてできないのかをばかげたことを言うべきではありません。誰が知っているのか...おそらく数年後には、正確性を証明できる新しいプログラミング言語とツールが簡単にできるようになるでしょう。
いいえ
David Hilbert は、1900年に数学の彼の 2番目の問題 を提案しました。彼は後に「 The Entscheidungsproblem 」を支持し、論理的な用語で同様のことを尋ねました。 Kurt_Gödel's " first incompleteness theorem "は1931年に、初等演算の理論が一貫していて完全である可能性がないことを証明しました。 Alan Turing's Entscheidungsproblemを「 停止の問題 」として表現すると、問題がこの質問の中心に移動し、プログラムが完了するまで実行するかどうか。 不可能性を考えると、プログラムにバグがあるかどうかを証明することも不可能です。
そのいずれも、私たちの間で実践しているプログラマーがバグをなくそうと努力することから解放します。それは単に私たちが一般に成功できないことを意味します。
B-method のような正式な言語でコードを記述しても、要件が満たされていることを数学的に証明するために使用できます。
正式な仕様言語を使用しても
ユーザーのニーズを1つ以上の頭脳からコンピューターに抽出することからなる人間のステップは常に存在します。
この人間のステップはエラーが発生しやすく、ワームはアップルにあります。
私が遭遇した「バグ」のかなりの部分は、システム設計と顧客の期待との間のミスマッチとしてより適切に説明されるかもしれません。
さて、これらのバグを呼び出すかどうかは学術的ですが、不完全なコミュニケーションと顧客の期待のシフトの直接的な結果として、かなりのメンテナンス作業が発生するという事実が残っています。
システムが技術的には、仕様を満たすという意味で「正しい」可能性があるとしても(実際の商用ソフトウェアではありそうもないことですが)、ソフトウェアの機能を顧客のこれまでと一致させるという問題が依然としてあります。シフトと明確に定義されていない期待。
要するに:
番号。
仕様が十分に厳しく制限されている場合、バグのないプログラムを証明できる可能性がありますが、それはシステム内の他のすべてが正しく機能していることを証明できない前提に基づいているだけです。これは当然のことですが、元の問題を引き起こした人やサービスを使用した人が仕様が正しいと見なすことを証明する方法はありません。
私はジムショアのセクション バグなし がこのトピックについて非常に有用な読み物であることがわかりました。短い形式:バグを生成せずに開発することは不可能ですが、できるだけ早くバグを検出するように作業できます。
コード自体の生成中。たとえば、開発中にユニットテストを頻繁に記述して実行することにより、コードが想定どおりに機能することを常に保証します。また、目的のシステム動作を最も明確に表すように、既存のコードを永続的に書き換えることも役立ちます。
ただし、あなたのケースでは、何百万行ものコードが存在する既存のコードベースについて話しています。このようなシステムのバグをなくしたい場合は、まずこのシステムの「バグ」とは何かを知る必要があります。システムの機能を保証する一連の事後テストを作成できます(まだ存在しない場合)。これらのテストのウェブは、正しいシステム動作の近似定義として機能します。しかし、コードが多ければ多いほど、そのような演習にはより多くの努力が必要になります。したがって、ほとんどの企業は妥協します。彼らは不完全な状態で生活し、バグリストとメンテナンスを利用して、最も厄介なバグをシステムから排除します。
コンピュータ部分による検証について。
コンピュータを使用してプログラムを検証するには、2つの方法があります。 1つはテストで、もう1つは証明システムを使用しています。
完全なテストが不可能になるとすぐに、テストはプログラムにバグがないことを示すことができなくなります。バグがあるだけです。 (そして、テスト自体がバグの存在をテストしていないことを示す問題があります)。
証明システムを使用するには、正式な要件から始めます(そして、要件自体にバグがある可能性があります。要件に使用される言語が、プログラミング言語よりもバグがないことを納得させるのに適していると思います)。プログラムにバグがないことの証明システムの助け(そして証明システムのバグの問題がありますが、彼らはそれ自体が正しいことを証明しました)。現在の最新技術は Cサブセットのコンパイラ です(そしてサブセットは学術的ではありません。「CompCertはC-のすべての MISRA-C 2004サブセットをサポートしています。加えて、MISRAによって除外された多くの機能」)。
いいえ、アプリケーションが実行されるコンピューターとソフトウェア環境は、コードがフリーズしている間も変化し続けるためです。オペレーティングシステムは、パッチと修正、デバイス、ドライバとともに進化を続けています。 AMDまたはnVidiaは、既知のバグがなくなるポイントに達したと思ったときに、ビデオサブシステムとのやり取りに影響を与えるビデオドライバーのアップデートをリリースします。これで、特定のビデオカードまたは構成(SLI?LOL)を使用しているお客様にとって、アプリケーションに視覚的な欠陥(点滅、ちらつき、フレームレートの低下など)が生じます。
ハードウェアとOSのほかにも、最も重要なアプリの下にミドルウェア製品がいくつかあります。これらのミドルウェア製品も、制御を超えて進化し、コードが欠陥ゼロの状態になると、その下のレイヤーがEOLされます。
テクノロジーは進化し、テクノロジーを活用するビジネスも進化しており、コードを「解放」するという考えは不可能または実現不可能です。新しい機能セットを求めるビジネスは、「既知のすべてのバグを追跡している間はコードがロックされており、Xか月以内に有効なソフトウェアの欠陥を報告する人はいません」には適切に対応できません。ビジネスがそのラインを購入したとしても、Xか月後には新機能がどのように登場するかを尋ねられ、答えは「Oracleがパッチをリリースしただけで、さらにXか月を要するため、凍結を延長することに決めました」それを証明する」。
いいえ、ある時点で、企業はテクノロジーのスピードで前進する必要性をサポートする、より柔軟な開発チームを探しています。これは、現代の開発チームが直面する根本的な問題です。
はい、しかしあなたは確実に知ることは決してないでしょう。あなたが見るのが難しいほど、あなたはより多くを見つけるでしょう。システムが重いほど、またEdgeケースが多く使用されるほど、元の意図や仕様との不一致がさらに発生しやすくなります。これは、バグ自体が正確なものではないことを意味し、多くの場合、一部の個人が認識された異常をどの程度悪い評価するかによって、解釈に依存します。
ぼんやりしたものです。最後のビットまで指定されているシステムはほとんどありません。システムが正常に動作し、ユーザーが不満を持たず(何の問題もない)、ユーザーがシステムに完全に適応している場合は、バグのない状態で呼び出すこともできます。