ソフトウェアのバグ?これらの10の高価なプログラミングミスを避ける

なぜプログラムは失敗するのですか? Ada Lovelaceが19世紀に普遍的な計算の可能性を見出して以来、私たちのソフトウェアにはまだバグがあります。長年にわたり、成功したコードを保証するための洗練された方法を開発したにもかかわらず、プログラムは依然として破綻しています。

しかし、なぜ?

その答えはいくつかの実践的な方向性の中で取ることができますが、私たちは実践的な答えを提供することに決めました。プログラマーは間違いを犯す。時には邪魔になることもあります。常に最高のツールやベストプラクティスを使用するとは限りません。

ビジネスエグゼクティブは、ますます大きくて長いプロジェクトに集中することなく、変化と革新を推進するための、より持続可能な、より短い努力に集中しているIT環境にますます移行しています。ここに長所と短所、そしてそれを実現させる方法があります。

私は、UC Berkeleyの拡張機能でオブジェクト指向プログラミングを教えています。そこでは、学生がコード自体を理解する手助けをしているのと同じくらい良いプログラミング練習を教える時間を多く(またはそれ以上)費やしています。私の授業ではよくある間違いが多く見られますが、私はこのコラムであなたと共有しています。

私はノースウェスタン工科大学の工学部のJames A. Connor教授に連絡を取り、生徒の間違いを共有するように頼んだ。

私は最初に行くし、ジムの洞察をあなたと共有します。

間違い#1:コメントの練習が悪い

コメントは、コンピュータが実行しないプログラム内のテキストの要素です。プログラマーがノートとして書き、コード内で何が起こっているのかを説明します。

私の生徒の多くは、自分のコードにコメントすることを避け、実際にいくつかのノートを書くために時間を費やす理由を理解していません。私の最も実践的な例は自分の人生から来ています。

私は世紀のターンの前に、初期のコンテンツ管理システムの1つであるZENPRESSのバージョン1.0を書きました。私はそれが数年間記事を配信することを期待していました。 14年後、まだ記事を摂取しており、約75,000件の記事を準備し、26億ページを摂取していました。

最終的には、実行していたプラットフォームが廃止されました。私はコードに戻って潜んでいなければならなかった。 2009年に、私はそれを元のプラットフォームから現代のプラットフォームに移植しました。私は最近、PHPの主要言語機能がバージョンアップで消えてしまったので、もう一度変更しなければなりませんでした。

19年後にすべてのコードがどのように機能したかを覚えておく方法はありませんが、コードをよくコメントしたので、私はロードマップの何かを持っていました。コードを見たり、コードに埋め込まれたノートを見たり、修正を加えたりできました。

コメントは、チームで作業しているとき、またはソフトウェアがあなたのスチュワードシップを超えて生きるときにも重要です。あなたは自分のキャリアを進んでいくことができ、他の人があなたのコードを理解して理解する必要があるかもしれません。コメントは役に立ちます。

間違い#2:変数名の誤り

言語を使ってコードを理解できるようにするテーマを続けていきます。これを例を使って説明します。ガロンあたり20マイル、100マイル走行する車に乗っているとします。あなたはどれくらいのガスを使用しましたか?

クラウドコンピューティングは1度に1つのAPIを成長させ、開発者はApigeeを6億2500万ドルで買収し、ハードウェアはラスベリーパイが1000万回の売上を上げ、プレミアムバンドルで賞賛し、セキュリティは4年間後にNPAPI FlashをLinux用に復活させるスタシス

これは簡単な例ですが、私たちの目的のために動作します。線a = b / cに遭遇したとしましょう。どういう意味ですか? bとcは何ですか?コードの残りの部分とはどのように関連していますか?あなたがルーチンを書いてから10分後に、あなたは忘れるでしょう。他の誰かが来て、修正を加えたり更新を書かなければならないかどうか気にしないでください。

次にこの表現を見てみましょう:gallons = miles / mpg。それぞれの変数が何を意味するのかはすぐに分かります。 1つはガロンを表し、1つはマイルを表し、1つは1ガロンあたりのマイルを表す。それは明らかだ。

変数を明確にすること、英語の名前(またはあなたの母国語が何であれ)とコメントの関係について考えてみてください。コードの塊を継承し、a = b / cと見てみましょう。それは何をするためのものか?あなたは何か考えていますか?

変数の名前は、その機能を表すようにしてください。あなたは多くの時間を節約し、多くの頭痛を軽減します。

特殊機能

間違い#3:ノートなし

私はZENPRESSを1997年中頃に書き始めました。それは1998年1月に生きていました。悲しいことに、私はプロジェクトを終えるのに急いでいました。最初のリリースではノートを書く時間がかかりませんでした。私は何度もそれを後悔しています。 1999年6月からバージョン2を開始したとき、私は定期的な実験ノートを保管していました。

ラボノートは、コード内のコメントを超えるレコードです。科学者は、開発プロセスのジャーナルまたはダイアログとして常にラボノートを使用します。研究ノートは、科学的発見の所有権を証明するために使用されてきました。なぜなら、調査のプロセスは、科学者が進歩を記録するために使用する日誌にしばしば記録されているからです。

ノートは、プログラマーにとっても強力なツールです。 ZENPRESSの最後のラボノートは今年3月に書かれました.ZATZアーカイブをあるホスティングプロバイダから別のホスティングプロバイダに移動しなければならなかったときです。私は他のプロジェクトについても定期的に実験ノートを保管しています。私はメモに戻って何度も救われました。

特殊機能

すでに実験ノートを保管していない場合は、今すぐ開始してください。あなたが行った変更、あなたの推論、考慮したもの、捨てたもの、有用なリソースへの言及、将来を助けるものを書き留めてください。また、将来の同僚や交換を手助けすることになります。また、所有権を証明する必要がある場合は裁判官にも相談してください。

間違い#4:人間言語で書かない

私の生徒は、クラスを通過するようにプログラムするだけではありません。また、特定のコーディングの概念を理解していることを示すディスカッション掲示板を書く必要があります。

これには2つの理由が必要です。最初に、もちろん、概念の理解の実証です。しかし、もっと重要なことは、すべての専門家が書くことができる必要があることです。

要約

私は学生からこれに多くのプッシュバックを得る。少なくとも2つの学期ごとに、「私はライターではなくプログラマーになりたい」と叫ぶ。しかし、プログラミング、エンジニアリング、IT(ほぼすべての専門的な努力)は、真空中に存在しません。

概念を説明したり、アイディアを投げたり、資金を調達したり、説明を求めたり、提案を準備したり、より良い成績を挙げて論じるために書く必要があります。オープンソースのプロジェクト参加者は、非常に拡張されたチームの同僚として働き、彼らが同期して居ることができる唯一の方法は、明確かつ分かりやすいメッセージを書くことです。

結論は簡単です:プロフェッショナルな仕事や重要なことをしたい場合は、プログラミング言語だけでなく、英語のような人間の言語で書く必要があります。

間違い#5:コードフォーマットが間違っている

疑いの余地がないように、ここにテーマがあります:コードを理解できるようにする。コードのメンテナンスには非常に時間とコストがかかります。率直に言って、それほど楽しいことではありません。あなた(またはコードを継承した人)が何をしようとしているかを把握しようと、古いコードを掘り下げて何週間も費やすよりも、生産的な時間を追加することができる方がずっと優れています。

私はこれを私の古いコードだけでなく、私が継承したコードから個人的に経験しました。私は、放棄されたWordPressオープンソースプラグインをサイドプロジェクトとして採用します。私が知る限り、私は他の誰よりも多くを採用しています(そして今週のWordCampで話題になっています)。それぞれのプラグインは他の誰かによって開発されたもので、それを動作させるために、私は見知らぬ人のコードを掘り下げなければなりませんでした。

幸いにも、これらの開発者はプログラミング芸術の優れた実践者でした。もしそうでなければ、私はこれらのプロジェクトに参加していないでしょう。しかし、それでもスピードアップするのは難しいことです。彼らのコードが構造化されていないとどれくらい難しいのか想像できますか?

構造化では、コードの配置方法を意味します。私は学生のためにこれについてビデオをしました。 YouTubeでご覧になれます。

オンラインで読んだ記事を考えてみてください。いくつかは、各段落の間に1行の書式が整えられており、すべてが一貫しています。しかし、一部の記事では、すべてが1つの大きな塊に整理されており、読むことは不可能です。

すべてのプログラマー(またはプロジェクト)はプログラミングスタイルを持つ傾向があります。一貫している限り、あなたのスタイルはそれほど重要ではありません。あなたはコード形式のヘルプがあなたを導くようにする必要があります。

たとえば、私のコードでは、セクション間に空白行が複数あることは決してありません。もっと大きな空白が見える場合は、すぐに何かがそうでないという事実に直面しています。その領域にバグがあるかもしれません。

コードを進めていくうちに、組織にコーディングスタイルがあるかどうかを調べます。すべてのプログラマーにコーディングスタイルを定義し、明確で保守性の高いものに固執することを検討してください。

間違い#6:間違ったエラーチェック

ある有名な将軍は、計画は敵との出会いから生き残ることは決してないと言った。私のバリエーションは、あなたのコードがユーザーに遭遇したときに決して生き残ることができないということです。ユーザーがコードをどのように使用するかを知っているとは思いますが、これについては信頼してください。

ユーザーはコードを壊します。

これを適切に処理する方法は、テストとエラーチェックです。エラーチェックは、コード内のすべての操作の結果をチェックする方法です。それが期待どおりのものか、コードが予期しない結果を処理できることを確認してください。

例えば、私の生徒は、ファイルを読むことを含む課題を持っています。それらのほとんどすべてがファイル読み込みルーチンを呼び出してコードを書きます。ユーザーがダイアログボックスをキャンセルしたかどうかを確認しますが、ファイルが実際に読み込まれているか、何らかの種類のシステムエラーがあるかどうかを確認することはめったにありません。ファイルを書き込もうとすると悪いです。実際にファイルが保存されているかどうかを確認することはほとんどありません。おっとっと。

これがどうやって悪いのか分かります。それに対抗するには、行動を絶対的に予測できるかどうかを考える必要があります。あなたはテストする必要があります。テストはコードを自分で実行することを意味するだけではありません。テストとは、予測できない動作をする可能性がある実際のユーザーにコードを実行させることです。

無限に有益な情報があります。

間違い#7:実際のデバッガの代わりにprintステートメントを使う

私は長年にわたり、異なる言語のプログラマーが異なる文化を持つ傾向があることを発見しました。大部分は、異なる種類のソリューションを構築し、さまざまなツールを使用しているからです。

その1つの例は、私のC#プログラミングの学生と私のプロジェクトのいくつかで動作するオープンソースのPHP開発者の違いです。シンボリックデバッガを使用せずに自分のコードをデバッグすることを考えるC#プログラマーはほとんどいません。これは、C#がコーディング環境としてVisual Studioを使用してネイティブにプログラミングされており、デバッガが組み込まれているからです。

これとは対照的に、echo文を削除すると思っているPHP開発者や、var_dumpがコードをデバッグするのに役立つような終わりのないPHP開発者のストリームを見てきました。これは、ほとんどのPHPプログラマが開発環境ではなくエディタでプログラミングする傾向があるためです。 2つの大きな違いはデバッガです。

では、デバッガとは何ですか?簡単に言えば、実行時にコードを見ることができるツールです。あなたのコードには、X線、超音波、またはMRIと考えることができます。特定の時点で停止して、すべての変数の状態を調べるようにデバッガに指示できます。特定の条件で停止するようにデバッガに指示することができます。値を変更することができます。値を見ることができます(ただし、プロファイリングは別のツールになることもあります)。

生産性の差は相当なものになります。作業をより迅速かつ正確に行うためには、実際のシンボリックデバッガを使用してください。

それで、私のヒントと観測のセクションは終わり、私はJames Connor教授に床を向けるつもりです。

間違い#8:魔法の数字を使う

多くのプログラマーは、一度コードを作成しなければならないと考えており、完璧なものになるでしょう。しかし、エンタープライズソフトウェアや産業用ソフトウェアの長期ライフサイクルコストを最適化するには、変化する条件に耐えるコードを記述する必要があります。

これの古典的な例の1つは、マジックナンバーの考え方です。魔法では、プログラマーが時間のテストで常に生き残ると思う数字を意味します。

たとえば、顧客の購入金額に基づく手数料の計算を行います。執筆時点では、手数料の割合は3%、つまり0.03となる可能性があります。

さて、このコードの書き方を想像してみましょう:手数料= .03 *販売。この文脈では、マジックナンバーは0.03です。プログラマーはこれが永遠に魔法のように有効であると考えているので、0.03の数字をコードにハードコードします。

それはすべてうまくいいですが、手数料は毎年変わる傾向があります。手数料が翌年に半分になって0.035になると、何千行ものコードで手数料を払うのは非常に難しいでしょう。

マジックナンバーを使用するのではなく、変数や定数を1か所に定義し、それらの変数をコードに使用させます。 commission_rateを事前定義すると、commission = commission_rate * saleのようなコードは変更する必要がありません。

考慮すべきもう一つのことは、あなたが魔法の数字を見つけるたびに、ユーザに公開したいオプションを特定しているかもしれないということです。

間違い#9:厄介な日時

ここに厳しい質問があります:1年に何日ありますか? 365は通常の答えかもしれませんが、今年は366となっています。年間365.25日ありますか?いいえ、ありません。

しかし、私の生徒の中には、うるう年が4年に一度来るので、平均して365.25日が毎年であると決定しました。日付計算を行うとき、彼らはこの平均を使用し、その結果、何も正しいことはありません。

あなたが計算している日付は西洋の暦の日付でないかもしれないので、しばしばシステムライブラリを使って日付を計算する方が良いでしょう。

時間と同様の問題を見てみましょう。数年ごとに、地球が減速するにつれて、通常6月30日か12月31日のいずれかに1日に余分な秒が追加されます。これはうるう秒と呼ばれ、11:59から時計を使うことは可能です: 59〜11:59:60〜12:00:00です。

ここでもう一度挑戦します。サマータイムが使用されている場所では、トランザクションの順序が乱れる可能性があります。たとえば、トランザクションAが最初に配置されますが、時間は1時間後にリセットされ、トランザクションBが配置されます。しかし、あなたが時間の順序付けに関して怠け者ならば、トランザクションBが最初に起こったことが記録されます。このタイプのタイム・エラーは、金銭的な違約金が間違って発生し、あらゆる方法で他の混乱を引き起こす可能性があります。

もう一度、これらの時間の問題の両方に対応するための多くの優れた言語とシステムライブラリが用意されています。独自の時間計算をコード化するよりも、既存のライブラリを使用するほうがよい場合がよくあります。

間違い#10正しいデータ構造を選んでいない

データ構造は、プログラム内のデータを表現するためのメカニズムです。あなたの多くは、リンクされたリスト、ツリー、配列のような用語を聞いてきました。これらのそれぞれは、表現しようとしているアーキテクチャの構造に対応する論理的なデータ表現です。

プログラマーが経験する最も一般的な間違いの1つ(経験豊富なコーダーと初心者の両方)は、データ構造の選択にあまり注意を払っていません。ほとんどすべてのコードは、データ表現方法の選択に基づいて構築されるため、間違ったデータ構造を選択すると、コストがかかることがあります。

このような設計エラーを示す例として、循環キューの代わりに単純なスタックまたはキューを選択する例があります。スタックを複数の料理の皿と考えてください。一番下の料理を、次にもう一枚を上に、そして別の料理を上に置きます。

物事のインターネットは深刻な新たなセキュリティリスクを作り出しています。可能性と危険性を調べます。

ディッシュを取り除きたい場合は、スタックの上部から取り出します。これはラスト・イン・ファースト・アウトと呼ばれます。問題は、スタック内の古いものを削除する必要がある場合は、面倒です。スタックに10個の料理があるとしましょう。最初のものにするには、最初に他のものをすべて削除する必要があります。

今、キューを考えてみましょう。あなたが銀行に並んでいるとき、あなたは待っています。最初の人は最初の人です。最初の人にサービスが提供されるとすぐに、次の人が起きていて、その人にサービスが提供されます。もう1つのことは、一人一人が一歩前進してキューに入っていくことです。

あまりにも多くの人々が現れたらどうなりますか?彼らは離れているか、またはラインが出て行く。そして、最初の人が呼ばれたとき、これらの人々はすべて移動しなければなりません。

大量のデータがある場合、この種のキューは非常に非効率的です。データがキューの先頭から引き出されるたびに、すべてのデータを移動する必要があります。私たちは大規模なデータの世界に入り、システムを通じてデータの流れが一定しています。

この場合、循環キューを実装するほうがよいでしょう。この場合、データは決して移動しません。代わりに、ポインタはキューの先頭と末尾を指すように設定され、内部的にキューはラップアラウンドし、データは1行ではなくリング内で整理されます。データ要素を使用してリングから削除すると、リング内のすべてのデータを移動する必要はありません。起こっているのは、最初の要素ポインタがリング内の新しい要素を指し示すことだけです。

これは、正しいデータ構造の選択がコードの効率と有効性にどのように大きな影響を及ぼすかについての多くの例の1つです。

ここにデビッド。彼の洞察力の一部を分かち合い、Connor教授に大きな感謝の言葉をお送りしたいと思います。うまくいけば、私のヒントと彼の間で、あなたはより効率的かつ効果的なプログラマーになり、これらの重大な間違いのいくつかを避けるでしょう。

ところで、私はこれまで以上にTwitterやFacebookのアップデートをしています。 @DavidGewirtzのTwitter、Facebook.com/DavidGewirtzのFacebookで私をフォローしてください。

クラウドコンピューティングの成長

GoogleがApigeeを6億2,500万ドルで買収

ラズベリーパイは1000万回の売り上げを記録し、「プレミアム」バンドルで賞賛します

アドビは、4年間の停滞後、NPAPI Flash for Linuxを再編