Q1
Medium
What is the difference between deepcopy and shallow copy in Python?
A shallow copy (copy.copy()) constructs a new compound object and inserts references into it to the objects found in the original. If the elements are mutable, altering an inner element modifies both.
A deep copy (copy.deepcopy()) constructs a new compound object and recursively inserts copies of the objects found in the original.
import copy
original = [[1, 2], [3, 4]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)
original[0][0] = 99
print(shallow[0][0]) # 99 (modified)
print(deep[0][0]) # 1 (isolated)
Q2
Medium
How do Python decorators work behind the scenes?
A decorator is a callable that takes another function as an argument, extends or alters its behavior without modifying the original function code, and returns a new callable.
import functools
def timer(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}...")
result = func(*args, **kwargs)
print("Done!")
return result
return wrapper
@timer
def calculate(x, y):
return x + y
Q3
Easy
What are Python generators and why are they memory efficient?
Generators are functions that return an iterator yielding one item at a time using the yield keyword. Instead of storing an entire dataset in RAM, they compute values on demand (lazy evaluation), allowing you to process gigabyte-sized log files with minimal memory.
def read_large_file(file_path):
with open(file_path, 'r') as f:
for line in f:
yield line.strip()
# Consumes only one line in memory at any given instant
for line in read_large_file('huge_log.csv'):
if 'ERROR' in line:
print(line)
Q4
Easy
Explain the difference between *args and **kwargs.
*args allows a function to accept any number of positional arguments as a tuple.
**kwargs allows a function to accept any number of keyword arguments as a dictionary.
def custom_log(*args, **kwargs):
print("Positional:", args)
print("Keywords:", kwargs)
custom_log(1, 2, status="active", role="engineer")
Q5
Hard
How does memory management and garbage collection work in Python?
Python uses Reference Counting as its primary memory management mechanism. Every object tracks how many references point to it. When the count drops to zero, its memory is immediately deallocated. To resolve cyclic references (e.g. object A referencing B and B referencing A), Python runs a cyclic garbage collector divided into three generations.
Prepare for Live Technical Interviews
At DoxaTech Hub, students receive mock interview drills, resume reviews, and direct
coaching to ensure they pass rigorous engineering screens.
Join DoxaTech Today