web-dev-qa-db-ja.com

コンピュータサイエンス、プログラミング、抽象化の理解に役立つ

今まで、私は常に、内部で何が起こっているのか、そしてコンピューターが実際にどのように機能しているのかを理解するために、低レベルのもの(Cなど)を実行させるプログラミング言語を学ぶべきだと常に信じていました。 この質問この質問 および この質問からの回答 はその信念を強化しました:

抽象化された言語でプログラミングをすればするほど、そもそもコンピューターに夢中になってしまったこと、つまりコンピューターをざっと見て、何がひっくり返るのかを見逃すことが多くなります。アセンブラーとCは、ポーキングに非常に適しています。

結局のところ、すべてが魔法であると仮定するのではなく、何が起こっているのかを知ることができるので、あなたはこれを知っているより優れたプログラマーになるだろうと思いました。そして、低レベルのものを知る/書くことは、ビジネスプログラムを書くことよりもはるかに興味深いと思います。

しかし、1か月前、この本に出くわしました コンピュータプログラムの構造と解釈 。 Webのすべては、これが最高のコンピューターサイエンスの本の1つであることを示唆しており、それを読むとプログラマーとしてより上手になります。

コンセプトを本当に楽しんでいます。しかし、この本では、抽象化がコンピュータサイエンスの最高のコンセプトであるように見えますが、低レベルの部分については1つの章しか費やしていません。

私の目標は、より優れたプログラマーになること、コンピューターサイエンスをより深く理解することであり、これは私を本当に混乱させました。主に、すべての抽象化を避けて、非常に低いレベルで実際に何が起こっているのかを観察するべきではありませんか?抽象化が優れている理由を私は知っていますが、それがコンピュータの動作を学ぶことを妨げていないのですか?

31
morbidCode

いいえ、抽象化によって物事の仕組みを理解することができます。抽象化により、なぜ(何のために)物事が機能するのかを理解できます。

まず、1つはっきりさせておきましょう。これまでにわかったことのほとんどすべてが抽象化のレベルにあります。 Javaは抽象化、C++は抽象化、Cは抽象化、x86は抽象化、1と0は抽象化、デジタル回路は抽象化、集積回路は抽象化、アンプは抽象化、トランジスタは抽象化、回路は抽象化、半導体は抽象化、原子は抽象化、電子バンドは抽象化、電子は抽象化です(そして私たちが知っている限り、それはずっと下の抽象化である可能性があります)。何かが実際にどのように機能するかを理解するために低レベルの知識が必要であるという論理、コンピュータが実際にどのように機能するかを理解したい場合は、物理学、次に電気工学、次にコンピュータ工学、そしてコンピュータ科学を研究し、基本的には次の段階に進む必要があります抽象化の条件。(私はそれについて言及しない自由を取っています あなたも最初に数学を勉強する必要があります 、物理学を本当に理解するために。)

現実的には、最下位レベルの詳細から作成してコンピューターとプログラミングを理解できる日は、コンピューターの最も初期の日でした。今では、この分野はあまりにも進歩しており、一人でそれをゼロから再発見することはおそらく不可能になっています。抽象化のすべてのレベルに特化した数十万人の非常に有能な人々がいて、特定の部分を徹底的に研究し、そこで最新の進歩に追いつくことに何年も費やすことなく理解できないと期待できない進歩を毎日頑張っています。

これを検討してくださいJava snippet:

public void Example() { 
    Object obj = new String("...");
    // ...
}

Java言語のレベルで、このスニペットが約束すること(および約束しないこと)を簡単に理解できます。ただし、スタックフレームなどのトピックに精通していなければ、ヒープデータ構造、同時生成トレースガベージコレクション、メモリ圧縮、静的分析、エスケープ分析、仮想マシン、動的分析、アセンブリ言語、実行可能スペースの保護など、実際に関係するすべての低レベルの詳細を本当に知っていると思った場合、誤りです実際のコンピューターで実行します。

または、次のCコードを検討してください。

void example(int i) {
    int j;
    if(i == 0) {
        j = i * 2;
        printf("Received zero, printing %d", j);
    } else {
        printf("Received non-zero, printing %d", j);
    }
}

初心者にそれを示すと、「変数は実際には舞台裏の単なるメモリアドレスである」ため、引数がゼロ以外の場合、メモリの場所の残りの内容が出力されることがわかります。それらを初期化しないのは、単にそれらのアドレスに何も移動しないことを意味します」、「それらに魔法はありません」。初心者以外にそれを示すと、このプログラムの動作はこの関数のパラメーターのゼロ以外の値に対して未定義であり、コンパイラーは条件を削除し、この関数へのすべての引数をゼロとして扱い、すべてを置き換える可能性があることを通知します引数としてゼロを渡す呼び出しのある関数の呼び出しスポットの、この関数の引数として渡されるすべての変数をゼロに設定する、または 他の矛盾したように見える を実行します。

常に抽象化のレベルで作業していることを認識することが重要です。この例の初心者は、彼/彼女が知っているすべてを考慮に入れ、完全に間違った答えにエレガントに到着しました。なぜなら、(a)彼/彼女は言語の仕様を読んでいなかった(これは抽象化です )意図的に、Cプログラマーはコンピューターアーキテクチャを理解するのに十分なほど賢くないわけではありません)および(b)完全に把握しておらず、進化した実装の詳細について推論しようとした今では彼/彼女のメンタルモデルをはるかに超えています。この例は架空のものですが、日常の現実世界の誤解-時には危険なバグや、場合によっては有名なセキュリティホールにつながるようなもの-を利用しています。

全体像を見ることも重要です。たとえば、より高い抽象化を十分に理解していない場合、Cには構造体、同じサイズの構造体ポインタ、不完全な型宣言と関数ポインタがあることがわかり、それらを関連のない機能の束として見る可能性があります。時々役立つかもしれません。しかし、OOPのようなより高度な抽象概念を十分に理解していれば、前述の機能はOOP概念の構成要素として認識されます。構造体には他の構造体を含めることができます。 (コードの再利用)、データポインターは何かを参照として(クラスのように)渡すことができます。これらのポインターが同じサイズであるという事実により、それらを置換(サブタイピング)できます。不完全な型宣言により、構造体への不透明なポインター(プライベートメンバー)を使用できます)と関数ポインタを使用すると、ディスパッチテーブルを作成できます(ポリモーフィズム)。

この架空の例では、OOP言語の知識により、Cを理解できなくなっただけでなく、実際にCに引き継ぐことができる概念がわかりました。これらの概念は選択的に適用できます。言語が積極的にプッシュしない場合でも、コードを管理しやすくするためにそれらを必要とする場合(OOPとFPの間にも同様の関係があると私は主張しますが、夢中にならないでください。)

私が出会った最高のプログラマーの一部は、抽象化を理解していて、知識をあらゆる言語に引き継いで、解決する必要のあるあらゆる問題に、それがたまたま働いているあらゆるレベルに適応できるので、彼らの在り方です。私が出会った最悪のプログラマーの一部は、彼らが実際に理解していない、または多くの場合正確に最新ではない、または関連性のない詳細および雑学に集中することを主張するので、彼らがそうである方法です問題、または彼らがそれらを使用しようとする状況で適用できる、またはそもそも真実ではなかった。

あなたが理解する必要があるのは、特定の時点で単一レベルの抽象化は存在せず、人は特定の瞬間に単一レベルの抽象化に限定されないことです。 1つを理解してから、次のステップに進むことができます。あなたは1つを採用し、次に別のものに切り替えることができます-いつでも好きなときに。

結局のところ、すべてが魔法であると想定するのではなく、何が起こっているのかを知ることができるので、これを知っているより優れたプログラマーになると思いました。

これらは矛盾するものではありません。道路を舗装する方法はわかりませんが、それは魔法ではないことを知っています。

しかし、1か月前に、「コンピュータプログラムの構造と解釈」と呼ばれるこの本に出会いました。Webのあらゆるものは、これが最高のコンピュータサイエンスの本の1つであり、それを読むとプログラマとしてより上手になると示唆しています。

はい、そうです。

主に、すべての抽象化を避けて、非常に低いレベルで実際に何が起こっているのかを観察するべきではありませんか?

1回か2回かもしれませんが、毎回そうすることはあなたが良いプログラマーになるのを妨げます。電子が魔法ではないことを知るために、電子がゲートを流れるのを見る必要はありません。それが魔法ではないことを知るために、CPUがそれらの電子を数値のビットごとの表現に変換するのを見る必要はありません。あなたはそれらが魔法ではないことを知るためにそれらのビットが行き渡るのを見る必要はありません。これらの文字を並べて配置するだけで、数十の抽象化が必要になります。おそらく数百人で、それらをSEのサーバーからコンピューターに取得するためです。

Nobodyはそれらのすべてを知っています-詳細ではありません。

これは、プログラミングの初心者にとってveryよくある問題です。彼らは物事がどのように機能するか知りたいです。低レベルが最高のレベルだと彼らは考えています。なぜなら、それが彼らに最大のパワー、またはコントロール、または知識を与えるからです。ありません。

ええ、あなたはそれを魔法として扱うことはできません。しかし、実際にそのことを知る必要はありません。文字列を手動で連結することは興味深いことではありません。独自の並べ替えアルゴリズムをロールするのは面白くありません。何十年も前にはるかに優れたプログラマーが書いたものを使用することで、どのプログラマーも数桁短い時間で同じ結果を得ることができるからです。

40
Telastyn

抽象化が優れている理由を私は知っていますが、それがコンピュータの動作を学ぶことを妨げていないのですか?

確かに違います。職場での抽象化を理解したい場合は、それらの抽象化を研究してください。実際の物理的なコンピューターの低レベルの技術的詳細を理解したい場合は、それらの詳細を調べてください。 両方を理解したい場合は、両方を勉強してください。 (私の意見では、優れたプログラマーがそうするでしょう。)

一度に1つの抽象化レベルしか理解できない(または、さらに悪いことに、一度に1つの抽象化レベル存在するのようにしか理解できない)かのように、誤った二分法に悩まされているようです。それはむしろ、物理学と数学の両方を理解することは基本的に不可能であると示唆しているようなものです。

良いスタートは、コンピュータサイエンスとプログラミングの違いを発見することです。

プログラミングの主要なスキルは、抽象化のmultipleレベルで同時に考えることです。もう1つの重要なスキルは、抽象化を構築することです。このスキルは以前のものを使用します。低レベルのプログラミングは、これらの両方のスキルを行使して拡張するため、一部には価値があります。

SICPは、インタープリター、マシンモデルのシミュレーター、およびそのマシンモデルのコンパイラーをモデル化および実装します(その出力はシミュレーターで実行できます)。マシンモデルは非常に単純ですが、x86_64よりも本質的に低レベルではありません。率直に言って、かなりの量の低レベルプログラミングが、ビジネスロジックの恣意的なルールに劣らない、恣意的で難解なハードウェア/ファームウェアインターフェイスを処理しています。

16

抽象化が優れている理由を私は知っていますが、それがコンピュータの動作を学ぶことを妨げていないのですか?何か不足していますか?

マジックショーに行けば楽しまれますが、トリックの仕組みがわかりません。魔法に関する本を読んで、トリックがどのように機能するかを学びますが、あなたはまだ面白くないでしょう。

両方してください。頑張って。そして、あなたは両方かもしれません。

私は、SOLID、bash、UMLの高レベルで働いてきました。私は低レベルのTASM、算術論理演算ユニット、アナログ回路で働いてきました。私はあなたに言うことができます、あなたから離れて抽象化されたいくつかの魔法がないというあなたが働くことができるレベルはありません。

重要なのは、抽象化のすべてのレベルを一度に理解することではないことは確かです。あるレベルを正しく理解するために十分理解し、別のレベルに移動する時期を知るのに十分です。

十分に進歩した技術は、魔法と区別がつきません。

アーサーCクラーク

5
candied_orange

ソフトウェアエンジニアリングには複数の詳細レベルがあります。あなたの質問は「最もやりがいがあり、価値があり、興味深いレベルは何ですか?」です。

それはあなたの仕事やあなたがなりたいもの、あなたが何に関心があるかに依存します。大規模なシステムでは、ビットシフトやクロックサイクルについてあまり気にする必要はありません。単純なマイクロコントローラーで実行される組み込みソフトウェアの場合、使用するメモリの量に注意する必要があり、いくつかのプリミティブタイミングルーチンを作成する必要がある場合があります。

高い抽象化レベルでの選択は、システムのパフォーマンスやリソースの使用に影響を与えることがあります。それを認識し、その理由と方法を理解することで、より良い選択を行うか、既存のシステムをより効率的にする方法を見つけることができます。これは両方の方法で機能します。利用可能な高レベルのユーティリティがあることを知っていると、低レベルのドメインで独自のホイールを発明することができなくなります。したがって、現在取り組んでいるレベル以外のレベルをある程度理解しておくと、より効果的になる可能性があります。

個人的なレベルでは、「レンガを敷くのが好きですか、それとも家をデザインしたいのですか?」または、都市のレイアウトを作成することもできます。または、より強く、より軽く、より安価なレンガを作る科学を改善しますか?

3
Martin Maat

私たちがコンピュータサイエンスで教える抽象化は、歴史的に、ほとんどのプログラムを書くほとんどの人々にとって最も有益であるとされてきたものです。現代のプログラムの膨大なサイズとビジネスが開発者に課す時間の制約のために、アセンブリで現代のプログラムを書くことはできません。何が起こっているのかを100%理解することなく、目標を達成する準備ができている必要があります。抽象化は、まさにそれを行うのに役立つ強力なツールです。

さて、最初の文で、私は多くの「ほとんど」を持っていました。あなたのキャリアにおいて、あなたは意志時々、あなたが学んだ抽象化があなたを迷わせる状況に自分を見つけます。このとき、他の知識を掘り下げる必要があります。時々、それは仕事のための正しい抽象化を学ぶのと同じくらい簡単です。他の場合には、それはあなたがやったことを正確に必要とします:それらの抽象化を使用するときに基礎となるシステムが何をしているかを理解しようとします。

例として、マルチスレッドを見てください。 mutex、クリティカルセクション、条件変数などを使用する従来のマルチスレッドは、抽象的なレベルで非常によく理解されています。カーネルがスレッドをどのようにスワップインまたはスワップアウトするか、またはタイマー駆動割り込みがユーザースレッドから制御を奪ってカーネルに魔法をかける方法を理解する必要はありません。 RCUとは何か、カーネルの腸の奥深くにあるミューテックスの使用をやめなければならない理由を知る必要はないかもしれません。実際、カーネルレベルから理解しようとすると、危険な間違いをする可能性があります。誰かが操作を「十分にアトミック」であると考え、ミューテックスで適切に保護しなかったため、修正しなければならなかったレースケースの数を数えることができません。安全なマルチスレッドコードを作成するのに役立つ知識を得るには、カーネル(およびコンパイラ)を本当に理解する必要があります。ミューテックスの抽象層ですべてを行う方がはるかに効果的です。

少しプッシュしましょう。 「ほとんど」のマルチスレッド化されたプログラムを書くのではなく、抽象化で十分ですが、アトミック操作を使用して、本当に最先端のEdgeコードを書き始めましょう。これで、アトミック操作を抽象的な概念として学び、それらをうまく使用することができますが、APIを組み合わせたときに何が喫煙されているのかと頭を悩まされることになります。頭を痛めるアトミック操作のメモリ同期の詳細には、あらゆる種類のものが表示されます。この場合、あなたが述べたように、最初から物事を学ぶことは、なぜ抽象化が何をするかを理解するのに非常に役立ちます。キャッシュの機能と、同期を維持するためにキャッシュがどのように覗き見されるかを理解したら、アトミック操作APIの不条理が生じた理由がわかります。これはハードウェアの必要性でした。それらを理解すれば、貴重なリアルタイムアルゴリズムから最後の数ミリ秒を引き出す方法を理解し、その日を節約するためのより良い立場になります!

したがって、どちらのアプローチにも価値があります。ハードウェアに縛られることなく抽象化を受け入れることをいとわないなら、より価値のあるコードをより速く生成することができます。ただし、ハードウェアを理解することで、他の開発者が決して考えられなかった方法で抽象化の境界を広げることができる場合があります。幸せな媒体だと私は言う。両方のバランスを見つけてください!

3
Cort Ammon

今何時ですか?

万能のプログラマになる時ですか、それとも生産的なプログラマになる時ですか?

作業しているレイヤーの下に存在する抽象化レイヤーを理解することは良いことであり、作業の構造の背後にある理解を深め、より良いソリューションを作成することもできます。

それでも、あなたはそれを行い、生産的である時がではないときを勉強します。生産性を高める時期になったら、高レベルのツールを使用して構築します。物事がどのように機能するかについてのすべての知識を使用し、問題の空間に意味のある用語でソリューションを表現します。

もちろん、そのようなツールを使用するには知っておく必要があります。貧弱なツールでビルドするのにかかる時間にはトレードオフがあります vs より適切なツールの使用を学ぶ時間。それはこの質問の範囲を超えています。それでも、さまざまなツールを理解することには利点があることを理解しています。


今までは、低レベルのものを実行するプログラミング言語(Cなど)を学ぶべきだといつも信じていました

あなたがすべきであるということではありません、それは低レベルのものを知るのは良いことです。

フードの下で実際に何が起こっているのか、そしてコンピューターが実際にどのように機能するのかを理解する。

まず、コンピュータがどのように機能するかを理解するのにプログラミング言語は必要ありません。第二に... Cが高すぎるかもしれないし、少し狭いかもしれません。 Cは古いバージョンのハードウェアアーキテクチャの優れたマッピングであり、さまざまなシステムにソースを移植できるほど抽象化されています。詳細な理解が必要な場合は、アセンブリ言語を目指す必要があります(アセンブリ言語は機械語の抽象概念であることに注意してください)。

結局、あなたはこれを知っているより良いプログラマーになると思いました

はい、あなたはそれを知ることでより良いプログラマーになります。

すべてが魔法であると仮定するのではなく、何が起こっているのかがわかるからです。

それらが魔法ではないことを知るために、物事がどのように機能するかを知る必要はありません。必要なのは、それらがどのように機能するか、そのコストは何か、それから何を期待できるかを理解することです。

そして、低レベルのものを知ることは、ビジネスプログラムを書くよりもはるかに興味深いと思います。

うーん...低レベルのものは、彼らが好奇心を刺激し、刺激するものと考えられているという意味で興味深いです。ビジネスプログラムは、お金に関連する別の意味の関心事に対処する場合があります。

その上、あなたはすべてのビジネスプログラムがほとんど同じであるという印象を受けるかもしれません:いくつかのデータベース、いくつかのモデルクラス、いくつかのCRUDなど...それらは退屈なものです。しかし、ソフトウェアの多様性と、その周りのビジネスの多様性を見てください。自分を拘束しないでください。

私の目標は、より優れたプログラマーになること、コンピューターサイエンスをより深く理解することであり、これは私を本当に混乱させました。

より優れたプログラマーになりたい場合は、再利用可能なコードを書く方法を学びます。動作が信頼できるコードを使用し、毎回書き直す必要がないため、生産性が向上します(例:同じタスクをより少ない時間で実行するだけでなく、バ​​グも減少するため)。これを行う場合、再利用可能なコードを再利用可能で共有可能な形式で配置することに関心があり、他の開発者と共有することもできます。少なくともあなたがこれを行うことさえ考えれば、他の人が共有する再利用可能なコードに対する感謝、開発ツールの有用性に対する感謝、そしてより高水準の言語に対する感謝を育てることを願っています。これらはあなたをより良いプログラマーにします。

一方、コンピュータサイエンスを学びたい場合は、詳細を無視する必要があります。たとえば、アルゴリズムが別のアルゴリズムよりも効率的であるかどうかを確認する場合、結果が特定のCPUによる制約を受けるべきではありません。コンピュータサイエンスは数学に似ており、抽象的なものです。

主に、すべての抽象化を避けて、非常に低いレベルで実際に何が起こっているのかを観察するべきではありませんか?

いいえ、抽象化を避けるべきではありません。そして、はい、かなり低いレベルで何が起こるかを観察できます。

今何時ですか?物事がどのように機能するかを学ぶ時なのか、それとも生産性を高める時なのか?

物事がどのように機能するかを学ぶ時が来たら、抽象化を避けないでください...それらをより低いレベルから実際に観察し、自分で作成することさえできます!彼らがどのようにそしてなぜ彼らが彼らのやり方で働くかを体験してください。

生産性を高める時期になったら、抽象化を避けないでください...目前のタスクに適したものを選択して活用してください。

生産性を高める方法にまったく興味がある場合は、ツールを使用することを検討してください。ハンマーがあるときに、なぜ釘を押して木を素手で突き刺そうとするのでしょうか。 手元にテキストエディタがある場合に、磁化された針と安定した針を使用してハードディスクのビットを反転するのはなぜですか?

抽象化を避けないでください、それらはツールです。

抽象化が優れている理由を私は知っていますが、それがコンピュータの動作を学ぶことを妨げていないのですか?何か不足していますか?

複数のことを学ぶことができることを忘れます。学習JavaはCの学習を妨げません。学習CはC#の学習を妨げません。学習OOPはデータの学習を妨げません構造、データ構造の学習はAOPの学習を妨げません。アセンブリ言語の学習は電子工学の学習を妨げません;電子工学の学習は論理ゲートの学習を妨げません。


Nobodyは、コンピュータを機能させるために必要なことをすべて知っています。だからといって、どこでも快適な知識レベルに到達できるという意味ではありません。核物理学から始まり、ユーザーエクスペリエンスに至るまで、オンラインでコースやコミュニティを支援してくれるコミュニティを見つけることができます。

編集:上記のものは不人気な意見かもしれません。私はそれについて3つのことを言う必要があります。あなたがフィールドのエキスパートになるとは言ったことはありません。 2)私はオンラインコースを出発点として言及します-そして、はい、核物理学に関するオンラインコースがあります(オンラインで何か良いものが欲しい場合は有料です)。 論理ゲートから原始的なビデオゲーム 3)に進むコースもあります。私は専門分野に価値があることを理解しており、すべてを学ぶように奨励するつもりはありませんでした。

繰り返しますが、これがあなたの時間の最善の利用法であるかどうかを検討してください...クライアントが新しいモバイルアプリを作成するために雇ったとき、半導体がどのように機能するかをまだ理解していないため、プロジェクトを中止しますか?いいえ、もちろんそうではありません。

理由は詳細です。物理学や材料に興味がないので「いいえ」と言うかもしれませんが、生産的である時なので「いいえ」と言うべきです。いずれにせよ、あなたが学ぶ抽象化レベルを選択できることに同意します。

一般的に抽象化を避けてきたように思われるかもしれませんが、それらのいくつかだけを避けてきました。


コンポーネントで分割してすべてを理解するアプローチは不十分であり、多くの分野で不十分です。これは、コンポーネントが統合されている場合にのみ表示され、したがって調査のみが可能な緊急の動作があるためです。

土木技師は個々の原子の位置を気にしていますか?いいえ、そうではありません。彼らは新しい材料を作成しようとする気にさえしません(その仕事は材料エンジニアのためのものです)-土木技術者にとって、材料は便利な抽象概念です。彼らは原子がどのように配置されているかを知る必要はなく、どれだけの費用がかかり、どのように振る舞うか(ストレスや湿気などにどのように反応するか)を必要としますが、それでも材料が魔法ではないことを知っています。

すべてを原子に分解することを主張した場合、生物学について学ぶことはほとんどありません。すべてをニューロンに分解することを主張した場合、心理学について学ぶことはほとんどありません。

あなたはアイデアを得ます。

3
Theraot

スペクトルの反対側には、アルゴリズムを教える方法の古典としてしばしば賞賛される別の本があります。DonaldE. KnuthのArt of Computer Programmingです。彼の見解では、プログラマーは使用している言語でシンプルかつ効率的なコードを書く傾向があり、マシンコードのサイズとパフォーマンスが実際に何であるかを考えると、DEKはすべてのアルゴリズムを(偽の、抽象化された)機械語で提供しました問題。

その本は本当に古典的であり、彼は大きな点を指摘しました。プログラムの実際のコストを隠す抽象化を避けるために、彼の初版にはオペレーティングシステムがなく、サンプルプログラムの呼び出し規約には自己変更コードが使用されていました。最近のデスクトッププロセッサでは、CPUとOSがアプリケーションコードがハードウェアと直接通信することを許可しないため、そのようなプログラムは文字通り実行されません。また、最近のCPUには、自己変更によって無効になる命令キャッシュがあります。

同様に、高速なコードを記述したい場合は、プロファイルを作成して、パフォーマンスが最も重要なセクションが頻繁に呼び出されるループであることを確認します。ループとは?次の保証が行われます。各反復は任意のステートメントに基づいて順次実行されますが、通常は任意に変更でき、&で取得できるメモリ内のアドレスを持つループインデックスの値です。ただ、最新のハードウェアでは、並列化による高速化が得られます。ループをベクトル化するか、スレッド間で作業を共有します。また、低レベルのC構文は、元々作成されたPDPマシンが実行できる機能に非常に密接にマッピングされているため、最新のオプティマイザに非常に役立つ多くの保証が破られていることがわかります。

foreach、コンテナー、イテレーター、関数型プログラミングなど、Cにはないプログラミング言語の抽象化の一部は、これらのループのほとんどを、かつての多くの最適化よりも効率的かつ安全にコンパイルできますポインタ演算やDuff's DeviceなどのCコードを効率的にしました。同様に、DOSゲームは、人々がDOSBoxなどのエミュレーターでのみ実行できるようになるまで、金属に非常に接近して実行されたため、非常に効率的でした。今日のコードサイズについて心配する人はいません。また、1つのタイムスタンプを保持して除算を行い、残りの部分を実行する方が簡単になったため、プログラマーはゲームの時間を計るために多数のカウンターを保持しません。対数表との間で変換を行って乗算や除算を行う人がいないように。

あなたが理解したいのは、あなたがそれらを実装するときあなたの操作がどのように実行するかtodayです。最新のハードウェアでは何が速く動作しますか?しかし重要なのは、数学的優雅さが時代を超えているということです。デザインを明確かつわかりやすく表現したい、効率的に最適化したい、プロジェクトのどの部分をより低い抽象化レベルでリファクタリングする必要があるかを理解したい。

1
Davislor

この質問に対処する Zen and the Art of Motorcycle Maintenance をお読みください。それが到達する結論は、あなたが選択した抽象化のレベルで最高の「品質」を生み出すことを目指すべきであるということです。時々これはあなたの上下のレベルについてもっと理解することを意味しますが、一般的にはすべてのレベルをマスターすることはできません。

1
DrMcCleod

抽象化は複雑さを管理するために必要ですこれはすべてのプログラマーの宿敵です。抽象化の使用を学ぶことは、その背後にある詳細を学ぶことと同じくらい重要です。

現実の問題の解決策には、問題のモデルによく似た表現が必要です。そのため、サイコロゲームにはDieというクラスがあり、roll()というメソッドを持つクラスがあり、_011100110000001110101000100001010101000100_を持つコードのブロックはありません(これらの2進数の抽象化がプラットフォームによっては理にかなっていると仮定しています) )。これはラーマンによって representational gap と呼ばれています。抽象化により、このギャップを小さく保つことができます。これは、低表現ギャップ(LRG)として知られる戦略です。これにより、コードを要件までたどり、理解しやすくなります。 ドメイン駆動設計(DDD) アプローチも同様です。


UML class diagram of DiceGame

プログラマーとして、私たちは自然に複雑なパズルに惹かれます。複雑な問題を解決したことを誇りに思います。しかし、パラドックスは、物事が常に複雑すぎると、人間としての私たちは多くの仕事を成し遂げられないということです。選択肢がある場合は、(抽象化によって)シンプルに保つことをお勧めします。

1
Fuhrmanator

philipxy's answer に示されているように、デジタルはすべて抽象概念です。電流と電圧の電気工​​学的見方でさえ抽象化です。

私はコンピューターアーキテクト、コンパイラライター、オペレーティングシステム開発者として働いていました。 Java私が設計を支援したサーバーで実行するつもりのプログラムを書いた経験があります。

データが変更され、現在別のプロセッサで読み取り専用モードのキャッシュにある場合に、キャッシュミスがどのように機能するかについてのサイクルごとの知識は、Javaプログラム。一方、特定のキャッシュミスの場合にレイテンシのサイクルを追加することによるパフォーマンスへの影響を分析していたとき、そのレベルの詳細が必要でした。

プログラミング技術の重要な部分は、解決している問題に適したモデルを選択することです。

0

他の人が指摘したように、すべては抽象化と詳細の両方です。抽象化により、関連する概念の理解と操作に集中できる一方で、詳細の知識によりそれらを実装できます。ソリューションアーキテクトにとって、プログラミング言語は単なる詳細であり、コーダーがソートアルゴリズムを最適化する上で、データ型は単なる抽象化です。私は常に、少なくとも必要なレベルよりも低いレベルで詳細を認識することをお勧めします。これは、貧弱または高価な実装の選択を行わないようにするのに役立ちますが、同様に、ソリューションのコンテキストを理解するために必要なレベルより上のレベルでの概念の認識をお勧めします予想に適合します。

0
Paul Smith