Вопросы на собеседовании: Rust
Курс-тренажёр для подготовки к собеседованию по Rust. Каждый урок — это один-три вопроса, которые реально задают на интервью: сначала сам вопрос, затем что за ним проверяет интервьюер, развёрнутый разбор с кодом (в том числе кодом, который не компилируется, и текстом ошибки rustc), типичные промахи кандидатов и выжимка «как ответить кратко» на 20–30 секунд. Прогрессия — от базового ownership до Send/Sync, async и unsafe.
Курс «Вопросы на собеседовании: Rust» состоит из 5 разделов и 15 уроков: Владение и заимствование, Времена жизни и типы, Трейты и абстракции, Обработка ошибок и умные указатели и Конкурентность и продвинутые темы. Уроки идут по порядку — от основ к более сложным темам, в каждом есть объяснение с примерами, а в конце — вопросы для самопроверки. К урокам привязаны задачи с автоматической проверкой: прочитали тему — сразу закрепили её кодом.
Программа курса
1 Владение и заимствование
- Что такое ownership и зачем он нужен
Что отвечать на вопрос про ownership в Rust: три правила владения, стек и куча, RAII и Drop, сравнение с ручным free в C и со сборщиком мусора.
- Move-семантика и трейт Copy
Что будет после let s2 = s1 для String, чем Copy отличается от Clone, почему i32 копируется, а String перемещается, и как читать ошибку E0382.
- Правила заимствования и почему нельзя две &mut
Правила заимствования в Rust: одна изменяемая ссылка или много общих, ошибки E0499 и E0502, инвалидация итератора при push и что такое non-lexical lifetimes.
- Что такое ownership и зачем он нужен
2 Времена жизни и типы
- Лайфтаймы простыми словами и элизия
Что такое lifetime в Rust, зачем нужны аннотации 'a, откуда берётся ошибка E0106 и почему в большинстве функций лайфтаймы можно не писать.
- String против &str и срезы
Чем String отличается от &str, что принимать в параметрах функции, как устроены срезы и почему индексация строки числом не компилируется.
- Структуры, перечисления и pattern matching
Чем enum в Rust отличается от enum в C и Java, зачем нужен исчерпывающий match и ошибка E0004, а также guard, связывание @, if let и let else.
- Лайфтаймы простыми словами и элизия
3 Трейты и абстракции
- Трейты и чем они отличаются от интерфейсов
Что такое trait в Rust, чем он отличается от интерфейсов Java и Go, как реализовать свой trait для чужого типа и почему существует orphan rule (E0117).
- Статическая и динамическая диспетчеризация
Разница между impl Trait и dyn Trait в Rust: мономорфизация, vtable и fat pointer, почему нужен Box<dyn Trait>, ошибки E0277 и E0038, что такое object safety.
- Дженерики, стандартные трейты и ленивые итераторы
Trait bound и where в Rust, ошибка E0277, разница Clone и Copy, Debug и Display, blanket impl для Into, TryFrom и ленивость итераторов с collect и turbofish.
- Трейты и чем они отличаются от интерфейсов
4 Обработка ошибок и умные указатели
- Option и Result вместо исключений
Почему в Rust нет исключений, чем Option отличается от Result, что не так с unwrap и expect — разбор частых вопросов собеседования по Rust.
- Оператор ? и когда panic уместен
Во что разворачивается оператор ?, как он преобразует ошибки через From, когда panic оправдан, а когда нужен Result — ответы на вопросы собеседования.
- Box, Rc, RefCell и внутренняя изменяемость
Зачем нужен Box, что такое Rc и счётчик ссылок, чем RefCell отличается от обычной изменяемой ссылки и как устроена interior mutability в Rust.
- Option и Result вместо исключений
5 Конкурентность и продвинутые темы
- Потоки, передача владения, Send и Sync
Собеседование по Rust: fearless concurrency, thread::spawn и join, зачем move в замыкании потока, ошибка E0373 и трейты Send и Sync с примерами.
- Каналы, Arc и Mutex
Как безопасно делить данные между потоками в Rust: каналы mpsc, Arc против Rc, Mutex, который владеет данными, poisoning, MutexGuard, RwLock и deadlock.
- async в Rust и зачем нужен unsafe
Senior-вопросы по Rust: чем async отличается от потоков, почему рантайма нет в std, ленивость Future и забытый await, пять суперспособностей unsafe и UB.
- Потоки, передача владения, Send и Sync