Вступление, или Как я оказалась здесь

Я Java‑разработчик (по крайне мере, пытаюсь им остаться). Пришла в профессию без классического IT‑бэкграунда, прошла очень много всяких разных курсов, пробовала изучать разные языки и парадигмы, и вот однажды мне повезло, и я нашла работу. Там приходилось доучиваться на ходу, через боль, Stack Overflow и фразу «а почему это работает?». Но в целом, я думала будет гораздо сложнее, потому что вроде как почти со всеми задачами я справлялась достаточно легко. То есть, получается, что у меня получилось. На моём предыдущем проекте я разобралась в высоконагруженной системе, написала весомую часть бизнес‑логики, выделила свой функционал в полноценный модуль, и — внимание — ничего не сломала. Я чувствовала себя вполне уверенно. Я понимала, куда и откуда текут данные, где точка входа, почему упал тест. Это было счастье (которое не ценилось, как всегда бывает).

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

Я думала: ну, данные, трансформации, ETL. Логично. Интересно. Справлюсь.

Я не справляюсь. Я в шоке. И сейчас расскажу, почему.

Классические призраки легаси, или «Я думала, что видела плохой код»

Первое время я искала в интернете статьи про легаси, думала — это я не права или просто чего‑то не знаю? Было уже очень сложно разбираться с тем, что здесь происходит. Читала и кивала: да, это про нас, просто я не знаю таких умных слов. А по‑простому так: много наследований. Интерфейсы, из которых часть методов переопределяется, часть — нет, а часть вообще не используется. Перегруженные методы, которые вызываются непонятно откуда. Общая библиотека, которую нельзя менять.

Классика, наверное... все через это проходили. Но есть нюанс. Я даже не понимаю, где точка входа. Я не понимаю, в каком порядке выполняется код. Я пишу логирование — в консоли пусто. Я пишу System.out.println — тишина. Я чувствую себя человеком, который пытается включить свет в комнате, а выключатель находится в другом здании, и здание это снесли в 2014 году.

Трансформеры, конфигурации и магия

Вот пример. В системе есть трансформеры. Каждый трансформер имеет конфигурации, которые описаны только в общей библиотеке. При неправильном подборе можно всё сломать. Как выбрать правильную — неизвестно. Потому что куча переопределений и наследований, и никто не может объяснить, что за что отвечает. Документации нет, конечно же.

Это как собирать шкаф из IKEA, где инструкция написана на языке, которого не существует, а все детали выглядят почти одинаково, и, допустим, отличаются на 1 мм. И если ты ошибаешься — шкаф не просто кривой, он удаляет таблицу из базы данных.

Ага. Код удалял таблицу. Вместо оптимизации. Причем, как я выяснила, люди, которые это писали, сами не знают, как оно работает. И конечно же, ничего не знают о том, как комбинировать их собственные конфигурации. Зато все красиво — просто напиши здесь это, там то, перечисли таблицы, колонки, которые нужны методу, и все заработает (нет). С одной стороны, я понимаю, почему здесь все так. Люди, которые это писали, сильны в SQL, и там действительно сложные запросы, но JAVA используются тут лишь для красоты, но это не красота, а переусложнение, на мой взгляд, и мне печально от этого...

MAX(loading_id), или Где живёт ошибка

Был у меня квест. По логу нашла ошибку: нужно было найти, откуда приходит максимальный loading_id. Смотрю в стек вызовов — вроде ноги растут отсюда. А на самом деле этот MAX приходит из методов выше по стеку. А проверяется только потом, внутри самой сути.

По моей логике — достал loading_id, сразу его проверь. Ведь не везде он нужен в методе ниже. Но нет. Логика такова, что данные гуляют по системе, как пьяный турист по незнакомому городу, и валидируются где‑то в конце, когда уже поздно. И таких мест в коде полно, так же как и одинаковых «ифов», которые могут повторяться несколько раз за один метод!!! (на 3 экрана вниз, естественно)

Логи, которых нет

Отдельная боль — логирование. Я добавила логирование в саму библиотеку. С параметром для отключения. Оно работает. На тестовом стенде ничего не ломается. Но логи пишутся не полностью. Я не понимаю почему. Возможно, я теряю что‑то важное. Возможно, нет.

Единственный вариант — выкатить и проверить. Это называется «тестирование в проде», и это не то, чему меня учили.

А ещё я сделала файлы с проверкой, чтобы параметры логирования (время и размер файлов) можно было менять. Мне сказали: захардкодь. А пути для хранения логов бери из «загадочных методов».

Я захардкодила, а что остается делать...

Оптимизация, которая не оптимизация

Последняя задача: взять данные не из снепшотной схемы реплики (источника), а из дифф‑схемы. То есть из более маленькой таблицы. Точнее, дифф‑таблица конечно больше снепшотной, но просто мы берем какой‑то небольшой кусочек, который в целом меньше чем весь снепшот. Вроде просто же, да?

Нет. На самом деле это повторение того, что писала выше про трансформеры и магию. Просто этот факт меня больше всего убивает, потому что задачу я не сделала, как и все остальные по «оптимизации уже существующего». Если что‑то надо сделать с нуля — я справляюсь. Но если что‑то такое... встроенными средствами этой самой общей библиотеки такие задачи мне не сделать. Да и не нужно, как оказалось, хотя по смыслу — оно прям для этого и создано.

Возможно, я просто туплю, но может быть, не исключаю, что все происходит потому, что повсеместно в этом коде, помимо перегруженной вложенности, повторяющихся «ифов», множества наследников и интерфейсов (в которых, кстати, половина методов просто не используются, ничего не делают или возвращают null), еще и подменяются имена схем и имена таблиц, и все это находится в строковых литералах и константах, никаких конфигов... и узнать «правду» очень сложно. Например, в коде схема называется так, а в реальной базе — такой схемы нет. И тут уж не знаю, как не сойти с ума. Просто догадаться, что вот эта схема или таблица — это вот та же самая, просто с другим префиксом/суффиксом. И да, чтобы найти то место, где происходит drop table, я, по‑моему, потратила 2 дня.

Зато, как будто бы, вскрываются какие‑то явные недостатки, но с нюансом: вскрываются они только на мне, остальные этого не замечают или просто не знают, что можно по‑другому.

Что я поняла

Всё надо переделать. Так жить нельзя. Но я одна не могу ничего сделать. И, что самое страшное, всех здесь всё устраивает. Да, я согласна: что уже работает, трогать не стоит, и не факт что переписывание вообще поможет. Но! В новом проекте они так же и пишут... пытаются сразу вынести какую‑то общую логику, хотя ведь мы написали всего 1,5 трансформера! У меня взрывается мозг... ведь если есть возможность написать что‑то заново, почему хотя бы не попробовать сделать это по‑другому? Но у меня здесь нет единомышленников, я пыталась высказывать свой мнение, но со мной не согласились...

Я понимаю, что тут давно работают люди и они так привыкли, но я — новенькая. И мне просто очень тяжело, иногда кажется, что я схожу с ума. Наверное, я вижу реальность. Это как быть единственным зрячим в стране слепых.

Что я делаю, чтобы не сойти с ума

  1. Я перестала пытаться что‑то улучшить, хотя поначалу прям очень хотелось. Моя энергия нужна мне, а не им, и моя метрика успеха теперь — «я выжила и не сорвалась». А еще иногда я просто не понимаю, что я делаю и зачем. Но сказали так — и ладно. «Вот здесь надо дописать суффикс к названию таблицы, потому что там через 10 вызовов оно сломается» — окей, так и сделаю. Не буду думать, что этот суффикс не нужен, и вообще, названия колонок и таблиц хорошо бы хранить в конфигах и не завязывать на них какую‑то логику... Но да ладно:)

  2. Не спорю с легаси. Сказали захардкодить — захардкодила. Сказали взять из магического метода — взяла. Что, как мне кажется, не способствует инженерному развитию, но может в этом есть тоже своего рода прокачка... я почти каждый день думаю про себя: «я бы сделала по‑другому». Но не делаю. С одной стороны, грустно, но с другой, если тратить энергию на борьбу с ветряными мельницами, то от меня вообще ничего не останется. Поэтому мне просто достаточно понимать, что «я бы все переделала», и объяснять себе же, почему. Кстати, мне здорово помогает ИИ, когда я прошу его объяснить, что происходит в коде и в каком порядке:)»

  3. Поддерживаю существующие тесты в актуальном состоянии. (Которые, кстати, пришлось допилить, чтобы они действительно работали. По задумке они должны были создавать таблицы‑источники из DDL‑файлов проекта, но по факту до парсинга этих файлов дело даже не доходило...) Тесты помогают мне не сойти с ума и хотя бы что‑то проверять перед тем, как смотреть, что оно сломается на стенде. Хоть это тесты просто на трансформеры, они мне очень помогают, так как мне не хватает экспертности, чтобы глядя на SQL сказать, выполнится он без ошибок или нет, сможет ли Spark построить по нему корректный план или упадет... Когда‑то я мечтаю написать full‑walk тесты и иметь поменьше дел с выкаткой версий на стенд, которые здесь как будто тоже устроены так, чтобы тебя бесить. Они завязаны на проверке excel‑файлов с колонками таблиц и так далее... Но, может быть в мире данных это норма, я не знаю. Кто знает, скажите пожалуйста:)

Вместо заключения

Если вы тоже сейчас в легаси и чувствуете, что сходите с ума, — вы не один. Это не вы плохой. Это код такой. И у вас есть право на усталость, на грусть и на то, чтобы иногда просто захардкодить и пойти домой.

Несмотря на все это, я изо всех сил стараюсь не унывать, а учиться работать с тем, что есть.