Middle-аналитик в центре контроля качества контактных центров: SQL и Python на больших данных, метрики CX и операционные KPI КЦ, прокси-метрики удовлетворенности и работа с бизнес-заказчиками.
Фишка: Фокус на контроль качества контактных центров и автоматизированных агентов: аналитик не только считает отчёты, но ищет прокси-метрики (паузы, перебивания, лингвистические маркеры недовольства), до того как упадёт CSAT/NPS, и доводит изменения до скриптов, обучения и процессов.
| Этап | Длительность | Что проверяют |
|---|---|---|
| HR / рекрутер | 30–45 мин | Мотивация, опыт в аналитике (банк/финтех/e-commerce), готовность к офису (м. Кутузовская), софт-скиллы и коммуникация с заказчиками. |
| Технический скрининг | 60–90 мин | SQL live-coding или разбор запросов: JOIN, оконные функции, агрегации. Базовый Python: Pandas, чистка данных. Вопросы по статистике и A/B-тестам. |
| Интервью с тимлидом / hiring manager | 60–90 мин | Кейсы из контроля качества КЦ: как перевести «клиенты жалуются» в аналитическую задачу, метрики FCR/AHT/CSAT, прокси-метрики, визуализация и защита методологии. |
| Финальное / кросс-функциональное | 45–60 мин | Взаимодействие с руководителями смен, тренерами, QA и продуктовыми командами; приоритизация, внедрение изменений в скрипты и обучение. |
Обязательный минимум
Плюсом будет
Опыт написания SQL-запросов — какие типы задач решали?
Структура: источники данных → JOIN/CTE → агрегации → оконные функции → оптимизация. Упомяни витрины, регулярные отчёты, проверку качества данных.
Какие оконные функции в SQL вы знаете?
ROW_NUMBER, RANK/DENSE_RANK, LAG/LEAD, SUM/COUNT OVER (PARTITION BY … ORDER BY …). Отличие от GROUP BY: строки не схлопываются.
Является ли PARTITION BY обязательным в оконных функциях?
Нет. Без PARTITION BY окно — все строки результата; с PARTITION BY — отдельные окна по группам.
Какие логические JOIN существуют и когда что использовать?
INNER — пересечение; LEFT — все из левой + совпадения; RIGHT — зеркально; FULL — объединение с NULL на пропусках. CROSS — декартово произведение.
Как работает FULL JOIN?
Все строки из обеих таблиц; NULL где нет пары. Часто заменяют UNION LEFT + RIGHT.
Какой JOIN возвращает наибольшее количество записей?
Зависит от данных: CROSS — максимум теоретически; FULL/LEFT при дубликатах ключей — размножение строк. Всегда проверяй уникальность ключей.
Как рассчитать медиану в SQL без PERCENTILE/MEDIAN?
Сортировка + ROW_NUMBER; для нечётного n — средняя позиция; для чётного — среднее двух центральных. Через оконные функции и фильтр по позициям.
Какие функции смещения (OFFSET) существуют в SQL?
OFFSET … FETCH/LIMIT для пагинации; LAG/LEAD для смещения внутри окна. OFFSET без ORDER BY — нестабильный порядок.
Как подходить к решению SQL-задачи?
1) Понять вход/выход и граничные случаи. 2) Нарисовать схему таблиц. 3) Простой запрос → CTE. 4) Проверить дубликаты и NULL. 5) Оптимизировать при необходимости.
Какие конструкции в SQL избегаете или используете чаще?
Избегай: SELECT *, неявные JOIN, коррелированные подзапросы в цикле. Предпочитай: CTE, явные JOIN, EXISTS вместо IN на больших таблицах.
Что такое составной ключ в таблице?
Уникальность по комбинации столбцов (например, call_id + segment_id). Первичный или уникальный constraint.
Как устроены таблицы и JOIN в SQL?
Таблица = строки + типизированные столбцы; связи через ключи. JOIN объединяет по условию ON; важно понимать кардинальность.
Ловушка: Дубликаты в ключах JOIN размножают строки и искажают агрегаты — всегда проверяй COUNT(*) vs COUNT(DISTINCT id).
Совет: Для КЦ типичны сессии звонков: LAG/LEAD по времени, PARTITION BY operator_id ORDER BY call_start — для пауз и последовательности событий.
Фишка: В Сбере аналитика часто на GreenPlum: думай о распределении данных, партициях по дате и избегании broadcast на больших JOIN.
Как посчитать количество уникальных значений в колонке DataFrame?
df['col'].nunique() или df['col'].value_counts(). Для больших данных — drop_duplicates + len или groupby size.
Как автоматизировать регулярные отчёты в Python?
Pandas для трансформаций, параметризованный SQL через connector, schedule/cron, логирование, валидация выходных данных, алерты при аномалиях.
Совет: Для прокси-метрик из аудио/текста: чистка → feature extraction (длина пауз, частота перебиваний) → корреляция с CSAT.
Ловушка: Pandas merge без проверки дубликатов ключей — та же проблема, что в SQL JOIN.
Что такое A/B-тест и почему он полезен?
Сравнение двух вариантов на случайных группах; изолирует эффект изменения (скрипт, маршрутизация). Нужны гипотеза, метрика, размер выборки, значимость.
Проводил ли A/B-тесты?
Опиши: гипотеза → дизайн (сплит, длительность) → метрика (CSAT, FCR) → статистический тест → решение и ограничения.
Что такое стандартная ошибка среднего?
SEM = σ/√n — неопределённость оценки среднего; уменьшается с ростом n. Отличается от стандартного отклонения.
Ловушка: Множественные сравнения без коррекции → ложноположительные результаты. В КЦ часто сезонность — нужен контроль когорт.
Фишка: Позиция про прокси-метрики: корреляция пауз/перебиваний с оценкой диалога — типичный кейс для гипотез и пилотов.
Какие метрики качества классификации существуют?
Accuracy, Precision, Recall, F1, ROC-AUC, PR-AUC. Выбор зависит от баланса классов (недовольные клиенты — часто редкий класс).
Какие метрики использовать для оценки модели на пилотной группе?
Offline: F1/ROC на hold-out. Online: бизнес-метрики (CSAT, FCR, AHT) на пилоте vs контроль, статистическая значимость, guardrail-метрики.
Как перевести запрос «клиенты жалуются» в аналитическую задачу?
Уточнить: когорт, канал, период, тип жалобы → гипотезы → данные (CRM, QA-оценки, транскрипты) → метрики и сегменты → рекомендации.
Фишка: FCR — решение на первом контакте; AHT — среднее время обработки; ASA — скорость ответа; SL — % звонков в SLA; CSAT/CES/NPS — удовлетворенность.
Совет: Прокси-метрики: длительность пауз оператора, перебивания, лингвистические маркеры недовольства — отслеживают «здоровье» до падения CSAT.
Есть ли опыт или знания о СберАналитике?
Корпоративная BI/визуализация в Сбере. Если нет опыта — покажи аналоги (Tableau, Power BI) и готовность быстро освоить.
Что такое колоночные базы и почему они лучше для аналитики?
Читают только нужные столбцы; эффективны для агрегаций на больших объёмах (ClickHouse, Vertica). Row-store лучше для OLTP.
Как проверять качество данных после Kafka/API?
Row count, null-rate, дубликаты, freshness, schema drift, reconciliation с источником, алерты на аномалии, постановка задач разработчикам с примерами.
Фишка: GreenPlum — MPP PostgreSQL в Сбере: DISTRIBUTED BY, партиции по дате, локальные агрегации перед JOIN.
Доля FCR по операторам за месяц
Таблица calls: call_id, operator_id, client_id, call_date, resolved_on_first_call (boolean). Напишите SQL: для каждого operator_id — число звонков и доля resolved_on_first_call = true за последний полный месяц. Топ-5 операторов с наименьшим FCR.
WITH month_calls AS (
SELECT operator_id,
COUNT(*) AS total_calls,
AVG(CASE WHEN resolved_on_first_call THEN 1 ELSE 0 END) AS fcr_rate
FROM calls
WHERE call_date >= date_trunc('month', CURRENT_DATE) - INTERVAL '1 month'
AND call_date < date_trunc('month', CURRENT_DATE)
GROUP BY operator_id
)
SELECT operator_id, total_calls, fcr_rate
FROM month_calls
ORDER BY fcr_rate ASC, total_calls DESC
LIMIT 5;Сложность: O(n) scan + O(k) группировка
Паузы оператора как прокси-метрика
Таблица dialog_segments: call_id, segment_start, segment_end, speaker ('operator'|'client'). Напишите SQL: для каждого call_id найдите максимальную паузу оператора между сегментами клиента (в секундах).
WITH ordered AS (
SELECT call_id, segment_start, segment_end, speaker,
LEAD(segment_start) OVER (PARTITION BY call_id ORDER BY segment_start) AS next_start
FROM dialog_segments
),
pauses AS (
SELECT call_id,
EXTRACT(EPOCH FROM (next_start - segment_end)) AS pause_sec
FROM ordered
WHERE speaker = 'client' AND next_start IS NOT NULL
)
SELECT call_id, MAX(pause_sec) AS max_operator_pause
FROM pauses
WHERE pause_sec > 0
GROUP BY call_id;Сложность: O(n log n) per call при сортировке
Медиана AHT без PERCENTILE
Таблица calls: operator_id, handle_time_sec. Вычислите медиану handle_time_sec по каждому operator_id.
WITH ranked AS (
SELECT operator_id, handle_time_sec,
ROW_NUMBER() OVER (PARTITION BY operator_id ORDER BY handle_time_sec) AS rn,
COUNT(*) OVER (PARTITION BY operator_id) AS cnt
FROM calls
),
bounds AS (
SELECT operator_id,
MAX(handle_time_sec) FILTER (WHERE rn = (cnt + 1) / 2) AS low,
MAX(handle_time_sec) FILTER (WHERE rn = (cnt + 2) / 2) AS high,
cnt
FROM ranked
GROUP BY operator_id, cnt
)
SELECT operator_id,
CASE WHEN cnt % 2 = 1 THEN low ELSE (low + high) / 2.0 END AS median_aht
FROM bounds;Сложность: O(n log n)
Анализ CSAT после изменения скрипта (Python)
DataFrame: call_id, date, operator_team, csat_score (1–5), script_version ('A'|'B'). Напишите код: сравнить средний CSAT и долю оценок 4–5 между версиями скрипта за последние 30 дней, с фильтром min 100 звонков на версию.
import pandas as pd
from datetime import timedelta
df = df[df['date'] >= df['date'].max() - timedelta(days=30)]
agg = df.groupby('script_version').agg(
n=('call_id', 'count'),
mean_csat=('csat_score', 'mean'),
high_csat_rate=('csat_score', lambda s: (s >= 4).mean())
).query('n >= 100')
print(agg)Сложность: O(n)
Каркас ответа
3 дня
7 дней
14 дней
| Блок | Готов, если... |
|---|---|
| SQL | можешь написать FCR по операторам, медиану через оконные функции и паузы через LAG/LEAD без подсказок |
| Python | можешь в Pandas сравнить CSAT между группами с фильтром по размеру выборки |
| Статистика | можешь описать дизайн A/B-теста и объяснить p-value и стандартную ошибку среднего |
| Метрики КЦ | можешь объяснить FCR, AHT, ASA, SL, CSAT и как строить прокси-метрики |
| Бизнес-кейсы | можешь за 5 минут разложить «клиенты жалуются» в аналитический план |
| Коммуникация | есть 2 кейса защиты методологии и постановки задач разработчикам |
В день собеседования