Базовый CS с нуля
Время и конкурентность: тест с выбором ответа
Шесть вопросов поперёк всего юнита. Каждый — это предсказание или решение о реально работающей программе: не определение для заучивания, а рассуждение, к которому вели уроки, доведённое на шаг дальше — туда, где задачи делят общее состояние.
Убедись, что связываешь спину юнита — зачем существует async, blocking vs non-blocking, единственное правило event loop и concurrency vs parallelism — и рассуждаешь о том, что происходит, когда переплетённые или параллельные задачи трогают одни и те же данные.
Веб-сервер читает файл с диска на каждый запрос. Переход с blocking-чтения на non-blocking делает само чтение с диска насколько долгим и что реально улучшается?
Программа выполняет: console.log('A'); setTimeout(cb, 0), где cb печатает 'B'; затем console.log('C'). Что она печатает и какое правило за этим стоит?
Программа устроена как одна задача с одним thread. Ты запускаешь её на 16-ядерной машине. Насколько она быстра и почему?
Одноядерная машина переплетает 50 задач через event loop. Сколько выполняется в один и тот же момент и это concurrency или parallelism?
Два thread'а на двух ядрах каждый выполняет counter = counter + 1 миллион раз над одним общим counter, без synchronization. Итоговое значение часто гораздо ниже двух миллионов. Почему?
Команда добавила lock, чтобы только один thread мог выполнять обновление counter за раз. Race исчез, но throughput упал на 8-ядерной машине. Как это читать?
Сквозная линия юнита — одна идея, доведённая до края: CPU быстр, а устройства медленны, поэтому программы используют async — non-blocking-вызовы плюс callback’и — и event loop, выполняющий один callback за раз, только когда call stack пуст. Это concurrency: много задач переплетены на одном ядре, по очереди. Parallelism — иное: задачи по-настоящему выполняются в один и тот же момент на нескольких ядрах — и помогает только когда работа структурирована в задачи. Как только эти задачи делят состояние, становится возможен race condition: шаг вроде counter = counter + 1 на деле чтение-сложение-запись, и параллельные thread’ы могут переплестись и потерять обновления. Lock восстанавливает корректность, сериализуя общую секцию — ценой того самого parallelism, который он защищает. Сначала корректность, затем минимизируй то, что должно быть последовательным.