Вопросы по Linux и bash на собеседовании
Linux спрашивают через задачи эксплуатации, а не через определения. Что делать, если df показывает переполнение, а du нет. Почему процесс не убивается через kill -9. Куда исчезло место при живых гигабайтах. Тут же bash: кавычки, коды возврата и set -e.
Что спрашивают
- +Процессы и сигналы: состояния R, S, D, T и Z, чем SIGTERM отличается от SIGKILL, почему PID 1 в контейнере игнорирует сигналы
- +Файловая система: inode и жёсткие ссылки, удалённый но открытый файл, исчерпание inode, права и umask
- +systemd: юниты и daemon-reload, политики перезапуска, журнал и его хранение
- +Диагностика и bash: ss, lsof, strace, load average и iowait, ловушки кавычек, пайплайнов и set -euo pipefail
Из чего состоит тема
Так тема разложена в тренажёре: движок ведёт прогресс по каждой подтеме отдельно и возвращает те, где вы ошибаетесь.
- Bash: переменные и кавычки8
- Процессы и сигналы8
- Файловая система и права8
- grep, sed, awk, jq7
- systemd и юниты7
- Коды возврата и set -e7
- Память, CPU, диски7
- cron и systemd-таймеры6
- Диагностика и логи6
- Скрипты в проде6
Разборы подтем
Конспект по каждой: что это, как отвечать вслух, на чём валятся, плюс вопросы для самопроверки.
- Процессы и сигналы в Linux8 вопросов
- Файловая система Linux: inode и ссылки8 вопросов
- systemd: юниты, перезапуск, журнал7 вопросов
- Память, CPU и диски в Linux7 вопросов
- Диагностика в Linux: ss, strace, lsof6 вопросов
- Bash: кавычки, переменные, разделение слов8 вопросов
- Bash: коды возврата и set -euo pipefail7 вопросов
- grep, sed, awk и jq на практике7 вопросов
- cron и systemd-таймеры6 вопросов
- Скрипты в проде: идемпотентность и секреты6 вопросов
Примеры вопросов с разбором
- Сервис не стартует: bind: address already in use. Чем быстрее найти, кто держит порт?A)netstat -rB)ss -lptnC)ps aux с грепом по номеру портаD)tcpdump -i any port 8080
показать ответ и разбор
+B)ss -lptn// разбор: ss -lptn показывает слушающие TCP-сокеты (-l) вместе с процессом-владельцем (-p) и без резолва имён (-n) — сразу видно PID и команду. Аналог: lsof -i :8080. Если владельца не нашлось, порт может держать сокет в TIME_WAIT после прошлого процесса — тогда помогает SO_REUSEADDR в приложении, а не поиск виновного.
- На файл f сделаны жёсткая ссылка h и симлинк s. Удаляем f. Что с h и s?A)h читается, данные живы по счётчику ссылок; s ломаетсяB)Обе ссылки ломаются: файл удалён вместе с содержимымC)h ломается, s работает: симлинк хранит копию данныхD)Работают обе: ядро переводит симлинк на оставшуюся ссылку
показать ответ и разбор
+A)h читается, данные живы по счётчику ссылок; s ломается// разбор: rm снимает имя с inode и уменьшает счётчик ссылок. Жёсткая ссылка — второе равноправное имя того же inode, поэтому данные живы, пока счётчик больше нуля. Симлинк — отдельный файл с текстом пути: путь исчез, переход даёт ENOENT. Отсюда и разница в применении: hardlink не переживает переезд на другую ФС, symlink переживает, но легко становится битым.
- В ps процесс висит в состоянии Z и не убивается через kill -9. Что это такое?A)Процесс приостановлен сигналом STOP и ждёт продолженияB)Процесс уже завершился, но родитель не забрал его код возвратаC)Процесс потерял управляющий терминал и ушёл в фонD)Процесс застрял в ожидании диска и не принимает сигналы
показать ответ и разбор
+B)Процесс уже завершился, но родитель не забрал его код возврата// разбор: Z — зомби: процесс мёртв, от него остались PID и код возврата в таблице процессов, пока родитель не сделает wait(). Убивать нечего, сигнал адресуется живому процессу — потому kill -9 бессилен. Уходит либо когда родитель заберёт статус, либо когда родитель умрёт: тогда зомби усыновит PID 1 и приберёт. Толпа зомби — баг родителя, а не утечка памяти.
- free -m: free почти ноль, buff/cache — гигабайты. Память на хосте кончилась?A)Да: приложениям остался только swapB)Да: buff/cache — это утечка ядра, лечится drop_cachesC)Нет: под кэш отдана свободная память, смотри availableD)Нет: buff/cache учтён дважды, реальная занятость вдвое меньше
показать ответ и разбор
+C)Нет: под кэш отдана свободная память, смотри available// разбор: Ядро занимает незанятую память страничным кэшем: это ускоряет чтение и мгновенно отдаётся под запросы приложений. Поэтому смотрят не MemFree, а MemAvailable — оценку того, сколько можно выделить без подкачки. Нулевой MemFree на прод-хосте норма; тревожит падающий MemAvailable и растущий swap-in.
- Поправил unit-файл, сделал systemctl restart — сервис работает со старыми параметрами. Почему?A)systemd держит описания юнитов в памяти: нужен daemon-reloadB)Юнит надо переключить: сначала disable, потом enableC)Правка юнита применяется после перезагрузки хостаD)Нужен systemctl reload — он перечитывает файл юнита
показать ответ и разбор
+A)systemd держит описания юнитов в памяти: нужен daemon-reload// разбор: systemd читает юниты при старте и по daemon-reload, а restart перезапускает сервис с уже загруженным описанием. Порядок: правка → systemctl daemon-reload → systemctl restart. Сам daemon-reload работающие сервисы не трогает, а systemctl status честно предупреждает: unit file changed on disk.
- Скрипт вызывает утилиту так: deploy --token "$SECRET". Чем это плохо на общей машине?A)Длинная строка запуска обрежется по лимиту аргументовB)Переменная в кавычках попадёт в команду с лишними пробеламиC)Токен уедет в лог только при ошибке, в остальном это безопасноD)Аргументы процесса видны в ps любому пользователю хоста
показать ответ и разбор
+D)Аргументы процесса видны в ps любому пользователю хоста// разбор: Командная строка процесса лежит в /proc/PID/cmdline и читается всеми: любой пользователь на хосте увидит токен через ps, а сам вызов осядет в истории shell и в логах CI. Секреты передают переменной окружения, файлом с правами 600 или через stdin, а в идеале берут из хранилища с коротким сроком жизни.
- Скрипт обходит файлы через for f in $(ls). На каталоге с именем «отчёт за март.log» он ломается. Почему?A)ls в подстановке отдаёт имена с цветовыми кодамиB)ls сортирует вывод и обрывает его на первом пробелеC)Подстановка режется по пробелам на три словаD)for умеет обходить только массивы, а не вывод команды
показать ответ и разбор
+C)Подстановка режется по пробелам на три слова// разбор: Результат $(...) без кавычек проходит разделение слов по IFS (пробел, таб, перевод строки) и глоббинг: имя с пробелами разъезжается на несколько «файлов», а имя со звёздочкой ещё и раскроется. Правильно обходить глобом: for f in *.log — он отдаёт имена целиком. Для рекурсии — find -print0 в паре с read -d ''.
- Что даёт строка set -euo pipefail в начале скрипта?A)Пишет команды в лог, включает отладку и трассировкуB)Стоп по ошибке, ругань на пустую переменную, честный код пайплайнаC)Перезапуск скрипта при ошибке и продолжение с той же строкиD)Запрет на внешние команды и подстановки в скрипте
показать ответ и разбор
+B)Стоп по ошибке, ругань на пустую переменную, честный код пайплайна// разбор: -e завершает скрипт, когда команда вернула ненулевой код (кроме условий if, && и ||); -u роняет обращение к необъявленной переменной вместо тихой пустой строки; -o pipefail отдаёт кодом пайплайна первый ненулевой, а не код последней команды. Это минимальная страховка от «скрипт отработал успешно, но ничего не сделал».
- Скрипт руками работает, из crontab падает с «command not found». Первая причина?A)cron запускает скрипт без прав пользователя, от которого он заведёнB)cron не умеет запускать скрипты, только бинарникиC)У cron короткий PATH и нет окружения логинаD)Относительный путь в crontab считается от корня ФС
показать ответ и разбор
+C)У cron короткий PATH и нет окружения логина// разбор: cron даёт задаче минимальное окружение: PATH обычно /usr/bin:/bin, профиль пользователя не читается, переменных из .bashrc нет. Поэтому в задачах пишут полные пути к бинарям либо задают PATH и нужные переменные в самом скрипте. Заодно стоит перенаправлять вывод в лог — иначе он уйдёт письмом в никуда, и отладка станет гаданием.
это 9 из 70
Ещё 61 вопросов по теме — в тренажёре, с движком повторения
Прочитать разбор и ответить самому — разные навыки. В Сеньорчике вопросы идут сессиями, а движок возвращает подтемы, где вы ошибаетесь, пока они не начнут отскакивать. Бесплатно, лимит по энергии.
Частые вопросы
Какие команды диагностики спрашивают чаще всего?
Кто занял порт (ss или lsof), кто ест диск (du и df с их расхождением), почему процесс висит (strace и состояние в ps), что с памятью (free и MemAvailable вместо MemFree). Важнее не список, а порядок действий.
Насколько глубоко спрашивают bash?
До уровня, на котором скрипт не падает молча: кавычки и разделение слов, коды возврата пайплайнов, set -euo pipefail и его ограничения, блокировка от параллельного запуска. Экзотику вроде подстановки процессов ждут только от сильных кандидатов.