Собес в Сбер · IOS-разработчик (Middle)
Материал Эйч · Опубликовано 27 октября 2026
Обзор
Middle iOS в команде Управления развития технологий: Swift/UIKit/SwiftUI, Clean+MVVM, Core Data, concurrency и сильный упор на инженерную культуру, code review и современные практики (в т.ч. ИИ в разработке).
Фишка: Сочетание классического банковского стека (UIKit, Core Data, REST, Gitflow) с акцентом на масштабируемую архитектуру, инструменты сборки (Tuist) и осознанное использование ИИ в разработке с ограничением доступа к репозиторию.
| Этап | Длительность | Что проверяют |
|---|---|---|
| Скрининг / HR | 30–45 мин | Мотивация, опыт 3–5 лет, офис в Москве, Agile/Scrum, готовность к code review и срокам. |
| Техническое интервью | 60–90 мин | Swift (замыкания, коллекции, протоколы), UIKit layout, архитектура модуля, асинхронность, задачи на бумаге/IDE. |
| Углубление / системное | 45–60 мин | Крупные фичи и модули, перфоманс (в т.ч. watchOS), настройка проекта, DI, CI/CD, использование ИИ в команде. |
| Финал с лидом | 30–45 мин | Принятие архитектурных решений, взаимодействие с командой, оценка задач и качество кода. |
Стек и темы
Обязательный минимум
- Swift: value/reference types, optionals, closures, protocols
- UIKit: UIView vs UIViewController, constraints, intrinsic content size
- MVVM + Clean Architecture на практике
- GCD, DispatchQueue; async/await, actors
- Core Data: модель, миграции, производительность
- REST API, сетевой слой, обработка ошибок
- DI (Swinject или аналог), composition root
- Git: ветвление, code review
- Live coding: строки, массивы, map/compactMap/flatMap
Плюсом будет
- SwiftUI в продакшене
- RxSwift: сложные потоки, не только биндинг VM–View
- Tuist / генераторы проектов
- watchOS, перфоманс и энергопотребление
- CI/CD, схемы и targets
- Практики безопасного доступа ИИ-агентов к GitLab
Swift: язык и рантайм
Определите, компилируется ли рекурсивная struct LinkedList с полем nextNode: LinkedList?
Размер struct должен быть конечным; рекурсия без indirect enum → ошибка «value type has infinite size». Нужен indirect enum или class.
Какой вывод у программы с функцией a(), возвращающей замыкание с counter?
Замыкание захватывает var counter; каждый вызов a() — новый counter. first() дважды: 10+20; second() из другого a(): 10 → сумма 40.
Скомпилируется ли сравнение FinancialInstitution.sberbank == "sber"?
Нет: enum не сравнивается со String без rawValue. Нужно .rawValue == "sber" или case .sberbank.
Что выведут print после map / compactMap / flatMap для matrix с nil и вложенными массивами?
map даёт [Optional(2), nil, Optional(2), ...]; compactMap отбрасывает nil верхнего уровня; flatMap разворачивает вложенные элементы — считайте nil внутри массивов отдельно.
NSMutableArray: arr2 = arr1, arr2.add — что в arr1?
NSMutableArray — reference type; обе переменные указывают на один объект, в arr1 тоже появится "1".
Ловушка: Часть задач — не «написать приложение», а предсказать компилятор/вывод: читайте код построчно и проговаривайте capture list и тип коллекции.
Совет: Всегда уточняйте версию Swift и контекст (@MainActor, strict concurrency), если ответ зависит от языка.
Протоколы и dispatch
Какая реализация test() вызовется у класса, conforming A2, C2, B2 с default в extensions?
Без реализации в классе Swift часто не компилирует из‑за ambiguous witness; если спрашивают теорию — самый специфичный протокол в иерархии (C2) или явная реализация в типе.
Что может сломать компиляцию в execute(action:) с DispatchQueue.main.async?
Параметр closure по умолчанию non-escaping; передача в async требует @escaping у action.
Фишка: Сбер любит «лестницы» протоколов и extension default implementation — готовьте объяснение witness table и зачем в проде пишут явную реализацию.
UIKit и Auto Layout
Чем UIViewController отличается от UIView и обязателен ли контроллер?
UIView — отрисовка и layout; VC — lifecycle, иерархия, координация. Приложение может жить на SwiftUI WindowGroup / UIHostingController без классического VC-дерева.
Почему UIImageView/UILabel могут корректно отображаться с двумя constraints?
Intrinsic content size + приоритеты constraints; система может разрешить underconstrained layout, если хватает intrinsic размеров по одной оси.
Почему многострочный UILabel при ограничении ширины растёт вниз?
Preferred max layout width / numberOfLines; intrinsic height пересчитывается после известной ширины — рост по вертикали ожидаем.
Совет: Связывайте ответ с реальным багом: обрезанный текст, conflicting constraints, layout на scroll stack.
Архитектура, DI и модули
Когда писать свой DI, а когда Swinject/аналог?
Малый граф — init injection и factory в одном месте; большой модульный проект — scopes, тестовые сборки, иначе ручное связывание не масштабируется.
Почему предложенная архитектура модуля понравилась команде?
Ответ через критерии: тестируемость, границы слоёв, независимость UI, скорость онбординга, согласованность с Clean/MVVM.
Как в команде организовано архитектурное проектирование?
RFC/ADR, ревью с техлидом, пилот на модуле, критерии «готово» и откат; Middle должен приводить пример своего участия, не только «решал лид».
Расскажите об опыте проектирования и запуска большой задачи или нового модуля.
Структура: цель → декомпозиция → риски → метрики → rollout; упомяните code review и техдолг.
Фишка: Вакансия явно требует Clean Architecture + MVVM — готовьте схему слоёв и поток данных для одной фичи (например, список операций).
Асинхронность и Rx
Насколько глубоко знакомы с Rx? Сложные потоки vs биндинг View–ViewModel?
Операторы merge/flatMapLatest, error/retry, share, schedulers, утечки подписок, тестирование TestScheduler; отличие hot/cold.
GCD vs Swift Concurrency для сетевого слоя?
GCD — очереди и legacy; async/await + actors — структурированная конкуренция, изоляция состояния, @MainActor для UI.
Ловушка: Не сводите Rx к «привязал кнопке» — на Middle ждут сценарий с несколькими источниками и отменой.
Данные, сеть, перфоманс
Опыт Core Data: что оптимизировали?
Batch fetch, prefetch, фоновые контексты, merge policy, индексы, миграции lightweight/heavyweight.
Как искать причину нагрева Apple Watch и скачков CPU?
Instruments (Time Profiler, Energy), частые layout/update на main, таймеры, лишние сетевые вызовы, WatchConnectivity, размер payload.
Как подойти к переносу большого iOS-приложения на Apple Watch?
MVP сценарии, общий домен vs отдельный target, complications, ограничения памяти, синхронизация с phone, поэтапный rollout.
Совет: Банковый контекст: офлайн-кеш, безопасность данных на устройстве, идемпотентность запросов.
Инструменты и ИИ в разработке
Какие инструменты ИИ используете и как подходите к использованию?
Когда ускоряет (boilerplate, тесты, рефакторинг), когда нет (безопасность, контракты API); политика команды.
Как валидируете код и решения, созданные с помощью ИИ?
Review, тесты, статанализ, сравнение с документацией Apple, воспроизводимость, не доверять без проверки.
Что в крупной задаче автоматизировали бы с ИИ?
Генерация моков, документация, миграции шаблонов — с human gate на архитектуру и секреты.
Как агент получает доступ к GitLab и почему не полный доступ?
Токен с минимальными scope, read-only ветки, без secrets; принцип least privilege.
Как обеспечить, чтобы ИИ учёл контекст прошлой фичи и выявил техдолг?
RAG по репо, чёткий prompt с ADR/тикетами, ограниченный контекст, чеклист ревью.
Подключались ли к настройке проектов: зависимости, target/scheme, CI/CD?
Xcode schemes, configurations, SPM/CocoaPods, pipeline lint/test/archive, сертификаты.
Использовали Tuist? Настраивали сами?
ProjectDescription, модули, кэш, единые настройки warnings/Swift version.
Фишка: Блок про ИИ — не маркетинг: покажите зрелость (валидация, безопасность, границы автоматизации).
Задачи
Первый неповторяющийся элемент массива
Напишите функцию, которая возвращает первый элемент массива, встречающийся ровно один раз (или nil, если такого нет).
func firstUnique<T: Hashable>(_ a: [T]) -> T? {
var counts: [T: Int] = [:]
for x in a { counts[x, default: 0] += 1 }
for x in a where counts[x] == 1 { return x }
return nil
}Сложность: O(n) по времени, O(n) по памяти
Модификация: самый частый элемент
Как изменить решение, чтобы вернуть элемент, встречающийся чаще всего? При равенстве частот — любой из лидеров или первый по появлению (уточнить у интервьюера).
Подсчёт в словаре, затем max по counts; для «первого лидера» — один проход с отслеживанием best при обновлении max.
Сложность: O(n)
Скрытие символов кроме последних четырёх
Строка → новая строка, все символы кроме последних четырёх заменены на '#'.
func mask(_ s: String) -> String {
let n = s.count
guard n > 4 else { return String(repeating: "#", count: n) }
return String(repeating: "#", count: n - 4) + s.suffix(4)
}Сложность: O(n)
Результат вывода: NSMutableArray
var arr1 = NSMutableArray(array: ["0"]); var arr2 = arr1; arr2.add("1"); print(arr1, arr2)
Обе печатают ("0", "1") — общая ссылка на один mutable массив.Сложность: —
System Design
- Спроектируйте модуль «история операций» в банковском приложении: offline-first, Core Data, синхронизация с REST
- Как разделить монолитное iOS-приложение на feature-модули с DI и общим networking layer?
- Дизайн экрана с тяжёлым списком и пагинацией: UIKit vs SwiftUI, кэш изображений, отмена запросов
Каркас ответа
- Уточнить сценарии, NFR (безопасность, офлайн, доступность)
- Нарисовать слои Clean: Domain / Data / Presentation
- Описать модели данных, API контракты, кэш и политику обновления
- Потоки: main vs background, ошибки и retry
- Тестируемость: протоколы репозиториев, моки
- Риски: миграции БД, race conditions, размер приложения
Поведенческое
- Расскажите о крупной фиче или модуле, который вы довели до продакшена
- Пример конфликта в code review и как договорились
- Как оцениваете задачи и что делаете, если сроки горят
- Опыт работы в Agile/Scrum: роль на стендапе и ретро
- Как поддерживаете качество кода в команде
План подготовки
3 дня
- Пройти все задачи «что выведет / скомпилируется» из блока Swift
- Повторить MVVM+Clean на одном примере фичи из вакансии
- Подготовить 2 истории: большой модуль и code review
- Прогнать live coding: first unique + mask string
7 дней
- Core Data: миграции, фоновые контексты, типичные баги
- Swift Concurrency: actors, @MainActor, отмена Task
- Rx: один сложный pipeline словами
- DI: сравнить ручной composition root и Swinject
- ИИ: ответы на валидацию и доступ к GitLab
14 дней
- Системный кейс: offline-first список с REST
- UIKit layout: intrinsic size, priority, scroll + stack
- Tuist/CI: что настраивали лично
- watchOS/перфоманс: Instruments и чеклист
- Мок-собес с таймером 90 мин
| Блок | Готов, если... |
|---|---|
| Swift | объясняете escaping, capture, разницу struct/class и NSArray |
| UIKit | можете разобрать layout label с двумя constraints |
| Архитектура | рисуете Clean+MVVM для одной фичи за 3 минуты |
| Concurrency | сравниваете GCD и async/await на примере сети |
| ИИ | даёте чёткий процесс валидации и least privilege для репо |
| Live coding | пишете first unique и mask без подсказок за 15 мин |
В день собеседования
- Повторить шпаргалки по map/compactMap и escaping closures
- Проверить примеры архитектуры и ИИ-политику
- Подготовить вопросы команде про стек, review, релизный цикл