Skip to content

Вопросы на собеседовании: Flutter-разработчик

100 реальных вопросов с образцовыми ответами и пояснениями для уровня Junior Flutter-разработчик.

Смотреть пример резюме: Flutter-разработчик

Тренировка флешкарточками

Интервальное повторение · Hunter Pass

Вопросы

dart

Они различаются моментом выбора типа и объёмом статических проверок Dart.

  • var выводит один статический тип из инициализатора, поэтому после var count = 1 нельзя присвоить count строку.
  • Object принимает любой объект Dart, кроме null, а Object? также принимает null, но оба требуют проверки типа перед обращением к его членам.
  • dynamic откладывает проверки членов и присваиваний до выполнения, поэтому я оставляю его только на границах нетипизированных данных и быстро преобразую.

Зачем это спрашивают: Интервьюер проверяет, умеете ли вы пользоваться системой типов Dart, не отключая без необходимости статические проверки и null safety.

dart

final присваивается один раз во время выполнения, а const обозначает константу времени компиляции.

  • Значение final может прийти из DateTime.now() или ответа API, но после этого его нельзя переназначить.
  • Значение const и всё содержимое его константной коллекции должны быть известны при компиляции.
  • Экземпляры const-виджетов могут быть канонизированы и переиспользованы, поэтому я ставлю const у конструкторов, когда все аргументы постоянны.

Зачем это спрашивают: Сильный ответ отличает однократное присваивание от константы времени компиляции и связывает const с виджетами Flutter.

fundamentalsdartnull-safety

Типы Dart по умолчанию не допускают null, а nullable-тип нужно пометить знаком ?.

  • String name не может содержать null, а String? name может, поэтому перед использованием значение нужно проверить или безопасно прочитать.
  • ?? задаёт запасное значение, а ?. выполняет условный доступ; ! утверждает, что значение не равно null, и может вызвать ошибку при неверном утверждении.
  • late откладывает инициализацию, но чтение до присваивания вызывает ошибку выполнения, поэтому я использую его лишь при гарантированном порядке жизненного цикла.

Зачем это спрашивают: Интервьюер оценивает, обрабатываете ли вы отсутствие значения явно, а не полагаетесь на небезопасные утверждения.

dart

Я выбираю List для упорядоченных значений, Set для уникальных значений и Map для поиска по ключу.

  • List сохраняет порядок и допускает повторы, что подходит для последовательности сообщений или товаров.
  • Set удаляет повторы и даёт быстрые проверки наличия, например для ID выбранных категорий.
  • Map получает значение по ключу, например userById[id], а collection if и for позволяют декларативно строить любую из этих коллекций.

Зачем это спрашивают: Интервьюер проверяет, умеете ли вы сопоставлять основные коллекции Dart с данными приложения.

dart

Dart поддерживает необязательные позиционные и именованные параметры, а функции можно передавать и хранить как другие значения.

  • Именованные параметры заключаются в фигурные скобки, а required отмечает обязательные, поэтому вызов createUser(name: 'Ana') легко читать.
  • Необязательному параметру нужен nullable-тип или значение по умолчанию, а необязательные позиционные параметры заключаются в квадратные скобки.
  • Callback типа VoidCallback можно передать кнопке, а короткую функцию из одного выражения записать через =>.

Зачем это спрашивают: Хороший ответ показывает синтаксис функций, который постоянно используется в конструкторах и callback-функциях Flutter.

dart

Класс Dart объединяет состояние и поведение, а его конструкторы создают корректные экземпляры.

  • Параметр this.name сразу инициализирует поле, а обязательные именованные параметры явно показывают необходимые входные данные.
  • Именованный конструктор вроде User.guest() даёт ещё один понятный способ создания, а factory-конструктор может вернуть кэшированный экземпляр или подтип.
  • extends переиспользует реализацию одного суперкласса, а переопределённые члены стоит отмечать @override, чтобы анализатор мог их проверить.

Зачем это спрашивают: Интервьюер проверяет практическое создание объектов и основы наследования, а не запоминание синтаксиса.

typesdart

Интерфейс задаёт контракт для реализации, а mixin добавляет классам переиспользуемое поведение.

  • Каждый класс Dart предоставляет неявный интерфейс, а implements требует реализовать все его члены в новом классе.
  • interface class можно реализовать, но нельзя наследовать вне его библиотеки, что явно задаёт границу API.
  • mixin подключается через with и позволяет делиться методами между несвязанными классами без глубокой цепочки наследования.

Зачем это спрашивают: Сильный ответ учитывает модификаторы классов Dart 3 и не путает mixin с контрактом интерфейса.

dart

Records позволяют вернуть или объединить несколько типизированных значений без отдельного класса, а patterns распаковывают или проверяют их форму.

  • Функция может вернуть (User, bool), сохранив типы обоих полей в статической системе типов.
  • Деструктурирующее объявление final (user, cached) = result даёт имена полям record.
  • List-, map-, object- и switch-паттерны извлекают вложенные значения, но для данных с идентичностью, методами или стабильной публичной моделью я использую именованный класс.

Зачем это спрашивают: Интервьюер проверяет знание современного синтаксиса Dart и умение не заменять им содержательные доменные модели.

dart

sealed class задаёт закрытое семейство подтипов, которое switch может обработать исчерпывающе.

  • Подтипы должны быть объявлены в той же библиотеке, поэтому компилятор знает полный набор.
  • Loading, Success(data) и Failure(error) образуют практичную sealed-иерархию результата для экрана.
  • Switch-выражение по такой иерархии выдаёт ошибку компиляции при пропущенном варианте, в том числе после добавления нового подтипа.

Зачем это спрашивают: Сильный ответ связывает sealed-типы с исчерпывающей обработкой состояний, а не представляет их синтаксической мелочью.

dart

Future завершается один раз значением или ошибкой, а Stream может выдавать много значений со временем.

  • Я ожидаю Future через await для одного ответа REST или чтения файла и ловлю ошибку через try и catch.
  • Я подписываюсь на Stream для повторяющихся событий, например изменений авторизации или обновлений базы в реальном времени.
  • Подписки Stream нужно отменять при dispose владельца, а await for может читать события до закрытия потока.

Зачем это спрашивают: Интервьюер проверяет, умеете ли вы выбирать и очищать основные асинхронные абстракции Dart.

flutter

Во Flutter метод build описывает UI для текущего состояния, а не отправляет команды для изменения отдельных представлений.

  • При изменении состояния Flutter снова вызывает build и сопоставляет новую конфигурацию виджетов с существующим деревом.
  • Флаг загрузки может прямо в дереве выбирать индикатор прогресса или содержимое.
  • В build не должно быть сетевых вызовов и других побочных эффектов, поскольку фреймворк может вызывать его много раз.

Зачем это спрашивают: Интервьюер оценивает понимание модели от состояния к UI и умение сохранять build повторяемым.

widgets

Я использую StatelessWidget без изменяемого локального состояния и StatefulWidget, когда состояние должно сохраняться между пересборками.

  • Объекты обоих виджетов неизменяемы; StatefulWidget создаёт отдельный изменяемый объект State.
  • Заголовку только из аргументов конструктора подходит StatelessWidget, а локальному переключателю видимости пароля подходит StatefulWidget.
  • Если состояние относится к нескольким экранам или бизнес-логике, я поднимаю его выше или переношу в слой управления состоянием, а не раздуваю локальный State.

Зачем это спрашивают: Сильный ответ знает, что сам StatefulWidget неизменяем, и хранит состояние в подходящей области.

widgets

Объект State инициализируется, может получать обновления зависимостей или виджета, пересобирается и в конце освобождается.

  • initState запускается один раз для настройки без зависимости от inherited-виджетов, например для создания AnimationController.
  • didChangeDependencies обрабатывает inherited-зависимости, а didUpdateWidget реагирует на новую конфигурацию виджета от родителя.
  • dispose освобождает контроллеры, focus nodes и подписки перед вызовом super.dispose.

Зачем это спрашивают: Интервьюер проверяет, размещаете ли вы настройку, обновления и очистку в правильных методах жизненного цикла.

widgets

BuildContext определяет положение виджета в дереве элементов и служит для поиска предков вроде Theme или Navigator.

  • Theme.of(context) ищет вверх именно из этой точки, поэтому нужный provider должен быть её предком.
  • Context над только что созданным Scaffold не видит этот Scaffold; Builder может создать context под ним.
  • После await я проверяю context.mounted перед навигацией или показом UI, потому что виджет могли удалить.

Зачем это спрашивают: Хороший ответ рассматривает context как положение в дереве и учитывает область предков и асинхронное время жизни.

flutterwidgetsrendering

Widgets являются неизменяемыми конфигурациями, elements управляют их смонтированной идентичностью, а render objects выполняют layout и отрисовку.

  • build создаёт лёгкие описания widgets, которые можно заменять при каждой пересборке.
  • Element связывает widget с позицией в дереве и сохраняет связанный State, пока совпадают тип и key.
  • Экземпляры RenderObject получают constraints, выбирают размер, рисуют пиксели и выполняют hit testing для виджетов с рендерингом.

Зачем это спрашивают: Интервьюер проверяет, понимаете ли вы Flutter глубже фразы о том, что всё является виджетом.

flutterwidgets

Keys помогают Flutter сопоставлять конфигурации виджетов с существующими elements при изменении порядка или идентичности соседей.

  • ValueKey(item.id) сохраняет правильный State при перемещении элементов в сортируемом списке.
  • Keys важны среди соседей одного типа; случайные UniqueKeys принудительно теряют состояние вместо исправления идентичности.
  • GlobalKey может обращаться к state или перемещать element по дереву, но он тяжелее и нужен лишь в случаях вроде FormState.

Зачем это спрашивают: Сильный ответ объясняет сохранение идентичности и не предлагает GlobalKey как стандартное решение.

flutter

Родитель передаёт constraints вниз, каждый ребёнок выбирает допустимый размер, а родитель размещает его.

  • Constraints задают минимальную и максимальную ширину и высоту, а не всегда один точный размер.
  • Ребёнок не может выйти за эти пределы, поэтому width 500 не переопределит максимум родителя в 300.
  • Неограниченные constraints часто появляются внутри scrollables и конфликтуют с Expanded или ребёнком, который пытается занять бесконечное пространство.

Зачем это спрашивают: Интервьюер проверяет, можете ли вы объяснять типичное поведение layout через constraints, а не подбор размеров наугад.

schema

Row и Column используют Flex layout, а Expanded и Flexible определяют, как дети делят оставшееся место по главной оси.

  • Row располагает детей горизонтально, Column вертикально, а mainAxisAlignment распределяет свободное место на этой оси.
  • Expanded использует tight fit и растягивает ребёнка на его долю flex, что может убрать переполнение текста в Row.
  • Flexible по умолчанию использует loose fit и разрешает ребёнку занять меньше своей доли, а значения flex делят пространство пропорционально.

Зачем это спрашивают: Хороший ответ связывает Flex-виджеты с конкретной моделью переполнения и распределения пространства.

flutter

Для длинного или динамического списка я использую ListView.builder, чтобы создавать только видимые элементы и ближайший кэш.

  • ListView с явным списком children сразу создаёт каждого ребёнка и подходит лишь для небольшого фиксированного списка.
  • SingleChildScrollView создаёт всего ребёнка, поэтому оборачивание большой Column тратит память и время build.
  • Для смешанных секций вроде app bar, grid и list CustomScrollView со slivers объединяет их в одну область прокрутки.

Зачем это спрашивают: Интервьюер оценивает понимание ленивого создания и умение избегать дорогих прокручиваемых layout.

flutterwidgets

MaterialApp предоставляет ThemeData для Material-виджетов, а CupertinoApp предоставляет CupertinoThemeData для виджетов в стиле iOS.

  • Theme.of(context) и CupertinoTheme.of(context) читают унаследованные цвета и типографику вместо дублирования констант на каждом экране.
  • ColorScheme позволяет Material-компонентам последовательно использовать роли primary, surface и error в светлой и тёмной темах.
  • Я выбираю одну цельную дизайн-систему продукта и применяю платформенно-адаптивные элементы лишь там, где пользователи ожидают нативное поведение.

Зачем это спрашивают: Сильный ответ знает обе системы тем и не смешивает платформенные стили без продуктовой причины.

Закрытые вопросы

  • 21

    Как валидировать и отправить форму во Flutter?

    formsfluttervalidation
  • 22

    Как нужно управлять TextEditingController и FocusNode?

  • 23

    Когда использовать GestureDetector вместо InkWell?

    interaction
  • 24

    Как перейти на экран и вернуть результат во Flutter?

    flutter
  • 25

    Как добавить изображения и собственные шрифты в Flutter-приложение?

    flutter
  • 26

    Как сделать экран Flutter адаптивным?

    responsiveflutter
  • 27

    Как выглядит базовый процесс локализации во Flutter?

    flutter
  • 28

    Как обеспечить базовую доступность экрана Flutter?

    flutter
  • 29

    Когда использовать implicit animation во Flutter?

    flutteranimation
  • 30

    Что необходимо делать при использовании AnimationController?

    animation
  • 31

    Когда уместен setState и что он делает?

    state
  • 32

    Что означает lifting state up во Flutter?

    flutter
  • 33

    Когда использовать ValueNotifier и ValueListenableBuilder?

  • 34

    Как выглядит базовый поток Riverpod на экране Flutter?

    flutterstate-management
  • 35

    В чём основная идея BLoC во Flutter?

    flutterstate-management
  • 36

    Как вызвать REST API из Flutter-приложения?

    restflutter
  • 37

    Как преобразовать JSON-ответ в модель Dart?

    dart
  • 38

    Как Flutter-приложению обрабатывать сетевые ошибки и timeouts?

    flutterresilience
  • 39

    Какой вариант локального хранения выбрать во Flutter-приложении?

    flutter
  • 40

    Что нужно для добавления Firebase во Flutter-приложение?

    flutter
  • 41

    Для чего нужен pubspec.yaml в проекте Flutter?

    yamlpackagesflutter
  • 42

    Как оценить Flutter package перед добавлением?

    decision-makingflutter
  • 43

    Какой базовый Git-процесс вы используете для функции Flutter?

    fluttergit
  • 44

    Что делают dart analyze и dart format?

    dart
  • 45

    В чём разница между hot reload и hot restart?

    tooling
  • 46

    Чем режимы сборки Flutter отличаются от app flavors?

    flutter
  • 47

    Что такое unit-, widget- и integration-тесты во Flutter?

    integrationintegration-testingflutter
  • 48

    Как добавить и запросить мобильное permission во Flutter?

    flutter
  • 49

    Как Flutter-приложение может реагировать на изменения жизненного цикла?

    reactflutter
  • 50

    Для чего вы используете Flutter DevTools?

    flutterflutter-devtools
  • 51

    На узком телефоне Row показывает желто-черные полосы переполнения; как вы это исправите?

  • 52

    ListView внутри Column выдает ошибку неограниченной высоты; какое точное изменение вы внесете?

    schema
  • 53

    Экран создает 1000 карточек товаров в Column и зависает при открытии; как вы переделаете список?

    schema
  • 54

    HTTP-запрос завершается после ухода пользователя с экрана, и Flutter сообщает setState() called after dispose(); как это исправить?

    flutterstatehttp
  • 55

    Экран поиска создает TextEditingController, а его listener продолжает срабатывать после повторной навигации; что нужно очистить?

    navigation
  • 56

    После перестановки редактируемых задач введенный текст оказывается у другой задачи; как исправить keys?

  • 57

    FutureBuilder повторно загружает профиль при каждой перестройке родителя, и индикатор постоянно мигает; как это остановить?

    async
  • 58

    Сохранение завершается после закрытия страницы, а попытка показать SnackBar через context завершается ошибкой; что вы измените?

  • 59

    Форма входа отправляет невалидные поля без сообщений и оставляет клавиатуру поверх результата; как вы исправите этот сценарий?

    forms
  • 60

    Image.asset работает у одного разработчика, но в CI с учетом регистра появляется Unable to load asset; что вы проверите?

    system-design
  • 61

    REST-клиент пытается декодировать каждый ответ как JSON, падает на 204 и оставляет индикатор загрузки на 401; как вы обработаете статусы?

    rest
  • 62

    API иногда возвращает null в avatarUrl и не присылает address, из-за чего возникает ошибка приведения типа; как сделать парсинг безопасным?

    fundamentals
  • 63

    Запрос товаров может навсегда зависнуть при плохом соединении; как добавить timeout и восстановление?

    resilience
  • 64

    Лента на мгновение показывает Нет элементов, пока первый запрос еще загружается; как вы смоделируете экран?

  • 65

    При быстрой прокрутке страница 3 запрашивается дважды и появляются дубликаты товаров; как это исправить?

    pagination
  • 66

    Экран заметок должен показать последний успешно загруженный список, если телефон открыт без сети; какой базовый кэш вы добавите?

    caching
  • 67

    На ревью access token обнаружили в SharedPreferences; куда его перенести и что еще проверить?

    tokens
  • 68

    Вход через Firebase Auth проходит успешно, но после каждого перезапуска приложение на мгновение показывает экран входа; как это исправить?

  • 69

    Сообщения FCM видны в логах, пока приложение открыто, но пользователь не видит баннер; что вы реализуете?

  • 70

    Обновление заполненного каталога завершается ошибкой 500, и экран становится пустым; какой UI ошибки вы покажете?

  • 71

    Счетчик Riverpod меняется после нажатия кнопки, но подпись остается старой, потому что виджет использует ref.read; что вы измените?

    widgetsstate-management
  • 72

    ConsumerWidget выдает No ProviderScope found при открытии в widget-тесте; как исправить scope?

    widgetsstate-management
  • 73

    Двойное нажатие Сохранить отправляет два события BLoC и создает две записи; как это предотвратить?

    state-management
  • 74

    BLoC оформления заказа сбрасывается при каждом setState родителя, и введенные данные доставки исчезают; что вы проверите?

    statestate-management
  • 75

    Ввод в одном поле, похоже, перестраивает весь экран товаров на Riverpod; как это диагностировать и сократить?

    state-management
  • 76

    StreamSubscription состояния сети продолжает обновлять удаленный экран; как вы ее очистите?

    streams
  • 77

    Timer.periodic продолжает обновление после закрытия dashboard; какое точное исправление жизненного цикла нужно?

  • 78

    Декодирование JSON размером 5 МБ заметно замораживает прокрутку; как перенести эту работу с UI isolate?

    concurrency
  • 79

    Пользователь вводит cat, затем car, но более медленный запрос cat завершается последним и заменяет результаты car; как исправить гонку?

  • 80

    После ухода с экрана загрузка файла не останавливается, а поздний callback прогресса обращается к удаленному state; как добавить отмену?

    resiliencecallbacks
  • 81

    Widget-тест нажимает Отправить, но ожидаемый текст успеха не появляется, потому что UI ждет Future; как правильно вызвать pump?

    widgets
  • 82

    Golden-тест совпадает локально, но текст отличается в CI из-за другого шрифта; как его стабилизировать?

  • 83

    Widget-тест профиля обращается к настоящему staging API и падает без сети; как заменить эту зависимость?

    widgetsapidependencies
  • 84

    Как написать один integration-тест для входа и открытия экрана профиля?

    integrationintegration-testing
  • 85

    Отчет о production-баге содержит только request failed, а debug-логи печатают полные токены; как безопасно улучшить логирование?

    tokensloggingbug-reporting
  • 86

    После отказа в доступе к камере нажатие Сканировать ничего не делает; как обработать разрешения?

  • 87

    Android debug-сборка не обращается к локальному http API и сообщает cleartext traffic not permitted; что вы измените?

    http
  • 88

    iOS-приложение закрывается при открытии выбора фото, а консоль сообщает об отсутствующем usage description; как это исправить?

  • 89

    Открытие myapp://product/42 запускает приложение, но всегда показывает Home; как вы отладите deep link?

  • 90

    Таймер опроса продолжает отправлять запросы, пока приложение в фоне; как вы отреагируете на изменения жизненного цикла?

    react
  • 91

    После Git merge в pubspec.yaml и одном Dart-файле остались маркеры конфликта; как безопасно разрешить конфликт?

    gityamlpackages
  • 92

    flutter pub get падает, потому что package_a требует http ниже 1.0, а package_b требует http 1.x; что вы сделаете?

    flutterhttp
  • 93

    После добавления поля json_serializable сгенерированный part не содержит его, и компиляция падает; как обновить генерацию?

  • 94

    CI останавливается на flutter analyze из-за unawaited-вызова save, хотя при ручной проверке все работает; как это исправить?

    fluttertesting
  • 95

    Android release-сборку отклонили, потому что она подписана debug-сертификатом; что вы проверите?

  • 96

    Staging flavor по ошибке отправляет запросы в production; как разделить и проверить окружения?

  • 97

    Скринридер произносит кнопку удаления только как Кнопка, потому что на ней одна иконка; как сделать ее доступной?

    a11y
  • 98

    Телефонная компоновка растягивает одну текстовую колонку на весь 12-дюймовый планшет, и читать становится неудобно; как ее адаптировать?

    schema
  • 99

    Приложение показывает 1 items и использует английские правила в русском; как правильно локализовать количество?

  • 100

    На code review блок catch игнорирует ошибку запроса заказа, а finally всегда показывает Заказ оформлен; какой дефект вы отметите и исправите?

    code-reviewdefects