Материал Эйч · Опубликовано 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 мин | Принятие архитектурных решений, взаимодействие с командой, оценка задач и качество кода. |
Обязательный минимум
Плюсом будет
Определите, компилируется ли рекурсивная 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), если ответ зависит от языка.
Какая реализация 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 и зачем в проде пишут явную реализацию.
Чем 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, а когда Swinject/аналог?
Малый граф — init injection и factory в одном месте; большой модульный проект — scopes, тестовые сборки, иначе ручное связывание не масштабируется.
Почему предложенная архитектура модуля понравилась команде?
Ответ через критерии: тестируемость, границы слоёв, независимость UI, скорость онбординга, согласованность с Clean/MVVM.
Как в команде организовано архитектурное проектирование?
RFC/ADR, ревью с техлидом, пилот на модуле, критерии «готово» и откат; Middle должен приводить пример своего участия, не только «решал лид».
Расскажите об опыте проектирования и запуска большой задачи или нового модуля.
Структура: цель → декомпозиция → риски → метрики → rollout; упомяните code review и техдолг.
Фишка: Вакансия явно требует Clean Architecture + MVVM — готовьте схему слоёв и поток данных для одной фичи (например, список операций).
Насколько глубоко знакомы с 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 массив.Сложность: —
Каркас ответа
3 дня
7 дней
14 дней
| Блок | Готов, если... |
|---|---|
| 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 мин |
В день собеседования
Компания