10

ローカル変数の初期化に関するこの質問に出くわしました。回答の多くは、シンプルさ/読みやすさと堅牢性について議論していました。(リモートで展開された) 組み込みシステムの開発者として、私は常に堅牢性を好み、いくつかの一見矛盾するルールに従う傾向があります。

  • デバイスが動作を継続できるように、すべてのエラーをできる限り処理してください。

  • プログラミングまたは致命的なエラーが発生した後、できるだけ早く失敗するようにコードを設計します。

私たちは皆、入力を検証して、ユーザー (またはその他の外部) 入力の結果としてデバイスが破損するのを防ぐように訓練されています。データが無効である可能性があると常に想定し、それに応じてテストします。

堅牢性を確保するために、他にどのような具体的な慣行に従っていますか? 例は役に立ちますが、普遍的に適用できる手法 にも興味があります。

4

10 に答える 10

7

私は「The Pragmatic Programmer」で説明されているテクニックのファンです。また、より柔軟で生産性が高いため、DBC ではなくTDDを使用しています。たとえば、「pragprog」で説明されているテクニックには次のものがあります。

  • 頻繁にテストします。早めにテストしてください。自動テスト
  • 繰り返さないで
  • 破壊工作員を使用してテストをテストする
  • 例外的な問題には例外を使用する
  • 壊れた窓と一緒に暮らすな
  • 手動の手順を使用しない

それらはすべて常識のように思えますが、締め切りに直面したときに、チームがこれらの基本原則からいかに迅速に逸脱するかは驚くべきことです。

于 2008-11-12T06:07:25.097 に答える
6

私は2 番目の方法が好きです。いくつかの重要なコードを書いてテストした後、それを破る方法を探す目的で、同僚に具体的にレビューするように依頼することがあります。

こうして人々のクリエイティビティを引き出すのは楽しい。:-)

于 2008-11-12T14:08:57.107 に答える
5

すでに次の 2 つがダウンしているようですね:
Fail Fast。http://en.wikipedia.org/wiki/Fail-fast
フェイル セーフ。http://en.wikipedia.org/wiki/フェイルセーフ

これらの 3 つは、おそらく他のどれよりも私に役立ちます。

可能な限り状態を避けてください。不変オブジェクトを作成して使用します。テストが容易で、裏切られる可能性が低くなります。

不要なコードを書かないでください。これは難しいです。Strunk と White による" The Elements of Style " とプログラミングに関する最近の記事をチェックしてください。

約10分ごとに「これはばかですか?」と自問してください。正直に言ってください。こっちの方が難しいです。

-ジェイソン

于 2008-11-12T06:39:26.140 に答える
2

私は...制限値を (java)doc に文書化するのが好きです。(パラメータを空にすることはできますか? null にすることはできますか?)

そうすれば、自分のコードが使用されたとき (または自分のコードを使用したとき) に、何が期待できるかがわかります。シンプルな推奨事項ですが、実装されることはめったにありません ;)

そのドキュメントには、静的例外と実行時例外の明確な分離も含まれています。そうすれば、堅牢性を向上させるためにプログラムができるだけ早く失敗する必要がある場合、予測された例外 (静的であり、コーディング時にキャッチまたは再スローによって処理する必要がある) が原因で失敗するかどうかがわかります。これは、パラメーターが正しくないためです (ランタイム例外、アプリケーションの有効期間中にのみ検出されます)。

両方のタイプの例外が明確に文書化されている場合 (特に、パラメーターの値を制限する場合)、全体的な堅牢性を適用するのが簡単になります。

于 2008-11-12T06:48:58.320 に答える
2

パラノイアであることは、プログラマーのサバイバル特性です。どうすればこれが失敗するのか、常に自問自答してください。次に、その失敗を防ぐ方法を見つけようとします。

于 2008-11-12T20:48:40.887 に答える
2

可能な場合は、別の専門家の意見を聞きます。これにより、物事を破壊するまったく新しい方法が 1 つまたは複数明らかになることがよくあります。

于 2008-11-12T20:42:46.467 に答える
2

契約によるデザインをできるだけ使用するようにしています。しかし、私の仕事の分野ではほとんど実用的ではありません。

于 2008-11-12T06:04:58.050 に答える
2

私はローカル変数を初期化しないのが好きです。必要に応じて設定する必要があります。そうしないと、コードを読んでいるプログラマーが のように混乱する可能性があります"hmm why is this 0 at the beginning..."。初期化しない場合、まだ使用されていないことは明らかです。

于 2008-11-12T06:12:29.767 に答える
2

エラーを防止および回復するために、さまざまな方法を実装しています。

1) すべての例外を処理します。あなたが述べたように、「すべてのエラーを処理する」。ユーザーがフォームのボタンをクリックした場合、未処理の例外からアプリケーションが消えてしまう ("poof") 可能性はありません。そのため、一般的な try キャッチでイベント ハンドラーをラップします。

2) 完全なスタック トレースでエラーをログに記録します。例外を再スローするときは、常に新しい例外を作成し、キャッチされた例外を内部例外として追加します。私のロギング コードはメッセージを再帰的にアンラップします。

3) クラスを再利用可能にするかどうかを決定します。そうでない場合は、文書化します。IRestartableまたはのようなインターフェイスをコードに実装することを検討してくださいIReusable。それを実装していないオブジェクトは、一度使用したら破棄する必要があります。

4) スレッドセーフを仮定しないでください。私は、.NET が非常にマルチスレッド化されているという難しい方法を学びました。多くのイベントは任意のスレッドで処理されます。.NET で記述された特定のアプリは、多数の同時実行スレッドを持つことができ、1 行のコードで明示的にスレッドを作成することはできません。

5) 変数のスコープをできるだけ狭くします。メソッドの先頭にある大きなブロックではなく、使用される場所の近くでオブジェクトをインスタンス化します。オブジェクトの寿命が短くなる可能性があり、クラスまたはメソッドの上部にある巨大なブロックにある不要または再利用された変数を忘れることはありません。

5) シンプルですが、まだ起こっていることがわかります。ペストのようなグローバルを避けてください。何百もの未使用/再利用変数を含むコードを見てきました。把握してリファクタリングするのは面倒でした。

于 2008-11-12T06:21:54.427 に答える
1

私が(Cで)書いたシステムには、パフォーマンスと信頼性に関して高い要件があります。失敗のための設計は問題ありません。安全のための設計に関しては、より複雑になります。

ハードウェアは常に故障する可能性があり、それ以外に、外部からシステムに無効なデータが入るという問題があります。これらの分野での私の解決策は通常、手の込んだもの(安全のための設計)であり、他のすべての分野では、本質的に非常に単純なコードを持ち、データ検証をまったく行わないことで失敗するように設計されます。

ですから、リスクが小さいときは失敗し、リスクが高いときは安全になるように設計していると言えます。

デバッグのために、ゼロによる除算などを含む、決して入力してはならない条件付きコードを作成することがあります。これにより、処理がそこに入ると、デバッガーがすぐに呼び出されます。

コンパイラが初期化する必要がある変数と完全に省略できる変数を教えてくれるので、私は通常、ローカルスタック変数を初期化しません。

コードレビューは素晴らしいですが、絶対確実ではありません。私はかつて、小さな(無限)ループ(恥ずかしいですね)を数時間見て、インデックスがインクリメントされていないことを確認できませんでした。私の同僚もそれを見ませんでした。生成されたコードリストを最終的に見ると、ループテストが単一の無条件ジャンプに最適化されていることがわかり、それから初めて問題が何であるかがわかりました。

于 2011-03-17T10:17:02.420 に答える