MiddlePerformance Marketer > Google Ads > Устойчивость результатов и управление рисками
Короткий ответ Полезный постмортем связывает исходную гипотезу, фактические метрики и хронологию решений с доказанной корневой причиной и конкретными действиями на будущее. Как это работает подробнее Низкие конверсии — симптом, а не объяснение. Ищите первопричину, например пересечение аудитории с клиентской базой, методом «пяти почему» и проверяйте гипотезу сегментацией или CRM-данными. Что использовать на практике Запишите критерии успеха, фактические показатели в динамике и даты ключевых изменений. Сформулируйте корневую причину, подтверждённую данными. Назначьте проверяемое действие, ответственного и срок; сохраните разбор в общем месте команды. Подводные камни Не ограничивайтесь фразами «кампания не сработала» или «нужно лучше таргетироваться» без цифр и конкретного изменения для следующего запуска.
campaign-metricscorrective-actions
JuniorPython Developer > Основы Python > Контекстные менеджеры
Короткий ответ Функция оборачивается декоратором @contextlib.contextmanager, внутри использует yield ровно один раз: код до yield работает как __enter__, значение после yield передаётся в as, а код после yield (в finally) работает как __exit__. Как это работает подробнее contextlib.contextmanager превращает функцию-генератор в фабрику контекстных менеджеров: первый next() доводит выполнение до yield и возвращает значение для as, а выход из блока with вызывает продолжение генератора после yield. Пример кода Что использовать на практике Практика. Это удобный, менее многословный способ написать контекстный менеджер без отдельного класса — подходит для простых случаев: временного изменения состояния, замера времени, временной подмены конфигурации. Код освобождения ресурса нужно оборачивать в try/finally вокруг yield. Подводные камни Риски. Забывают try/finally вокруг yield, из-за чего при исключении в блоке with код очистки не выполняется; делают больше одного yield в функции (RuntimeError) или забывают сам декор
contextlibcontext-managers
MiddlePython Developer > Основы Python > Django и DRF
Короткий ответ Middleware реализуется как вызываемый класс с методом __call__, принимающий get_response в конструкторе; его нужно разместить как можно раньше в MIDDLEWARE, чтобы замер включал время работы всех последующих middleware и view. Как это работает подробнее Современный стиль middleware в Django — класс с __init__(self, get_response) и __call__(self, request), который вызывает self.get_response(request) для передачи запроса дальше по цепочке и получает response для пост-обработки. Пример кода Что использовать на практике Практика. Замер времени логично делать «снаружи» (ближе к началу списка MIDDLEWARE), чтобы учесть работу всех остальных middleware; добавление заголовка X-Response-Time в ответ помогает диагностировать медленные запросы в production без дополнительного профилирования. Подводные камни Риск. Размещают измеряющий middleware слишком «глубоко» в списке (близко к view), из-за чего он не учитывает время работы middleware аутентификации/сессий, которые могут быть источником задержки; забываю
djangomiddleware
MiddlePython Developer > Основы Python > Тестирование кода
Короткий ответ Нужно замокать клиент внешнего сервиса так, чтобы он бросал исключение таймаута (или возвращал ответ с кодом 500), и проверить, что код приложения перехватывает это и ведёт себя предсказуемо — например, возвращает понятную ошибку клиенту или делает повторную попытку по заданной политике. Как это работает подробнее В зависимости от HTTP-клиента симулируют конкретное исключение библиотеки (например, httpx.TimeoutException, requests.exceptions.Timeout) через side_effect мока, либо настраивают мок-сервер (responses/respx) так, чтобы он отвечал статусом 500 или зависал дольше настроенного таймаута, точно воспроизводя условия частичного отказа внешней зависимости. Пример кода Что использовать на практике Практика. Важно проверять не просто факт перехвата исключения, а итоговое поведение системы: вернулся ли клиенту корректный код ошибки (502/503), сработал ли circuit breaker или retry с backoff, залогировано ли событие для последующей диагностики. Это особенно важно для сервисов с частичными отказами
fault-tolerancehttp
MiddlePython Developer > Основы Python > Тестирование кода
Короткий ответ Нужно отдельно проверить успешную валидацию корректных данных, явный отказ при невалидных данных (через pytest.raises(ValidationError)) и граничные значения — минимум/максимум допустимой длины, диапазона, пустые и None значения там, где они формально допустимы или недопустимы. Как это работает подробнее Pydantic при создании экземпляра модели с некорректными данными бросает ValidationError со списком конкретных ошибок по каждому полю отдельно; тест может проверить не только факт ошибки, но и то, что она относится к ожидаемому полю и имеет ожидаемый тип, через анализ e.value.errors(). Пример кода Что использовать на практике Практика. Параметризация (@pytest.mark.parametrize) хорошо подходит для перебора набора граничных и некорректных значений одного поля: пустая строка, строка ровно на границе max_length, отрицательное число для поля с ge=0, неверный формат email. Это системно покрывает значимые классы эквивалентности входных данных. Подводные камни Риск. Тестировать только один успешный приме
boundary-testingpydantic
MiddleData Analyst > SQL и данные > Статистика и теория вероятностей
Короткий ответ На больших объёмах поиск дублей и аномалий стоит делать через агрегирование и оконные функции с фильтрацией по ключевым полям и временному диапазону, избегая полных самосоединений (self-join) без ограничивающих условий, а аномалии искать через сравнение с историческими статистиками по тем же разрезам (дата, сегмент). Как это работает подробнее GROUP BY с HAVING COUNT(*) > 1 на индексированных ключевых полях обычно эффективнее, чем JOIN таблицы самой на себя по этим же полям, так как последний может создавать квадратичный рост промежуточного результата. Для аномалий по времени удобно агрегировать метрику по дням/часам и сравнивать с историческим средним и стандартным отклонением (или процентилями) за предыдущий сопоставимый период. Sanity check: день с cnt, отличающимся от avg_28d более чем на 3×std_28d, стоит проверить вручную на технический сбой (дубликаты событий, задержка в пайплайне) перед тем как считать его реальной аномалией поведения. Пример кода Что использовать на практике На очень бо
anomaly-detectiondata-quality
JuniorData Analyst > SQL и данные > Статистика и теория вероятностей
Короткий ответ Среднее по группам считается через AVG(...) ... GROUP BY; для медианы в PostgreSQL используется percentile_cont(0.5) WITHIN GROUP (ORDER BY ...), а точный синтаксис медианы отличается между диалектами SQL. Как это работает подробнее AVG — стандартная агрегатная функция, доступная практически во всех СУБД одинаково. Медиана не входит в стандартный набор агрегатных функций большинства СУБД и требует функций для расчёта процентилей или оконных конструкций. Такие запросы часто становятся основой для автоматизированных регулярных отчётов и дашбордов. Пример кода Что использовать на практике На практике: диалект имеет значение: в PostgreSQL используют percentile_cont/percentile_disc, в ClickHouse — median()/quantile(0.5)(), в BigQuery — PERCENTILE_CONT как оконную функцию, в MySQL до версии 8 нет встроенной функции медианы и её часто эмулируют через переменные или оконные функции ROW_NUMBER/PERCENT_RANK. Перед использованием медианы в проде стоит явно проверить синтаксис под конкретную СУБД. Для восп
meanmedian
JuniorPython Developer > Основы Python > Доступ к базе из Python
Короткий ответ Тест запускают на изолированной тестовой БД, каждый тест оборачивают в транзакцию, которая откатывается после теста, чтобы тесты не влияли друг на друга. Как это работает подробнее Django предоставляет класс TestCase, который оборачивает каждый тест в транзакцию и делает ROLLBACK в конце; для SQLAlchemy аналогичный паттерн реализуют вручную через фикстуры pytest, открывающие транзакцию на тестовую БД. Пример кода Что использовать на практике Практика. Тестовую БД настраивают через отдельные переменные окружения/настройки, отличные от production, и никогда не указывают реальный production DSN в тестовом окружении. Подводные камни Ошибка. Используют один и тот же экземпляр БД для тестов и разработки без изоляции транзакций, из-за чего тесты влияют друг на друга; мокают слишком много уровней БД, из-за чего тест не проверяет реальное SQL-поведение (например, constraint).
database-accesspostgresql
MiddlePerformance Marketer > Google Ads > Специфика рекламных площадок и каналов
Короткий ответ Brand safety обеспечивается через комбинацию pre-bid верификации контента (сторонние вендоры оценивают контекст страницы до участия в аукционе), post-bid мониторинга фактических показов и ручных/автоматических списков включений и исключений доменов и приложений. Как это работает подробнее pre-bid инструменты анализируют содержание страницы/видео до подачи ставки и блокируют показ на контенте, не соответствующем заданным категориям риска; post-bid мониторинг проверяет уже прошедшие показы постфактум и позволяет добавлять обнаруженные проблемные домены в чёрный список, а white-list ограничивает закупку только заранее проверенным списком сайтов. Что использовать на практике На практике. выбор между white-list и black-list — компромисс между охватом и контролем: white-list даёт предсказуемость, но резко ограничивает масштаб, black-list даёт больший охват, но требует постоянного дополнения; для чувствительных к репутации брендов обычно комбинируют строгий pre-bid фильтр с регулярным post-bid аудитом
ad-verificationblocklists
MiddleDevOps Engineer > Контейнеры и доставка > systemd
Короткий ответ Автоперезапуск настраивается директивами Restart= (например, on-failure или always) и RestartSec= в секции [Service]; защита от бесконечного цикла обеспечивается директивами StartLimitIntervalSec и StartLimitBurst, которые переводят юнит в состояние failed после превышения числа попыток за заданный интервал, вместо бесконечных рестартов. Как это работает подробнее systemd отслеживает код завершения и, если он подпадает под условие Restart= (on-failure реагирует на ненулевой код выхода или сигнал, always — на любое завершение), перезапускает сервис через RestartSec; при этом ведётся счётчик попыток запуска за скользящее окно StartLimitIntervalSec, и если число попыток превышает StartLimitBurst, systemd прекращает попытки и помечает юнит как failed, требуя ручного вмешательства. Пример кода Что использовать на практике Практика. без лимита на рестарты сервис, падающий из-за неисправимой проблемы (битая конфигурация, недоступная зависимость), будет бесконечно перезапускаться, создавая нагрузку на
linuxrate-limiting