Время от времени я вижу вопросы о крайних случаях и других странностях в переполнении стека, на которые легко отвечают такие люди, как Джон Скит и Эрик Липперт, демонстрирующие глубокое знание языка и многих его тонкостей, как этот:
Вы можете подумать, что для того, чтобы использовать
foreach
цикл, коллекция, которую вы перебираете, должна реализовыватьIEnumerable
илиIEnumerable<T>
. Но, как оказалось, это не является обязательным требованием. Требуется, чтобы у типа коллекции был открытый методGetEnumerator
, который должен возвращать некоторый тип, для которого вызываетсяCurrent
метод получения открытого свойства и открытый метод,MoveNext
который возвращает abool
. Если компилятор может определить, что все эти требования выполнены, генерируется код для использования этих методов. Только если эти требования не выполняются, мы проверяем, реализует ли объектIEnumerable
илиIEnumerable<T>
.
Это круто, что нужно знать. Я могу понять, почему Эрик знает это; он в команде компиляторов, поэтому он должен знать. Но как насчет тех, кто демонстрирует такие глубокие знания, которые не являются инсайдерами?
Как простые смертные (которые не входят в команду по компиляции C #) узнают о таких вещах?
В частности, существуют ли методы, которые эти люди используют, чтобы систематически выкорчевать такие знания, исследовать их и усваивать (делать их своими)?
источник
Ответы:
Прежде всего, спасибо за добрые слова.
Если вы хотите получить глубокие знания C #, несомненно, будет полезно иметь языковую спецификацию, десять лет проектных заметок, исходный код, базу данных ошибок, а также Андерса, Мэдса, Скотта и Питера. Мне, конечно, повезло, никаких вопросов по этому поводу.
Однако даже без этих преимуществ все еще возможно получить глубокое знание предмета.
Когда я начинал в Microsoft, я работал над интерпретатором JScript, который поставлялся с Internet Explorer 3. В то время мой менеджер сказал мне один из лучших советов, которые я когда-либо получал. Он сказал, что хочет, чтобы я стал признанным экспертом в Microsoft по синтаксису и семантике языка JScript, и что я должен пойти на это, отыскивая вопросы по этим аспектам JScript и отвечая на них. Особенно отвечая на вопросы, ответы на которые я не знал, потому что это те, из которых я бы узнал.
Очевидно, что StackOverflow и другие общедоступные форумы по вопросам и ответам подобны питью из пожарного рукава для подобных вещей. Тогда я неукоснительно читал comp.lang.javascript и наши внутренние форумы Microsoft «JS User» и следовал совету моего менеджера: когда я увидел вопрос о семантике языка, на который я не знал ответа, я сделал это мое дело выяснить.
Если вы хотите совершить такое «глубокое погружение», вы должны тщательно выбирать. Я до сих пор замечательно не знаю, как работает объектная модель браузера. Поскольку в последние годы я сосредоточился на том, чтобы стать экспертом по языку C #, я удивительно не осведомлен о том, как работают различные классы в библиотеках базовых классов. Мне повезло, что у меня есть работа, которая ценит конкретные глубокие знания; если ваша работа или ваши таланты более соответствуют тому, чтобы быть универсалом, углубление может не работать для вас.
Написание блога также чрезвычайно полезно; требуя от меня объяснения сложных тем другим людям, я вынужден постоянно сталкиваться с собственным неадекватным пониманием различных тем.
источник
Будучи на стороне "гуру" в разговоре один или два раза, я могу вам сказать, что часто то, что вы воспринимаете как "глубокое знание" языка программирования или системы, часто является результатом "гуру", который недавно боролся за месяц, чтобы решить точно такую же проблему. Это особенно верно на форуме, где люди могут выбирать, на какие вопросы они будут отвечать. Даже такие люди, как Джон Скит и Эрик Липперт, должны были однажды изучить мир приветствия. Они приобретают свои знания по одной концепции за раз, как и все остальные.
источник
Перефразируя Йоги Бхаджана:
Программирование похоже на высшую учебную задачу. Чтобы научить компьютер делать что-то, требуется, чтобы вы действительно хорошо разбирались в своих вещах - или вы научитесь овладевать ими
Например, если вы хотите изучать физику, напишите физический движок. Если вы хотите изучать шахматы, запрограммируйте игру в шахматы. Если вы хотите получить глубокие знания C #, напишите компилятор C # (или другой инструмент).
источник
Насколько я знаю, способы узнать это:
Второй способ может занять гораздо больше времени, но, вероятно, приведет к более глубокому пониманию (но не всегда).
источник
Я бы сказал, сделать следующее:
После изучения относительно полезного набора языков (тех, которые вам нужны для реальной работы) на уровне, на котором вы можете выполнять наиболее распространенные задачи, прекратите изучать больше языков, пока не изучите хотя бы один из них. На мой взгляд, часть проблемы в нашей отрасли сейчас заключается в том, что люди изучают только первые 5-10% языка, прежде чем переходить на какой-либо другой язык. Как только у вас появится возможность выполнять наиболее распространенные задачи в работе, начните углубляться в одну вещь. (Вы можете вернуться к получению ширины после того, как вы достигнете некоторой глубины, а затем переходить назад и вперед между ними.)
Доброволец решает более сложные и сложные задачи, которые заставляют вас углубляться в решение проблем. Если вы нигде не работаете, поищите задачи с открытым исходным кодом или начните работать над личным проектом, который заставит вас углубиться. Если на вашей работе нет интересных проблем, подумайте о поиске более сложной работы.
Прочитайте расширенные книги на одном языке (например, для SQl Server это будет включать чтение о настройке производительности и внутренних данных базы данных) вместо книг Learn X за 30 дней.
Прочитайте интересные вопросы здесь и в других местах, где они задаются, и попытайтесь решить некоторые самостоятельно. Если вы хотите учиться, попробуйте решить некоторые, не читая сначала другие ответы. Даже если на этот вопрос уже дан ответ, вы узнаете больше, если найдете ответ самостоятельно. Вы могли бы даже найти лучший ответ, чем тот, который был у вопроса.
Задайте несколько сложных вопросов. Оцените ответы, которые вам даны, а не просто используйте их. Убедитесь, что вы понимаете, почему ответ будет или не будет работать. Используйте эти ответы в качестве отправной точки для исследования.
Найдите несколько хороших технических блогов от известных экспертов в этой области и прочитайте их.
Прекратите выбрасывать свои знания после того, как с ними покончено. Научись сохранять. Большинству экспертов не нужно искать общий синтаксис. Им не нужно заново изобретать колесо каждый раз, когда они сталкиваются с проблемой, потому что они помнят, как они подходили к такой же проблеме раньше. Они могут соединить точки и посмотреть, как проблема X, которую они сделали два года назад, похожа на проблему Y, которая у них есть сейчас (меня поражает, как мало людей, кажется, способны устанавливать такие подключения). Следовательно, у них больше времени для изучения более интересных предметов.
источник
Вы можете начать с глубокого изучения языковых спецификаций тех, с кем вы хотите быть экспертом. Например:
источник
foreach
и разъясняет поведение, описанное в цитируемом сообщении в блоге Эрика Липперта. Если кто-то когда-нибудь подумает что-то вроде: «Интересно, как на самом деле работает foreach ...», это было бы хорошим местом, чтобы начать искать.Получите Reflector или любой другой декомпилятор (поскольку он сейчас платит) и начните открывать некоторые из наиболее часто используемых библиотек .NET, чтобы узнать, как работают внутренние компоненты. В сочетании с такой книгой, как CLR через C #, вы получите достаточно глубокое понимание (глубже, чем большинство из нас пойдет на свою обычную работу).
источник
BitConverter
классами и обнаружилIsLittleEndian
системный флаг.Я разработал такие знания в C ++, потусив
comp.lang.c++.moderated
пару лет, хотя на самом деле я не очень-то усердно работал над их созданием. Я не уверен, насколько гуру я могу сказать, что я есть.Я думаю, что есть два вида знаний, которые можно получить о языке программирования:
Номер 2 может быть достигнут только путем программирования на языке и просмотра кода других людей, но номер 1 может быть достигнут, если потратить много времени на чтение языка на его форумах, увидеть, какие вопросы люди задают, и какие ответы есть. StackOverflow также является хорошим местом для этого.
источник
Глубокие знания и опыт программирования означают комфорт на всех уровнях абстракции. Т.е.
Все, что я видел за последние 15 лет, показало, что только если вы действительно сможете войти в компилятор и среду выполнения, у вас есть шанс стать очень опытным. Возможно, вам придется заставить себя сделать шаг и начать рассуждать (и строить) программное обеспечение на следующем уровне абстракции, ниже в стеке , но это единственный путь к опыту.
Все, что у нас есть, это язык абстракции. Вы должны понимать, как языки программирования спроектированы и созданы, чтобы действительно знать, что делает машина.
источник
Прочитайте Руководство по мелким предметам. Это не особенно глубокое знание. Он опубликован в разделе спецификации языка C # 8.6.4. Вы должны иметь привычку как минимум просматривать спецификации для языков, которые вы используете, а также просматривать документацию для всех встроенных библиотек.
Во всяком случае, это не моя идея глубокого знания; это просто неинтересная деталь реализации. Было бы более интересно, если бы дизайнер объяснил, почему это было сделано более динамичным способом, вместо того, чтобы просто проверить, что объект реализует Iterable.
источник