Как успешно пройти backend собеседование и получить лучший оффер
Как я учился говорить "нет" менеджерам и не чувствовать себя мудаком
Менеджер пишет:
Там мелкая доработка, надо просто поле добавить. Сможешь сегодня?
Срочно надо пофиксить расчёт формулы, иначе отчёты не сходятся
Что происходит, когда мы пишем new в Java: от байткода до оптимизаций
Кажется, мы просто создаём объект:
var user = new User();
var user = new User()
превращается во что-то вроде:0: new #2
3: dup
4: invokespecial #1
7: astore_1
new
– резервирует место в heap, но не вызывает конструктор. dup
– после new ссылка на объект оказывается на вершине стека. dup нужен, чтобы использовать её дважды: и для вызова конструктора, и для присваивания переменной. invokespecial
– вызывает <init>-метод (конструктор). astore_1
– сохраняет ссылку в переменную user. Как учиться, когда у тебя работа, семья, дела и вообще ни на что не хватает времени
Учиться легко, когда тебе 18, ты живешь в общаге, ешь пельмени и всё свободное время твое.
Но если тебе за 25-30, ты работаешь full-time, у тебя семья, дети, ипотека, собака, кошка, больная спина и прод упал – то любая мысль о том, чтобы ещё учиться, вызывает злость, вину и выгорание.
Я устал.
У меня нет времени.
У меня нет сил.
Но я хочу лучшую работу.
Я слабак. У других же получается.
Наверное, не так уж и хочу.
Надо просто собраться и начать.
Практикум по Java собеседованиям
Весной я решил попробовать новый для себя формат подготовки разработчиков к собеседованиям.
Вместо индивидуального менторства – встречи в небольшой группе.
Я опасался, что это будет не так эффективно, как личная работа 1 на 1.
Но по завершении группового практикума, я могу с уверенность сказать, что это не так.
Нас было 7 человек, включая меня.
Мы встречались 2 раза в неделю по вечерам на протяжении месяца и обсуждали разные вопросы: от внутрянки jvm до системного дизайна и оформления резюме.
Трое уже нашли новую работу с повышением должности и дохода. Двое получили контр-офферы на текущей работе и приняли их. Один в процессе прохождения собесов. Я уверен и у него все получится.
Главный плюс, который я вижу в групповой работе – это комьюнити, которое тебя подталкивает.
Пример.
Чтобы более менее уверенно чувствовать себя на алгоритмических секциях, нужно самостоятельно прорешать не один десяток задач.
Когда ты один – трудно заставить себя тратить на это время.
Ментор тебя тоже не заставит. Он же не будет бить тебя палкой.
А когда ты в группе – возникает азарт.
Петя решил 30 задач, Ваня решил 40 задач, а я решил всего лишь одну – непорядок, я что ленивее других?
Более того, все разбились на пары, самостоятельно встречались и вместе решали задачки. В том числе и по системному дизайну.
Плюс коллективный разум. Кто-то может задать такой вопрос, о которым ты даже не подозревал. Это очень сильно расширяет кругозор.
Поэтому я считаю, что групповая работа ни чуть не уступает по эффективности личному менторству.
Кроме того, она намного выгоднее по деньгам.
Менторство предполагает пред-оплату 10/20/30 тысяч и пост-оплату в процентах от полученного оффера – 50/100/150% в зависимости от уровня человека.
В группу же можно залететь за несколько тысяч рублей в месяц при использовании рассрочки.
Суммы отличаются в разы.
Что в итоге?
Я решил продолжить развивать формат групповой подготовки к собеседованиям:
– Переработал программу
– Увеличил количество групповых встреч до 10
– Включил проверку домашнего задания
– Добавил одну личную встречу в конце практикума для большей уверенности, что человек усвоил весь материал и готов выйти на рынок
Какие темы изучаем?
– Java (от core до virtual threads)
– Spring (от бинов до hibernate)
– SQL/NoSQL (от индексов до explain)
– Kafka (от устройства до гарантий доставки)
– Docker, Kubernetes
– Задачи на код-ревью и алгоритмы
– Паттерны проектирования
– Системный дизайн
– Soft skills (от оформления резюме до рассказа о себе)
Короче, суть в том, чтобы ты:
– Закрыл все вопросы по собеседованиям
– Чувствовал себя уверенно в любых ситуациях
– Нашел новую интересную работу, на которой сможешь расти
– Увеличил свой доход
Если тебе интересен такой формат подготовки, пиши мне в личку @principal_swe
Созвонимся, обсудим все вопросы и решим подойдет ли это для тебя.
Стартуем в начале августа.
Так как это небольшая группа, то, конечно, количество мест ограничено.
Поэтому выбор – действовать сейчас или отложить – только за тобой.
Я уверен это отличный буст для любого разработчика.
Я шёл на собеседование, а попал на допрос
Вот какую цель ставит перед собой любой адекватный интервьюер, проводя собеседование?
Правильно. Найти человека к себе в команду.
Должен ли этот человек знать 100500 фреймворков? Нет. Любой технологии можно обучить.
Должен ли этот человек молниеносно и оптимизировано решать алгоритмические задачи? Нет. Любой алгоритм требует неспешных размышлений.
Должен ли этот человек вызубрить методы класса Object? Нет. Он не энциклопедия.
Что же должен этот человек?
Да ничего никому он не должен.
Как говорят психологи, долженствование – это когнитивное искажение.
Кстати, почитайте про когнитивные искажения. Очень познавательно.
Так вот. Если тебе комфортно общаться с этим человеком, если ты видишь его рост, если ты видишь его стремления, то этого достаточно, чтобы работать с ним.
Соответственно и вопросы интервьюера должны быть направлены на это.
На опыт человека, на то как он принимает решения, как подходит к компромиссам, к решению проблем, какую ответственность он готов брать.
Неадекватный интервьюер же пришел на собеседование не для того, чтобы найти коллегу себе в команду, а чтобы самоутвердиться.
Он не спрашивает, он соревнуется.
Он не слушает, он выискивает момент, когда ты ошибешься.
Он не хочет понять, он хочет почувствовать себя крутым.
Отсюда и вопросы «А если я сделаю вот такую дичь, где будет NPE?».
Это не собеседование.
Это допрос с элементами показательного унижения.
А после – его ехидная улыбка.
Каждый день мы разгребаем дерьмо:
– запутанное легаси
– ошибки прома
– тонны фич без полной аналитики
– отсутствие архитектуры и нормального техдолга
– бесконечные митинги
И ты ещё приходишь на собеседование, чтобы расти, менять проект, доход – а тебе: «Что делает GC, если у тебя в finalize вылетело исключение?».
Серьёзно? Это то, по чему ты судишь про мой опыт?
Если ты когда-нибудь выходил с собеса с мыслью: «Я вроде сеньор… но чувствую себя идиотом» – это не ты глупый. Это интервьюер сделал глупость – не смог раскрыть тебя. А иногда – и не хотел.
В предыдущем посте вы ставили 🔥 чтобы узнать как застать интервьюера врасплох на вопросах про прокси.
Адекватного интервьюера вам и не захочется заставать врасплох. Он не даст причин.
А на неадекватного – не тратьте свои силы, время и нервы. Он того не стоит. Поблагодарите судьбу за то, что работать вы с ним не будете.
❤️ если согласен
Что будет с твоим кодом через 250 лет?
На выходных с девушкой посетил Екатерининский дворец в Царском Селе.
Во-первых, это безумно красиво!
Благодаря колоннам и пальмам складывается ощущение будто ты в Древней Греции.
Во-вторых, это архитектурная медитация.
Ты смотришь на детали: колонны, золото, лепнину, геометрию.
Каждый зал – как модуль.
Каждая анфилада – как правильно выстроенный маршрут пользователя.
И в какой-то момент ловишь себя на мысли:
Чёрт, так ведь и с системным дизайном то же самое!
Карточки про гарантии доставки Apache Kafka
При работе с сообщениями могут возникать различные проблемы как на стороне producer, так и на стороне consumer.
Часть проблем решается настройками на уровне Kafka, а часть - использованием определенных паттернов проектирования.
Рассмотрим:
– At most once
– At least once
– Exactly once
– Transactional Outbox
– Идемпотентный Consumer
Почему вы хотите сменить работу?
Этот вопрос звучит на 99% собеседований.
И вот тут самая частая ошибка: кандидат начинает жаловаться.
Ну, у нас руководство странное…
Проект заморожен…
Я там вообще не расту, всё токсично…
У нас ужасный менеджмент
Все уволились, и я тоже
Меня не ценят
Полный бардак, всё рушится
Я просто устал
Я благодарен текущей компании – за 3 года я вырос из джуна в мидла, дебажил прод, участвовал в релизах. Сейчас я понимаю, что достиг потолка: проект стабильный, зона ответственности не меняется, стек устоявшийся. Мне хочется новых технических вызовов, больше влияния на архитектуру и возможность общаться с бизнесом. Именно поэтому я рассматриваю компании, где смогу использовать накопленный опыт и продолжать развиваться.
Компания сократила команду в рамках реструктуризации. Это не связано с моей производительностью – скорее с пересмотром приоритетов. Я воспринял это как возможность выйти на рынок, переосмыслить свою траекторию и найти команду, где смогу быть полезным и продолжать рост.
В текущем проекте я много работал с внутренними сервисами, и за это время понял, что мне интереснее клиентские фичи и влияние на конечный продукт. Я ищу роль, где смогу сочетать технический опыт с пониманием бизнес-целей и влиянием на UX. Ваш проект как раз про это.
У нас полная анархия, всё через одно место.
Я понял, насколько для меня важны прозрачные процессы, поддержка команды и чёткая техническая стратегия. Сейчас этого нет, и я ищу место, где это есть.
Сборка мусора: что нужно знать, а не зубрить
На собесе тебе задают вопросы:
– Какой GC вы используете на проде? Почему?
– Как вы разбирались с OutOfMemoryError?
– Что у вас в GC-логах, когда пауза 3 секунды?
И вот тут ответ «Eden → Survivor → Old Gen» уже не канает.
Потому что тебя проверяют не на термины, а на мышление и опыт.
Давай разберём, что должен уметь и понимать разработчик, чтобы не плавать на вопросах по GC.
1. GC – это не про зазубрить типы
G1, ZGC, Shenandoah, Epsilon, Parallel, CMS...
Зубрить смысла нет. Надо уметь отвечать через "зачем" и "в каких случаях".
G1 – баланс между throughput и latency, хорош для сервисов с разной нагрузкой.
ZGC – очень маленькие паузы, используется когда uptime критичен.
Shenandoah – похож на ZGC, но смещен в сторону throughput.
Сеньора отличает не знание, как называется флаг, а понимание, когда его стоит использовать.
2. Разработчик должен уметь читать GC-логи
На собесах иногда дают лог вида:
[GC pause (G1 Evacuation Pause) (young), 0.1234567 secs]
[Parallel Time: 98.7 ms, GC Workers: 4]
[Eden: 512M(512M)->0B(512M) Survivors: 32M->32M Heap: 2G(4G)->1.6G(4G)]
Мы использовали G1, потому что это дефолт.
Мы использовали G1, потому что у нас SLA на паузы не выше 200ms, и через -XX:MaxGCPauseMillis добились приемлемого баланса. При этом контролировали нагрузку через метрики jvm_gc_pause_seconds в Prometheus и сигнализировали при росте p99 выше 100ms.
У нас были скачки пауз до 2 секунд. Мы посмотрели GC-логи, заметили, что Full GC шёл каждые 30 минут. Оказалось – утечка через кэш без лимита. Ограничили по размеру, добавили метрики и алертинг – всё стабилизировалось.
Почему даже плохой код лучше, чем никакой
Начнём с простого вопроса: ты когда-нибудь писал говнокод?
Не в смысле «ой, забыл валидацию».
А вот прям настоящий, липкий, позорный.
Я писал.
Ты писал.
Писал даже тот самый архитектор, который сейчас выступает на конференциях и вещает «как нужно».
Как-то мы делали интеграцию с внешней системой.
По тестам – всё огонь. Как только вывели в пром – кошмар.
Внешняя система не принимала некоторые поля. Иногда. Без причины.
Ошибки рандомные. Логи непонятные. Поддержка молчит.
Откатывать было невозможно.
Пока мои коллеги ставили брейкпоинты, бизнес терял сотни заказов в час.
В попытках воспроизвести проблему, я заметил, что если отправить во внешнюю систему один и тот же запрос несколько раз подряд, то когда-нибудь он завершится успешно. Иногда со второго раза, иногда с седьмого.
Поэтому я написал максимально тупой цикл, в котором делал переотправку запроса, если предыдущий завершился ошибкой.
Да, это был код уровня "больно смотреть".
Но именно он спас компанию от убытков.
Никакой код = никакого результата.
Вот простая математика:
Идеальный код, не готовый вовремя – бизнес терпит убытки. Тебе нечем платить зарплату.
Грязный, но рабочий фикс – бизнес делает продажи. Ты получаешь премию.
Плохой код – не преступление. Он следствие.
Вот когда появляется плохой код?
– Когда сроки горят
– Когда бизнес не может ждать архитектурных сессий
– Когда данных мало, требований ноль, а надо "вчера"
– Когда ты впервые трогаешь чужой монолит
– Когда ночью прод лег, а CTO смотрит тебе в душу
В этих условиях ты не кодишь красиво.
Ты спасаешь ситуацию.
Но ты не должен останавливаться на этом.
Плохой код без исправления – это лень.
Плохой код с последующим рефакторингом – это техдолг.
Проблема не в плохом коде. Проблема в стыде.
Многие разработчики боятся писать не идеально и поэтому не пишут вообще.
А я тебе скажу: лучше говнокод в проде, чем идеальный код в голове.
Итог: действуй – потом улучшай
Сделай, чтобы работало.
Сделай, чтобы было правильно.
Сделай, чтобы было красиво.
Если ты начнешь с шага 2,
шанс, что ты вообще что-то выпустишь, будет стремиться к нулю.
Научись принимать компромиссы осознанно.
10 вопросов, которые я задаю себе перед код-ревью
Чтобы быть не формальным ревьюером, а настоящим наставником.
Когда я только начинал делать код-ревью, я думал:
Моя задача – найти баги и указать на нарушение code style
Хорошее ревью – это искусство. Это баланс между вниманием к деталям и пониманием общей картины. Это когда ты помогаешь сделать чужую работу лучше, не мешая ее закончить.
Ты не обязан быть гением, чтобы стать сильным разработчиком
Я помню тот день очень хорошо.
Конец осени. Холодно, темно.
Я сижу в офисе на старом скрипучем стуле.
На экране передо мной – стена ошибок в логе.
Я туплю в код уже четвёртый час.
Все коллеги давно ушли домой. В коридоре пусто.
И в голове крутится одна навязчивая мысль:
Может, это не моё?
Если я не могу всё понять сразу, значит, я недостаточно умен для этой профессии
Spring как алхимия
С ностальгией вспоминаю свой первый раз, когда я открыл исходники рабочего проекта на Spring.
Классы с десятками зависимостей, полей и аннотациями: @Service
, @Autowired
, @Qualifier
, @Value
, @PostConstruct
...
Все это выглядело сложно, непонятно, но так завораживающе.
Тогда у меня пролетела мысль, что Spring это алхимия джавистов.
Суди сам.
1. Магические символы
Алхимики верили в силу символов.
Мы – в силу @Transactional
, @Bean
, @Scheduled
, @ConditionalOnMissingBean
.
Поставил аннотацию – и вуаля, мир изменился. Или сломался.
2. Эликсир жизни
В алхимии искали философский камень.
В Spring мы ищем способ "оживить" зависимости через IoC-контейнер.ApplicationContext.getBean()
– современный аналог древнего эликсира.
Вытаскиваешь сущность из эфира и она оживает с нужными зависимостями.
3. Тайная лаборатория
Помнишь xml-конфигурации?
Тайные книги заклинаний.
А теперь java-конфигурации: @Configuration
, @Bean
.
Всё как в старых манускриптах.
4. Побочные эффекты
Как и в алхимии, эксперимент может неожиданно взорваться.
Написал @Transactional
– но метод private? Извините, магия не работает.
5. Оккультные знания
В каждом проекте есть один человек, который понимает, почему всё работает.
Он не пишет код. Он заклинает ApplicationContext.
И когда его нет, система перестаёт работать. Потому что никто не знает, почему этот @ComponentScan
искал в другом пакете.
Как алхимия переросла в химию, так и Spring перерос из магии xml и прокси в чёткую конфигурацию и зрелую модульность.
Но дух алхимии остался. Потому что в головах все еще витает вера, что если правильно расположить бины, то случится чудо.
Не ронял прод в пятницу вечером – не мужик
Это была обычная пятница.
Мы только что выкатили новый релиз нашего микросервиса, который отвечал за расчёт скидок в реальном времени.
Всё прошло гладко – автотесты зелёные, CI/CD прошёл без ошибок, мониторинг молчит.
Можно было спокойно закрывать ноутбук и врываться в вечер пятницы.
Но я решил "быстренько" выкатить одну маленькую правочку. Самую безобидную.
Фронт тоже выкатил новую версию и попросил сделать небольшое изменение – если скидка по акции не рассчитывается, нужно вместо null возвращать 0.
Казалось бы, мелочь.
Я открываю код, правлю один метод, пушу.
Code Review?
А зачем, это же фигня. Всё работает, я написал юнит тесты.
Вливаю PR в trunk, выкатываю на прод – и… пошёл гулять.
Спустя 40 минут мне звонит тимлид: «Ты что-то выкатывал? У нас метрики конверсии ушли в ноль»
Я захожу в Kibana – вижу шквал 500-х. Буквально шквал. Что-то точно пошло не так.
Открываю логи – NullPointerException в самом неожиданном месте.
И тут до меня доходит: моя "маленькая правочка" поменяла контракт.
Раньше discount == null обрабатывался особым образом на фронте. Теперь discount == 0 означает "нет скидки", но фронт это не понял и начал считать "скидка 0%, значит, акция есть" – и показывать баннер.
Но сам баннер вёл на несуществующий оффер.
Пользователи кликали, получали ошибку и уходили.
Подождите, но ведь фронт сам попросил сделать эту правку. Почему не работает?
Оказалось, они свой релиз откатили из-за критичного бага, а старая версия не поддерживает мою правку. Но сказать об этом мне они забыли.
Упущенные за вечер заказы: минус 20% к дневной выручке.
Нервный откат.
Испорченный вечер пятницы.
И моё собственное осознание: нет "маленьких" изменений в проде, особенно в пятницу.
Что я сделал после:
1. Релизы в пятницу вечером только после согласования всех участников продукта
2. Запрет вливать в trunk свои собственные PR
3. Прикрытие feature toggle даже "безопасных" правок
Одна строчка кода может стоить компании десятки и сотни тысяч рублей. И да, именно твоя строчка.
Самые тупые ошибки, которые ломают даже сильных кандидатов
Ты можешь быть отличным разработчиком.
Ты можешь знать java, spring, kafka, kubernetes и ещё кучу технологий.
Ты можешь даже решать leetcode hard с закрытыми глазами.
Но всё равно проваливать собеседования.
Почему?
Потому что есть тупые ошибки, которые ломают даже сильных кандидатов.
Сегодня разберём, какие ошибки убивают твои шансы на оффер.
1. Говорить слишком мало или слишком много
Ошибка 1: отвечать коротко, как на допросе.
Интервьюер: «Работали ли вы с микросервисами»
Кандидат: «Да, работал»
Ну и что интервьюеру с этим делать?
Правильный ответ:
Я работал с микросервисной архитектурой последние 2 года. В одном проекте мы перевели монолит в микросервисы, и это сократило время развертывания с 30 минут до 5. Могу подробнее рассказать про реализацию.
Честно говоря, я не углублялся в эту тему. Но если это важно, могу быстро разобраться.
Я backend-разработчик с 4 годами опыта, специализируюсь на масштабируемых сервисах. В последнем проекте я ускорил работу api в 3 раза и помог внедрить Kubernetes, что снизило расходы на инфраструктуру на 20%.
Мы измеряли эффективность через lead time и количество деплоев. Когда я пришёл в команду, у нас было 1 релиз в месяц, а потом мы оптимизировали процессы и сократили цикл до 1 релиза в день.
Я хочу больше работать с масштабируемыми системами. В моей текущей компании не так много сложных архитектурных задач, поэтому я ищу новый вызов.
Спасибо за предложение! На основе рынка и моего опыта я рассчитывал на 230–250 тыс. Есть ли возможность пересмотреть?
Как говорить про проект на собеседовании: 3 удачные схемы
Что делает большинство?
Ну… это был корпоративный портал. Мы там использовали Spring. И делали интеграцию с 1С. Я там пилил фичи.
Бизнес хотел ускорить расчёт скидок в корзине: было слишком медленно, 3+ секунды. Я переписал калькулятор на чистом Java, оптимизировал SQL-запросы и закешировал правила. Это был отдельный сервис на Spring Boot с Redis и асинхронной обработкой. Время ответа – 300 мс.
Делали сервис нотификаций для внутренних систем. При получении события генерировались уведомления по шаблону и отправлялись через Kafka -> Email/Push. Использовали Spring Cloud Stream, FreeMarker, RetryTemplate, Prometheus, Zipkin для трейсинга.
Была монолитная система, которую тяжело было масштабировать. После перехода на микросервисы – катим фичи независимо, проще локализовать баги, уменьшили время отклика на 30%. Внедрили Spring Cloud, API Gateway, Eureka, и распилили 3 ключевых модуля: аутентификацию, биллинг и отчёты.
Пет-проекты не нужны
Ты уже долго работаешь на одном месте, хочешь сменить работу, попробовать новый стек, чувствуешь, что отстал от рынка, или решаешь просто прокачать резюме.
И вот первая мысль:
А может, мне сделать пет-проект? Ну, типа… TODO-лист или трекер задач.
Карточки про синхронизаторы Java
Синхронизаторы позволяют управлять потоками более гибко, мощно и безопасно, чем низкоуровневые и примитивные synchronized, wait, notify и join.
Примеры использования:
– Ограничить количество одновременных действий
– Дождаться завершения нескольких потоков
– Запустить все потоки одновременно
– Обменяться данными между потоками
Виды:
– Semaphore
– CountDownLatch
– CyclicBarrier
– Phaser
– Exchanger
Вечный Junior
С Антоном мы пересеклись на одном митапе, когда он работал джуном в аутстаффе уже 3 года.
Джуном 3 года, Карл!
Никакого роста и архитектурных задач. Ревью – формальность. Сеньоры заняты, а тимлид кидает таску и исчезает. Джуниорская вилочка и бесконечное "ещё не время".
Он чувствовал себя застрявшим.
И он был прав.
Но он боялся.
Боялся собеседований, общения с hr, рассказов о своем опыте.
«А вдруг я не пройду собес?»
«А вдруг я ничего не умею?»
«А вдруг я уйду, и окажется, что я действительно слабый?»
Правда в том, что это нормальное состояние.
Так чувствуют себя многие, кто остался без настоящей обратной связи и без возможности развиваться.
И это не их вина.
Это можно исправить.
Но нужен план, поддержка и кто-то, кто скажет: «Ты не тупой, просто ты слишком долго был один в этом болоте».
Я понимал, что могу помочь Антону, направить его в правильное русло.
Но раньше я никогда не менторил разработчиков не из своей команды.
Как и для Антона, так и для меня это был вызов.
И мы оба решили действовать.
С первого же созвона я понял – у Антона есть потенциал. Просто его никто не видел. А он сам – не знал, как его раскрыть.
Что мы сделали?
– Выявили пробелы в знания
– Прокачали многопоточку и алгоритмы
– Написали пет-проект с популярными технологиями
– Переписали резюме
– Провели мок-собеседование
– Разобрали реальные собеседования
– Обсудили его страхи
И вот спустя два месяца:
– Несколько офферов
– Один из бигтех
– Уровень мидл
– Доход x2
Главное – он обрел уверенность и понятный план развития до сеньора.
И знаешь, что самое интересное?
Ты можешь так же.
Ты можешь оставаться в болоте – или пойти по пути роста.
Ты можешь бояться – или готовиться и пробовать.
Ты можешь ждать, пока настанут времена получше – или взять и вытащить себя на новый уровень уже сейчас.
Выбор только за тобой.
Как выделиться среди других кандидатов, когда спрашивают про Transactional в Spring
Рассказать про механизмы создания прокси: JDK Dynamic Proxy, CGLIB, Byte Buddy.
Согласись, ответ «спринг использует несколько вариантов создания прокси, могу рассказать про каждый» звучит более экспертно, чем «ну там прокси используются».
Поэтому разберём отличия.
JDK Dynamic Proxy
Используется, если класс реализует интерфейс.
Встроен в JDK (java.lang.reflect.Proxy
), лёгкий, быстрый, прост в отладке.
Работает только с интерфейсами.
CGLIB
Используется, если класс не реализует интерфейс.
Основан на наследовании – создаёт подкласс твоего класса с переопределёнными методами.
Не требует интерфейсов.
Не работает с final
классами и методами, менее прозрачен в отладке.
Byte Buddy
Используется в более гибких и низкоуровневых сценариях (Spring Actuator, Spring DevTools, Mockito, APM-агенты).
Генерирует или модифицирует байткод в рантайм, без ограничения интерфейсами или наследованием.
Безумно гибкий, работает даже с final
классами и методами (если использовать javaagent
).
Какой прокси используется в Transactional
В AOP используется JDK Dynamic Proxy или CGLIB.
Если есть интерфейс – JDK Dynamic Proxy.
Если нет – CGLIB.
Есть возможность всегда использовать CGLIB, указав proxyTargetClass=true
.
Можно легко понять, какой механизм используется, посмотрев в дебаг:
– JDK Dynamic Proxy: com.sun.proxy.$Proxy32
– CGLIB Proxy: MyService$$EnhancerBySpringCGLIB$$abc123
хочешь узнать как застать интервьюера врасплох на вопросах про прокси, ставь 🔥 и разберем в следующем посте.
Если
Извините, но мы не готовы сделать вам предложение
Я получал это сообщение десятки раз.
Оно всегда приходит холодным текстом. Без эмоций. Без объяснений.
И каждый раз – будто удар в поддых.
⠀
Ты читаешь и замираешь.
Ощущение, как будто тебе сказали:
Ты недостаточно хорош. Мы посмотрели на тебя – и решили, что ты не подходишь.
Может, я переоценил свой уровень?
А вдруг я уже не дотягиваю до рынка?
Может, мне стоит бросить java и уйти во что-то полегче?
Как один Scheduled превратился в DDoS на наш собственный сервис
Есть у нас микросервис, который раз в секунду проверяет статусы задач.
Обычный @Scheduled(fixedRate = 1_000)
Работал год – вообще без проблем.
Вычитывал из бд задачи, проверял статусы и обновлял другие таблицы.
А потом мы немного добавили логики:
– запросы к бд стали тяжелее
– появились внешние вызовы
– и, внимание, время выполнения стало больше секунды
Что это значит?
Scheduler с fixedRate не ждёт окончания предыдущей задачи.
Он просто запускает новую копию метода каждую секунду.
Из-за того, что предыдущий метод не успел завершиться и внести изменения в бд, новый метод работал со старыми данными и делал всю ту же работу, что и первый метод.
И вот у нас уже 5 потоков, 10, 15…
Потребление cpu взлетает.
Внешние системы начинают отваливаться, потому circuit breaker мы не добавили, подумав «ну что тут может случиться».
По факту мы устроили себе локальный DDoS.
Благо обнаружили мы это очень быстро, потому что у нас есть алерты на замедления.
В итоге мы поменяли fixedRate на fixedDelay и проблема ушла.
Поэтому не доверяй слепо аннотациям – понимай, как они работают внутри.
Роадмап подготовки к Java собеседованиям
Цель роадмапа – предоставить список тем и источников для быстрой подготовки к собеседованиям.
Темы:
– Java (архитектура jvm, gc, многопоточность)
– Spring (aop, transaction, cloud)
– SQL/NoSQL (acid, base, уровни изоляций, explain)
– Kafka/Docker/Kubernetes
– Паттерны проектирования, ООП, SOLID
– Алгоритмы и структуры данных
– Системный дизайн
📋 Полную версию роадмапа со всеми темами и источниками забирай по кнопке ниже 👇
Почему нельзя слишком долго сидеть в комфортной компании
У меня хорошая команда.
Меня никто не трогает.
Зарплата – ну, нормально.
Проект – обычный, но вроде стабильный.
Можно потерпеть ещё годик-другой.
Отдых – это часть работы
На этих выходных я отправился в Карелию. Без ноутбука, без интернета, без Jira.
Я отключился от рабочих задач и позволил себе просто быть.
Знаете, что самое интересное?
Впервые за долгое время я почувствовал, что отдохнул по настоящему.
Не просто "не работал", а молчал, смотрел, дышал.
Мы постоянно живем в каком-то аврале: еще одна таска, еще один фикс, еще один фреймворк.
И в какой-то момент ты замечаешь: код работает эффективно, а ты – нет.
Когда ты пашешь без отдыха, ты не становишься героем. Ты становишься медленным, неэффективным и уставшим.
Ты решаешь отдохнуть. Но ты путаешь отдых с отвлечением.
Посмотреть YouTube или поиграть в GTA это не отдых.
Настоящий отдых это смена режима. От "анализировать и держать все в голове" к "отпустить и наблюдать".
Устраивай себе один выходной в неделю без IT-контекста вообще.
Никаких курсов, pet-проектов, видео "как стать ещё лучше".
Выйди на природу (лес, вода, любое место без визуального шума).
Твой мозг нуждается в "тишине", чтобы потом создать что-то по-настоящему стоящее.
Я, как и ты, часто чувствую вину за отдых.
Но отдых это не слабость. Это стратегия.
Необходимо научиться системно встраивать отдых в рабочий процесс, чтобы не сгореть.
А теперь факты:
После 50 часов работы в неделю производительность резко падает, а количество ошибок – растёт. Исследование
Мозг в покое (когда ты, казалось бы, "ничего не делаешь") активирует Default Mode Network – зону, где рождаются идеи, креатив и долгосрочные решения. Исследование
Сон и отдых усиливают нейропластичность – способность мозга адаптироваться, обучаться, решать нестандартные задачи. Исследование
Вывод: хочешь думать лучше – перестань работать постоянно и отдыхай.
«Чистый код» – вредная книга?
Да, если читать её как библию.
Однажды ко мне на ревью пришёл молодой и воодушевленный разработчик.
Он только что прочитал «Чистый код» Роберта Мартина – и пришёл в полном восторге.
Методы у него были максимум по 5 строк.
Всё строго по SRP.
Комментарии удалены.
Названия переменных по 12 слов, чтобы «говорили сами за себя».
А читать этот код было невозможно.
И тогда я понял:
«Чистый код» – это не книга. Это оружие. И как любое оружие – оно может ранить. Особенно в руках новичков.
Стоит ли в 2025 году учить Spring Boot, если есть Quarkus и Micronaut?
Обсудим, как оно происходит в реальных проектах, а не на хайповых митапах.
1. Почему Spring всё ещё нужен
Когда ты учишь Spring, ты получаешь не просто знание одной библиотеки.
Ты получаешь:
– Понимание подходов к проектированию, которые стали стандартом в мире Java
– Навык строить интеграционные решения (Kafka, PostgreSQL, Redis, ElasticSearch) через готовые стартеры
– Умение работать с мониторингом и продакшн-инфраструктурой (Actuator, Sleuth, Zipkin, Prometheus, Cloud)
– Глубокую связь с реальным бизнесом (90% финансового сектора, банков, страховых компаний используют Spring)
Spring сегодня это фактически стандарт корпоративной разработки на Java.
Пока ты его не знаешь – вход на собеседования закрыт.
2. Почему появились Quarkus и Micronaut и в чём их реальный профит
Quarkus и Micronaut родились не на пустом месте.
Они решают конкретную проблему: производительность.
Spring Boot приложение:
– Стартует 5-10-30 секунд (особенно если много контекста)
– Жрёт память прилично
– Поднимает много всего "на авось" (через автоконфигурации)
Quarkus и Micronaut говорят:
– Мы стартуем за 100 миллисекунд
– Мы используем AOT компиляцию
– Мы готовы к GraalVM и native-образам для serverless решений
Это действительно важно, если ты:
– Пишешь микросервисы для облаков типа AWS Lambda, Azure Functions
– Оптимизируешь стоимость биллинга в облаке (меньше памяти = дешевле)
– Работаешь над системами с требованием "холодного старта" в доли секунд
Но...
Когда ты разрабатываешь огромную корпоративную систему из сотен микросервисов, 30 секунд старта роли почти не играет.
Тебя интересуют:
– Стабильность
– Тестируемость
– Наличие специалистов
– Богатая экосистема библиотек
И здесь Spring пока безальтернативен.
3. Реальные кейсы из жизни
Проект 1 (финтех):
Сервис управления кредитными историями. Java 17, Spring Boot 3.
Выбирали между Micronaut и Spring.
Выбрали Spring, потому что нужно было быстро найти команду из 5+ разработчиков, а рынок по Spring в разы больше.
Проект 2 (стартап в e-commerce):
Сервис обработки заказов в serverless-инфраструктуре AWS.
Выбрали Micronaut + AOT. Потому что cold start критичен: 50 миллисекунд против 5 секунд имеет значение в деньгах.
Проект 3 (госзаказ):
Огромная система документооборота. Строгие требования к надёжности.
Только Spring Boot. Потому что есть готовые решения для безопасности и аутентификации через OpenID и LDAP.
4. Когда стоит учить Quarkus или Micronaut
Если ты хочешь:
– Специализироваться в cloud-native решениях
– Работать с serverless архитектурами
– Любишь экспериментировать и быть на острие технологий
То да, изучение Quarkus и Micronaut даст тебе фору перед теми, кто застрял только в "традиционном" Spring.
Но без понимания принципов, которые дал тебе Spring, ты рискуешь строить неуправляемую архитектуру и натыкаться на больные углы DI, транзакций и обработки ошибок.
5. Что будет дальше?
Моё личное мнение, Spring останется ещё минимум 5-7 лет доминирующим стеком в Java-разработке.
Он меняется. Он уже поддерживает полный AOT-подход (Spring Boot 3 + Spring Native).
Он идёт к компактности, но остаётся зрелым.
Тот, кто хорошо знает Spring – освоит любой новый фреймворк за пару недель.
Тот, кто учит только новые фреймворки – будет тратить месяцы на догонку базовых концепций.
Итог
Учи Spring Boot.
Он даст тебе фундамент.
А потом – осваивай Quarkus, Micronaut, Helidon и другие инструменты.
Так ты будешь не просто кодером, а инженером, который умеет выбирать технологию под задачу, а не под хайп.
Выстрел в ногу через @Transactional
Плавающий баг, который не могли поймать неделями.
Дано:
– Два микросервиса
– У каждого своя база данных
– Первый микросервис записывает в бд информацию об операции и отправляет событие в kafka
– Второй микросервис вычитывает это событие, обрабатывает его и сохраняет результат в свою бд
Классика.
Записали в бд, кинули событие.
Что может пойти не так?
Как оказалось, многое.
Через месяц после релиза аналитики заметили расхождение.
Количество записей в базах данных двух микросервисов не совпадало.
Во втором микросервисе записей было больше, чем в первом.
Начали копать.
В кибана ни error, ни warn логов нет.
Но с каждой неделей расхождение в базах данных становилось все больше.
Не на много. Всего лишь на несколько записей. В рамках нескольких десятков тысяч не такой уж и существенный процент.
Плавающий баг, с которым никто не хочет разбираться и закрывает на него глаза.
Каждый успокаивал себя тем, что это инфраструктурная проблема, которая сама когда-нибудь решится.
Но шел уже второй месяц, а проблема никуда не девалась.
Всех это уже начало раздражать и я решил найти корень проблемы.
Для начала я посмотрел, а как же первый микросервис записывал в бд и отправлял в kafka.
Делал он это примерно так:
@Transactional
public void registerOp(OpDto dto) {
opRepository.save(dto.toEntity());
kafkaTemplate.send("topic-name", dto);
}
Стоит ли соглашаться на оффер, если от тебя требуют быстрый ответ?
Ты прошел собеседование, получил оффер, но вдруг…
Нам нужно ваше решение до завтра
Если не ответите в течение 24 часов, мы предложим оффер другому кандидату
Спасибо за оффер! Хочу всё внимательно взвесить, чтобы принять осознанное решение. Смогу дать ответ в понедельник.
Я понимаю, что вам важно закрыть позицию быстро. Но для меня это серьёзное решение, и мне нужно несколько дней на его обдумывание.
На данный момент у меня есть другие офферы, поэтому мне нужно немного времени, чтобы сравнить предложения.
Как справиться со стрессом на собеседовании?
Ты заходишь в zoom, ждёшь подключения интервьюера…
Руки потеют, сердце колотится, в голове пустота.
Что делать, чтобы не слить собеседование из-за стресса?
Сегодня рассмотрим систему, как успокоиться, включить концентрацию и не завалить собеседование.
1. Почему стресс убивает твой шанс на оффер?
Когда ты нервничаешь, мозг переключается в режим «бей или беги»
– Кровь уходит в мышцы (а не в лобные доли мозга)
– Логика и память проседают
– Ты начинаешь заикаться, путаться, тупить
И даже если ты знаешь ответ — в стрессовом состоянии ты не сможешь его нормально объяснить.
Наша цель — войти в собеседование спокойным и собранным.
Как это сделать?
2. Подготовка за 24 часа до собеседования
Уменьши неопределённость
Чем меньше неожиданностей, тем спокойнее.
Что делать?
– Узнай у рекрутера структуру собеседования
– Проверь, кто будет интервьюером
– Потестируй софт
Мозгу станет проще, когда он знает, чего ждать.
Проведи тестовое собеседование (но правильно)
Не нужно заучивать — это не помогает.
Прогоняй мысли вслух!
– Поставь камеру, запиши, как ты отвечаешь
– Слушай себя: звучит уверенно или нет?
– Попробуй объяснить задачу своему другу
Главная цель — научиться говорить спокойно и чётко.
Выспись и отдохни
Звучит банально?
Но если ты недоспишь, мозг работает на 20-30% хуже.
– Спи 7-8 часов перед собеседованием
– Не зубри ответы в ночь перед собеседованием — только закрепляй
Отдохнувший мозг лучше решает задачи.
3. За 1 час до собеседования
1.5 минуты физической активности
Доказано, что короткая нагрузка снижает уровень кортизола (гормона стресса).
– Сделай 10-15 отжиманий или приседаний
– Пройди пешком 5-10 минут
– Потянись, разомни шею и плечи
Ты сбросишь лишнее напряжение и соберёшься.
4. Настрой себя правильно
Не думай: «А вдруг я завалю?»
Думай: «Сейчас я покажу, на что способен»
– Вспомни свои сильные стороны
– Напомни себе: «Я не обязан знать всё, главное - думать вслух»
– Визуализируй процесс: представь, как ты спокойно отвечаешь
Твой настрой — 50% успеха.
5. Во время собеседования: как не терять концентрацию?
Если завис — говори вслух
Когда стресс растёт, мозг замирает. Но если ты начинаешь говорить, ты «размораживаешь» мышление.
Правильная фраза, если завис: «Хороший вопрос. Давайте разберём его по шагам…»
Так ты даёшь себе время на обдумывание.
Фокусируйся на процессе, а не на результате
«Я должен получить оффер» – лишнее давление.
«Я просто покажу, как мыслю» – расслабленность и концентрация.
Сконцентрируйся на задаче, а не на страхе.
Итог: как войти на собеседование спокойным и уверенным?
1. За день: уменьши неопределённость, протестируй оборудование, выспись
2. За час: сделай разминку, настройся
3. Во время: размышляй вслух, фокусируйся на процессе