Вопросы по 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 и его ограничения, блокировка от параллельного запуска. Экзотику вроде подстановки процессов ждут только от сильных кандидатов.