バグの調査方法の学習[終了]


11

この難しさをどのように定義すればよいかさえ分かりません。就職する前に、数人の有望な従業員が私に対して行ったテストを思い出します。彼らは部屋のオブジェクトを選択し、そのオブジェクトが何であるかを自分で判断するのに役立つ質問をすることができます(20個の質問のように)。私はこれで途方もなく優れていたので(いや、謙虚さで高いポイントを獲得したことはありませんでした)、バグのトラブルシューティングは本当に上手だと思いました...

しかし、私が最近見つけたものは次のとおりです。部屋にあるすべてのものを見るのは本当に簡単なので、そのような状況では本当に良いです。したがって、コンポーネントの一部の概念で問題に取り組むことができます。本質的に、「知らないことを知っている」。しかし、プログラミングでは、問題が私にとって完全に未知である多くの状況に遭遇します。私はそれが壊れていることを知っていますが、どのように壊れるかという概念はありません。私はすべての指示に従いました、私は技術をかなりよく知っています...

正直なところ、間違っている可能性のあるものを想像するのに苦労しているように感じるので、それらをテストし、できれば解決策を見つけることができます。

そのスキルを開発するにはどうすればよいですか?どうやら、私の想像上の限られた想像力が私のプロジェクトを破壊する可能性のある方法を思い付くために何をする必要がありますか?これで私を良くすることができるエクササイズ(おそらくパズル?)はありますか?おそらく最大の治療法は経験だけであることを知っています...しかし、できればプロセスを加速する手助けをしたいと思っています。一度に数時間、ぼんやりと私のコンピューター画面を見つめることは、ちょっと面白くないです...


3
どのように機能するかを想像し、調査するパスを見つけるために出力から入力まで逆方向に作業します
スティーブンA.ロウ14

1
私はそこにリンクを投げます- プログラマーになる方法 -最初にリストされているスキルは「Learn to Debug」です。

1
私は「箱から出して」の思考に関して何かを投げ出したかった。バグに関しては、最初に行うことは、相互作用しているすべてのシステムを単純にリストし、それ以外の部分が別の方法で証明されるまで故障している可能性があると想定することだと思います。次に、ジョブが簡単になります。コンポーネントに障害が発生していると想定し、最初は非論理的である(「出力が破損している」など)場合でも解決できる方法を見つけます。次に、コンポーネントが失敗していないことを証明します。まず、最も迅速な対話から始めます。事実の後、それは想像力のように見えるかもしれませんが、多くの場合、それは悲観的な見方から始まっています。
Jトラナ14

すべてのコード行で使用するprintfprintlnまたは何でも記述して、すべてがあなたが望むように動作することを100%確実にするようにします(笑)。次に、コンソールアプリケーションを実行しますApp > out.txt。巨大なファイルを表示するのは難しい部分です。ログファイルが数百万行を超えることがあり、時間がかかる場合があります。もちろん、デバッガーとブレークポイントを使用するのが正しい方法ですが、それができない場合もあります。
SSpoke

1
Pirsigの禅とオートバイのメンテナンスのアート を読むamazon.com/Zen-Art-Motorcycle-Maintenance-Inquiry/dp/0060589469
ジェフリーケンプ14

回答:


11

ソフトウェアのすべての欠陥は、最終的に仮定と現実の不一致によるものです。陰湿なバグは、特に根深い仮定と現実との間の単なる矛盾です。バグを診断する能力は、あなた自身の仮定に疑問を投げかける能力に依存します。それは確かに、特定の事柄を知らないという認識を必要とします。

当然、取引のツール、ログファイル、デバッガーなどは、このような仮定を明らかにし、ワールドモデルを実際のシステムと再調整するのに役立ちます。しかし、「包括的な入力チェックがあるので、悪い入力にはなりえない」などの重要な仮定に疑問を抱く準備ができるまで、システムの間違った部分をチェックするか、単に他のどこを見るべきかわからないそもそも。


3
キリアンとは言いたくありませんが、頭に釘を打ったと思います。私はここにいる間に獲得したシステムの「知識」を非常に誇りに思っており、間違っているという考えに精神的に抵抗していると思います。私が言及したかもしれないように、私は決して謙虚さで高得点しませんでした。私の仮定に挑戦するためのあなたのアドバイスに従うことで、実際に私は自分のコードで直面していたいくつかの問題でいくつかの堅実な進歩を遂げることができました。ですから、これから先もこのことを心に留めておきます。
ジェイカー14

2
@JayCarr:「間違っているという考えに精神的に抵抗している」-間違いではなく、誤りの原因を学習の源として見ようとしたらどうでしょうか。あなたがそこで止まらない限り、間違っていることは何も悪いことではありません。
JensG 14

14

どうやら、私の想像上の限られた想像力が私のプロジェクトを破壊する可能性のある方法を思い付くために何をする必要がありますか?

ほとんどの場合、絶対に何も言いません。プログラムが壊れる原因になる可能性のあることを考えようとするべきではありません。あなたは体系的かを決定する必要がありますされ、それが破損する原因となります。

次の情報を使用して、デバッグプロセスに入る必要があります。

  • 実行された手順と、バグを生成するために入力された値。
  • これらのステップと入力が与えられたときにプログラムが実行すべきこと。
  • これらのステップと入力が与えられたときにプログラム実行していること。

エラーメッセージが表示された場合は、エラーに関する情報をすべて入手してください。エラーメッセージ自体が明確ではなく、実際の意味がわからない場合(一部のエラーメッセージは特に有用ではない場合があります)、Google、StackOverflow、またはその他のオンラインリソースを使用して、それに関する情報を検索します。

フロントエンドにエラーメッセージが表示されない場合は、バグを再現した期間中にアプリケーションがエラーメッセージを書き込むログを確認します。コードは最後まで実行された可能性がありますが、途中で処理されている例外が発生し、最終結果がスローされ、ログにエントリが生成されます。それらを探し、上記と同じことを行い、それらが意味するものを正確に特定します。

コードによってスローされた例外とともにスタックトレースが提供されている場合(および存在するはずです)、記載されているコード行を参照してください。行自体は、実際に問題を引き起こしているものではない場合があります。Javaコードの一部でNullPointerExceptionを受け取った場合、スタックトレースは、nullであったはずのないものを使用しようとした場所を通知します。それは問題の原因となっている行を正確に指し示すものではありませんが、一般にどの変数が期待する値を持たないかを教えてくれるので、その変数への参照/割り当てを見て値を決定できます設定されていないか、値が正しく設定されていない。

それでも解決しない場合は、デバッガを起動してください。問題の原因であることがわかっているコードのセクションに絞り込んでいるが、どの行が正確にわからないのかを確認してから、それをステップ実行します。そうでない場合は、全体をステップスルーします。これは、与えられた入力に対してプログラムが何をすべきかを正確に知る必要がある場所です。なぜなら、各行の後に各値を見て、それが期待していることから逸脱している場所を正確に判断する必要があるからです。

それでも問題が何であるか手がかりを持っていませんか?誰かに助けを求めてください。同僚、友人、オンラインコミュニティ。あなたが今やったすべての仕事を見せてください。エラーメッセージ、スタックトレースを表示し、プログラムが何をするかを一般的な用語で説明します(まだ知らない場合)、この特定のインスタンスで何をすべきか(例:値4を返す)、実際に何をするか(例値5)を返します。デバッガーで数行のコードに絞り込んだ場合、「問題はコード内のこれらの行が原因であることがわかります。Yになるはずの値をXに設定していますが、表示されません」なぜそれが起こっているのか」。

数時間画面を見つめているのは間違いなく楽しいことではありませんが、そうすべき理由はありません。コードに問題がある場合は、コードを読むかステップスルーする必要があります。


この答えを判断するのは少し早かったかもしれませんが、それを読んだときは少しイライラしていました。健全なアドバイス。Killiansのコメントは、私が思うに私の問題の核心にもっと語っただけです。これが代わりに選択された答えではない唯一の理由です。
ジェイカー14

4

ある程度までは、刑事事件の調査や、気が遠くなるようなパズルのようなものです。

最初に、あなたは犠牲者を得ました。しばらく掘り下げた後、数人の容疑者を特定し、被害者が正確に殺害される可能性があるという作業仮説も立てました。調査を続け、より役立つ情報を探し、問題の実際の原因にどんどん近づけます。

たまに行き止まりに入ってしまうことがあります(しゃれが意図されています)。それはその一部であり、あなたができるだけ早く軌道に乗ることができれば、何も問題はありません。重要なのは、次に必要な情報を常に考え、仮説を提供する(さらに詳細な情報を提供する)か、それが間違っていることを証明することです。その後、その情報を効率的な方法で取得し、結論を出して、最終的に有罪を宣告できるようになるまで進みます。

そして、時には、犯人を見つけるのに必要なすべての事実と兆候が、30分前にすでにあなたの前で待っていたことに気づきます。迷惑ではあります、これは最も興味深い部分の1つです。なぜなら、アクションやミスについて批判的なレビュー行うと、学習して改善できるからです。次のような質問を自問してください。

  • この時間の無駄をどのように回避できたでしょうか?
  • そもそも私が見落としていたのはなぜですか?
  • どのような未検証および/または間違った仮定に依存しましたか?

これはあなたの能力を訓練します。また、腸の本能を発達させるので、時間の経過とともに、見過ごされがちなマイナーなものすべてに自動的に気づくことを学び、より迅速に正しい答えを導きます。最後に、それはすべて意図的な練習についてです。

最後に、シャーロック・ホームズが教えてくれたことを常に忘れないでください。不可能を排除したとき、どんなにありそうにないものでも、真実でなければなりません。


3

どうやら、私の想像上の限られた想像力が私のプロジェクトを破壊する可能性のある方法を思い付くために何をする必要がありますか?

歴史をガイドにしましょう。プロジェクトが適切に管理されている場合、バグの発見方法、再現方法、分析方法、および修正方法の分析とともに、製品でこれまでに修正されたすべてのバグのデータベースが必要です。それは書き込み専用データベースではありません。データベースを読むと、すぐにバグ分類法が発生し始めます。

それはあなたの製品でうまくいかないことの種類の良い概要を提供します。あらゆる種類のソフトウェアで何がうまくいかないか、特にセキュリティに影響を与える欠陥に重点を置いて、より一般的に興味がある場合は、CWEリストを読むことをお勧めします。http//cwe.mitre.org/data/index.html


2

特定の欠陥を再現して修正しようとするのではなく、製品を調査してそのような状況で製品が機能するかどうかを確認するために使用できる新しいテストを検討することを求めていると思います:特殊文字を入力するとどうなりますか?サインアップページのパスワードが提出された、またはデータベースへの書き込み中にプログラムを強制的に閉じるとどうなりますか。これらのケースを実際に考えるのは難しいです。

過去10年間のソフトウェア開発(アジャイル/ XP / TDDなど)は、明示的な要件のみを満たし、機能の終了を宣言し、何かを壊す可能性のあるすべての方法を見つけられないことを重視しています(例外がある場合は、可能性がありますNASAで働いているか、ホワイトハットセキュリティを行っていますが、その場合でも、ユーザーストーリーの受け入れ基準でそのようなことを呼び出す必要がある場合があります)。

そのため、入力の処理方法、そのパフォーマンス特性、ユーザーワークフローアクションなど、システムが必要とする機能が受け入れ基準として明示的にリストされている場合、テストでチェックする必要があるものの完全なリストがあります。要件が満たされていることを検証するためにテストを行う必要があります。そのための最善の方法は、すべての要件を明示的にリストすることです。見てみましょうアジャイルテスト象限を

一部の人々は、これらのテストが要件の明示的な宣言であり、コードの前に記述される必要があること、つまりテストファースト(またはテスト駆動開発)であると主張しています。

ただし、開始前に独自の開発ベストプラクティスを設定し、代わりにソフトウェアが記述されて「テストする」ように求められた後に、新しいプロジェクトを設定できる新しいプロジェクトを検討しているとは思えません。これは実際にはより困難ですが、同じ原則が適用されます。何をすべきかを知って初めてテストすることができます。開発チームが満たす必要のある包括的な要件リストが存在しない場合は、質問することが最善の方法です。チームによっては、ソフトウェアシステムを構築する前に要件を明示的にリストしていない人は、見落としたことを思い出したくないので、これを微妙に行う必要がありますが、このタスクを適切に実行するために不可欠です。

要件を見つけたら-堅牢である必要があり、安全である必要があります。次に、より深く掘り下げて、どれだけ安全であるか、またはどの程度の障害を許容できるかを調べてみてください。アプリケーションの要件としてのセキュリティレベル、またはその代価を支払うことを希望するレベル。掘り下げるほど、どのタイプのセキュリティ攻撃を防御する必要があるか、または目的の使いやすさを明確にする必要があります。いくつかのドメイン知識は、セキュリティ、設計、パフォーマンスなどで役立ちます。ここで、チーム、またはSE、またはgoogle / booksで見つけることができる専門家からさらに質問をすることができます。


私が答えを探していた質問ではありませんが、それでもなお優れた解説です。私はあなたに投票しています、これは非常に有益な解説です。
ジェイカー14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.