
Я занимаюсь собеседованиями бэкенд-разработчиков уже более десяти лет.
У некоторых было впечатляющее резюме. Некоторые работали в компаниях с громкими именами. У некоторых жирным шрифтом было написано «Опыт работы 10+ лет».
И всё же… на собеседовании многие из них проваливались. Не из-за синтаксиса. Не из-за фреймворков. А из-за фундаментальных бэкенд-концепций, которые они якобы «отлично» знали.
Эта статья — не для того, чтобы кого-то оскорбить. Ее цель — показать разрыв между годами стажа и реальным пониманием.
Потому что, проинтервьюировав десятки кандидатов на должность старшего бэкенд-разработчика, я заметил четкую закономерность.
Одни и те же 12 концепций неизменно отделяют настоящих старших разработчиков от тех, кто только числится в этой должности.
1. Потокобезопасность: все о ней знает, мало кто понимает
Когда я спрашиваю: «Этот код потокобезопасен?», большинство ответов начинаются так: «Да, потому что мы использовали ключевое слово synchronized».
И здесь-то и начинается проблема.
Что их подводит?
Они думают, что потокобезопасность = ключевое слово synchronized. Настоящее понимание означает знание:
- что такое разделяемое изменяемое состояние;
- почему возникают условия гонки;
- как возникают проблемы видимости даже без условий гонки;
- почему одной атомарности недостаточно.
Я задаю уточняющие вопросы:
- Что произойдет без синхронизации на многоядерных процессорах?
- Зачем нужно ключевое слово volatile?
- Когда ключевое слово synchronized не требуется?
Обычно в ответ — молчание.
Старший бэкенд-разработчик должен понимать суть многопоточности, не ограничиваясь заучиванием ключевых слов.
2. Индексы в базе данных: используются ежедневно, понимаются редко
Почти все говорят: «Индексы повышают производительность».
Но ответы становятся расплывчатыми, когда я спрашиваю:
- Как именно?
- Что происходит внутри?
- Когда индекс замедляет работу?
Что их подводит?
Они не понимают:
- для чего используются B-деревья и хэш-индексы;
- почему важна селективность индекса;
- почему слишком много индексов замедляет запись;
- почему индекс может вообще не использоваться.
Некоторые даже убеждены: «Добавление индексов всегда повышает производительность».
Это мышление разработчика-новичка.
Старшие разработчики понимают компромиссы, а не только преимущества.
3. Транзакции: одного ACID недостаточно
Большинство кандидатов могут перечислить принципы ACID: atomicity (атомарность), consistency (согласованность), isolation (изолированность), durability (долговечность).
Но обычно на этом их знания заканчиваются.
Что их подводит?
Они не могут объяснить:
- Как на самом деле работают уровни изоляции?
- Разницу между READ COMMITTED и REPEATABLE READ.
- Почему возникают фантомные чтения?
- Как MVCC (Multiversion Concurrency Control — многоверсионное управление конкурентным доступом) решает многие из этих проблем?
Однажды я спросил: «Почему уровень изоляции READ COMMITTED все равно допускает неповторяющееся чтение?»
В комнате повисла тишина.
Вызубрить ACID — не значит понимать, как работают транзакции.
4. REST: все создают API, но не все проектируют их правильно
Почти каждый бэкенд-разработчик работает с REST API.
Но многие проваливают простой вопрос: «Что делает API по-настоящему RESTful?»
RESTful — соответствующий архитектурному стилю REST (representational state transfer — передача состояния представления).
Что их подводит?
Они думают, что REST — это просто:
- HTTP + JSON.
Они забывают о ключевых принципах:
- правильном использовании HTTP-методов;
- идемпотентности;
- статус-кодах;
- URL’ах, ориентированных на ресурсы;
- отсутствии фиксации состояния (statelessness).
Когда кто-то использует POST для всего подряд и всегда возвращает 200 OK — это явный признак проблемы.
Старшие разработчики проектируют API, а не просто реализуют конечные точки.
5. Кэширование — самый опасный инструмент для повышения производительности
Кэширование — мощный инструмент.
И именно поэтому он опасен.
Многие кандидаты говорят: «Мы добавили Redis и решили проблему производительности».
Что их подводит?
Они игнорируют:
- недействительность кэша (когда данные становятся неактуальными);
- согласованность данных между кэшем и источником;
- проблемы устаревших данных;
- проблемы «давки» в кэше (одновременного массового построения одного и того же результата и его записи в кэш).
Я спрашиваю: «Что происходит, когда кэшированные данные устаревают?»
Большинство ответов: «Мы очищаем кэш».
Это не стратегия. Это наивный подход.
Старшие разработчики знают: в информатике есть только две сложные вещи: недействительность кэша и присвоение имен.
6. Микросервисы — модный тренд, используемый где надо и не надо
Если в резюме соискателей упоминаются микросервисы, я копаю глубже.
Что их подводит?
Они не могут объяснить:
- Почему система была разделена?
- Какую проблему решили микросервисы?
- Какие новые проблемы они создали?
Многие думают, что микросервисы = сервисы меньшего размера.
Они не учитывают:
- задержки в сети;
- распределенные сбои;
- согласованность данных;
- сложность мониторинга.
Некоторым системам никогда не стоит становиться микросервисами.
Старшие разработчики понимают, когда их не следует использовать.
7. Логирование — не то же самое, что использование print-операторов
Логирование игнорируется многими разработчиками до тех пор, пока не произойдет сбой в производственной среде.
Что их подводит?
Они:
- пишут слишком много или слишком мало логов;
- ведут логи без структуры;
- невольно регистрируют конфиденциальные данные.
Я спрашиваю: «Что делает лог подходящим для производственной среды?»
Лишь единицы упоминают:
- идентификаторы корреляции;
- уровни логирования;
- Контекстную информацию;
- возможность поиска по логам.
Старшие разработчики ведут журналы для отладки в 3 часа ночи, а не только для удобства разработки.
8. Управление памятью: сборщик мусора (GC) не всемогущ
Многие бэкенд-разработчики слепо доверяют сборщику мусора.
Что их подводит?
Они верят в то, что GC все уладит.
Они не могут объяснить:
- утечки памяти в автоматически управляемых языках;
- разницу между кучей и стеком;
- как выделение объектов влияет на производительность;
- почему возникают длительные паузы GC.
Однажды я спросил: «Может ли в Java-приложении возникать утечка памяти?»
Половина кандидатов ответила: «Не может».
Этого ответа уже достаточно, чтобы провалить собеседование.
9. Обработка ошибок: исключения не являются управляющей конструкцией
На этом отсеиваются многие соискатели.
Что их подводит?
Они:
- ловят общие исключения;
- «проглатывают» ошибки (оставляют блок catch пустым);
- использует исключения для обычной логики.
Когда я спрашиваю: «Что делает эффективным ответ на ошибку?»
Многие затрудняются объяснить:
- понятность сообщения об ошибках;
- корректные статус-коды HTTP;
- четкое разделение ошибок клиента и сервера.
Старшие разработчики рассматривают ошибки как часть проектирования системы, а не как нечто второстепенное.
10. Масштабируемость — не то же самое, что производительность
Многие соискатели путают масштабируемость с производительностью.
Что их подводит?
Они рассуждают так: «Если система быстрая, значит, она масштабируема».
Они не могут объяснить:
- вертикальное и горизонтальное масштабирование;
- узкие места;
- преимущества stateless-архитектуры (без сохранения состояния) для масштабирования;
- Почему разделяемое состояние (shared state) губит масштабируемость
Я спрашиваю: «Может ли быстрая система выйти из строя под нагрузкой?»
Если соискатель отвечает «нет» — это уже проблема.
11. Безопасность — задача не разработчика
Многие разработчики отодвигают проблему безопасности на второй план.
Что их подводит?
Они полагаются исключительно на «безопасность фреймворка».
Они игнорируют:
- SQL-инъекции;
- разницу между аутентификацией и авторизацией;
- истиечение срока действия токенов;
- правильное хранение паролей.
Я спрашиваю: «Как бы вы обеспечили безопасность этой конечной точки?»
И получаю ответ: «Spring Security с этим разберется».
Это не ответственность. Это уклонение от решения проблем.
12. Компромиссное мышление — главный отличительный признак старшего разработчика
Это самый важный момент, о котором не догадываются многие соискатели.
Что их подводит?
Они мыслят категориями абсолютов:
- «это всегда лучшее”;
- «это — плохо»;
- «надо всегда делать только так».
Старшие разработчики мыслят в терминах компромиссов и поиска баланса:
- скорость или стабильность;
- простота или гибкость;
- быстрый выход на рынок или обеспечение долгосрочной поддержки.
Я всегда спрашиваю: «Что бы вы изменили, если бы завтра трафик удвоился?»
Лучшие ответы начинаются со слов: «Это зависит от…»
Это не колебания.
Это опыт.
Читайте также:
- Изучаем GraphQL: Простое дополнение к вашему бэкенд-стеку
- Я понял разницу между SQL и NoSQL — и мой бэкенд заработал быстрее
- Архитектура BFF — бэкенд для фронтенда
Читайте нас в Telegram, VK и Дзен
Перевод статьи Pudari Madhavi: These 12 Backend Concepts Quietly Decide Who Passes Senior Interviews





