Also known as: bytecode
Bytecode is a compact, portable instruction set that sits between human-readable source and raw machine code: a compiler produces it, and a virtual machine (VM) executes it rather than the CPU running it directly.1
How it works
Rather than emit instructions for a specific processor, the compiler emits bytecode — a low-level program for an idealized, abstract machine. At run time the VM reads that bytecode and either interprets it or, with JIT compilation, translates the hot parts to native code. Because the bytecode targets the VM and not the hardware, the same bytecode file runs unchanged on any platform where the VM is available.1
Trade-offs
The big win is portability: you ship one set of bytecode and it runs anywhere the VM is installed, sidestepping the per-platform builds that native compilation requires. The cost is the VM layer — interpreting bytecode adds overhead, and the user must have the runtime installed rather than a self-contained static binary. Bytecode is also more compact and faster to load than re-parsing source each time.1
In practice
Java and other JVM languages compile to JVM bytecode;
Python caches .pyc bytecode for its VM; and
C# and the rest of .NET compile to an intermediate
language (IL). This bytecode-plus-VM design is what lets these languages promise
“write once, run anywhere.”