From 70e12fbfb38ef67f4117ec04795dd4e7fcad5645 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Wed, 4 Feb 2026 22:11:07 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A2=D0=B5=D0=BA=D1=81=D1=82=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/DE-task.md | 55 +++++++++++++++++++++++++++++++++ data/Задание дата инженер.docx | Bin 18504 -> 0 bytes 2 files changed, 55 insertions(+) create mode 100644 data/DE-task.md delete mode 100644 data/Задание дата инженер.docx diff --git a/data/DE-task.md b/data/DE-task.md new file mode 100644 index 0000000..357fba9 --- /dev/null +++ b/data/DE-task.md @@ -0,0 +1,55 @@ +**Дашборд для e-commerce кликстрима** + +Представьте, что вы работаете в e-commerce проекте. Бизнес-юнит в процессе обсуждения, закупать ли вам кликстрим логов посещения некоторого портала другого магазина. Для первичного анализа вам предоставили данные, чтобы оценить применимость и выводы, которые можно сделать из них. + +Вам нужно подготовить данные для первичного анализа и собрать несколько графиков в дашборд. Финальный результат вашей работы — развернутая инфраструктура и дашборд с графиками на которых "бизнес" может сделать выводы о данных. Вам дали полный карт-бланш на тему того, как эти данные можно обработать. + +## Вам нужно: + +* спроектировать хранилище в /PostgreSQL/Clickhouse/ со слоями и объектами, которые вы посчитаете нужными +* написать все нужные расчёты и алгоритмы для создания витрин +* реализовать расчёт с помощью какого-то регулярного процесса +* сделать на основе этих данных дашборд который можно будет посмотреть в браузере + +### Какие инструменты выбрать + +Пара вариантов: + +* **Kafka + Clickhouse + Airflow + Superset/Power BI** +* Postgresql + dagster + Grafana +* dlt + duckdb + Airflow + [Panel](https://panel.holoviz.org/) +* Clickhouse + Airflow + Redis + [Streamlit](https://streamlit.io/) +* sqlitedb + скрипты питона + Flask + d3.js + +Начните с маленького среза данных, чтобы ознакомиться, что за данные вам предоставляют: + +* browser_events.jsonl — данные с информацией о просмотрах браузера +* device_events.jsonl — данные об устройствах, с которых пользователи пользовались сайтом +* geo_events.jsonl — данные о локации пользователя +* location_events.jsonl — вопреки названию, это данные не о локации пользователя, а непосредственно о положении пользователя на сайте и информации о том, откуда пользователь попал на страницу + +Смысл задачи на **своей ВМ** развернуть инструменты и загрузить данные в Kafka и из нее прогнать их в Clickhouse /другая DB по слоям. + +В Airflow взять данные из таблиц и преобразовать, потом выгрузить в Clickhouse / другая DB в агрегированном формате под дашборд. + +Дашборд не оценивается, но будет плюсом, если получиться собрать удобный визуал. + +Записать можно на видео и отправить контактному лицу или продемонстрировать на собеседовании + +Можно использовать любые инструменты. + +Данные могут быть(скорее всего) с ошибками и компания которая их предоставляем заранее об этом сообщила т.к. они не хотят делиться 100% качественными данными полноценно с продакшена. + +### ИНФРАСТРУКТУРА + +* инфраструктура клевая и работает = 18 баллов +* инфраструктура работает, но есть баги = 12 баллов +* инфраструктура почти есть, но не совсем = 6 баллов +* инфраструктуры нет = 0 баллов + +### ДАШБОРДЫ + +* дашборды есть и удобные и работают = 12 баллов +* дашборды работают, но неудобные = 8 баллов +* дашборды почти работают = 4 балла +* дашбордов нет = 0 баллов diff --git a/data/Задание дата инженер.docx b/data/Задание дата инженер.docx deleted file mode 100644 index 1a9ffe9e99208511194b8e0423bccb6a7948119e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18504 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