Добавить в корзинуПозвонить
Найти в Дзене
Worst Programming

Повелитель багов

Привет. Я - повелитель багов. А теперь стоп и отмотаем немного назад. Решил я как то написать немного о себе. Причин много - брат пишет, какие то люди пишут, да все вокруг пишут, а я только работаю и ем. При этом копится внутри какая то невысказанная суета. Хочется поговорить - пристаю к Коляну по телефону, но вот он уже все про меня знает, а хочется поговорить еще и получить больше фидбэков... Надо что-то написать. Устроился я как то на работу в компанию и думал, что это хорошо и что мне очень повезло. Да, мне повезло, но я, как Джорди Верилл, не воспользовался своим везением, однако это не по делу, а по делу вот что. Очень скоро я заметил, что кодовая база полна технического долга, что код с которым мне приходится работать сплошь прогрызен маленькими невидимыми червячками и часто стреляет в ногу... тому, кто стоит рядом. Сначала я стал записывать то, что мне не нравится - неверный выбор типов данных для хранения, слишком сложные или жадные до ресурсов алгоритмы, но очень скоро понял,
Оглавление

Привет. Я - повелитель багов. А теперь стоп и отмотаем немного назад.

Решил я как то написать немного о себе. Причин много - брат пишет, какие то люди пишут, да все вокруг пишут, а я только работаю и ем. При этом копится внутри какая то невысказанная суета. Хочется поговорить - пристаю к Коляну по телефону, но вот он уже все про меня знает, а хочется поговорить еще и получить больше фидбэков... Надо что-то написать.

Устроился я как то на работу в компанию и думал, что это хорошо и что мне очень повезло. Да, мне повезло, но я, как Джорди Верилл, не воспользовался своим везением, однако это не по делу, а по делу вот что.

Очень скоро я заметил, что кодовая база полна технического долга, что код с которым мне приходится работать сплошь прогрызен маленькими невидимыми червячками и часто стреляет в ногу... тому, кто стоит рядом. Сначала я стал записывать то, что мне не нравится - неверный выбор типов данных для хранения, слишком сложные или жадные до ресурсов алгоритмы, но очень скоро понял, что это все цветочки. Технологии с которыми пришлось работать были старыми, но не такие, чтоб назвать их раритетом, а такие, чтоб назвать их хламом. При этом иногда попадались такие знатные костыли, что хотелось тут же о них забыть. Я даже видел ассемблерные вставки, блокирующие некоторые механики стандартных библиотек языка с которым приходилось работать. По долгу службы приходилось работать с широким стеком: база данных, фронтенд, бэкэнд, десктоп и всякие средние слои. Будем считать, что с рабочим окружением я вас ознакомил.

Первый баг, который я победил

-2

Ну ладно-ладно, это не первый баг в моей жизни. Их было миллионы на тот момент. Но это был первый баг, который я победил в этой компании. И создал его я.

Это был первый мой деплой на прод. И был он не в пятницу, и звоночек пришел не в этот же день. Да, обновление разошлось на какой то процент серверов и все бы ничего, но после этого обновления перезагрузка одного из сервисов на проде приводила к конфликту библиотек и сервис падал. Я бы рассказал про этот сервис, но страшно вспоминать. Это что-то вроде шедулера, который запускает по расписанию какие то рутинные операции. Написан он на дельфи и очень часто падал из-за плохой многозадачности и вобще, как это "на дельфи" да и не падать (извините Borland и все, кто потом это купили). Так вот этот сервис упал в очередной раз и не встал... сначала на одном сервере, а потом на остальных. Масштабы поражения = примерно треть торговой сети.

Сделали откат, поручили разобраться, что не так. Каково же было мое удивление, когда я понял, что сборку обновления одного из компонентов выполнили не от рабочей версии на проде, а от "тупиковой ветки" - какого то обновления, которое так и не пошло в прод. А в этой новой ветке планировали обновить связанные библиотеки... Да короче, эта статья не про слабую связанность и не про микросервисную архитектуру. Эта статья о куче файлов в одном каталоге из которого каждый компуктер тянет к себе нужные файлы по smb протоколу, раскидывает их по разным папкам и называет это обновлением. Обновляли один компонент, а обновили все, что там использует файлы с таким же именем.

Нашел, пересобрал, доставили обновление, все рады. Начальник сказал: "не переживай, каждый из нас на первом своем обновлении в лужу... садился".

Эй, сервер, чем ты там занят?

-3

Каждый из нас сталкивался с проблемой, когда на сервере зациклилась какая то задача и жрет ресурсы по максимуму, что влияет на все процессы. Я бы на этом месте перестал читать, с понтом: "Че? А где слабая связаность? Где отказоустойчивость? Опять история про монолиты на выделенных "серверах" и грязную архитектуру?" Нет, это не про архитектуру, а про "повелителя багов", успокойся и читай дальше. Короче, те, кто работают в нормальных компаниях с кубернетесами такого не боятся. Но вот стабильно раз в неделю одна из крупных торговых точек зависала наглухо, когда выполняли завершение процесса приемки товара и виноват был... алкоголь.

Алкоголь, будь он трижды проклят! Сервер жрал диск, усердно запивая процессором и пытался урвать еще и сеть, но она была широка. Было непонятно, что происходит, чем это вызвано и как это остановить. Решалось примерно так: два-три часа программист (или я) копался в базе данных, пытаясь понять, где нет нужных данных, почему произошла такая ситуация, и не до чего не докопавшись вносил правки прямо в данные прода.

Но в скором времени до кода добрался "повелитель багов" и почитал его... Потом выпил валерьянки, взял китайский словарик и прочитал снова. Ок. Проблема обнаружена - цикл WHILE в коде хранимой процедуры в базе данных, который никогда не завершался. Он меня поразил в самое сердце, я немного поговорил с автором, попытался поделиться опытом и объяснить, почему нельзя использовать WHILE циклы таким образом. Плохой код не был переписан, вставили костыль, который при обнаружении бесконечности завершался, и код выполнялся далее, как будто ничего и не было. А?! Как вам?

Алкоголь, ты пьян, иди домой

Следующая проблема алкоголя - очень часто при попытке принять этот товар происходила ошибка - то упаковка в базе не распознана, то информации о штрих-коде нет. Процесс был простой: приемщик сканирует ШК один за другим и затем нажимает кнопку "завершить". Что тут то может поломаться? Очень часто помогало удаление данных об операции и повторный запрос этих данных с центрального сервера. От оно как! Значит данные в порядке, просто на тот момент, когда начинается приемка, их кто-то уже удалил...

Ладно, много было дискуссий, пытались решить, какой процесс ломает данные, пытались повторить эту проблему используя все известные инструменты - ручные и автоматические. Попытки обвинить отдел сопровождения в использовании "забагованых" инструментов. И бог еще знает что.
Потом пришел "повелитель багов". Конечно, процесс сбора данных и последующий анализ занял много времени. Решено было в несколько этапов. Во-первых, я обнаружил в базе данных бэкап тех данных, которые присылал сервер в формате XML и написал скрипт, который парсит дерево, выявляет потерянные данные (а там было много узлов и сложная иерархиия). Скрипт работал отлично, не нужно было больше обращаться к разрабам, сопровожденцы просто запускали его и процесс приемки продолжался далее. Договорились о том, что это временное решение и проблему я в будущем исправлю. Но как же много мне хотелось исправить! Я был в корне не согласен с форматом данных, мне не нравилась неоднозначность некоторых элементов XML. Было больно смотреть на код SQL и переписать хотелось все.

К концу второго года работы в этой компании мы с моим другом в рамках большой фичи с дедлайном взялись переделать архитектуру. И проблема была устранена на уровне архитектуры.

Вечером деньги, утром стулья

Вот представьте себе, Вы стоите на кассе с десятью миллионами рублей, Вам говорят, что товар уже собран и вот-вот начнется отгрузка... сразу же, как перестанет зависать наша программа...

Ой, какая неловкая ситуация. И угораздило же меня в этот вечер немного задержаться, короче пришлось снова надевать костюм "повелителя багов". И вот я сижу за компом и вижу, что хранимка в базе выполняется ужжжжасно медленно, а за моей спиной начальник отделения и начальник службы... Давай-давай скорее, че ты копаешься, там покупатель с десятью миллионами рублей...

Ахаха... Это я сейчас тут сижу и мне смешно - код не мой, эту подсистему я вообще первый раз вижу, у автора спрашивать совета не собираюсь просто потому, что нечего спрашивать - код написан, все работает. Вот только не тестировали это с расчетом на такое количество данных (почему?) а за моей спиной стоят "большие дядьки".

Ну уж я переписал этот медленный код на свой лайтовый и быстрый. И сказал "вуаля!", но только на следующий день =). Только утром покупатель получил свой товар. Ну а что вы от меня хотели в 7 часов ночи? Немного пожурил автора, рассказал про нагрузочное тестирование и о том, как SQL придумывает план, а программист следил за там, чтобы этот план был оптимальным.

И что мне теперь делать оставшиеся 3 дня?

Как то раз из-за меня пришлось корректировать планы отдела тестирования. И вот как это было.

После нового года один из разработчиков в нашей команде ушел в отпуск и оставил свои задачи на меня. Задачи были уже на этапе тестирования, ничего не ожидалось, но вот приходит ко мне тестировщик и говорит, "суммы не сходятся, давай править", ну ок, давай. Только вот скрипт, который должен эти суммы генерить, выполняется около трех часов. Чтоооо?! Какие три часа?! Пошел ко я за костюмом "повелителя багов".

Нужно было просто найти баг в расчетах и тогда тестировщик запустил бы скрипт, а через три часа стал бы сверять результат. И на следующий день, если все плохо, я бы снова правил, а он снова запускал. Какой то сильно тяжелый цикл, не правда ли? Я все переписал. Я переписал все шесть процедур, которые вызывают одна другую, я переделал алгоритм, его сложность была O(n^3), а стала O(n *log n). И зачем писать такую ресурсоемкую логику? Ведь всегда проще написать что-то понятное и легкое, чем забивать голову промежуточными вычислениями и вложенными циклами.

Передаю я работу в тест, через 5 минут возвращается тестировщик и говорит "ты что наделал?! я запускаю скрипт, а он отрабатывает всего 15 секунд!". "Ну и что", - говорю я, "ты его проверял? Правильные данные?". Тестировщик проверил - все правильно. За пару часов он выполнил все кейсы и все ОК. Руководитель сектора тестировщиков позвонил мне и спросил, а что нам теперь делать в освободившиеся 3 дня?

Теперь это твое дело

Из параллельного сектора уволился человек, начальник отделения кричит через весь офис "Мне нужен повелитель багов! Где повелитель багов?!". Нет, ну конечно все было не так, но я услышал следующее: "эта подсистема закрепляется за тобой, перепланируй свой пулл так, чтобы эти задачи были в приоритете".

Что за узел я распутывал! Куча комитов и реверт-комитов, комментарии к комитам в стиле "комит 1", "фикс", "реверт". Еще и несколько параллельных веток и фич. О боже! Что нужно было доделать, что в тестировании, а что нет - ничего не понятно. Багом было это состояние. Конечно не с первого раза я нашел концы, но по ходу разбирательства я выяснил, что несколько фич попали в прод даже без теста. Исправил кучу замечаний от продукт-овнера и даже запилил пару новых фич, короче привел проект в более-менее божеский вид.

А ведь мне презентовали этот проект в форме "темное дело, куча легаси, разрабы постоянно меняются, аналитики вообще не в зуб ногой". Но начальник сказал "теперь это твое" и деваться было некуда, не смотря на то, что мой пул был загружен аж на три месяца вперед.

Давай до свидания

Я уволился с этого места. Не потому, что устаревший инструментарий, кривая архитектура или громадный объем технического долга, а потому, что мало платили и "нет возможности" платить больше. После того, как я подал заявление, нашли пару способов платить больше, но я не из тех, кто передумывает на половине пути.

Оглядываясь назад я могу сказать, что эти два года многому меня научили. Я не сорвал ни одного дедлайна, я работал под сумасшедшей нагрузкой и вел отчет о проделанной работе в трекере с высокой детализацией. Там было такое понятие "атом" - мы отчитывались этими "атомами" в трекере так, что можно было поминутно видеть, чем ты сегодня занимался. Мне довелось и планировать работу сектора и собирать отчет за месяц. И согласовывать переносы работ и участвовать в проработке архитектуры крупных проектов. Я завел кучу друзей среди разработчиков, тестировщиков и службы сопровождения. Они все пришли провожать меня в мой последний день и вручили мне подарок - офисное кресло.

До того, как я устроился на эту работу у меня не было ничего, а после у меня осталось ничего и дергающийся глаз =) Брошенные мною коллеги, помню вас и люблю!