Тех собес на middle-senior Data Инженер в ****

Доступно с премиум-подпиской

Оформите премиум-подписку, чтобы получить доступ к:

  • Фильтрации по компаниям
  • Названиям компаний в интервью
  • Видеозаписям собеседований в категории Data Инженер

Посмотреть видео в категории

(2025-10-26)

1 этап: Техническое интервью (Python и SQL)

Задача 1. Python
Дан отсортированный по неубыванию список целых чисел a, индекс элемента index и целое число k.
Необходимо вернуть в любом порядке k чисел из списка, которые являются ближайшими по значению к элементу a[index].

Ограничения:
- Размер списка 1 <= N <= 10^6 ;
- Элементы списка: -10^9 <= a[i] <= 10^9 ;
- Число 0 <= k <= N ;
- Индекс элемента 0 <= index < N .

Примеры:
find_k_closest(a=[2, 3, 5, 7, 11], index=3, k=2) -> [5, 7]
find_k_closest(a=[4, 12, 15, 15, 24], index=1, k=3) -> [12, 15, 15]
find_k_closest(a=[2, 3, 5, 7, 11], index=2, k=2) -> [3, 5] или [5, 7]
Задача 2. SQL
-- Таблица с 1 колонкой:
id
---
1
2
3
4
5
NULL
NULL
---
-- Что вернет ф-ия в запросе вида:
-- SELECT ... FROM table
count(*)    = 7
count(1)    = 1
count(id)   = 5
count('id') = exception
count(NULL) = 0
Задача 3. SQL
-- Нужно получить топ 10 водителей по кол-ву заказов в каждом городе.
create table orders (
driver_id varchar,
city      varchar,
order_id  varchar
-- еще какие-то поля
);
Задача 4. SQL
-- Есть две таблицы DEBIT и CREDIT, содержащие транзакции о поступлениях (DEBIT) и расходах (CREDIT)
-- на лицевых счетах, со следующей одинаковой структурой:
----------------------------------------------------------
| ACC_ID | номер лицевого счета
| DT     | дата транзакции
| AMNT   | сумма транзакции (всегда положительная)
----------------------------------------------------------
-- Напишите SQL-запрос, возвращающий разность между поступлениями и расходами за каждый
-- день по каждому лицевому счету на основе представленных в таблицах данных

Примеры решений из прикрепленных файлов

Решение для Задачи 1. Python
print(find_k_closest([2, 3, 5, 7, 11], index=3, k=2))  # [7, 5] или [5, 7]
print(find_k_closest([4, 12, 15, 15, 24], index=1, k=3))  # [12, 15, 15]
print(find_k_closest([2, 3, 5, 7, 11], index=2, k=2))  # [5, 3] или [5, 7]


def find_k_closest(a: list[int], index: int, k: int) -> list[int]:
    if k == 0:
        return []
    if k == 1:
        return [a[index]]

    result = [a[index]]
    left = index - 1
    right = index + 1

    while len(result) < k:
        # Если вышли за границы массива
        if left < 0:
            result.append(a[right])
            right += 1
        elif right >= len(a):
            result.append(a[left])
            left -= 1
        else:
            diff_left = abs(a[left] - a[index])
            diff_right = abs(a[right] - a[index])

            # При равенстве берём левый (можно поменять логику)
            if diff_left <= diff_right:
                result.append(a[left])
                left -= 1
            else:
                result.append(a[right])
                right += 1

    return result
Решение для Задачи 3. SQL
CREATE TABLE orders (
  driver_id VARCHAR,
  city      VARCHAR,
  order_id  VARCHAR
  -- еще какие-то поля
);

WITH grouped_table AS (
    SELECT 
        city,
        driver_id,
        COUNT(order_id) AS orders_cnt
    FROM orders
    GROUP BY city, driver_id
),
ordered_table AS (
    SELECT 
        city,
        driver_id,
        orders_cnt,
        RANK() OVER (
            PARTITION BY city 
            ORDER BY orders_cnt DESC
        ) AS rn
    FROM grouped_table
)

SELECT 
    rn,
    city, 
    driver_id,
    orders_cnt
FROM ordered_table
WHERE rn <= 10
ORDER BY city, rn;
Решение для Задачи 4. SQL
-- Суммируем поступления по счетам и датам
WITH debit_grouped AS (
    SELECT 
        ACC_ID,
        DT,
        SUM(AMNT) AS debit_sum
    FROM DEBIT
    GROUP BY ACC_ID, DT
),

-- Суммируем расходы по счетам и датам
credit_grouped AS (
    SELECT 
        ACC_ID,
        DT,
        SUM(AMNT) AS credit_sum
    FROM CREDIT
    GROUP BY ACC_ID, DT
),

-- Создаем диапазон всех дат (пример для PostgreSQL)
range_dt AS (
    SELECT MIN(DT) + i AS DT
    FROM generate_series(
        (SELECT MIN(DT) FROM DEBIT),
        (SELECT MAX(DT) FROM CREDIT),
        interval '1 day'
    ) AS s(i)
)

-- Объединяем данные и считаем разницу
SELECT 
    COALESCE(dg.ACC_ID, cg.ACC_ID) AS ACC_ID,
    COALESCE(dg.DT, cg.DT, rng.DT) AS DT,
    COALESCE(dg.debit_sum, 0) - COALESCE(cg.credit_sum, 0) AS DIFF
FROM range_dt rng
FULL OUTER JOIN debit_grouped dg
    ON rng.DT = dg.DT
FULL OUTER JOIN credit_grouped cg
    ON dg.ACC_ID = cg.ACC_ID AND dg.DT = cg.DT
ORDER BY ACC_ID, DT;