Расскажите про концепции асинхронности и параллелизма
Что проверяют
Различаете ли вы конкурентность и параллелизм и понимаете ли, что асинхронность про освобождение потока.
Как отвечать
Три понятия, которые постоянно смешивают:
- конкурентность это про структуру: несколько задач продвигаются в перекрывающиеся промежутки времени. Они могут выполняться и на одном ядре, чередуясь;
- параллелизм это про исполнение: несколько задач физически работают одновременно на разных ядрах. Требует нескольких ядер;
- асинхронность это способ не блокировать поток на ожидании: операция запускается, поток освобождается, продолжение выполняется по готовности результата.
В C# это выражается конкретно:
async/awaitнад операциями ввода-вывода не создаёт потоков вовсе. Пока идёт запрос, ждёт драйвер и порт завершения ввода-вывода в ядре, а поток вернулся в пул;Task.RunиParallel.For, наоборот, отдают работу потокам пула. Это про загрузку процессора;Parallel.ForEachи PLINQ распараллеливают обработку коллекций;ChannelиIAsyncEnumerableописывают потоки данных между производителем и потребителем.
Правило выбора простое: ждём внешнюю систему, значит async/await; считаем, значит параллельные конструкции и пул. Их путаница даёт две классические ошибки: Task.Run вокруг запроса к базе (занимает поток вместо того, чтобы освободить) и .Result поверх асинхронного кода (блокирует поток и в контексте с синхронизацией даёт дедлок).
Где спотыкаются
Считают асинхронность синонимом многопоточности.
Оборачивают вызовы базы в Task.Run.
Не различают конкурентность и параллелизм и потому не понимают, почему на одном ядре асинхронность всё равно помогает.
Смешивают асинхронный код с блокирующим ожиданием.