Python Interview Questions 2026: Freshers to 10 Years, Answers, Internals, Async and Coding Rounds
Python interview guide: round pattern, core language and data types, mutability, generators, decorators, the GIL, memory, concurrency and asyncio, Django and FastAPI, testing and coding problems with expected answers.
How to use this guide
This guide covers Python from core language to production. Each question has the expected answer and the reason it matters. Practise the coding questions in a plain editor without autocomplete, because most rounds run that way.
The answers follow the official language behaviour in current CPython 3 releases. Where a detail changed across versions, the guide says so.
What the interview pattern usually looks like
| Round | What is tested | Typical length |
|---|---|---|
| Screening | Output prediction, basic lists and dictionaries | 30 minutes |
| Coding | Two or three problems with strings, arrays and hashing | 45 to 60 minutes |
| Language depth | Mutability, decorators, generators, the GIL, memory | 45 minutes |
| Framework | Django, FastAPI, ORM, REST design | 45 minutes |
| Design or project | Your project, trade-offs, testing | 45 minutes |
| Manager | Teamwork, ownership, handover | 30 minutes |
Service companies test coding and language basics heavily. Product companies test design, concurrency and debugging.
Level 1: Core Python
Q1. What are the built-in data types, and which are mutable?
Immutable: int, float, str, tuple, frozenset, bytes, bool. Mutable: list, dict, set, bytearray. Mutability decides whether a function can change the caller's object.
Q2. What is the difference between is and ==?
== compares values. is compares identity, meaning whether two names point to the same object. Use is for None and singletons, and == for values.
Q3. What is a mutable default argument, and why is it a bug?
def add_item(item, bucket=[]):
bucket.append(item)
return bucket
add_item(1) # [1]
add_item(2) # [1, 2], the same list is reused
The default is created once, when the function is defined. Use None and create the list inside the function.
Q4. What is the difference between shallow and deep copy?
copy.copy creates a new outer object, but nested objects are shared. copy.deepcopy copies nested objects too. Know that slicing and list(...) make shallow copies.
Q5. What are list comprehensions, and when would you avoid them?
They build a list in one expression. Avoid them when the logic needs several statements or when a generator expression is enough, because a comprehension builds the whole list in memory.
Q6. What does *args and **kwargs mean?
*args collects extra positional arguments as a tuple. **kwargs collects extra keyword arguments as a dictionary. The unpacking operators work the same way in calls.
Q7. What is the difference between a list and a tuple?
A list is mutable and is used for a sequence that changes. A tuple is immutable and is used for a fixed record, and it can be a dictionary key. Tuples are slightly faster and signal intent.
Q8. How does the in operator perform on a list, a set and a dictionary?
On a list it scans, O(n). On a set or a dictionary key, it uses a hash, O(1) on average. Use a set for membership tests on large data.
Q9. What is None, and how do you check for it?
None is the singleton value for "no value". Check it with is None. Use if x: only when you want to treat empty values and zero as false too.
Q10. What is string interning, and does it matter?
CPython reuses some strings, such as short identifiers. Do not depend on is for string comparison. Use ==.
Level 2: Functions, generators and decorators
Q11. What is a generator, and how does it differ from a list?
A generator yields values one at a time and keeps its state between calls. It uses little memory for large sequences. A list holds every value at once.
def read_big_file(path):
with open(path) as f:
for line in f:
yield line.rstrip("\n")
Q12. What is a decorator? Write one that logs the call time.
A decorator takes a function and returns a new function that wraps it.
import functools
import time
def timed(fn):
@functools.wraps(fn)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = fn(*args, **kwargs)
print(f"{fn.__name__} took {time.perf_counter() - start:.3f}s")
return result
return wrapper
Mention functools.wraps, which keeps the original name and docstring.
Q13. What is a closure in Python?
A nested function that keeps a reference to variables from the enclosing scope. Use nonlocal to rebind such a variable inside the inner function.
Q14. What are lambda functions, and when are they limited?
Anonymous single-expression functions. Use them for short key functions in sorted or map. Use a named function for anything that needs a statement, a docstring or a test.
Q15. What is the difference between map, filter and a comprehension?
They do the same job in different styles. Comprehensions are usually clearer in Python. map and filter return iterators in Python 3.
Q16. What is yield from?
It delegates iteration to another iterable or generator. It also passes sends and throws through to the sub-generator.
Q17. What are context managers?
Objects that set up and tear down a resource with with. Implement __enter__ and __exit__, or use contextlib.contextmanager. They make sure files and locks are released even when an error occurs.
Level 3: OOP and data structures
Q18. What are __init__, __str__ and __repr__?
__init__ initialises an instance. __str__ gives a readable string for users, used by print. __repr__ gives an unambiguous string for developers, ideally one that could recreate the object. Define __repr__ at least.
Q19. What is the difference between a class attribute and an instance attribute?
A class attribute is shared by all instances. An instance attribute belongs to one object. Assigning through self creates an instance attribute that hides the class one.
Q20. What are @staticmethod, @classmethod and a regular method?
A regular method gets the instance as self. A class method gets the class as cls, which is useful for alternative constructors. A static method gets neither, and is a function namespaced in the class.
Q21. What is a dataclass?
A class decorator that generates __init__, __repr__ and comparison methods from annotated fields. Use it for plain data records.
from dataclasses import dataclass
@dataclass(frozen=True)
class Point:
x: int
y: int
Q22. What is inheritance and the method resolution order?
A subclass reuses the parent's methods. For multiple inheritance, Python follows C3 linearisation, visible through ClassName.__mro__. Prefer composition when classes do not share a clear is-a relationship.
Q23. What are abstract base classes?
Classes from abc that define methods subclasses must implement. Use them to document and enforce an interface, for example a storage backend with save and load.
Q24. Which data structure would you use for a frequency count, an LRU cache and a priority queue?
Frequency count: collections.Counter. LRU cache: collections.OrderedDict with move-to-end, or functools.lru_cache for function results. Priority queue: heapq, which is a min-heap over a list.
Level 4: Internals, the GIL and memory
Q25. What is the Global Interpreter Lock?
A mutex in CPython that allows only one thread to execute Python bytecode at a time. Threads still help with I/O, because the lock is released while waiting on I/O. CPU-bound work does not speed up with threads. Use multiprocessing, or a native extension that releases the GIL.
Q26. How does memory management work in CPython?
Reference counting frees an object when its count reaches zero. A cyclic garbage collector finds reference cycles. Small integers and interned strings are shared. Large objects go to the operating system's allocator.
Q27. What is a memory leak in Python, and how do you find one?
Objects kept alive by a reference that is never released, such as a global cache that grows without a limit, or a closure that holds a large object. Use tracemalloc or a profiler to compare snapshots over time.
Q28. How do you make a slow Python function faster?
Measure first with cProfile or timeit. Then use a better algorithm or data structure, such as a set instead of a list for membership. Cache repeated work with lru_cache. Use vectorised operations in NumPy or pandas for numeric loops. Use a compiled library only after measuring.
Q29. What is __slots__?
It stops the instance from storing a dictionary for attributes, which reduces memory for many small objects. The trade-off is that you cannot add arbitrary attributes.
Level 5: Concurrency and asyncio
Q30. When do you use threads, processes and asyncio?
- Threads: many I/O-bound tasks that use blocking libraries.
- Processes: CPU-bound work that needs multiple cores.
- asyncio: many I/O-bound tasks with async-capable libraries, such as HTTP clients and async database drivers.
Q31. What is the difference between async def and a regular function?
Calling an async def function returns a coroutine. It runs only when awaited or scheduled. Inside it, await yields control to the event loop while waiting.
import asyncio
async def fetch(n):
await asyncio.sleep(1)
return n * 2
async def main():
results = await asyncio.gather(*(fetch(i) for i in range(3)))
print(results)
asyncio.run(main())
Q32. What goes wrong if you call a blocking function inside asyncio?
The event loop stops, and every other task waits. Move blocking calls to a thread with asyncio.to_thread, or use an async library.
Q33. How do you protect shared data between threads?
Use threading.Lock around the critical section, or use queue.Queue, which handles the locking for you. Keep critical sections short.
Level 6: Web frameworks and APIs
Q34. What is the difference between Django and FastAPI?
Django is a full framework with an ORM, an admin site, authentication and migrations. It suits full web applications. FastAPI is a lighter framework for APIs, with async support, type hints for validation and automatic documentation. It suits services and APIs.
Q35. How does Django's ORM avoid the N+1 query problem?
Use select_related for foreign keys and prefetch_related for many-to-many and reverse relations. Check the SQL with the debug toolbar or query logging.
Q36. How do you validate input in FastAPI?
Use Pydantic models as request bodies. The framework validates types and returns a 422 response with details when the input is wrong.
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Order(BaseModel):
item: str
quantity: int = Field(gt=0)
@app.post("/orders")
async def create_order(order: Order):
return {"status": "accepted", "item": order.item}
Q37. How would you secure a Python API?
Authenticate with tokens, check authorisation for every object access, validate input, hash passwords with bcrypt or argon2 through a library, set secure headers, rate limit login routes, and keep secrets out of code.
Q38. How do you handle database migrations?
Use a migration tool, such as Django migrations or Alembic. Make changes backward compatible in steps, as described for zero-downtime deploys. Review generated migrations before applying.
Level 7: Testing, packaging and production
Q39. How do you test Python code?
Use pytest for unit tests with plain asserts and fixtures. Mock external calls at the boundary with unittest.mock. Use parametrised tests for many input cases. Measure coverage, but use it as a guide, not a target.
Q40. What is a virtual environment, and why use one?
An isolated set of packages for one project, so versions do not clash. Create it with python -m venv, and pin dependencies in a lock file or requirements.txt.
Q41. How do you log in a production Python service?
Use the logging module with structured output, a clear level for each message, and a request identifier in each line. Do not use print in services. Avoid logging secrets and personal data.
Q42. What is the difference between except Exception and a bare except:?
A bare except: also catches KeyboardInterrupt and SystemExit, which should usually stop the program. Catch the specific exception you can handle, or Exception at a boundary where you log and return an error.
Q43. How do you handle type hints?
Annotate public functions and run a type checker such as mypy or pyright in the pipeline. Hints are not enforced at run time, so validate data at the boundary with a library such as Pydantic.
Coding questions asked in Python rounds
Solve these without a library unless the question allows it. State the complexity.
C1. Check whether two strings are anagrams.
Compare sorted characters for a short solution, O(n log n). For the best time, count characters with Counter in O(n).
from collections import Counter
def is_anagram(a, b):
return Counter(a) == Counter(b)
C2. Find the first non-repeating character in a string.
Count each character, then scan the string again and return the first with count one. O(n) time.
C3. Given a sorted list, find two numbers that add up to a target.
Use two pointers, one at each end. Move the left pointer up if the sum is too small, and the right pointer down if it is too big. O(n) time, O(1) extra space.
C4. Find the longest substring without repeating characters.
Use a sliding window with a dictionary that stores the last index of each character. Move the left edge past any repeat. O(n) time.
def longest_unique(s):
last = {}
left = best = 0
for right, ch in enumerate(s):
if ch in last and last[ch] >= left:
left = last[ch] + 1
last[ch] = right
best = max(best, right - left + 1)
return best
C5. Merge overlapping intervals.
Sort by the start value. Walk the list, extending the last merged interval when the next one starts before it ends.
C6. Design a small class for a bank account with deposit, withdraw and a balance that cannot go negative.
Raise a clear error on an invalid operation. Keep the balance private and expose it as a read-only property. Write one test per rule.
class Account:
def __init__(self, balance=0):
self._balance = balance
@property
def balance(self):
return self._balance
def deposit(self, amount):
if amount <= 0:
raise ValueError("deposit must be positive")
self._balance += amount
def withdraw(self, amount):
if amount <= 0 or amount > self._balance:
raise ValueError("invalid withdrawal")
self._balance -= amount
How to answer 'explain a project'
Prepare three minutes:
- The problem and who uses the output.
- Your part and the design choice you made.
- The data or request flow, and where it could fail.
- Testing: what you tested and what you did not.
- One performance or bug fix, with the measurement that showed it.
Be ready for a follow-up on any library you name, because interviewers ask how it works.
Common mistakes
- Mutable default arguments. Use
None. - Calling blocking code inside
asyncfunctions. It freezes the whole loop. - Expecting threads to speed up CPU work. Use processes.
- Catching every exception and hiding it. Catch what you can handle.
- Using
isfor values. Use==. - Writing a long solution without testing edge cases. Test empty input, one element, and duplicates.
A four-week preparation plan
| Week | Focus | Output |
|---|---|---|
| 1 | Core types, comprehensions, functions, mutability | Predict twenty output snippets |
| 2 | Generators, decorators, OOP, dataclasses | Write a small module with tests |
| 3 | Concurrency, asyncio, GIL, memory | Explain when you choose each model |
| 4 | Framework and coding rounds | Build a small FastAPI service and solve C1 to C6 |
Frequently asked questions
Should I learn Django or FastAPI first? Learn the one your target companies use. Django is common in product and enterprise teams, and FastAPI is common for new APIs.
Is the GIL something I must explain in depth? Explain the effect on threads and when to use processes. The internals are a bonus.
What if I have only done data work in Python? Show a small API or a command-line tool with tests. Interviewers want evidence that you can write and maintain code beyond notebooks.
Frequently Asked Questions
Python 3.10 and later. Know match statements, type hints, dataclasses and f-strings. State the version you are answering for.
For backend roles, yes. Django suits full web apps with an ORM and admin. FastAPI suits APIs with async and type-based validation. Know one well.
Mutable default arguments, shallow copies, and the difference between is and ==. Expect at least one question on each.
It limits CPU-bound threads. For I/O-bound work, threads and asyncio are fine. For CPU-bound work, use multiprocessing or a library that releases the GIL.
String and list manipulation, dictionaries and counters, two-pointer and sliding-window problems, and a small class design task.
Keshav founded StudentUpdate.in and edits every recruitment notice, syllabus page and practice set the site publishes. Each notice is read from the issuing body's PDF or portal before it goes live; dates, fees, vacancy tables and eligibility rules are copied from that document, not from other websites.