Вопросы на собеседовании: Мобильный разработчик
100 реальных вопросов с образцовыми ответами и пояснениями для уровня Junior.
Смотреть пример резюме: Мобильный разработчик →Тренировка флешкарточками
Интервальное повторение · Hunter Pass
Вопросы
iOS и Android дают приложениям похожие возможности, но используют разные SDK, инструменты и платформенные соглашения.
- Для iOS обычно используют Swift, Xcode и фреймворки Apple, например UIKit или SwiftUI.
- Для Android обычно используют Kotlin, Android Studio и библиотеки AndroidX, например Jetpack Compose.
- У каждой платформы свои правила навигации, разрешений, фоновой работы и проверки в магазине, поэтому даже общий дизайн требует отдельных решений.
Зачем это спрашивают: Интервьюер проверяет, понимает ли кандидат различия мобильных платформ глубже, чем на уровне названий языков.
Жизненный цикл приложения описывает платформенные изменения видимости, интерактивности, фонового состояния и завершения приложения или его компонента.
- Приложение должно запускать работу, связанную с интерфейсом, когда экран активен, и приостанавливать камеру при уходе в фон.
- Операционная система может завершить фоновый процесс ради освобождения памяти, поэтому важное состояние нельзя хранить только в RAM.
- iOS сообщает фазы приложения и сцен, а Android предоставляет колбэки жизненного цикла Activity и других компонентов, поэтому общей state machine у платформ нет.
- Колбэки жизненного цикла не гарантируют, что перед завершением процесса обязательно вызовется каждый метод очистки.
Зачем это спрашивают: Сильный ответ связывает состояния жизненного цикла с ресурсами и восстановлением, а не только перечисляет колбэки.
Я бы выбрал нативную разработку, если интеграция с платформой и её особое поведение важнее общего кода интерфейса.
- Swift и Kotlin дают прямой доступ к новым API iOS и Android без ожидания кроссплатформенной обёртки.
- React Native или Flutter позволяют разделить между платформами значительную часть продуктовой логики и UI, что помогает небольшой команде выпустить оба приложения.
- Кроссплатформенному коду всё равно нужна нативная часть для неподдерживаемых SDK, виджетов, фоновых режимов и необычных аппаратных функций.
- Выбор зависит от навыков команды, нужных API устройства и требуемого соответствия правилам каждой платформы.
Зачем это спрашивают: Интервьюер ждёт взвешенный выбор по конкретным ограничениям, а не приверженность одному фреймворку.
Junior iOS-разработчик должен уверенно работать с константами, опциональными значениями, функциями, коллекциями, структурами и классами Swift.
- Используйте let для неизменяемой привязки, а var только когда значение действительно должно меняться.
- Обрабатывайте optional через if let, guard let, optional chaining или значение по умолчанию вместо принудительного извлечения.
- Выбирайте struct для простых моделей-значений, например Profile; class нужен, когда важна общая идентичность экземпляра или наследование.
- Протоколы описывают поведение, которое могут реализовать разные типы без общего суперкласса.
Зачем это спрашивают: Интервьюер оценивает, умеет ли кандидат писать безопасный и идиоматичный код на Swift, а не только узнавать синтаксис.
Kotlin делает Android-код безопаснее и короче благодаря null safety, data class, extension-функциям и корутинам.
- Nullable-тип обозначается знаком ?, а safe call и оператор Elvis позволяют явно обработать отсутствие значения.
- Data class генерирует методы equals, hashCode, copy и понятный toString для работы с данными.
- Extension-функции добавляют удобные операции существующему типу без его изменения или наследования.
- Корутины позволяют последовательно описывать асинхронную работу, а структурированные coroutine scopes управляют её жизненным циклом.
Зачем это спрашивают: Интервьюер проверяет знание возможностей Kotlin, которые ежедневно используются в Android-проектах.
Dart поддерживает строгую null safety, изменяемые переменные и неизменяемые привязки.
- Переменной final присваивается значение один раз во время выполнения, а const создаёт константу времени компиляции.
- Тип с ? может содержать null, а обычный String не может.
- Именованные параметры делают конструкторы виджетов читаемыми, а required отмечает обязательный именованный аргумент.
- Функция с async возвращает Future, а await получает будущий результат без блокировки UI-потока.
Зачем это спрашивают: Сильный ответ охватывает возможности Dart, которые сразу встречаются в реальных Flutter-виджетах и загрузке данных.
TypeScript находит многие ошибки в структуре данных и работе с null до запуска React Native-приложения.
- Интерфейсы и псевдонимы типов могут описывать ответы API, свойства компонентов и параметры навигации.
- Union-типы моделируют состояния загрузки, успеха и ошибки безопаснее, чем набор несвязанных булевых флагов.
- Сужение типа проверяет значение перед обращением к свойствам, доступным только одному варианту union.
- Типы TypeScript исчезают во время выполнения, поэтому внешний JSON всё равно нужно проверять.
Зачем это спрашивают: Интервьюер проверяет, понимает ли кандидат преимущества TypeScript и границу его гарантий во время выполнения.
Nullable-значения нужно обозначать явно и проверять перед обычным использованием; конкретный синтаксис зависит от выбранного стека.
- Swift использует optional-типы вроде String? и требует извлечь значение перед обычным использованием.
- Kotlin и Dart тоже отмечают nullable-типы знаком ?, а safe call и явные проверки сужают их до non-null.
- TypeScript проверяет null только при включённом strictNullChecks, и эти проверки не валидируют JSON во время выполнения.
- Операторы Swift !, Kotlin !! и Dart ! обходят защиту, поэтому подходят только для заранее доказанных инвариантов.
Зачем это спрашивают: Интервьюер проверяет, умеет ли кандидат предотвращать распространённый класс падений в разных мобильных стеках.
Значение копируется как независимые данные, а ссылка позволяет нескольким переменным указывать на один объект.
- Структуры Swift имеют семантику значения, поэтому изменение копии Settings не меняет оригинал.
- Классы Swift, экземпляры классов Kotlin и объекты Dart имеют ссылочную идентичность, поэтому мутация видна через все ссылки.
- Data class в Kotlin предоставляет удобный copy, но его экземпляры остаются ссылками, а вложенные изменяемые объекты могут быть общими.
- Неизменяемые модели в стиле значений упрощают состояние UI, потому что обновление заменяет данные, а не скрытно меняет их.
Зачем это спрашивают: Сильный ответ объясняет наблюдаемый эффект для состояния, а не только воспроизводит термины о памяти.
Асинхронная работа не даёт сетевым и дисковым операциям заморозить главный UI-поток.
- Swift async и await, корутины Kotlin и Future в Dart приостанавливают задачу на время ожидания вместо блокировки интерфейса.
- В React Native асинхронные результаты обычно представлены Promise и обрабатываются через async и await.
- UI нужно обновлять в главном контексте платформы, даже если данные загружались в другом месте.
- Ошибки и отмену надо обрабатывать явно, потому что экран может закрыться до завершения операции.
Зачем это спрашивают: Интервьюер оценивает, связывает ли кандидат асинхронный синтаксис с отзывчивостью и безопасностью жизненного цикла.
Экран на UIKit обычно состоит из UIViewController и иерархии объектов UIView.
- UILabel, UIButton и UITableView создаются в коде или подключаются из storyboard.
- Auto Layout constraints задают положение и размеры относительно guides, соседних элементов или родительского view.
- Контроллер обрабатывает события жизненного цикла и действия пользователя, а затем императивно обновляет view.
- Данные и бизнес-правила лучше держать вне view controller, чтобы он не превратился в огромный универсальный класс.
Зачем это спрашивают: Интервьюер проверяет понимание основных объектов UIKit и его императивной модели обновления.
SwiftUI описывает view как функцию текущего состояния и пересчитывает body при изменении наблюдаемого состояния.
- VStack, HStack и ZStack располагают дочерние view вертикально, горизонтально или слоями.
- Простое состояние, принадлежащее view, можно хранить в @State, а общие данные модели должны приходить из наблюдаемого источника.
- Модификаторы возвращают новые описания view, поэтому их порядок может менять компоновку и внешний вид.
- Body может вычисляться много раз, поэтому он должен описывать UI, а не запускать неконтролируемые побочные эффекты.
Зачем это спрашивают: Сильный ответ отличает декларативный рендеринг от ручного изменения элементов UIKit.
Compose повторно вызывает composable-функции, которые прочитали изменившееся состояние.
- remember сохраняет значение между recomposition, а rememberSaveable умеет также восстанавливать поддерживаемые значения после пересоздания Activity.
- Mutable state нужно менять через его holder, чтобы Compose заметил обновление.
- Compose может пропустить неизменившиеся composable, если их входные данные остались стабильными.
- Дорогие вычисления стоит вынести из часто выполняемого кода или мемоизировать по используемым входным данным.
Зачем это спрашивают: Интервьюер проверяет понимание состояния Compose и того, что recomposition не равен полной перерисовке экрана.
React Native рендерит платформенные view из React-компонентов, а не обычный HTML в браузере.
- View, Text и Pressable соответствуют нативным примитивам интерфейса, а не элементам div, span и button.
- Компоновка использует Flexbox-модель Yoga с отличающимися от браузерного CSS значениями по умолчанию, например вертикальной главной осью.
- TypeScript или JavaScript отвечает за React-логику, а native modules открывают API устройства, которых нет в самом фреймворке.
- WebView служит отдельным компонентом для веб-контента и не участвует в обычном рендеринге React Native-экрана.
Зачем это спрашивают: Интервьюер хочет убедиться, что кандидат не путает React Native с сайтом, завёрнутым в приложение.
Widget во Flutter представляет собой неизменяемое описание части пользовательского интерфейса.
- У StatelessWidget нет собственного изменяемого объекта State, но он может зависеть от inherited context, например Theme или MediaQuery.
- Widgets образуют дерево конфигурации, из которого Flutter создаёт структуры элементов и render objects для обновления и layout.
- Для композиции часто используются Row, Column, Stack, Padding и ListView.
- Небольшие widgets с явными параметрами конструктора упрощают понимание rebuild и повторное использование.
Зачем это спрашивают: Интервьюер проверяет понимание того, что widget является описанием, а не изменяемым объектом экрана.
Декларативный UI описывает, как интерфейс должен выглядеть при текущем состоянии, вместо последовательности ручных изменений view.
- В состоянии загрузки описание возвращает индикатор, а после успешной загрузки возвращает контент, поэтому видимую ветку определяет модель состояния.
- Фреймворк сравнивает или повторно вычисляет описания и применяет нужные изменения к отрисованному интерфейсу.
- У состояния должен быть понятный владелец, иначе несколько копий одного значения превращаются в конфликтующие источники истины.
- Код рендеринга не должен содержать неконтролируемых побочных эффектов, потому что он может выполняться многократно.
Зачем это спрашивают: Сильный ответ выделяет общую модель, но не утверждает, что внутреннее устройство четырёх фреймворков одинаково.
Мобильная компоновка задаёт связи и гибкое пространство вместо фиксированных координат в пикселях.
- UIKit использует Auto Layout constraints, а SwiftUI и Compose строят компоновку из стеков, размеров и гибких модификаторов.
- React Native использует Flexbox, а во Flutter constraints идут вниз по дереву, после чего размеры передаются вверх.
- Фиксированный размер подходит иконкам, но области контента должны расширяться, переноситься или прокручиваться.
- Проверяйте узкие и большие телефоны, landscape и увеличенный текст, потому что одной ширины экрана недостаточно для всех ограничений.
Зачем это спрашивают: Интервьюер оценивает, умеет ли кандидат строить адаптивный layout, а не подгонять один скриншот.
Логические единицы сохраняют похожий воспринимаемый размер элементов на экранах с разной плотностью пикселей.
- iOS строит layout в points, Android использует dp для геометрии и sp для текста, а Flutter использует логические пиксели.
- Операционная система переводит эти единицы в подходящее конкретному устройству число физических пикселей.
- Изображению могут понадобиться варианты для разных плотностей, чтобы оно оставалось чётким при неизменном размере в layout.
- Текст должен учитывать выбранный пользователем масштаб шрифта, а не помещаться в фиксированную физическую высоту.
Зачем это спрашивают: Интервьюер проверяет понимание независимости от плотности и масштабирования текста для доступности.
Safe areas и insets описывают области экрана, перекрытые системным UI или аппаратными элементами устройства.
- Status bar, вырез камеры, navigation bar и home indicator могут перекрывать контент, нарисованный от края до края.
- iOS предоставляет safe-area guides, а Android предоставляет window insets для системных панелей и вырезов экрана.
- Flutter SafeArea и аналогичные API фреймворков добавляют нужные отступы вокруг важного контента.
- Фон может заходить под системный UI, но элементы управления и важный текст должны оставаться доступными и видимыми.
Зачем это спрашивают: Сильный ответ показывает, как поддержать современные экраны от края до края без слепого отступа для всего интерфейса.
Состояние должно находиться у ближайшего общего владельца, который координирует всех читателей и авторов изменений.
- Временное состояние элемента, например открыто ли меню, храните внутри компонента-владельца этого меню.
- Общее состояние формы или выбора поднимайте в родителя или модель экрана, а вниз передавайте значения и события.
- Фильтрованное количество вычисляйте из исходного состояния, а не храните второй экземпляр, который может устареть.
- Recomposition или rebuild после изменения состояния нормальны, поэтому обычный рендеринг не должен напрямую запускать дорогой I/O.
Зачем это спрашивают: Интервьюер проверяет, умеет ли кандидат избегать дублирования состояния и случайной работы во время рендеринга.
Закрытые вопросы
- 21
Как работают стеки навигации в мобильном приложении?
navigation - 22
Что должно произойти при открытии мобильного приложения по внешнему маршруту?
- 23
Зачем экрану или компоненту собственный жизненный цикл?
componentslifecycle - 24
Что такое configuration change в Android и почему он может пересоздать Activity?
android-componentslifecycleconfig - 25
Что делает мобильный интерфейс доступным?
types - 26
Как приложению обрабатывать нажатия, свайпы и более сложные touch-жесты?
interaction - 27
Как сохранить форму удобной при появлении экранной клавиатуры?
forms - 28
Как организовать валидацию мобильной формы?
formsvalidationswift - 29
Почему длинному мобильному списку нужен виртуализированный компонент?
componentsvirtualization - 30
Зачем элементам декларативного списка нужны стабильные keys?
- 31
Что происходит при выполнении HTTP-запроса мобильным приложением?
http - 32
Что делает HTTP API RESTful с точки зрения мобильного клиента?
resthttpui - 33
На что мобильному разработчику обратить внимание при декодировании JSON?
- 34
Какие коды HTTP-статуса должен знать junior mobile-разработчик?
httpstatus-codes - 35
Как мобильный экран должен показывать ошибки API?
api - 36
Как загрузить данные API без зависания мобильного экрана?
api - 37
Почему сетевой запрос нужно уметь отменять при закрытии экрана?
- 38
Как мобильному приложению загружать и кешировать удалённые изображения?
caching - 39
Когда приложению использовать preferences, а когда обычные файлы?
- 40
Когда мобильному приложению использовать SQLite, Keychain или Android Keystore?
secure-storage - 41
Как мобильному приложению запрашивать runtime permission?
permissions - 42
Из каких шагов состоит добавление простой съёмки с камеры?
- 43
Что junior-разработчик должен учитывать при добавлении геолокации?
- 44
Как push-уведомления доходят до мобильного приложения?
android-components - 45
Чем deep link с custom scheme отличается от подтверждённой веб-ссылки?
navigation - 46
Как выглядит пирамида тестирования мобильного приложения?
testing - 47
Как использовать debugger для поиска неверного значения на мобильном экране?
debugging - 48
Для чего в мобильной разработке нужны build variants или configurations?
config - 49
Как работают signing и beta distribution для приложений iOS и Android?
distributions - 50
Какой Git workflow должен знать junior mobile-разработчик?
git - 51
Пользователь нажимает Сохранить, данные в памяти меняются, но экран по-прежнему показывает старое значение. Что вы проверите первым?
memory - 52
React Native-экран после каждого рендера снова добавляет AppState listener, и одно изменение состояния вызывает несколько колбэков. Как это исправить?
reactcallbacks - 53
После удаления строки из списка следующая строка показывает состояние переключателя удалённой строки. Какова вероятная причина и как это исправить?
- 54
Экран профиля падает только у пользователей без URL аватара. Как вы найдёте и исправите проблему?
- 55
На Android форма очищается при повороте телефона, хотя пользователь её ещё не отправил. Что вы измените?
forms - 56
Черновик заказа исчезает после того, как приложение долго было в фоне и операционная система завершила его процесс. Как это исправить?
system-design - 57
На экране регистрации клавиатура закрывает последнее поле и кнопку Продолжить. Какое практичное исправление вы сделаете?
- 58
Карточка товара выглядит правильно на большом эмуляторе, но на маленьком телефоне цена перекрывает кнопку. Как это исправить?
- 59
После переключения телефона на тёмную тему нестандартная подпись становится почти невидимой. Что вы измените?
theming - 60
При максимальном системном размере текста строка настроек обрезает заголовок и скрывает переключатель. Как вы это исправите?
system-design - 61
Сетевой запрос иногда навсегда остаётся в состоянии ожидания, и индикатор загрузки не исчезает. Что вы добавите?
- 62
Лента ненадолго показывает сообщение о пустом состоянии до завершения первого запроса. Как исправить состояние UI?
state - 63
API возвращает HTTP 401, но приложение показывает общее сообщение Что-то пошло не так. Что должен сделать клиент?
httpgenerics - 64
Запрос завершается с HTTP 200, но декодирование ломается после того, как бэкенд изменил price с числа на строку. Как вы поступите?
http - 65
Flutter-экран падает с ошибкой "Vertical viewport was given unbounded height" после помещения ListView внутрь Column. Как это исправить?
cssflutterschema - 66
Отправка сообщения не удаётся, когда телефон ненадолго теряет сеть. Как сделать безопасный повтор?
resilience - 67
Некоторые удалённые изображения показываются как пустые блоки, когда их URL не загружаются. Что должен делать компонент изображения?
components - 68
Экран профиля продолжает показывать старое имя после его успешного изменения. Как вы исследуете устаревшие данные в кеше?
caching - 69
При загрузке следующей страницы ленты несколько публикаций появляются дважды. Что вы проверите и исправите?
- 70
Запрос pull-to-refresh и более старый запрос страницы завершаются в обратном порядке, из-за чего обновлённые элементы исчезают. Как исправить эту гонку?
- 71
Настройка уведомлений выглядит сохранённой, но после перезапуска приложения возвращается к значению по умолчанию. Что вы проверите?
android-components - 72
Экран заметок должен показывать только незавершённые заметки, но SQLite-запрос возвращает все строки. Как его исправить?
queries - 73
После добавления обязательного столбца category приложение старых пользователей падает при открытии локальной базы. Как исправить это безопасно?
databaseschemafundamentals - 74
Экспорт отчёта работает на эмуляторе, но на реальном телефоне завершается ошибкой разрешения на файл. Как это исправить?
permissionslinux - 75
На ревью вы находите access token, сохранённый в обычных настройках открытым текстом. Где его следует хранить?
tokens - 76
Пользователь запрещает доступ к микрофону, после чего экран записи становится бесполезным. Что должно сделать приложение?
permissions - 77
После съёмки фотографии приложение возвращается к форме, но предпросмотр остаётся пустым. Как вы будете отлаживать результат камеры?
forms - 78
Экран ближайших магазинов бесконечно загружается, когда службы геолокации отключены. Как обработать этот случай?
android-components - 79
Открытие deep link товара при уже запущенном приложении показывает главный экран вместо товара. Что вы исправите?
navigation - 80
Нажатие на push-уведомление о заказе открывает приложение, но не нужный заказ. Как исправить навигацию?
navigationandroid-components - 81
Список плавно прокручивается с 20 строками, но тормозит с 500. Какие базовые проверки и исправления вы попробуете?
- 82
Открытие галереи фотографий с камеры приводит к падению из-за нехватки памяти. Что вы измените первым?
memory - 83
Приложение зависает на две секунды при открытии большого JSON-файла. Как исправить работу в главном потоке?
concurrency - 84
Экран кажется медленным, но вы не знаете, виноваты ли компоновка, сеть или код. Как вы используете профилировщик?
ui - 85
Ошибка входа возникает только на одном устройстве, а текущий лог сообщает лишь Login failed. Какие данные вы добавите в лог?
logging - 86
Ветка валидации должна выполняться для пустого email, но этого не происходит. Как поможет breakpoint?
validation - 87
Отчёт о падении в production указывает на строку 42 в ItemScreen и исключение выхода за границы индекса. Как вы используете stack trace?
indexeserror-handlingdebugging - 88
Unit-тест форматтера цены ожидал 10.00, но на одном компьютере получает 10,00. Как исправить тест?
unit - 89
UI-тест иногда нажимает Продолжить до того, как кнопка становится активной. Как уменьшить нестабильность теста?
- 90
Нужно проверить экран погоды без обращения к настоящему API. Как использовать mock API?
mockingapi - 91
После получения изменений коллеги Git сообщает о конфликте в файле навигации. Какие шаги вы выполните?
navigationgit - 92
Android debug-сборка работает, но release-сборка не может найти класс из библиотеки. Что вы проверите?
- 93
Тестовая сборка отправляет запросы в production API. Как исправить конфигурацию окружения?
configapi - 94
Архивная сборка завершается ошибкой подписи, хотя приложение запускается в симуляторе. Что вы проверите?
- 95
Сборка TestFlight успешно загружена, но так и не появляется у тестировщиков. Что вы проверите?
- 96
Сборка загружена в Google Play, но внутренний тестировщик её не видит. Что вы проверите?
- 97
Магазин отклоняет приложение, потому что ревьюер не может открыть функции только для аккаунта. Как вы ответите?
- 98
При отправке iOS-приложения появляется сообщение об отсутствующей информации privacy manifest для нового SDK. Что вы сделаете?
android-components - 99
Скринридер объявляет три кнопки как Icon, поэтому пользователь не может их различить. Как это исправить?
a11y - 100
Вы готовите небольшое обновление приложения к завтрашнему релизу. Какой базовый чек-лист вы используете?