深いプログラミング知識の開発について


136

時折、私は実証し、簡単にジョンスキートとエリックリペットの同類によって回答されているスタックオーバーフロー上のエッジケースや他のすごみについての質問を参照して、言語とその多くの複雑さの深い知識を この1のように:

foreachループを使用するには、繰り返し処理するコレクションがIEnumerableまたはを実装する必要があると考えるかもしれませんIEnumerable<T>。しかし、結局のところ、それは実際には要件ではありません。必要なのは、コレクションの型が、パブリックメソッドが呼び出されていなければならないということでGetEnumerator、それが呼ばれるパブリックプロパティのゲッター持ついくつかのタイプを返す必要がありCurrent、パブリックメソッドMoveNextを返しますbool。コンパイラがこれらの要件をすべて満たしていると判断できる場合、これらのメソッドを使用するためのコードが生成されます。それらの要件が満たされていない場合にのみ、オブジェクトがIEnumerableまたはを実装しているかどうかを確認しますIEnumerable<T>

それは知っておくべきクールなものです。エリックがこれを知っている理由を理解できます。彼はコンパイラチームに所属しているので、知っておく必要があります。しかし、インサイダーではないそのような深い知識を実証する人はどうでしょうか?

単なる人間(C#コンパイラチームに所属していない人)は、このようなことをどのようにして見つけるのでしょうか?

具体的には、これらの人々が体系的にそのような知識を根絶し、それを探求し、それを内面化するために使用する方法がありますか?


10
これは特にオープンソースソフトウェアが輝くところだと思います。フレームワーク/システム/ライブラリに完全に足を踏み入れることができてうれしいです。以前は、WinFormsを使っていたときよりもQtを使ったときの方が、フレームワークの内部をよりよく理解することができました。
Vitor Py

2
特別な群衆の前で馬鹿げているように見えないこと以外に、この特定の例を知る必要があるのはいつですか?彼らはこれを馬鹿にした。それ以外に、Effective C#、Java、C ++などのシリーズにはいくつかのクールなものがあるかもしれません。Eric Lippertのブログも良い情報源です。一般的に、私たちはしばしば知らないことを知らないので、彼らは「100年間生き、100年間学び、愚か者で死ぬ」と言うのです。
ジョブ

26
努力する価値はありますか?私はバイリンガルで、他のいくつかの話されている言語を学ぼうとしています。数学のクラスを受講しましたが、十分ではありません。テニスを半々とする方法を学び、バタフライを使って泳ぐことを学びたいです。もっと旅行したいです。Clojureをいくつか学びたいです。私が望んでいないのは、1つの言語に精通し、数学の博士号を取得し、マイケルフェルプスなどのプールで週30時間過ごすことです。リッパートとスキートの知識は、他の経験を見逃しながら、1つ(またはいくつか)の努力をします。転職するかもしれない?
ジョブ

10
「エリックがこれを知っている理由を理解できます。彼はコンパイラチームに所属しているので、彼は知る必要があります。」- そもそもそれを考えたので、彼はこれを知っている可能性があります。私は彼がそれがこのように機能することを「発見」しなければならなかったことを疑います:)
アレックス10ブリンク

10
@Alex:C#3の実装を実際に構築し始めて以来、私は実際にC#のみに取り組んできました。「foreach」仕様はその6年前に書かれました。私は今でも毎日その言語についての狂った歴史的なことを見つけています。たとえば、今日、代表者については、((A + B)+ C)-(A + C)= A + B + Cであるが、((A + B)+ C)-(B + C)= A奇妙な!
エリックリッパー

回答:


167

最初に、親切な言葉をありがとう。

C#の深い知識が必要な場合は、言語仕様、10年の設計ノート、ソースコード、バグデータベース、およびAnders、Mads、Scott、Peterがすぐに利用できることは間違いありません。確かに幸運です、それについては疑いの余地はありません。

ただし、これらの利点がなくても、主題の深い知識を得ることが可能です。

Microsoftに入社したとき、私はInternet Explorer 3に同梱されていたJScriptインタープリターに取り組んでいました。当時のマネージャーは、私が今までに得た最高のアドバイスのいくつかを教えてくれました。彼は、私が私にJScript言語の構文とセマンティクスのマイクロソフトで認められた専門家になってほしいと言ったので、JScriptのこれらの側面に関する質問を探して答えることでこれを進めるべきだと言いました。特に私が答えを知らなかった質問に答えるのは、それらが私から学ぶものだからです。

明らかに、StackOverflowや他の公開Q&Aフォーラムは、そのようなことをするために消火ホースから飲むようなものです。当時、私はcomp.lang.javascriptとMicrosoftの内部「JSユーザー」フォーラムを宗教的に読み、マネージャーのアドバイスに従いました。答えがわからない言語セマンティクスに関する質問を見たとき、それを作りました見つけるために私のビジネス。

そのような「ディープダイブ」を行いたい場合は、慎重に選択する必要があります。私は今日まで、ブラウザオブジェクトモデルがどのように機能するかについて非常に無知です。この数年、私はC#言語の専門家になることに専念してきたので、基本クラスライブラリのさまざまなクラスがどのように機能するかについて非常に無知です。幸運なことに、特定の深い知識を賞賛する仕事があります。あなたの仕事や才能がゼネラリストであることと一致している場合、深く行くことはあなたには役に立たないかもしれません。

ブログを書くことも非常に役立ちます。複雑なトピックを他の人に説明するように要求することにより、私は常にさまざまなトピックの自分の不十分な理解に立ち向かうことを余儀なくされます。


14
これをトピック外にドラッグすることはできませんが、この回答を読んだ後、ここまたはStack Overflowで質問をしていない理由に興味があります。この時点で同僚やブログなどで十分ですか?知っておくべきSOよりも優れたリソースはありますか?
マシュー

6
おそらくあなたは彼が言っていることを誤解したでしょう。直感に反して、彼は物事を学ぶために質問をするのではなく、質問に答えていました。
ジョッキング

65

会話の「第一人者」側に1回または2回参加したことはありますが、多くの場合、プログラミング言語またはシステムの「深い知識」としてあなたが感じるものは、最近苦労している「第一人者」の結果です。まったく同じ問題を解決するための月。これは、人々が回答する質問を選択できるフォーラムでは特に当てはまります。ジョン・スキートやエリック・リッパートのような人でさえ、ある時点でハローワールドを学ばなければなりませんでした。彼らは自分の知識を他の誰と同じように一度に一つの概念を拾います。


1
非常に良い点。長期間の研究に着手すると、その日早くに学んだことが原因で答えられる質問を見つけることがよくあります。
マシュー

47

ヨギバジャンの言い換え:

「何かを学びたいなら、それについて読んでください。何かを理解したいなら、それについて書いてください。何かをマスターしたいなら、 それをプログラムしてください。」

プログラミングは、究極の教育課題のようなものです。コンピューターを教えるには、自分のものを本当によく知っているか、それをマスターすることを学ぶ必要があります。

たとえば、物理学を学びたい場合は、物理エンジンを作成します。チェスを学びたいなら、チェスゲームをプログラムしてください。C#の深い知識を学びたい場合は、C#コンパイラー(または他のツール)を作成してください。


2
プログラミングは、最も明白な方法で(もちろん、人々に読まれるように)控えめな書き方でもあります。
vpit3833

4
チェスの例を読むまで、その引用は本当に深く聞こえました。残念ながら、チェスAIをプログラミングしても、あなたがより良いチェスプレイヤーになることはありません(基本的にはMin-Maxツリーでの検索です)。まだ+
1-ブギ

1
@bughiたぶん、あなたはルールを習得することができます:D
フリオ・ロドリゲス

@bughi、「プログラムする」は、コードの記述に常に関連するとは限らない非常に広い用語です!! ちょっと箱から出して考えてください。
ニテシュバーマ

25

私の知る限り、これを学ぶ方法は次のとおりです。

  • Eric Lippertのような人からそれについて読む
  • 問題を直接経験し、解決してください。

2番目の方法ははるかに長い時間がかかる可能性がありますが、おそらくより深い理解になります(常にではありません)。


17
または両方。[15文字]
マイケルK

23

私は次のことを行うと言うでしょう:

最も一般的なタスクを実行できるレベルで、比較的有用な言語のスタック(実際の仕事に必要な言語)を学習した後、少なくとも1つを徹底的に学習するまで、それ以上の言語の学習を停止します。私の意見では、現在の業界の問題の一部は、他の言語に移る前に言語の最初の5〜10%しか学習しないことです。ジョブで最も一般的なタスクを実行できるようになったら、1つのことを詳しく調べ始めます。(ある程度の深さを取得したら、幅を取り戻すことができ、2つの間を行き来できます。)

問題を解決するために深く行かなければならない、より複雑で困難な作業にボランティアをしてください。作業する場所がない場合は、実行するオープンソースのタスクを探すか、個人プロジェクトで作業を開始してください。仕事に興味深い問題がない場合は、より挑戦的な仕事を探すことを検討してください。

30日間の種類Xの本ではなく、1つの言語で高度な本を読んでください(たとえば、SQl Serverの場合、これにはパフォーマンスチューニングとデータベース内部についての読書が含まれます)。

ここでの興味深い質問や、質問されている他の場所を読んで、自分で解決してみてください。学習したい場合は、最初に他の回答を読まずにいくつかを解決してください。質問がすでに回答済みであっても、回答を自分で見つければさらに学習できます。質問の答えよりも良い答えを見つけるかもしれません。

いくつかの難しい質問をしてください。与えられた答えを評価し、それらを使用するだけではありません。答えがなぜ機能するのか、または機能しないのかを理解してください。これらの回答を調査の出発点として使用してください。

この分野の有名な専門家からの優れた技術ブログを見つけて読んでください。

あなたがそれを使い終わったら、あなたの知識を捨てるのをやめてください。保持することを学ぶ。ほとんどの専門家は、一般的な構文を調べる必要はありません。彼らは問題に直面するたびに車輪を再発明する必要はありません。彼らは以前同様の問題にどのようにアプローチしたかを覚えているからです。彼らは点をつなげて、2年前に行った問題Xが現在の問題Yにどのように似ているかを見ることができます(そのような接続を行うことができる人が少ないことに驚かされます)。その結果、彼らはより興味深い主題の研究に費やすためにより多くの時間を利用できます。


いい答えです。しかし、どうすれば知識を保持し、点をつなぐことができるようになるのでしょうか?

学んだことはすべてメモを取ることをお勧めします。私はEvernoteでこれを始めましたが、数年かけて、私は自分のメモで生活できることに気付きました。ゆっくりと、メモをプレゼンテーションにすることもできるようになりました。これをすぐに発表する準備ができています。
シバスブラマニアンA

9

専門家になりたい言語仕様を深く勉強することから始めることができます。例えば:


3
良い答え-たとえば、リンクされたC#仕様のセクション15.8.4は、の実装をカバーしておりforeach、Eric Lippertの引用されたブログ投稿で説明されている動作を詳しく説明しています。「foreachが実際にどのように機能するのか不思議に思う。」のようなことを考えている人がいたら、ここから始めるのが良いでしょう。
Carson63000

6

Reflectorまたはその他の逆コンパイラを入手して(今は有料なので)、最もよく使用される.NETライブラリの一部を開いて、内部の仕組みを学習します。C#経由のCLRのような本と組み合わせると、かなり深くなります(私たちのほとんどが通常の仕事をするよりも深くなります)。


5
実際にBitConverterクラスでこれを行い、IsLittleEndianシステム固有のフラグを発見しました。
ロバートハーヴェイ

笑。isLittleEndianの+1
ルディ

4

comp.lang.c++.moderatedはその時点でコーディングするのにそれほど苦労していませんでしたが、C ++でこの種の知識を数年間ぶらぶらして開発しました。しかし、私がどのように自分が言えるのかわからない。

プログラミング言語について理解できる2種類の知識があると思います。

  1. 言語についての雑学を知り、落とし穴を避ける方法を知る。
  2. 問題を効果的に解決する方法を知っている。

2番目の言語は、言語でプログラミングし、他の人のコードを調べることによってのみ達成できますが、1番目の言語は、ディスカッションフォーラムで多くの時間をかけて言語について読み、人々がどのような質問をし、答えは。StackOverflowもそのための良い場所です。


4

深い知識とプログラミングの専門知識は、すべての抽象化レベルで快適であることを意味します。すなわち

  • ライブラリとAPI
  • 言語セマンティクス
  • コンパイラーの最適化
  • コンパイラ内部とコード生成
  • ランタイムおよびガベージコレクターの動作
  • アーキテクチャおよび命令セットの問題

過去15年間に私が見てきたすべてのことは、本当にコンパイラーとランタイムを使用できるようになった場合にのみ、十分に熟練する可能性があることを示しています。スタックの下位の次の抽象化レベルで、一歩踏み込んでソフトウェアの推論(および構築)を開始する必要がありますが、それが専門知識への唯一の方法です。

私たちが持っているのは、抽象化のための言語だけです。プログラミング言語がどのように設計され構築されているかを理解して、マシンが何をしているかを本当に知る必要があります。


3

ファインマニュアルを読むこれは特に深い知識ではありません。C#言語仕様セクション8.6.4で公開されています。少なくとも、使用する言語の仕様をスキミングする習慣を身に付け、すべての組み込みライブラリのドキュメントをスキムする必要があります。

とにかく、これは私の深い知識のアイデアではありません。それは単に面白くない実装の詳細です。オブジェクトがIterableを実装していることを単にチェックするのではなく、デザイナーがこの動的な方法で行われた理由を説明すれば、さらに興味深いかもしれません。


1
C#言語仕様を「スキミング」するようなことはないと思います。
ロバートハーヴェイ

@RobertHarvey:演算子の優先順位や宣言構文など、すでに知っていることをカバーするほとんどの形式言語をざっと読み、C#foreachやJava enumコンストラクターの正確な動作など、予期しないが有用な詳細に焦点を当てることができます。
ケビンクライン

標準の注釈付きバージョンを購入できます。少し古いですが、コメントは対象言語の部分にとって非常に興味深いものです。
ヨルゲンフォグ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.