Почему решая литкод ты никогда не станешь архитектором (но на самом деле никогда не хотел им быть)
Специальный выпуск для linux.org.ru.
Когда я был юношей, то они мне говорили «вырастешь — поумнеешь». Я вырос, но не поумнел. Но иногда я жалею, что не знал тогда того, что знаю сейчас — так и хочется написать тому юноше письмо из будущего, что я и намерен импровизировать в виде треда на LOR.
Среди взрослых людей есть довольно ярко выраженная дихотомия в способе принятия решений: люди, которые знают решение, и люди, которые это решение всегда способны найти за достаточно продолжительное время; те, кто ни за что не признают ошибку, и те, кто ошибаются на регулярной основе даже если уже знают решение; те, чей максимальный интервал принятия решений составляет «между двумя глотками смузи» (ведь «моё время дорого стоит»), и те, кто тщательно выстраивает цельную картину проблемы и неспешно обсасывают ее со всех сторон.
Поскольку первых людей сильно больше, чем вторых (соответственно спросу), то массовый программист, как правило, оценивается по тому, как много решений он может выдать между двумя глотками смузи. Индустрии нужно зарабатывать деньги на массовом конвеерном фуфле, индустрии не нужны оригинальные решения. Как решить большую сложную задачу на подобном конвеере? Взять больше смузи и хлебать чаще, посадить дополнительных смузихлебов на тестирование этого дела. Самое страшное — когда в подобном духе начинает работать Boeing, и самолеты начинают падать. Можно радоваться тому, что упал не ваш самолет, а можно подумать о том, что завтра ваше авто с вами за рулем может внезапно оказаться не ваше, потому что его хакнет 7-летний китайский ребенок, и единственная реальная защита — это тот факт, что Илон Маск платит всем денеги только чтобы уязвимостями в автомобилях и инфраструктуре не пользовались злоумышленники.
Мне вспоминается старый-престарый эпизод моей жизни, как я еще будучи школьником выиграл олимпиаду по информатике. Задача была на поиск кратчайшего пути (пардон, точного условия уже не помню, это было давно и неправда). Грамотный программист быстро выдаст вам «правильное» решение O(N log N) по алгоритму Дейкстры. Но поскольку на тот момент я не знал алгоритма Дейкстры и не был грамотным программистом, то вместо «правильного» решения выдал асимптотику O(N), заэксплуатировав некоторые особенности конкретных условий той задачи.
И второй эпизод, современный. Меня выбесило одно из недавних моих собеседований: некая контора дала мне тестовую задачку, являющуюся также одной из фундаментальных задач, решаемых их продуктом. Мне просто забыли сказать, что «правильный» метод должен быть O(N^3), и я случайно потратил целый день на разработку метода O(N^2), который оказался настолько неожиданным для «сеньоров», что им понадобилась целая неделя для анализа моего решения на 500 строчек (inb4: фу-фу, лапшемес), а на собеседование со мной собрали всю верхушку — на минуту у меня сложилось ощущение, будто меня собеседуют в гугл, а не в местную помойку. Я не удивлюсь, если вся их шарашка уже работает над интеграцией моего метода, и в скором времени получит премию, мол «наш отдел провел тщательные исследования предметной области...», а тебе, мартыха, хрен с маслом. И это собравшееся начальство на собеседовании было серьезно намерено развести меня на решение еще одной важной для их помойки задачки. Большая часть их штата джуно-мидлов занимается обвязками-прокладками-интерфейсами-тестированием, короче говоря, теми задачами, под которые можно нанять горсть рабов с улицы хоть прям щас — но эти люди в жизни не смогут выдать оригинального решения, а только будут ждать команд сверху.
Вишенка на тортике — под конец мне дали задачку с литкода, которая была будто специально подобрана так, чтобы быстрое решение требовало от меня знание специфичных фич стандартной либы, которое я им изначально честно заявил как «слабое». Те функции выучиваются наизусть за пару дней, а аналитическое мышление развивается годами, но нет «ты слабоват, мы можем тебя взять, но на ЗП в два раза меньше». Вот так вот: «не подскажешь, как пройти к вокзалу?... А теперь встань раком и вези меня туда».
Что мы всё про меня да про меня. С точки зрения массовой индустрии Дуглас Крокфорд — посредственный программист, и в недавнем треде большое число отписавшихся доходчиво пояснило, почему это так. Да, подумаешь, он создал какой-то там JSON, на котором работает половина индустрии, а еще создал JSLint, который ведь оказался так себе и был вытеснен ESLint-ом, и вообще «я могу сделать лучше, просто оно мне не надо». Но печальная истина в том, что тысячи смузихлебов писали на JS безо всякого линта, и, я уверен, при возникновении онного долго противились новой технологии. Проходит время, и вот уже каждый школьник считает своим долгом задействовать ESLint и JSON, а пишет, естественно, на ES2015, добрая половина фич которого была реализована при непосредственном участии Крокфорда (кстати, мало кто знает, что Object.keys/Object.values еще в ES5 было внесено по инициативе Крокфорда) — но этот школьник понятия не имеет, откуда взялись «мои любимые технологии».
Я хочу подчеркнуть, что это не одиночный пример мнения отдельной макаки — это закономерность, которую заметил не только я, и не только эту. Такие люди, как Крокфорд, могут бесконечно выдавать оригинальные идеи, но как исполнитель они так-себе, у них вечно шило в попе, толкающее на приключения, потенциально грозящие сорвать сдачу проекта (которая назначена на вчера, как обычно). Я задумался: а кому могут быть в самом деле нужны такие люди? Да, в силиконовой долине можно себе пригреть местечко — по этому пути успешно прошелся Крокфорд. А что делать, если я не хочу развивать силиконовую долину? Я в молодости отказался ехать туда, и сейчас не особо горю желанием (но и не предлагают уже). Вот такое вот я капризное животное.
Более того, если допустить, что Крокфорд выдал некое супер-пупер классное решение для вашей фирмы, то возникает проблема — кто его будет поддерживать/развивать? А также так называемый Bus factor — что делать, если Крокфорда убьют Крокфорд уйдет? Типовой сеньор-помидор, посмотрев на код Крокфорда, выпучит глаза и закричит «ты где такое видел? Кто так делает? У тебя своя голова на плечах есть?».
Всё ли так безнадежно, и есть ли более-менее прикладные задачи, которые не сможет решить сеньор-принципал-архитектор даже в обнимку с цистерной смузи, даже выдавая по два заученных решения литкода в секунду? А может быть и есть. Например, быстрой инкрементальной Agile Scrum Kanban Fast-shipping Test Driven методикой постепенной разработки невозможно реализовать распределенную отказоустойчивую БД со строгой согласованностью данных. Отказоустойчивость — это бинарное свойство, БД либо отказоустойчива, либо нет. Не бывает почти отказоустойчивой приблизительно распределенной БД которая чуть ли не сохраняет все подтвержденные транзакции (привет разработчикам MongoDB). Ну то есть она в таком случае не отказоустойчива и не дает гарантий.
Даже Clickhouse можно почти сделать при достаточном стратегическом запасе смузи (только для единственного хоста), но яндекс так и не осилил аналога ZooKeeper (кластер ClickHouse работает через ZooKeeper), поскольку никакое количество костылей, инкрементально разработанных в Яндексе ранее, так и не смогли заменить одного грамотно продуманного решения. Что мы по итогу видим сейчас? Вся инфраструктура Яндекса стоит на ZooKeeper, найди возможность положить ZooKeeper — весь Яндекс встанет колом. Тот же Facebook тоже полагается на ZooKeeper (хоть и меньше, они там саги любят). В Amazon вообще всё печально, и я не поверю, что с любым количеством денег Amazon способен создать аналог ZooKeeper, поскольку я читал статьи их отдела по исследованию распределенных систем, и уровень там совершенно никакущий. Достоверно мне известна ровно одна контора, способная разрабатывать распределенные СУБД с гарантиями согласованности — это Google. Она разработала самое первое подобное решение, Google Chubby, близкой копией которого позже стал ZooKeeper.
Но вот в чем проблема — ZooKeeper уже есть, а значит «ты нам не нужен». Что же еще требует глубокого вдумчивого погружения и нестандартной находчивости? Похожие требования есть у многопоточных приложений. Еще подобного рода мышление нужно при тяжелой глубокой отладке софтины, на отладку которой систематически забивали, предпочитая спринты и быстрые релизы. Правда, с распространением защищенных сред выполенния, вроде JVM, CLR, JS, и Python, неустранимая потребность в отладке сильно снизилось, потому что в крайнем случае можно просто перезапустить контейнер или иметь запасные контейнеры сразу. (Еще есть UI/UX, но про мертвых либо хорошо, либо ничего).
Второй отягчающий фактор — обычно такие вечные дети-экспериментаторы любят знать всё про всё. Следствие — редко можно встретить такого экспериментатора, который знает единственную тематику очень-очень глубоко, как того требует конвверное производство софта. Например, я проектировал и собирал аналоговые схемы, я проектировал и моделировал логические схемы, изучал устройство процессоров и проектировал микроконтроллеры, в конце-концов начал работать программистом, вплоть до самого высокого уровня динамических языков программирования. Я знаком с компьютерами сверху донизу, но эти общие знания не помогают получить теплое место у конвеерной ленты (о чем я был давно осведомлен и систематически игнорировал этот фактор).
Третий отягчающий фактор — вечно детскими глазами не получается избавиться от «о боже, это срань, этим невозможно пользоваться». Вы могли заметить, что я довольно много писал на Си, но не потому, что мне так нравится этот язык — он просто чуть менее страшный и подходит для моих задач, в остальном же нет особой разницы, из чего лепить свою софтину.
Парадокс в том, что смузи-мастеры чуть ли не поголовно мечтают быть творцами. Какой смысл этого стремления? «Хорошо там, где нас нет»? «Полчаса побунтовал - и фатит»? Прежде чем окончательно и бесповоротно решить встать на этот путь, посмотрите на настоящих успешных творцов (не путать с клоунами вроде меня или Илона Маска). Такие люди не заработают заоблачных денег, их не расхватывают на рынке труда, им не так просто устроиться на обычную должность, а даже если устроятся — умрут со скуки, попутно занимаясь ремонтом того, что не ломалось, таким образом выведя из строя какой-нибудь старый добрый сервис на Cobol или MUMPS, написанный в 70-х годах «настоящими программистами, настоящими, не то что новое поколение».
Показательно, что работодатели идут навстречу этому стремлению, мол «пишешь конфиги для CI/CD? Ну ты же архитектор теперь». Аналитический склад ума нельзя поменять за месяц, его нельзя быстро приобрести или положить на полку на период отпуска. Wannabe-творец-на-выходные в лучшем создаст популярный клон существующего софта — даже не потому, что не способен ни на что другое, а потому, что понимает, что сообщество не примет ни одной значимой инновации серьезнее плагина к Emacs или очередных скрипт-костылей для сборки C++. Да и то, плагины к Emacs не нужны, поскольку уже есть настоящее проверенное решение в виде Vim и его аналогов.
И я не могу упрекать работодателей (как правильно заметил Kogrom по ссылке выше): им нужна взаимозаменяемость и предсказуемость, им нужно снижение рисков и издержек; им нужен посредственный сайт, который будет создавать иллюзию наличия этого сайта у компании — а больше и не нужно; заказчикам нужна иллюзия масштабирования и отказоустойчивости, с бессмысленными невыполнимыми требованиями к системы — выдайте ему микросервисную архитектуру со стоимостью и временем разработки в 3 раза больше грамотного монолита, также бонусом дайте ценные инструкции по масштабированию бигдата-серверов монги сверх 500 ГБ (на случай, если его бигдата размещается в кластере из айфонов). Можно упрекать разве что себя (мне — себя, а вам — себя, не меня). Например, много лет назад я имел возможность выбрать семью и карьеру, но я выбрал то, что выбрал — не иметь власти, но знать всё и ничего одновременно. В этом есть свой кайф и неудобство одновременно.