デバッグに費やす時間を減らす方法 [閉まっている]


15

パレートルールに従って、プログラマーは本当に便利なことに時間の20%しか費やしません。

デバッグに80%の時間を費やし、小さなものを修正してすべてが機能するようにします。

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


9
それがパレートの原理をどのように解釈するかわからない。
-c_maker

6
<meme> TDDを
ご覧ください

1
あなたが実際に何をするデバッグ時?

3
詳細に注意を払うためにより多くの時間を費やす必要がある

1
コードをときどき見るだけで多くのことが得られます。さらに良いのは、衝動を感じながらコメントを書くことです。そうすれば、後で間違いを見つけやすくなります。
ジョーイアダムス

回答:


5

AgdaまたはCoqのコード。コードがコンパイルされると、動作します。ハードコアすぎる場合は、HaskellやF#など、型システムの弱い言語を選択してください。

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


1
何かが実行されるからといって、バグがないわけではありません。バグは多くの場合、コードが間違ったことをした結果です。
HLGEM

3
@HLGEM、投票する前に、AgdaとCoqの詳細を読んでおくべきです。コードがコンパイルされる と 、その仕様どおりに動作することが保証および証明されます。もちろん、仕様にもバグがある可能性がありますが、この種の問題の修正を「デバッグ」とは呼びません。
SKロジック

2
@HLGEM、あなたの「デバッグ」の概念は非常に創造的であり、主流からはほど遠い。とにかく、このアプローチでは、コーディングと「デバッグ」の割合は20/80にはほど遠いでしょう。だから、あなたの下票を説明してください。
SKロジック

1
@HLGEM、それはOP要件のリストにありませんでした。開発者の人数や担当者などについては何もわかりません。唯一の質問は「20/80比を測定する方法」でした。静的に検証された言語を使用することは、明らかに最も明白な答えです。しかし、すでに述べたように、この答えは非常にまれな場合にのみ適用可能であり、一般的には20/80ルールに従うことがはるかに優れたオプションです。
SKロジック

1
@ uhbif19クヌースはそれを言うときにユーモラスであることを意味していました。彼の本当の意味を知っていますか?
フィル

44

単体テスト。

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

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


私は単体テストを使用し、あなたに完全に同意します。しかし、すべてをテストすることはできません。
uhbif19

5
もちろんできます。すべてではありませんが、重要なすべてです。インターフェイス、依存関係の注入、偽装およびクラス/メソッドのモックにより、ほとんどすべてのコードのテストを作成できます。
フレドリック

8
@Fredrik、a + bコードの一部でさえ適切に単体テストを行うことはできません(テストが算術データ型の全範囲をカバーしていない限り)。
SKロジック

「デバッグセッションの後、コードを修正しました。」 - 本当に?デバッグセッションの後、さらに多くのバグを導入したと思う-どこにあるのかわからない。
B七つの

35
  • ユニットテスト。コードが最初に機能するかどうかを確認できます。
  • 少なくともある程度の事前設計により、コーディング内容を把握できます。
  • コードレビュー。2つのヘッドが1よりも優れており、4つの目が2よりも優れているためです。コードを他の人に説明しようとしても、多くの問題が明らかになることは言うまでもありません。
  • バージョン管理。これにより、バグの原因となった可能性のある変更をすばやく特定できます。
  • あなたのコードが恐ろしく理解できない混乱にならないように、リファクタリング。
  • Robert C. Martinの「Clean Code」を読んで、彼が言ったことをしてください。あなたはその結果に驚くでしょう。

5
正確に-単一のプラクティス(例:単体テスト)で桁違いの改善が得られるわけではありませんが、プラクティス組み合わせることで改善できます。つまり、特効薬はありません。
マイケル

TDDを追加します(可能な場合)。
トム

1
私は実際にきれいなコードとリファクタリングを最初にソートしたいと思います。単体テストはバグを早期に発見して修正するのに適していますが、バグの数を減らすことはありません(メモリに新しいものがすべてある場合でもバグを修正するため、時間は少し短縮されます)。一方、きれいなコードを書くと、実際のバグの数が減ります。
ジャン・ヒューデック

1
@JanHudecリファクタリング+クリーンコード+テスト= TDD
トム

1
@Tom:はい。ただし、そのさまざまな部分にはさまざまな効果があります。きれいなコードを書くことを学ぶことは、テストなしでデバッグ時間を短縮するのに役立ちます。テストがあるので、使用する前にモジュールをテストでき、リファクタリング時に動作を変更しなかったことを確認できます。これは、古い乱雑なコードをクリーンアップするために必要です。
ジャン・ヒューデック

8

ユニットテストは、実稼働コードの前にそれらが壊れるバグを導入する場合に役立ちます-よく書かれたユニットテストは、正確に何が壊れたかを教えてくれます。

ほとんどの場合、これで問題は解決しますが、99.999%のプロジェクトでは、時間をかけてデバッグする必要があります。ここで行うのに最適なことは、4つのことを行うことです。

  1. 不変の型を可能な限り使用します-何かが間違った値を持っている場合、すぐにどこを探すべきか(構築されている場所)を正確に知ることができます。
  2. コードに不変条件を強制する-値が絶対に許可されないことがわかっている場合は、その値を確認し、メソッドとコンストラクターへのエントリポイントで例外をスローします。これを不変の型と組み合わせると、何が有効かどうかについて特定の仮定を立てることもできます。
  3. 十分なログを記録するようにしてください-これを早めに取得すると、問題が発生した場合の重要な情報がたくさん得られます。AOPはここで本当にうまく機能します。後付けでログを記録することは、通常少しゴミです-プロジェクトのセットアップの一環として、早めに入手してください。
  4. コードベースが十分に大きい/複雑な場合は、プリミティブを使用しないでください。たとえば、単にintを使用するのではなく、「Age」という型を使用します。最初は少し無意味に思えますが、何かのすべての使用を瞬時に追跡できることは、デバッグの大きな勝利です。

6

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

単体テストを書くことから始めて、可能な限り高いカバレッジを持つようにしてください。誰かがTDDについて言及しましたが、私はBDDを使います。

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


6

デバッグ時間を短縮する方法は?より少ないコードを記述します。

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


4

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


3

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


全くもって同じ意見です。コードを書いた直後にコードを読むと、コピーアンドペーストのタイプミスなどの明らかなバグがすぐに明らかになります(後で見つけるのが難しい場合があります)。
jirkamat

3

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

  • バージョン管理ソフトウェアの使用方法を知ってください。

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

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

    • 一度に複数のことを変更しないでください。そうしないと、動作が変更された場合、どの変更が動作の変更を引き起こしたのかわかりません。
    • 前提を確認してください。

2

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

また、静的分析ツール(MSの世界ではFxCop / Microsoft Code Analysis、Resharper、JustCodeなど)を実行することを強くお勧めします。これらはすべての種類の一般的なコーディングの問題を見つけることができ、愚かなデバッグタスクを削減し、ビジネスロジックのデバッグにより重点を置くことができます。


2

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


1
「ほとんどのバグは...」という主張は良いように聞こえますが、それを裏付ける証拠はありますか?「ほとんどのバグは、不十分に指定された要件または明確な設計の欠如に由来する」と言った場合、それは同様に説得力があると思うと思います。あなたの声明を裏付ける研究へのリンクまたは引用を追加すべきです。
カレブ

2

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

言い換えれば、優れた設計はエラーを最小限に抑えます。これは、いくつかのことを意味しますが、そのほとんどはすでに行っています(ただし、正確な理由はわからないかもしれませんが)。

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

-悪いコードを書くのを難しくしてください。不正な入力をチェックし、エラーをスローするのではなく、遅らせる、必要に応じてハンガリー語のアプリを使用するなど。これらはロックアウト関数と呼ばれます。

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

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

-ユニットテスト。これらは、バグがどこにあるのかを明らかにするだけでなく、実際にエラーを防ぐものではなく、健全性を提供します。

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


1

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


1

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

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

時々、紙の上にすばやく落書きをすると、パズルのより大きな接続部分を見るのに役立ちます。

最初に頭を下げてキーボードをたたくと最悪のコードを書きます。少しの思考と熟考が世界を変えます。

PS。5時間というのは10時間ということで、数時間で大きなスペックを書くのではありません。


1

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

あなたの間違いから学びましょう。同じものを何度も作り続けないでください。

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

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

例外ログは、今から6か月後に問題が発生した場合に役立ちます。例外を記録する習慣をつけてください。


0

私の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 ...;

そのコードを実行するたびに例外がスローされ、デバッガーが停止するため、新しい機能でコードを作成したり、条件を回避したりするのではなく、何が起こっているのか、バグを抱えている

コールスタック、ブレークポイント(条件付き)、イミディエイトウィンドウ(プロンプトウィンドウまたはレプリケートウィンドウとも呼ばれる)、「ウォッチ」変数など、さまざまな問題をデバッグするのに優れています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.