Все мы знаем истории о программистах — рок-звёздах. Свои первые деньги от первого сайта она заработала в 11 лет. Закончила колледж в 16 лет; открыла LLC в 17; заработала миллиард в 23... Мы любим эти истории, их героев; они вдохновляют нас плодотворным программированием и своим умением устанавливать тенденции. От решения NP-полных задач и до того, чтобы зарабатывать миллионы, кажется, они никогда не ошибались на своём пути.
Но реальность такова, что все разработчики, даже рок-звёзды, ошибаются! И преодолевают неудачи. Разница только в масштабе: когда мы что-то сломали, повреждаются записи БД, когда что-то ломают они, то это ошибка на миллиард долларов.
Почему же все так боятся ошибок? Ошибаться — это хорошо, нет учителя лучше неудачи. А ещё ошибки приносят с собой стигму. Никто не хочет о них рассказывать. Никто не хочет выглядеть глупцом среди гениев.
У такой сдержанности есть последствия: когда разработчики ошибаются, они воспринимают ошибку как личный провал. Им стыдно, и их часто обвиняют в ошибках: “Майк забыл обновить документацию релиза” или “Билл сделал cherry-pick не той ветки” — и это контрпродуктивно.
Неудачи почти всегда не индивидуальны, они носят системный характер. Как таковые, они представляют собой прекрасную возможность выявить и исправить недостатки бизнеса. Нет учителя лучше неудач, и мы не должны бояться рассказывать о них. Следуя духу сказанного, ниже я откопаю три своих самых жутких промаха в карьере программиста. Затем я расскажу, как вырос благодаря ошибкам и за что я благодарен каждой из них.
Я стёр тысячу URL-адресов
Будучи занятым в крупном финансовом учреждении, я разработал систему очистки от неиспользуемых адресов в сетевом слое F5. Пул маршрутов F5 поддерживал около 5000 URL, не больше, затем происходило истощение. Моя система автоматизировала мониторинг трафика на эти адреса, уведомляла владельцев неиспользуемых ресурсов и начисто очищала их, защищая F5 от падения, а в операции не нужно было вмешиваться руками.
Система отлично работала и успешно использовалась, чтобы удалить несколько десятков маршрутов в окружениях ниже. Однако одним воскресным утром я проснулся от цепочки писем о том, что удалена тысяча маршрутов и пользователи жалуются, что удалённые адреса были задействованы в их работе.
Выходные пошли прахом, а наша команда приступила к действию. Оказалось, что один старый конфиг YAML был развёрнут с контейнером приложения, который удалял маршруты не раз в месяц, а раз в неделю. К счастью, я поставил предохранитель, чтобы предотвратить удаление серьёзных ресурсов в продакшне. Часто встречающиеся отказы приложений в масштабах всей компании скорее всего происходили из-за того, что моя программа удалила активные ресурсы.
Оказалось, что большинство ресурсов, которые были неактивны неделю, остаются неактивными и месяц. Так что в итоге ущерб был управляемым; мы удалили тысячу адресов, но жаловались немногие команды. Однако случившееся стало колоссальным стрессом для меня и моих менеджеров, особенно в самом начале, когда не был ясен масштаб ущерба. Мы создали штаб, перераспределив ресурсы так, чтобы команда могла вручную заново создать потерянные ресурсы.
Как такое могло произойти?
С самого начала я чувствовал, что это моя вина (мои менеджеры с этим согласились — мне это не помогло). Но в ретроспективе провал был системным. Во-первых, большой проблемой был тот факт, что существующая система управления маршрутами F5 не справлялась с потребностями бизнеса, а также не имела чёткой стратегии отката/бэкапа. Более того, старый конфиг зависал из-за неоправданно сложного процесса развёртывания. Он был слишком бюрократичным и склонным к подобным ошибкам. Наконец, с этой важнейшей задачей я остался один на один, то есть без код-ревью и без взаимодействия с командой и с оптимистичным крайним сроком; всё это — рецепт несчастья. Мы никогда не рассматривали эту задачу как первоочередной приоритет, и теперь, имея больше опыта, я понимаю, что провал был неизбежен.
Как неудача помогла мне вырасти?
Я никогда ещё не был так благодарен моим коллегам, как в момент, когда они вмешались и вытащили нас из того месива, что я сотворил. И в то же время я никогда не чувствовал себя настолько растоптанным профессионально, как в тот момент, когда мой менеджер и самый старший разработчик сказали мне, что потеряли веру в меня как в в инженера и не позволят мне продолжить работу в нашем важном проекте. Другими словами, они не могли поверить, что я написал нечто настолько тупое, и не могли доверить мне работу в этом или каком-то другом ключевом проекте. В конце концов, они отреклись от меня.
Как ни стыдно это признать, но я действительно плакал из-за этого. Это случилось позже, когда коллега из команды вытащил меня на пиво. Когда я отдал инициативу в разговоре ему, он сказал, что это было крайне несправедливо, некрасиво и что он и вся команда очень ценят меня. После этого я был подавлен неделю, был просто комком нервов, и кто-то сказал, что это слишком. Мой главный менеджер тоже пригласил меня на обед и помог мне справиться с ситуацией. Эти поступки остались со мной на долгие годы.
Ситуация научила меня тому, что код контролируется чрезвычайно хорошо, а инфраструктура — нет. Крайне важно использовать такие инструменты миграции БД, как DBMate и Terraform, чтобы управлять компонентами системы и рассматривать эти компоненты как равные коду приложения или даже более важные.
Также первостепенную важность имеет ограничение доступа к производственной среде. К примеру, я даже не держу ветку master локально в моей IDE и предпочитаю блокировать все общекомандные пуши, которые делаются напрямую, то есть не в ветку фичи. Учётные записи БД и облаков по умолчанию должны быть доступны только для чтения, а также должны иметь чёткие стратегии резервного копирования и восстановления.
На следующем месте работы разработчик на проде случайно удалил файлы из корзины S3. Если бы не стратегия управления версиями S3, которую я установил всего за неделю до этого (она отключена по умолчанию — что за чёрт, Amazon?!), мы могли потерять её навсегда.
Наконец, последний и самый важный урок, который я усвоил, — это урок эмпатии. Сделать такую ошибку было довольно отстойно, так что куча менеджмента здесь была не нужна и губительна. Что-то такое недавно произошло с моим товарищем по команде: он запустил на проде несоответствующий стандартам код, и нам пришлось вручную корректировать некоторые данные. С виноватым видом он говорил об этом. Я воспользовался случаем, чтобы чётко объяснить причину: наши процессы развёртывания миграции данных ниже среднего. Это был провал нашей команды, а не его личный провал, и это то, что должно было произойти. Я напомнил ему о прекрасных функциях, которые он провернул, и о том, как они важны для нас и для дела. Его ошибка была просто напоминанием о том, чтобы пересмотреть процессы, и это мотивировало его вложиться в решение. Ошибки — это возможности.
Я отправил электронное письмо с кодом за пределы компании
Прежде чем уйти с работы, я отправил свой код по электронной почте.
В работе над библиотеками Spring я провёл почти год и в процессе создал несколько действительно хороших паттернов тестирования. Я не хотел забывать все эти замечательные идеи и планировал написать о них серию постов на Medium. Примерно через месяц, в первый же день моей новой работы, я получил текст, от которого побледнел как никогда:
Чувак, вся команда как ошпаренная. Кто-то отправил код по электронной почте за пределы компании, в деле замешан юрист. Ты знаешь, кто это был?
Я немедленно позвонил моему бывшему менеджеру. Ответа не последовало. Позвонил коллегам. Ответа не последовало. Вмешался юрист и дал компании указание прервать контакт со мной. Это было не просто жутко. Почувствовав неладное, мой новый менеджер спросил меня об этом. В прошлом он был адвокатом и посоветовал мне на всякий случай обратиться к своим бывшим коллегам. Я срочно позвонил семейному адвокату моей жены, и мы обсудили возможные ситуации. Поскольку это был служебный код, было не так вероятно, что “за мной придут”, но всё же это было возможно.
В тот день жена заехала за мной, её настроение было прекрасным. Она спросила, как прошёл мой первый день, на что я ответил: “Кажется, я совершил большую ошибку”.
На её лице засветились нежность.
Когда я рассказал, что произошло, она восприняла это как истинный победитель. Она сказала мне, что, хотя это и вправду глупо, мы это переживём. Всю следующую неделю я жил как в тумане, пока команда юристов из моей бывшей компании не связалась со мной и не передала, что они не будут выдвигать обвинения, если я подпишу соглашение о незамедлительном удалении этого кода.
Как такое могло произойти?
У меня было туннельное зрение — простое и ясное. Хотя это похоже на какой-то гнусный заговор, простая истина в том, что я гордился разработанными мной паттернами и утилитами и думал, что потеряю что-то как разработчик, если потеряю их. У меня была грандиозная идея, что код приведёт к нескольким статьям в блоге, и каким-то образом в моём сознании выгода перевесила риск.
Я по сей день чувствую себя ужасно из-за того, как это повлияло на моих бывших коллег в команде. Эта ошибка была на 100 % моей, но с последствиями должны были разбираться они. Репутация команды, вероятно, была запятнана, и работа с аудитом, должно быть, стала большой проблемой для всех. Ситуация испортила мою профессиональную репутацию и сожгла многие мосты.
Как неудача помогла мне вырасти?
Прежде всего, я стал крайне осторожно относиться к электронной почте в компании и внутренним коммуникациям. С начала моей новой работы не прошло и недели, как несколько сотрудников уволены за неподобающий разговор в личных сообщениях Slack. Дело было довольно грязным — уволили их всех, и в конце концов остальным пришлось пройти обязательное обучение персонала по вопросам домогательств на рабочем месте. Несмотря на то, насколько неумелым может быть технический персонал вашей компании, вы всегда должны предполагать, что они видят всю вашу личную коммуникацию.
Ещё одним замечательным уроком было то, как моя жена и родители сплотились вокруг меня. Я был в смятении и не мог мыслить здраво, их понимание и спокойствие вернули меня в реальность. Я был на грани экзистенциального кризиса — как я, со своей учёной степенью кандидата, мог работать в этой области и быть таким беспечным и глупым? Неужели я только что разрушил своё будущее? Без замечательной поддержки я, возможно, сошёл бы с рельсов и только ухудшил всю ситуацию. Советы и рекомендации по привлечению адвоката остановили меня.
YAGNI (вам это не понадобится) — это не просто софтверный принцип. Неужели я действительно посмотрел бы на этот код ещё раз? Даже если благодаря этому коду получится несколько статей, оправдается ли риск? Нет, чёрт возьми! Когда вы уходите с работы или заканчиваете главу своей жизни, если на то пошло, просто уходите. Ничего не берите с собой, не смотрите в зеркало заднего вида, просто двигайтесь дальше.
Я потерял работу во время Covid-19
В 2019 году я работал в относительно успешном стартапе по модернизации процесса содержания upkeep. Нашим основным источником дохода были местные органы власти, а также венчурные инвестиции. В марте 2020 года оба источника внезапно исчезли. Наша компания несколько месяцев успешно боролась с волной Covid, резко развернувшись на текущие приоритеты клиентов и собрав некоторые средства через фонды помощи малому бизнесу.
Однако к июлю стало ясно: мы или сокращаем штат, или тонем. В 11:30 генеральный директор лично позвонил мне в Slack со зловещей просьбой позвонить в 12. В 12:15 меня уволили. Перефразируя: Адам, увольнение вступает в силу немедленно. Мы чувствуем, что вы хорошо справились; однако в связи с нынешним климатом сокращаем персонал.
Я был одним из 15 человек, которым бесцеремонно уволили — без предупреждения, без пособия; не дали даже пяти минут, чтобы попрощаться с коллегами (аккаунт Slack отключили во время разговора).
Мы с женой переехали в первый собственный дом полгода назад и были не в том положении, чтобы долго жить без стабильного дохода.
Следующие несколько месяцев были жестокими: я нигде не мог найти работу. Рынок был насыщен квалифицированными инженерами, которые были в одной и той же ситуации. Чёрт возьми, я не мог получить компенсацию по безработице, и это было настолько неприятно, что я написал об этом целый пост в блоге.
Как такое могло произойти?
Если сравнивать с боксом, Covid стал комбинацией джеба и кросса, он привёл к сокращению и к жестокой конкуренции на рынке труда. Но здесь есть трудный урок — меня уволили, потому что я не был важным сотрудником. Бизнес вполне мог обойтись и без меня. Инженеры, которых компания удерживала, технически были очень сильны, но, что важнее, они работали с системами, составляющими ядро бизнеса. То есть их увольнение могло разрушить бизнес. И здесь я оступился.
В штате я был новым человеком, и компания направляла меня на свежие, неосвоенные проекты. Я работал над конвейером ML и анализом данных в Jupyter. Но сущностью системы были заурядные приложения Flask. Никто не подталкивал меня работать с ними, так что я держал дистанцию. Я не исправлял в них баги. Когда они тормозили, я не поддерживал их. Никто не просил меня об этом, и я этого не делал.
Я творил новые крутые штуки — будущее компании!
Оказалось, что эти системы и инженеры, которые разрабатывали и поддерживали их, представляли для компании большую ценность, чем я. Сейчас, оглядываясь назад, я ясно вижу это. Если поразмыслить, позволив мне уйти, CEO сделал жестокий, но правильный выбор.
Как неудача помогла мне вырасти?
Период с июля по сентябрь был жёстким; я упускал вакансии раз за разом. Я по-настоящему близко подошёл к работе моей мечты на онлайн-собеседовании, чтобы быть отвергнутым на втором этапе, уже второй год подряд, и это было особенно сокрушительным.
В конце концов, я устроился на скучную работу на Java в скучной компании. И быстро понял, что скучный софт — это просто прекрасно! У скучного ПО прямолинейные требования и преданные пользователи. Вещи вроде “эта кнопка не работает” легко исправляются и не требуют кандидатской степени или многолетнего планирования. На самом деле очень приятно легко снимать сливки стандартного веб-приложения и видеть искреннюю человеческую благодарность!
Скучные вещи делают вас критически важным. Я добровольно вызвался работать с сущностью системы, от создания инфраструктуры до сложной функциональности. И пока моя цель — не стать частью самой системы (то есть не автоматизировать самого себя), так компании должно быть труднее меня уволить.
Также я больше не беспокоюсь о собеседованиях или о потере работы. Мы можем сделать всё возможное, но остальное нам не подвластно.
Возможно, вы не получили работу, потому что у другого кандидата было больше опыта в определённой технологии. Может быть, они уже сделали оффер. Или, может быть, вы просто не так хорош, как парень справа или слева от вас. Избавьтесь от своего эго, смиритесь со всеми этими причинами, и страх исчезнет.
Поймите, что вы, вероятно, не рок-звезда и никогда ею не будете, и это на все 100 % нормально. Софтверный бизнес — это целая армия, а не только [её элита –] морские котики.
Наконец, последнее, чему я научился, — это просить о постоянной обратной связи. Что я делаю? Почему я работаю над X? X имеет решающее значение для успеха компании? Если нет, тогда что действительно важно? Не привязывайся так к своей работе. Часто мы боимся обратной связи, потому что она ранит наше эго, но принятие обратной связи — быстрый путь вперёд.
PS: если вы одна из многих компаний, отказывающихся давать отзывы соискателям, вам должно быть стыдно.
Вывод из всего этого: неудачи и препятствия не только неизбежны, но и необходимы. Отдельные неудачи редко бывают виной отдельных людей. Неудача — это возможность; возможность узнать что-то о себе и об окружающих. Ваш босс рвёт вас на части или подтягивает вверх? Семья и друзья прикрывают вас? Это прекрасный момент, чтобы остановиться, подумать и скорректировать курс.
Узнайте, как прокачаться в других специальностях или освоить их с нуля:
Другие профессии и курсы
ПРОФЕССИИ
КУРСЫ
gsaw
Сам я крупно не косячил. Зато один раз участвовал в правке накосяченного другим. В одном проекте, который вырос из 90-х еще, ну как вырос, вернее вырыли яму и туда накидали всякого. Разбирать и развивать эту кучу малу ни денег, ни желания у клиентов не было, а залить бетоном и положить газон сверху рука не поднималась. Хотя там обрабатывались сотни грузовиков в день, на многие миллиарды товаров в год. Потому все, что не было в интерфейсе, они сами SQL-ем правили.
В один прекрасный момент, кто то из них решил пару контрактов в базе данных пометить как выполненные. У контрактов были разные статусы от одного до ста. Соответственно программа по разному реагировала в зависимости от статуса. А чудак у них update не весь выделило, забыло where. В результате все контракты одним махом оказались выполнены. Мне пришлось пол дня анализировать данные и код этого старья и подбирать соответствующий статус контрактам эмпирически.
В том же проекте был еще один случай. Софт был установлен на unix сервере. Видимо в 90-х это была пара файликов и лежали они в одной папочке «start». А потом с годами в эту папку сложили все. И архивные данные, и логи, и исполняемые файлы, и распечатки контрактов и шелл скрипты. Причем некоторые шелл скрипты получали какие то данные параметрами из базы данных и вызвались прямо из сервера написанного на Си. Они создавали временные файлы и потом за собой удаляли все. И однажды звонит клиент и говорит, что ничего не работает. Я смотрю в логи и не вижу их. Причем вообще не вижу ничего — вся папка «start» девственно чиста. Куда все делось непонятно. Восстановили из бэкапов, через пол часа опять все исчезло. Так раз три пытались, пока анализ не показал, что клиенты в базе поменяли какие то данные и шел скрипту в качестве параметра передавалась пустая строка. А этот параметр прямиком в шелл скрипте подставлялся в команду типа «rm -r ./$print_file*», что превращалось в «rm -r ./*» и все успешно удаляло.
Неудивительно, софт старый, текучка в проекте была неслабая, кому охота с этим разбираться, я от туда тоже в свое время, бочком-бочком свалил. Софт до сих пор работает как не странно, ему уже 26 лет. Все так же на Си плюс обвязка из шелл-скриптов.
alexs0ff
Какой же он чудак? В систему, минуя API, разрешали лезть руками, что не очень профессионально. Такое может с кем угодно случится. Не зря придумали публичные API, а нарушение инкапсуляции рано или поздно приведет к выстрелу в голову.
ArsenAbakarov
«подбирать соответствующий статус контрактам эмпирически.» — я бы тут трижды подумал