Процессы, потоки и планирование
- Как ОС запускает программу: от exec() до первого кванта планировщика. Разбор жизненного цикла процесса: создание, загрузка ELF/PE, инициализация адресного пространства, попадание в очередь планировщика. (strace, ps, top и вывод /proc).
- Планировщик Linux CFS: как считается «справедливость» и что такое виртуальное время. Понятное объяснение vruntime, весов, групп задач и почему «равные» процессы могут вести себя по-разному. (chrt, nice, cgroup и простые бенчмарки).
- Потоки vs процессы: где граница в ядре и как это видно в /proc. Разбираем, что общего у потоков (адресное пространство, файлы, сигналы) и чем они отличаются (TID, стек, регистры). Пример: вывод ps -eLo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan,args.
- Контекстный переключатель: из чего складывается задержка и как её увидеть. Теория + практика: сохранение регистров, обновление TLB, переключение стеков. Для примера — perf stat с метриками context-switches и простой тест с большим числом потоков.
Память и адресные пространства
- Виртуальная память: как адреса превращаются в байты и где прячется «магия» страниц. Объясняем MMU, таблицы страниц, PTE, TLB и что происходит при промахе. (Практическая часть: pmap, /proc/pid/maps, numactl для NUMA).
6 Стек, куча и mmap: где живёт программа и как ОС управляет этими областями. Разбираем сегменты ELF, аллокаторы (glibc malloc), mmap-файлы и анонимные регионы. (Пример: простая программа на C с выводом карт памяти).
7 Copy‑on‑Write и fork(): почему копирование памяти почти бесплатное. Механизм CoW, страницы только на чтение, триггер записи. (Практика: маленький бенчмарк fork + запись в память, сравнение с реальным копированием).
8 Huge pages и Transparent Huge Pages: зачем и какой эффект. Объясняем экономию TLB, сценарии баз данных, NUMA и возможные минусы фрагментации. (Практика: cat /proc/meminfo | grep Huge, настройка THP).
Ввод‑вывод и файловые системы
- Как работает обычный read(): от системного вызова до диска. Путь запроса: VFS → драйвер ФС → блочное устройство → контроллер. Практика: strace, iostat, iotop, blktrace
- Журналирование в файловых системах: зачем и как устроено. На примере ext4/XFS: журнал операций, порядок записи, гарантии целостности. Сравнение: «быстрее, но менее надёжно» vs «медленнее, но безопасно».
- Асинхронный ввод‑вывод: что реально даёт POSIX AIO и io_uring. Понятный разбор моделей: polling, callbacks, очереди. Практика: сравнение простого теста синхронного и асинхронного чтения.
- Файловая система как дерево: inodes, dentry, superblock и VFS. Объясняем абстракции ядра, которые позволяют одной ОС работать с разными ФС. Практика: stat, df, разбор вывода tune2fs.
Прерывания, таймеры и реальное время
- Прерывания и таймеры: как ОС узнаёт, что «прошло время». IRQ, обработчики, deferred work (softirq, workqueue), системные часы. Практика: /proc/interrupts, watch -n1 cat /proc/stat, простой тест задержек.
- Приоритеты и вытеснение: почему высокоприоритетный поток всё равно ждёт. Разбираем уровни приоритета, инверсию приоритетов и базовые способы её избегать. Практика: chrt и простой тест на задержку.
Безопасность, изоляция и контейнеры
- Процессы в изоляции: namespaces и cgroups. Что скрывает PID, mount, network namespace и как cgroups ограничивают CPU/память. Практика: запуск простой команды в unshare или через systemd-run --scope.
- Контроль доступа: DAC vs MAC на примере Linux. Права файлов (DAC) и мандатный контроль (SELinux/AppArmor) — где граница и когда нужен MAC. Практика: просмотр контекста SELinux (ls -Z) и правил AppArmor.
- Как устроены драйверы: от системного вызова к железу. Упрощённая модель: пользователь → ядро → драйвер → устройство. Практика: lsmod, dmesg, udevadm info, разбор простого модуля ядра (без компиляции — только структура).