Я начинал эникейщиком – “Ваня, сделай всё”. Слов DevOps и Platform Engineer тогда ещё не существовало в обиходе. Инженерный мир выглядел довольно просто: есть техническая проблема, надо найти правильный инструмент и реализовать “то, что надо”.
Чем дальше я рос, тем чаще выяснялось, что корни самых дорогих ошибок вообще не лежат в коде. Они возникают раньше: когда мы неправильно поняли задачу, договорились непонятно о чём, выбрали красивое/популярное решение или просто затыкали плохо организованную работу одним героем.
Ниже не “советы для начинающих”. Скорее подмножество набора граблей, за которые я платил временем, переделками, нервами и здоровьем. И одна ошибка, от которой мне повезло увернуться.
1. Проблема, которая кажется технической, часто находится в договорённостях между людьми
Серьёзно. Мы – люди – понимаем происходящее вокруг намного меньше, чем это выглядит со стороны, и даже меньше, чем нам самим кажется. Такой рассинхрон в договорённостях всегда сильно влияет на любой проект – от неправильных стратегических решений до неудачных мелких прикладных выборов.
На заре AI-ажиотажа вообще все со всеми договаривались непонятно о чём. CEO стартапов хотели “AI, который всё сделает”. На вопросы “для чего?” и “что именно эти агенты должны делать?” отвечали примерно так:
“Агента. Надо построить агента. Агентов..? Мультиагентов!!!”
Мы пять лет делали API-first, теперь надо всё это “запихнуть” в AI. Совершенный делюр и неадекват. Незабываемый.
Запрос оказался слишком сложным. Модели тогда были слабее, tool calling – глупее, а без проблем засунуть столько функций в одного агента было невозможно. Переделывать приходилось всё, минимум три раза. А в итоге оказалось, что большинство этих функций вообще не нужны.
Я почти с первого дня говорил об этом. Но тогда я думал: “Они меня не слышат, не слушают, не понимают”. На самом деле я просто не умел говорить на языке менеджеров – на языке их ценностей, боли и интересов.
Хотя и до AI-мира приходилось чуть ли не по каждой задаче уточнять: что именно нужно сделать? Устаревшая или отсутствующая документация – это тоже недоговорённость. Плохая организация команд и зон ответственности – тоже.
Теперь я всегда помню, что у моего собеседника есть роль и картина мира этой роли, есть предметы интереса и язык. Я стараюсь говорить на языке собеседника настолько, насколько могу, докапываюсь до сути, ищу способы договориться и убедиться, что мы говорим об одном – и что это “одно” связано с реальной бизнес-потребностью.
2. Архитектуру нельзя выбирать лишь потому, что она стильная-модная или интеллектуально привлекательная
Речь на самом деле не только об архитектуре. Любой компульсивно-эмоциональный или “племенной” выбор – это откровенный позор.
Мне нравится X, потому что Y плохой. Или потому, что Y разрабатывают “не те” люди. Я никогда не буду работать с X, потому что много раз видел/слышал/читал, как это доставляло проблемы в проектах.
Я буду использовать Y просто потому, что мне нравится, ну вот так вот я хочу, мне “приятна” эта технология.
Или вот: мы будем делать “так”, потому что “так” делает Google/Netflix/whatever. Вот это последнее – вообще сущий кошмар.
Я никогда не забуду распределённые монолиты в кластерах Kubernetes, которые делали для бизнеса, у которого никогда не могло быть больше 200–300 RPS в пике просто из-за модели самого бизнеса.
К моему счастью, это был не мой выбор. Я думаю, что вряд ли когда-то выбрал бы Kubernetes для того проекта. Но я обслуживал последствия: огромный ворох ненужных over-engineered зависимостей и техдолга. Мы платили постоянной бесполезной работой – обслуживали эти зависимости и боролись со сложностью вместо того, чтобы решать реальные задачи.
Тогда это доказало мне, что я всё-таки неплохой инженер и понимаю, насколько важна связь архитектуры с реальностью и требованиями. Насколько важно провести аналитику, спрогнозировать нагрузку системы и только потом синтезировать решение.
Кумулятивный эффект слишком большого количества неправильных архитектурных решений буквально разрушает всё в организации – от расходов на инфраструктуру и топологии команд до скорости разработки и успеха всего проекта.
Теперь для меня порядок такой: реальность и требования -> аналитика -> прогноз нагрузки -> синтез решения.
3. Коллекция фреймворков не заменяет развитого мышления
Это не ошибка, на которой я обжёгся. Это ошибка, от которой мне повезло увернуться.
Ещё 6–7 лет назад я думал: “Сколько всего интересненького и полезного!”
Сколько языков программирования, разных баз данных, методологий и прочего, прочего, прочего. Всего не перепробовать и не узнать! Играть в кубики – норма индустрии. И мне тоже хотелось играть в эти кубики.
Благодаря моему ментору я не потратил слишком много времени на всё это – у него был буквальный запрет: или учишься у меня, или ууу.
Польза в насмотренности на разные прикладные технологии, конечно, есть. Но не выходить за рамки этого уровня – dead end.
По-настоящему “зуд на интересненькое” пропал у меня лишь тогда, когда я на практике увидел, насколько окупается вложение в сильные методы мышления и построение у себя в голове “машинки типов”.
Опытные программисты всегда отвечают на джуновский вопрос “какой мне ЯП учить” как-то так: “Учи не ЯП, а учись программировать”. Вот тут примерно то же самое, только чуть выше уровнем абстракции. Пропитывание мозга концепциями из учебников по программной инженерии, функциональной парадигмы и релевантной математики повлияло на ход моего мышления, рабочие решения и жизнь вообще невообразимо сильнее, чем сотни рандомных гайдов из интернета.
Все дивные инструменты после этого никуда не исчезли. Просто перестали быть целью и топливом для развития.
4. Сильные специалисты не компенсируют плохо спроектированную коллективную работу
Я долго верил в обратное: сильные специалисты могут долго и хорошо всё “вытягивать”. В большом проде и особенно вдолгую это никогда не работает.
Я прочувствовал это на собственной шкуре – не как менеджер со стороны, а как тот, кого пытались поставить в роль “терминатора”. Моей ошибкой было радостно в эту роль становиться.
Ну это же круто! Очередь к тебе. Все ждут. Ты в ужасном зарубе: десять контекстов параллельно, почти нигде нет нормального handoff, зато везде есть “ну ты же разберёшься, ты крутой молодец!”.
Для меня эта роль закончилась серьёзными проблемами со здоровьем. Если бы я не остановился, всё было бы ещё хуже. Именно тогда я понял: это поломка системы, так работать нельзя в принципе.
Выгорание не из-за “сложного кода”, а из-за того, что через одного человека течёт слишком много.
Боттлнек – ты. Или соседний “герой” – это не важно. Тут проблема чисто в биологическом ограничении, с ним почти бесполезно бороться: через людей столько не проходит без влияния на качество работы.
Я давно не IC в найме, и никто уже не может сделать меня единственной точкой прохождения работы в вышедшем в прод проекте. Пусть сейчас я и founding engineer в новых стартапах, моя роль именно в том, чтобы собрать prod-ready MVP и спрогнозировать нагрузку не только на систему как продукт, но и на систему, которая будет дальше этот продукт создавать. Чтобы нанять подходящее количество подходящих сотрудников.
Хорошего миддла или сеньора – разработчика, девопса, тестировщика – найти намного проще, чем двух T-shaped единорогов, которые потащат всё и сразу на хорошем уровне. И будут тащить, тащить, тащить… Пока не сдохнут.
5. Я слишком поздно научился проверять, существует ли вообще задача, которую собрались решать
Очень легко принять чьё-то уверенное и громкое “надо” за факт. Особенно: “Ой, ну надо вчера было, блин! Меня сверху давят!”
Надо написать новый сервис, переписать старый, автоматизировать X. Добавить AI туда тоже надо, помните?
В одной B2B-компании нам продавили чрезвычайную срочность: вокруг нашего B2B-продукта надо было построить… B2C-продукт. Это был ужасный аврал.
Пользователей у новой платформы в итоге оказалось – ноль. Её вообще никому не смогли продать.
А потом “вдруг” выяснилось, что исходную проблему сформулировали криво. Или её можно было решить в десять раз проще.
Или она вообще существовала только в чьей-то голове, но никто не догадался вовремя переспросить: какой эффект мы хотим получить в реальности, с чего мы взяли, что для этого нужно делать именно вот это, и почему прямо сейчас?
Для инженера, который занимался реализацией “этого”, наверное, нет почти ничего более поганого. Ты тратишь время и силы, а в итоге система, которую ты собрал, никому не нужна, никто ей не пользуется.
Ну, так получилось! И мало кто признает: “Извини, это провал аналитики/продаж/маркетинга, организации работ…”
Теперь я не просто задаю вопросы до начала реализации. Я исследую домен, в котором мы начинаем работать. В какой среде вообще будет существовать проект? Какие агенты в этой среде работают, чем они занимаются, какие у них интересы? Какую выгоду им даст наш продукт и чем эта выгода спрогнозирована?
В общем и целом, в моей работе стало очень много системного подхода – от начала и до конца.
Лучший код – тот, который не пришлось писать. Но чтобы его не написать, нужно уметь остановить коллективный разгон и расковырять основания, на которых всё это “надо” появилось.
Это намного сложнее, чем тупо начать фигачить. Особенно сейчас, с AI-агентами.
Я слишком много раз видел, как умные люди отлично решали задачи, которых не существовало.
Что я теперь проверяю перед большим техническим решением
- Мы одинаково понимаем, что сейчас происходит? Если попросить участников пересказать задачу своими словами, они опишут одну и ту же реальность?
- По каким критериям мы выбираем решение? Что у нас есть, кроме вкуса, привычки, “так делают гиганты” или “так написали в Twitter”?
- Какими методами мы думаем над задачей? Мы разбираемся в системе или перебираем знакомые инструменты?
- Сможет ли этот проект жить без двух незаменимых терминаторов, через которых проходит вообще всё? Мы закрыли все роли и понимаем, сколько подходящих сотрудников понадобится?
- Какой эффект мы хотим получить в реальности – и нужно ли для него делать именно ту работу, которую мы собрались делать?
Если внятного ответа хотя бы на один вопрос нет, молча двигаться дальше нельзя. Сперва приходится докапываться до реальных намерений и боли людей, проверять предпосылки и точно определять саму проблему.
Иногда после этого реализовывать уже нечего. Чаще решение оказывается проще, чем казалось “на входе”.
И да, не написать ни строчки кода иногда тоже вполне себе успешный результат инженерной работы.