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

+1 260новых вакансий за сутки·70 005вакансий открыто сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

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

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

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

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

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

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

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

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

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

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

Все подборки
  • Python14 550
  • Облачные технологии10 965
  • QA вакансии3 255
  • Android1 702
  • Инженер данных1 270
  • Продакт-менеджер586

Разработка

  • Backend вакансии1 657
  • iOS1 575
  • AI вакансии798
  • Fullstack вакансии672
  • Frontend вакансии578
  • Mobile вакансии30

По стеку

  • Go7 978
  • Java5 162
  • Node.js1 622
  • Kotlin1 384
  • Rust1 326
  • .NET1 258
  • PHP538
  • C++386
  • C#356

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

  • Kubernetes6 272
  • Linux-инфраструктура4 763
  • DevOps вакансии4 488
  • Terraform / IaC3 459
  • Мониторинг и Observability1 587
  • CI/CD1 482
  • SRE458
  • Кибербезопасность127

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

  • Аналитик данных683
  • Бизнес-аналитик638
  • Data Scientist622
  • Системный аналитик92

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

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

По регионам

  • Вакансии в США34 823
  • Вакансии в Европе15 244
  • Работа в России3 882
  • Вакансии в Канаде3 408

По формату

  • Удалённые вакансии54 624
  • Релокация в США34 823
  • Гибридная работа9 286
  • Офисная работа6 546

По уровню

  • Senior вакансии31 197
  • Middle вакансии14 037
  • Junior вакансии5 059

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

Все компании
  • Wise194 вакансии
  • Rakuten189 вакансий
  • ASML164 вакансии
  • Grab134 вакансии
  • Celonis45 вакансий
  • Spotify37 вакансий
  • Infobip28 вакансий
  • Adyen27 вакансий
  • Monzo19 вакансий
  • Darktrace17 вакансий

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

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

Что такое FutureBuilder и StreamBuilder и когда использовать каждый?

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

FutureBuilder подписывается на Future (разовый результат) и перестраивает UI по трём состояниям: ожидание, данные, ошибка. StreamBuilder работает с непрерывным Stream, обновляясь при каждом событии. Главная ошибка: создавать Future прямо в build() — это запускает новый запрос при каждом rebuild.

FutureBuilder — разовый асинхронный результат

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

import 'package:flutter/material.dart';

Future<String> fetchUserName(String userId) async {
  // Имитируем сетевой запрос
  await Future.delayed(const Duration(seconds: 1));
  if (userId.isEmpty) throw Exception('User not found');
  return 'Alice';
}

class UserProfilePage extends StatelessWidget {
  final String userId;
  const UserProfilePage({super.key, required this.userId});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Profile')),
      body: FutureBuilder<String>(
        // Future создаём ВНЕ build() или через late/initState,
        // иначе при каждом rebuild будет новый запрос
        future: fetchUserName(userId),
        builder: (context, snapshot) {
          // Три состояния ConnectionState
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}'));
          }
          // snapshot.data гарантированно non-null здесь
          return Center(child: Text('Hello, ${snapshot.data}!'));
        },
      ),
    );
  }
}

StreamBuilder — непрерывный поток данных

StreamBuilder подписывается на Stream и обновляет UI при каждом новом событии. Используется для real-time данных — WebSocket, Firestore snapshots, локальные события (датчики, таймеры, состояние авторизации).

import 'dart:async';
import 'package:flutter/material.dart';

// Stream, который каждую секунду отдаёт текущее время
Stream<DateTime> clockStream() =>
    Stream.periodic(const Duration(seconds: 1), (_) => DateTime.now());

class ClockPage extends StatelessWidget {
  const ClockPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Live Clock')),
      body: StreamBuilder<DateTime>(
        stream: clockStream(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return const Center(child: Text('Starting...'));
          }
          if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}'));
          }
          final time = snapshot.data!;
          return Center(
            child: Text(
              '${time.hour}:${time.minute.toString().padLeft(2, '0')}:${time.second.toString().padLeft(2, '0')}',
              style: const TextStyle(fontSize: 48),
            ),
          );
        },
      ),
    );
  }
}

Правильное место для создания Future

Критическая ошибка: создавать Future прямо в методе build(). Каждый rebuild создаёт новый Future и новый запрос:

// ПЛОХО: новый запрос при каждом setState() родителя
FutureBuilder(
  future: api.fetchData(), // вызывается при каждом build!
  ...
)

// ХОРОШО: храним Future в State
class _MyPageState extends State<MyPage> {
  late final Future<Data> _dataFuture;

  @override
  void initState() {
    super.initState();
    _dataFuture = api.fetchData(); // создаётся один раз
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _dataFuture, // передаём сохранённый Future
      builder: (context, snapshot) { ... },
    );
  }
}

Когда что использовать

СценарийВиджет
HTTP-запрос при загрузке экранаFutureBuilder
Firestore / WebSocket данныеStreamBuilder
Чтение из локальной БД (один раз)FutureBuilder
Состояние авторизации (auth changes)StreamBuilder
Загрузка файла с прогрессомStreamBuilder

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

  • Future в build() — двойной запрос. Если родитель вызовет setState(), виджет перестроится и создаст новый Future. Всегда сохраняйте Future в полях State или используйте state management (Provider, Riverpod, BLoC).
  • Stream не закрывается автоматически. Если Stream создаётся в State, его нужно закрывать в dispose(). Незакрытый StreamController — утечка памяти.
  • ConnectionState.none vs waiting. Future возвращает ConnectionState.none если передан null, и waiting пока Future не завершился. Игнорирование none приводит к непредвиденному UI-состоянию.
  • snapshot.data может быть null даже при hasData == false. Всегда проверяйте snapshot.hasData и snapshot.hasError перед обращением к snapshot.data.
  • StreamBuilder держит последнее значение. При ошибке в Stream, snapshot.data всё ещё содержит последнее успешное значение. Проверяйте snapshot.hasError первым.
  • Лишние rebuild при каждом событии Stream. StreamBuilder перестраивает весь поддерево при каждом событии. Для частых событий (GPS, датчики) используйте where/throttle на Stream или вынесите FutureBuilder/StreamBuilder на минимальный виджет.

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

  • Сводить «FutureBuilder и StreamBuilder и когда использовать каждый» к синтаксису и не объяснять platform channel.
  • Игнорировать жизненный цикл, основной поток или момент освобождения ресурсов в сценарии flutter-14.
  • Выбирать API по привычке, не проверяя состояние, ошибки, доступность и платформенные ограничения.

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

  • Формулирует точную модель для «FutureBuilder и StreamBuilder и когда использовать каждый» и подтверждает ее корректным примером.
  • Умеет связать ответ с widget tree, тестированием и отладкой на устройстве.
  • Называет ограничения подхода flutter-14, включая производительность, память и сопровождение.

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

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

Источники

  • https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
←Предыдущий вопросВ чём разница между виджетами `Expanded` и `Flexible`?Следующий вопрос→Как обрабатывать deep linking в приложении Flutter?

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

Flutterconcurrency-debuggingMobile-Engineering

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

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