web-dev-qa-db-ja.com

バグゼロのプログラマーになるには?

上司は常に、優れたプログラマーが変更したコードが信頼性が高く、正しく、完全に自己検証されることを保証できるようにすべきだといつも言ってきました。変更がもたらすすべての結果と影響を完全に理解する必要があります。私は何度も何度もテストして、この種のプログラマーになるために最善を尽くしましたが、バグはまだ残っています。

どのようにしてバグゼロのプログラマーになり、コードのすべての文字が何を引き起こし、影響を与えるかを知ることができますか?

168
Elaine

コード化しないでください。

それがバグゼロのプログラマーになるための唯一の方法です。

プログラマーは人間なので、バグは避けられません。バグを防ぐために最善を尽くし、バグが発生した場合は迅速に対応し、間違いから学び、最新の状態を維持することができます。

365
wildpeaks

重要なプログラムでは、バグをゼロにすることは不可能です。

非常に接近することは可能ですが、生産性が低下します。また、特定のリスクの高いソフトウェアにとってのみ価値があります。 スペースシャトルソフトウェア が思い浮かびます。しかし、その生産性は1日に数行程度です。あなたの上司がそれを望んでいるとは思えません。

このソフトウェアにはバグがありません。人間が達成したのと同じくらい完璧です。これらの統計を考えてみましょう:プログラムの最後の3つのバージョン(それぞれ420,000行)には、それぞれ1つのエラーしかありませんでした。このソフトウェアの最新の11バージョンには、合計17のエラーがありました。

ソフトウェアのアップグレードを行って、シャトルが全地球測位衛星で航行できるようにします。この変更には、プログラムの1.5%、つまりコードの6,366行が含まれます。その1つの変更の仕様は2,500ページであり、電話帳よりも厚いボリュームです。現在のプログラムの仕様は30巻を満たし、40,000ページを実行します。

124
CodesInChaos

「ゼロバグプログラマー」は、サイレントシンガーのような矛盾した表現ですが、60年以上前のプログラミングにより、次のような優れたプログラマーになるように、いくつかの知恵が蒸留されています。

  • 謙虚に-あなたは間違いを犯しているし、間違いも犯すでしょう。繰り返し。
  • あなたの頭蓋骨の限られたサイズに十分に注意してください。謙虚さをもってタスクに取り組み、ペストのような巧妙なトリックを避けます。 [エドガーダイクストラ]
  • 戦い 組み合わせ爆発
  • 変更可能な状態を取り除きます(可能な場合)。はい、関数型プログラミングを学びます。
  • 可能なコードパスの数を減らす
  • (関数の)入力スペースと出力スペースのサイズ(の大きさ)を理解し、100%のテストカバレッジにさらに近づくために、それらを縮小してみてください。
  • コードが機能していないことを常に想定してください。
98
Maglob

TDD

TDDのポイントは、そのコード行を必要とするテストがない場合は、コードの1行を記述しないことです。そして、それを極端にするには、受け入れテストを書くことによって常に新しい機能の開発を開始します。ここで私は cucumber スタイルのテストを書くことが理想的であることを発見しました。

TDDアプローチには少なくとも2つの利点があります。

  • すべてのコードは特定の機能を解決するために書かれているため、不必要な過剰生産はありません。
  • 既存のコード行を変更するたびに、機能を中断すると通知されます

それは不可能であるため、バグがゼロであることは証明されません(他の無数の回答ですでに指摘されています)。しかし、TDDを学んでそれが得意になった後(そうです、これも練習が必要なスキルです)、徹底的にテストされているので、自分のコードにはるかに自信を持っています。さらに重要なことに、機能を壊すことを心配することなく、完全には理解していない既存のコードを変更できます。

しかし、TDDはあなたを完全に助けるわけではありません。システムのアーキテクチャとそのアーキテクチャの落とし穴を完全に理解していないと、バグのないコードを書くことができません。例えば。複数の要求を同時に処理するWebアプリケーションを作成している場合は、複数の要求間で可変デー​​タを共有できないことを知っておく必要があります(パフォーマンスの向上のために可変データをキャッシュする初心者トラップに陥らないでください)。

TDDが得意な開発チームが、欠陥の少ないコードを提供できると思います。

25
Pete

問題は、バグはあなたが認識しないものです。アプリケーションが実行されるすべての環境と同様に、プログラミング言語/コンパイラのある種の百科事典的な知識がない限り、100%バグのないコードを生成することは期待できません。

たくさんのテストを行うことでバグの数を減らすことができますが、結局のところ、考慮されないいくつかのフリンジケースがあるでしょう。 Joel Spolskyが bug-fixing に関して特に素晴らしい記事を書いた。

19
user7007

はい、コードにバグがないことは不可能ですが、バグを少なくすることは不可能ではありません。 「それはばかげている、あなたはいつもバグを抱えるだろう」という態度は、コード内のバグの数を減らすことを避けるための単なる警戒態勢です。誰も完璧ではありませんが、私たちはより良くなるために努力することができますし、努力すべきです。私自身の改善への取り組みの中で、以下の点が参考になりました。

  • これは簡単ではありません。あなたは一晩で改善されません。したがって、落胆したり、あきらめたりしないでください。
  • 書く量を減らして賢く書く。コードが少ないほど、通常はより優れたコードになります。事前に計画して素晴らしいデザインパターンを作成するのは当然のことですが、長期的には、必要なものを書くだけで時間を節約し、バグを防ぐことができます。
  • 複雑さは敵です。 Lessは、あいまいな複雑な混乱である場合はカウントされません。コードゴルフは楽しいですが、理解するのは地獄であり、デバッグするのはさらに悪いことです。複雑なコードを書くときはいつでも、問題の世界に自分を開放します。物事はシンプルで短いものにしてください。
  • 複雑さは主観的です。かつて複雑だったコードは、優れたプログラマーになると単純になります。
  • 経験は重要です。より優れたプログラマーになるための2つの方法の1つは、実践することです。練習は、簡単に書く方法を知っているプログラムを書くのではなく、少し傷つけて考えさせるプログラムを書くことです。
  • 良くなるもう一つの方法は読むことです。プログラミングには学ぶべき難しいトピックがたくさんありますが、プログラミングだけではそれらを学ぶことができないので、それらを学ぶ必要があります。あなたは難しいものを読む必要があります。セキュリティや同時実行性などは、災害を片付けて学びたいのでない限り、コードを書くだけでは正しく学習できません。あなたが私を信じていないなら、ゴーカーのような壮大なセキュリティ問題を見てください。彼らがセキュリティを正しく行う方法を学ぶために時間をかけ、うまくいった何かを作るだけでなく、そのような混乱は決して起こらなかっただろう。
  • ブログを読んでください。そこにたくさんの興味深いブログがあり、これを見てプログラミングすることについて新しく興味深い方法を提供し、これがあなたを助けるのに役立ちます...
  • 汚い詳細を学びます。言語とアプリケーションのあいまいな部分がどのように機能するかについてのマイナーな詳細は非常に重要です。それらは、複雑なコードの記述を回避するのに役立つ秘密を保持したり、回避する必要のある独自のバグがあるパーツである可能性があります。
  • ユーザーの考えを学ぶ。時々、ユーザーは正気を失い、理解できず予測できない方法でアプリを操作します。あなたは彼らがしようとしている他のことを知り、あなたのアプリがそれを処理できることを確認するのに十分なほど彼らの頭に入る必要があります。
17
AmaDaden

バグゼロ? LISPが必要 (懐疑的な道を進み、ミュージックビデオを避けます)のように聞こえます。

主流のコーディング環境(Java、C#、PHPなど)でバグのないコードを実現するのは非常に困難です。私はよく制御された反復で十分にテストされ、ピアレビューされたコードを生成することに焦点を当てます。

できる限りコードをシンプルに保つことは、バグを回避するのに役立ちます。

コード分析ツールFindBugs[〜#〜] pmd [など)を使用していることを確認してください〜#〜] など)-厳密なコンパイラ警告と組み合わせると、コードに関するあらゆる種類の問題が明らかになります。彼らがあなたに何を言っているかに注意して、本当にバグの性質を理解するように努力し、次に、そのバグを再び導入するような方法でコードを書くのが不自然に感じるようにプログラミングイディオムを変更する手順を実行します。

8
Gary Rowe

個人的には、バグのないプログラミングに努めることは(時間とお金の両方で)より高価に思われると思います。バグをゼロにするか、ゼロに近づけるには、開発者に徹底的にテストしてもらう必要があります。これは、パッチレビュー用のコードを送信する前にすべてを回帰テストすることを意味します。このモデルは、費用対効果が高いとは思いません。開発者に十分な注意を払ってテストを実施してもらい、詳細なテストはQAチームに任せてください。理由は次のとおりです。

  • 開発者はテストにうんざりしています。それは本当であり、あなたはそれを知っています。 (私は開発者です!)優れたQAチームは、開発者が考えたことのないEdgeのケースを常に見つけます。
  • 開発者はコーディングが得意です。彼らが何に優れているか(そして通常、とにかく彼らがとにかく好むこと)に戻してもらいましょう。
  • QAチームは、1つのパスで複数の開発者タスクに関連するバグを見つけることができます。

コードを書くとき、それに対してバグが記録されることを受け入れます。それがあなたがQAプロセスを持っている理由であり、それはすべて開発者であることの一部です。もちろん、これは最後のセミコロンを書いた直後に何かを提出することを意味するものではありません。あなたはまだあなたの仕事の品質を保証する必要がありますが、あなたはcanそれをやりすぎます。

ピアレビューやテストを行わずに、常に最初から正しく仕事を行える職業をいくつ挙げられますか?

8

すべての「まったくコード化しない」。答えは要点を完全に欠いています。また、あなたの上司はバカじゃないようです!

自分のコードが何をしているのかを知らないプログラマーを見たことがあるか思い出せません。彼らの唯一の開発哲学は試行錯誤であるように思われました(そして、しばしばコピー/貼り付け/修正もします)。試行錯誤はいくつかの問題を解決するための有効な方法ですが、多くの場合、問題の領域を分析してから、使用するツールの理解に基づいて非常に具体的な解決策を適用することができます。初めてデプロイする前に、問題だけでなくほとんどのコーナーケース(潜在的なバグ)も解決しました。コードにバグがないことを保証できますか?もちろん違います。しかし、あなたが遭遇したり読んだりするすべてのバグについて、あなたが次に何かを書いたり変更したりしたときに考えたくなるかもしれないことにそれを追加することができます。これを行うと、ほぼバグのないコードの記述方法に関する多くの経験が得られます。 -旅であなたを助けることができるより良いプログラマーになる方法について利用可能なリソースがたくさんあります...

個人的には、すべての行を説明できないコードをコミットすることはありません。すべての行に存在する理由があります。それ以外の場合は削除する必要があります。もちろん、呼び出すメソッドの内部動作を想定することもあるでしょう。そうでない場合は、フレームワーク全体の内部ロジックを知る必要があります。

上司は、既存のシステムに記述したコードの結果と影響を理解する必要があると言うのは完全に正しいことです。バグが発生しますか?はい、もちろん。ただし、これらのバグは、使用するシステム/ツールを完全に理解していないためであり、すべてのバグ修正を行うと、対象範囲が広がります。

8
Patrick Klug

他のコメントですでに正しく指摘されているように、バグのない重要なソフトウェアはありません。

ソフトウェアをテストする場合は、常に心に留めておいてください。そのテストは、バグがないことではなく、バグがあることのみを証明できます。

仕事のドメインによっては、ソフトウェアの正式な検証を試みる場合があります。形式的な方法を使用すると、ソフトウェアが仕様を正確に満たしていることを確認できます。

もちろん、ソフトウェアが目的どおりに動作するという意味ではありません。完全な仕様を書くこともほとんどすべての場合不可能です。基本的に、エラーが発生する可能性のある場所を実装から仕様に移行します。

したがって、「バグ」の定義に応じて、正式な検証を試すか、ソフトウェアでできる限り多くのバグを見つけようとします。

7
FabianB

「Hello World!」よりも複雑なものは書かないでください。または、誰にも絶対に使用しないように指示した場合。

このいわゆるバグのないコードの例を上司に尋ねてください。

6
JeffO

私は他のものに同意します。これが私が問題に取り組む方法です

  • テスターを取得します。理由については、Joel Testを参照してください。
  • ライブラリを広範囲に使用します。おそらくよりよくデバッグされています。私はCPAN for Perlの大ファンです。
5
Brian Carlton

バグゼロのプログラマーになるために努力することができます。私はコードを書いているときはいつでもバグゼロのプログラマーになるように努力しています。しかし、私はしません

  • 複数のテスト手法を使用する(ATDD以外)
  • ソフトウェアの正式な検証を作成する
  • 別のQAチームがいる
  • コードベースに加えられた変更ごとにハード分析を行う
  • 安全と注意に傾く言葉を使う

これらのことは、私が作成するソフトウェアにとって非常にコストがかかるため、行いません。私がこれらのことをしたなら、私はおそらくバグゼロに向かってさらに進んでいるでしょうが、それはビジネスに意味をなさないでしょう。

私は、インフラストラクチャの大部分が使用する内部ツールを作成しています。テストとコーディングに関する私の基準は高いです。ただし、バランスがあります。私は、そのような時間を1つの作業に費やすことができないので、バグがゼロになることを期待していません。 X-Rayマシン、ジェットエンジンなどを制御するソフトウェアを作成している場合は、状況が異なる可能性があります。ソフトウェアが故障した場合、命が失われることはないので、そのレベルの保証は行いません。

保証のレベルをソフトウェアの使用目的に合わせます。 NASAシャトルが使用するコードを記述している場合、バグの許容度はゼロであることは妥当です。必要なのは、追加の非常に高価なプラクティスを追加することだけです。

5
dietbuddha

「バグゼロ」のプログラマになるための良い第一歩は、バグに対する態度を変えることだと思います。 「実際に起こる」、「QAとテスターを改善する」、または「開発者がテストに夢中になる」と言う代わりに、

バグは受け入れられません、そして私はそれらを排除するために私の力の範囲内ですべてを行います。

これがあなたの態度になると、バグはすぐに落ちます。バグを排除する方法を見つけるための検索では、テスト駆動開発に出くわします。あなたはたくさんの本、ブログ投稿、そしてより良い技術についての無料のアドバイスを提供している人々を見つけるでしょう。 practiceを通じてスキルを向上させることの重要性がわかります(katasのコーディングや、家での新しいことの試みなど)。家で工芸品の作業を開始するので、仕事のパフォーマンスが向上します。そして、うまくいけば、それを見つけたらis良いソフトウェアを書くことが可能で、あなたのクラフトへの情熱が高まります。

4
Darren

ある意味であなたの上司は正しいです。バグゼロに近づくソフトウェアを書くことは可能です。

しかし問題はコスト(ほとんど)バグのないプログラムを書くことの法外に高いであるということです。あなたは次のようなことをする必要があります:

  • 要件の正式な仕様を使用します。 Z、VDM、またはその他の数学的に適切な表記法の使用と同様に、形式的。

  • 定理証明手法を使用して、プログラムが仕様を実装していることを正式に証明します。

  • 広範なユニット、回帰、システムテストスイートとハーネスを作成し、あらゆる方法でバグをテストします。 (そしてそれだけでは十分ではありません。)

  • 多数の人々に要件(公式および非公式)、ソフトウェア(および証明)をレビューしてもらいます。テスト、および展開。

上司がこのすべての費用を支払う準備ができていることはほとんどありません...またはすべてを行うのにかかる時間を我慢します。

2
Stephen C

「バグゼロ」のステータスになりました。文書化されていない機能であること、または新機能を求めているため機能強化であることをユーザーに伝えます。これらのどちらも受け入れられない場合、私は単に彼らが自分の要件を理解していないことを伝えます。したがって、バグはありません。プログラマーは完璧です。

1
angryITguy

バグをフリープログラムにする手順は次のとおりです。

  1. 機能の明確な仕様がない限り、コーディングを開始しないでください。
  2. テストを行わないか、ソフトウェアの欠陥を見つけるためにテストに依存しないでください。
  3. テスト、レビュー、および生産中に発見された欠陥からのすべてのフィードバックを、最初に欠陥を挿入したプロセスおよび開発者に適用します。欠陥が見つかったらすぐに、すべての欠陥のあるコンポーネントを完全に廃棄します。チェックリストを更新し、開発者に再ト​​レーニングして、開発者がそのような間違いを繰り返さないようにします。

テストはあなたがバグを持っていることを証明することができるだけですが、それ以外のことを証明することは通常役に立ちません。フィードバックについて-あなたがコインを作るコイン製造機を持っていて、平均して10代ごとにコインに欠陥がある場合。あなたはそのコインを受け取り、それを平らにし、再び機械に挿入することができます。リサイクルされたブランクを作ったコインは、それほど良くはありませんが、おそらく受け入れられます。 100コインごとに2回再スタンプする必要があります。機械を修理する方が簡単でしょうか?

残念ながら人々は機械ではありません。欠陥のない優れたプログラマーを作るには、多くの時間を費やし、行われたすべての欠陥に対してトレーニングと反復を行わなければなりません。開発者は、実際に学び、実際に適用することが難しいことが多い正式な検証方法についてトレーニングを受ける必要があります。ソフトウェア開発の経済学もそれに反対しています-2年を費やして、プログラマーが別の雇用主にジャンプするのを見るためだけに欠陥を減らすことができるプログラマーのトレーニングに投資しますか?完璧なコインを作成するマシンを購入するか、10個以上のコードモンキーを雇って、同じコストで一連のテストを作成できます。この徹底的なプロセスを「マシン」、つまり資産と見なすことができます。優れた開発者の広範なトレーニングに投資しても、見返りはありません。

すぐにあなたは許容できる品質のソフトウェアを開発する方法を学びますが、遅いので完璧なコードを作る開発者のための市場がないという単純な理由で欠陥のない人になることはおそらくないでしょう。

1

大きなソフトウェアハウスを想定している場合know一流の開発者を取得する方法(のようにバグゼロのプログラマー)マイクロソフトのソフトウェアを差し引くことができますする必要がありますバグなし。しかし、それが真実からかけ離れていることはわかっています。

ソフトウェアを開発し、特定のレベルの優先度の低いバグに達したら、製品をリリースして後で解決します。

単純な計算機よりも複雑なものを開発しているのでなければ、バグを一緒に回避することは不可能です。地獄でさえNASAは彼らの車とバグにも冗長性を持っています。ただし、壊滅的な障害を回避するために、厳密なテストが行​​われています。しかし、それでもソフトウェアにバグがあります。

バグは避けられない人間の本性と同じように。

バグがないということは、100%安全なシステムを持っているようなものです。システムが100%安全である場合、それは間違いなくもう役に立たない(それはおそらく数トンのコンクリートの中にあり、まったく外部に接続されていません。有線でも無線でもありません。完全に安全なシステムがないのと同じように) 、バグのない複雑なシステムはありません。

0
Robert Koritnik

防御的にプログラムする: http://en.wikipedia.org/wiki/Defensive_programming

誰かが防御的なプログラミングの慣例に従っている場合、変更は簡単に追跡できます。これを、開発中の厳密なバグレポート、およびdoxygenのような堅固なドキュメントと組み合わせると、すべてのコードが何をしているかを正確に把握し、発生したバグを非常に効率的に修正できます。

0
Jason McCarrell

これは、goodの方法論を誤解した結果であり、一般的な骨の先が悪いだけではありませんか?

つまり、上司が "ゼロ欠陥方法論" (セクション5を参照)を聞いて、それが何を意味するのかわからなかった可能性があるということです。
もちろん、あなたが入れるべきではないバグを支持して、新機能の開発を延期することは管理者にとって不便です...
そしてもちろん、それは彼のボーナスを脅かしているので、「優れたプログラマーにはバグがない」ため、もちろんあなたはそれを手に入れることはできません...

できる限りmakeバグをfindして、 fixそれらを(当然のことながら)修正します。

0
AviD

ソフトウェアテストの基本的な概念の1つは、プログラムが完璧であることを絶対に確信することは決してできないということです。あなたはそれを永遠に検証することができますが、すべての入力/変数の組み合わせに対してテストすることさえすぐに実行不可能になるので、プログラムが完全であることを決して証明しません。

あなたの上司は、「タイプするだけなので、プログラミングの難しさを理解していない」人のようです

0
SpacePrez