docs(labs): обращение «вы» во всех учебных заданиях

- Зачем:
  - README и путеводитель обращаются к читателю на «вы», а ТЗ в docs/labs/
    были на «ты»; после пересборки индекса смесь стала заметна.
- Что:
  - во всех восьми файлах docs/labs/ местоимения, глаголы и повелительное
    наклонение переведены во второе лицо множественного числа.
  - названия ступеней в таблице README оставлены как в спеке.
- Проверка:
  - grep по формам «ты/твой», 'ё' и 'менти' по docs/labs/ молчит;
    git diff --check чистый; ревью диффа свежей сессией.
This commit is contained in:
ddadmin committed 2026-09-03 17:29:13 -04:00
1 parent 830efa7ef4
commit cffe1aeb73
8 files changed
+80 -77

No files matched your search

+8 -8
View File
@@ -1,7 +1,7 @@
# Учебные задания
Программа состоит из двух частей: основная включает семь ступеней, которые ты
проходишь по порядку, а факультативы выбираешь по желанию. Причины такого
Программа состоит из двух частей: основная включает семь ступеней, которые вы
проходите по порядку, а факультативы выбираете по желанию. Причины такого
порядка и формы заданий описаны в [программе учебных лаб](../specs/2026-09-01-labs-program.md#2-устройство-программы-основная-программа-и-факультативы).
## Основная программа
@@ -21,7 +21,7 @@
## Ступень 1: пять витрин слоя DM
Слой DM в стенде построен наполовину: витрины трех сюжетов дашборда и контроль
качества уже построены, остальные пять витрин строишь ты. Каждая из них —
качества уже построены, остальные пять витрин строите вы. Каждая из них —
самостоятельное ТЗ: в нем есть состав витрины, зерно, источники и способ
проверки.
@@ -59,7 +59,7 @@ DDS, и задания остаются независимыми. Исключе
остается обычным представлением. Довод — [дока DM](../architecture/dm.md),
«Форма: по зерну, не по цене запроса».
**Ключ шардирования — твое решение.** Ни одно ТЗ ключа не называет.
**Ключ шардирования — ваше решение.** Ни одно ТЗ ключа не называет.
Правило выбора и требование к донору — [дока
хранилища](../architecture/storage.md), «Раскладка по шардам»: донор
объявляется через `AS <цель>_rep` и шардируется тем же ключом, что цель,
@@ -69,7 +69,7 @@ DDS, и задания остаются независимыми. Исключе
`dm.revenue_daily_dist` в [`sql/ddl/55-dm-tables.sql`](../../sql/ddl/55-dm-tables.sql).
**Где лежит код.** DDL домашек — свой файл `sql/ddl/70-labs.sql`: он
применяется после стендовых по порядку имени, и твои объекты не мешаются
применяется после стендовых по порядку имени, и ваши объекты не мешаются
со стендовыми. У агрегатов рядом со стендовыми ложатся еще три запроса —
`sql/dm/<витрина>_scope.sql` спрашивает у хранилища, какие дни пересобирает
запуск, `_rebuild.sql` собирает их в донор, `_replace.sql` заменяет
@@ -106,14 +106,14 @@ DDS, и задания остаются независимыми. Исключе
**Предупреждение.** Запросы самой проверки лежат в `sql/dq/` открыто, и
имена называют витрину и роль сверки. Проверка на инвариантах неизбежно
близка к ответу: чтобы сверить витрину, надо ее пересчитать. Прятать эти
файлы никто не станет — но открыв их до того, как задание сделано, ты
обменяешь урок на готовый SQL.
файлы никто не станет — но открыв их до того, как задание сделано, вы
обменяете урок на готовый SQL.
Смотреть туда стоит после своей сборки: сравнить два решения полезно,
списать одно — нет.
## Факультативы
Эти задания ты берешь по желанию. Полный список сюжетов — в разделе
Эти задания вы берете по желанию. Полный список сюжетов — в разделе
[«Факультативы — пять разделов»](../specs/2026-09-01-labs-program.md#4-факультативы--пять-разделов)
программы.
+5 -5
View File
@@ -67,7 +67,7 @@
марта удалены.
Отсюда правило прогона: пересобираются **только те дни загрузки, которые
еще есть в источнике**. Спроси у источника список живых дней и замени
еще есть в источнике**. Спросите у источника список живых дней и замените
партиции ровно этих дней. Соблазн «собрать все заново в донор и подменить
таблицу целиком» здесь стоит дороже обычного: истекшие по `TTL` дни исчезли
бы из витрины навсегда, а вместе с ними — единственная оставшаяся память о
@@ -79,9 +79,9 @@
## Ключ шардирования
Твое решение по [правилу донора](../architecture/storage.md), «Раскладка по
Ваше решение по [правилу донора](../architecture/storage.md), «Раскладка по
шардам». Витрина крошечная: классов брака у событий и заказов вместе меньше
десятка. Учти это в защите ключа — иногда правильный ответ звучит как
десятка. Учтите это в защите ключа — иногда правильный ответ звучит как
«перекос здесь ничего не стоит, и вот почему».
## Как проверить себя
@@ -91,8 +91,8 @@
день за границей `TTL` сверять не с чем, и его отсутствие в источнике не
ошибка.
Собери прямой счет по обеим таблицам ошибок, соедини с
`dm.dq_errors_daily_v` полным внешним соединением по ключу и посчитай
Соберите прямой счет по обеим таблицам ошибок, соедините с
`dm.dq_errors_daily_v` полным внешним соединением по ключу и посчитайте
строки, где ключа нет с одной из сторон или где расходится `error_rows`.
Ноль — зеленый.
+4 -4
View File
@@ -91,10 +91,10 @@
## Как проверить себя
Деловой ключ — `event_id` внутри дня. Собери прямой ответ из `dds.event_v`
за тот же день, соедини с витриной полным внешним соединением и посчитай
строки, где ключа нет с одной из сторон или где различаются значения
деловых колонок. Ноль — зеленый.
Деловой ключ — `event_id` внутри дня. Соберите прямой ответ из
`dds.event_v` за тот же день, соедините с витриной полным внешним
соединением и посчитайте строки, где ключа нет с одной из сторон или где
различаются значения деловых колонок. Ноль — зеленый.
Отдельно проверяются три производные колонки: `event_hour`, `page_path` и
`referer_host` должны совпасть с тем же выражением, посчитанным по
+7 -7
View File
@@ -64,7 +64,7 @@ DDS уже перевел код источника в слово. Словар
С `visitors` история тоньше, и в ней главная ловушка задания. Складывать
уникальных по строкам нельзя: один и тот же посетитель, попавший в две
строки, будет посчитан дважды. Проверь на стенде — и увидишь, что сумма
строки, будет посчитан дважды. Проверьте на стенде — и увидите, что сумма
`visitors` по устройствам за день **сходится** с `dm.daily_traffic_v`.
Это не отменяет правила, а показывает, откуда берется совпадение: в мире
@@ -87,17 +87,17 @@ DDS уже перевел код источника в слово. Словар
## Ключ шардирования
Твое решение по [правилу донора](../architecture/storage.md), «Раскладка по
Ваше решение по [правилу донора](../architecture/storage.md), «Раскладка по
шардам». Здесь у измерения всего три встречающихся значения, и распределены
они неровно: планшеты — тонкая полоса, а телефоны и настольные машины держат
основную массу. Прежде чем брать хеш от одного `device_category`, посчитай,
сколько строк ляжет на каждый шард, и назови, чем тебя устраивает результат.
основную массу. Прежде чем брать хеш от одного `device_category`, посчитайте,
сколько строк ляжет на каждый шард, и назовите, чем вас устраивает результат.
## Как проверить себя
Деловой ключ — `device_category` внутри дня. Собери прямой агрегат из
`dds.session_v` за день, соедини с `dm.session_overview_v` полным внешним
соединением и посчитай строки, где ключа нет с одной из сторон или где
Деловой ключ — `device_category` внутри дня. Соберите прямой агрегат из
`dds.session_v` за день, соедините с `dm.session_overview_v` полным внешним
соединением и посчитайте строки, где ключа нет с одной из сторон или где
расходится любой счетчик. Ноль — зеленый.
Две проверки покрупнее ловят грубую ошибку сразу:
+24 -23
View File
@@ -10,20 +10,20 @@
## Роль графика
В задании 3 ты собрал витрину `dm.session_overview_v`. Теперь покажи, с каких
устройств чаще уходят после первой страницы. Построй столбиковый график доли
отказов по `device_category` за весь период витрины. Измерение одно —
`device_category`, метрика тоже одна.
В задании 3 вы собрали витрину `dm.session_overview_v`. Теперь покажите, с
каких устройств чаще уходят после первой страницы. Постройте столбиковый
график доли отказов по `device_category` за весь период витрины. Измерение
одно — `device_category`, метрика тоже одна.
## Что сделать
Заведи физический датасет в подключении к `ClickHouse`: схема `dm`, объект
`session_overview_v`. Назови по-русски хотя бы две колонки:
Заведите физический датасет в подключении к `ClickHouse`: схема `dm`, объект
`session_overview_v`. Назовите по-русски хотя бы две колонки:
- `device_category` — «Категория устройства»;
- `report_date` — «Дата отчета».
В редакторе датасета, на вкладке «Metrics», создай метрику:
В редакторе датасета, на вкладке «Metrics», создайте метрику:
| Поле | Значение |
|---|---|
@@ -33,35 +33,35 @@
| `D3 format` | `.1%` |
Доля считается из сумм слагаемых: среднее готовых долей соврет. Поэтому
метрике нужно это выражение. Сохрани ее в датасете, а не в графике: подписи и
формат задаются в датасете, а график их использует. Так во всех будущих
графиках у метрики будут одинаковые подписи. Это правило описано в
метрике нужно это выражение. Сохраните ее в датасете, а не в графике:
подписи и формат задаются в датасете, а график их использует. Так во всех
будущих графиках у метрики будут одинаковые подписи. Это правило описано в
[справочнике Superset](../architecture/superset.md#дерево-импорта).
Не используй вкладку «Custom SQL» конструктора графика. Созданная там метрика
доступна только этому графику, а нужна метрика датасета.
Не используйте вкладку «Custom SQL» конструктора графика. Созданная там
метрика доступна только этому графику, а нужна метрика датасета.
Создай столбиковый график с метрикой «Доля отказов». В поле «X-axis» укажи
«Категория устройства», а «Dimensions» не заполняй. Дашборд создавать не
нужно: сохраненного графика достаточно.
Создайте столбиковый график с метрикой «Доля отказов». В поле «X-axis»
укажите «Категория устройства», а «Dimensions» не заполняйте. Дашборд
создавать не нужно: сохраненного графика достаточно.
По умолчанию в графике выбран период «No filter». Оставь его таким или задай
явные даты. Относительный период, например «Last week», даст пустой
По умолчанию в графике выбран период «No filter». Оставьте его таким или
задайте явные даты. Относительный период, например «Last week», даст пустой
график: модельный календарь стенда отстает от настоящего. Последнюю дату
витрины посмотри в SQL Lab:
витрины посмотрите в SQL Lab:
```sql
SELECT max(report_date)
FROM dm.session_overview_v;
```
Стендовые объекты не меняй. Что переживает `make up`, а что стирает
Стендовые объекты не меняйте. Что переживает `make up`, а что стирает
`make clean`, описано в главе [«Немного Superset»](../handbook/superset.md#стендовые-объекты-и-ваши).
## Как проверить себя
График проверяется глазами, поэтому задачи для него в `homework_check` нет.
В SQL Lab выполни запрос:
В SQL Lab выполните запрос:
```sql
SELECT device_category,
@@ -71,9 +71,10 @@ GROUP BY device_category
ORDER BY device_category;
```
Сверь с графиком значение для каждой категории. В разделе «Customize» включи
«Show Value» или наведи указатель на столбик. Запрос возвращает проценты с одним знаком,
как формат `.1%`, поэтому числа должны совпасть один в один.
Сверьте с графиком значение для каждой категории. В разделе «Customize»
включите «Show Value» или наведите указатель на столбик. Запрос возвращает
проценты с одним знаком, как формат `.1%`, поэтому числа должны совпасть
один в один.
## Приемка
+17 -15
View File
@@ -9,30 +9,31 @@
## Роль дашборда
Собери обзор трафика и поведения посетителей. Он должен отвечать на три
Соберите обзор трафика и поведения посетителей. Он должен отвечать на три
вопроса: что происходило в магазине, какие страницы, устройства и рекламные
каналы дали результат, были ли ошибки приема данных.
Стендовый дашборд «Бизнес-сюжеты» собран из готовых витрин. Свой дашборд
собери из пяти витрин, которые ты построил в заданиях. Копировать раскладку
стендового дашборда не нужно: выбери форму, в которой ответы читаются без
соберите из пяти витрин, которые вы построили в заданиях. Копировать раскладку
стендового дашборда не нужно: выберите форму, в которой ответы читаются без
пояснений рядом с экраном.
## Свои объекты — отдельно
Не добавляй графики в стендовый дашборд и не правь его датасеты. При
Не добавляйте графики в стендовый дашборд и не правьте его датасеты. При
инициализации Superset импорт с `--overwrite` заменит ручные правки стендовых
объектов файлами из репозитория. `make up` свой дашборд не стирает; срок жизни
таких объектов описан в [доке Superset](../architecture/superset.md), «Импорт
при каждой инициализации».
Заведи отдельные датасеты и графики, собери из них свой дашборд. Назови его,
например, «Мои витрины DM». Это то же правило, по которому DDL домашек лежит
в `sql/ddl/70-labs.sql`: стендовые объекты уже есть, свои создаешь ты.
Заведите отдельные датасеты и графики, соберите из них свой дашборд.
Назовите его, например, «Мои витрины DM». Это то же правило, по которому DDL
домашек лежит в `sql/ddl/70-labs.sql`: стендовые объекты уже есть, свои
создаете вы.
## Датасеты
Заведи в подключении `ClickHouse` пять физических датасетов схемы `dm`:
Заведите в подключении `ClickHouse` пять физических датасетов схемы `dm`:
- `events_enriched_v`;
- `top_pages_daily_v`;
@@ -43,7 +44,7 @@
## Состав дашборда
Каждая из пяти витрин должна появиться хотя бы в одном графике. Точный тип
графика выбери сам. На дашборде покажи следующее:
графика выберите сами. На дашборде покажите следующее:
| Витрина | Что показать |
|---|---|
@@ -53,7 +54,7 @@
| `dq_errors_daily_v` | число ошибок по дню загрузки, источнику и классу |
| `utm_effectiveness_v` | трафик, покупки и заявленную выручку по рекламным каналам |
Для долей используй слагаемые из витрин. Например, доля отказов считается
Для долей используйте слагаемые из витрин. Например, доля отказов считается
как сумма `bounce_sessions`, деленная на сумму `sessions`. Среднее по готовым
долям для такого графика не подходит — урок задания 3 остается в силе.
@@ -64,19 +65,20 @@
Эта лаба проверяется глазами. У расположения панелей и понятных подписей нет
счетного инварианта, поэтому задачи для нее в `homework_check` нет.
Открой список дашбордов и проверь:
Откройте список дашбордов и проверьте:
- «Бизнес-сюжеты» остался отдельным стендовым дашбордом;
- твой дашборд открывается без ошибок и содержит график от каждого из пяти
- ваш дашборд открывается без ошибок и содержит график от каждого из пяти
датасетов;
- подписи, единицы измерения и легенды читаются без обращения к SQL;
- прямой трафик не исчез из графика UTM, а заявленная выручка не выдана за
серверную;
- пустой график ошибок нормален, если в таблицах брака сейчас нет строк.
Последний проход сделай как читатель: найди на экране самый заметный канал,
страницу и устройство, затем проверь, понятно ли из подписей, что именно
сравнивается. Если ответ приходится угадывать, поправь график или его название.
Последний проход сделайте как читатель: найдите на экране самый заметный
канал, страницу и устройство, затем проверьте, понятно ли из подписей, что
именно сравнивается. Если ответ приходится угадывать, поправьте график или
его название.
## Приемка
+7 -7
View File
@@ -64,7 +64,7 @@
пересобирать нужно только то, что еще не собрано: хвост дней, которых в
витрине нет, — от первого несобранного прожитого дня до последнего
прожитого. Готовые дни трогать незачем, а вот дыру, оставленную частичным
отказом, объем прогона обязан подобрать: ищи не последний собранный день, а
отказом, объем прогона обязан подобрать: ищите не последний собранный день, а
первый несобранный.
Механика — сборка отрезка в донор одной вставкой и замена дневных партиций
@@ -72,16 +72,16 @@
## Ключ шардирования
Твое решение по [правилу донора](../architecture/storage.md), «Раскладка по
шардам». Подумай, чем эта витрина отличается от `revenue_daily`: там кроме
Ваше решение по [правилу донора](../architecture/storage.md), «Раскладка по
шардам». Подумайте, чем эта витрина отличается от `revenue_daily`: там кроме
дня было одно измерение из шести близких по объему значений, здесь —
страницы, которых много и которые по популярности очень неровные.
## Как проверить себя
Деловой ключ — `page_path` внутри дня. Собери прямой агрегат из
`dds.event_v` за день, соедини с `dm.top_pages_daily_v` полным внешним
соединением по ключу и посчитай строки, где ключа нет с одной из сторон или
Деловой ключ — `page_path` внутри дня. Соберите прямой агрегат из
`dds.event_v` за день, соедините с `dm.top_pages_daily_v` полным внешним
соединением по ключу и посчитайте строки, где ключа нет с одной из сторон или
где расходится любой из четырех счетчиков. Ноль — зеленый.
Две проверки попроще, ими удобно ловить грубую ошибку до полного
@@ -94,7 +94,7 @@
Проверки ловят разное. Фильтр `WHERE event_type = 'pageview'` первая из них
пропускает: отбор строк по типу не меняет счет событий того же типа.
Расхождение покажет только вторая — вместе с `cart_adds` обнулятся и
`purchases`. Проверку выбирают по тому, умеет ли она покраснеть на твоей
`purchases`. Проверку выбирают по тому, умеет ли она покраснеть на вашей
ошибке, а не по тому, как быстро она пишется: [проверка, которая не умеет
краснеть, бесполезна](../architecture/testing.md).
+8 -8
View File
@@ -3,7 +3,7 @@
**Чему учит:** приставка `declared_` в имени колонки — предупреждение, а не
украшение. Она говорит: это заявка клиента, а не деньги отчетности. Урок
здесь дает конфликт: суммы не сойдутся, и раскапывать почему предстоит
самому.
самостоятельно.
Правило стенда: **поведение и атрибуцию считаем по трекеру, деньги — по
бэкенду**. Эта витрина — единственное разрешенное исключение: атрибуции по
@@ -88,21 +88,21 @@ UTM у бэкенда нет, метки живут только в кликст
## Ключ шардирования
Твое решение по [правилу донора](../architecture/storage.md), «Раскладка по
Ваше решение по [правилу донора](../architecture/storage.md), «Раскладка по
шардам». Зерно здесь составное, из трех колонок, и решение «взять хеш от
одной из них» надо защищать отдельно: назови, какая доля строк придется на
одной из них» надо защищать отдельно: назовите, какая доля строк придется на
самое частое значение выбранной колонки.
## Конфликт, ради которого витрина и написана
Собери за один и тот же день две суммы: `sum(declared_revenue)` из своей
Соберите за один и тот же день две суммы: `sum(declared_revenue)` из своей
витрины и `sum(revenue)` из `dm.revenue_daily_v`. Они не сойдутся, и это
верное поведение обеих витрин.
Базы у двух сумм при этом сравнимые: `revenue_daily` складывает цену позиций
на количество и ни скидки, ни доставки в себя не берет — ровно то, что видит
клиент. Значит все расхождение до копейки объясняется тем, что случилось с
заказом, а не тем, как считали деньги. Ищи ответы среди таких причин:
заказом, а не тем, как считали деньги. Ищите ответы среди таких причин:
- отмененный заказ из кликстрима никуда не девается: событие покупки
случилось, а `revenue_daily` считает только оплаченные;
@@ -113,7 +113,7 @@ UTM у бэкенда нет, метки живут только в кликст
Как эти же расхождения выглядят на зерне заказа, показывает стендовая
витрина `dm.purchase_vs_orders_v` с ее классами расхождений: это готовый
ответ на вопрос «а сколько именно и из-за чего». Запиши свой вывод —
ответ на вопрос «а сколько именно и из-за чего». Запишите свой вывод —
в двух-трех фразах, своими словами.
Проверять сходимость этих двух сумм не нужно и нельзя: они и не должны
@@ -122,8 +122,8 @@ UTM у бэкенда нет, метки живут только в кликст
## Как проверить себя
Деловой ключ — тройка `utm_source`, `utm_medium`, `utm_campaign` внутри
дня. Собери прямой агрегат из `dds.event_v` за день, соедини с
`dm.utm_effectiveness_v` полным внешним соединением и посчитай строки, где
дня. Соберите прямой агрегат из `dds.event_v` за день, соедините с
`dm.utm_effectiveness_v` полным внешним соединением и посчитайте строки, где
ключа нет с одной из сторон или где расходится любая из пяти величин. Ноль —
зеленый.