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

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

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

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

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

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

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

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

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

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

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

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

Все подборки
  • Python17 121
  • Облачные технологии14 079
  • QA вакансии3 451
  • Backend вакансии2 115
  • Инженер данных1 805
  • Продакт-менеджер1 260

Разработка

  • Android1 862
  • iOS1 700
  • Fullstack вакансии986
  • AI вакансии950
  • Frontend вакансии744
  • Mobile вакансии44

По стеку

  • Go8 659
  • Java6 537
  • Node.js2 020
  • .NET1 721
  • Kotlin1 614
  • Rust1 455
  • C#710
  • PHP681
  • C++571

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

  • Kubernetes7 772
  • DevOps вакансии6 050
  • Linux-инфраструктура5 488
  • Terraform / IaC4 272
  • CI/CD3 239
  • Мониторинг и Observability1 789
  • SRE567
  • Кибербезопасность452

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

  • Data Scientist1 140
  • Бизнес-аналитик923
  • Аналитик данных855
  • Системный аналитик152

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

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

По регионам

  • Вакансии в США44 276
  • Вакансии в Европе23 819
  • Вакансии в Канаде4 471
  • Работа в России3 904

По формату

  • Удалённые вакансии74 928
  • Релокация в США44 273
  • Гибридная работа12 388
  • Офисная работа7 083

По уровню

  • Senior вакансии42 627
  • Middle вакансии20 864
  • Junior вакансии6 721

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

Все компании
  • Wise190 вакансий
  • Rakuten189 вакансий
  • ASML166 вакансий
  • Grab137 вакансий
  • Celonis39 вакансий
  • Spotify37 вакансий
  • Adyen28 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace16 вакансий

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

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

В чём разница между Column и ListView? Когда использовать ListView.builder?

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

Column строит всех детей сразу и не скроллится. ListView — скроллируемый виджет. ListView.builder создаёт элементы лениво по мере прокрутки — нужен при списке от ~20 элементов или неизвестной длине.

Пример: все три варианта

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Column vs ListView')),
        body: const ListDemo(),
      ),
    );
  }
}

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

  // Генерируем 1000 элементов — Column здесь упадёт с overflow
  static final items = List.generate(1000, (i) => 'Элемент $i');

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // --- 1. Column: только для коротких фиксированных наборов ---
        const Text('Column (3 элемента, без прокрутки):',
            style: TextStyle(fontWeight: FontWeight.bold)),
        Column(
          children: const [
            ListTile(title: Text('A')),
            ListTile(title: Text('B')),
            ListTile(title: Text('C')),
          ],
        ),

        const Divider(),

        // --- 2. ListView.builder: 1000 элементов, ленивое построение ---
        const Text('ListView.builder (1000 элементов):',
            style: TextStyle(fontWeight: FontWeight.bold)),
        Expanded(
          child: ListView.builder(
            itemCount: items.length,
            // itemBuilder вызывается только для видимых + буферных элементов
            itemBuilder: (context, index) {
              return ListTile(
                leading: CircleAvatar(child: Text('$index')),
                title: Text(items[index]),
              );
            },
          ),
        ),
      ],
    );
  }
}

Column vs ListView: в чём разница

Column — layout-виджет без прокрутки. Он строит все дочерние виджеты сразу и размещает их вертикально. Если суммарная высота детей превышает доступное пространство, Flutter бросит исключение RenderFlex overflowed.

ListView — скроллируемый контейнер. В базовой форме ListView(children: [...]) он тоже строит всех детей сразу, но позволяет прокрутку. Когда список фиксированный и небольшой (до ~10–15 элементов), это допустимо.

ListView.builder создаёт элементы лениво: виджет строится только тогда, когда он попадает в viewport. Flutter вызывает itemBuilder по индексу по мере прокрутки и переиспользует RenderObject'ы, освобождая память для виджетов вне экрана.

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

  • Column — статичная верстка внутри экрана, элементы всегда видны, прокрутка не нужна.
  • ListView (обычный) — короткий фиксированный список, когда удобнее передать готовый список виджетов.
  • ListView.builder — список неизвестной или большой длины, данные из API/БД, бесконечная лента.
  • ListView.separated — то же, что builder, но с автоматическим разделителем между элементами.

ListView.builder с реальным API

import 'package:flutter/material.dart';

// Имитация сетевого запроса
Future<List<String>> fetchJobs(int page) async {
  await Future.delayed(const Duration(milliseconds: 400));
  return List.generate(20, (i) => 'Job ${page * 20 + i}');
}

class JobListScreen extends StatefulWidget {
  const JobListScreen({super.key});

  @override
  State<JobListScreen> createState() => _JobListScreenState();
}

class _JobListScreenState extends State<JobListScreen> {
  final List<String> _jobs = [];
  int _page = 0;
  bool _loading = false;
  final ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    _loadMore();
    _scrollController.addListener(() {
      // Подгружаем следующую страницу при приближении к концу
      if (_scrollController.position.pixels >
          _scrollController.position.maxScrollExtent - 200) {
        _loadMore();
      }
    });
  }

  Future<void> _loadMore() async {
    if (_loading) return;
    setState(() => _loading = true);
    final newJobs = await fetchJobs(_page);
    setState(() {
      _jobs.addAll(newJobs);
      _page++;
      _loading = false;
    });
  }

  @override
  void dispose() {
    // ВАЖНО: всегда освобождать ScrollController
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Вакансии')),
      body: ListView.builder(
        controller: _scrollController,
        // +1 для индикатора загрузки внизу
        itemCount: _jobs.length + (_loading ? 1 : 0),
        itemBuilder: (context, index) {
          if (index == _jobs.length) {
            return const Center(
              child: Padding(
                padding: EdgeInsets.all(16),
                child: CircularProgressIndicator(),
              ),
            );
          }
          return ListTile(
            title: Text(_jobs[index]),
            subtitle: Text('Страница ${index ~/ 20}'),
          );
        },
      ),
    );
  }
}

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

  • Column внутри ListView без Expanded/Flexible. Если положить Column с Expanded прямо в ListView, получите ошибку — ListView даёт неограниченную высоту дочернему Column, а Expanded требует ограниченное пространство.
  • ListView.builder без itemCount = бесконечный скролл. Если не передать itemCount, Flutter будет вызывать itemBuilder бесконечно, пока builder не вернёт null. Легко получить выход за границы списка.
  • Неправильные ключи при динамическом списке. Если элементы меняются (удаление, вставка), без key Flutter может перепутать состояние виджетов — особенно критично для StatefulWidget внутри builder.
  • Забытый dispose для ScrollController. ScrollController, созданный в State, нужно освобождать в dispose(). Иначе — утечка памяти и ошибка при обращении к контроллеру после unmount.
  • Тяжёлые виджеты в itemBuilder без кэширования. itemBuilder вызывается при каждом rebuild. Если внутри создаётся дорогой виджет (например, с Image.network без кэша), список будет дёргаться при прокрутке.
  • Column не скроллится — не оборачивайте в SingleChildScrollView без необходимости. Комбинация SingleChildScrollView + Column строит всех детей сразу и не даёт преимуществ ленивой загрузки — используйте ListView.builder.
  • shrinkWrap: true убивает производительность. ListView(shrinkWrap: true) рассчитывает полный размер всего списка сразу, отключая ленивость. При больших списках это катастрофа для производительности.
  • setState из scrollListener после dispose. Если пользователь ушёл с экрана во время загрузки, setState в callback вызовет ошибку. Нужна проверка if (!mounted) return; перед каждым setState в асинхронном коде.

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

  • Сводить «Column и ListView? Когда использовать ListView.builder» к синтаксису и не объяснять widget tree.
  • Игнорировать жизненный цикл, основной поток или момент освобождения ресурсов в сценарии flutter-10.
  • Выбирать API по привычке, не проверяя состояние, ошибки, доступность и платформенные ограничения.

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

  • Формулирует точную модель для «Column и ListView? Когда использовать ListView.builder» и подтверждает ее корректным примером.
  • Умеет связать ответ с element tree, тестированием и отладкой на устройстве.
  • Называет ограничения подхода flutter-10, включая производительность, память и сопровождение.

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

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

Источники

  • https://docs.flutter.dev/ui/layout
←Предыдущий вопросКак обрабатывать deep linking в приложении Flutter?Следующий вопрос→В чём разница между режимами сборки `release`, `profile` и `debug`?

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

FlutterMobile-Engineeringui-rendering-performance

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

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