Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+661новая вакансия за сутки·58 731вакансия открыта сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании5 712
РезюмеAIПодготовкаСтатьи
ТарифыТарифы
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 393 кандидата открыты к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python11 079
  • Облачные технологии8 824
  • QA вакансии2 977
  • Android1 395
  • Инженер данных1 032
  • Продакт-менеджер351

Разработка

  • Backend вакансии1 342
  • iOS1 307
  • AI вакансии660
  • Fullstack вакансии524
  • Frontend вакансии465
  • Mobile вакансии28

По стеку

  • Go6 622
  • Java3 670
  • Kotlin1 199
  • Node.js1 190
  • Rust1 181
  • .NET780
  • PHP329
  • C++301
  • C#211

DevOps и инфраструктура

  • Kubernetes5 251
  • Linux-инфраструктура4 138
  • DevOps вакансии3 024
  • Terraform / IaC2 834
  • Мониторинг и Observability1 406
  • CI/CD917
  • SRE389
  • Кибербезопасность40

Аналитика и данные

  • Аналитик данных586
  • Бизнес-аналитик487
  • Data Scientist458
  • Системный аналитик75

Другие направления

  • Проджект-менеджер114
  • UI/UX дизайн74
  • Ручное тестирование14

По регионам

  • Вакансии в США31 201
  • Вакансии в Европе11 507
  • Работа в России3 630
  • Вакансии в Канаде2 546

По формату

  • Удалённые вакансии47 761
  • Релокация в США31 201
  • Гибридная работа7 699
  • Офисная работа6 071

По уровню

  • Senior вакансии27 027
  • Middle вакансии12 284
  • Junior вакансии4 495

Сейчас нанимают

Все компании
  • Wise196 вакансий
  • Rakuten188 вакансий
  • ASML163 вакансии
  • Grab134 вакансии
  • Celonis48 вакансий
  • Spotify38 вакансий
  • Adyen28 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace17 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме FlutterВсе вопросы
FlutterSeniorТеория

Как работает дерево виджетов (widget tree) во Flutter (widget tree, element tree, render tree)?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

Flutter поддерживает три синхронизированных дерева: Widget (неизменяемые конфигурации), Element (живые узлы с состоянием и жизненным циклом), RenderObject (геометрия и отрисовка). Widget пересоздаётся при каждом rebuild, Element и RenderObject переиспользуются.

Widget Tree — неизменяемые конфигурации

Виджет — это иммутабельное описание части UI. Объект дешёв в создании: вызов build() каждый кадр создаёт новые экземпляры виджетов. Виджеты не хранят состояние и не знают о размерах.

// Каждый вызов build() возвращает новый объект Column,
// новый Text, новый ElevatedButton — это нормально и дёшево.
@override
Widget build(BuildContext context) {
  return Column(
    children: [
      Text('Hello, $_name'),
      ElevatedButton(
        onPressed: _onTap,
        child: const Text('Go'),
      ),
    ],
  );
}

Три дерева Flutter

Система рендеринга Flutter построена на трёх параллельных деревьях. Каждое решает свою задачу, и только понимание всех трёх объясняет, почему Flutter быстр и как правильно использовать ключи (Key).

Element Tree — живые узлы

Element — это «живой» узел, соответствующий конкретному виджету в конкретном месте дерева. Element создаётся один раз при монтировании и сохраняется между rebuild'ами. Он хранит ссылку на текущий виджет и на RenderObject.

При rebuild Flutter сравнивает новый виджет со старым по типу и ключу (runtimeType && key). Если они совпадают — Element обновляется (widget заменяется), RenderObject получает новые параметры без пересоздания. Если тип изменился — старый Element размонтируется, создаётся новый.

  • StatelessElement — для StatelessWidget.
  • StatefulElement — хранит объект State, переживающий rebuild.
  • ComponentElement — не имеет RenderObject, делегирует дочерним (InheritedElement и др.).
  • RenderObjectElement — непосредственно владеет RenderObject (например, SingleChildRenderObjectElement).

Render Tree — геометрия и пиксели

RenderObject выполняет layout и paint. Протокол layout передаёт Constraints сверху вниз, дочерние объекты возвращают размеры снизу вверх. RenderBox — наиболее распространённый подкласс, работающий с прямоугольными ограничениями.

// Упрощённая схема кастомного RenderObject
class RenderColoredBox extends RenderProxyBox {
  Color _color;

  RenderColoredBox({required Color color, RenderBox? child})
      : _color = color, super(child);

  set color(Color value) {
    if (_color == value) return;
    _color = value;
    markNeedsPaint(); // только перерисовка, без нового layout
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    context.canvas.drawRect(
      offset & size,
      Paint()..color = _color,
    );
    super.paint(context, offset);
  }
}

Жизненный цикл Element

  • mount() — первое присоединение к дереву, создание RenderObject.
  • update(Widget newWidget) — вызывается при rebuild, если тип+ключ совпали.
  • unmount() — удаление из дерева, освобождение ресурсов.
  • activate() / deactivate() — временное извлечение из дерева и возврат (GlobalKey).

Роль Key

Ключ позволяет Flutter правильно сопоставить Element при изменении порядка дочерних виджетов.

// Без ключей перестановка списка не перемещает State
Column(
  children: items.map((item) => ItemWidget(key: ValueKey(item.id), item: item)).toList(),
);

// GlobalKey позволяет перемещать элемент между разными
// ветками дерева, сохраняя State
final _key = GlobalKey();
// ... Widget(key: _key) может жить в другом месте дерева

Оптимизация перестройки

Методы markNeedsLayout(), markNeedsPaint() и markNeedsBuild() — гранулярные сигналы. Flutter батчит их и обрабатывает в рамках одного кадра. RepaintBoundary изолирует поддерево в отдельный layer, предотвращая его перерисовку при изменениях соседей.

// Изолируем сложную анимацию от перерисовки статичного контента
RepaintBoundary(
  child: AnimatedLogo(),
);

Подводные камни

  • Отсутствие ключей в списках с состоянием: перестановка StatefulWidget без ValueKey / ObjectKey приводит к тому, что Flutter переиспользует неправильный Element и State «прыгает» между элементами.
  • Избыточное использование GlobalKey: GlobalKey дорог — он регистрируется в глобальном реестре, а перемещение элемента с GlobalKey запускает deactivate/activate цикл; предпочитайте ValueKey.
  • build() с побочными эффектами: метод build может вызываться многократно; размещение в нём логики (запросы, подписки) нарушает архитектуру и вызывает баги.
  • markNeedsLayout vs markNeedsPaint: вызов markNeedsLayout дороже — он пересчитывает размеры; если изменился только цвет, достаточно markNeedsPaint.
  • Глубокое дерево без RepaintBoundary: любое изменение в корне инвалидирует весь layer; для сложных scroll-списков каждый элемент стоит обернуть в RepaintBoundary.
  • const-виджеты и canUpdate: Flutter пропускает rebuild, если виджет const — это бесплатная оптимизация. Неиспользование const там, где это возможно, ведёт к лишним пересозданиям виджетов.
  • InheritedWidget и rebuild-буря: каждый потомок, читающий InheritedWidget через dependOnInheritedWidgetOfExactType, перестраивается при любом изменении; разбивайте InheritedWidget на мелкие или используйте InheritedModel для частичных зависимостей.
  • Dispose в State не вызван: контроллеры анимаций, потоки и слушатели, созданные в initState, должны освобождаться в dispose; иначе они держат ссылки на Element после его удаления из дерева.

Частые вопросы на собеседовании

  • Как работает управление состоянием (state management) во Flutter? Назовите распространённые решения.
  • Каковы лучшие практики оптимизации производительности Flutter?
  • В чём разница между StatelessWidget и StatefulWidget?
  • Каков жизненный цикл виджета StatefulWidget?

Типичные ошибки

  • Сводить «работает дерево виджетов (widget tree) во Flutter (widget tree, element tree, render tree)» к синтаксису и не объяснять frame scheduling.
  • Игнорировать жизненный цикл, основной поток или момент освобождения ресурсов в сценарии flutter-3.
  • Выбирать API по привычке, не проверяя состояние, ошибки, доступность и платформенные ограничения.

Что проверяет интервьюер

  • Формулирует точную модель для «работает дерево виджетов (widget tree) во Flutter (widget tree, element tree, render tree)» и подтверждает ее корректным примером.
  • Умеет связать ответ с platform channel, тестированием и отладкой на устройстве.
  • Называет ограничения подхода flutter-3, включая производительность, память и сопровождение.

Как вы знаете этот вопрос?

Проверить себя по теме Flutter →

Источники

  • https://docs.flutter.dev/resources/inside-flutter
←Предыдущий вопросКак работает управление состоянием (state management) во Flutter? Назовите распространённые решения.Следующий вопрос→Каковы лучшие практики оптимизации производительности Flutter?

Связанные темы

FlutterMobile-Engineeringui-rendering-performance