Про розвиток глибоких знань з програмування


136

Іноді я бачу запитання щодо крайових випадків та інших дивацтв на Stack Overflow, на які легко відповідати, як подібні Джон Скіт та Ерік Ліпперт, демонструючи глибокі знання мови та її багатьох тонкощів, як ця:

Ви можете подумати, що для використання foreachциклу колекція, яку ви повторюєте, повинна реалізувати IEnumerableабо IEnumerable<T>. Але, як виявляється, це насправді не є вимогою. Потрібно, щоб тип колекції мав публічний метод, який називається GetEnumerator, і він повинен повертати певний тип, який має виклик публічної власності Currentта публічний метод, MoveNextякий повертає a bool. Якщо компілятор може визначити, що всі ці вимоги виконуються, код формується для використання цих методів. Тільки якщо ці вимоги не виконані, ми перевіряємо, чи реалізується об'єкт IEnumerableчи IEnumerable<T>.

Це класні речі, щоб знати. Я можу зрозуміти, чому Ерік це знає; він в команді компілятора, тому він повинен знати. Але як бути з тими, хто демонструє такі глибокі знання, хто не є інсайдерами?

Як просто смертні (які не входять до команди компілятора C #) дізнаються про подібні речі?

Зокрема, чи існують методи, які ці люди використовують для того, щоб систематично викорінювати такі знання, досліджувати їх та інтерналізувати (робити їх своїми)?


10
Я думаю, що це особливо там, де світить програмне забезпечення з відкритим кодом. Приємно мати можливість зайти в рамки / систему / бібліотеки до кінця. У мене раніше було краще розуміти внутрішні рамки, коли я працював з Qt, ніж коли я працював з WinForms.
Vitor Py

2
Коли вам потрібно було б знати цей конкретний приклад, крім того, щоб не виглядати німим перед особливим натовпом? Вони ідіотом підтвердили це. Крім цього, ефективні серії 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
Щоб не перетягувати цю тему, але після прочитання цієї відповіді мені цікаво, чому ви тут не ставили жодних запитань або на Stack Overflow. Чи достатні для вас зараз ваші колеги, блог тощо? Чи є кращі ресурси, ніж ТА, про які ми повинні знати?
Матвій

6
Можливо, ви неправильно зрозуміли, що він говорить. Навмисно, він не задавав запитань, щоб дізнатися щось, він відповідав на запитання.
поштовх

65

Опинившись один раз або два рази на стороні розмови «гуру», я можу вам сказати, що багато разів те, що ви сприймаєте як «глибоке знання» мови програмування або системи, часто є результатом того, що «гуру» останнім часом бореться за на місяць, щоб вирішити точно таку ж проблему. Особливо це стосується форуму, де люди можуть вибрати, на які питання вони відповідатимуть. Навіть подобається Джону Скіту та Еріку Ліпперту в один момент довелося навчитися привіт світу. Вони підбирають свої знання по одній концепції, як і будь-хто інший.


1
Дуже хороший момент. Я часто виявляю, коли займаюся довгими періодами досліджень, що знаходжу питання, на які зараз можу відповісти через речі, про які я дізнався раніше.
Матвій

47

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

"Якщо ви хочете чогось навчитися, прочитайте про це; якщо ви хочете щось зрозуміти, пишіть про це; якщо ви хочете щось освоїти, запрограмуйте його".

Програмування - це як вища проблема викладання. Навчання комп’ютера робити щось вимагає, щоб ви справді добре знали свої речі - або навчитесь її опановувати.

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


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

4
Ця цитата звучала дуже глибоко, поки я не прочитав приклад шахів. На жаль, програмування шахового AI не зробить вас кращим шахістом (це в основному пошук у дереві Min-Max). Ще +1
bughi

1
@bughi Можливо, ти зможеш опанувати правила: D
Хуліо Родрігес

@bughi, "програма це" - це дуже широкий термін, не завжди пов'язаний з написанням коду !! Подумайте трохи з коробки.
Нітеш Верма

25

Наскільки я знаю, способи цього дізнатися:

  • Прочитайте про це від когось, як Ерік Ліпперт
  • Досвід, а потім вирішити проблеми з перших рук.

Другий шлях може зайняти набагато більше часу, але, ймовірно, призведе до глибшого розуміння (але не завжди).


17
Або і те й інше. [15 годин]
Майкл К

23

Я б сказав, зробіть наступне:

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

Будьте добровільними для складніших, складніших завдань, тих, що змушують вас поглибитись, щоб вирішити проблеми. Якщо немає жодної, де ви працюєте, шукайте завдання з відкритим кодом, які потрібно виконати, або почніть працювати над особистим проектом, який змусить вас заглибитись у глибину. Якщо у вашій роботі немає цікавих проблем, подумайте про пошук більш складної роботи.

Читайте вдосконалені книги на одній мові (наприклад, для сервера SQl, це може включати читання про налаштування продуктивності та внутрішні бази даних), а не книги X за 30 днів.

Прочитайте тут цікаві питання та інші місця, де їх задають, і спробуйте вирішити деякі самостійно. Якщо ви хочете навчитися, спробуйте вирішити деякі, не читаючи спочатку інших відповідей. Навіть якщо на питання вже відповіли, ви дізнаєтесь більше, якщо самі знайдете відповідь. Ви навіть можете знайти кращу відповідь, ніж відповідь на питання.

Задайте кілька складніших питань. Оцініть відповіді, які вам дають, не використовуйте їх просто. Не забудьте зрозуміти, чому відповідь не спрацювала б чи ні. Використовуйте ці відповіді як вихідне місце для дослідження.

Знайдіть хороші технічні блоги від відомих фахівців у цій галузі та прочитайте їх.

Перестаньте викидати свої знання після того, як ви закінчите його. Навчіться зберігати. Більшість експертів не повинні шукати загальний синтаксис. Їм не доведеться винаходити колесо кожен раз, коли вони стикаються з проблемою, бо пам’ятають, як раніше підходили до подібної проблеми. Вони можуть підключити точки і побачити, як проблема X, яку вони робили два роки тому, схожа на проблему Y, яку вони мають зараз (це мене дивує, як мало людей здається здатними налагодити подібні зв’язки). Отже, у них є більше часу для проведення цікавих предметів.


Гарна відповідь. Але мені залишається цікаво, як мені стати кращим у збереженні знань та підключенні крапок?

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

9

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


3
Хороша відповідь - наприклад, розділ 15.8.4 пов'язаної специфікації C # охоплює реалізацію Еріка Ліпперта та пояснює 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 enum.
Кевін Клайн

Ви можете придбати анотовану версію стандарту. Це трохи датовано зараз, але коментарі все ще дуже цікаві для тих частин мови, які висвітлюються.
Jørgen Fogh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.