回答
デバッグに対する考え方と態度はおそらく最も重要な部分は、エラーをどれだけ効果的に修正するか、そしてエラーから何を学ぶかを決定するからです。
The Pragmatic Programmer や Code Complete などのソフトウェア開発の古典は、基本的に同じアプローチを主張しています:すべてのエラーは、ほとんどの場合、自分自身について学ぶ機会です(初心者だけが最初にコンパイラ/コンピュータを非難するため)。
それで、それを謎として扱ってください。そして、その謎を解き明かすには、私たちの仮定を(自分自身または他の人に)表現し、必要に応じて1つずつテストすることによって、体系的に行う必要があります。すべてのツール、特にデバッガーと自動テストフレームワークを使用します。次に、謎が解かれた後、すべてのコードを調べて、同様のエラーが発生していないかどうかを確認することで、さらに改善することができます。
最後の注意点-エラーを「バグ」ではなく「エラー」と呼びたい-ダイクストラは、後者の用語を使用したことで同僚を非難した。それは不誠実であり、私たち自身の(ずさんな)思考のためにそこにいるのではなく、私たちが見ていなかったときに、有害で気まぐれなバグフェアリーが私たちのプログラムにバグを植え付けたという考えを支持しています: http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html
たとえば、次の方法で言語をクリーンアップすることから始めることができます。バグをバグと呼ぶのではなく、エラーと呼ぶことによって。それが属する場所に正直に責任を負わせるので、それははるかに正直です。エラーを起こしたプログラマーと。プログラマーが見ていなかったときに悪意を持って潜入したバグのアニミズム的なメタファーは、エラーがプログラマー自身の作成であると偽装しているため、知的に不誠実です。この単純な語彙の変更の良い点は、それが非常に大きな効果をもたらすことです。 :以前は、バグが1つしかないプログラムは「ほぼ正しい」ものでしたが、その後、エラーのあるプログラムは「間違っている」だけです(エラーがあるため)。
コメント
回答
-
テストを作成します。テストはバグの防止に優れているだけでなく(私の経験では、TDDを正しく実行すると、ほとんどすべての些細で愚かなバグが排除されます)、デバッグにも大いに役立ちます。テストにより、設計はかなりモジュール化され、問題の切り分けと複製がはるかに簡単になります。また、あなたは環境をコントロールするので、驚きはずっと少なくなります。さらに、失敗したテストケースを取得すると、「気になる行動の本当の理由を突き止めた」と合理的に確信できます。
-
デバッガーの使用方法を学びます。print
ステートメントは、あるレベルではかなりうまく機能する可能性がありますが、ほとんどの場合、デバッガーは非常に役に立ちます(1回限り)使い方を知っているので、print
ステートメントよりもはるかに快適です。
-
問題について誰かに話し、たとえそれが単なるゴム製のダッキーであっても。自分が取り組んでいる問題を言葉で表現するように強制することは、本当に奇跡です。
-
時間制限を設けてください。たとえば、45分後にどこにも行かないと感じた場合は、しばらくの間他のタスクに切り替えてください。バグに戻ると、「これまで考えていなかった他の可能な解決策が見つかることを願っています。
コメント
回答
他のほとんどの回答が好きですが、ここにいくつかのヒントがあります。あなたがそのいずれかをする前に。時間を節約できます。
-
本当にバグがあるかどうかを判断します。バグは常にシステムの動作と要件の違いです。テスターは、期待される動作と実際の動作を明確に表現できる必要があります。彼が期待される動作をサポートできない場合は、要件もバグもありません。誰かの意見だけです。返送してください。
-
可能性を検討してください。これは、要件の誤った解釈が原因である可能性があります。また、要件自体の欠陥(詳細な要件とビジネス要件のデルタ)が原因である可能性もあります。これらを返送することもできます。
-
問題を解決します。経験だけがこれを行うための最速の方法を教えてくれます。一部の人はほとんど腸でそれを行うことができます。1つの基本的なアプローチは、1つのことを変えることです。他のすべてのものを一定に保つ(問題は他の環境で発生しますか?他のブラウザーで?異なるテスト領域で?1日の異なる時間に?)別のアプローチは、スタックダンプまたはエラーメッセージを調べることです-時々あなたはただ言うことができますちなみに、システムのどのコンポーネントが元のエラーをスローしたかがフォーマットされています(たとえば、ドイツ語の場合は、何とかすることができます)ベルリンで一緒に仕事をしているサードパーティです。
-
コラボレーションする2つのシステムに絞り込んだ場合は、トラフィックモニターまたはログファイルを使用して、2つのシステム間のメッセージを調べます。 、およびどのシステムが仕様どおりに動作しているか、どのシステムが動作していないかを判別します。シナリオに3つ以上のシステムがある場合は、ペアワイズチェックを実行して、アプリケーションスタックを「ダウン」させることができます。
-
問題を切り分けることが非常に重要である理由問題は、自分で制御できるコード(サードパーティのシステムや環境など)の欠陥が原因ではない可能性があり、そのパーティにできるだけ早く引き継がせたいということです。これは、作業を節約することと、すぐに問題を解決して、できるだけ短い時間枠で解決を達成できるようにすることの両方です。問題を見つけるためだけに10日間作業したくないのは、本当に他の誰かのWebサービスの問題です。
-
本当に欠陥があり、それが実際に管理しているコードにあると判断した場合は、最後の「既知の良好な」ビルドを探すことで、問題をさらに切り分けることができます。問題の原因となった可能性のある変更についてソース管理ログを検査します。これにより、時間を大幅に節約できます。
-
ソース管理からそれを理解できない場合は、デバッガーを接続し、コードをステップ実行して理解するときです。とにかく問題についてかなり良い考えを持っている可能性があります。
バグがどこにあるかがわかり、修正を考えることができたら、ここで「良い」修正手順:
-
問題を再現して失敗する単体テストを作成します。
-
単体テストを変更せずに、 (アプリケーションコードを変更することで)合格します。
-
ユニットテストをテストスイートに保持して、リグレッションを防止/検出します。
回答
バグの再現も重要だと思います。バグを再現するすべてのケースを一覧表示して、バグ修正がそれらすべてのケースをカバーしていることを確認できます。
回答
このテーマについて読んだプログラムが失敗する理由という優れた本があります。この本には、科学的方法を適用してバグを特定して解決するまでのさまざまな戦略が概説されています。バグ、デルタデバッグへ。この本の他の興味深い部分は、「バグ」という用語がなくなっていることです。 Zellerのアプローチは次のとおりです。
(1)プログラマーがコードに欠陥を作成します。(2)欠陥が感染を引き起こします(3)感染が伝播します(4)感染が失敗を引き起こします。
デバッグスキルを向上させたい場合は、この本を強くお勧めします。
私自身の個人的な経験では、アプリケーションに多くのバグが見つかりましたが、管理者は単に私たちを先に進めます。新しい機能を引き出すために。 「このバグは自分たちで見つけたのですが、クライアントはまだ気づいていないので、気付くまでそのままにしておきます」とよく耳にします。バグの修正に積極的に取り組むのではなく、反応的に対応することは非常に悪い考えだと思います。実際に修正を加えるときが来たら、解決する必要のある他の問題があり、より多くの機能管理ができるだけ早くドアから出て欲しいので、捕まります。大きなストレスと燃え尽き症候群、そして最終的には欠陥のあるシステムにつながる可能性のある悪循環の中で。
バグが見つかった場合の通信も別の要因です。メールを送信するか、バグトラッカーはすべて問題ありませんが、私自身の経験では、他の開発者が同様のバグを見つけ、コードを修正するために配置したソリューションを再利用するのではなく(「すべてを忘れてしまったため)、独自のバージョンを追加します。コードには5つの異なるソリューションがあり、結果として肥大化して混乱しているように見えます。したがって、バグを修正するときは、数人の人が修正を確認し、同様の問題を修正した場合にフィードバックを提供するようにしてください。それに対処するための良い戦略を見つけました。
リミストは本に言及しました、
実用的なプログラマー。バグの修正に関する興味深い資料がいくつかあります。前の段落で示した例を使用して、これを見てみましょう:ソフトウェアエントロピー。ここでは、壊れた未亡人の例えが使用されています。ウィンドウが表示されると、積極的な姿勢をとらない限り、チームはそれを修正することに無関心になる可能性があります。
コメント
バグ、エラー、問題、欠陥-どのように呼んでも、それほど大きな違いはありません。それ以来、問題に固執します。 「私は慣れている」
- 問題の認識が何であるかを理解する:顧客の「ボブはまだシステムにない」から「私がしようとしたとき」に翻訳するボブのユーザーレコードを作成すると、重複キーの例外で失敗しますが、ボブは「まだそこにいません」
- それが本当に問題なのか、単なる誤解なのかを判断します(実際、ボブはそうではありません)。そこには、bobと呼ばれる人は誰もいないので、挿入は機能するはずです。
- 問題を再現するために実行できる最小限の信頼できる手順を取得するようにしてください。 -「ユーザーレコード「Bruce」のシステムを指定すると、ユーザーレコード「Bob」が挿入されると、例外が発生します」
- これはテストです-可能であれば、自動化されたものに入れます何度も実行できるテストハーネス。これはデバッグ時に非常に役立ちます。また、テストスイートの一部にして、特定の問題が後で再発しないようにすることもできます。
- デバッガーを取り出してブレークポイントの設定を開始します。テストを実行するときにコードパスを把握し、何が悪いのかを特定します。その際、テストをできるだけ狭くすることでテストを改善することもできます。理想的には単体テストです。
- 修正します。テストに合格することを確認します。
- 元の問題を確認します。顧客が説明したように、修正されています(非常に重要です-問題のサブセットを修正しただけかもしれません)。プログラムの他の側面でリグレッションを導入していないことを確認します。
コードに精通している場合、または問題や修正が明らかな場合は、それらの一部をスキップできます。手順。
貴重な時間を最大限に活用し、検索に費やす時間を減らし、コーディングにより多くの時間を費やせるようにするには、どのようにアプローチすればよいですか。 ?
新しいコードを書くことは、高品質の作業プログラムを持つよりも価値があることを意味するので、私はそれについて問題を抱えています。問題の修正に可能な限り効果的であることには何の問題もありませんが、プログラムにコードを追加するだけでプログラムが改善されるとは限りません。
コメント