diff --git a/HR_BASE.md b/HR_BASE.md new file mode 100644 index 0000000..1ca24a8 --- /dev/null +++ b/HR_BASE.md @@ -0,0 +1,369 @@ +# База перед тех-скринингом (HR, видеосвязь) + +Собрано под вакансию Eltex «Разработчик C/C++» (Новосибирск, 1–3 года, ключевые навыки +C/C++, Linux, TCP/IP). Формат — вопрос → короткий ответ. Читать подряд, вслух проговаривая +ответы: на скрининге важно не «знаю», а «скажу связно за 20 секунд». + +--- + +## 1. ООП (спрашивают почти всегда) + +**Что такое ООП?** Парадигма, где программа — набор объектов, обменивающихся сообщениями; объект объединяет данные и поведение. + +**Три кита?** Инкапсуляция, наследование, полиморфизм. (Иногда добавляют абстракцию.) + +**Инкапсуляция?** Сокрытие внутреннего состояния за публичным интерфейсом: поля private, доступ через методы. + +**Наследование?** Переиспользование и расширение: класс-наследник получает члены базового. + +**Полиморфизм?** Один интерфейс — разные реализации. В C++ динамический полиморфизм — через `virtual` (решение принимается в рантайме по фактическому типу), статический — перегрузка и шаблоны (на компиляции). + +**Класс и объект?** Класс — описание (чертёж), объект — экземпляр в памяти. + +**struct и class в C++?** Разница только в доступе по умолчанию: у struct public, у class private. + +**Что такое виртуальная функция?** Функция, вызываемая по фактическому типу объекта. Реализуется через таблицу виртуальных функций (vtable) — отсюда +указатель на объект. + +**Зачем виртуальный деструктор?** Если удалять наследника через `Base*` без него — UB, деструктор наследника не вызовется, ресурсы утекут. + +**Можно ли вызвать virtual из конструктора?** Можно, но вызовется версия текущего класса, а не наследника: объект ещё не достроен. + +**Абстрактный класс?** Класс с хотя бы одной чисто виртуальной функцией (`= 0`), экземпляр создать нельзя. В C++ нет отдельного `interface` — его роль играет такой класс. + +**Перегрузка и переопределение — в чём разница?** Перегрузка: несколько функций с одним именем и разными параметрами в одной области видимости. Переопределение: virtual-функция наследника с той же сигнатурой. + +**Что такое static-член?** Общий для всех объектов класса, живёт вне объекта; у static-метода нет `this`. + +**Что такое SOLID?** S — единственная ответственность, O — открыт для расширения/закрыт для изменения, L — подстановка Лисков, I — разделение интерфейсов, D — инверсия зависимостей. Достаточно назвать и объяснить одну-две. + +**Композиция или наследование?** Предпочитают композицию: наследование жёстко связывает классы, композиция гибче. + +--- + +## 2. C/C++ (ядро вакансии) + +**Указатель и ссылка — разница?** Указатель — адрес, может быть null, его можно менять и арифметикой ходить. Ссылка — псевдоним существующего объекта, не бывает null, перепривязать нельзя. + +**new/delete против malloc/free?** `new` вызывает конструктор и возвращает типизированный указатель, `malloc` даёт сырой блок; `new` бросает исключение, `malloc` возвращает NULL; `delete` вызывает деструктор. + +**Стек и куча?** Стек — автоматическая память (локальные переменные, быстрая, ограничена). Куча — динамическая (`new`/`malloc`, больше, но освобождать вручную). + +**Что такое утечка памяти?** Выделили и не освободили. Ищется ASAN (LeakSanitizer), valgrind. + +**RAII?** Ресурс захватывается в конструкторе, освобождается в деструкторе — утечек нет даже при исключениях. Так работают `std::vector`, `std::ifstream`, умные указатели. + +**unique_ptr и shared_ptr?** `unique_ptr` — единственный владелец, без счётчика, дешевле. `shared_ptr` — общий, считает ссылки, есть накладные расходы и проблема циклических ссылок (`weak_ptr`). + +**Правило трёх/пяти?** Если класс владеет ресурсом и задан деструктор — надо определить копирование и перемещение (в C++11+: конструктор/присваивание копированием и перемещением). + +**Что делает std::move?** Ничего сам по себе — это `static_cast` к rvalue-ссылке. Перемещение выполняет конструктор/присваивание перемещением. + +**Что такое UB?** Undefined behavior — стандарт не накладывает требований. Примеры: выход за границы, знаковое переполнение, сдвиг в знаковый бит, разыменование null, гонка данных. + +**Что проверяют ASAN и UBSAN?** ASAN — выходы за границы, use-after-free, двойное освобождение, утечки. UBSAN — неопределённое поведение (переполнения, сдвиги, выравнивание). + +**sizeof(struct { char a; int b; char c; }) на x86-64?** 12: `a` в 0, padding 1–3, `b` в 4–7, `c` в 8, padding 9–11 до выравнивания структуры по 4. + +**Порядок вычисления аргументов f(a(), b()) задан?** Нет, не определён — нельзя полагаться. + +**Что делает const после сигнатуры метода?** Делает `this` указателем на константу: метод не меняет поля объекта, и его можно вызывать у const-объекта. + +**Что такое перегрузка операторов и зачем?** Своя семантика для `+`, `==`, `[]` и т.п., чтобы тип вёл себя как встроенный. Нельзя перегружать `.`, `::`, `?:`, `sizeof`. + +**Компиляция по шагам?** Препроцессор (`#include`, `#define`) → компиляция в объектные файлы → линковка в исполняемый. Ошибка «undefined reference» — от линковщика. + +**Зачем header guards?** Чтобы заголовок не подключался дважды — иначе повторное определение типа. + +**Что такое forward declaration?** Объявление класса/функции без определения, чтобы не тянуть `#include`; достаточно для указателей и ссылок. + +**Что такое шаблон (template)?** Обобщённый код, тип подставляется при компиляции. Цена — ошибки и раздувание кода. + +**Что такое лямбда?** Анонимная функция с захватом контекста (`[&]`, `[=]`). Синтаксический сахар над функтором. + +**Что такое пространство имён?** Способ избежать конфликта имён; `std::` — пример. + +**volatile — что это?** Говорит компилятору не кэшировать значение в регистре (регистры железа, переменные, меняемые извне). Это не про многопоточность — для неё `std::atomic`. + +--- + +## 3. STL (обязательно, спрашивают про сложности) + +**Какие контейнеры знаешь?** Последовательные: `vector`, `list`, `deque`, `array`. Ассоциативные: `map`, `set` (деревья, O(log n)). Хеш-таблицы: `unordered_map`, `unordered_set` (O(1) в среднем). Адаптеры: `stack`, `queue`, `priority_queue`. + +**vector — сложности?** Доступ по индексу O(1), push_back амортизированное O(1), вставка/удаление в середине O(n), поиск O(n). + +**Почему push_back амортизированное O(1)?** Ёмкость удваивается, реаллокация O(n) случается редко — в среднем одна операция O(1). + +**list — сложности?** Доступ по номеру O(n), вставка/удаление при известном узле O(1), поиск O(n). Память дороже из-за указателей. + +**map против unordered_map?** `map` — красно-чёрное дерево: O(log n), ключи упорядочены. `unordered_map` — хеш-таблица: O(1) в среднем, порядок не определён, нужен `std::hash`. + +**Что быстрее и когда?** Поиск — обычно `unordered_map`. Если нужен порядок обхода или диапазонные запросы — `map`. + +**Итераторы и их инвалидация?** Итератор — обобщённый указатель на элемент. У `vector` реаллокация инвалидирует все итераторы, у `list` — только итератор удалённого элемента. + +**Как удалить элементы из vector по условию?** Идиома erase-remove: `v.erase(std::remove_if(v.begin(), v.end(), pred), v.end());`. + +**reserve и resize?** `reserve` меняет ёмкость (память), не размер. `resize` меняет размер (создаёт/удаляет элементы). + +**emplace_back против push_back?** `emplace_back` конструирует объект на месте — без копирования/перемещения. + +**Как работает priority_queue?** Бинарная куча поверх `vector`: вставка O(log n), извлечение максимума O(log n), доступ к максимуму O(1). По умолчанию max-куча. + +**Какие алгоритмы STL знаешь?** `sort` (O(n log n), неустойчив), `stable_sort`, `find`, `count`, `lower_bound`/`upper_bound` (O(log n) на отсортированном), `accumulate`, `remove_if`, `unique`, `next_permutation`. + +**Что такое функтор и предикат?** Объект с `operator()`. Предикат — функция/функтор, возвращающий bool, используется в алгоритмах. + +**string — это контейнер?** Да, `std::basic_string`: `size()`, `substr`, `find`, `append`; данные лежат непрерывно, `.c_str()` даёт C-строку. + +--- + +## 4. Linux и ОС + +**Процесс и поток?** Процесс — программа в исполнении со своим адресным пространством и PID. Поток — единица выполнения внутри процесса: общая память, свой стек и регистры. + +**Что делает fork()?** Создаёт копию процесса. Возвращает дважды: в родителе — PID ребёнка, в ребёнке — 0, при ошибке −1. + +**Что с памятью при fork()?** Copy-on-write: страницы общие, копируются при первой записи. + +**exec?** Заменяет образ текущего процесса (код, данные, стек). При успехе не возвращается. `fork` + `exec` — запуск внешней программы. + +**Зачем waitpid?** Забрать код возврата и не оставлять зомби. + +**Зомби и сирота?** Зомби — завершившийся процесс, чья запись ждёт `wait`. Сирота — процесс, чей родитель умер; его усыновляет init (PID 1). + +**Коды возврата 137 и 139?** 137 = 128+9 (SIGKILL), 139 = 128+11 (SIGSEGV). Так кодирует оболочка. + +**Сигналы, основные?** SIGINT (2, Ctrl+C), SIGKILL (9, не перехватить), SIGTERM (15, корректное завершение), SIGSEGV (11), SIGPIPE (13, запись в закрытый сокет), SIGCHLD (17). + +**SIGTERM против SIGKILL?** SIGTERM можно перехватить и завершиться аккуратно, SIGKILL нельзя ни перехватить, ни проигнорировать. + +**Файловый дескриптор?** Число, по которому программа обращается к открытому файлу, сокету, pipe. 0/1/2 — stdin/stdout/stderr. + +**Что такое epoll?** Механизм мультиплексирования: ядро сообщает о готовых дескрипторах, сложность O(1) на событие. `select`/`poll` перебирают все дескрипторы — O(n). + +**mmap?** Отображает файл в память: страницы подгружаются по обращению, вместо read/write работаешь с указателем. + +**Виртуальная память и страница?** Каждому процессу — своё адресное пространство; память делится на страницы (обычно 4 КБ), отображаемые на физическую. + +**Что такое swap?** Выгрузка страниц на диск при нехватке памяти. Медленно, но спасает от OOM. + +**Что такое inode?** Структура метаданных файла (права, размер, владелец, указатели на блоки). Имя файла — отдельно, в каталоге. + +**Права доступа 755?** Владелец rwx, группа r-x, остальные r-x. `chmod`, `chown` — смена прав и владельца. + +**Что такое pipe и перенаправление?** `|` соединяет вывод одной программы со входом другой; `>`, `>>`, `2>&1` перенаправляют потоки. + +**Как посмотреть процессы и нагрузку?** `ps aux`, `top`/`htop`, `pidstat`; `free -h` — память, `df -h` — диски, `iostat` — ввод-вывод. + +**Что такое демон?** Фоновый процесс без управляющего терминала; запускается systemd (unit-файлы, `systemctl start/status`). + +**Что такое ядро и системный вызов?** Ядро управляет ресурсами; программа обращается к нему через системные вызовы (`open`, `read`, `write`, `fork`). `strace` показывает эти вызовы. + +**Мьютекс, семафор, атомик?** Мьютекс — блокировка на одного владельца. Семафор — счётчик на N владельцев. Атомик — операция без блокировки, аппаратно. + +**Что такое гонка данных и дедлок?** Гонка — несинхронизированный доступ к общей памяти (ловит ThreadSanitizer). Дедлок — потоки ждут ресурсы друг друга; лечится единым порядком захвата. + +**Условие переменная (condition_variable)?** Способ ждать событие: ждать в цикле с предикатом (`while (!ready) cv.wait(lock);`) — защита от ложных пробуждений. + +--- + +## 5. Сети: OSI, TCP/IP, TCP, UDP (ядро вакансии) + +**Семь уровней OSI?** Физический, канальный, сетевой, транспортный, сеансовый, представления, прикладной. Практически работают с пятью. + +**Что на каждом уровне?** L1 — биты и среды (витая пара, оптика). L2 — кадры, MAC, коммутатор. L3 — пакеты, IP, маршрутизатор. L4 — TCP/UDP, порты. L5–L7 — сессии, кодирование, прикладные протоколы (HTTP, DNS). + +**TCP/IP модель?** Канальный, интернет, транспортный, прикладной. Соответствует OSI снизу. + +**Инкапсуляция?** Каждый уровень добавляет свой заголовок: Ethernet (14 байт) → IP (20) → TCP (20) → данные. При передаче пакет кладут внутрь кадра. + +**Сколько байт в Ethernet-заголовке?** 14 (MAC получателя 6, MAC отправителя 6, тип 2). VLAN 802.1Q добавляет 4. + +**MAC-адрес?** 48 бит, физический адрес интерфейса, действует в пределах сегмента. + +**ARP?** Находит MAC по IP в локальном сегменте: широковещательный запрос → ответ. + +**MTU?** Максимальный размер полезной нагрузки кадра, для Ethernet 1500 байт. Больше — фрагментация или ошибка. + +**IPv4-заголовок, что важно?** Минимум 20 байт: версия/IHL, длина, TTL, протокол, контрольная сумма заголовка, адреса источника и назначения. TTL уменьшается на 1 на каждом маршрутизаторе. + +**Маски и подсети?** Маска делит адрес на сеть и узел. `/24` — 254 узла, `/26` — 62, `/30` — 2 (точка-точка). Широковещательный адрес — все единицы в хостовой части. + +**Маршрутизация?** Узел сравнивает адрес со своей маской: своя подсеть — ARP и напрямую, чужая — на шлюз. Шлюз по умолчанию — выход в другие сети. + +**ICMP?** Служебные сообщения: `ping` (echo request/reply), `traceroute` (истечение TTL), «destination unreachable». + +**Порядок установки TCP-соединения?** SYN → SYN-ACK → ACK (трёхстороннее рукопожатие). + +**Как закрывается TCP?** FIN → ACK → FIN → ACK; сторона, закрывшая первой, ждёт TIME_WAIT (2×MSL), чтобы добить потерянные сегменты. + +**Флаги TCP?** SYN, ACK, FIN, RST, PSH, URG. + +**Что даёт TCP?** Надёжность: нумерация, подтверждения, ретрансмиссии по таймауту, окно (управление потоком), контроль перегрузки, сохранение порядка. + +**Что такое окно?** Сколько байт можно отправить без подтверждения. Управляет скоростью и защищает от переполнения получателя. + +**UDP?** Без соединения и гарантий: заголовок 8 байт, порядок и доставка не гарантируются. Быстро и дёшево: DNS, DHCP, VoIP, игры, стриминг. + +**TCP или UDP — когда что?** TCP — когда важна целостность (файлы, HTTP, SSH). UDP — когда важна задержка или данные самодостаточны (DNS, видео, телеметрия). + +**Что такое порт?** Номер приложения на узле (16 бит). Известные: 22 SSH, 53 DNS, 80 HTTP, 443 HTTPS. + +**DNS?** Превращает имя в IP. Обычно UDP/53, при больших ответах — TCP/53. + +**DHCP?** Автоматическая выдача IP, маски, шлюза, DNS. + +**NAT?** Подмена адресов при выходе в интернет: много внутренних устройств через один внешний IP. + +**Сокеты: как устроен сервер?** `socket` → `bind` → `listen` → `accept` → `read`/`write` → `close`. Клиент: `socket` → `connect`. Для множества соединений — `epoll` и неблокирующие сокеты. + +**Что такое неблокирующий сокет и EAGAIN?** Вызов не ждёт данных: если их нет, возвращает −1 и `errno = EAGAIN` — надо вернуться позже. + +**Чем смотрят трафик?** `tcpdump`, Wireshark. Базово: `tcpdump -i eth0 -nn port 80`. + +--- + +## 6. Многопоточность (в вакансии: многопоточные приложения) + +**Как создать поток в C++?** `std::thread t(f, args); t.join();` (или `detach`, но тогда следи за временем жизни). + +**Как защитить общие данные?** `std::mutex` + `std::lock_guard`/`std::unique_lock`; для счётчиков — `std::atomic`. + +**Что такое ложное пробуждение?** `wait` может вернуться без сигнала — поэтому ждут в цикле с предикатом. + +**Как избежать дедлока?** Единый порядок захвата мьютексов, `std::lock`/`std::scoped_lock` для нескольких сразу, не держать блокировку при вызове чужого кода. + +**Producer/consumer — как?** Очередь + мьютекс + condition_variable: производитель кладёт и уведомляет, потребитель ждёт и забирает. + +**Пул потоков зачем?** Создание потока дорого; пул переиспользует N потоков и очередь задач. + +**Потокобезопасный size()?** Нужен либо атомарный счётчик, либо мьютекс: без этого чтение и запись — гонка данных. + +--- + +## 7. Git + +**Основной цикл работы?** `git clone` → `git checkout -b feature` → правки → `git add` → `git commit` → `git push` → pull request. + +**Что такое коммит, ветка, HEAD?** Коммит — снимок состояния с родителями. Ветка — подвижный указатель на коммит. HEAD — где ты сейчас. + +**merge и rebase?** merge создаёт коммит слияния, история ветвится. rebase переносит коммиты поверх другой ветки — история линейная, но переписываются хеши. + +**Конфликт — что делать?** Git помечает файлы, правишь вручную, `git add`, `git merge --continue` (или `--abort`). + +**reset, revert, checkout?** `reset` двигает ветку (может потерять коммиты), `revert` создаёт обратный коммит — безопасно для общей ветки, `checkout`/`switch` переключает ветки и файлы. + +**stash?** Отложить незакоммиченные изменения: `git stash`, потом `git stash pop`. + +**fetch и pull?** `fetch` скачивает без слияния, `pull` = fetch + merge (или rebase). + +**Как посмотреть историю и что менялось?** `git log --oneline --graph`, `git diff`, `git show `, `git blame`. + +**Что не коммитить?** Секреты, артефакты сборки, большие бинарники — через `.gitignore`. + +--- + +## 8. Docker + +**Образ и контейнер?** Образ — неизменяемый шаблон (слои файловой системы). Контейнер — запущенный экземпляр образа плюс своё изменяемое состояние. + +**Чем отличается от виртуальной машины?** Контейнер использует ядро хоста и изолирует процессы (namespaces, cgroups) — легче и стартует за секунды; VM несёт своё ядро. + +**Dockerfile — ключевые инструкции?** `FROM`, `RUN`, `COPY`, `WORKDIR`, `ENV`, `CMD`/`ENTRYPOINT`, `EXPOSE`. + +**Зачем слои и порядок инструкций?** Каждая инструкция — слой, слои кэшируются; часто меняющееся (код) ставят после редко меняющегося (зависимости), чтобы кэш работал. + +**Volume и bind mount?** Volume — управляемое Docker хранилище (данные переживают контейнер). Bind mount — каталог хоста внутри контейнера. + +**Сети в Docker?** По умолчанию bridge с внутренними IP; порты публикуются через `-p 8080:80`. Есть host и overlay для swarm. + +**docker-compose?** Описание нескольких сервисов в одном YAML: `docker compose up -d`. + +**Где это в Eltex?** Воспроизводимая сборка и тесты: один образ у всех, «у меня работает» перестаёт быть аргументом. + +--- + +## 9. GDB и отладка + +**Как запустить?** `g++ -g -O0 prog.cpp -o prog` (обязательно `-g`), затем `gdb ./prog`, `run`. + +**Основные команды?** `break main` / `break file:line`, `run`, `next` (по шагам, через вызовы), `step` (внутрь), `continue`, `print x`, `bt` (стек вызовов), `frame N`, `watch var`, `info threads`. + +**Как отладить падение?** Запустить, получить `bt`, посмотреть кадр с падением, `print` указателей; либо core dump (`ulimit -c unlimited`, затем `gdb prog core`). + +**Что такое core dump?** Снимок памяти процесса в момент падения; позволяет разобраться постфактум. + +**Санитайзеры?** ASAN (память), UBSAN (UB), TSan (гонки), MSan (неинициализированная память) — включаются флагом `-fsanitize=...`. + +**valgrind?** Инструмент поиска утечек и ошибок памяти без пересборки; медленнее санитайзеров. + +--- + +## 10. Bash и инструменты + +**Что такое скрипт и его шапка?** `#!/usr/bin/env bash` плюс `set -euo pipefail` — падать на ошибках, на необъявленных переменных и в конвейерах. + +**Переменные и аргументы?** `name=value`, `$name`, `$1..$9`, `$#`, `$@`, `$?` (код возврата), `$$` (PID). + +**grep, awk, sed — для чего?** grep — поиск по шаблону, awk — обработка по колонкам и подсчёты, sed — замена/правка потока. Для больших файлов — только они, а не bash-цикл по строкам. + +**Пайплайны и перенаправления?** `cmd1 | cmd2`, `>`, `>>`, `2>`, `2>&1`, `tee`. + +**Как найти файлы и выполнить команду?** `find /path -name '*.log' -mtime -1`, `find ... -exec ... {} +`, `xargs`. + +**Полезное на каждый день?** `ps/top`, `ss -tulpn` (порты), `df -h`, `du -sh`, `tail -f`, `journalctl -u сервис`, `systemctl status`. + +--- + +## 11. Embedded и SoC (в вакансии «плюс», знать обзорно) + +**Что такое bringup?** Запуск новой платы: uboot → ядро → корневая ФС → периферия. Задача — довести устройство до стабильной работы. + +**uboot?** Загрузчик: инициализирует железо, грузит ядро и передаёт ему параметры (device tree). + +**Модуль ядра?** Код, загружаемый в ядро (`insmod`/`rmmod`), с `init`/`exit`; печатает через `printk`, видно в `dmesg`. + +**Символьный драйвер?** Даёт доступ к устройству как к файлу через `file_operations` (`open`, `read`, `write`, `ioctl`). + +**Device tree?** Описание железа (адреса, прерывания, шины) для ядра — отдельно от кода. + +**Cross-compile?** Сборка под другую архитектуру (например ARM на x86) тулчейном `arm-linux-gnueabihf-gcc`. + +**Что сказать честно?** Опыта продуктовой разработки драйверов нет, теорию знаю: модуль, драйвер, device tree, cross-compile; готов добирать на месте. + +--- + +## 12. Вопросы, которые задаст HR (и хорошие ответы) + +**Расскажи о себе.** 40 секунд: кто, сколько лет в разработке, на чём пишешь (C/C++, Linux), чем занимался последним, почему интересна встраиваемая разработка и сети. + +**Почему Eltex?** Продукт настоящий и низкоуровневый: коммутаторы, маршрутизаторы, GPON. Хочу расти в C++/Linux/сетях на реальном железе, а не на абстрактных сервисах. + +**Что знаешь о компании?** Более 2000 человек, Новосибирск, телекоммуникационное оборудование (Ethernet-коммутаторы, сервисные маршрутизаторы, Wi-Fi, GPON, IoT), свои SoC-устройства. + +**Почему уходишь с текущего места?** Без негатива: хочу ближе к системной разработке и сетям, где больше глубины. + +**Готов к офису/гибриду в Новосибирске?** Отвечай прямо, как есть; если релокация — скажи, что готов обсуждать сроки. + +**Ожидания по зарплате?** Назови вилку с обоснованием по рынку и добавь «готов обсуждать по итогам интервью». + +**Сильные и слабые стороны?** Сильная — довожу до работающего результата, разбираюсь в отладке. Слабая — называй реальную и что делаешь: например, «раньше писал по памяти, теперь веду заметки и проверяю сложности по коду». + +**Готов к задачам на алгоритмы?** Да, тренируюсь: базовые структуры, сложности, типовые задачи на строки/массивы/графы. + +**Есть вопросы к нам?** Обязательно спроси: какой продукт и команда, на каком стеке и железе, как устроен онбординг, как выглядит процесс разработки и ревью, что считается успехом в первые месяцы. + +**Что почитать про нас перед интервью?** Сайт Eltex, раздел про продукты и вакансию; интервью и доклады сотрудников на конференциях. + +--- + +## 13. Шпаргалка чисел (выучить наизусть) + +- Ethernet-заголовок 14 байт, VLAN-тег +4, MTU 1500. +- IPv4-заголовок 20 байт, TCP-заголовок 20 байт, UDP-заголовок 8 байт. +- MAC 48 бит, IPv4 32 бита, порт 16 бит. +- Подсети: /24 → 254 узла, /26 → 62, /30 → 2. +- log₂(1000) ≈ 10, log₂(10⁶) ≈ 20. +- 137 = SIGKILL (128+9), 139 = SIGSEGV (128+11), 143 = SIGTERM (128+15). +- Порты: 22 SSH, 53 DNS, 80 HTTP, 443 HTTPS. diff --git a/README.md b/README.md index 2e0f43c..14e9396 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ - `lessons/` — уроки по дням: теория по-русски, рабочие примеры кода с разбором, готовые ответы на вопросы собеседования, ссылки на первопартийные материалы. Начинать с них. - `PLAN.md` — полный трек M1–M10 на пост-офферный период (модули, артефакты, материалы). +- `HR_BASE.md` — база вопрос-ответ под тех-скрининг (ООП, C/C++, STL, Linux, сети, Git, + Docker, GDB, bash, embedded, вопросы HR) + шпаргалка чисел. - `TRACKER.md` — дневник: что решено, где встал, сколько минут. Это вход для калибровки. - `diag/` — пакет: - `quiz.py` + `quiz.json` — 32 вопроса по 4 доменам; diff --git a/diag/facts.json b/diag/facts.json index 96be7df..b965d08 100644 --- a/diag/facts.json +++ b/diag/facts.json @@ -1,5 +1,5 @@ { - "version": 2, + "version": 3, "note": "Уровни: base — база (начинать отсюда), core — то, что спросят, deep — нишевое. Поле ref — куда смотреть, why — пояснение.", "facts": [ { @@ -1265,6 +1265,578 @@ "level": "base", "ref": "", "why": "С -Werror предупреждения становятся ошибками — полезная привычка." + }, + { + "domain": "algo", + "q": "Сложность доступа к элементу по индексу в массиве (vector)?", + "a": "O(1)", + "accept": [ + "o(1)" + ], + "level": "base", + "ref": "", + "why": "Массив лежит подряд: адрес считается арифметикой, без перебора." + }, + { + "domain": "algo", + "q": "Сложность вставки в конец vector (push_back)?", + "a": "амортизированное O(1)", + "accept": [ + "o(1)", + "амортизированное o(1)", + "амортизированно o(1)" + ], + "level": "base", + "ref": "", + "why": "Обычно O(1); при переполнении массив копируется за O(n), но редко — в среднем O(1)." + }, + { + "domain": "algo", + "q": "Сложность вставки или удаления в середине vector?", + "a": "O(n)", + "accept": [ + "o(n)" + ], + "level": "base", + "ref": "", + "why": "Надо сдвинуть все элементы после места вставки." + }, + { + "domain": "algo", + "q": "Сложность поиска в неотсортированном массиве и в отсортированном?", + "a": "O(n) и O(log n)", + "accept": [ + "o(n) и o(log n)", + "o(n) против o(log n)", + "o(n), o(log n)" + ], + "level": "base", + "ref": "", + "why": "Отсортированность — то, за что платят O(n log n) при сортировке и получают O(log n) поиска." + }, + { + "domain": "algo", + "q": "Сложность доступа к элементу связного списка по номеру?", + "a": "O(n)", + "accept": [ + "o(n)" + ], + "level": "base", + "ref": "", + "why": "К узлам нет произвольного доступа — только идти по указателям от начала." + }, + { + "domain": "algo", + "q": "Сложность вставки и удаления в связном списке, если узел уже известен?", + "a": "O(1)", + "accept": [ + "o(1)" + ], + "level": "base", + "ref": "", + "why": "Меняются два указателя, сдвигать ничего не надо — в этом плюс списка." + }, + { + "domain": "algo", + "q": "Сложность поиска в бинарном дереве поиска (BST)?", + "a": "O(log n) в среднем, O(n) в худшем", + "accept": [ + "o(log n) в среднем o(n) в худшем", + "o(log n), o(n)", + "o(log n) в среднем" + ], + "level": "base", + "ref": "", + "why": "Худший случай — вырожденное дерево в список; лечится балансировкой (AVL, красно-чёрное)." + }, + { + "domain": "algo", + "q": "Что быстрее по памяти: vector или list?", + "a": "vector (нет указателей и отдельных аллокаций)", + "accept": [ + "vector", + "вектор" + ], + "level": "base", + "ref": "", + "why": "У list на каждый узел ещё два указателя и аллокация; зато вставка в середину дешевле." + }, + { + "domain": "algo", + "q": "Сложность поиска, вставки и удаления в std::map?", + "a": "O(log n)", + "accept": [ + "o(log n)" + ], + "level": "base", + "ref": "", + "why": "Красно-чёрное дерево: операции логарифмические и порядок ключей сохраняется." + }, + { + "domain": "algo", + "q": "Сложность тех же операций в std::unordered_map?", + "a": "O(1) в среднем, O(n) в худшем", + "accept": [ + "o(1) в среднем", + "o(1) в среднем o(n) в худшем" + ], + "level": "base", + "ref": "", + "why": "Хеш-таблица: порядок не сохраняется, зато быстрее в среднем." + }, + { + "domain": "algo", + "q": "Сложность поиска в std::set и std::unordered_set?", + "a": "O(log n) и O(1) в среднем", + "accept": [ + "o(log n) и o(1)", + "o(log n), o(1) в среднем" + ], + "level": "base", + "ref": "", + "why": "set — дерево, unordered_set — хеш-таблица." + }, + { + "domain": "algo", + "q": "Что такое in-place сортировка и пример?", + "a": "сортировка без дополнительной памяти O(1), например heapsort", + "accept": [ + "без дополнительной памяти", + "сортировка на месте" + ], + "level": "base", + "ref": "", + "why": "quicksort тоже in-place, но у него O(log n) на стек рекурсии." + }, + { + "domain": "algo", + "q": "Какие операции у стека и очереди и их сложность?", + "a": "push/pop за O(1), доступ только к одному концу", + "accept": [ + "push pop o(1)", + "o(1) на push и pop" + ], + "level": "base", + "ref": "", + "why": "Стек — LIFO, очередь — FIFO; произвольного доступа нет." + }, + { + "domain": "algo", + "q": "Сложность доступа к элементу std::deque по индексу?", + "a": "O(1)", + "accept": [ + "o(1)" + ], + "level": "base", + "ref": "", + "why": "deque — массив блоков фиксированного размера, индекс считается арифметикой." + }, + { + "domain": "algo", + "q": "Что такое структура данных?", + "a": "способ организации данных, определяющий доступ и сложность операций", + "accept": [ + "способ организации данных", + "организация данных для эффективного доступа" + ], + "level": "base", + "ref": "", + "why": "Массив, список, хеш-таблица, дерево, куча — разные компромиссы время/память." + }, + { + "domain": "algo", + "q": "Что такое алгоритм?", + "a": "конечная последовательность шагов, превращающая вход в выход", + "accept": [ + "последовательность шагов", + "конечная последовательность действий" + ], + "level": "base", + "ref": "", + "why": "Оценивается по времени и памяти, чаще всего через O-нотацию." + }, + { + "domain": "algo", + "q": "Что такое рекурсия и её цена?", + "a": "функция вызывает себя; цена — стек вызовов O(глубины)", + "accept": [ + "функция вызывает себя", + "самовызов функции" + ], + "level": "base", + "ref": "", + "why": "Глубина важна: на 10⁵ уровнях стек переполняется, нужна итерация." + }, + { + "domain": "algo", + "q": "Что такое жадный алгоритм?", + "a": "на каждом шаге берём локально лучшее решение", + "accept": [ + "локально лучшее на каждом шаге", + "выбор лучшего на каждом шаге" + ], + "level": "base", + "ref": "", + "why": "Работает не всегда: пример — размен монет; для интервального расписания работает." + }, + { + "domain": "algo", + "q": "Что такое динамическое программирование?", + "a": "разбиение задачи на подзадачи с сохранением результатов", + "accept": [ + "разбиение на подзадачи с запоминанием", + "запоминание результатов подзадач" + ], + "level": "base", + "ref": "", + "why": "Отличие от рекурсии — мемоизация: каждая подзадача считается один раз." + }, + { + "domain": "algo", + "q": "Что такое граф, вершина и ребро?", + "a": "набор вершин и связей между ними", + "accept": [ + "вершины и рёбра", + "набор вершин и связей" + ], + "level": "base", + "ref": "", + "why": "Дерево — это связный граф без циклов на n вершинах с n−1 рёбрами." + }, + { + "domain": "algo", + "q": "Что такое DAG?", + "a": "ориентированный ациклический граф", + "accept": [ + "ориентированный ациклический граф", + "направленный без циклов" + ], + "level": "base", + "ref": "", + "why": "Только на DAG возможна топологическая сортировка — порядок зависимостей." + }, + { + "domain": "algo", + "q": "Что такое связный компонент графа?", + "a": "максимальный набор вершин, достижимых друг из друга", + "accept": [ + "набор вершин достижимых друг из друга", + "максимальная связная часть графа" + ], + "level": "base", + "ref": "", + "why": "Число компонент ищется обходом BFS/DFS или union-find." + }, + { + "domain": "linux", + "q": "Что такое поток (thread) и чем отличается от процесса?", + "a": "единица выполнения внутри процесса; общая память, свой стек", + "accept": [ + "единица выполнения внутри процесса", + "общая память но свой стек" + ], + "level": "base", + "ref": "", + "why": "Потоки дешевле по переключению, но требуют синхронизации общей памяти." + }, + { + "domain": "linux", + "q": "Что такое виртуальная память?", + "a": "каждому процессу — своё адресное пространство, страницы отображаются на физическую память", + "accept": [ + "своё адресное пространство", + "адреса процессов транслируются в физические" + ], + "level": "base", + "ref": "", + "why": "Изоляция процессов и возможность swap — следствие виртуальной памяти." + }, + { + "domain": "linux", + "q": "Что такое страница памяти?", + "a": "блок памяти фиксированного размера (обычно 4 КБ)", + "accept": [ + "блок фиксированного размера", + "4 кб" + ], + "level": "base", + "ref": "", + "why": "Страницами оперируют ядро, mmap, copy-on-write и swap." + }, + { + "domain": "linux", + "q": "Что такое планировщик и контекст-свитч?", + "a": "компонент ядра, решающий кто исполняется; переключение потоков", + "accept": [ + "переключение между задачами", + "ядро выбирает кому исполняться" + ], + "level": "base", + "ref": "", + "why": "Свитч — дорого: сохранить регистры и стек, поэтому меньше потоков ≠ хуже." + }, + { + "domain": "linux", + "q": "Что такое мьютекс и что такое гонка данных?", + "a": "мьютекс — блокировка на одного владельца; гонка — несинхронизированный доступ", + "accept": [ + "блокировка и несинхронизированный доступ", + "мьютекс блокировка, гонка одновременный доступ" + ], + "level": "base", + "ref": "", + "why": "Гонки ловит ThreadSanitizer, взаимные блокировки — анализ порядка захвата." + }, + { + "domain": "linux", + "q": "Что такое дедлок?", + "a": "взаимная блокировка: потоки ждут ресурсы друг друга", + "accept": [ + "взаимная блокировка", + "потоки ждут друг друга вечно" + ], + "level": "base", + "ref": "", + "why": "Четыре условия Коффмана; профилактика — единый порядок захвата мьютексов." + }, + { + "domain": "linux", + "q": "Что такое семафор?", + "a": "счётчик, разрешающий доступ N потокам", + "accept": [ + "счётчик доступа", + "разрешение N потокам" + ], + "level": "base", + "ref": "", + "why": "Мьютекс — частный случай семафора с единицей." + }, + { + "domain": "net", + "q": "Что такое инкапсуляция в сетях?", + "a": "каждый уровень добавляет свой заголовок к данным верхнего", + "accept": [ + "добавление заголовка уровнем", + "заголовок уровня добавляется к данным" + ], + "level": "base", + "ref": "", + "why": "Поэтому кадр = Ethernet-заголовок + IP + TCP + данные." + }, + { + "domain": "net", + "q": "Что такое кадр (frame) и пакет (packet)?", + "a": "кадр — единица L2, пакет — единица L3", + "accept": [ + "кадр l2 пакет l3", + "кадр на канальном пакет на сетевом" + ], + "level": "base", + "ref": "", + "why": "Пакет едет внутри кадра; на каждом узле кадр пересобирается заново." + }, + { + "domain": "net", + "q": "Что такое CIDR-запись /24?", + "a": "24 бита на сеть, 8 на узлы: 256 адресов", + "accept": [ + "24 бита сети", + "256 адресов 24 бита сети" + ], + "level": "base", + "ref": "", + "why": "Чем больше префикс, тем меньше подсеть: /30 — 4 адреса, /26 — 64." + }, + { + "domain": "net", + "q": "Что такое широковещательный адрес?", + "a": "все единицы в хостовой части — адрес всех узлов подсети", + "accept": [ + "все единицы в хостовой части", + "адрес всех узлов подсети" + ], + "level": "base", + "ref": "", + "why": "Поэтому в /24 последний адрес (.255) — broadcast, он не узел." + }, + { + "domain": "net", + "q": "Что такое время жизни (TTL) и зачем он?", + "a": "счётчик переходов в IPv4, уменьшается на каждом маршрутизаторе", + "accept": [ + "счётчик переходов", + "уменьшается на каждом маршрутизаторе" + ], + "level": "base", + "ref": "", + "why": "Защита от вечных петель; traceroute использует истечение TTL." + }, + { + "domain": "c_cpp", + "q": "Что такое объект и класс?", + "a": "класс — описание, объект — экземпляр в памяти", + "accept": [ + "класс описание объект экземпляр", + "класс это описание, объект это экземпляр" + ], + "level": "base", + "ref": "", + "why": "Класс не занимает память, объект занимает." + }, + { + "domain": "c_cpp", + "q": "Три кита ООП?", + "a": "инкапсуляция, наследование, полиморфизм", + "accept": [ + "инкапсуляция наследование полиморфизм" + ], + "level": "base", + "ref": "", + "why": "Инкапсуляция — скрыть состояние, наследование — переиспользовать, полиморфизм — один интерфейс, разные реализации." + }, + { + "domain": "c_cpp", + "q": "Что такое инкапсуляция?", + "a": "сокрытие внутреннего состояния за публичным интерфейсом", + "accept": [ + "сокрытие состояния за интерфейсом", + "скрытие внутреннего состояния" + ], + "level": "base", + "ref": "", + "why": "В C++ — private/protected + методы доступа." + }, + { + "domain": "c_cpp", + "q": "Что такое полиморфизм в C++?", + "a": "вызов функции по фактическому типу объекта через virtual", + "accept": [ + "virtual вызов по фактическому типу", + "вызов по фактическому типу" + ], + "level": "base", + "ref": "", + "why": "Без virtual будет раннее связывание по типу указателя — классическая ловушка." + }, + { + "domain": "c_cpp", + "q": "Что такое абстрактный класс?", + "a": "класс с чисто виртуальной функцией, экземпляр создать нельзя", + "accept": [ + "с чисто виртуальной функцией", + "нельзя создать экземпляр" + ], + "level": "base", + "ref": "", + "why": "В C++ нет отдельного `interface` — его роль играет класс из чисто виртуальных методов." + }, + { + "domain": "c_cpp", + "q": "Чем перегрузка отличается от переопределения?", + "a": "перегрузка — разные параметры в одной области, переопределение — virtual в наследнике", + "accept": [ + "перегрузка параметры, переопределение virtual", + "разные параметры против virtual" + ], + "level": "base", + "ref": "", + "why": "Перегрузка решается на компиляции, переопределение — в рантайме." + }, + { + "domain": "c_cpp", + "q": "Что такое static-член класса?", + "a": "общий для всех объектов, живёт вне объекта", + "accept": [ + "общий для всех объектов", + "принадлежит классу а не объекту" + ], + "level": "base", + "ref": "", + "why": "У static-метода нет this, поэтому он не может быть const." + }, + { + "domain": "c_cpp", + "q": "Что такое шаблон и зачем он?", + "a": "обобщённый код, тип подставляется при компиляции", + "accept": [ + "обобщённый код", + "код обобщённый по типу" + ], + "level": "base", + "ref": "", + "why": "Так устроены контейнеры STL: код один, тип разный, цена — ошибки на компиляции." + }, + { + "domain": "c_cpp", + "q": "Что такое виртуальная таблица (vtable)?", + "a": "таблица указателей на виртуальные функции объекта", + "accept": [ + "таблица указателей на виртуальные функции", + "таблица виртуальных методов" + ], + "level": "base", + "ref": "", + "why": "Отсюда +8 байт на объект и невозможность virtual в конструкторе." + }, + { + "domain": "c_cpp", + "q": "Что такое header guard / #pragma once?", + "a": "защита от повторного включения заголовка", + "accept": [ + "защита от повторного включения", + "защита от двойного включения" + ], + "level": "base", + "ref": "", + "why": "Без неё повторное определение типа — ошибка компиляции." + }, + { + "domain": "c_cpp", + "q": "Что делает линковщик?", + "a": "собирает объектные файлы в один исполняемый, разрешает внешние символы", + "accept": [ + "собирает объектные файлы", + "разрешает внешние символы" + ], + "level": "base", + "ref": "", + "why": "«undefined reference» — ошибка линковщика, а не компилятора." + }, + { + "domain": "c_cpp", + "q": "Что такое std::vector внутри?", + "a": "динамический массив с удвоением ёмкости", + "accept": [ + "динамический массив", + "динамический массив с удвоением" + ], + "level": "base", + "ref": "", + "why": "Отсюда амортизированное O(1) на push_back и invalidate итераторов при росте." + }, + { + "domain": "c_cpp", + "q": "Чем emplace_back лучше push_back?", + "a": "строит объект на месте, без копирования/перемещения", + "accept": [ + "строит на месте", + "конструирует на месте без копии" + ], + "level": "base", + "ref": "", + "why": "Разница видна на тяжёлых объектах и типах без копирования." + }, + { + "domain": "c_cpp", + "q": "Что делает reserve и зачем?", + "a": "резервирует ёмкость, убирая реаллокации", + "accept": [ + "резервирует ёмкость", + "выделяет память заранее" + ], + "level": "base", + "ref": "", + "why": "Когда размер известен, reserve — дешёвая оптимизация." } ] }