# Вопросы: Linux и Bash Опираются на кейс: [CASE.md](CASE.md). Источники — [VK Cloud.md](../../interview/VK%20Cloud.md) (основной объём), [Dit Moscow.md](../../interview/Dit%20Moscow.md), [Alfa-Bank.md](../../interview/Alfa-Bank.md). ### Есть load average в Linux — как считается? Скользящее экспоненциально взвешенное среднее числа процессов в состоянии "runnable" (готовы выполняться/выполняются) плюс процессов в непрерываемом ожидании ввода-вывода (D-state), усреднённое за 1/5/15 минут. Число выше количества ядер не всегда значит перегрузку CPU — часто виноват диск или сеть (процессы висят в D-state), поэтому смотрю load average вместе с `top`/`vmstat`, а не отдельно. ### Free и available в выводе free — чем отличаются, и если free почти 0, а available много — это плохо? `free` — буквально свободная, ничем не занятая память. `available` — память, реально доступная для новых приложений без свопинга, с учётом того, что ядро может быстро освободить часть кеша страниц (page cache) и буферов при необходимости. Linux агрессивно использует свободную память под кеш файловой системы — это не потеря, а разумное использование ресурса. Поэтому если `free` близко к 0, а `available` большое — это нормально и даже хорошо: система эффективно использует память под кеш, который мгновенно отдаст приложениям по запросу. Плохой признак — низкий именно `available` вместе с активным использованием swap. ### Кейс: сервер тормозит, с каких 3-5 команд начнёшь диагностику? `uptime` (load average, масштаб проблемы) → `top`/`htop` (кто ест CPU/память прямо сейчас) → `free -h` (память) → `df -h` (не кончилось ли место, особенно если есть запись логов) → `iostat -x 1`/`vmstat 1` (I/O, если по CPU и памяти виновник не найден). Порядок именно такой — от общей картины к частностям, чтобы не тратить время на глубокую диагностику не в том направлении. ### Как найти pid нужного процесса и убить его? `ps aux | grep <имя>` или `pgrep -f <паттерн>` — найти pid. Убить: `kill -15 ` (SIGTERM, вежливое завершение, процесс может перехватить сигнал и корректно закрыть ресурсы) или `kill -9 ` (SIGKILL, безусловное принудительное убийство ядром — процесс не может его ни перехватить, ни проигнорировать). Второй способ — `pkill -f <паттерн>` находит и убивает сразу по паттерну имени команды, без отдельного поиска pid. ### Команда kill и её популярные сигналы, 2 способа убить процесс Основные сигналы: `SIGTERM` (15, по умолчанию у `kill`) — просьба завершиться корректно; `SIGKILL` (9) — принудительное безусловное завершение ядром; `SIGHUP` (1) — исторически «повесить трубку», многие демоны используют его как сигнал перечитать конфиг без полного рестарта; `SIGINT` (2) — то же, что Ctrl+C. Два способа убить: `kill ` (по идентификатору процесса) и `pkill -f <паттерн>` (по имени/паттерну командной строки, без предварительного поиска pid). ### Что делают df и du — с подвохом (df говорит место закончилось, du — что всё в порядке) `df` считает занятое место по факту использованных блоков файловой системы. `du` считает по дереву каталогов, суммируя размеры файлов, которые там реально видны. Расхождение возникает, когда файл удалён (`rm`), но его всё ещё держит открытым какой-то процесс — файла больше нет в дереве каталогов (`du` его не видит), но место физически не освобождается, пока не закроется последний файловый дескриптор, ссылающийся на inode этого файла (`df` показывает место как занятое). Я воспроизвёл это вживую: `dd` создаёт большой файл в фоне, `rm` его удаляет, пока процесс жив — `df` и `du` расходятся, пока процесс не завершится (`ls -l /proc//fd` при этом показывает "живой" дескриптор на уже удалённый файл). ### Что покажет ps -aux / ps -ef? Оба показывают список всех процессов в системе, но в разном формате: `ps aux` — BSD-стиль (USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND), `ps -ef` — System V-стиль (UID, PID, PPID — родительский процесс явно виден, C, STIME, TTY, TIME, CMD). `ps -ef` удобнее, когда нужно явно видеть иерархию процессов через PPID; `aux` привычнее для быстрой оценки потребления ресурсов. ### Как назначить владельца папки в Linux? Как выдаются права, что такое 777 и 755? `chown user:group /path/to/dir` — сменить владельца (пользователя) и группу; `chown -R` — рекурсивно для содержимого. Права задаются тремя цифрами (владелец/группа/остальные), каждая — сумма: read=4, write=2, execute=1. `755` = владелец rwx (7), группа и остальные r-x (5) — типично для исполняемых скриптов и директорий, куда нужен доступ на чтение всем. `777` = rwx всем без ограничений — практически всегда небезопасно на проде, разрешает любому пользователю системы читать, менять и исполнять файл. ### Что делает awk и варианты использования? Текстовый процессор, работающий построчно и разбивающий каждую строку на поля по разделителю (по умолчанию — пробел/таб): `$1`, `$2` — первое/второе поле, `$0` — вся строка, `NR` — номер текущей строки. Типичное использование: `awk '{print $1}' file` — вывести первую колонку, `awk -F: '{print $1}' /etc/passwd` — сменить разделитель на `:`, `awk 'NR==2 {print $5}'` — взять конкретное поле конкретной строки (я так парсил вывод `df -h` в скрипте disk-check из [CASE.md](CASE.md)), `awk '/pattern/ {print}'` — фильтрация строк по регулярке, аналог grep, но с доступом к полям. ### У тебя большой лог — как найти все строки с ошибкой connection timeout? `grep -c "connection timeout" file.log` — посчитать количество вхождений; `grep -n "connection timeout" file.log` — вывести с номерами строк; для действительно больших файлов и потоковой обработки в реальном времени — `tail -f file.log | grep --line-buffered "connection timeout"`. Если нужен контекст вокруг ошибки — `grep -B2 -A2 "connection timeout" file.log` (2 строки до и после). ### Что такое cgroups и namespaces в Linux? Namespaces — механизм ядра, изолирующий, что процесс видит: свой PID namespace (процесс видит только «свои» процессы, начиная нумерацию с 1), сетевой namespace (свои интерфейсы, таблицы маршрутизации), mount namespace (своя файловая система), UTS (своё hostname) и т.д. Cgroups (control groups) — механизм, ограничивающий и учитывающий, сколько ресурсов процесс может использовать (CPU, память, I/O). Вместе это и есть технический фундамент контейнеризации: контейнер — это обычный процесс на хосте, которому через namespaces ограничили видимость системы, а через cgroups — доступные ресурсы (без отдельной виртуализации ядра, в отличие от полноценных VM). Подробнее в контексте Docker — [../docker/QUESTIONS.md](../docker/QUESTIONS.md). ### Что такое inode? Структура данных файловой системы, хранящая метаданные файла (владелец, права, размер, время изменения, указатели на блоки данных на диске) — но не само имя файла. Имя файла — это просто запись-ссылка в каталоге, указывающая на inode. Отсюда и разница между df/du из вопроса выше: пока хотя бы один процесс держит открытым файловый дескриптор, указывающий на inode, место на диске не освобождается, даже если все имена (ссылки в каталогах) на этот inode уже удалены. ### Что такое дескрипторы и reference count в файловом дескрипторе? Файловый дескриптор — небольшое целое число, которым процесс ссылается на открытый файл/сокет/пайп внутри ядра (0, 1, 2 — stdin/stdout/stderr зарезервированы). Reference count в контексте inode — счётчик количества ссылок на него: это и жёсткие ссылки в каталогах (`ln`), и открытые файловые дескрипторы процессов. Данные на диске реально освобождаются только тогда, когда reference count падает до нуля — то есть удалены все имена (hard links) и закрыты все процессы, державшие файл открытым. ### Ссылки жёсткие и мягкие (hard/soft) — в чём разница и что происходит при удалении файла? Жёсткая ссылка (`ln`) — ещё одно имя, указывающее прямо на тот же inode: у файла и его hard link одинаковый inode-номер, и оба «равноправны» — удаление одного из имён не трогает данные, пока жива хотя бы одна ссылка (см. reference count выше). Мягкая/символическая ссылка (`ln -s`) — отдельный маленький файл, который просто хранит путь к другому файлу; если оригинал удалить, symlink останется, но будет указывать в никуда («битая ссылка»). Hard link не может пересекать границы файловых систем и не может указывать на директорию (за редкими системными исключениями), symlink может — это одно из отличий на практике. ### Как проверить, что порт открыт/слушается, и как найти порт нужного процесса? `ss -tulpn` (современный аналог `netstat`) — покажет все слушающие TCP/UDP порты и какой процесс их держит. Для конкретного процесса: `ss -tulpn | grep ` либо через `/proc//net/tcp` (низкоуровнево). Для проверки доступности порта на удалённом хосте: `nc -zv host port` или `curl -v telnet://host:port`. ### Как будешь менять параметры ядра Linux? Через `sysctl`: временно — `sysctl -w vm.swappiness=10` (действует до перезагрузки), постоянно — правка `/etc/sysctl.conf` или файла в `/etc/sysctl.d/*.conf` с последующим `sysctl -p` для применения без перезагрузки. Типичные параметры, которые встречаются на практике: `vm.swappiness` (насколько активно система уходит в своп), `net.core.somaxconn` (размер очереди входящих TCP-соединений), `fs.file-max` (лимит открытых файловых дескрипторов на систему). ### Что такое systemd? Зачем нужна директория /etc/systemd/system? Systemd — современная система инициализации и менеджер служб в большинстве дистрибутивов Linux (включая Astra и современные CentOS/RHEL) — управляет запуском, остановкой, зависимостями и мониторингом состояния сервисов через unit-файлы. `/etc/systemd/system` — стандартное место для unit-файлов, добавленных администратором вручную (в отличие от `/usr/lib/systemd/system`, куда unit-файлы кладут пакеты дистрибутива) — сюда я клал свои unit и timer для скрипта disk-check из [CASE.md](CASE.md). ### Что такое zombie/orphan процесс? Zombie — процесс, который уже завершился, но его родитель ещё не вызвал `wait()`, чтобы забрать его код возврата — запись о процессе висит в таблице процессов (виден в `ps` со статусом `Z`), но сам процесс уже не потребляет ресурсов кроме этой записи. Orphan — процесс, чей родитель завершился раньше него; такой процесс автоматически «усыновляется» init-процессом (PID 1 или ближайшим subreaper), который и заберёт его код возврата, когда тот завершится — то есть orphan сам по себе не проблема, в отличие от накопления zombie-процессов, что говорит об ошибке в родительском процессе (не вызывает wait()). ### Что будешь делать, если упал сервер? Если сервер на VMware — как будешь спасать VM и какую диагностику проведёшь? Порядок действий: сначала проверить, отвечает ли хост вообще (ping, SSH) — если нет, для VM это часто означает проблему на уровне гипервизора, а не гостевой ОС. Дальше — зайти через консоль гипервизора (у VMware это vSphere/ESXi console, доступ к которой не зависит от сетевого стека самой VM) и посмотреть состояние виртуалки: зависла ли она (нет отклика на клавиатуру в консоли), ушла в панику ядра (виден текст паники на консоли), или процесс просто не отвечает по сети из-за исчерпания ресурсов. Дальнейшая диагностика по возможности зайти в саму гостевую ОС: `dmesg`/`journalctl -xb` на предмет OOM killer или паники ядра, проверка диска (не забился ли под 100%, что часто останавливает запись логов и сервисов), проверка сети гипервизора (не отвалился ли виртуальный сетевой адаптер). Если гостевая ОС совсем не отвечает — крайняя мера восстановления это перезапуск VM средствами гипервизора (soft reset через ACPI-сигнал, если возможно, иначе hard reset) с последующим разбором причины по логам, которые сохранились до сбоя. Личного опыта администрирования именно VMware у меня нет — это разбор на уровне общей логики диагностики сбоя виртуальной машины, применимой к любому гипервизору.