Критерии оценки финального проекта — Методическое руководство
Общая структура оценки
| Раздел | Вес | Max баллов |
|---|---|---|
| Полнота и качество SRS | 25% | 25 |
| Корректность диаграмм (UML + BPMN) | 25% | 25 |
| Связность артефактов (Traceability) | 20% | 20 |
| Качество тест-кейсов | 15% | 15 |
| Защита и ответы на вопросы | 15% | 15 |
| Итого | 100% | 100 |
1. Детальная матрица оценок для каждого артефакта
1.1. SRS-документ (25 баллов)
| Критерий | Max баллов | 0 баллов | 0.5 балла | 1 балл |
|---|---|---|---|---|
| 1.1. Введение (цель, область применения) | 2 | Отсутствует или «вода» | Есть, но неполно | Чётко описаны цель, область, границы |
| 1.2. Глоссарий | 2 | Отсутствует | < 10 терминов | 10+ терминов с чёткими определениями |
| 1.3. Пользователи и роли | 2 | Отсутствуют | Роли есть, но без описания прав | Таблица ролей с правами и описанием |
| 1.4. FR: полнота (5+ требований) | 4 | < 3 FR | 3–4 FR | 5+ FR с уникальными ID |
| 1.5. FR: Acceptance Criteria (минимум 3 на каждое) | 4 | Нет AC | AC для части FR | AC для каждого FR, минимум 3 |
| 1.6. NFR: полнота (3+ требования с метриками) | 4 | < 2 NFR | 2 NFR с метриками | 3+ NFR с измеримыми метриками |
| 1.7. Data Dictionary | 4 | Отсутствует | Неполный (нет типов/FK) | Все сущности ERD, с типами, FK, ограничениями |
| 1.8. Описание As-Is / To-Be | 3 | Отсутствует | Есть, но поверхностно | Подробно: проблема, цифры, ожидаемый эффект |
| Итого SRS | 25 |
1.2. UML и BPMN диаграммы (25 баллов)
| Критерий | Max баллов | 0 баллов | 0.5 балла | 1 балл |
|---|---|---|---|---|
| 2.1. Use Case Diagram | 5 | Отсутствует или не по нотации | Есть, но неполно (пропущены актёры/UC) | Все актёры из SRS, все UC, отношения |
| 2.2. Activity / BPMN Diagram | 7 | Отсутствует | Есть, но линейная (нет gateway) | Есть gateway, роли, ошибки, default flow |
| 2.3. Sequence Diagram | 7 | Отсутствует | Только Happy Path, нет alt | Синхр/асинхр вызовы, alt для ошибок |
| 2.4. Class Diagram | 6 | Отсутствует | Неполный (нет атрибутов/методов) | Полный: классы, атрибуты, связи, multiplicity |
| Итого диаграммы | 25 |
1.3. Трассируемость (20 баллов)
| Критерий | Max баллов | 0 баллов | 0.5 балла | 1 балл |
|---|---|---|---|---|
| 3.1. FR → Use Case → API → Test | 5 | Нет связи | Частично | Полная таблица маппинга |
| 3.2. ERD → Data Dictionary → OpenAPI | 5 | Нет связи | Частично | Все сущности мапятся на схемы |
| 3.3. Нет orphan-артефактов | 5 | Есть orphan | 1–2 orphan | 0 orphan |
| 3.4. Все ID уникальны, нет пропусков | 5 | Дубли/пропуски | 1–2 ошибки | Идеально |
| Итого трассируемость | 20 |
1.4. Тест-кейсы (15 баллов)
| Критерий | Max баллов | 0 баллов | 0.5 балла | 1 балл |
|---|---|---|---|---|
| 4.1. Минимум 5 тест-кейсов | 3 | < 3 | 3–4 | 5+ |
| 4.2. Структура (Preconditions, Steps, Expected) | 4 | Нет структуры | Неполная | Полная структура у каждого |
| 4.3. Покрытие (Happy + Error + Security) | 4 | 1 тип | 2 типа | 3+ типа |
| 4.4. Связь с FR | 4 | Нет связи | Неявная | Явная ссылка на FR-ID |
| Итого тест-кейсы | 15 |
1.5. Защита (15 баллов)
| Критерий | Max баллов | 0 баллов | 0.5 балла | 1 балл |
|---|---|---|---|---|
| 5.1. Структура презентации | 3 | Хаотично | Есть структура | 10 слайдов по шаблону |
| 5.2. Аргументированность решений | 4 | «Так сделал» | Частично обосновал | Каждое решение обосновано (почему так, а не иначе) |
| 5.3. Ответы на вопросы | 5 | Не ответил | Ответил, но неуверенно | Чёткие, аргументированные ответы |
| 5.4. Знание предметной области | 3 | Путается в терминах | Знает, но с ошибками | Свободно оперирует терминами |
| Итого защита | 15 |
2. Шкала итоговых оценок
| Процент | Баллы | Оценка | Описание |
|---|---|---|---|
| 90–100% | 90–100 | 5 (Отлично) | Все артефакты полные, связные, глубокие. Студент свободно отвечает на вопросы. |
| 75–89% | 75–89 | 4 (Хорошо) | Есть мелкие недочёты (1–2 незаполненных поля, пропущенный переход на диаграмме). Студент отвечает на большинство вопросов. |
| 60–74% | 60–74 | 3 (Удовлетворительно) | Существенные недочёты: пропущены разделы SRS, неполные диаграммы, нет трассируемости. Студент путается в ответах. |
| < 60% | 0–59 | 2 (Неудовлетворительно) | Работа не завершена, артефакты не связаны, грубые ошибки в нотациях. Требуется полная переработка. |
3. Гайд для экзаменатора: 15 глубоких вопросов на защите
Цель раздела: Проверить, что студент не просто скопировал артефакты из интернета, а понимает каждое своё решение. Вопросы построены так, что ответ «не подумал(а)» = 0 баллов за защиту.
Блок 1: Базы данных и ER-моделирование (вопросы 1–4)
Вопрос 1. Почему выбрали UUID для PK, а не автоинкремент (SERIAL)?
Проверяет: Понимание trade-offs между surrogate key типами.
Ожидаемый ответ студента:
- UUID не требует централизованной генерации (хорошо для распределённых систем)
- UUID не раскрывает количество записей (безопасность:
/api/users/1→ понятно, что первый пользователь) - Но UUID: больше размер индекса (16 байт vs 4 для INT), медленнее вставка
- Компромисс: для Task Manager (внутренняя система, 120 пользователей) можно было взять SERIAL, но UUID даёт гибкость на будущее
Красный флаг: «Мне сказали так сделать» / «Не знаю».
Вопрос 2. Покажите на ERD, какие индексы вы создадите и почему?
Проверяет: Понимание физического моделирования данных.
Ожидаемый ответ студента:
assignee_id(FK) — INDEX — для JOIN по исполнителюstatus— INDEX — для фильтрации по статусу (если селективность высокая)deadline— INDEX — для поиска просроченных задач(project_id, status)— COMPOSITE INDEX — для дашборда по проектам- Composite index
(assignee_id, status)для дашборда загрузки сотрудника
Красный флаг: «Индексы не нужны, база маленькая» / Не может объяснить, зачем индекс на FK.
Вопрос 3. В SRS у вас есть статусная модель. Как вы защитите данные от перехода в невалидный статус на уровне БД?
Проверяет: Понимание CHECK constraints, enum-типов, триггеров.
Ожидаемый ответ студента:
CHECK (status IN ('To Do', 'In Progress', 'Testing', 'Done', 'Blocked'))— базовый уровень- Если переходы сложные (не все статусы разрешены) — нужна отдельная таблица
allowed_transitionsили триггер на UPDATE - В PostgreSQL можно создать тип
CREATE TYPE task_status AS ENUM(...)— жёстче, чем CHECK - В коде — enum в приложении + валидация на уровне сервиса
Красный флаг: «Валидация только на фронтенде» / Не знает, что такое CHECK constraint.
Вопрос 4. У вас есть таблица User и Task. Какой SQL-запрос покажет загрузку сотрудника в процентах?
Проверяет: SQL, JOIN, GROUP BY, CASE WHEN, понимание бизнес-метрик.
Ожидаемый ответ студента:
SELECT
u.id,
u.name,
COUNT(t.id) AS total_tasks,
COUNT(CASE WHEN t.status NOT IN ('Done', 'Cancelled') THEN 1 END) AS active_tasks,
ROUND(COUNT(CASE WHEN t.status NOT IN ('Done', 'Cancelled') THEN 1 END) * 100.0 /
GREATEST(COUNT(t.id), 1), 1) AS load_percent
FROM "User" u
LEFT JOIN Task t ON u.id = t.assignee_id
GROUP BY u.id, u.name
ORDER BY load_percent DESC;
Красный флаг: «Я не писал сложные запросы, это сделал бэкенд» / Не может объяснить LEFT JOIN vs INNER JOIN.
Блок 2: REST API и OpenAPI (вопросы 5–8)
Вопрос 5. Ваш API возвращает список задач на GET /tasks. Почему выбрали пагинацию через page/limit, а не cursor-based? В каком случае cursor-based лучше?
Проверяет: Понимание пагинации, её видов.
Ожидаемый ответ студента:
- Offset/limit (page/limit): Просто, понятно, можно перейти на любую страницу. Проблема: при вставке данных пагинация «съезжает» (duplicate/skip). Хорошо для статических списков или UI с нумерацией страниц.
- Cursor-based (keyset): Стабильная пагинация (не «съезжает»), быстрее на больших таблицах (WHERE id > last_seen). Проблема: нельзя перейти на страницу 3, только «дальше/назад». Хорошо для лент, бесконечного скролла.
- Выбор: Для Task Manager (внутренняя система, статические задачи) page/limit ок. Для дашборда в реальном времени — лучше cursor-based.
Красный флаг: «Не знаю, что такое cursor-based пагинация» / «Пагинация не нужна, задач мало».
Вопрос 6. На защите вы показали PATCH /tasks/{id}/status. Почему PATCH, а не PUT? Почему не POST?
Проверяет: Понимание идемпотентности, разницы HTTP-методов.
Ожидаемый ответ студента:
- PATCH — частичное обновление (меняем только status). PUT — полная замена ресурса (передали бы все поля). POST — создание (не подходит).
- Идемпотентность: PATCH и POST — НЕ идемпотентны. PUT — идемпотентен. Если клиент повторно отправил PATCH — статус может измениться снова (если не реализована идемпотентность).
- Безопасность: Если бы статус менялся на «Done» только один раз — нужно добавить
Idempotency-Keyили сделать проверку на сервере.
Красный флаг: «Всегда использую POST, потому что удобно» / Не слышал про идемпотентность.
Вопрос 7. В OpenAPI-спецификации вы указали security: Bearer JWT. Как будет обрабатываться запрос без токена? Какой статус-код?
Проверяет: Понимание аутентификации и статус-кодов.
Ожидаемый ответ студента:
- 401 Unauthorized — если токен отсутствует или невалидный (просрочен, неверная подпись)
- 403 Forbidden — если токен валиден, но у пользователя нет прав на ресурс (роль не позволяет)
- Middleware на Gateway или в каждом сервисе проверяет JWT, извлекает userId, role, проверяет права
- OpenAPI: эндпоинты с security — требуют токен; /auth/* — без security (public)
Красный флаг: «403 — если не авторизован» (путает 401 и 403).
Вопрос 8. Вы описали модель Task с полем status (enum). Как в OpenAPI 3.0 правильно описать enum?
Проверяет: Знание OpenAPI, JSON Schema.
Ожидаемый ответ студента:
Task:
type: object
properties:
status:
type: string
enum: [To Do, In Progress, Testing, Done, Blocked]
description: "Текущий статус задачи"
priority:
type: string
enum: [Low, Medium, High, Critical]
- Можно добавить
x-enum-varnamesдля маппинга на код - В OpenAPI 3.1 можно использовать
oneOfс константами, но enum — стандарт
Красный флаг: «Не помню, как описать enum» / Использует type: integer для статуса.
Блок 3: Интеграции и брокеры сообщений (вопросы 9–11)
Вопрос 9. В SRS вы описали, что система отправляет уведомления. Какую архитектуру выбрали — синхронную или асинхронную? Почему?
Проверяет: Понимание интеграционных паттернов (модуль 07).
Ожидаемый ответ студента:
- Асинхронную (RabbitMQ/Kafka). Причина: отправка email/Slack не должна блокировать создание задачи.
- Task Service отправляет событие
task.createdв очередь. - Notification Service читает из очереди, отправляет email/Slack.
- Если Notification Service упал — сообщение остаётся в очереди (At-least-once).
- Если Slack API временно недоступен — retry + Circuit Breaker.
Красный флаг: «Синхронную — отправляем email сразу из Task Service» / Не знает, зачем нужен брокер сообщений.
Вопрос 10. Что будет, если Notification Service получил событие task.created дважды? Как это предотвратить?
Проверяет: Понимание идемпотентности и гарантий доставки.
Ожидаемый ответ студента:
- At-least-once доставка → сообщение может прийти дважды.
- Решение: идемпотентность обработчика.
- Хранить
processed_events(eventId, processed_at) в БД. - Перед отправкой — проверить, обработан ли eventId.
- Если уже обработан — пропустить (ACK без отправки email).
- Хранить
- Альтернатива: Idempotency-Key от продюсера (но в асинхронной схеме eventId — аналог).
eventIdгенерируется как UUID при создании события.
Красный флаг: «У нас такого не будет, Kafka гарантирует exactly-once» (миф!).
Вопрос 11. Если дашборд загрузки (NFR-001: время < 2 сек) грузится слишком долго из-за JOIN к Task + Comment + Notification — что будете делать?
Проверяет: Понимание нефункциональных требований и путей оптимизации.
Ожидаемый ответ студента:
- Materialized View — денормализованная таблица для дашборда, обновляется раз в N минут
- Redis Cache — кэшировать результат дашборда на 5 минут (данные не должны быть real-time)
- Отдельная таблица статистики — считать загрузку при изменении статуса (триггером или событием) и писать в отдельную таблицу
- CQRS — разделить write model (нормализованная) и read model (денормализованная для дашборда)
Красный флаг: «Оптимизация не нужна, база маленькая» / Не знает, что такое Materialized View.
Блок 4: Нефункциональные требования и архитектура (вопросы 12–15)
Вопрос 12. NFR-03: «Аутентификация через JWT, пароли — bcrypt». Почему bcrypt, а не MD5 или SHA?
Проверяет: Понимание безопасности хранения паролей.
Ожидаемый ответ студента:
- MD5, SHA1 — хеши для контроля целостности, а не для хранения паролей. Они быстрые — 1 млн хешей в секунду на GPU, перебор всех паролей за минуты.
- bcrypt — адаптивный хеш. Можно регулировать cost factor (скорость). Даже с cost=10 — ~10 хешей в секунду, перебор 8-символьного пароля — миллионы лет.
- bcrypt автоматически добавляет соль (salt) — одинаковые пароли дают разные хеши.
- Альтернативы: argon2 (современнее, победитель Password Hashing Competition), scrypt.
Красный флаг: «Хешируем пароли MD5, он быстрый» / «Пароли храним в открытом виде, у нас же своя система».
Вопрос 13. NFR-02: uptime 99.5%. Сколько минут простоя допустимо в месяц? Что будете делать, если БД упала?
Проверяет: Понимание SLA, доступности, disaster recovery.
Ожидаемый ответ студента:
- 99.5% = допустимо ~3.5 часа простоя в месяц (43 200 минут × 0.5% = 216 минут).
- При падении БД:
- Connection pool (HikariCP) — не дать приложению упасть сразу
- Retry с exponential backoff — БД может перезагрузиться
- Circuit Breaker — если БД не отвечает, отключать запросы, возвращать fallback
- Replica — переключиться на read replica (если чтение)
- Backup — последний бэкап, point-in-time recovery
- Для внутренней системы (120 пользователей) 99.5% — приемлемо. Для production заказчика нужно 99.9%+.
Красный флаг: «99.5% — это много, хватит» / Не знает формулу расчёта допустимого времени простоя.
Вопрос 14. Как вы обеспечите, что дашборд загрузки видит только HR, а разработчик — только свои задачи?
Проверяет: Понимание ролевой модели, авторизации.
Ожидаемый ответ студента:
- Роли: ADMIN, TEAM_LEAD, DEVELOPER, HR (enum в таблице User)
- JWT содержит
roleпри аутентификации - Middleware/Interceptor в Spring/.NET Core:
- DEVELOPER → GET /api/v1/tasks — только свои задачи (
WHERE assignee_id = :userId) - HR → GET /api/v1/dashboard — все данные
- TEAM_LEAD → GET /api/v1/tasks — задачи своей команды
- DEVELOPER → GET /api/v1/tasks — только свои задачи (
- Row-Level Security (RLS) в PostgreSQL — можно добавить политики на уровне БД
- В OpenAPI: указать x-roles для каждого эндпоинта
Красный флаг: «Все видят всё, у нас доверенная среда» / Не может объяснить разницу между аутентификацией и авторизацией.
Вопрос 15. В проектном брифе сказано: «Новая задача создаётся не более чем за 3 клика». Как вы проверите это требование на этапе проектирования? А в production?
Проверяет: Понимание проверяемости требований, Usability Testing.
Ожидаемый ответ студента:
- На этапе проектирования:
- Посчитать клики в прототипе (Figma). Создание задачи: кнопка «+» (1) → заполнить поля (2) → сохранить (3) = 3 клика.
- Если прототип требует 5 кликов — перепроектировать.
- В production:
- Usability Test: посадить 5 пользователей, замерить количество кликов. Среднее не более 3.
- Analytics: добавить фронтенд-событие
clicks_to_create_task, собрать статистику. - Если > 3 — оптимизировать UI.
- Критерий приёмки: 95% задач создаются за ≤ 3 клика (P95).
Красный флаг: «3 клика — это слишком абстрактно, не проверяется» / Не может предложить способ проверки.
Дополнительные вопросы (для усиления)
| Тема | Вопрос | Что проверяет |
|---|---|---|
| CI/CD | Как будете выкатывать новую версию без простоя? | Понимание деплоя (blue-green, canary, rollback) |
| Мониторинг | Как узнаете, что система упала в 3 часа ночи? | Понимание observability (логи, метрики, алерты, Grafana/Prometheus) |
| Безопасность | Как защититься от SQL-инъекции в поле title? | Prepared statements, ORM, параметризованные запросы |
| Тестирование | Какие тесты должны быть в CI перед деплоем? | Unit → Integration → E2E (пирамида тестирования) |
| Брокеры | Что делать, если RabbitMQ/Kafka умер? | Dead Letter Queue, health check, Circuit Breaker, fallback |
| Кэш | Почему вы выбрали Redis, а не in-memory кэш? | Redis — распределённый, persistence, TTL, не теряется при рестарте приложения |
| Масштабирование | Как система поведёт себя при 5000 одновременных пользователей? | Connection pool, load balancer, кэш, асинхронность |
4. Процесс защиты
1. Презентация (7–10 минут)
├── Студент показывает 10 слайдов
└── Экзаменатор слушает, записывает вопросы
2. Вопросы (10–15 минут)
├── Минимум 3 вопроса из разных блоков (БД, API, интеграции, NFR)
├── 1 вопрос по трассируемости («Покажите, как FR-001 связан с API?»)
└── 1 вопрос по выбору технологии («Почему PostgreSQL, а не MongoDB?»)
3. Оценка
├── По матрице оценки
└── Субъективная оценка: уверенность, глубина, аргументация
Инструкция экзаменатору
- Не принимайте ответы «по бумажке». Если студент читает с листа — прервите и задайте уточняющий вопрос.
- Провоцируйте каверзными вопросами. Хороший студент скажет: «В моём проекте это не учтено, но в реальной системе я бы сделал так...».
- Проверяйте трассируемость вживую: «Покажите на SRS, где описана эта сущность. Теперь найдите её в ERD. А в OpenAPI?».
- Если студент не знает — задайте наводящий вопрос. Оценка «2» — только если студент не может ответить даже с наводящими.
- Записывайте тайминг. Защита — не более 25 минут. Если студент не укладывается — оценка снижается.