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;