MiddlePython Developer > Основы Python > Типы данных
Короткий ответ assertEqual (как и обычный оператор ==) сравнивает структуры по значению рекурсивно, а не по идентичности объектов, поэтому два разных объекта dict/list с одинаковым содержимым считаются равными — это и есть правильное, ожидаемое поведение теста на корректность данных; проверка идентичности (assertIs / is) нужна только в особом случае, когда тест специально проверяет, что функция вернула именно тот же самый объект (например, из кэша), а не его копию. Как это работает подробнее == для list и dict определён так, что он рекурсивно сравнивает элементы/значения по их собственному ==, независимо от того, являются ли контейнеры одним и тем же объектом в памяти. assertEqual в unittest внутри вызывает именно ==, поэтому для словарей и списков он фактически проверяет совпадение содержимого, а не адреса в памяти. Пример кода Что использовать на практике Практика. Такое поведение — то, что обычно и нужно в тестах на бизнес-логику: "функция должна вернуть структуру данных с такими-то полями и значениями", а
data-typesdict
JuniorDevOps Engineer > Контейнеры и доставка > Infrastructure as Code и управление конфигурацией
Короткий ответ + означает создание нового ресурса, - — удаление существующего, ~ — изменение атрибутов на месте без пересоздания, а -/+ означает удаление и создание нового ресурса взамен (replacement); итоговая строка суммирует количество ресурсов по каждому типу действия. Как это работает подробнее Terraform вычисляет эти символы, сравнивая желаемую конфигурацию с данными из state (и опционально свежим refresh реального состояния); "updated in-place" означает, что провайдер поддерживает изменение этого атрибута без простоя и пересоздания ресурса (как в случае с тегами). Пример кода Что использовать на практике Практика. перед apply важно просматривать не только итоговую строку с числами, а каждый блок изменений — особенно обращая внимание на - (destroy) и -/+ (replace), так как они могут означать потерю данных или простой сервиса, если ресурс содержит state (например, EBS-том, база данных). Подводные камни Ошибка. считать, что раз итоговая строка выглядит компактно, то можно не читать детали; не замечать уда
configuration-managementiac
JuniorDevOps Engineer > Контейнеры и доставка > CI/CD и управление релизами
Короткий ответ Судя по логу, упала стадия `test`: сборка (`build`) завершилась успешно, а тест `test_calculate_discount` завершился с ошибкой `AssertionError`, поэтому пайплайн остановился до стадии деплоя. Как это работает подробнее пайплайн состоит из последовательных стадий, и большинство CI-систем по умолчанию останавливают выполнение следующих стадий, если текущая завершилась с ненулевым кодом возврата. Код в логе (`exit code 1`) и явное сообщение об ошибке теста — главные подсказки для диагностики. Пример кода Что использовать на практике На практике. нужно читать лог снизу вверх или искать первое красное сообщение, а не последнюю строку — иногда после ошибки выводится ещё технический «cleanup»-вывод. Важно также смотреть, какая именно стадия помечена как failed в интерфейсе CI, а не полагаться только на текст. Пример. Правильный ответ: упала стадия `test` из-за неверного значения, возвращаемого функцией расчёта скидки; стадия `deploy` не запускалась, потому что пайплайн остановился раньше. Подводные ка
artifactscicd-and-release-management
SeniorPython Developer > Основы Python > Надёжность API
Короткий ответ Нужны лимиты на нескольких уровнях одновременно — per-user/per-API-key (справедливое распределение между клиентами), per-IP (защита от анонимных/нелегитимных источников) и глобальный лимит на уровне всего сервиса (защита инфраструктуры в целом) — с централизованным хранилищем счётчиков (например, Redis) для корректной работы при множестве инстансов сервиса; конкретные пороги и алгоритм (token bucket, sliding window) выбираются исходя из реальной емкости системы и бизнес-тарифов. Как это работает подробнее в распределённой системе за балансировщиком счётчики лимитов не могут храниться в памяти одного процесса — нужно общее атомарное хранилище, иначе реальный лимит клиента фактически умножается на число инстансов, через которые пройдут его запросы. Per-user лимит защищает от того, чтобы один клиент "съел" ресурсы, предназначенные для всех; глобальный лимит защищает от ситуации, когда суммарная легитимная нагрузка от множества клиентов (каждый в рамках своего лимита) всё равно превышает реальную ё
distributed-systemsrate-limiting
SeniorPython Developer > Основы Python > Безопасность API и сети
Короткий ответ Нужно выбрать алгоритм и уровень ограничения (per-IP, per-account, per-API-key, поведенческий анализ) под конкретный профиль трафика: простые алгоритмы (fixed window) дёшевы, но грубы и дают всплески на границах окна; скользящее окно или token bucket точнее, но дороже по вычислениям и состоянию при высокой нагрузке; одного универсального порога часто недостаточно против распределённой атаки. Как это работает подробнее Fixed window считает запросы в фиксированных интервалах и обнуляет счётчик на границе, что даёт эффект всплеска (burst) на стыке окон; sliding window и token bucket сглаживают эту проблему ценой необходимости хранить больше состояния (временные метки запросов или текущее число токенов) в быстром хранилище вроде Redis, что увеличивает нагрузку при очень высоком трафике. Компромисс. Более точные алгоритмы (sliding window, token bucket с детальным состоянием) снижают ложные блокировки легитимных пользователей, но увеличивают нагрузку на инфраструктуру лимитирования при росте трафика;
abuse-preventionapi
SeniorPython Developer > Основы Python > ООП и модель объектов
Короткий ответ Немедленно сделать поле обязательным в коде и в сериализованном формате — это breaking change для всех, кто создаёт объект без нового поля или десериализует старые сообщения без него; безопасная эволюция обычно идёт через добровольный (optional) этап: поле добавляется с безопасным значением по умолчанию или как Optional, старые данные продолжают десериализоваться, а переход к реально обязательному полю выполняется отдельным скоординированным этапом с поддержкой потребителей и периодом депрекации. Как это работает подробнее Если поле добавлено как field: NewType без значения по умолчанию в существующий @dataclass, любой код, создающий объект позиционными/именованными аргументами без этого поля, немедленно перестанет работать (TypeError: missing required argument), а код, десериализующий старые JSON-сообщения без этого поля в словарь и передающий его как data в конструктор, упадёт точно так же. Добавление поля со значением по умолчанию (field: NewType = default или Optional[NewType] = None) сохра
dataclassdata-model
SeniorPython Developer > Основы Python > Эволюция API
Короткий ответ Единого универсального рецепта нет: решение обычно строится вокруг явного версионирования API, длительного периода параллельной поддержки старой и новой версии и измеримых критериев (доля трафика на старой версии, контакты с интеграторами) для принятия решения об отключении старой версии. Как это работает подробнее При большом числе независимых внешних потребителей невозможно синхронно обновить всех клиентов, поэтому несовместимое изменение почти всегда требует либо версии в URL/заголовке (/v2/resources), либо расширяемого формата, допускающего постепенный переход (например, поддержка обоих форматов идентификатора одновременно с флагом). Сам факт версионирования не решает проблему — нужен ещё процесс коммуникации с интеграторами и мониторинг перехода. Пример кода Что использовать на практике Практика. Решение зависит от того, насколько критичен сервис для интеграторов, сколько их и насколько активно они поддерживают свою интеграцию: для десятка хорошо известных партнёров может подойти индивидуа
apibackward-compatibility
MiddleData Analyst > Метрики и эксперименты > A/B-тесты
Короткий ответ Код считает конверсию по группам и проверяет значимость разницы долей через хи-квадрат тест на таблице сопряжённости 2x2; он корректен для данной задачи при условии, что каждый пользователь встречается в данных только один раз и его группа не меняется в течение теста. Как это работает подробнее Как это работает: pd.crosstab строит таблицу сопряжённости 'группа x converted' с частотами, chi2_contingency проверяет гипотезу о независимости группы и конверсии, что эквивалентно проверке равенства долей между группами. Ожидаемый результат: таблица 2x2 с частотами и p-value теста. Проверка корректности: df.duplicated("user_id").sum() должно быть равно 0 перед запуском этого анализа, иначе нужно сначала дедуплицировать пользователей. Пример кода Что использовать на практике На практике: перед использованием результата стоит убедиться, что данные агрегированы на уровне пользователя (а не событий) и что в таблице нет ячеек с ожидаемой частотой меньше 5, при которых аппроксимация хи-квадрат становится мен
ab-testingexperiment-design
JuniorSMM Manager > Общее > Контент и форматы
Короткий ответ В этом брифе отсутствуют конкретные данные — нет текста для размещения, размера скидки, площадки и пропорций, дедлайна и референсов, а слова «красивый» и «яркое» субъективны и не дают дизайнеру опоры для решения; в результате дизайнер будет угадывать, а правок будет много. Как это работает подробнее бриф должен переводить задачу в конкретные, проверяемые параметры; расплывчатые эпитеты («красивый», «современный», «цепляющий») не являются техническим заданием, потому что у каждого человека свои представления о красоте. Что использовать на практике Рекомендация. вместо «яркое» нужно указать конкретные цвета бренда или референс поста с похожим настроением; вместо «про скидки» — точный размер скидки, товар, срок действия и пропорции под конкретную площадку. Подводные камни Риск. надеяться, что дизайнер «сам придумает», не давая вводных; присылать бриф без текста, который обязательно должен быть на макете; не прикладывать референсы, хотя бы в виде ссылок на похожие удачные примеры.
aspect-ratiocontent-production
SeniorData Analyst > SQL и данные > SQL
Короткий ответ Покажите руководству таблицу из двух частей: конверсию A и B внутри каждого сегмента и долю сегмента в каждой группе. Разворот общего эффекта создаёт не арифметическая ошибка, а смешение эффекта варианта с различием состава аудитории. Как это работает подробнее Если сегмент определён до эксперимента и дисбаланс случаен, можно оценить стандартизированный эффект с одинаковыми весами сегментов. Если дисбаланс указывает на ошибку назначения, результат нельзя спасать выбором выгодной агрегации: нужно расследовать рандомизацию. Не сегментируйте по переменной, появившейся после воздействия варианта: это может внести post-treatment bias. Решение должно опираться на дизайн эксперимента и целевую популяцию. Пример кода Что использовать на практике Покажите веса. Без них сегментированные проценты не объясняют общий итог. Проверьте баланс. Сравните распределение предэкспериментальных признаков и SRM в сегментах. Зафиксируйте estimand. Определите, для какой популяции и при каком составе трафика нужен эффект
conversionsegmentation