Как я проверяю архитектурное мышление на собеседованиях одной задачей
- пятница, 27 марта 2026 г. в 00:00:11
Всем привет!
Недавно мне нужно было нанять людей в команду по созданию системы на Python, Java, Go. Для меня крайне важны соблюдения принципов SOLID, Чистой архитектуры, Чистого кода.
Я придумал задачу, которую спрашиваю на собеседованиях в свою команду. И мне хочется поделиться ею с вами.
Надеюсь, она будет вам полезна!
Для Go
Представь, у тебя есть структура, которая считает зарплату сотрудника: его KPI, премии и т. п., и создает PDF-отчет. Тебе нужно создать структуру для подсчета зарплаты и генерации отчета по менеджеру.
Учти, что премия и KPI у них одинаковый процент от зарплаты. Отличие лишь в том, что менеджер получает больше.Также, учти, что система будет жить долго и в нее должно быть легко вносить изменения
Как ты это реализуешь?
Для языков где есть классы
Представь, у тебя есть класс, который считает зарплату сотрудника: его KPI, премии и т. п., и создает PDF-отчет. Тебе нужно создать класс для подсчета зарплаты и генерации отчета по менеджеру. Учти, что премия и KPI у них одинаковый процент от зарплаты. Отличие лишь в том, что менеджер получает больше.
Также, учти, что система будет жить долго и в нее должно быть легко вносить изменения
Как ты это реализуешь?
Задача звучит просто, но в этом и ее коварность.
Можете написать свое решение и ваш уровень в комментариях)
Представь, у тебя есть структура, которая считает зарплату сотрудника: его KPI, премии и т. п., и создает PDF-отчет. Тебе нужно создать структуру для подсчета зарплаты и генерации отчета по менеджеру. Учти, что премия и KPI у них одинаковый процент от зарплаты. Отличие лишь в том, что менеджер получает больше. Как ты это реализуешь? Это архитектурная задача для Go, не пиши код, просто объясни словами, как бы ты реализовал это. Пиши кратко и опиши каждый шаг для создания правильной архитектуры.
Для реализации этой архитектуры в Go я бы использовал композицию и интерфейсы, следуя принципам SOLID.
1. Выделение базовой сущности
Создал бы общую структуру Employee (или BaseSalaryCalculator), содержащую общие поля: базовую ставку, процент KPI, процент премии. В ней реализовал бы общие методы расчета — например, CalculateBase(), CalculateKPI(), CalculateBonus().
2. Определение интерфейса
Ввел бы интерфейс SalaryCalculator с методом CalculateSalary() *Report. Это позволит легко добавлять новые типы сотрудников, не меняя существующий код генерации отчетов.
3. Композиция для менеджера
Создал бы структуру Manager, которая встраивает Employee (композиция, а не наследование). Это дает все базовые поля и методы. Отличие менеджера (большая зарплата) реализовал бы через:
Либо переопределение метода CalculateSalary(), где вызывается родительский расчет, а затем применяется повышающий коэффициент.
Либо через отдельный параметр coefficient в структуре Manager, который учитывается при финальном расчете.
4. Отделение генерации отчета
Создал бы отдельный пакет или структуру ReportGenerator, который принимает интерфейс SalaryCalculator. Это разделяет ответственность: расчет зарплаты не зависит от формата вывода (PDF). Генератор получает готовые числовые данные и формирует PDF.
5. Фабрика или конструкторы
Для удобства добавил бы функции-конструкторы (NewEmployee, NewManager), чтобы гарантировать корректную инициализацию и скрыть внутреннюю логику расчета от клиентского кода.
6. Тестируемость
Такая архитектура позволяет легко тестировать каждый компонент изолированно:
базовый расчет, логику менеджера и генерацию отчета отдельно, подставляя моки.
Учитывая, что ИИ не может задавать вопросов, его решение имеет место быть, но оно недостаточно гибкое, и вот почему:
На первый взгляд решение выглядит добротно: есть интерфейс SalaryCalculator, есть отдельный ReportGenerator, композиция вместо наследования. Но есть одна ошибка.
ИИ создал один генератор отчетов для всех. Он принял как данность, что отчет для сотрудника и менеджера одинаковый, и заложил это в архитектуру.
А что будет, когда завтра бизнес скажет:
«В отчете менеджера нужно показывать количество подчиненных»
«У сотрудника добавить график выполнения KPI по месяцам»
При текущей архитектуре у нас два пути:
Напихать if employee.Type == "manager" внутрь ReportGenerator
Переписывать архитектуру с нуля
Ни один из них не подходит для поддерживаемой системы.
Более гибко было бы:
Добавить интерфейс, который реализуют классы-шаблоны для отчетов, и еще один, который реализуют классы расчета ЗП.
Каждый шаблон сам знает свой класс. В нем хранится ссылка на класс расчета ЗП для этого типа сотрудника.
Фабрика отчетов принимает интерфейс и не знает, кто именно пришел — сотрудник или менеджер.
Эти проблемы, нужны для того, чтобы кандидат обратил на них внимание, и исправил или начал задавать вопросы и с учетом ответов выдавать свое решение.
класс, который считает ЗП сотрудника ... и создает отчет
Большинство кандидатов даже не замечают нарушения SRP. Они берут условие как данность и начинают наследоваться от этого класса. А правильно — сначала сказать: «Этот класс делает две вещи, давайте разделим».
Учти, что премия и KPI у них одинаковый процент от ЗП
Кандидат слышит «одинаковые» и думает: «Ну раз одинаковые, можно обобщить». У сотрудника и менеджера разные причины для изменения формулы расчёта. Сегодня они одинаковы, а завтра — нет. Вероятность изменения расчета премии для менеджера или сотрудника низкая, но может меняться каждый месяц. Также мы можем добавлять новые сущности. Поэтому важно их разделять
Отличается только оклад
Фраза «отличается только оклад» создаёт иллюзию, что менеджер — это просто сотрудник с большей цифрой. Менеджер — другая бизнес-сущность с другими KPI, другими зонами ответственности и другими причинами для изменения системы мотивации.
В этой задачи важно:
Какие вопросы задает кандидат. Как он на них основывает свои решения.
Какие плюсы и минусы он видит в своем решении
Как он планирует действовать при внесении изменений в систему
Я привел одно из возможных решений. Но кандидат может предложить другое — я буду оценивать аргументацию, а не совпадение с моим вариантом.
Разделить расчет ЗП и создание отчета на разные модули.
Разделить расчет ЗП и создание отчета на разные классы/структуры для работника и менеджера.
Создать фабрику для генерации PDF-отчетов, чтобы она принимала на вход структуры/классы, которые реализуют определенный интерфейс, который будет гарантировать, что они имеют нужные методы.
Также структуры для расчета ЗП должны реализовывать свой интерфейс, который будет гарантировать, что они имеют все методы, нужные для создания отчета. А в шаблоне отчета сохранять ссылку на класс расчета ЗП для этого типа сотрудников.

Надеюсь, эта задача будет для вас полезна и вы возьмете ее на вооружение :-)