Practice
Solution
Step 1: Understand encapsulation purpose
Encapsulation bundles data and methods and restricts direct access to internal state to protect object integrity.Step 2: Analyze options
When you want to expose all internal data directly for easy access exposes internal data directly, violating encapsulation. When you want to avoid using any access modifiers and rely on global variables ignores access control, risking data corruption. When you want to implement multiple inheritance to reuse code relates to inheritance, not encapsulation.Final Answer:
Option B -> Option BQuick Check:
Encapsulation is about bundling and controlled access, not exposing all data or inheritance.
- Confusing encapsulation with inheritance
- Thinking encapsulation means no access at all
- Believing global variables are encapsulated
Solution
Step 1: Understand naive search
MRO does not simply search the first parent class fully before moving to the next; it uses a more sophisticated approach.Step 2: Recognize MRO linearization
MRO uses a specific linearization (like C3 linearization) that merges parent classes and their ancestors in a consistent order.Step 3: Eliminate incorrect options
MRO always calls the method from the last parent class listed in the inheritance is incorrect because the last parent is not always chosen; order and ancestors matter. MRO randomly picks the method from any parent class that defines it is incorrect because MRO is deterministic, not random.Final Answer:
Option A -> Option AQuick Check:
MRO merges inheritance hierarchies to find the correct method in a predictable order.
- Assuming simple left-to-right search suffices
- Believing last parent always overrides
- Thinking method choice is random
import copy
class Profile:
def __init__(self, name, scores):
self.name = name
self.scores = scores
def __deepcopy__(self, memo):
new_name = self.name # Bug here
new_scores = copy.deepcopy(self.scores, memo)
return Profile(new_name, new_scores)
original = Profile('Alice', [10, 20])
copy_obj = copy.deepcopy(original)
copy_obj.scores.append(30)
print(original.scores)
Solution
Step 1: Examine __deepcopy__ method
The line new_name = self.name copies the reference to the name string instead of deep copying it.Step 2: Understand impact
Strings are immutable in Python, so shallow copy is usually safe, but if name were a mutable object, this would cause shared references and bugs. Proper deep copy should be used for consistency.Final Answer:
Option A -> Option AQuick Check:
Only new_name assignment lacks deepcopy -> subtle bug [OK]
- Forgetting to deepcopy all nested fields, assuming immutables are safe
prepare_recipe method in the Template Method Pattern implementation for a beverage, assuming each step runs in constant time?Solution
Step 1: Identify number of steps
The template method defines a fixed sequence of steps (boil_water, brew, pour_in_cup, add_condiments).Step 2: Analyze step execution time
Each step runs in constant time; the hook method only conditionally calls add_condiments but does not affect asymptotic complexity.Final Answer:
Option D -> Option DQuick Check:
Fixed steps with constant time each -> O(1) total [OK]
- Confusing n as input size
- Assuming recursion adds complexity
Solution
Step 1: Identify overridden methods
Tea overrides prepare_recipe, which breaks the template method pattern by duplicating and changing the algorithm flow.Step 2: Understand impact
Overriding the template method in subclass bypasses the base class skeleton, causing inconsistent behavior and code duplication.Final Answer:
Option A -> Option AQuick Check:
Template method must not be overridden by subclasses [OK]
- Thinking overriding abstract methods is bug
- Ignoring hook method usage
