私のキャリアの過程で、一部の開発者はデバッグツールを使用していませんが、問題のあるコードを特定するために誤ったコードをスポットチェックしていることに気づきました。
多くの場合、デバッガーなしでコードのエラーをすばやく見つけることができるのは良いスキルですが、デバッガーがタイプミスのような小さな間違いを簡単に見つけることができる場合、問題を探すのに多くの時間を費やすことは生産性が低いようです。
デバッガなしで複合システムを管理することは可能ですか?それはお勧めですか? 「 サイキックデバッグ 」を使用するとどのようなメリットがありますか?
外部から推測しているように見えるのは、私が「心の中でデバッグする」と呼ぶものであることがよくあります。ある意味で、これはチェス盤を見ずにチェスをプレイするグランドマスターの能力に似ています。
はるかに私が知っている最も効率的なデバッグ手法です。デバッガはまったく必要ないからです。脳は複数のコードパスを同時に探索するため、デバッガーを使用した場合よりもターンアラウンドが向上します。
競争力のあるプログラミング の世界に簡単に入る前は、この手法について意識していませんでした。デバッガを使用すると、貴重な秒数を失うことになります。約1年の競争の後、私はこの技術をほぼ独占的に最初の防衛線として使用し始め、その後、離れた3番目の場所に座っている実際のデバッガーを使用してデバッグログを記録しました。この方法の便利な副作用の1つは、新しいコードを書いたときに「心の中でのデバッグ」が止まらなかったため、新しいバグをゆっくりと追加し始めたことです。
もちろん、この方法には限界があります。これは主に、コード内の複数のパスを視覚化する際の頭の制限によるものです。私は私の心のこれらの制限を尊重することを学び、より高度なアルゴリズムのバグを修正するためにデバッガーに目を向けました。
コードベースをよく知っていればするほど、デバッガーの必要性は少なくなります(ただし、報告されたエラーを引き続きチェックしますが、それはどんな理由でも重要な手がかりです)。
これは、中小規模の複雑な動的動作を理解するための優れたツールですが、全体像ではなく詳細に焦点を当てていることがよくあります。そしてしばらくすると、問題が発生します。動的な動作が他のツール(たとえば、モジュール境界での入力と出力のログ)でより簡単に理解できる傾向がある、より広いスコープの相互作用で。
彼らは悪いプログラマではないかもしれませんが、おそらくひどく非効率的なトラブルシューティング担当者です。
私は デバッグからのアドバイスに従う傾向があります:最もわかりにくいソフトウェアおよびハードウェアの問題 を見つけるための9つの不可欠なルール(David Agans)、これは当てはまります「思考と見方をやめる」の指導のもとに
どのような仕事でも、適切なツールを適切に使用する必要があります。デバッガーがある場合は、それを使用して実際に何が起こっているかを確認します。ほとんどのバグは仮定によって引き起こされます。
私は、彼らがよりよく知っているので、デバッガーの使用を拒否する開発者と協力してきました。私が一度得た古典的な応答は、「私がクラッシュを引き起こしたのではなく、コードを[クラッシュした場所で]一日中調査し、何も問題はない」でした。 (データベースから読み取られたそのnull値はどうですか?)上司はそれを素晴らしい返信だと思っていたようですが、顧客はそうではありませんでした。
私はそのチームをできるだけ早く降りました。彼らの目的は、仕事を羽ばたかせ、10分の単純な問題を終日忙しい問題にすることでした。
デバッグの実践への最良のガイドは、Steve McConnelの本Code Completeです。第23章ではデバッグについて詳しく説明します。ここからいくつかのポイントを抽出します。
このトピックに関する議論で「単体テスト」について言及していないことに驚いています。
私はテスト駆動開発をしているので、デバッガーで多くの時間を費やしません。 10年前、私は忠実にデバッガーをステップスルーしていました:
10年間のテスト駆動開発の後でわかったことは、以下の場合、プログラマーとしての生産性が大幅に向上するということです。
コンピューターがコードを実行して結果を検証できるようにすることは、コードを思考またはステップ実行して結果を精神的に検証するよりも何千倍も速く、間違いを犯しません。
私はまだ時折デバッガーをステップスルーする必要があります、そして私はまだコードの精神分析に従事しています...
わかりにくい。推測によるデバッグmightは、バグが何か(ライブラリ関数に渡された値が正しくない、SQLが無効であるなど)についてすでに考えている場合に機能します。 「文字バッファが小さすぎる」など、エラー自体が小さいか明らかであると思われる場合、時々それを行います-スタックトレースは、失敗した行を示し、それを解決するためにデバッガーは必要ありません。
これを行うと常時は逆効果になる可能性があり、最初の数回の「推測」が失敗した場合、推測はおそらく間違った問題解決戦略であり、実際のデバッガーを呼び出す必要があります。通常、デバッガーを使用してもまったく問題ありません。
そうは言っても、私はデバッガーが正しく機能するのが非常に難しいか、最小限で役に立たないツールや環境で作業してきましたが、残念ながら、多くの場合、推測はより良いアプローチでした。私は適切なデバッガさえもないいくつかのプロプライエタリなツールで働いてきました。そのような環境で長時間作業していると、最終的にデバッガーに対する信頼を失い、推測アプローチに頼る可能性があると思います。
個人的には、デバッガーの使用を最小限に抑えるようにしています。
もちろん、誰もがエラーを起こすので、この方法でプログラムを作成する場合でも、テストが失敗した場合は、デバッガーを使用して中間式の値を検査します。しかし、上記の原則を順守することで、欠陥の特定が容易になり、デバッグが苦痛で不確定なプロセスを意味するわけではありません。
可能な限りデバッガを使用してください。デバッガーは単に問題を突き止める(ああ、この値を確認しなかった)か、関連するコードの分析に役立つ大量のコンテキストを提供します(うわー、スタックは完全にめちゃくちゃになっています。バッファオーバーフローの問題です)。
デバッグは、実行時にコード内のオブジェクトと変数の状態を検査するための非常に便利なツールです。
上記の回答で前述したように、デバッグは非常に役立ちますが、制限される場合もあります。
私の経験では、コードの状態について誤った仮定を明らかにするのに役立つため、デバッガーを使用すると非常に便利です。一部の人々は、コードを読んでバグを見つけるのが難しいので、デバッグは、あなたや他の開発者がコードの状態について行った誤った仮定を明らかにするのに役立ちます。
メソッドに渡されたときにパラメーターがnullになることはないと予想されるので、そのケースをチェックして、パラメーターがnullになることのないようにメソッドを実行することはありません。実際には、パラメータにwillを指定すると、メソッドの前提条件として、パラメータをnullにしてはならないという条件を設定しても、ある時点でnullになります。それは常に起こります。
前述の例でのデバッガーの有用性とは対照的に、私はマルチスレッド(つまり、同時実行、非同期処理)が関係しているときに使用することは困難であり、いくらか役に立たないことがわかります。助けることができますが、デバッガーのブレークポイントがポイントAの1つのスレッドとポイントBの完全に別のスレッドでヒットされている場合、マルチスレッドフォグで向きを失うのは簡単です。開発者は新しいブレークポイントをプッシュする必要があります。思考プロセス」を彼の脳の「スタック」の上に置き、新しいブレークポイントのポイントで自分自身をコードに向けます。ブレークポイントBの関連性が低下した後、開発者は最初のブレークポイントに戻り、ブレークポイントBのトリガーの前に探していたものを思い出さなければなりません。これは混乱を招く説明かもしれませんが、私のポイントこの段落では、同時実行が使用されるデバッグは非常に追加することができます(注意欠陥障害)プロセス、およびデバッグ思考パターンで生産性を維持することがより困難になる場合があります。
また、並行コードの予測不能性は、並行コードのデバッグで開発者の気を散らす可能性があります。
結論として、私の正直な意見では:
そして
彼らはちょっとハードコアすぎると思います。個人的にバグに遭遇したときは、コードを再チェックし、プログラムロジックから心の中でそれをたどります。 。
私はそれを釘付けにしたと思ったときでさえ、私は通常それが正しいことを確認するためにデバッグします。問題がもう少し複雑な場合、デバッグは絶対に不可欠だと思います。
また...私の意見だけですが、現代のIDEはツールを適切に活用しないことの言い訳はありません。それがあなたの仕事をより速くそしてより信頼できる方法では、それを使用する必要があります。
一般化するのは嫌いですが、私が出会った多くのプログラマーは、問題を解決する方法は1つだけ(その方法)だと思っています。すべての可能なテストが考えられてきたと仮定するのは簡単です。別の見方は非常に価値があります。
試行錯誤によるプログラミングは、いくつかの素晴らしい新しいアプローチを思い付くことができ、他の人が見逃したものをキャッチすることができます。
マイナス面は、通常、はるかに長くかかります。
えーと、それは人次第です。個人的には、私はデバッガをあまり使用していません。マイクロコントローラーをプログラムする場合、基本的にはLEDを使用するか、EEPROMにデータを書き込んでコードを「デバッグ」します。 JTAGは使用していません。
PCまたはサーバー用のソフトウェアをプログラミングするときは、ロギングと多くのコンソール出力を使用する傾向があります。 Cスタイルの言語では、プリプロセッサディレクティブを使用し、Javaではログレベルを使用しました。
私はデバッガーを使用しないので、私は何か間違っていると思いますか?エディターの仕事で、構文エラーのある場所を示し、論理エラーがある場合は、テストを実行するだけです。
デバッガーを使用する必要がないことと、デバッガーの使用方法を知らない(または使用を拒否する)ことには違いがあります。デバッガーは、バグの追跡と修正に使用する多くのツールの1つにすぎません。私は頭の中でそれを困惑させることができる開発者と、彼らがそうすることができると思う他の人たちと協力してきました。
最善の組み合わせは、単体テストで簡単にテストできるようにコードを記述し、エラーをログに記録することです。次に、ログを確認したり、デバッガを使用したりする必要がないことを望みます。保険を購入するようなものです。うまくいけばそれを使用する必要はないでしょうが、コードを再チェックしても解決できないバグに遭遇したら、適切なエラー処理/ロギング、ユニットテストを追加したり、デバッガーの使用を学ぶには遅すぎます。
ツール/プラットフォームが異なれば、デバッグ手法も異なります(デバッガー、ロギング、単体テストなど)。開発者がプラットフォーム/ツールのいくつかの手法に精通している限り、コードを再チェックするだけでなく、熟練した開発者ですが、デバッグに関して1つのトリックしかない場合、最終的には発見または修正できないバグに遭遇します。
ハイゼンバグ ?!?!
ハイゼンバグは、出力ステートメントの挿入やデバッガーでのプログラムの実行など、プログラムをデバッグする一般的な試みが通常コードを変更し、変数のメモリアドレスとその実行のタイミングを変更するために発生します。
私は最悪の場合にのみデバッガーを使用します(見つけにくいバグの場合)。また、多くの称賛されている開発者/テスターが話しているベストプラクティスに従って、コードを完全に単体テストすることは良いことです。これにより、ほとんどの問題をカバーできるため、デバッガーを使用する必要がなくなります。
優れた単体テストとバックトレースを提供する例外により、デバッガを使用する必要はほとんどありません。
最後にデバッグを使用したのは、レガシーアプリケーションでコアファイルを取得したときです。
私は「デバッガミニオン」なのか、それとも「ハードコアすぎる」のか?
どちらでもない。彼らは人生をより困難にしたい人のような人です。
最近、ここでデバッガのデバッグに対する引数を読みました(またはStackOverflowでしたか?)。コードに対するテストケースが必要です。テストに合格した場合、デバッグでバグが発生することはおそらくありません(想定:テストデータと同様のデータでデバッグすることを想定しています)。
一方、ロギングは必須です。テストに合格して本番環境にデプロイすると、バグが発生する場合があります。バグの証拠は、過去に発生した何かからのものです。つまり、誰かが「どうやってそこに入ったのですか」と言います。適切なログがない場合、原因を見つけることはできません。その時点では、実際にバグを引き起こしたデータのように見えないため、デバッガでさえ役に立たない場合があります。ログからアプリケーションをデバッグできる必要があります。
残念ながら、私はかなり言い換えているので、元の議論を邪悪なものにしているのかもしれません。特に、「開発時間をサポートするために重要なデバッグ支援者がいる」という立場は、デバッガーの重要性と直交するかもしれません。しかし、構成でシステム状態を設定することの難しさのために、バグを見つけるためのデバッグが有用になるという部分が、私が考えるべきことだと思いました。
デバッグは、優れた開発者が上手に使用すべきツールにすぎません。
確かに、コードベースを知っていれば、バグがどこにあるのかを心で知ることができます。しかし、コードを調べるだけで、1日または1週間も失われて厄介なバグを見つけることもできます。
なんらかのデバッグを行わない動的に型付けされた言語では(たとえ値をコンソールにダンプするだけでも)、推測が不可能になることがあります。
だからあなたの質問に答えるために-多分彼らは優秀なプログラマーかもしれませんが、彼らのトラブルシューティングスキルとバグを狩るときの彼らの熟練は悪いです。
問題の範囲によって異なります。プログラムが小さくて、物事がうまく分割されているなら、あなたはおそらく見ることによってそれを理解することができます。プログラムが、数年の間に100人以上のチームによって開発された450万行のコードである場合、特定のバグを特定することは不可能です。
上記のプログラム(C)で問題となっているのは、メモリの上書きでした。メモリブレークポイントを備えたデバッガーは、バグが発生するとすぐに問題のコード行を特定しました。しかし、この場合、誰かが配列を超えて書き込んだ1つのスポットを特定するために、450万行のコードをすべて読み取って保持することはできません(さらに、巨大なプログラムの状態のメモリのランタイムレイアウトを知っている必要があります)入力の長い実行に約10分かかり、そのポイントに到達します)。
ポイント:小さなプログラムや高度にモジュール化されたものでは、デバッガーなしで離れることができます。プログラムが本当に大きくて複雑な場合、デバッガーは多くの時間を節約できます。他の人が言ったように、それはツールであり、他のどの方法よりも優れている状況と、それが最良の選択ではない状況があります。
バグがクライアントのコンピューターで発生する場合、または環境がユーザーのコンピューターと大きく異なるコンピューターで発生する場合、デバッガーまたはリモートデバッガーのセットアップは面倒です。したがって、フィールドからバグが発生する寒い日には、「しかし...デバッガーがない」という応答は役に立ちません。したがって、コードとログファイルを理解するだけで、トラブルシューティングとバグの発見のスキルセットを開発する必要があります。