На развитие глубоких знаний в области программирования


136

Время от времени я вижу вопросы о крайних случаях и других странностях в переполнении стека, на которые легко отвечают такие люди, как Джон Скит и Эрик Липперт, демонстрирующие глубокое знание языка и многих его тонкостей, как этот:

Вы можете подумать, что для того, чтобы использовать foreachцикл, коллекция, которую вы перебираете, должна реализовывать IEnumerableили IEnumerable<T>. Но, как оказалось, это не является обязательным требованием. Требуется, чтобы у типа коллекции был открытый метод GetEnumerator, который должен возвращать некоторый тип, для которого вызывается Currentметод получения открытого свойства и открытый метод, MoveNextкоторый возвращает a bool. Если компилятор может определить, что все эти требования выполнены, генерируется код для использования этих методов. Только если эти требования не выполняются, мы проверяем, реализует ли объект IEnumerableили IEnumerable<T>.

Это круто, что нужно знать. Я могу понять, почему Эрик знает это; он в команде компиляторов, поэтому он должен знать. Но как насчет тех, кто демонстрирует такие глубокие знания, которые не являются инсайдерами?

Как простые смертные (которые не входят в команду по компиляции C #) узнают о таких вещах?

В частности, существуют ли методы, которые эти люди используют, чтобы систематически выкорчевать такие знания, исследовать их и усваивать (делать их своими)?


10
Я думаю, что это особенно, где программное обеспечение с открытым исходным кодом светит. Приятно иметь возможность полностью войти в рамки / системы / библиотеки. Когда-то, когда я работал с Qt, раньше я лучше понимал внутреннюю среду фреймворка, чем когда работал с WinForms.
Вит Пи

2
Когда вам нужно будет знать этот конкретный пример, кроме как не выглядеть глупым перед особой толпой? Они доказали это идиотами. Помимо этого, в серии Effective C #, Java, C ++ и т. Д. Могут быть некоторые интересные вещи. Блог Эрика Липперта также является хорошим источником. Вообще, мы часто не знаем, чего не знаем, так как говорят «живи 100 лет, учись 100 лет и умри дураком».
Работа

26
Стоит ли усилий? Я говорю на двух языках и пытаюсь выучить несколько других разговорных языков. Я взял несколько уроков по математике, но их недостаточно. Я хотел бы научиться играть в теннис прилично и научиться плавать, используя ход бабочки. Я хотел бы путешествовать больше. Я хочу выучить немного Clojure. Чего я не хочу, так это быть экспертом по одному языку, иметь докторскую степень по математике, проводить 30 часов в неделю в бассейне, таком как Майкл Фелпс и т. Д. Знания Липперта и Скита связаны с тем, что они вкладывают много усилия в одном (или нескольких) вещах, в то же время упускаясь на других событиях Может сменить работу?
Работа

10
«Я могу понять, почему Эрик знает это; он в команде компиляторов, поэтому он должен знать». - Скорее всего, он знает это, потому что он придумал это в первую очередь . Я сомневаюсь, что он должен был «выяснить», что это работает так :)
Алекс тен Бринк

10
@Alex: На самом деле я работал только на C #, так как мы начали создавать реализацию C # 3. Спецификация «foreach» была написана за шесть лет до этого. Я до сих пор узнаю сумасшедшие исторические вещи о языке каждый день. Например, сегодня я узнал, что для делегатов ((A + B) + C) - (A + C) = A + B + C, но ((A + B) + C) - (B + C) = A Странно!
Эрик Липперт

Ответы:


167

Прежде всего, спасибо за добрые слова.

Если вы хотите получить глубокие знания C #, несомненно, будет полезно иметь языковую спецификацию, десять лет проектных заметок, исходный код, базу данных ошибок, а также Андерса, Мэдса, Скотта и Питера. Мне, конечно, повезло, никаких вопросов по этому поводу.

Однако даже без этих преимуществ все еще возможно получить глубокое знание предмета.

Когда я начинал в Microsoft, я работал над интерпретатором JScript, который поставлялся с Internet Explorer 3. В то время мой менеджер сказал мне один из лучших советов, которые я когда-либо получал. Он сказал, что хочет, чтобы я стал признанным экспертом в Microsoft по синтаксису и семантике языка JScript, и что я должен пойти на это, отыскивая вопросы по этим аспектам JScript и отвечая на них. Особенно отвечая на вопросы, ответы на которые я не знал, потому что это те, из которых я бы узнал.

Очевидно, что StackOverflow и другие общедоступные форумы по вопросам и ответам подобны питью из пожарного рукава для подобных вещей. Тогда я неукоснительно читал comp.lang.javascript и наши внутренние форумы Microsoft «JS User» и следовал совету моего менеджера: когда я увидел вопрос о семантике языка, на который я не знал ответа, я сделал это мое дело выяснить.

Если вы хотите совершить такое «глубокое погружение», вы должны тщательно выбирать. Я до сих пор замечательно не знаю, как работает объектная модель браузера. Поскольку в последние годы я сосредоточился на том, чтобы стать экспертом по языку C #, я удивительно не осведомлен о том, как работают различные классы в библиотеках базовых классов. Мне повезло, что у меня есть работа, которая ценит конкретные глубокие знания; если ваша работа или ваши таланты более соответствуют тому, чтобы быть универсалом, углубление может не работать для вас.

Написание блога также чрезвычайно полезно; требуя от меня объяснения сложных тем другим людям, я вынужден постоянно сталкиваться с собственным неадекватным пониманием различных тем.


14
Не перетаскивать это не по теме, но после прочтения этого ответа мне стало любопытно, почему вы не задали ни одного вопроса здесь или о переполнении стека. Достаточно ли вам ваших коллег, блога и т. Д. На данный момент? Есть ли лучшие ресурсы, чем SO, о которых мы должны знать?
Мэтью Прочитал

6
Возможно, вы неправильно поняли, что он говорит. Неудобно, он не задавал вопросы, чтобы узнать что-то, он отвечал на вопросы.
Джоккинг

65

Будучи на стороне "гуру" в разговоре один или два раза, я могу вам сказать, что часто то, что вы воспринимаете как "глубокое знание" языка программирования или системы, часто является результатом "гуру", который недавно боролся за месяц, чтобы решить точно такую ​​же проблему. Это особенно верно на форуме, где люди могут выбирать, на какие вопросы они будут отвечать. Даже такие люди, как Джон Скит и Эрик Липперт, должны были однажды изучить мир приветствия. Они приобретают свои знания по одной концепции за раз, как и все остальные.


1
Очень хороший момент. Когда я приступаю к длительным исследованиям, я часто нахожу вопросы, на которые я могу теперь ответить из-за того, что я узнал ранее днем.
Мэтью Прочитал

47

Перефразируя Йоги Бхаджана:

«Если вы хотите чему-то научиться, прочитайте об этом; если вы хотите что-то понять, напишите об этом; если вы хотите что-то освоить, запрограммируйте это».

Программирование похоже на высшую учебную задачу. Чтобы научить компьютер делать что-то, требуется, чтобы вы действительно хорошо разбирались в своих вещах - или вы научитесь овладевать ими

Например, если вы хотите изучать физику, напишите физический движок. Если вы хотите изучать шахматы, запрограммируйте игру в шахматы. Если вы хотите получить глубокие знания C #, напишите компилятор C # (или другой инструмент).


2
Программирование также является скромной попыткой написания (конечно, для чтения людьми) самым недвусмысленным образом.
vpit3833

4
Эта цитата звучала очень глубоко, пока я не прочитал шахматный пример. К сожалению, программирование шахматного ИИ не сделает вас лучшим шахматистом (в основном это поиск по дереву мин-макс). Еще +1
Буги

1
@bughi Может быть, вы можете освоить правила: D
Хулио Родригес

@ Bughi, «программируй» - это очень широкий термин, не всегда связанный с написанием кода! Просто подумай немного из коробки.
Нитеш Верма

25

Насколько я знаю, способы узнать это:

  • Читайте об этом от кого-то вроде Эрика Липперта
  • Опыт, а затем решить проблемы из первых рук.

Второй способ может занять гораздо больше времени, но, вероятно, приведет к более глубокому пониманию (но не всегда).


17
Или оба. [15 символов]
Майкл К

23

Я бы сказал, сделать следующее:

После изучения относительно полезного набора языков (тех, которые вам нужны для реальной работы) на уровне, на котором вы можете выполнять наиболее распространенные задачи, прекратите изучать больше языков, пока не изучите хотя бы один из них. На мой взгляд, часть проблемы в нашей отрасли сейчас заключается в том, что люди изучают только первые 5-10% языка, прежде чем переходить на какой-либо другой язык. Как только у вас появится возможность выполнять наиболее распространенные задачи в работе, начните углубляться в одну вещь. (Вы можете вернуться к получению ширины после того, как вы достигнете некоторой глубины, а затем переходить назад и вперед между ними.)

Доброволец решает более сложные и сложные задачи, которые заставляют вас углубляться в решение проблем. Если вы нигде не работаете, поищите задачи с открытым исходным кодом или начните работать над личным проектом, который заставит вас углубиться. Если на вашей работе нет интересных проблем, подумайте о поиске более сложной работы.

Прочитайте расширенные книги на одном языке (например, для SQl Server это будет включать чтение о настройке производительности и внутренних данных базы данных) вместо книг Learn X за 30 дней.

Прочитайте интересные вопросы здесь и в других местах, где они задаются, и попытайтесь решить некоторые самостоятельно. Если вы хотите учиться, попробуйте решить некоторые, не читая сначала другие ответы. Даже если на этот вопрос уже дан ответ, вы узнаете больше, если найдете ответ самостоятельно. Вы могли бы даже найти лучший ответ, чем тот, который был у вопроса.

Задайте несколько сложных вопросов. Оцените ответы, которые вам даны, а не просто используйте их. Убедитесь, что вы понимаете, почему ответ будет или не будет работать. Используйте эти ответы в качестве отправной точки для исследования.

Найдите несколько хороших технических блогов от известных экспертов в этой области и прочитайте их.

Прекратите выбрасывать свои знания после того, как с ними покончено. Научись сохранять. Большинству экспертов не нужно искать общий синтаксис. Им не нужно заново изобретать колесо каждый раз, когда они сталкиваются с проблемой, потому что они помнят, как они подходили к такой же проблеме раньше. Они могут соединить точки и посмотреть, как проблема X, которую они сделали два года назад, похожа на проблему Y, которая у них есть сейчас (меня поражает, как мало людей, кажется, способны устанавливать такие подключения). Следовательно, у них больше времени для изучения более интересных предметов.


Хороший ответ. Но мне интересно, как мне лучше сохранить знания и соединить точки?

Я предлагаю вам делать записи всего, что вы узнали. Я начал делать это в своем Evernote, и через несколько лет я обнаружил, что могу жить по своим записям. Постепенно я также подошел к тому моменту, когда мои заметки можно превратить в презентации, которые я готов представить в любой момент.
Шивасубраманян А

9

Вы можете начать с глубокого изучения языковых спецификаций тех, с кем вы хотите быть экспертом. Например:


3
Хороший ответ - например, раздел 15.8.4 связанной спецификации C # охватывает реализацию foreachи разъясняет поведение, описанное в цитируемом сообщении в блоге Эрика Липперта. Если кто-то когда-нибудь подумает что-то вроде: «Интересно, как на самом деле работает foreach ...», это было бы хорошим местом, чтобы начать искать.
Carson63000

6

Получите Reflector или любой другой декомпилятор (поскольку он сейчас платит) и начните открывать некоторые из наиболее часто используемых библиотек .NET, чтобы узнать, как работают внутренние компоненты. В сочетании с такой книгой, как CLR через C #, вы получите достаточно глубокое понимание (глубже, чем большинство из нас пойдет на свою обычную работу).


5
Я на самом деле сделал это с BitConverterклассами и обнаружил IsLittleEndianсистемный флаг.
Роберт Харви

ЛОЛ. +1 для isLittleEndian
Руди

4

Я разработал такие знания в C ++, потусив comp.lang.c++.moderatedпару лет, хотя на самом деле я не очень-то усердно работал над их созданием. Я не уверен, насколько гуру я могу сказать, что я есть.

Я думаю, что есть два вида знаний, которые можно получить о языке программирования:

  1. Знать мелочи о языке и знать, как избежать подводных камней.
  2. Зная, как эффективно решать проблемы.

Номер 2 может быть достигнут только путем программирования на языке и просмотра кода других людей, но номер 1 может быть достигнут, если потратить много времени на чтение языка на его форумах, увидеть, какие вопросы люди задают, и какие ответы есть. StackOverflow также является хорошим местом для этого.


4

Глубокие знания и опыт программирования означают комфорт на всех уровнях абстракции. Т.е.

  • библиотеки и API
  • семантика языка
  • оптимизация компилятора
  • внутренности компилятора и генерация кода
  • время выполнения и поведение сборщика мусора
  • архитектурно-инструктивные вопросы

Все, что я видел за последние 15 лет, показало, что только если вы действительно сможете войти в компилятор и среду выполнения, у вас есть шанс стать очень опытным. Возможно, вам придется заставить себя сделать шаг и начать рассуждать (и строить) программное обеспечение на следующем уровне абстракции, ниже в стеке , но это единственный путь к опыту.

Все, что у нас есть, это язык абстракции. Вы должны понимать, как языки программирования спроектированы и созданы, чтобы действительно знать, что делает машина.


3

Прочитайте Руководство по мелким предметам. Это не особенно глубокое знание. Он опубликован в разделе спецификации языка C # 8.6.4. Вы должны иметь привычку как минимум просматривать спецификации для языков, которые вы используете, а также просматривать документацию для всех встроенных библиотек.

Во всяком случае, это не моя идея глубокого знания; это просто неинтересная деталь реализации. Было бы более интересно, если бы дизайнер объяснил, почему это было сделано более динамичным способом, вместо того, чтобы просто проверить, что объект реализует Iterable.


1
Я не думаю, что существует такая вещь, как "скимминг" спецификации языка C #.
Роберт Харви

@RobertHarvey: вы можете просмотреть большую часть формального языка, охватывающего вещи, которые вы уже знаете, такие как приоритет оператора и синтаксис объявления, и сосредоточиться на неожиданных, но полезных деталях, таких как точное поведение C # foreach или конструкторов перечисления Java.
Кевин Клайн

Вы можете купить аннотированную версию стандарта. Это немного устарело, но комментарии все еще очень интересны для частей языка, которые покрыты.
Йорген Фог
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.