Test your expertise with this advanced Python quiz featuring hard interview-style questions. Assess your knowledge of Python's internals, advanced features, data structures, memory model, and nuanced language behaviors to prepare for high-level technical interviews.
When using a mutable object as a default argument in a Python function, such as a list, what is the most significant risk illustrated by the following function definition: def append_item(val, my_list=[]): my_list.append(val); return my_list?
Explanation: Default mutable arguments like lists are evaluated only once at function definition, not at each call. This causes them to retain data between calls, resulting in unexpected behavior. A new list is not created each time (so the second option is incorrect), and by default my_list is an empty list, not None, making the third option wrong. No SyntaxError is raised, which makes the fourth option incorrect.
Which statement most accurately describes the effect of Python’s Global Interpreter Lock (GIL) on multi-threaded programs running CPU-bound code?
Explanation: The GIL allows only one thread to execute Python bytecode at a time, which limits parallelism for CPU-bound tasks. While I/O-bound threads can release the GIL during waits, they do not bypass it entirely (third option). The GIL is a concern for threads, not multi-processing (last option). Contrary to the second option, threads do not utilize all CPU cores efficiently when Python bytecode is involved.
Given a = [10], b = [10]; c = a; which of the following statements is True?
Explanation: a and b contain equal contents, so a == b is True, but they reference different objects, so a is b is False. a is c is True, but a != c is False. The last option incorrectly states a != b, which is not true since their contents are identical. Only the first option accurately represents object equality versus identity.
Why are Python generators typically more memory efficient than list comprehensions for large datasets?
Explanation: Generators compute each item only as needed, so they don’t require storing the whole dataset. List comprehensions store all elements in memory, so the second option is wrong. Syntax conciseness does not guarantee memory optimization (third option), and generators process all requested values, so the fourth option is incorrect.
When implementing a decorator that adds logging around a function, why is it essential to use closures inside the decorator?
Explanation: Closures let decorators remember the specific function instance to modify its behavior. Decorators do not inherently cause syntax errors (second option). Using @staticmethod is unrelated (third option). The fourth option is incorrect: decorators can wrap functions with any signature if coded flexibly.
Which method must a Python descriptor class implement to customize an attribute's retrieval behavior?
Explanation: __get__ defines how to handle getting an attribute from an object or its class. __call__ is for callable objects, not attribute retrieval. __repr__ is for string representation, and __del__ is for clean-up, so those options are incorrect. Only __get__ is required for customizing attribute access with a descriptor.
What is a primary use case of metaclasses in Python?
Explanation: Metaclasses allow customization of class construction and can alter or inject attributes and methods during class creation. Adding methods to instances is typically done via monkey-patching, not metaclasses. Metaclasses are not used for multiprocessing or direct memory management, so those options are incorrect.
Why can simple reference counting fail to reclaim memory in Python, leading to the need for a cyclic garbage collector?
Explanation: When two or more objects reference each other but are otherwise unreachable, their reference counts never drop to zero, so memory isn’t reclaimed. Reference counting does not immediately remove cyclic references (contradicting option two). Reference counting applies to all objects, not just immutable ones. The last option confuses purpose with speed; it’s not a reason for cyclic GC.
Which special method enables you to control exactly what is serialized when using Python's pickle module?
Explanation: __getstate__ lets you specify what state of the object gets pickled, giving control over serialization. __main__ is the main module’s namespace and unrelated. __enter__ is used for context managers, and __delattr__ handles attribute deletion; neither affects pickling behavior.
What is a distinguishing feature of a dictionary comprehension compared to a set comprehension in Python?
Explanation: Dict comprehensions generate mappings from keys to values, while set comprehensions generate sets of values. Sets do not create mappings, so option two is incorrect. Both comprehensions support conditionals, which disproves option three. Sets can contain any hashable type; they fail only with unhashable types, not all mutables. Only the first option accurately differentiates them.