プログラミングで最も厄介な7つの問題

古い地図の未知の領域には、「ここでドラゴンになってください」という不吉な警告が表示されることがよくあると言われています。恐らく外典であると考えられたのは、恐ろしい敵と戦う準備ができていなければ、世界のこれらの未知の隅に迷い込んだ人は誰もそうすべきではないということでした。これらの神秘的な地域では何かが起こる可能性があり、多くの場合、何かが良くなかった。

プログラマーは中世の騎士よりも少し文明的かもしれませんが、それは現代の技術の世界が予期しない場所で私たちを待っている技術的なドラゴンのシェアを持っていないという意味ではありません。締め切りが数分になるまで待つ難しい問題。マニュアルを読み、何が明確に指定されていないかを知っている合併症;多くの場合、コードがコミットされた直後に、バグやタイムリーでないグリッチを忍び込む方法を知っている邪悪なドラゴン。

コンピュータが完全に予測可能であるという素朴な自信に暖められ、真剣に正しい答えを出している夜に静かに休む人もいるでしょう。ああ、彼らはほとんど知らない。チップ設計者、言語開発者、そして世界中の何百万人ものプログラマーのすべてのハードワークのために、最も強力なプログラマーでさえもひざまずく可能性のあるプログラミング問題の厄介な茂みがまだあります。

これがプログラミングの世界で最も危険な7つのコーナーで、「ここでドラゴンになってください」という大きなマーカーを配置しました。

マルチスレッド

それは良い考えのように聞こえました:あなたのプログラムを独立したセクションに分割し、OSにそれらを別々の小さなプログラムのように実行させてください。プロセッサに4、6、8、またはそれ以上のコアがある場合は、すべてのコアを個別に使用して4、6、8、またはそれ以上のスレッドを持つことができるようにコードを記述してみませんか?

アイデアは機能します—パーツが実際に完全に分離していて、互いに何の関係もない場合。ただし、同じ変数にアクセスしたり、同じファイルにビットを書き込んだりする必要がある場合は、すべての賭けが無効になります。スレッドの1つが最初にデータにアクセスするため、どのスレッドになるかを予測することはできません。

したがって、マルチスレッドの混乱を整理するためのモニター、セマフォ、およびその他のツールを作成します。彼らが働くとき、彼らは働きます。それらは単に複雑さの別の層を追加し、変数にデータを格納する行為をもう少し考える必要のあるアイテムに変えます。

それらが機能しないとき、それは純粋な混乱です。データは意味がありません。列は合計されません。お金は、だまされたアカウントから消えます。それはメモリ内のすべてのビットです。そして、それのいずれかを特定しようとして頑張ってください。ほとんどの場合、開発者はデータ構造の大きなチャンクをロックダウンして、1つのスレッドだけがそれに触れることができるようにします。それは混乱を食い止めるかもしれませんが、同じデータで複数のスレッドが動作することの利点のほとんどを殺すことによってのみです。「シングルスレッド」プログラムとして書き直したほうがよいでしょう。

閉鎖

どこかで、誰かが関数をデータであるかのように渡すことが有用であると判断しました。これは単純なインスタンスではうまく機能しましたが、プログラマーは、関数が自分の外部に到達し、「自由変数」と呼ばれることが多い他のデータにアクセスしたときに問題が発生することに気付き始めました。どのバージョンが適切でしたか?関数呼び出しが開始されたときのデータでしたか?それとも、関数が実際に実行されたときでしたか?これは、間に長いギャップが存在する可能性があるJavaScriptにとって特に重要です。

このソリューションである「クロージャ」は、JavaScript(および現在はJavaとSwift)プログラマーにとって最大の頭痛の種の1つです。初心者や多くのベテランでさえ、何が閉鎖されているのか、そしていわゆる閉鎖の境界がどこにあるのかを理解することはできません。

名前は役に立ちません。最後の呼び出しをアナウンスするバーのようにアクセスが完全に閉鎖されるわけではありません。どちらかといえば、アクセスは開かれていますが、データと時間の連続体のワームホールを介してのみアクセスできます。これは、最終的にSFテレビ番組を生み出す奇妙なタイムシフトメカニズムです。しかし、それを「複雑なスタックアクセスメカニズム」または「データ制御ジャグリングシステム」と呼ぶのは長すぎるように思われるため、「クロージャ」で立ち往生しています。誰かが非自由変数にお金を払う必要があるかどうかについて私を始めさせないでください。

ビッグデータが大きすぎる

RAMがいっぱいになり始めると、すべてがうまくいかなくなります。消費者データの新しい統計分析を実行しているのか、退屈で古いスプレッドシートで作業しているのかは関係ありません。マシンのRAMがなくなると、いわゆる仮想メモリに変わり、超低速のハードディスクに流出します。完全にクラッシュしたり、仕事を終了したりするよりはましですが、男の子はすべてを遅くします。

問題は、ハードディスクがRAMより少なくとも20倍または30倍遅く、大衆市場のディスクドライブがしばしば遅いということです。他のプロセスもディスクからの書き込みまたは読み取りを試みている場合、ドライブは一度に1つのことしか実行できないため、すべてが劇的に悪化します。

仮想メモリをアクティブ化すると、ソフトウェアに関する他の隠れた問題が悪化します。スレッドの不具合がある場合、ハードディスクの仮想メモリに突き出ているスレッドの実行速度が他のスレッドよりも非常に遅いため、スレッドの不具合がはるかに速く発生し始めます。ただし、ウォールフラワースレッドがメモリにスワップされ、他のスレッドがハングアップするため、これは短時間しか続きません。コードが完璧な場合、結果ははるかに遅くなります。そうでない場合、欠陥はすぐにそれを災害に陥らせます。これは1つの小さな例です。

これを管理することは、大量のデータを扱うプログラマーにとって真の課題です。無駄なデータ構造の構築に少しだらしなくなった人は誰でも、本番環境でのクロールが遅くなるコードになってしまいます。いくつかのテストケースでは問題なく動作する可能性がありますが、実際の負荷によってスパイラルが失敗します。

NP完全

コンピュータサイエンスの大学教育を受けている人なら誰でも、めったに綴られない頭字語に包まれた不思議な問題を知っています。非決定論的多項式完全、別名NP完全です。詳細を学ぶのに学期全体がかかることがよくありますが、それでも、多くのCS学生は、これらの問題は難しすぎるため誰も解決できないという霧の概念を持っています。

NP完全問題は、単純に力ずくで攻撃した場合、非常に難しいことがよくあります。たとえば、「巡回セールスマン問題」は、販売ルートに含まれる都市が増えるにつれて、指数関数的に長い時間がかかる可能性があります。ある値Nに最も近い数のサブセットを見つけることによって「ナップサック問題」を解決することは、非常に大きな数であるすべての可能なサブセットを試すことによって解決されます。これらの問題は、シリコンバレーで最大のブギーマンの一人、つまり拡張できないアルゴリズムの完璧な例であるため、誰もがこれらの問題を恐れて走っています。

トリッキーな部分は、いくつかのNP完全問題は近似で簡単に解けるということです。アルゴリズムは正確な解決策を約束するものではありませんが、かなり近いものです。彼らは巡回セールスマンにとって完璧なルートを見つけられないかもしれませんが、正解の数パーセント以内に入ることができます。

これらのかなり良い解決策の存在は、ドラゴンをより神秘的にするだけです。あなたがちょうど十分に良い答えによって満足することをいとわないならば、問題が本当に難しいか、または十分に簡単であるかどうか誰も確信することができません。

セキュリティ

「既知の既知のものがあります。ブッシュ政権の第二次国防長官であるドナルド・ラムズフェルドはかつて記者会見で語った。「私たちはまた、既知の未知のものがあることも知っています。つまり、私たちが知らないことがいくつかあることを私たちは知っています。しかし、未知の未知のものもあります。私たちが知らないもの、私たちが知らないものです。」

ラムズフェルドはイラク戦争について話していましたが、コンピューターのセキュリティについても同じことが言えます。最大の問題は、私たちが知らない穴が可能であるということです。パスワードを推測しにくくする必要があることは誰もが理解しています。これは既知のことです。しかし、ネットワークハードウェアに独自のソフトウェア層が埋め込まれていると誰が言われたことがありますか?誰かがあなたのOSのハッキングをスキップし、代わりにこの秘密の層を標的にする可能性は不明です。

そのようなハッキングの可能性は今のところあなたには知られていないかもしれませんが、他にあるとしたらどうでしょうか?存在すら知らない穴を固めることができれば、私たちには手がかりがありません。パスワードを打ち消すことはできますが、想像もできないような亀裂があります。それは、コンピュータセキュリティを扱うことの面白さです。そしてプログラミングに関しては、セキュリティ志向の考え方がますます重要になっています。あなたはあなたの混乱をきれいにするためにそれをセキュリティの専門家に任せることはできません。

暗号化

法執行官が議会の前に出て、それを止めるために公式の抜け穴を要求するとき、暗号化は強力で侵入できないように聞こえます。問題は、ほとんどの暗号化が不確実性の霧の雲の上に構築されていることです。本当に大きな数を因数分解したり、離散対数を計算したりするのが難しいなど、不確実な仮定に基づいて私たちが持っている数学的証明は何ですか。

それらの問題は本当に難しいですか?それらを破るためのアルゴリズムを公に説明した人は誰もいませんが、それは解決策が存在しないという意味ではありません。すべての会話を盗聴して銀行に侵入する方法を見つけたら、すぐに世界に知らせて、彼らが穴を塞ぐのを手伝ってくれませんか?それとも黙っていますか?

本当の課題は、独自のコードで暗号化を使用することです。基本的なアルゴリズムが安全であると確信している場合でも、パスワード、キー、および接続を調整するために行うべき作業はたくさんあります。1つの間違いを犯してパスワードを保護しないままにすると、すべてが開いたままになります。

ID管理

「インターネットでは、あなたが犬だと誰も知らない」というオチのあるニューヨーカーの漫画は誰もが大好きです。4つの精巧なセクションがある独自のウィキペディアページもあります。(インターネットでは、ユーモアの分析とカエルの解剖についての古い見方を誰も知りません。)

良いニュースは、匿名性が解放され、役立つ可能性があるということです。悪いニュースは、匿名のコミュニケーション以外の方法がわからないことです。一部のプログラマーは「2要素認証」について話しますが、賢いプログラマーは「N要素認証」にジャンプします。

パスワードと携帯電話へのテキストメッセージの後で、私たちは非常に安定したものをあまり持っていません。指紋リーダーは印象的ですが、多くの人がハッキングの方法を明かそうとしているようです(初心者については、ここ、ここ、およびここを参照してください)。

SnapchatやRedditでのアイドルチャタリングの世界では、これはそれほど重要ではありませんが、ハッキングされたFacebookページのストリームは少し当惑しています。財産、お金、ヘルスケア、または意味のない小さな話を除いて人生の他のほとんどすべてのような深刻な問題を処理する簡単な方法はありません。ビットコインのファンボアは、ブロックチェーンがどれほど堅固であるかについて悩むのが大好きですが、どういうわけかコインは剥ぎ取られ続けています(こことここを参照)。アイデンティティを処理する実際の方法はありません。

硬度の測定

もちろん、プログラミングに関しては、問題の難易度を測定する方法さえありますか?誰も本当に知りません。いくつかの問題は簡単に解決できることを私たちは知っていますが、それを難し​​いと認定することはまったく異なります。NP完全性は、アルゴリズムとデータ分析の複雑さを体系化するための精巧な試みの一部にすぎません。理論は役に立ちますが、保証はできません。問題が難しいかどうかさえ知るのは難しいと言いたくなりますが、まあ、あなたは冗談を言います。

関連記事

  • ダウンロード:開発者のキャリア開発ガイド
  • 遅延プログラミングの力
  • うまくいく7つの悪いプログラミングのアイデア
  • 私たちが密かに愛している9つの悪いプログラミング習慣
  • 21のホットなプログラミングトレンドと21のコールド
  • ダウンロード:プロのプログラマーのビジネスサバイバルガイド
  • ダウンロード:独立した開発者として成功するための29のヒント
  • 私たちが嫌う7つのプログラミング言語
  • プログラミングの5つの時代を超越したレッスン「灰色のひげ」
  • 開発者が聞きたくない22の侮辱
  • プログラミングの未来のための9つの予測
  • 今習得する必要のある13の開発者スキル
  • 世界をプログラムする:あなたが今知る必要がある12の技術
  • 1文字のプログラミング言語の攻撃