Переобучение в IT?

В статье я НЕ буду затрагивать вопросы мотивации и целеполагания, а также крайне важного вопроса «А зачем это делать?». Если уважаемые читатели будут заинтересованы и напишут в комментариях о своем желании увидеть рассмотрение этих нюансов — готов написать продолжение статьи.

Препарировать вопрос подготовки новых специалистов я решил с двух сторон. Со стороны технической и человеческой. Технической стороной назовем некоторые знания предметной области, языка программирования, инструментария и прочие штуки. Человеческой же стороной будем считать качества: способность к постоянному обучению, умение рассуждать, абстрактно мыслить, и, что особенно важно, видеть проблему на нескольких уровнях абстракции одновременно. Джоэль Спольски (в свое время руководил проектом Microsoft Excel, а также автор интереснейшего блога для разработчиков и руководителей) прекрасно осветил обе стороны в своих статьях. В статье «Закон дырявых абстракций» речь идет про техническую сторону. В статье «Опасность обучения на Java» — про качественную.

Часть 1. Закон дырявых абстракций

Есть в Интернете инженерное волшебство, на работу которого мы с вами полагаемся каждый день. Оно заключено в сетевом протоколе TCP, одном из основных кирпичей, из которых выстроен Интернет. TCP — способ пересылки данных, который считается надёжным. Это значит: если вы с его помощью отсылаете сообщение по сети, оно обязательно прибудет на место в неискажённом виде.

Мы все пользуемся TCP для повседневных нужд: загрузить страничку с веба, послать электронную почту. Надёжность TCP позволяет всякому Остапу Бендеру из Восточной Африки рассылать по миру спам наивысшего качества. О счастье, о радость!

Посмотрим теперь на другой, ненадёжный, метод пересылки данных под названием IP. Тут уже никто не обещает, что посылка доедет до места назначения, и что по дороге с ней ничего не случится. Отправляя через IP кучу сообщений, не удивляйтесь, если половина из них потеряется, а из остальных часть окажется совсем не тем, что посылалось: может, они будут содержать фотографии прелестных котят, но скорее всего — просто нечитаемый мусор, вроде столь любимого нами всеми тайваньского спама.

Волшебство же состоит в том, что TCP основан на IP. Иными словами, TCP обязуется работать надёжноиспользуя лишь ненадёжные детали.

 

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

Предположим, некая дама отправляла подводами из Петербурга в Москву диван, чемодан, саквояж и т.д. Часть подвод сломалась и до Москвы не доехала. Часть подвод опрокинулась по пути, разбив картину, картонку и зеркала. Подводы добирались до Москвы не в том порядке, в каком выезжали из Петербурга, поскольку некоторых задержали страшные лесные разбойники, и вообще возницы выбирали разные маршруты. А теперь представим, что даме предлагается новая услуга: Красная Стрела, которая гарантирует, что багаж (а) прибудет на место (б) в целости и сохранности (в) и в нужном порядке. Но волшебным образом Красная Стрела не использует, как вы подумали, железной дороги, а нанимает тех самых возниц с подводами. Красная Стрела организует работу возниц следующим образом. Состояние багажа каждой подводы тщательно проверяется. В случае повреждения диван, чемодан и проч. заменяются со склада точно такими же. Подводы выстраиваются в правильном порядке. Если страшные лесные разбойники сумели захватить Бологое и перерезать дорогу, то Красная Стрела перенаправляет подводы другим путём, и дама ничего не подозревает. Ей просто кажется, что багаж прибывает немного медленнее, чем обычно; а об ужасных событиях в Бологом даме знать необязательно.

Примерно так TCP и работает. По-учёному это называется абстракция: упрощённое описание процесса, механизм которого остаётся скрытым. На самом деле, значительная часть программирования заключается в построении абстракций. Что такое, допустим, строковая библиотека? Это способ сделать вид, что компьютеры умеют легко работать со строками, как с числами (складывать, вычитать и т.п.). Что такое файловая система? Это способ сделать вид, что жёсткий диск состоит не из быстро вращающихся намагниченных тарелок, которые умеют сохранять биты в определённых местах, а якобы представляет из себя иерархическую систему папок внутри папок, внутри которых отдельные файлы содержат, в свою очередь, байтовые цепочки.

Вернёмся к TCP. Я тут для простоты слегка загнул, и у кого-то, может быть, от этого уже пар из ушей пошёл. Короче, я сказал, будто TCP гарантирует, что сообщение прибудет на место. На самом деле, это не так. Если ваш любимый хомячок перегрызёт сетевой кабель, так что никакие пакеты IP не дойдут до компьютера, то TCP ничего не сможет поделать, и сообщение не придёт. Если же вы поругались с сетевым администратором, который в отместку включил ваш компьютер в перегруженный хаб, то много пакетов IP потеряется, и хотя TCP будет работать, но так медленно, что за время пути собачка, сами понимаете, того.

Вот это я и называю дырявой абстракцией. TCP пытается абстрагироваться от ненадёжной сети полностью, но иногда эта сеть все-таки просвечивает сквозь дыры в абстракции, так что абстракция не всегда защищает от необходимости иметь дело с глубокими подробностями. Это всего лишь один пример того, что я назвал Законом Дырявых Абстракций:

Все нетривиальные абстракции дырявы.

 

В абстракциях обнаруживаются дыры. В одних немного, в других целая куча. Эти дыры постоянно просвечивают, протекают, абстракции не срабатывают.

  • Простой пример: итерация по большому двумерному массиву может идти с совершенно разной скоростью, смотря как он обходится: горизонтально или вертикально. Как и в случае с поленом, которое легче раскалывать вдоль волокна, а не поперёк, одно направление может вызывать значительно больше отказов памяти, чем другое, а отказы обслуживаются долго. Даже программистам на ассемблере приходится делать вид, что у компьютера большая плоская память, но в системе виртуальной памяти это всего лишь абстракция, в которой при отказе памяти образуется дырка, так что отдельные обращения к памяти могут занимать значительно больше наносекунд, чем обычно.
  • И ещё: несмотря на дворники, мощные фары, крышу и обогреватель, которые защищают (абстрагируют) от непогоды, под дождём быстро ехать нельзя; приходится иметь дело с водяной подушкой, а иногда ливень такой, что на дороге ничего не видно, и надо остановиться; так что и погоду, из-за закона дырявых абстракций, полностью не абстрагируешь.

 

Закон дырявых абстракций означает, к сожалению, что абстракции не так сильно упрощают нашу жизнь, как хотелось бы. Если я обучаю программистов C++, было бы здорово, если бы мне не нужно было рассказывать им про char* и арифметику указателей, а можно было сразу перейти к строкам из стандартной библиотеки темплейтов. Но в один прекрасный день они напишут "foo"+"bar", и возникнут странные проблемы, а мне придётся всё равно объяснить им, что такое char*. Или они попытаются вызвать функцию Windows с параметром типа LPTSTR и не смогут, пока не выучат char* и указатели и Юникод и wchar_t и хедерные файлы TCHAR — все то, что просвечивает через дырки в абстракциях.

 

Из-за закона дырявых абстракций вот что получается: придумает кто-нибудь чудесный новый генератор кода, с которым у программиста работа наконец-то станет эффективной, а ему и говорят: «Сперва научись делать это руками, а потом уж пользуйся генератором, чтобы сэкономить время». Генераторы кода, абстрагирующие разработку кусков кода, так же дырявы, как и все прочие абстракции. А единственный компетентный способ залатать эти дыры — выучить, как работают абстракции, и какие подробности они скрывают. Итак, абстракции экономят наше рабочее время, но НЕ экономят учебное время.

Отсюда парадоксальное следствие: в то время как инструментарий программиста забирается на всё более высокие уровни сложности со всё более развитыми абстракциями, подготовить высококвалифицированного программиста становится всё труднее.

 

Десять лет назад можно было мечтать, что на сегодняшний день новые компьютерные концепции облегчат труд программиста. И правда: созданные за эти годы абстракции позволяют работать с проектами на порядки более сложными, чем десять или пятнадцать лет назад, типа программирования GUI и сетевого программирования. Но хотя замечательные инструменты, вроде современных объектных языков визуальных форм, позволяют сделать много и очень быстро, вдруг в один злосчастный день приходится искать течь в абстракции, и на это уходит пара недель. А когда вам нужно найти себе программиста в основном на Вижуал Бэйсике, совершенно недостаточно нанять программиста только на Вижуал Бэйсике, потому что каждый раз, когда абстракции Бэйсика потекут, он не сможет сделать ни шага.

Закон дырявых абстракций крепко держит нас за штаны.

 

Часть 2. Опасность обучения на Java

Java в целом недостаточно сложна, чтобы отделить отличных программистов от посредственных. Более того, факт того, что Java не сложен, это особенность, а не ошибка — но это ведёт к проблеме, о которой мы поговорим чуть ниже.

Есть две вещи, которым традиционно учат в университетах в курсе компьютерных наук (Computer Science, CS) и которые многие люди никогда полностью по-настоящему так и не понимают: указатели и рекурсия. 

В самом начале обучения в колледже вы проходите курс структур данных, со связанными списками, хеш-таблицами и прочими мелочами, с широким использованием указателей. Такие курсы довольно часто используются как курсы для отсева: они так сложны, что все, кто не обладает мыслительными способностями, необходимыми для CS, бросают, и это очень хорошо, потому что если вы думаете, что указатели сложны, то подождите пока вам не придётся доказывать факты теории неподвижной точки.

Все те юные гении, которые в старших классах школы писали на Бейсике пинг-понг для Apple II, поступают в колледжи, выбирают CompSci 101, курс по структурам данных, и когда сталкиваются с работой с указателями, их мозги просто взрываются, и они решают перевестись на политологию, потому что теперь правовая школа кажется им лучшим выбором. Я много раз видел графики отсеивания студентов с курсов CS, и обычно процент выбывших составляет от 40% до 70%. В университетах склонны считать это разбазариванием; я думаю, что это просто необходимая естественная отбраковка людей, которые просто не смогут быть счастливы или успешны в карьере программиста.

Эй, в 1900 г. латынь и греческий были обязательными предметами в колледже, не потому, что они были как-то необходимы в жизни, но потому, что их знание было одним из обязательных признаков образованного человека. В некотором смысле мои аргументы не отличаются от тех аргументов, которые приводили сторонники латыни (все четыре). «[Латынь] тренирует ваш ум. Тренирует вашу память. Распутывание предложений на латыни — это отличное упражнение для ума, настоящая интеллектуальная головоломка, и хорошее введение в логическое мышление», писал Скотт Баркер (Scott Barker). Но я не смог найти ни одного университета, который до сих пор преподаёт латынь в обязательном порядке. Неужели указатели и рекурсия — это латынь и греческий компьютерных наук?

Итак, я легко соглашусь с тем, что программирование указателями сегодня не является необходимым в 90% разработки кода, и даже представляет опасность в промышленном коде. Да. Прекрасно. И функциональное программирование не так уж часто используется на практике. Согласен.

Но это все ещё важно для некоторых из самых восхитительных программных разработок. Например, без указателей вы никогда не сможете работать над ядром Linux. Вы не сможете понять ни строки кода Linux или любой операционной системы без реального понимания указателей.

Без понимания функционального программирования вы не сможете придумать MapReduce — алгоритма, который делает Google столь хорошо масштабируемым. Термины Map и Reduce пришли из Lisp и функционального программирования. MapReduce понятен любому, кто помнит из своего курса, эквивалентного 6.001, что истинно функциональные программы не имеют побочных эффектов и поэтому легко распараллеливаемы. Очень показателен тот факт, что в Google изобрели MapReduce, а в Microsoft нет, и это говорит кое-что о том, почему Microsoft до сих пор играет в догонялки, пытаясь заставить работать основные функции поисковой машины, в то время как в Google перешли к следующей проблеме: построению Skynet(стирает) величайшего в мире параллельного суперкомпьютера. Я не думаю, что Microsoft действительно понимает, насколько они отстали на этом пути.

Но даже вдали от задач, где важность указателей и рекурсии очевидна, их реальная значимость в том, что создание больших систем требует той гибкости мозга, которую вы получаете при их изучении, и тех способностей мозга, которые были вам необходимы для того, чтобы не вылететь с курса во время обучения. Указатели и рекурсия требуют от человека определённых способностей: рассуждать, абстрактно мыслить, и, что особенно важно, видеть проблему на нескольких уровнях абстракции одновременно. Поэтому способность понимать указатели и рекурсию напрямую связана со способностью быть сеньорным программистом (а ведь именно к этому мы якобы стремимся). Необходимы тренировки, чтобы научиться думать на нескольких уровнях абстракции одновременно, что является абсолютно необходимым для проектирования отличной архитектуры программного обеспечения.

 

Заключение

Мы с вами говорим про то, что люди идут учиться быть программистами. И часть из идущих просто не способны ими стать. Многих проблем можно было бы избежать, поняв это в самом начале своей первой, второй или N-ной карьеры. Некоторые могут наивно считать, что это легко — ведь достаточно всего лишь закончить 2-5 недельные курсы какого-либо языка программирования и вот он успех! В краткосрочной перспективе — может быть. В долгосрочной — совсем не факт. Статистика собеседований в одну из крупнейших IT-компаний Украины говорит о том, что нанимают примерно одного разработчика из десяти. Причем технический фактор имеет минорное (совершенно не важное) значение в долгосрочной перспективе — то есть если вас берут не закрыть срочную дыру, а на длительную работу. И вот тогда-то все решает человеческий фактор — ваши навыки и качества.

Удачи вам в выбранном пути! Пусть он будет тем самым, который приносит вам удовольствие, радость творчества и успех!

по материалам статей Джоэля Спольски

Comments

comments

Добавить комментарий