linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Cluster

← все кластеры

Процессы, сигналы, init

Базовый кластер. Здесь вопросы, на которых режутся даже сильные кандидаты потому что у Linux-процесса много пограничных деталей: PID 1, zombies, fork/exec, разница между сигналом и системным вызовом. Эти вопросы встречаются у Backend, SRE, DevOps и Platform-инженеров одинаково часто.

8 вопросов · ~25 мин чтения

Questions

На этой странице

  1. 01Что произойдёт, если PID 1 умрёт в Docker-контейнере?
  2. 02В чём разница между zombie и orphan процессом?
  3. 03В чём разница между SIGTERM и SIGKILL? Почему сначала TERM, потом KILL?
  4. 04Объясни fork() + exec(). Почему два syscall'а, а не один?
  5. 05В чём разница между namespaces и cgroups? Что делает контейнер контейнером?
  6. 06Как работает OOM killer? Можно ли защитить процесс?
  7. 07В чём разница между ps и top? Какой когда использовать?
  8. 08Что такое SUID-бит? Почему `passwd` работает от root, хотя запускает обычный юзер?

#pid-1-die

intermediateчасто

Что произойдёт, если PID 1 умрёт в Docker-контейнере?

Что отвечать

Контейнер немедленно завершится. PID 1 в Linux особенный - когда он умирает, ядро шлёт SIGKILL всем остальным процессам в этом PID namespace, и namespace разрушается. На хосте умерший PID 1 (обычно systemd) - это kernel panic.

Что хотят услышать

Senior должен: - разделить PID 1 на хосте и PID 1 в namespace контейнера - назвать обязанности PID 1: reap zombies, обработка SIGTERM - упомянуть `tini`/`dumb-init` и флаг `docker run --init` - объяснить почему `bash` как PID 1 - плохая идея (по умолчанию не реагирует на SIGTERM, не reap'ит zombies)

Подводные камни

  • ✗ Сказать «система пойдёт в panic» без оговорки про namespace - так бывает только для PID 1 хоста
  • ✗ Забыть про обязанность PID 1 вызывать wait() для осиротевших дочерних процессов - иначе они становятся zombies
  • ✗ Считать что node/python/java как ENTRYPOINT работают корректно в роли PID 1 - у большинства runtimes нет встроенного reaper'а

Follow-up

  • ? Зачем нужен tini и почему Docker сделал `--init` отдельным флагом, а не дефолтом?
  • ? Что произойдёт, если PID 1 не обрабатывает SIGTERM, а `docker stop` его шлёт?
  • ? Как Kubernetes отличает «pod завершился штатно» от «PID 1 крашнулся»?

Глубина в базе знаний

  • Процесс и PID
  • Сигналы (SIGTERM, SIGKILL, SIGHUP)
  • Linux namespaces
tags: containers, init, signalsbook: the.software.developer's.guide.to.linux.pdf:ch7

#zombie-vs-orphan

intermediateчасто

В чём разница между zombie и orphan процессом?

Что отвечать

Orphan - процесс, чей родитель умер раньше; ядро переподвешивает его на PID 1. Zombie - процесс, который УЖЕ умер, но родитель не вызвал `wait()` чтобы забрать exit-код; запись остаётся в process table со статусом `Z`. Zombie нельзя убить сигналом - он уже мёртв.

Что хотят услышать

Кандидат должен понимать что: - zombie не потребляет ресурсов кроме слота в process table, но если их много - упрётся в pid_max (по умолчанию 32768/4M) - починить zombie нельзя сигналом, только убить или дождаться wait() от родителя - правильный путь: убить родителя - PID 1 (или init-обёртка вроде tini) переподцепит и сделает wait() сам - в контейнере отсутствие zombie reaper'а в PID 1 - это бомба замедленного действия

Подводные камни

  • ✗ Перепутать местами: zombie - мёртв и ждёт wait(), orphan - жив, но без родителя
  • ✗ Сказать что `kill -9` убивает zombie - нет, zombie уже мёртв, kill ничего не делает
  • ✗ Не упомянуть SIGCHLD - сигнал, который ядро шлёт родителю когда ребёнок умирает

Follow-up

  • ? Как найти все zombies в системе одной командой?
  • ? Что такое `SIGCHLD` и как процесс может его проигнорировать чтобы не делать wait()?
  • ? Что делает `prctl(PR_SET_CHILD_SUBREAPER)` и зачем он tini/systemd-user?

Глубина в базе знаний

  • Процесс и PID
  • Сигналы (SIGTERM, SIGKILL, SIGHUP)
tags: process-lifecycle, signals

#sigterm-vs-sigkill

juniorчасто

В чём разница между SIGTERM и SIGKILL? Почему сначала TERM, потом KILL?

Что отвечать

SIGTERM (15) - вежливый запрос завершиться: процесс получает шанс сохранить буферы, закрыть файлы, дождаться детей. SIGKILL (9) - ядро убивает процесс мгновенно, без шанса. Стандартный workflow: TERM → подождать N секунд → KILL только если не вышел.

Что хотят услышать

Senior должен сказать: - SIGKILL и SIGSTOP - единственные сигналы, которые нельзя обработать или проигнорировать (обслуживаются ядром напрямую) - SIGKILL не вызывает финализаторов, fsync, не освобождает блокировки на уровне приложения → можно получить битые файлы - процесс в D-state (uninterruptible sleep, обычно ждёт диск/NFS) не реагирует даже на SIGKILL - застрял внутри syscall'а - в Kubernetes `terminationGracePeriodSeconds` - это именно тот интервал между SIGTERM и SIGKILL

Подводные камни

  • ✗ Сказать «kill -9 всегда работает» - нет, D-state процессы не убить
  • ✗ Не упомянуть что SIGKILL не даёт процессу освободить блокировки/буферы
  • ✗ Думать что SIGTERM = SIGKILL по умолчанию - `kill <pid>` без сигнала шлёт SIGTERM

Follow-up

  • ? Что такое D-state и как из него выбираться?
  • ? Что произойдёт с TCP-соединениями процесса при SIGKILL?
  • ? Какие сигналы по умолчанию игнорируются процессом (например SIGCHLD)?

Глубина в базе знаний

  • Сигналы (SIGTERM, SIGKILL, SIGHUP)
  • Процесс и PID
tags: signals, lifecycle

#fork-exec

intermediateиногда

Объясни fork() + exec(). Почему два syscall'а, а не один?

Что отвечать

`fork()` создаёт копию текущего процесса (родительский и дочерний идентичны, отличаются только PID и возвращаемым значением fork). `exec()` заменяет образ текущего процесса на другой бинарь, сохраняя PID. Разделение нужно чтобы дочерний процесс мог настроить окружение (переменные, fd, signal-handlers) ПЕРЕД запуском нового бинаря - что делает шелл при пайпах и редиректах.

Что хотят услышать

Кандидат должен: - объяснить copy-on-write - fork не копирует страницы памяти физически, только page tables, и копирование происходит при первой записи - назвать `vfork()` и `posix_spawn()` как оптимизации - привести пример: shell делает `fork`, в child закрывает stdin, открывает файл как fd 0, потом `exec` - так работает `cmd < file` - упомянуть `clone()` как более общий syscall (fork - обёртка над clone с дефолтными флагами)

Подводные камни

  • ✗ Сказать что fork медленный - на современном Linux с COW он дёшев
  • ✗ Забыть что после fork и в parent, и в child выполняется тот же код до проверки `if (pid == 0)`
  • ✗ Не упомянуть что fd наследуются дочерним процессом - отсюда работают пайпы шелла

Follow-up

  • ? Что такое copy-on-write и как это видно в /proc/<pid>/smaps?
  • ? Чем `clone()` отличается от `fork()`? Какие у него флаги?
  • ? Почему в многопоточных программах `fork()` опасен (mutex может остаться залоченным в child)?

Глубина в базе знаний

  • Процесс и PID
tags: syscalls, lifecyclebook: accelerated.linux.api.for.software.diagnostics.pdf:ch3

#namespaces-vs-cgroups

seniorчасто

В чём разница между namespaces и cgroups? Что делает контейнер контейнером?

Что отвечать

Namespaces изолируют **то, что видит процесс** (свой PID-tree, свою сеть, свой mount-table, свои users). Cgroups лимитируют **сколько ресурсов процесс может потратить** (CPU, RAM, IO, PIDs). Контейнер = процесс с собственными namespaces + cgroup-лимитами; это две независимых подсистемы ядра, которые Docker/runc склеивает.

Что хотят услышать

Senior должен назвать: - 8 типов namespaces: mnt, net, pid, user, uts, ipc, cgroup, time - что cgroups v2 (с 2016) - единая иерархия, в отличие от v1 где каждый ресурс жил в отдельном дереве - `unshare`, `nsenter`, `clone()` с флагами CLONE_NEW* - низкоуровневые инструменты для namespaces - что VM и контейнер - разные технологии: VM эмулирует железо, контейнер делит ядро с хостом

Подводные камни

  • ✗ Сказать что контейнер - это «облегчённая VM» - это инженерно неверно
  • ✗ Перепутать namespaces и cgroups: namespaces ≠ лимиты
  • ✗ Забыть про user namespace - самый сложный, нужен для rootless containers

Follow-up

  • ? Что произойдёт если процесс из контейнера попробует `mount`?
  • ? Как работает `memory.high` vs `memory.max` в cgroups v2?
  • ? Чем rootless container отличается от обычного - какие namespaces задействованы?

Глубина в базе знаний

  • Linux namespaces
  • cgroups (v2)
  • cgroups v2 - unified hierarchy, PSI, eBPF control
tags: containers, namespaces, cgroupsbook: the.software.developer's.guide.to.linux.pdf:ch8

#oom-killer

intermediateчасто

Как работает OOM killer? Можно ли защитить процесс?

Что отвечать

Когда ядру не хватает памяти и нельзя освободить страницы reclaim'ом, запускается OOM killer. Он считает `oom_score` для каждого процесса (грубо: %памяти процесса × штрафы) и убивает того, у кого score выше. Можно повлиять через `/proc/<pid>/oom_score_adj` (-1000 до 1000, -1000 = неуязвим).

Что хотят услышать

Кандидат должен сказать: - OOM killer работает не от total RAM, а от per-cgroup лимита (если процесс в cgroup с memory.max) - в логах ищется по `dmesg | grep -i oom` или `journalctl -k --grep=oom` - `oom_score_adj=-1000` делает процесс невыбираемым (systemd часто ставит так для критичных сервисов) - swap не спасает от OOM, только оттягивает; thrashing хуже OOM - есть `earlyoom`/`systemd-oomd` - userspace OOM-демоны, которые срабатывают раньше kernel OOM

Подводные камни

  • ✗ Сказать что OOM killer выбирает «самый старый» или «самый большой» процесс - на самом деле выбирает по oom_score, формула сложнее
  • ✗ Перепутать `oom_score` и `oom_score_adj`: первый ядро считает, второй задаёт админ для влияния
  • ✗ Не упомянуть что OOM в cgroup убивает процесс ВНУТРИ cgroup, а не глобально - это разные сценарии

Follow-up

  • ? Как найти кого OOM killer убил последним? Какие логи смотреть?
  • ? Чем `systemd-oomd` отличается от kernel OOM killer?
  • ? Почему swap не спасает от OOM, и когда swap всё-таки имеет смысл?

Глубина в базе знаний

  • OOM killer
  • cgroups v2 - unified hierarchy, PSI, eBPF control
  • Swap - когда RAM кончается
tags: memory, kernel, troubleshooting

#ps-vs-top

juniorиногда

В чём разница между ps и top? Какой когда использовать?

Что отвечать

`ps` - снимок процессов на момент вызова (читает `/proc/*/stat` один раз). `top`/`htop` - живое окно, перечитывает то же самое каждые N секунд и считает дельту (CPU% за интервал). Для «что сейчас живёт» - ps, для «что грузит систему прямо сейчас» - top/htop.

Что хотят услышать

Senior должен знать: - оба читают `/proc/<pid>/stat`, `/proc/<pid>/status`, `/proc/<pid>/cmdline` - CPU% в ps - total с момента старта процесса (почти бесполезно) - CPU% в top - за последний интервал sampling'а, реальная нагрузка - `ps aux` (BSD-стиль) vs `ps -ef` (Unix-стиль) - два формата, работают одинаково, разный вывод - htop добавляет TUI, сигналы по F9, tree-view по F5 - но за капотом то же `/proc`

Подводные камни

  • ✗ Использовать `ps aux | grep myproc` чтобы посмотреть нагрузку - CPU% будет средний за весь lifetime
  • ✗ Не знать что top по умолчанию сортирует по CPU%; htop - по PID
  • ✗ Думать что top «мониторит» - на самом деле он только периодически перечитывает /proc

Follow-up

  • ? Что покажет `ps -eo pid,ppid,user,cmd,wchan` и зачем нужна колонка wchan?
  • ? Как top считает разницу CPU между tick'ами? Откуда берёт jiffies?
  • ? Чем `pgrep`/`pkill` удобнее чем `ps | grep | awk | xargs kill`?

Глубина в базе знаний

  • Процесс и PID
  • ps - снимок процессов
  • htop - интерактивный монитор процессов
tags: process-tooling, observability

#setuid-binary

intermediateиногда

Что такое SUID-бит? Почему `passwd` работает от root, хотя запускает обычный юзер?

Что отвечать

SUID-бит на бинаре говорит ядру: при запуске установить EUID процесса равным владельцу файла, а не вызывающему юзеру. `/usr/bin/passwd` имеет SUID и владельца root, поэтому любой юзер может изменить свой пароль - passwd на короткое время работает как root, чтобы записать в `/etc/shadow`.

Что хотят услышать

Senior должен: - различать UID (реальный, кто запустил) и EUID (effective, от кого идут permission-checks) - назвать опасности SUID-бинарей: уязвимость в SUID-бинаре = локальный root, отсюда CIS-benchmark «находи и проверяй все SUID-бинари» - упомянуть `capabilities` как современную альтернативу SUID - выдать процессу только нужную capability (CAP_NET_BIND_SERVICE для bind <1024), а не весь root - назвать `nosuid` mount-option как защиту: SUID на /home или /tmp не сработает

Подводные камни

  • ✗ Сказать что SUID делает процесс root всегда - нет, только EUID меняется, и только для бинаря владельца root
  • ✗ Не упомянуть SGID и sticky-bit - родственные механизмы
  • ✗ Забыть что SUID игнорируется на скриптах с shebang (ядро отказывается повышать привилегии для интерпретируемого кода)

Follow-up

  • ? Как найти все SUID-бинари в системе одной командой?
  • ? Чем capabilities лучше SUID? Покажи на примере ping.
  • ? Почему SUID на shell-скрипте не повышает привилегии?

Глубина в базе знаний

  • SUID, SGID, sticky bit - спецбиты прав
  • Linux capabilities - биты привилегий
  • File permissions: rwx и chmod
tags: security, permissionsbook: linux.basics.for.Hackers.pdf:ch5
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки