Python Interview Preparation
# Python Interview Preparation
Welcome to Chapter 29! This chapter prepares you for Python interviews at all levels — from junior developer to senior positions. We cover conceptual questions, coding challenges, and debugging tasks.
---
1. Learning Objectives
- Answer common Python interview questions confidently.
- Solve coding challenges with optimal solutions.
- Understand Python internals.
- Debug common errors efficiently.
- Apply best practices in interviews.
---
2. Top 50 Interview Questions
Fundamentals (Q1-Q10)
Q1: What is Python? Why is it popular? Python is a high-level, interpreted, dynamically-typed language known for readability, extensive libraries, and versatility in web dev, data science, and AI.
Q2: Mutable vs Immutable types? Mutable: list, dict, set (can be changed). Immutable: int, float, str, tuple, frozenset (cannot be changed after creation).
Q3: What is self in Python?
Reference to the current instance of a class, used to access instance variables and methods.
Q4: What are *args and kwargs?
*args collects extra positional arguments as a tuple. kwargs collects extra keyword arguments as a dict.
Q5: List vs Tuple?
Lists are mutable, use []. Tuples are immutable, use (). Tuples are faster and can be dict keys.
Q6: What is a lambda function?
An anonymous, single-expression function: lambda x: x * 2.
Q7: What is list comprehension?
Concise syntax to create lists: [x2 for x in range(10) if x % 2 == 0].
Q8: What is PEP 8? Python's official style guide covering naming, indentation (4 spaces), line length (79 chars), and formatting.
Q9: What is _init?
The constructor method called when an object is created from a class.
Q10: What is the GIL? Global Interpreter Lock — prevents multiple threads from executing Python bytecode simultaneously. Limits true parallelism in CPython.
Intermediate (Q11-Q25)
Q11: Deep copy vs shallow copy?
Shallow copy copies references. Deep copy recursively copies all objects. Use copy.deepcopy().
Q12: What are decorators? Functions that wrap other functions to add behavior without modifying source code.
Q13: What are generators?
Functions using yield that produce values lazily, one at a time, saving memory.
Q14: is vs ==?
== checks value equality. is checks identity (same object in memory).
Q15: What is duck typing? Python doesn't check types; it checks behavior. "If it walks like a duck..."
Q16: How does Python manage memory? Reference counting + cyclic garbage collector. Objects are deallocated when reference count reaches zero.
Q17: What is a closure? A function that remembers the variables from its enclosing scope even after the outer function has returned.
Q18: @staticmethod vs @classmethod?
@staticmethod has no access to class/instance. @classmethod receives cls parameter.
Q19: What is monkey patching? Dynamically modifying a class or module at runtime. Useful but can be dangerous.
Q20: What are magic/dunder methods?
Special methods like init, str, add that customize class behavior.
Q21: What is a context manager?
An object with enter and exit methods, used with with for resource management.
Q22: How to handle exceptions?
try/except/else/finally. Catch specific exceptions, use custom exceptions for domain errors.
Q23: map() vs list comprehension?
Both transform data. List comprehensions are more Pythonic and readable.
Q24: What is name == "main"?
Checks if the script is run directly (not imported). Guards executable code.
Q25: What are slots?
slots restricts instance attributes to declared names, saving memory.
Advanced (Q26-Q50)
Q26: What are metaclasses?
Classes of classes. They control class creation. type is the default metaclass.
Q27: What is the MRO? Method Resolution Order — the order Python searches for methods in class hierarchy (C3 linearization).
Q28: What are descriptors?
Objects implementing get, set, or delete. Properties are descriptors.
Q29: How does Python's import system work?
Searches sys.path, checks sys.modules cache, loads module, caches for future imports.
Q30: What is asyncio?
Library for asynchronous programming using async/await syntax for concurrent I/O operations.
Q31: Concurrency vs Parallelism? Concurrency: managing multiple tasks (asyncio, threading). Parallelism: executing simultaneously (multiprocessing).
Q32: What are dataclasses?
@dataclass decorator auto-generates init, repr, eq for classes.
Q33: What is functools.lrucache?
Memoization decorator that caches function results for speed.
Q34: What is the Walrus operator?
:= assigns and returns a value in an expression (Python 3.8+).
Q35: Difference between _str and repr?
str is for users (readable). repr is for developers (unambiguous).
Q36-Q50:** See coding exercises below for practical questions.
---
3. Coding Exercises (20 Problems)
Easy Level
```python id="py29ex1" # 1. Reverse a string def reversestring(s): return s[::-1] print(reversestring("Python")) # nohtyP
# 2. Check palindrome def ispalindrome(s): s = s.lower().replace(" ", "") return s == s[::-1] print(ispalindrome("racecar")) # True
# 3. FizzBuzz def fizzbuzz(n): for i in range(1, n + 1): if i % 15 == 0: print("FizzBuzz", end=" ") elif i % 3 == 0: print("Fizz", end=" ") elif i % 5 == 0: print("Buzz", end=" ") else: print(i, end=" ") fizzbuzz(20) print()
# 4. Count vowels def countvowels(s): return sum(1 for c in s.lower() if c in "aeiou") print(countvowels("Hello World")) # 3
# 5. Find duplicates def findduplicates(lst): seen = set() dupes = set() for item in lst: if item in seen: dupes.add(item) seen.add(item) return list(dupes) print(findduplicates([1, 2, 3, 2, 4, 3, 5])) # [2, 3]
python id="py29ex2" # 6. Two Sum def twosum(nums, target): seen = {} for i, num in enumerate(nums): complement = target - num if complement in seen: return [seen[complement], i] seen[num] = i return [] print(twosum([2, 7, 11, 15], 9)) # [0, 1]
# 7. Anagram check def isanagram(s1, s2): return sorted(s1.lower()) == sorted(s2.lower()) print(isanagram("listen", "silent")) # True
# 8. Flatten nested list def flatten(lst): result = [] for item in lst: if isinstance(item, list): result.extend(flatten(item)) else: result.append(item) return result print(flatten([1, [2, [3, 4], 5], 6])) # [1, 2, 3, 4, 5, 6]
# 9. Second largest number def secondlargest(nums): unique = list(set(nums)) unique.sort() return unique[-2] if len(unique) >= 2 else None print(secondlargest([10, 5, 20, 15])) # 15
# 10. Group anagrams from collections import defaultdict def groupanagrams(words): groups = defaultdict(list) for word in words: key = ''.join(sorted(word)) groups[key].append(word) return list(groups.values()) print(group_anagrams(["eat", "tea", "tan", "ate", "nat", "bat"]))
python id="py29ex3" # 11. Fibonacci with memoization from functools import lrucache
@lrucache(maxsize=None) def fib(n): if n <= 1: return n return fib(n-1) + fib(n-2) print([fib(i) for i in range(10)])
# 12. Binary search def binarysearch(arr, target): left, right = 0, len(arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: return mid elif arr[mid] < target: left = mid + 1 else: right = mid - 1 return -1 print(binarysearch([1, 3, 5, 7, 9, 11], 7)) # 3
# 13. Matrix rotation (90 degrees clockwise) def rotatematrix(matrix): n = len(matrix) return [[matrix[n-1-j][i] for j in range(n)] for i in range(n)] m = [[1,2,3],[4,5,6],[7,8,9]] print(rotatematrix(m))
# 14. Longest common prefix def longestcommonprefix(strs): if not strs: return "" prefix = strs[0] for s in strs[1:]: while not s.startswith(prefix): prefix = prefix[:-1] if not prefix: return "" return prefix print(longestcommonprefix(["flower", "flow", "flight"])) # fl
# 15. Valid parentheses def isvalidparens(s): stack = [] mapping = {")": "(", "}": "{", "]": "["} for char in s: if char in mapping: if not stack or stack[-1] != mapping[char]: return False stack.pop() else: stack.append(char) return not stack print(isvalidparens("({[]})")) # True print(isvalid_parens("({[})")) # False
python id="py29ex4" # 16. Merge sorted arrays def mergesorted(a, b): result, i, j = [], 0, 0 while i < len(a) and j < len(b): if a[i] <= b[j]: result.append(a[i]); i += 1 else: result.append(b[j]); j += 1 result.extend(a[i:]) result.extend(b[j:]) return result print(mergesorted([1,3,5], [2,4,6])) # [1,2,3,4,5,6]
# 17. Remove duplicates from sorted list def removedupes(nums): return list(dict.fromkeys(nums)) print(removedupes([1,1,2,2,3,4,4,5])) # [1,2,3,4,5]
# 18. Power set def powerset(s): if not s: return [[]] rest = powerset(s[1:]) return rest + [[s[0]] + subset for subset in rest] print(powerset([1,2,3]))
# 19. Implement stack class Stack: def _init(self): self.items = [] def push(self, item): self.items.append(item) def pop(self): return self.items.pop() if self.items else None def peek(self): return self.items[-1] if self.items else None def isempty(self): return len(self.items) == 0 def size(self): return len(self.items)
# 20. Count words in string def wordfrequency(text): words = text.lower().split() freq = {} for word in words: word = word.strip(".,!?") freq[word] = freq.get(word, 0) + 1 return dict(sorted(freq.items(), key=lambda x: -x[1])) print(wordfrequency("the cat sat on the mat the cat"))
python id="py29ex5" # Common debugging approaches
# 1. Print debugging def buggyfunction(data): print(f"DEBUG: data = {data}, type = {type(data)}") # ... rest of function
# 2. Using breakpoint() (Python 3.7+) def complexfunction(x): result = x * 2 # breakpoint() # Drops into pdb debugger return result + 1
# 3. Using assert def divide(a, b): assert b != 0, "Divisor cannot be zero!" return a / b
# 4. Using logging import logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(name)
def processdata(data):
logger.debug(f"Processing: {data}")
logger.info("Data processed successfully")
logger.warning("This is a warning")
``
---
5. Common Pitfalls
-
1.
Mutable default arguments: def f(lst=[])
→ shared across calls.
- 2. Late binding closures: Lambda in loop captures variable by reference.
-
3.
Integer caching: Python caches -5 to 256; is
may give unexpected results for larger ints.
-
4.
String concatenation in loops: Use ''.join()
instead of+=.
-
5.
Not using if _name == "main_":
— Code runs on import.
---
6. MCQs with Answers
Q1: Time complexity of dict lookup?
A) O(n) B) O(log n) C) O(1) average D) O(n²)
Answer: C
Q2: What does enumerate() return?
A) Values B) Indices C) (index, value) pairs D) Keys
Answer: C
Q3: [1] * 3 produces:
A) [3] B) [1, 1, 1] C) [1, 3] D) Error
Answer: B
Q4: "hello"[1::-1] returns:
A) "eh" B) "he" C) "hel" D) "ol"
Answer: A — Start at index 1, go backwards.
Q5: What is collections.Counter?
A) Loop counter B) Dict subclass for counting hashable objects C) Timer D) Iterator
Answer: B
Q6: any([False, False, True]) returns:
A) True B) False C) [True] D) Error
Answer: A
Q7: zip([1,2], [3,4,5]) produces:
A) [(1,3),(2,4),(None,5)] B) [(1,3),(2,4)] C) Error D) [(1,3,5),(2,4)]
Answer: B — Stops at shortest.
Q8: globals() returns:
A) Local variables B) Global variables dict C) Built-in functions D) Module list
Answer: B
Q9: isinstance(True, int) returns:
A) True B) False
Answer: A — bool is a subclass of int.
Q10: Space complexity of set` lookup? A) O(1) B) O(n) C) O(log n) D) O(n²) Answer: B — Set stores n elements → O(n) space.
---
7. Summary
- Prepare both conceptual knowledge and coding skills.
- Practice data structures (lists, dicts, sets) and algorithms (search, sort).
- Understand Python internals (GIL, memory management, MRO).
- Use debugging tools (print, breakpoint, logging, assert).
- Avoid common pitfalls (mutable defaults, late binding, GIL limitations).
---
8. Next Chapter Recommendation
In Chapter 30: Final Projects and Real-World Applications, you'll build complete projects to solidify everything you've learned! 🚀