Interview Prep — Python Track
Python Interview Questions
15 curated Python questions — mutability, decorators, generators, the GIL, OOP, and async. Tagged for FAANG and startups. Check off as you go.
BasicsAdvancedOOPLibraries
15Total
5Basics
5Advanced
3OOP
2Libraries
01
What are Python's mutable and immutable data types?
Python
▾
Immutable:
int, float, str, tuple, frozenset, bool — cannot be changed after creation. Changing creates a new object.
Mutable: list, dict, set — can be modified in place.
Mutable: list, dict, set — can be modified in place.
Why it matters:
Immutable objects are hashable (usable as dict keys). Mutable default function arguments are a common bug — use
None
as default instead.
python
# Bug: mutable default argument def bad(lst=[]): lst.append(1); return lst # Fix: def good(lst=None): if lst is None: lst = [] lst.append(1); return lst
02
Explain Python decorators with an example.
Python
▾
A
decorator
is a function that wraps another function to add behaviour without modifying its code — uses the
higher-order function
concept.
Common uses:
logging, authentication, caching (
python
import time def timer(func): def wrapper(*args, **kwargs): t = time.time() result = func(*args, **kwargs) print(f"Took {time.time()-t:.3f}s") return result return wrapper @timer def slow_fn(): time.sleep(0.5)
@functools.lru_cache
), rate limiting.
03
What are generators in Python? How are they different from lists?
Python
▾
Generators
are functions that yield values one at a time using
yield
, producing values lazily (on demand) instead of storing the whole sequence in memory.
python
def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b gen = fibonacci() print([next(gen) for _ in range(8)]) # [0,1,1,2,3,5,8,13]
Memory:
Generator uses O(1) space regardless of sequence length. A list would use O(n). Perfect for large datasets, file reading, streaming.
04
What is the GIL in Python and how does it affect multithreading?
Python
▾
The
GIL (Global Interpreter Lock)
is a mutex in CPython that allows only one thread to execute Python bytecode at a time, even on multi-core CPUs.
- Problem: CPU-bound multithreaded code doesn't benefit from multiple cores
- Not a problem for I/O-bound tasks — GIL is released during I/O operations (network, file, sleep)
-
Solution for CPU-bound:
Use
multiprocessing(separate processes, each with own GIL) or C extensions
Python 3.13+:
Experimental "free-threaded" mode can disable the GIL.
05
Explain list comprehension vs map/filter vs for loop — when to use what?
Python
▾
python
nums = [1,2,3,4,5] # List comprehension — Pythonic, readable, fast evens = [x for x in nums if x%2==0] # map/filter — functional, lazy, returns iterators evens = list(filter(lambda x: x%2==0, nums)) # for loop — most readable for complex logic evens = [] for x in nums: if x%2==0: evens.append(x)
for
loops for complex logic. Use
map
/
filter
when chaining with itertools or for lazy evaluation.
06
What are *args and **kwargs in Python?
Python
▾
*args
collects extra positional arguments as a
tuple
.
**kwargs
collects extra keyword arguments as a
dict
.
python
def greet(name, *args, **kwargs): print(f"Hello {name}") print(f"Extra args: {args}") print(f"Extra kwargs: {kwargs}") greet("Alice", 25, "NYC", city="Boston", active=True)
07
What is the difference between deep copy and shallow copy?
Python
▾
Shallow copy
creates a new object but inserts references to the original nested objects.
Deep copy creates a new object and recursively copies all nested objects.
Deep copy creates a new object and recursively copies all nested objects.
python
import copy lst = [[1, 2], [3, 4]] shallow = copy.copy(lst) deep = copy.deepcopy(lst) lst[0][0] = 999 print(shallow) # [[999, 2], [3, 4]] - affected! print(deep) # [[1, 2], [3, 4]] - independent
08
Explain the difference between == and is in Python.
Python
▾
==
checks
value equality
(do they have the same content?).
is
checks
reference equality
(are they the same object in memory?).
python
a = [1, 2, 3] b = [1, 2, 3] c = a print(a == b) # True (same values) print(a is b) # False (different objects) print(a is c) # True (same reference)
09
What is the difference between list and tuple? When would you use each?
Python
▾
| Aspect | List | Tuple |
|---|---|---|
| Mutability | Mutable | Immutable |
| Syntax | [1, 2, 3] |
(1, 2, 3) |
| Performance | Slower | Faster |
| Use case | Dynamic data | Fixed records, dict keys |
10
What are context managers and the 'with' statement?
Python
▾
Context managers handle resource setup and teardown automatically using
__enter__
and
__exit__
methods.
python
# Using with statement with open("file.txt") as f: data = f.read() # File automatically closed # Custom context manager from contextlib import contextmanager @contextmanager def timer(): import time start = time.time() try: yield finally: print(f"Took {time.time()-start:.3f}s")
11
What is the difference between @classmethod, @staticmethod, and instance method?
Python
▾
python
class MyClass: count = 0 def instance_method(self): # access self & class return self @classmethod def class_method(cls): # access class, not instance return cls.count @staticmethod def static_method(x): # no self or cls return x * 2
12
What are dunder (magic) methods in Python?
Python
▾
Dunder methods
(double underscore) let you define how objects behave with built-in operators and functions.
-
__init__— constructor -
__str__,__repr__— string representation -
__len__—len(obj) -
__eq__,__lt__,__gt__— comparison operators -
__add__,__mul__— arithmetic operators -
__getitem__,__setitem__— indexingobj[key] -
__iter__,__next__— make object iterable -
__enter__,__exit__— context manager protocol
13
Explain inheritance and the MRO (Method Resolution Order) in Python.
Python
▾
Python uses
C3 linearization
to determine MRO in multiple inheritance.
Use
python
class A: pass class B(A): pass class C(A): pass class D(B, C): pass print(D.__mro__) # D → B → C → A → object
help(Class)
or
Class.__mro__
to inspect the order.
14
What is the difference between range() and xrange()?
Python
▾
Python 2:
-
range()returns a list -
xrange()returns a generator (lazy evaluation)
-
range()behaves like xrange() (returns a range object, lazy) -
xrange()doesn't exist
Tip:
In Python 3, range() is memory-efficient regardless of size.
15
How do you handle exceptions in Python? Explain try, except, else, finally.
Python
▾
python
try: result = 10 / 0 except ZeroDivisionError: print("Cannot divide by zero") else: print(f"Result: {result}") # runs if no exception finally: print("Cleanup complete") # always runs
- try: Code that might raise an exception
- except: Handle specific exceptions
- else: Runs if no exception occurred
- finally: Always executes (cleanup code)
16
Find the maximum profit by buying and selling stock at different times.
Python
▾
Problem: Given stock prices with timestamps, find the maximum profit by buying at one price and selling at a later higher price.
Explanation:
python
prices = [
("2026-03-29 09:30:00", 150.25),
("2026-03-29 09:31:00", 152.10),
("2026-03-29 09:32:00", 151.80),
("2026-03-29 09:33:00", 154.50)
]
max_profit = 0
min_price = prices[0][1]
for time, price in prices[1:]:
profit = price - min_price
max_profit = max(max_profit, profit)
min_price = min(min_price, price)
print(f"{max_profit:.2f}") # 4.25
- Track running minimum price seen so far
- Calculate profit if selling at current price
- Update max_profit and min_price as we iterate
- Time: O(n) — single pass through the array
- Space: O(1) — only two variables tracked
Pattern: This is the classic "Best Time to Buy and Sell Stock" interview problem. The key insight is that you must buy before you sell, so we track the minimum price seen so far and calculate potential profit at each step.
No questions match.