What Is Programming?
Programming is the act of writing precise, unambiguous instructions that a computer can carry out. Everything else in computer science — languages, compilers, operating systems, algorithms — exists to make that act easier, safer, or faster.
A computer only understands electrical signals representing 0s and 1s — binary. A program is a sequence of instructions, written in that binary form (machine code), that tells the CPU exactly what to do, step by step. Source code is the human-readable text a programmer writes; it gets translated into machine code before the CPU can run it.
Humans think in words, logic and math, not in streams of 0s and 1s. Programming languages let a person describe a task in a structured, readable way, and a translator (a compiler or interpreter) converts that description into the binary instructions the hardware actually executes.
Every piece of software you touch — a phone app, a website, a game, a car's engine control unit, a washing machine's controller — is the output of programming. An algorithm is the plan ("how to solve the problem"); a program is that plan expressed in a language the computer can eventually execute.
Think of a recipe. The recipe (algorithm) describes the steps to bake a cake in a language a cook understands. Source code is that recipe written in a specific cookbook's notation. The kitchen (CPU) doesn't read English — someone (the compiler/interpreter) has to translate the recipe into exact physical actions: measure, mix, heat to 180°C for 25 minutes.
The algorithm is language-independent — it's just a plan. The C code is one concrete implementation of that plan, written in a syntax the C compiler understands.
A program is a static file (or set of files) containing instructions; a process is that program actually running in memory — the same program can be one file but many simultaneous processes.
Source code → machine code is a translation problem. Different languages solve it differently: full ahead-of-time compilation, interpretation line-by-line, or a hybrid (bytecode + a virtual machine, discussed in the Execution Models section).
An instruction is the smallest unit of work a CPU understands — e.g. "add these two register values," "load this memory address," "jump to this location." Programs decompose into thousands to billions of these.
Binary is just base-2 counting (0 and 1). Machine code is binary that specifically encodes CPU instructions and their operands using an Instruction Set Architecture (ISA) — the CPU's own "vocabulary."
An algorithm is correct or incorrect independent of any programming language; a program is also judged on correctness, but additionally on readability, performance, memory use and maintainability.
Confusing "a program" with "an algorithm" — an algorithm has no bugs of syntax; only its logic can be right or wrong.
Assuming all source code is 'compiled the same way' — compiled, interpreted and hybrid languages behave very differently at runtime (see the next section).
Treating pseudocode as if it were executable — it isn't; it's a planning tool, not a language a computer can run directly.
Believing higher-level code 'skips' machine code entirely — even interpreted languages eventually reduce to machine instructions somewhere in their runtime.
Writing an algorithm on paper (or a whiteboard, in interviews) before touching a keyboard — this separates 'is my logic right' from 'is my syntax right.'
Debugging by asking, at each step: what instruction is actually executing right now, and does it match my intended algorithm?
Reading a stack trace or assembly dump when something crashes at a low level — an unavoidable skill in systems and embedded work.
Programs vs. processes vs. threads A program is inert data on disk. A process is an instance of that program loaded into memory with its own address space, given resources by the OS (memory, file handles, a process ID). A thread is a unit of execution within a process; multiple threads share the same address space but each has its own stack and register state. This distinction becomes central in the Memory & Program Execution and Concurrency modules.
Binary encodings aren't unique The same source instruction can compile to different binary machine code depending on the target CPU architecture (x86-64, ARM, RISC-V), the compiler, its version, and the optimization level requested. There is no single canonical machine code for a given piece of source — this is a recurring theme throughout the compiler and code-generation modules.
A programming language (or even something not designed as one, like CSS or a spreadsheet) is Turing-complete if it can, in principle, compute anything any other Turing-complete system can, given enough memory and time. Most general-purpose languages are Turing-complete; some intentionally restricted languages (regular expressions, many templating languages) are not, by design, to keep them analyzable and safe.
Instructions are architecture-specific "Add two numbers" is not one universal binary pattern — x86-64, ARM and RISC-V each define their own opcode for addition, their own register names, and their own encoding rules. A compiler's back end is precisely the component responsible for bridging a language's abstract operations to one specific ISA's actual instruction encoding.
What is the difference between a program and a process?
A program is a static, stored set of instructions (a file). A process is that program loaded into memory and actually executing, with its own allocated resources — memory space, process ID, open file handles, and execution state.
Is an algorithm the same thing as code?
No. An algorithm is a language-independent, abstract description of a solution's steps. Code is one specific implementation of that algorithm in a particular programming language's syntax.
Why can't the CPU run source code directly?
The CPU only executes machine code — binary instructions matching its specific instruction set architecture (ISA). Source code is human-readable text; it must be translated (compiled and/or interpreted) into that binary form first.
Is every programming language Turing-complete?
No. Most general-purpose languages are, but some domain-specific languages (regular expressions, many configuration or templating languages) are deliberately not Turing-complete, trading expressive power for guaranteed termination and easier static analysis.
Algorithm (plain English):
1. Take two numbers
2. Add them
3. Show the result
Same algorithm as C code:
int a = 5;
int b = 7;
int sum = a + b;
printf("%d", sum);