{ "meta": { "title": "Диагностика уровня: C/C++, алгоритмы, Linux, сети", "pass_hint": "24+ из 32 верных — уверенный вход; 16–23 — база есть, нужен добор; <16 — модуль в план с нуля", "domains": { "c_cpp": "C/C++ и системная память", "algo": "Алгоритмы и структуры данных", "linux": "Linux / ОС", "net": "Сети L2/L3, TCP/IP" } }, "questions": [ { "d": "c_cpp", "q": "Чему равен sizeof(struct S { char a; int b; char c; }) на 64-битной платформе без pack-атрибутов?", "o": [ "6", "9", "12", "16" ], "a": 2, "e": "a = 1 байт + 3 паддинга, b = 4, c = 1 + 3 хвостового паддинга = 12 (выравнивание структуры по 4)." }, { "d": "c_cpp", "q": "Что означает undefined behavior (UB)?", "o": [ "Программа гарантированно завершится с ошибкой", "Компилятор вправе сгенерировать любой код, программа не обязана иметь смысл", "Поведение определено стандартом, но зависит от платформы", "Это предупреждение компилятора, которое можно игнорировать" ], "a": 1, "e": "UB — стандарт не накладывает требований: компилятор может что угодно, вплоть до выкидывания проверок." }, { "d": "c_cpp", "q": "std::move(x) — что он делает сам по себе?", "o": [ "Перемещает объект и обнуляет исходный", "Вызывает конструктор перемещения", "Приводит x к rvalue-ссылке, перемещение делает уже вызванный конструктор/присваивание", "Освобождает память объекта" ], "a": 2, "e": "move — это static_cast к rvalue; фактическое перемещение выполняет конструктор/оператор присваивания." }, { "d": "c_cpp", "q": "Чем new отличается от malloc?", "o": [ "Только синтаксисом", "malloc работает только со структурами", "new не может вернуть nullptr", "new вызывает конструктор, возвращает типизированный указатель и бросает исключение при неудаче" ], "a": 3, "e": "new = выделение + конструктор + типизированный указатель + исключение; malloc возвращает void* и nullptr при неудаче." }, { "d": "c_cpp", "q": "Класс владеет ресурсом и имеет деструктор, освобождающий его. Копирующий конструктор/присваивание не объявлены. Что будет?", "o": [ "Всё нормально, компилятор сам сделает глубокую копию", "Неявные копии дадут два владельца одного ресурса → double free/утечка", "Программа не скомпилируется", "Компилятор сгенерирует перемещение вместо копирования" ], "a": 1, "e": "Правило трёх/пяти: владеющий ресурсом класс должен определить копирование/перемещение или запретить их." }, { "d": "c_cpp", "q": "Для чего нужен виртуальный деструктор у базового класса?", "o": [ "Чтобы ускорить разрушение", "Он не нужен, деструкторы всегда виртуальны", "Чтобы поля базы не копировались", "Чтобы при delete по указателю на базу вызвался деструктор производного класса" ], "a": 3, "e": "Без virtual-деструктора delete через Base* — UB, деструктор производного не вызовется." }, { "d": "c_cpp", "q": "Что делает ключевое слово const после сигнатуры метода (int size() const)?", "o": [ "Делает метод виртуальным", "Запрещает копирование возвращаемого значения", "Обязывает не менять поля объекта и позволяет вызывать метод на const-объекте", "Ничего, это оформление" ], "a": 2, "e": "const-метод получает this как const-указатель; на изменении поля — ошибка компиляции." }, { "d": "c_cpp", "q": "Определён ли стандартом порядок вычисления аргументов функции (f(a(), b()))?", "o": [ "Слева направо", "Справа налево", "Не определён (порядок не специфицирован, но вычисления не пересекаются)", "Зависит только от оптимизаций" ], "a": 2, "e": "Порядок аргументов не специфицирован; с C++17 вычисления не чередуются (indeterminately sequenced), но порядок всё равно не задан." }, { "d": "algo", "q": "Средняя сложность поиска в хеш-таблице (при разумной нагрузке)?", "o": [ "O(n log n)", "O(log n)", "O(n)", "O(1)" ], "a": 3, "e": "Амортизированно O(1) в среднем; худший случай при всех коллизиях — O(n)." }, { "d": "algo", "q": "Какая структура лучше подходит для задачи «поиск слов по префиксу»?", "o": [ "Префиксное дерево (trie)", "Хеш-таблица", "Двоичная куча", "Связный список" ], "a": 0, "e": "Trie даёт проход по префиксу за O(len) и общий префикс хранит один раз." }, { "d": "algo", "q": "Сколько сравнений нужно бинарному поиску в худшем случае в отсортированном массиве из 1 000 000 элементов?", "o": [ "20", "10", "100", "1 000" ], "a": 0, "e": "log2(1e6) ≈ 19.9 → 20 итераций." }, { "d": "algo", "q": "При каком условии применим алгоритм Дейкстры?", "o": [ "Граф обязательно связный", "Веса рёбер неотрицательны", "Граф неориентированный", "Граф разреженный" ], "a": 1, "e": "Отрицательные рёбра ломают инвариант «кратчайший путь найден»; тогда Беллман–Форд." }, { "d": "algo", "q": "Какова сложность построения кучи (heapify) из произвольного массива?", "o": [ "O(n)", "O(log n)", "O(1)", "O(n log n)" ], "a": 0, "e": "Просеивание снизу вверх даёт сумму геометрической прогрессии — O(n), хотя каждый push по отдельности O(log n)." }, { "d": "algo", "q": "Какая из сортировок устойчивая (stable)?", "o": [ "Быстрая (quicksort)", "Пирамидальная (heapsort)", "Слиянием (merge sort)", "Выбором (selection sort)" ], "a": 2, "e": "Merge sort сохраняет порядок равных элементов; quicksort/heapsort/selection — нет." }, { "d": "algo", "q": "Для какого графа возможна топологическая сортировка?", "o": [ "Для ориентированного ациклического (DAG)", "Для любого связного", "Для двудольного", "Для полного" ], "a": 0, "e": "Цикл делает линейный порядок невозможным; топосорт — признак DAG." }, { "d": "algo", "q": "Как найти цикл в связном списке за O(1) дополнительной памяти?", "o": [ "Алгоритм Флойда: медленный и быстрый указатели", "Хранить посещённые узлы в хеш-таблице", "Отсортировать список", "Рекурсивно пройти до nullptr" ], "a": 0, "e": "«Черепаха и заяц»: если цикл есть, указатели встретятся." }, { "d": "linux", "q": "Что делает fork()?", "o": [ "Заменяет образ процесса", "Создаёт поток в том же адресном пространстве", "Создаёт копию процесса; в родителе возвращает PID ребёнка, в ребёнке — 0", "Загружает библиотеку в процесс" ], "a": 2, "e": "fork = новый процесс (свой PID, COW-копия памяти); execve меняет образ, clone — поток." }, { "d": "linux", "q": "Чем поток отличается от процесса в Linux?", "o": [ "Ничем, это синонимы", "Потоки делят адресное пространство и файловые дескрипторы, но имеют свои стеки", "Поток всегда быстрее", "Процессы не могут работать параллельно" ], "a": 1, "e": "clone с CLONE_VM/CLONE_FILES — потоки; у каждого свой стек и регистры." }, { "d": "linux", "q": "Что такое процесс-зомби?", "o": [ "Процесс, съедающий CPU", "Завершившийся процесс, чей статус ещё не собран родителем через wait()", "Процесс без терминала", "Процесс, потерявший родителя" ], "a": 1, "e": "Запись остаётся в таблице процессов до wait/waitpid; «потерявший родителя» — это сирота (переходит к init)." }, { "d": "linux", "q": "Какой механизм в Linux штатно обслуживает десятки тысяч сетевых соединений в одном потоке?", "o": [ "select()", "Неблокирующие сокеты в цикле опроса", "epoll", "fork на каждое соединение" ], "a": 2, "e": "epoll — O(1) на готовое событие; select линейно по всем дескрипторам." }, { "d": "linux", "q": "Что происходит со страницами памяти при fork()?", "o": [ "Сразу полностью копируются", "Память обнуляется", "Копируются при первой записи (copy-on-write)", "Ребёнок получает те же физические страницы без защиты" ], "a": 2, "e": "COW: страницы помечаются read-only и копируются по факту записи." }, { "d": "linux", "q": "Процесс завершился с кодом 137. Что это значит?", "o": [ "Ошибка сегментации", "Процесс убит сигналом 9 (SIGKILL) — типично OOM-killer или docker kill", "Не найден файл", "Процесс вышел штатно" ], "a": 1, "e": "137 = 128 + 9: завершение по SIGKILL; код 139 = 128 + 11 (SIGSEGV)." }, { "d": "linux", "q": "Что даёт вызов mmap() на файл?", "o": [ "Полное чтение файла в кучу", "Отображение файла в адресное пространство: работа как с массивом в памяти", "Блокировку файла", "Копирование файла" ], "a": 1, "e": "Страницы подгружаются по обращению; запись уходит в файл (или в MAP_SHARED-память)." }, { "d": "linux", "q": "Зачем нужен waitpid() родителю?", "o": [ "Чтобы приостановить ребёнка", "Чтобы сменить приоритет ребёнка", "Чтобы получить доступ к памяти ребёнка", "Чтобы собрать статус завершения и убрать зомби" ], "a": 3, "e": "Без wait завершившиеся дети остаются зомби и держат запись в таблице процессов." }, { "d": "net", "q": "Сколько байт в Ethernet-заголовке кадра без VLAN-тега?", "o": [ "8", "14", "18", "20" ], "a": 1, "e": "dst MAC (6) + src MAC (6) + EtherType (2) = 14; VLAN 802.1Q добавляет 4 байта." }, { "d": "net", "q": "На каком уровне OSI работает обычный коммутатор (switch)?", "o": [ "L2", "L4", "L3", "L1" ], "a": 0, "e": "Коммутация по MAC-адресам и таблице обучения — канальный уровень (L2); маршрутизатор — L3." }, { "d": "net", "q": "Что делает протокол ARP?", "o": [ "Раздаёт IP-адреса", "Проверяет целостность пакетов", "Разрешает доменные имена", "Сопоставляет IP-адрес и MAC-адрес в локальном сегменте" ], "a": 3, "e": "ARP-запрос broadcast, ответ unicast; DHCP раздаёт адреса, DNS — имена." }, { "d": "net", "q": "Какое поле IPv4-заголовка уменьшается на единицу на каждом маршрутизаторе?", "o": [ "Total Length", "IHL", "Checksum", "TTL" ], "a": 3, "e": "TTL защищает от петель; при 0 пакет отбрасывается и уходит ICMP Time Exceeded. Контрольная сумма при этом пересчитывается, но не «уменьшается на 1»." }, { "d": "net", "q": "Правильная последовательность установки TCP-соединения?", "o": [ "SYN → SYN-ACK → ACK", "SYN → ACK → SYN-ACK", "SYN-ACK → SYN → ACK", "ACK → SYN → SYN-ACK" ], "a": 0, "e": "Клиент SYN, сервер SYN-ACK, клиент ACK; номера подтверждения = seq+1." }, { "d": "net", "q": "Ключевое отличие TCP от UDP?", "o": [ "TCP быстрее", "TCP работает только на L2", "UDP не поддерживает порты", "TCP даёт надёжный поток байт с подтверждениями, порядком и повторной передачей" ], "a": 3, "e": "UDP — дейтаграммы «как есть», без гарантий и порядка." }, { "d": "net", "q": "Что делает VLAN-тег 802.1Q?", "o": [ "Добавляет в кадр 4 байта с 12-битным идентификатором VLAN", "Шифрует кадр", "Увеличивает MTU", "Превращает кадр в IP-пакет" ], "a": 0, "e": "Тег EtherType 0x8100 + PCP/DEI + 12 бит VID; логически разделяет L2-сегменты." }, { "d": "net", "q": "Сколько адресов узлов доступно в подсети /26?", "o": [ "32", "126", "64", "62" ], "a": 3, "e": "/26 = 64 адреса, минус адрес сети и broadcast → 62 хоста." } ] }