Grading rubric
Шкала 0–100 для проектов и итогового практического экзамена. Краткая версия — в описании системы оценивания; здесь каждая категория разложена до проверяемых пунктов.
Rubric предназначен для самооценки. Отсюда единственное требование к нему: каждый пункт должен проверяться командой, а не впечатлением. Пункты, которые нельзя проверить, из шкалы исключены — иначе оценка становится обсуждением, а не измерением.
Как пользоваться
- Реализовать работу.
- Пройти
CHECKLIST.mdпроекта — он проверяет требования, а не баллы. - Пройти этот rubric, выполняя команды и записывая баллы.
- Сложить и сверить с порогами.
- Проверить обязательные требования — они не про баллы.
Порядок важен: rubric заполняется после checklist. Работа, не прошедшая checklist, до оценивания не доходит.
Как ставить частичный балл
У каждого критерия три состояния, а не шкала на глаз:
| Состояние | Балл | Когда |
|---|---|---|
| Выполнено | полный | Проверка проходит |
| Частично | половина, округление вниз | Проверка проходит с оговоркой, названной письменно |
| Нет | 0 | Проверка не проходит или не выполнялась |
Третья строка включает «не проверял». «Не проверено» и «проверено и работает» — разные состояния, и различать их приходится во всём курсе, от сканирования образов до оценки изоляции.
Категория 1. Корректность (25 баллов)
| № | Критерий | Баллы | Как проверить |
|---|---|---|---|
| 1.1 | Приложение выполняет все заявленные функции | 8 | Пройти сценарии из TASK.md |
| 1.2 | Сборка воспроизводится с чистого клона | 6 | git clone во временный каталог, сборка по README |
| 1.3 | Коды возврата различают исходы | 4 | Запуск с разными входами, сверка $? |
| 1.4 | Конфигурация применяется из заявленных источников | 4 | Задать значение каждым способом |
| 1.5 | Аргументы и стандартный ввод доходят до приложения | 3 | docker run с аргументами и -i |
1.2 — самый частый провал. Работа собирается у автора и не собирается больше нигде: файл вне репозитория, переменная в личном окружении, образ в локальном кэше. Проверка одна:
git clone . /tmp/проверка && cd /tmp/проверка && docker build -t проверка .
Каталог /tmp/проверка не содержит ничего, кроме отслеживаемых файлов. Если сборка падает — критерий 0, независимо от того, насколько хорошо работает оригинал.
Категория 2. Security (15 баллов)
| № | Критерий | Баллы | Как проверить |
|---|---|---|---|
| 2.1 | Процесс запускается от непривилегированного пользователя | 4 | docker image inspect --format '{{.Config.User}}' |
| 2.2 | Идентификатор числовой | 2 | Значение соответствует ^\d+(:\d+)?$ |
| 2.3 | Секретов нет в слоях образа | 4 | docker history --no-trunc | grep -iE 'password|secret|token' |
| 2.4 | Базовый образ выбран и обоснован | 2 | Обоснование в README |
| 2.5 | Лишние capabilities сняты | 2 | cap_drop: [ALL] или эквивалент |
| 2.6 | Корневая файловая система только для чтения | 1 | read_only: true работает |
2.3 не заменяется чтением Dockerfile. Секрет, скопированный и удалённый следующей инструкцией, в Dockerfile выглядит удалённым, а из слоя извлекается (урок 12.6). Проверять нужно историю образа.
2.2 отделён от 2.1 намеренно. USER app защищает не хуже USER 10001 — но Kubernetes с runAsNonRoot: true такой pod не запустит (урок 18.2).
Категория 3. Image optimization (15 баллов)
| № | Критерий | Баллы | Как проверить |
|---|---|---|---|
| 3.1 | Multi-stage там, где есть инструменты сборки | 4 | Компилятора и заголовков нет в итоговом образе |
| 3.2 | Кэш работает: изменение кода не пересобирает зависимости | 5 | Изменить файл в src/, пересобрать, замерить |
| 3.3 | .dockerignore присутствует и полон | 3 | .git, кэши, данные, окружения исключены |
| 3.4 | Размер соответствует требованию TASK.md | 2 | docker images ОБРАЗ --format '{{.Size}}' — это DISK USAGE; docker image inspect вернёт вчетверо меньший CONTENT SIZE (урок 3.4) |
| 3.5 | Кэш пакетного менеджера не остаётся в слоях | 1 | Удаление в той же RUN или cache mount |
3.2 весит больше размера, и это осознанно. Размер образа читатель видит сразу; сломанный кэш проявляется как «сборка стала медленной» через месяцы и почти никогда не связывается с порядком инструкций.
Проверка по времени надёжнее, чем по числу слоёв CACHED:
docker build -t проба . && touch src/*/main.py && time docker build -t проба .
Вторая сборка должна занимать секунды. Если минуты — критерий 0.
Категория 4. Reliability (15 баллов)
| № | Критерий | Баллы | Как проверить |
|---|---|---|---|
| 4.1 | SIGTERM завершает приложение в пределах grace period | 5 | time docker stop container |
| 4.2 | Активные запросы завершаются, а не обрываются | 3 | Остановка под нагрузкой |
| 4.3 | Healthcheck есть и различает «запущен» и «готов» | 3 | Остановить зависимость, наблюдать состояние |
| 4.4 | Ограничения ресурсов заданы | 2 | docker inspect показывает лимиты |
| 4.5 | Поведение при отказе зависимости описано и проверено | 2 | Остановить базу, наблюдать |
4.1 проверяется временем, а не фактом остановки. Container останавливается всегда — вопрос в том, по SIGTERM или по SIGKILL через десять секунд:
docker run -d --name t образ && time docker stop t
Менее секунды — обработчик есть. Ровно десять секунд — приложение сигнал не получило, скорее всего из-за shell-формы (урок 4.6).
Для проектов 1 и 2 применимость различается: инструменту командной строки, живущему доли секунды, SIGTERM не наступает. В таком случае критерий 4.1 засчитывается при письменном обосновании — это ровно то, для чего нужно состояние «частично».
Категория 5. Testing (15 баллов)
| № | Критерий | Баллы | Как проверить |
|---|---|---|---|
| 5.1 | Unit-тесты покрывают заявленный порог | 4 | pytest --cov --cov-fail-under |
| 5.2 | Тесты выполняются в образе, а не только локально | 4 | docker build --target test |
| 5.3 | Провал теста останавливает сборку | 4 | Сломать тест намеренно, собрать |
| 5.4 | Есть integration-тесты с реальными зависимостями | 2 | Проекты 3 и 4 |
| 5.5 | Тесты не зависят от порядка выполнения | 1 | pytest -p no:randomly против случайного порядка |
5.3 весит столько же, сколько само наличие тестов. Стадия test, на которую никто не ссылается, при обычной сборке не выполняется, и сборка при этом успешна (урок 15.5). Тесты, которые не могут остановить сборку, не являются проверкой — они являются документацией.
Проверка единственная:
# сломать одно утверждение
docker build --target test . ; echo "код: $?" # ожидается ненулевой
Категория 6. Documentation (10 баллов)
| № | Критерий | Баллы | Как проверить |
|---|---|---|---|
| 6.1 | README содержит команды сборки и запуска | 3 | Выполнить их дословно на чистом клоне |
| 6.2 | Переменные окружения описаны: имя, назначение, умолчание | 3 | Сверить со списком в коде |
| 6.3 | Принятые решения обоснованы | 3 | Не менее трёх решений с причиной |
| 6.4 | Ограничения названы явно | 1 | Что не сделано и почему |
6.1 проверяется копированием, а не чтением. Команда из README, которую нельзя выполнить дословно, — не документация. Типичный случай: docker run -e DATABASE_URL=... образ без указания, что именно подставить.
6.4 весит немного, но отсутствует чаще всего. Работа без раздела «чего решение не делает» создаёт впечатление полноты, которой нет, — и это то же требование, что предъявляется ко всем разборам курса.
Категория 7. Troubleshooting (5 баллов)
| № | Критерий | Баллы | Как проверить |
|---|---|---|---|
| 7.1 | Раздел с типичными проблемами есть | 2 | Не менее трёх записей |
| 7.2 | Для каждой указана команда диагностики | 2 | Команда, а не совет |
| 7.3 | Указана причина, а не только симптом | 1 | Механизм назван |
Различие 7.2 и 7.3 существенно: «проверьте логи» — не команда диагностики; docker inspect t --format '{{.State.ExitCode}}' — команда.
Итоговая таблица
| Категория | Баллы | Ваш результат |
|---|---|---|
| 1. Корректность | 25 | |
| 2. Security | 15 | |
| 3. Image optimization | 15 | |
| 4. Reliability | 15 | |
| 5. Testing | 15 | |
| 6. Documentation | 10 | |
| 7. Troubleshooting | 5 | |
| Итого | 100 |
Пороги
| Баллы | Оценка | Что это значит |
|---|---|---|
| 90–100 | Отлично | Решения обоснованы, крайние случаи учтены, конфигурация пригодна к эксплуатации |
| 80–89 | Хорошо | Работает корректно, отдельные упущения в оптимизации или документации |
| 70–79 | Удовлетворительно | Базовые требования выполнены, есть заметные пробелы |
| 70 | Проходной минимум | Ниже курс не считается пройденным |
| 50–69 | Не пройдено | Работает, но нарушены существенные требования |
| 0–49 | Не пройдено | Не воспроизводится или не выполняет заявленные функции |
Обязательные требования
Независимо от суммы баллов работа не принимается, если выполнено хотя бы одно условие ниже.
| № | Нарушение | Проверка | Почему блокирует |
|---|---|---|---|
| 1 | Секреты в слоях образа | docker history --no-trunc | Извлекаются кем угодно, имеющим образ |
| 2 | Запуск от root без обоснования | docker image inspect --format '{{.Config.User}}' | UID 0 внутри равен UID 0 снаружи (19.2) |
| 3 | Не воспроизводится с чистой машины | Клон во временный каталог | Работа существует только у автора |
| 4 | Development server в production-конфигурации | flask run, uvicorn --reload в команде запуска | Не рассчитан на нагрузку и раскрывает отладочные сведения |
| 5 | Не завершается по docker stop в пределах grace period | time docker stop | Незавершённые операции при каждой выкатке |
Эти пять — не «самые важные критерии». Это условия, при которых оценивание остального теряет смысл: нельзя обсуждать оптимизацию образа, из которого извлекается пароль.
Про пункт 2. Обоснование допускается и иногда верно — например, container, которому нужен доступ к устройству. Требуется, чтобы оно было письменным и называло, что именно перестанет работать при непривилегированном запуске. «Не успел разобраться с правами» обоснованием не является.
Что rubric не измеряет
Полезно назвать прямо, чтобы результат не читался шире, чем он есть.
| Чего нет в шкале | Почему |
|---|---|
| Качество кода приложения | Курс про контейнеризацию, а не про Python |
| Производительность под нагрузкой | Требует стенда, которого у читателя может не быть |
| Стоимость эксплуатации | Зависит от организации, а не от работы |
| Организационная готовность | Не проверяется ни одним инструментом (19.4) |
| Уместность самой контейнеризации | Отдельный вопрос, разбираемый в 19.3 |
Последняя строка стоит того, чтобы её заметить: работа может набрать 95 баллов и решать задачу, которой не требовалось контейнеризации. Rubric этого не поймает — и не должен.
Навигация
Вернуться к системе проверки
Описание системы оценивания
Практические проекты
Главное оглавление