Flutter — Dart однопоточный или многопоточный язык
Что проверяют
Понимаете ли вы модель выполнения Dart и отличаете ли асинхронность от параллельности. Для iOS-разработчика это ещё и проверка, сможете ли вы сопоставить её с GCD и Swift Concurrency. Следом обычно просят объяснить, почему интерфейс подвисает при разборе большого JSON, хотя код написан через async.
Как отвечать
Короткий ответ: код на Dart исполняется в изолятах, внутри каждого изолята он однопоточный, а параллельность дают несколько изолятов.
- изолят: своя куча памяти и один поток выполнения с циклом событий. Общей памяти между изолятами нет, поэтому гонок данных на объектах Dart не бывает и мьютексы не нужны;
- цикл событий: две очереди. Микрозадачи (
scheduleMicrotask, колбэки завершившихсяFuture) выполняются раньше событий (таймеры, ввод-вывод, жесты), и пока очередь микрозадач не пуста, до событий дело не доходит; async/await: не создают потоков. Ожидание сетевого ответа не блокирует изолят, потому что сам ввод-вывод выполняет рантайм, но код послеawaitснова работает в том же UI-изоляте;- параллельная работа:
Isolate.run()для разовой тяжёлой задачи илиcompute()во Flutter, для долгоживущих фоновых воркеровIsolate.spawnс обменом черезSendPortиReceivePort. Сообщения копируются, а результат черезIsolate.exitпередаётся без копирования.
Сравнение для iOS: в Swift потоки делят память, и защита лежит на вас (очереди, actor, замки). В Dart защищать нечего, зато вы платите копированием данных между изолятами. Сам движок Flutter при этом многопоточный, растеризация идёт на отдельном потоке, но ваш Dart-код туда не попадает.
Где спотыкаются
Считают, что обёртка в Future уводит работу в фон. Future(() => heavyParse()) выполнится в том же изоляте и так же уронит кадры.
Отвечают одним словом, «однопоточный» или «многопоточный». Полный ответ состоит из двух частей: однопоточный изолят и параллельность через несколько изолятов без общей памяти.
Гоняют в изолят каждую мелочь. Запуск изолята и копирование данных стоят времени, и для задачи на пару миллисекунд это медленнее, чем выполнить её на месте. На вебе изоляты недоступны, compute там работает в основном потоке.