web-dev-qa-db-ja.com

デバッグに費やす時間を減らす方法は?

パレート規則に従って、プログラマーは本当に役立つもののために時間の20%しか費やしません。

私は私の時間の80%をデバッグに費やし、すべてを機能させるために小さなことを修正します。

デバッグ時間を短縮する方法はありますか?

15
uhbif19

Agda または Coq のコード。コードがコンパイルされると、機能します。難易度が高すぎる場合は、型システムの弱い言語を選択してください(HaskellやF#など)。

それでも、ほとんどの場合、時間の20%をコーディングに費やし、80%をテストとデバッグに費やすことで、生産性が大幅に向上します。 1週間の100%は1時間の20%をはるかに超えています。デバッグが物事を成し遂げるために必要なものであれば、デバッグは時間の無駄ではなく、この比率を「改善」することに煩わされるべきではありません。

5
SK-logic

ユニットテスト。

単体テストの適用を開始した後、私が書いたコードはより適切に構造化されていることがわかりました。その後、バグを回避して特定するのが簡単になりました。デバッグに費やす時間は減りましたが、単体テストの作成により多くの時間を費やしました。

単体テストに費やした時間は、デバッグよりも投資収益率が高いと私は思います。デバッグセッションの後、コードを修正しました。同じバグが数週間後に現れる可能性があり、もう一度デバッグする必要があります。単体テストを作成すると、バグは単体テストとして文書化され、後で回帰テストとして機能します。バグが再び発生する場合、ユニットテストでこれが明らかになります。

44
Theo Lenndorff
  • 単体テスト。コードが最初から機能するかどうかを確認できます。
  • 少なくともいくらかの事前設計を行い、コーディング対象がわかるようにします。
  • 2つの頭は1つよりも優れており、4つの目は2つよりも優れているため、コードレビュー。コードを誰かに説明しようとしても、多くの問題が明らかになることは言うまでもありません。
  • バージョン管理。これにより、バグの原因となった可能性のある変更をすばやく特定できます。
  • コードをリファクタリングして、恐ろしい理解不能な混乱に陥らないようにします。
  • ロバート・C・マーティンの「クリーンコード」を読んで、彼があなたに言うことをしてください。あなたは結果に驚かれることでしょう。
35
Dima

単体テストは、本番コードの前に壊れるバグを導入した場合にも期待できます。適切に記述された単体テストでも、何が問題を起こしたかがわかります。

これでほとんどの方法が得られますが、99.999%のプロジェクトの場合は、時間をかけてデバッグする必要があります。ここで私が見つける最善のことは、4つのことを行うことです。

  1. 可能な限り不変の型を使用します-何かが間違った値を持っている場合、すぐにどこを見ればいいのか(どこで構築されているのか)がわかります。
  2. コードに不変式を適用する-値が絶対に許可されていないことがわかっている場合は、それを確認し、メソッドとコンストラクターへのエントリポイントで例外をスローします。これを不変の型と組み合わせると、何が有効であるか、またはそうでないかについて特定の仮定を始めることもできます。
  3. 適切なロギングがあることを確認してください-これを早期に取得すると、問題が発生したときの重要な情報がたくさん得られます。 AOPはここで非常にうまく機能します。後付けとしてのロギングは、通常、少しごみです-プロジェクトのセットアップの一部として早い段階で取得してください。
  4. コードベースが大きく複雑な場合は、プリミティブの使用を避けてください。単にintを使用するのではなく、 'Age'と呼ばれる型があります。最初は少し無意味に見えるかもしれませんが、何かのすべての使用を瞬時に追跡できることは、大きなデバッグの勝利です。
8
FinnNk

私の80%はデバッグです。私は簡単なバグを修正し、すべてが機能するようにしています。

単体テストを作成することから始めて、できるだけ高いカバレッジを持つようにしてください。誰かがTDDについて言及しましたが、私は [〜#〜] bdd [〜#〜] で行きます。

最後に、80%を複雑なバグのデバッグに費やすことになります。

6
BЈовић

デバッグに費やす時間を減らす方法は?より少ないコードを記述します。

真剣に、コードを書く限り、デバッグする必要があります。単体テストなどは非常に役立ちますが、その必要性を完全に取り除くことはないと思います。

6
Daniel Roseman

コードを書き始める前に、何を、そしてなぜを理解してください。次に、一貫して方法論を使用します。どの方法論を選択するかは、方法論の一貫した繰り返し使用ほど重要ではありません。一貫して優れた結果が必要な場合は、一貫して優れた作業を行う必要があり、「狂気への方法」を持つことは、これらの結果を得るための最初のステップです。問題を特定すると、必要に応じて方法論を調整でき、時間の経過とともに開発プロセスを改善し、できればバグの数を減らし、より有意義な開発を行うことができます。

4
cdkMoose

コードをコンパイルする前に、コードを注意深く読んでください。構文と機能の注意深い読み。これは驚くほど有益である可能性があり、コードのセクションが複雑すぎる場合にも良い指標となります。

3
anon

ほとんどの回答は、デバッグしなければならない問題の数を減らす方法に焦点を当てているようで、それは価値があります。ただし、デバッグは常に必要になるため、デバッグを高速化する方法を検討すると役立ちます。

  • バージョン管理ソフトウェアの使用方法を理解します。

    • ブランチを使用すると、開発の領域を分離するのに役立ち、どの開発領域にバグがあり、どの領域にバグがないかを確認できます。
    • VCSで二分割を使用する方法を学びます。Gitにはこれが組み込まれています。二分割が組み込まれていない別のVCSを使用している場合は、git bisectのように機能するツールを探しますが、VCS用です(これはSVNと他のVCS向けに作成するのは難しくありません)。これは、バグを引き起こしたコードの変更に絞り込むのに役立ち、デバッガーをどこに向けるかを知るのに役立ちます。この二分プロセスは、バグのテストがある場合に速くなり、どのコミットに問題のある変更が含まれているのかを知ることは、アトミックコミットを実践する場合にさらに役立ちます。
  • 使用するプログラミング言語の理解を深めます。

    • プログラミング言語に関する本、ブログ、コードを読んでください。
    • バグを修正するたびに、コードが機能しない理由と修正が機能する理由を完全に理解してください。時間が経つにつれて、問題を回避し、再発した場合の症状を見つけるのに役立つ、あなたの言語で多くの落とし穴を学びます。
  • 論理的であること

    • 一度に複数の変更を行わないでください。変更しないと、動作が変わった場合に、どの変更が動作の変更を引き起こしたかがわかりません。
    • 想定を確認します。
3
Stephen Paulger

単体テストのコメントに追加しますが、それがサポートされるようにコードが分離されている場合(MVCなど)にのみ有効です。 MVC(または同様のもの)(レガシープロジェクト)を実装できない場合、UIに対してユニットテストはまったく機能しません。次に、コードのその部分のエラーを減らすため、自動UIテスト(Microsoft Coded UI Tests、WaitN)を追加します。

また、静的分析ツール(FxCop/Microsoftコード分析、Resharper、MSワールド向けJustCodeなど)を実行することを強くお勧めします。これらは、ばかげたデバッグタスクを減らし、ビジネスロジックのデバッグにより集中できる、あらゆる種類の一般的なコーディングの問題を見つけることができます。

2
Scott Wylie

それを機能させて、それを速くして、それからきれいにしてください。ほとんどのバグは、初期の最適化または完全に問題のないコード行でのリファクタリングに起因しています。オブジェクトの方向付けを行う場合は、自分自身を繰り返さないでください。特に、メソッドが制約で機能する場合は、単純にして、常に値の範囲の健全性チェックを行ってください。ミスを減らすのには役立ちませんが、バグをより早く見つけるのに役立つため、デバッグにかかる​​時間が短くなります。

2
kibotu

最近、この問題について多くのことを考えてきました。簡単な答えは、Don NormanのThe Design of Everyday Thingsを読むことです。製品を設計するのと同じようにコードを記述します。

言い換えれば、優れた設計はエラーを最小限に抑えます。これは、いくつかのことを意味しますが、そのほとんどは既に実行しています(正確にはわからない場合もありますwhy)。

-名前は直感的に機能します。これは正式にはアフォーダンスとして知られています。つまり、ボタンは押すことができ、レバーは切り替えることができ、ハンドルは引くことができます。

-悪いコードを書くのを難しくする。不適切な入力をチェックし、後でエラーをスローする、適切なときにハンガリー語のアプリを使用するなど。これらはロックアウト機能と呼ばれます。

-必要に応じて抽象化を使用します。短期記憶が弱い。

-ドキュメントは明らかに重要ですが、コードが適切に使用されていることを確認するのに最も効果がありません。つまり、適切に設計された製品にはドキュメントは必要ありません。 (これを確認する最も明白な方法は、悪い例、つまり、プッシュするはずのハンドルが付いたドアを調べることです。)

-ユニットテスト。これらは実際にはエラーを防止するものではなく、バグの場所を明確にし、正気を提供します。

私はもっ​​と多くの原則を見逃していると確信していますが、要点は、エラーの設計について読んでください。

2
Ceasar Bautista

デバッグIMOを減らす最善の方法は、コーディング時に集中して速度を落とすことです。これはあなたにあなたがしたかもしれない間違いを見ることを強います!

1
Dynamic

上記のユニットテストは完全にサポートしていますが、TDDまたはBDDは、問題と解決策を最初に考える必要があるため、非常に価値があります。

しかし、私にとって個人的には、静かに座って問題とそのアプローチ方法、および各アプローチの長所と短所について考えるために数分かかると、私のコードの品質に疑問を感じ、混乱を解消するのに役立ちます。

時々、紙の上をすばやく落書きすることで、接続された大きなパズルのピースを確認できます。

最初に頭に飛び込んでキーボードを叩くだけで、最悪のコードを書きます。少し考え、熟考することで、世界は変わります。

PS。巨大な仕様を何時間も書くのではなく、5分、たぶん10分ということです。

1
SetiSeeker

すでに良い答えがいくつかありますが、他の人が言ったことに加えて、もう少し食べ物があります。

あなたの過ちから学びなさい。同じものを何度も何度も作り続けないでください。

プログラミングの際は必ずEdgeのケースをカバーしてください。これらは頻繁にバグが発生する場所です。

要件に注意してください。動作しても、要件が指定されていない場合でも、それはバグです。

例外ログは、6か月後に何か問題が発生した場合に非常に役立ちます。例外を記録する習慣を身につけましょう。

1
HLGEM

私の2つの重要な考えは、1)予期しない何かを実行すると失敗する、より優れたコードを記述します。2)デバッグがうまくいきます。

私のコードは散らかっています

if(value!=null) throw new NotImplementedException();
if(obj.v>0) throw new Exception(); //sometimes i dont write NotImplementedException
if(value=="thing") throw ...;

そのコードを実行するたびに例外がスローされ、デバッガーが停止して、新しい機能でコードを記述したり、状況を回避したりして、何が起こっているのか混乱する/バグが発生する

コールスタック、ブレークポイント(条件付き)、イミディエイトウィンドウ(プロンプトまたはreplウィンドウとも呼ばれます)、変数を監視する変数などを使用して、混乱のデバッグを改善します。

0
user2528