Learning Platform
Глоссарий Troubleshooting
Урок 01.01 · 20 мин
Начальный
Course introData engineeringDSA fundamentals

Кому этот курс

Этот курс — про структуры данных и алгоритмы для будущего Junior Data Engineer. Не про подготовку к LeetCode-собесам в Google, не про спортивное программирование, не про теорию ради теории. Цель — чтобы вы понимали, что происходит внутри list.append(), почему dict[key] обычно быстрый, а иногда внезапно нет, и почему ваш ETL-скрипт читает 10M строк за 2 секунды или за 2 минуты при одном и том же big-O.

Курс ориентирован на тех, кто:

  • Уже умеет писать базовый Python. Это не «желательно», а обязательное условие: нужен хотя бы модуль 1 курса Python 01 — переменные, условия (if/else), циклы (for/while), функции. Без этого минимума уже с модуля 2 будет по-настоящему тяжело: примеры и измерения здесь — это код на Python, который вы должны спокойно читать и запускать. Если вы ещё ни разу не открывали терминал и не писали программ, начните со «Ступени 0» — Computing Basics, а затем пройдите модуль 1 Python.
WARNING

Дальше первого модуля курс читается только если вы уже понимаете переменные, условия, циклы и функции в Python. Не нужен «продвинутый» Python — нужен именно фундамент из модуля 1 курса Python 01. Если этот фундамент есть, идите дальше. Если нет — сначала закройте его, иначе застрянете на модуле 2.

Коллекции Python: list, dict, set, tuple
  • Идёт в data engineering: ETL-пайплайны, Airflow DAG-и, SQL-модели, потоковая обработка. Везде, где «миллион строк» — это минимум, а не «много».
  • Хочет понимать числа, а не теорию. Если на собесе спросят «почему append O(1) amortized», вы должны не только сказать определение, но и показать, как это измеряется и где ломается.

Курс не для тех, кто:

  • Готовится к собеседованиям в FAANG — там нужен LeetCode-grind, другая методика и другие задачи (динамическое программирование, сложные графовые алгоритмы, оптимизация под constant time wall-clock).
  • Изучает CS на университетском уровне — мы не будем доказывать корректность алгоритмов через инварианты циклов и индукцию. Мы будем мерить.
  • Хочет глубокую теорию сложности (NP-полнота, теория автоматов, формальные грамматики) — это не наш профиль.

Чем этот курс отличается от LeetCode-туториалов

Большинство курсов по DSA выглядят так: «Вот связный список, вот его big-O для операций, вот задача — reverse a linked list, вот решение». Big-O записан, галочка поставлена, идём дальше. Проблема — после такого курса вы знаете формулы, но не понимаете, почему linked list реально медленнее массива на современном железе, хотя big-O у обхода одинаковый — O(n).

Здесь иначе. Главная идея этого курса — DSA до железа:

Три уровня понимания DSA

LeetCode останавливается на первом. Большинство курсов — на втором. Мы идём до третьего.

Уровень 1Синтаксис и APIlist.append(x), dict[key] = v, sorted(list). Чему учат за час.
Уровень 2Big-O и абстрактная модельВремя и память как функция от n. Что учат в LeetCode-курсах за неделю.
Уровень 3Memory layout, cache, измеренияПочему dict-lookup на самом деле быстрый, что такое cache line, как list разрастается при append. Что отличает middle от junior.

Конкретно это значит: для каждой структуры данных мы:

  1. Показываем зачем она нужна — задача из data engineering, где без неё было бы плохо.
  2. Разбираем внутреннее устройство — что лежит в памяти, какой layout, какие указатели.
  3. Записываем big-O для основных операций, но не как формулу, а как число секунд на конкретных n.
  4. Делаем бенчмарки через timeit и tracemalloc — реальные числа на вашей машине.
  5. Показываем где big-O врёт — место, где константы и cache-эффекты ломают теоретическую модель.

Что внутри курса

Курс из 20 модулей примерно на 60 часов. Структура:

Структура курса

От фундамента (Big-O, память) до прикладных DE-паттернов и capstone-проекта.

Модули 00-02Введение, Big-O, память и железоФундамент: что такое сложность, иерархия памяти, кэш-линии, branch prediction. Базис, без которого следующее непонятно.
Модули 03-06Массивы, списки, стеки, очередиБазовые линейные структуры. Contiguous memory vs pointer chasing. Реальные измерения.
Модули 07-08Хеш-таблицы (Python dict)Хеш-функция, коллизии, open addressing, compact dict layout (3.6+). До деталей CPython.
Модули 09-12Деревья, кучи, графы, обходыBST, heap, представления графов, BFS/DFS — на DE-примерах: топологический сорт DAG-а, агрегации.
Модули 13-16Сортировка, поиск, рекурсияTimsort внутри Python, merge sort, бинарный поиск, divide-and-conquer.
Модули 17-18DE-паттерны и capstoneПрименение всего: дедупликация миллиардов событий, оконные функции, capstone — настоящий event pipeline.

Все измерения — на Python 3.13. Python мы выбрали потому, что:

  • Это lingua franca для DE — Airflow, Spark, dbt, Polars, pandas. Если идёте в DE, вы будете писать Python.
  • В Python структуры данных видны «насквозь» — есть sys.getsizeof, dis, gc, tracemalloc. Можно реально потрогать байты, в отличие от Java/Go, где runtime прячет детали.
  • Python достаточно медленный, чтобы разница в big-O или cache-friendly коде сразу видна на секундомере — на C++ часто разница исчезает в шуме.

Но сам курс языко-нейтрален — концепты массивов, хеш-таблиц и графов одинаковы в любом языке. Просто измерения и API — на Python.

Ключевая идея: каждое утверждение подкреплено числом

Это правило курса номер один. Когда вы читаете «list slower than deque на head insertion» — будет код, который это показывает:

import timeit

# list — массив, вставка в начало двигает все элементы
t_list = timeit.timeit(
    'lst.insert(0, 1)',
    setup='lst = list(range(10000))',
    number=10000
)
print(f"list.insert(0): {t_list:.4f}s")

# deque — двусвязный список из блоков
t_deque = timeit.timeit(
    'd.appendleft(1)',
    setup='from collections import deque; d = deque(range(10000))',
    number=10000
)
print(f"deque.appendleft: {t_deque:.4f}s")

Типичный вывод на современной машине:

list.insert(0): 0.5421s
deque.appendleft: 0.0008s

Разница в ~700 раз. Не «O(n) против O(1)», а 0.54 секунды против 0.0008 секунды. Числа запоминаются лучше формул.

TIP

Скопируйте код выше в файл bench.py и запустите python bench.py. Числа будут немного отличаться (зависит от CPU, ОС), но порядок — те же 2-3 десятичных порядка разницы. Это ваше первое измерение в этом курсе. Привыкайте.

Что вы получите в итоге

К концу курса вы:

  • Знаете big-O для всех базовых структур и можете быстро прикинуть сложность чужого кода.
  • Понимаете, что числа из big-O — это упрощение, а на реальном железе константы и cache-эффекты могут поменять всё.
  • Умеете мерить код через timeit, tracemalloc, pympler и читать вывод правильно.
  • Знаете изнутри Python list (over-allocation), dict (compact layout, open addressing), set, deque, heapq.
  • Применяете правильные структуры в DE-задачах: дедупликация, агрегация, обход DAG-а, топологическая сортировка.
  • Не пугаетесь вопросов на собесе «почему dict O(1)» — у вас есть и формальный ответ, и числа, и понимание границ.

И главное — у вас будет интуиция. После курса, когда увидите чужой код с if x in some_big_list: внутри цикла, у вас в голове сразу загорится: «это O(n²), переделать на set». Не потому что зазубрили — а потому что почувствовали.

Операторы Python и введение в Big-O — уровень CPython
Цикл изучения каждой темы

Этот цикл повторяется в каждом уроке. Сначала угадайте — потом измерьте.

1ЗадачаКонкретная DE-задача, где нужна структура
2ТеорияКак устроена структура, big-O
3УгадайПредположите, какой результат измерения вы ожидаете
4ИзмерьЗапустите код, посмотрите числа
5ОбъясниСовпало? Не совпало? Почему?

В следующем уроке — что нужно знать, чтобы начать. И главное — что не нужно знать.


Как создавался курс

Курс создан при участии Claude (Anthropic) как соавтора: ИИ помогал писать материалы, структурировать темы, генерировать примеры кода и диаграммы. Каждая глава проходила ручную сверку с первоисточниками — спецификациями, документацией, исходным кодом рассматриваемых систем — но гарантировать 100% точность невозможно.

Если вы заметили неточность, опечатку или хотите предложить улучшение — напишите в Telegram-группу курса. Это самый ценный вклад в курс, который вы можете сделать.


Углублённое изучение с Claude

Курс рассчитан на самостоятельное изучение, но любая теория быстрее ложится, если задавать вопросы. Рекомендую держать рядом браузерное расширение Claude (claude.com/download) — оно работает с контентом открытой страницы: выделяете кусок урока и спрашиваете напрямую.

Сценарии, которые особенно хорошо работают для углублённого погружения:

  • «Объясни проще» / «дай ещё один пример» — когда формулировка из урока не дошла с первого раза.
  • «Покажи, как это устроено на уровне кода / железа» — когда хочется спуститься на слой ниже того, что даёт урок.
  • «Как это связано с [другая тема курса]» — когда нужно увязать концепцию с тем, что было раньше.
  • «У меня в проекте стек X — как применить?» — когда хочется примерить материал на свой реальный кейс.

Это не замена курсу, а способ ускорить интеграцию материала в вашу картину мира. Если что-то из ответов Claude расходится с уроком — присылайте в Telegram-группу, курс будет уточнён.


Нашли ошибку?

Если заметили неточность, опечатку или хотите предложить улучшение:

Telegram-группа курса
Обсуждение, вопросы, предложения

Telegram-канал

Подписывайтесь, чтобы узнавать об обновлениях и новых курсах:

@levoely_channel
Новости, обновления, новые курсы

Проверка знанийKnowledge check
Чем подход этого курса отличается от типичного LeetCode-туториала?
ОтветAnswer
LeetCode фокусируется на синтаксисе и формулах big-O — после задачи галочка ставится и идём дальше. Этот курс идёт на третий уровень: memory layout, cache lines, реальные измерения через timeit и tracemalloc. Главное правило — каждое утверждение про "быстрее/медленнее" подкрепляется числом, а не только big-O записью. Цель — интуиция, а не зазубренные формулы.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Какое ключевое отличие подхода этого курса от типичного LeetCode-туториала?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 3