Разработка ПО в 2023 году
Friday, 3 Nov 2023
Меня подзуживало назвать этот текст «пять мифов», чтобы полностью слиться в экстазе с тем говном, которое льется в уши добросовестного читателя в последнее время, но показалось, что это будет перебор.
Я пишу код с 1986 года, когда мой алгоритм Эвклида на фортране завелся с третьего раза с перфокарт на ЕС-1060. С тех пор я писал на таком количестве разных языков, что уже потерял им счет. За примерно дюжину — мне платили деньги. Всю жизнь я старательно избегал любых руководящих ролей, но генеральные директоры оказывались проницательны, и спустя некоторое непродолжительное время я обнаруживал у себя в прямом подчинении каких-то людей. Я хотел писать код и не особенно мечтал общаться с себе подобными.
Самым большим комплиментом, который мне довелось услышать за всю жизнь, оказалась случайно брошенная Ромой Ивановым фраза, когда на каком-то собрании, посвященном перспективам развития продукта в Яндексе (это был единственный случай в моей карьере, когда в зарплатной ведомости моя должность содержала слово «менеджер»), я начал углубляться в технические детали реализации и кто-то махнул рукой: «Да какая разница, не ты же это будешь реализовывать!». Роман крякнул и громко пробормотал: «Этот? — Этот будет.»
Когда в моей нынешней конторе разбушевался отдел кадров и нам было предъявлено требование: за такую зарплату у этого человека должна быть своя команда, CTO в который раз пошел мне навстречу и теперь я официально возглавляю «Aleksei Team», состоящую из одного человека.
За то время, пока я нажимаю кнопки на клавиатуре за еду, сменилось несколько эпох. У чужого кода появилась какая-никакая документация. Расплодились языки программирования, написанные умными людьми, профессионалами своего дела, облыжно полагавшими, что программист — по умолчанию неглуп, и ему нужно предоставлять как можно больше возможностей. Перл, руби, даже питон были созданы для того, чтобы сделать процесс написания кода — увлекательным, а выразительные возможности программиста — практически бесконечными. Это существенно снизило порог входа в профессию и породило кучу мастеровых, которые буквально добивались результата методом случайного тыка. Когда удельная масса дурачков в профессии превысила любые мыслимые пределы, надо было что-то делать, и самые дальновидные придумали максимально затруднить создание нерабочего кода: так появились тесты, а вслед за ними и типы (в тех языках, в которых они нахер не нужны).
Матц создавал язык, в котором программисту не будет препятствовать буквально ничего, и именно за это так любят руби адепты (к числу которых я принадлежу). Но такой подход хорошо работает только при условии высокой квалификации разработчика. К сожалению, в современном мире на нее полагаться нельзя никак, поэтому внятный и довольно интересный идейно джаваскрипт — оброс тяжеловесным и бессмысленным тайпскриптом. Питон — чертовыми аннотациями, которые не влияют буквально ни на что. Перл просто забыли, потому что почти неограниченная мощность его синтаксиса требует слишком значительных когнитивных усилий. PHP жив только благодаря фейсбуку.
Среди всего этого мракобесия люди с претензиями вытащили из пыльного чулана Haskell (с которым мне довелось работать в 2000–2002 гг. и который в результате погубил наш тогдашний проект из-за отсутствия зависимых типов). На дворе 2023 год, зависимых типов так и нет, что делает выбор Хаскеля довольно спорным в любом проекте, из-за отсутствия ярко выраженных плюсов и огромного числа не менее ярко выраженных минусов (что, в принципе, никогда не скрывалось авторами: язык учебный, пробный, «avoid success at any cost», и так далее). Idris, идеологически абсолютно верный, — оказался слишком сложным для дисфункциональных пижонов и пилится автором фактически в одно лицо.
Еще, пока мы семимильными шагами двигались в светлое будущее, команды поддержки языков никак не отреагировали на полностью изменившуюся парадигму использования. Пока сообщество хором вколачивало клинья типов между подогнанными бревнами кода и добивалось стопроцентного покрытия тестами, компьютеры стали многоядерными, а сеть — доступнее, чем жесткие диски.
В современном мире не нужны быстрые алгоритмы (потому что затык, скорее всего, будет в другом месте). Не нужны микрооптимизации (потому что докинуть памяти — дешевле, чем отлаживать ассемблерную вставку). Становятся бессмысленными подходы и практики, тянущиеся за нами из прошлого века, наподобие правильного именования переменных и разбиения кода по модулям.
Зато на вес золота становятся люди, понимающие вектор развития прикладного программирования и умеющие писать код, масштабируемый во все стороны простым подключением новых мощностей. Внезапно оказалось, что такие люди существовали и в эпоху допотопных компьютеров; диссертация Джо Армстронга содержит все, что нужно понимать про проектирование отказоустойчивых распределенных систем, а erlang — все, что требуется для написания такого кода.
Я часто слышал от разных людей, что синтаксис эрланга …эмммм… немного экзотический. Я решительно не согласен с этим утверждением (как и все остальные гениальные решения, Джо взял его из реальной жизни — он повторяет синтаксис английского языка), но все равно выбрал для своей работы elixir — не из-за грамматики, конечно, но из-за поистине идеально реализованного метапрограммирования. Сравнимо было только в ЛИСПе, но ЛИСП слишком громоздкий и у него ужасная инфраструктура.
Так вот, чтобы этот текст не казался огульным восхвалением эликсира (чем он является на самом деле, но я хотел бы этот факт скрыть) — приведу четыре самых главных, на мой не слишком уж дилетантский взгляд, — навыка, востребованных в 2023 году.
- умение гарантировать отказоустойчивость при наличии багов в коде;
- умение дробить целое на частные и реализовывать малые части большой системы в полной изоляции друг от друга;
- умение проектировать ПО таким образом, чтобы в первой версии не было ни единой строки «в расчете на будущие изменения», но будущие изменения не затрагивали существующий код никаким образом;
- умение сразу делать горизонтально масштабируемое решение, не добавляя специального кода для этого в первой версии.
Вот, пожалуй, и все. А все эти алгоритмы, оптимизации, расход памяти… — ну, лучше, если вы умеете оценить алгоритмическую сложность и не ходить внутри списка туда-сюда вложенными циклами. Наверное, O(n⁵)
лучше избегать прямо сразу. Но добиваться O(log(n))
вместо O(n)
— не нужно практически никогда, а если нужно — наверняка существует работающая реализация. «Нельзя зачитывать всю таблицу в память!» — как-то сказал мне с ужасом коллега. Я его спросил: «Почему?». — «Там может быть миллион записей!». На тот момент записей там было примерно пятьсот, и каждая не превышала по размеру килобайт. Я махнул рукой: «Да хоть миллиард, у нас на этой машине 120 гигов оперативы; уткнемся в отказы — добавим пейджинг».
В моем коде уже была функция get_page(from = 0, count = -1)
, которая всегда возвращала всю таблицу. Ей уже четыре года, и она когда-нибудь будет имплементирована посерьезнее. Году в 2037.