Базовый CS с нуля
От машинного кода к языку: тест с множественным выбором
Шесть вопросов, проходящих сквозь весь юнит. Каждый просит связать идеи из разных уроков — правило один-к-одному у assembler, что дают высокоуровневые языки, чем различаются стратегии трансляции и что делает runtime — а не воспроизвести одно определение.
Убедись, что можешь соединить ступени лестницы: сырой machine code, assembly, высокоуровневые языки, стратегии трансляции между ними и runtime с конвейером, доносящие твой код до CPU.
Ты пишешь одну строку assembly, ADD R0 R1, и одну строку TypeScript, total = price * qty + shipping. Сколько машинных инструкций даёт каждая и что это раскрывает?
Команда хочет доставить одну и ту же программу на серверы x86-64 Linux и на ноутбуки ARM. Они думают распространять её как написанный вручную assembly. Что пойдёт не так и что это исправит?
Пакетная задача с упором в CPU работает часами. Её можно доставить как скомпилированный C или как интерпретируемый скрипт Python. Не считая трудозатрат на разработку, что считает быстрее во время исполнения и почему?
Сервис на Node.js первые несколько секунд под нагрузкой медленный, затем ускоряется и остаётся быстрым. Какой механизм это объясняет и баг ли это?
Джуниор говорит: «runtime — это просто другое название операционной системы». Почему это неверно?
Ты нажимаешь Run на программе на C. Какой порядок стадий конвейера верный?
Весь юнит — одна лестница. Assembly называет machine code по одной инструкции; высокоуровневые языки позволяют одному оператору обозначать много инструкций и оставаться переносимыми между CPU; compiler транслирует всю программу заранее, а interpreter — оператор за оператором во время исполнения, JIT же смешивает оба, компилируя hot spot’ы на лету; runtime (GC, call stack, стандартная библиотека, VM) поддерживает твой код всё время; а полный конвейер — исходник → трансляция → линковка → загрузка → старт runtime → fetch-decode-execute — доносит каждую программу до CPU, который никогда не знает, с какого языка она пришла.