5 min read
CS Fundamentals Index
Tier 1 -- Foundations
Object-Oriented Programming
Tier 2 -- Core Concepts
Tier 3 -- Debugging & Tradeoffs
CS Fundamentals Index
Tier 1 -- Foundations
Object-Oriented Programming
Tier 2 -- Core Concepts
Tier 3 -- Debugging & Tradeoffs
Variables & Memory
1. What Is It?
A is a name bound to a value stored somewhere in memory. When you write x = 10, you're telling the language: reserve space for the number 10 and give me a way to refer to it as x. Without variables, you'd have to re-compute or re-read every value every time you needed it — and you'd have no way to express "the thing I just calculated" in a program.
What goes wrong without a clean mental model: you get surprised when two variables seem to point at the same data, when a value changes "by itself," or when code runs slower than expected because values are being copied instead of referenced. These are memory-behavior bugs, not syntax bugs, and they only make sense once you picture where the data actually lives.
A junior developer notices that after assigning result = computeTotal(), they never call computeTotal() again, yet they use result dozens of times throughout the function. Which core benefit of variables does this pattern demonstrate?
2. How It Works
When a is introduced, three things happen:
- A name enters a (a lookup table the language uses to resolve identifiers).
- Memory is allocated somewhere — on the for small fixed-size data, on the for dynamically-sized or longer-lived data.
- The name is bound to that memory, either directly (the name is the slot) or indirectly (the name holds a /pointer to the slot).
# Python x = 10 # x is a name bound to an int object in Python's managed memory y = x # y binds to the SAME object; no copy x = 11 # x now binds to a different int object; y is unchanged print(y) # 10
(Small ints like 10 are cached by CPython, so the already exists — but the mental model "the name points at an " is what matters here.)
// Java int x = 10; // x is a stack slot holding the int 10 directly (primitive) int y = x; // y is a new stack slot; value 10 is COPIED x = 11; System.out.println(y); // 10 String a = "hi"; // a is a stack slot holding a reference to a String object on the heap String b = a; // b holds the SAME reference; no String copy
// C++ int x = 10; // x is a stack slot holding the int 10 directly int y = x; // y is a new stack slot; value 10 is COPIED int& z = x; // z is a reference — another name for x's slot z = 99; // x is now 99 int* p = new int(5); // p on stack, int on heap; manual lifetime delete p; // you must free it
In a backend service written in Python, a developer writes the following code:
What does this print, and why?config = {'timeout': 30} cached = config config['timeout'] = 60 print(cached['timeout'])
3. What You Actually Need to Know
- Assignment is not always a copy. In Python and Java (for objects), assignment copies the , not the data. In C++,
=copies the value by default — which can be expensive for large objects. - "Uninitialized" means different things. In C++, a local
int x;holds garbage — reading it is undefined behavior. In Java, local variables must be assigned before use (compiler error); instance fields default to 0/null. In Python, a name that was never assigned raisesNameError. - controls lifetime (mostly). A declared inside
{ }in Java/C++ stops existing when that block ends. In Python, function-local names disappear when the function returns. But if something else still references the (not the name), the itself survives. - Common error signals:
NameError: name 'x' is not defined(Python) — you misspelled a name or used it before assignment.error: use of uninitialized(C++ compilers with warnings on) — declared but never set.NullPointerException(Java) — variable holds a , but the is null.- Mysterious value changes across functions — you passed a and the callee mutated the shared .
A Python backend service has a function that receives a list object, appends an item to it, and returns. After the function returns, the caller notices the original list has been modified. What is the most likely explanation for this behavior?
4. Language Differences
| Aspect | Python | Java | C++ |
|---|---|---|---|
| Must declare type? | No | Yes | Yes (or auto) |
| Primitive-vs-reference split? | No — everything is an object reference | Yes — primitives (int, double) vs. reference types | Yes — value types vs. pointers/references |
| Default memory for "small" data | Heap (boxed int objects) | Stack (primitives) | Stack |
| Who frees memory? | Garbage collector | Garbage collector | You do (via delete, smart pointers, or RAII) |
| Can a name be rebound? | Yes, freely | Yes (unless final) | Yes (unless const); references cannot be rebound |
The key divergence: Python has no "" in the C sense — every name is a to an . Java splits the world in two (primitives are values, objects are references). C++ gives you full control and full responsibility.
A backend team is debugging a memory leak in a long-running API server. In Python, they notice that objects are cleaned up automatically without any explicit deallocation code, while a C++ port of the same service requires careful manual cleanup after each request cycle. Which fundamental difference between the two languages explains this behavior?
5. Tradeoffs & Decisions
- Value semantics vs. semantics. If two variables should always move in lockstep, you want semantics. If changes to one must not leak to the other, you want value semantics. Python/Java force reference semantics for objects; C++ lets you pick (
T,T&,T*,std::shared_ptr<T>). - vs. allocation. is fast and auto-freed but fixed in size and tied to . is flexible but slower and needs cleanup. In C++ you decide; in Java/Python the runtime decides for you (objects on heap, primitives/locals on stack).
- Re-assignment vs. immutability.
const(C++),final(Java), and convention-based constants in Python prevent accidental rebinding. Use them when a represents a fixed configuration or when you want the compiler to catch logic bugs.
If you see mysterious shared mutation, it usually means two names reference the same . You'd choose a copy (or an type) when isolation matters more than memory.
You're building a backend service where a configuration object is created once at startup and passed to multiple handler functions. You want the compiler or runtime to prevent any handler from accidentally reassigning the configuration reference. Which approach best achieves this goal in C++ and Java respectively?
6. Interview Cheat Sheet
- A is a named binding to a value in memory — the name lives in a , the value lives in a memory region ( or ).
- Assignment semantics differ by language and type. Python and Java variables copy references; Java primitives and C++ values copy the data itself.
- Lifetime is -driven for locals, -count- or GC-driven for objects. The name disappears when its scope ends; the disappears when nothing references it (GC languages) or when you free it (C++).
- In C++, uninitialized locals hold garbage; reading them is undefined behavior. Java forbids it at compile time; Python throws
NameErrorat runtime.
Follow-ups:
- "What happens when you do
b = ain Python?" — Both names bind to the same object; no copy. - "Where do Java primitives live?" — On the (for locals) or inline in the enclosing object (for fields), not as separate heap objects.
- "Why would you prefer a over a copy?" — Avoid duplicating large data and keep a single source of truth; cost is shared mutation risk.
Glossary History
Click dotted jargon to save explanations here.
Glossary History
Click dotted jargon to save explanations here.