These questions test foundational conceptual mastery, syntax accuracy, and core theoretical knowledge:
Q1. Explain the difference between Python list and tuple with memory implications.
Foundation • 0-2 Yrs
Lists are mutable sequences stored as dynamic over-allocated arrays in memory, allowing items to be appended or modified in-place with O(1) amortized time. Tuples are immutable and allocated with fixed memory blocks, making them faster to iterate over and usable as dictionary keys. Tuples also benefit from Python's internal memory caching (free lists).
Q2. How does memory management work in Python? Explain Reference Counting and Garbage Collection.
Foundation • 0-2 Yrs
Python utilizes two primary mechanisms: Reference Counting and a Generational Cyclic Garbage Collector. Every object maintains an ob_refcnt counter; when this reaches zero, memory is immediately deallocated. To resolve cyclic references (e.g., objects pointing to each other), Python's GC runs across three generations (0, 1, 2) based on object survival thresholds.
Q3. What are Python decorators and how do you write a function with *args and **kwargs?
Foundation • 0-2 Yrs
A decorator is a callable that takes another function as an argument, extends its behavior without altering its source code, and returns a callable. Using *args allows passing variable positional arguments as a tuple, while **kwargs allows variable keyword arguments as a dictionary, making decorators flexible across any function signature.
Q4. Differentiate between '==' and 'is' in Python with practical examples.
Foundation • 0-2 Yrs
The '==' operator evaluates value equality (comparing contents by calling the __eq__() dunder method), whereas 'is' evaluates identity equality (verifying if both references point to the exact same memory address using id()). For example, small integers (-5 to 256) are interned so 'a is b' returns True, but newly instantiated lists with identical items return False for 'is'.
Q5. What is a generator in Python and how does 'yield' differ from 'return'?
Foundation • 0-2 Yrs
A generator is a function that produces a sequence of values on demand using the 'yield' keyword instead of returning a complete list. While 'return' terminates function execution and releases local stack variables, 'yield' pauses the function, saves its execution state, and yields control back to the caller, enabling memory-efficient iteration over massive datasets.
Q6. Explain Python's LEGB rule for variable scope resolution.
Foundation • 0-2 Yrs
LEGB defines the hierarchy Python searches when resolving variable names: Local (inside current function), Enclosing (in enclosing functions for nested scopes), Global (module-level namespace), and Built-in (predefined names in the builtins module like len, range). Variables can be modified in global scope using 'global' or in enclosing scope using 'nonlocal'.
Q7. What is the difference between shallow copy and deep copy in the 'copy' module?
Foundation • 0-2 Yrs
A shallow copy (copy.copy()) constructs a new compound object and inserts references to the original object's elements; changes to nested mutable objects affect both copies. A deep copy (copy.deepcopy()) recursively duplicates all nested objects, creating an entirely independent clone with zero shared references.
Q8. How do lambda functions work and what are their limitations?
Foundation • 0-2 Yrs
Lambda functions are anonymous, inline functions created with the 'lambda' keyword, taking multiple arguments but limited to a single evaluated expression. They cannot contain statements (like assignments, loops, or try-except blocks) or annotations, and are primarily used in functional contexts like map(), filter(), and sorted(key=...).
Q9. What is the purpose of the '__init__' and '__new__' methods in Python classes?
Foundation • 0-2 Yrs
'__new__' is the static constructor method responsible for creating and returning a new instance of a class (allocating memory). '__init__' is the initializer method called immediately after '__new__' to set up instance attributes and state. Customizing '__new__' is critical when implementing Singletons or subclassing immutable types like tuple or int.
Q10. How does exception handling work with 'try', 'except', 'else', and 'finally'?
Foundation • 0-2 Yrs
Code prone to runtime errors runs in the 'try' block. If an exception occurs, matching 'except' blocks catch it. If no exception occurs, the 'else' block executes. The 'finally' block always executes regardless of whether an exception occurred, was caught, or unhandled, making it ideal for resource cleanup like closing files or database cursors.
Q11. What are list comprehensions and when should they be avoided?
Foundation • 0-2 Yrs
List comprehensions provide a concise syntactic construct [expr for item in iterable if cond] to create lists. They execute faster than equivalent for-loops because bytecode iteration happens at C-level speed. However, they should be avoided when logic becomes deeply nested (reducing readability) or when dealing with massive datasets where generator expressions save memory.
Q12. Explain the concept of Duck Typing in Python.
Foundation • 0-2 Yrs
Duck typing is a dynamic typing philosophy summarized as: 'If it walks like a duck and quacks like a duck, it is a duck.' Rather than inspecting an object's explicit type or inheritance hierarchy (isinstance), Python checks whether the required methods and attributes are present at runtime when invoked.
Q13. How do dictionary lookups achieve O(1) average time complexity?
Foundation • 0-2 Yrs
Python dictionaries use compact hash tables. Keys are hashed via hash(), which determines the slot index in the table. Collisions are handled via open addressing with pseudo-random probing. Starting in Python 3.7, dictionaries maintain insertion order using a split indices array and an entries array, achieving O(1) average lookup, insertion, and deletion.
Q14. What are Python built-in data types, and which ones are immutable?
Foundation • 0-2 Yrs
Built-in types include numeric (int, float, complex), sequence (str, list, tuple, range), mapping (dict), set (set, frozenset), and boolean (bool). Immutable types cannot be altered after creation and include int, float, str, tuple, frozenset, and bytes. Modifying them creates a new object in memory.
Q15. What is the difference between 'append()' and 'extend()' methods on lists?
Foundation • 0-2 Yrs
'append(x)' adds its argument as a single element to the end of the list, increasing list length by 1 even if x is an iterable. 'extend(iterable)' iterates over its argument and appends each element individually, increasing the list length by the length of the iterable.