PYTHON INTERVIEW
QUESTIONS
1. Core Python & Language Basics
Q1: What is Python and what are its main features?
Python is a high-level, interpreted, dynamically typed, and object-oriented programming language
created by Guido van Rossum and released in 1991. It emphasizes code readability, developer
productivity, and expressive syntax.
Interpreted Language: Python code is executed line-by-line by the Python interpreter without
requiring explicit pre-compilation into machine code.
Dynamically Typed: Variable data types are evaluated at runtime, eliminating the need to declare
variable types explicitly.
Automatic Memory Management: Provides automatic memory allocation and garbage collection
via reference counting and cycle detection.
Extensive Standard Library: Comes with built-in modules for string handling, file operations, web
services, database interactions, and scientific computing.
Q2: Is Python an interpreted or compiled language? Explain its execution mechanism.
Python is technically both, but primarily called an interpreted language. The source code is first
compiled into intermediate bytecode (.pyc file), which is then interpreted and executed by the Python
Virtual Machine (PVM) line by line
Q3: What are the key differences between Python 2 and Python 3?
Feature / Aspect Python 2 Python 3
`print` Statement `print "Hello"` (Statement syntax) `print("Hello")` (Function syntax)
Integer Division `5 / 2` returns integer `2` `5 / 2` returns float `2.5` (`5 // 2`
for floor)
Unicode Support ASCII strings by default (`unicode` UTF-8 Unicode strings by default
type)
`range()` Function `range()` returns list; `xrange()` for `range()` returns an efficient
generator generator-like object
Q5: What is the difference between dynamically typed and statically typed languages?
In statically typed languages (like Java/C++), variable types must be declared explicitly before use. In
dynamically typed languages like Python, the type is determined automatically at runtime based on the
value assigned.
x = 10 # Dynamically typed as int
x = "Hello" # Type changed to str smoothly
print(type(x)) # <class 'str'>
Python provides built-in functions `type()` to inspect object type to check if an object belongs to a class
or tuple of classes.
2. Data Types & Memory References
Q1: What are Mutable and Immutable data types in Python?
In Python, objects are categorized based on whether their internal state or value can be changed after
creation:
Immutable Data Types: Objects whose value cannot be altered in place. Modifying them creates a
new object in memory. Examples: `int`, `float`, `bool`, `str`, `tuple`, `frozenset`.
Mutable Data Types: Objects whose state can be modified in place without changing their memory
identity (`id()`). Examples: `list`, `dict`, `set`, `bytearray`.
# Immutable Example
s = "Hello"
# s[0] = "h" --> Raises TypeError: 'str' object does not support item
assignment
# Mutable Example
lst = [1, 2, 3]
[Link](4) # Modifies same memory reference
Q9. What is type casting in Python? Give an example.
Ans: Type casting is the process of manually converting a variable from one data type to
another using built-in constructor functions like `int()`, `float()`, `str()`, `list()`, or `tuple()`.
Example: num_str = "100" num_int = int(num_str) # Converts string "100" to integer 100
Q2: Differentiate between Shallow Copy and Deep Copy.
When copying compound objects (like nested lists or dictionaries) using the `copy` module:
Shallow Copy (`[Link]()`): Creates a new container object, but inserts references to the nested
objects found in the original. Changes to nested mutable elements affect both copy and original.
Deep Copy (`[Link]()`): Creates a new container object and recursively copies all nested
objects found inside. Modifications to nested elements do NOT affect the original.
import copy
original = [[1, 2], [3, 4]]
shallow = [Link](original)
deep = [Link](original)
original[0][0] = 999
print(shallow[0][0]) # Prints 999 (Refers to same nested list)
print(deep[0][0]) # Prints 1 (Completely independent copy)
Q3: What is the difference between `==` and `is` operators in Python?
`==` Operator (Equality): Compares the values/contents of two objects to check if they are equal.
`is` Operator (Identity): Compares the memory addresses (`id()`) of two variables to check if they
point to the exact same object in memory.
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True (Contents are identical)
print(a is b) # False (Different memory locations)
3. Functions & Functional Programming
Q34. What is a function in Python and how do you define it?
Ans: A function is a reusable, organized block of structured code designed to execute a single,
related action. Functions are declared using the `def` keyword followed by a unique name.
Example:
def greet():
print("Hello Freshers!")
greet() # Call the function
Q35. What is the difference between arguments and parameters?
Ans: Parameters are the placeholder variables specified in the function's definition header.
Arguments are the actual, real values passed into the function when it is invoked.
Example:
def add(a, b): return a + b # a, b are parameters
add(5, 10) # 5, 10 are arguments
Q36. What are positional and keyword arguments?
Ans: Positional arguments are passed into a function based on their correct sequential order.
Keyword arguments are passed explicitly by matching the parameter name, disregarding order.
Example:
def info(name, age): print(name, “ and “,age)
info("Bob", 25) # Positional
info(age=25, name="Bob") # Keyword
Q37. What are *args and **kwargs in function definitions?
Ans: `*args` allows a function to accept any number of additional positional arguments as a
tuple. `**kwargs` allows the function to accept any number of keyword arguments as a
dictionary.
Example:
def test(*args, **kwargs):
print(args, kwargs)
test(1, 2, a=3) # args=(1,2), kwargs={'a':3}
Q38. What is a lambda function? Give an example.
Ans: A lambda function is a small, anonymous, single-expression function defined without a
name using the `lambda` keyword. It is typically used for short, throwaway operations.
Example:
square = lambda x: x * x
print(square(4)) # Outputs: 16
Q39. What is the scope of variables in Python (Local vs Global)?
Ans: Local variables are defined inside a function and can only be accessed within that function
block. Global variables are declared outside all functions and are accessible anywhere in the
script.
Example:
x = "global"
def check():
y = "local"
print(y)
Q40. What is the purpose of the global keyword?
Ans: The `global` keyword is used inside a local function scope to explicitly declare that a
variable belongs to the outer global scope, allowing you to modify its value permanently.
Example:
counter = 0
def increment():
global counter
counter += 1
Q41. What are default arguments in a function?
Ans: Default arguments are parameter values that are pre-assigned in the function definition. If
no argument value is provided during the function call, the default value is used automatically.
Example:
def welcome(name="Guest"): print("Hi", name)
welcome() # Outputs: Hi Guest
Q42. What is a return statement? Can a function return multiple values?
Ans: A `return` statement exits a function and sends data back to the caller. Python functions
can return multiple values separated by commas, which are implicitly bundled as a tuple.
Example:
def stats(): return 10, 20
result = stats() # returns tuple (10, 20)
Q43. What is a docstring in Python?
Ans: A docstring (documentation string) is a string literal placed as the very first statement
inside a function, class, or module to explain its functionality. It is accessed via the `__doc__`
attribute.
Example:
def f():
"""This calculates math"""
pass
print(f.__doc__)
Q44. What are higher-order functions in Python?
Ans: A higher-order function is any function that fulfills at least one of two conditions: it either
takes one or more functions as input arguments, or it yields a function as its output return value.
Example:
def apply(func, val):
return func(val)
print(apply(lambda x: x+1, 5)) # Outputs: 6
Q3: Explain `map()`, `filter()`, and `reduce()` with examples.
from functools import reduce
nums = [1, 2, 3, 4, 5]
# map(): Transforms each element
squares = list(map(lambda x: x**2, nums)) # [1, 4, 9, 16, 25]
# filter(): Filters elements based on predicate
evens = list(filter(lambda x: x % 2 == 0, nums)) # [2, 4]
# reduce(): Accumulates elements to a single value
product = reduce(lambda x, y: x * y, nums) # 120
4. Object-Oriented Programming (OOPs)
Q45. What is Object-Oriented Programming (OOP) in Python?
Ans: OOP is a popular programming paradigm centered around styling applications using
'classes' and 'objects' to model real-world attributes and behaviors, promoting code reusability.
Example:
# Built on 4 pillars: Inheritance, Polymorphism, Encapsulation,
Abstraction
Q46. What is a class and what is an object?
Ans: A class acts as a blueprint, prototype, or template for creating objects. An object is a real-
world instance of that class containing actual data and executable behaviors.
Example:
class Car: pass
my_car = Car() # my_car is an object of class Car
Q47. What is the purpose of the __init__ method?
Ans: The `__init__` method is a special, automatically called constructor method. It runs
whenever a new object is instantiated, initializing the object's unique instance attributes.
Example:
class Person:
def __init__(self, name):
[Link] = name
p = Person("John")
Q48. What is the self keyword in Python?
Ans: The `self` keyword represents the specific instance of the class that is currently being
operated on. It binds the object's local attributes and methods directly to its blueprint definition.
Example:
class Dog:
def speak(self):
print("Woof!") # self links method to object
Encapsulation
Q1: What is Encapsulation and how are access modifiers implemented in Python?
Encapsulation is wrapping data (variables) and methods into a single class while protecting the internal
data from direct outside modification
Public Members: Accessible from anywhere. Syntax: `[Link]`
Protected Members: Conventionally intended for internal use and subclass access only. Syntax:
single leading underscore `self._age`
Private Members: Inaccessible directly from outside the class. Syntax: double leading underscore
`self.__salary`
Q2: What is Name Mangling in Python?
Python handles double underscore private members (`__attribute`) via Name Mangling. The interpreter
renames `__attribute` to `_ClassName__attribute` internally to prevent accidental overrides in
subclasses.
Example:
class Employee:
def __init__(self, salary):
self.__salary = salary # Private attribute
emp = Employee(50000)
# print(emp.__salary) --> Raises AttributeError
print(emp._Employee__salary) # Accesses salary via mangled name (50000)
Q3: How do Getters, Setters, and `@property` decorators work in Python?
In Python, the @property decorator lets us use getter and setter methods like normal variables, keeping
our code clean while allowing us to add validation logic
@property acts as the getter.
@<attribute>.setter acts as the setter."
class Employee:
def __init__(self, balance):
self._salary = salary
@property
def salary(self): # Getter
return self._salary
@[Link]
def salary(self, amount): # Setter with validation
if amount < 0:
raise ValueError("Balance cannot be negative!")
self._ salary = amount
acc = Employee(100)
[Link] = 250 # Calls setter method transparently
print([Link]) # Calls getter method (250)
Abstraction
Q1: What is Abstraction in Python and how is it implemented using the `abc` module?
Abstraction is the concept of hiding complex implementation details from the user and exposing only
the essential interface
Q94. Why is abstraction used?
1. Reduces complexity for the user.
2. Makes the code easier to use.
3. Hides implementation details.
Q95. What is an abstract class?
An abstract class is a blueprint or template that cannot be instantiated directly (you cannot
create an object from it). It exists solely to be inherited by child classes, forcing them to
implement specific missing methods.
from abc import ABC, abstractmethod
class Parent(ABC): # Abstract class template
@abstractmethod
def display(self):
pass
# obj = Parent() # This will throw an error immediately!
Q96. What is an abstract method?
An abstract method is a method that is declared in an abstract parent class but contains no
implementation logic (no body). Any child subclass that inherits from this parent must write the
concrete implementation for this method, or Python will prevent the child class from creating
objects.
Q97. Which module is used to create abstract classes in Python?
Python uses the built-in abc (Abstract Base Classes) module. To create an abstract architecture,
a class must inherit from ABC, and individual abstract methods must be marked with the
@abstractmethod decorator.
from abc import ABC, abstractmethod
Inheritance
Q1: What is Inheritance? List the types supported in Python.
Inheritance allows a subclass (child class) to inherit attributes and methods from a superclass (parent
class), promoting code reusability.
Single Inheritance: Child inherits from one parent class.
Multiple Inheritance: Child inherits directly from multiple parent classes.
Multilevel Inheritance: Child inherits from a parent, which inherits from a grandparent class.
Hierarchical Inheritance: Multiple child classes inherit from a single parent class.
Hybrid Inheritance: A combination of two or more inheritance types.
Q72. Does Python support multiple inheritance? Yes. Unlike languages like Java, Python natively
supports multiple inheritance. A single subclass can inherit features from multiple distinct parents. class
Sub1(ParentA, ParentB): pass
Q2: What is Method Resolution Order (MRO) and the Diamond Problem?
The Diamond Problem occurs in multiple inheritance when a class inherits from two classes that both
inherit from a common base class. Python resolves this ambiguity using Method Resolution Order (MRO)
via C3 Linearization algorithm.
class A:
def show(self): print("A")
class B(A):
def show(self): print("B")
class C(A):
def show(self): print("C")
class D(B, C):
pass
obj = D()
[Link]() # Output: B (Follows MRO)
print(D.__mro__) # D -> B -> C -> A -> object
Q75. What is the super() function? In Python, super() is a built-in function used to call methods
from the parent class inside a child class. Its main purpose is to let us reuse and extend the
parent class's code instead of rewriting it from scratch
Polymorphism
Q1: What is Polymorphism in Python?
Polymorphism means 'many forms'. The same method name can behave differently based on the
object calling it.
Method Overriding: A child class provides a custom implementation of a method that is already
defined in its parent class.
Duck Typing: 'If it walks like a duck and quacks like a duck, it's a duck.' Python focuses on whether
an object has the required method/attribute rather than its explicit class hierarchy.
Q100. What are the types of polymorphism? Compile-time Polymorphism (Method Overloading):
Defining multiple methods with the same name but different arguments. Python does not support
this natively (it will just overwrite the old method with the latest one). Run-time Polymorphism
(Method Overriding): Where a child class replaces a method inherited from a parent class. Python
fully supports this.
Q79. What is method overloading? Method overloading means defining multiple methods in the
same class with the same name, but with a different number or type of parameters (arguments)
Q83. What is method overriding? Method overriding is an OOP feature where a child class provides
a specific implementation for a method that is already defined in its parent class. class Parent: def
display(self): print('Parent display') class Sub1(Animal): def display(self): print('Sub1 display') #
overriding
Q82. What is the difference between method overloading and method overriding? • "Overloading:
Happens in the same class. Methods have the same name but different parameters. • Overriding:
Happens across parent and child classes. Methods have the same name and same parameters, but
the child class rewrites the parent's logic."
Q2: Does Python support Method Overloading? How is it handled?
Python does NOT support traditional compile-time method overloading (having multiple methods with
the same name but different signatures in the same class). Defining multiple methods with the same
name overwrites previous definitions. Overloading is achieved using default arguments or variable
keyword arguments (`*args`, `**kwargs`).
class Calculator:
def add(self, a, b=0, c=0): # Simulates overloading with default arguments
return a + b + c
calc = Calculator()
print([Link](10)) # 10
print([Link](10, 20)) # 30
print([Link](10, 20, 30))# 60
3. Data Structures in Python
Lists
Q1: What is a List in Python? How does negative indexing and slicing work?
A List in Python is a mutable, ordered sequence of heterogenous elements enclosed in square brackets
[...]. Key features include dynamic sizing, support for duplicate elements, indexed access, and nested
array structures.
Negative Indexing: Python allows indexing from the end of the list. Index `-1` refers to the last
element, `-2` to the second last, etc.
Slicing Syntax: `list[start : stop : step]` extracts a subset from `start` up to (but not including) `stop`.
nums = [10, 20, 30, 40, 50]
print(nums[-1]) # Output: 50
print(nums[1:4]) # Output: [20, 30, 40]
print(nums[::-1]) # Output: [50, 40, 30, 20, 10] (Reversed list)
Q7. How does Python handle list memory allocation under the hood?
Python lists are implemented as dynamic arrays of pointers to object memory locations.
When new elements
exceed allocated capacity, Python automatically over-allocates extra buffer space to achieve
amortized O(1)
time complexity for append() operations.
Q8. What is the difference between append(), extend(), and insert() in Python lists?
append(item) adds a single element to the end of the list. extend(iterable) unpacks and
appends all elements
from an iterable to the end. insert(index, item) inserts an element at a specific index, shifting
subsequent items
to the right.
Q9. What is the difference between shallow copy and deep copy for lists?
A shallow copy ([Link]() or list[:]) creates a new outer list container but copies references
to nested elements.
A deep copy ([Link]()) recursively copies both the outer container and all nested
objects, ensuring
complete independence.
Q10. How do remove(), pop(), and clear() differ in Python lists?
remove(val) removes the first matching value from the list by value. pop(index) removes and
returns the element
at the specified index (defaulting to the last item). clear() removes all elements, leaving an
empty list.
Q2: What is List Comprehension? Give an example.
List comprehension provides a concise syntax for creating lists based on existing iterables.
Syntax: `[expression for item in iterable if condition]`
# Generating squares of even numbers from 1 to 10
squares = [x**2 for x in range(1, 11) if x % 2 == 0]
print(squares) # Output: [4, 16, 36, 64, 100]
Q3: Compare `append()`, `extend()`, and `insert()` methods in List.
Method Description Time Complexity
`append(item)` Adds a single element `item` to the $O(1)$ amortized
end of the list.
`extend(iterable)` Appends each element from an $O(k)$ where $k$ is length of
`iterable` individually to the end. iterable
`insert(index, item)` Inserts `item` at the specified $O(n)$ where $n$ is length of list
`index`, shifting elements right.
Tuples
Q1: What is a Tuple?
A Tuple is an immutable, ordered sequence of elements enclosed in parentheses (...). Unlike lists, tuples
cannot be modified (added to, updated, or removed from) after creation, making them lighter in
memory footprint and hashable.
Q12. Why are Tuples faster and more memory-efficient than Lists?
Tuples are allocated as static single contiguous memory blocks without extra buffer capacity. Lists
require extra
dynamic over-allocation overhead to support mutation, making tuples faster to construct and iterate
over.
Q13. How do you create a single-element tuple in Python?
You must include a trailing comma after the single value. Without a comma, Python evaluates the
parentheses as a standard grouping operator.
Example:
a = (5) # Type is <int>
b = (5,) # Type is <tuple>
Q14. Can a Tuple contain mutable elements like Lists? What happens if you modify them?
Yes, a tuple can contain mutable items like lists. While the tuple's outer reference structure remains
fixed, the
nested mutable objects inside it can be altered in place. However, such tuples become unhashable and
cannot
be used as dictionary keys.
Q15. What is Tuple Unpacking and how is it used?
Tuple unpacking allows assigning individual elements of a tuple directly to variables in a single
statement, e.g.,
a, b, c = (10, 20, 30). The asterisk operator (*) can capture remaining elements, e.g., head, *tail = (1, 2, 3,
4).
Why are Tuples used over Lists when Lists offer more features?
1. Memory Efficiency: Tuples require less memory space than lists.
2. Execution Speed: Iterating over tuples is faster than over lists.
3. Data Integrity: Protects write-protected data from accidental modification.
4. Hashability: Tuples can be used as keys in Dictionaries or elements in Sets (Lists cannot).
Q2: What is Tuple Packing and Unpacking?
Packing gathers multiple values into a single tuple, while unpacking assigns elements of a tuple into
individual variables.
# Tuple Packing
person = ("Alice", 25, "Software Engineer")
# Tuple Unpacking
name, age, profession = person
print(name) # Output: Alice
# Extended Unpacking using *
a, *b, c = (1, 2, 3, 4, 5)
print(b) # Output: [2, 3, 4]
Sets
Q1: What is a Set?
A Set is an unordered collection of unique, hashable elements defined with curly braces {...} or set(). Sets
automatically eliminate duplicate entries and provide mathematical set operations like union,
intersection, and difference.
What are the key properties of a Python Set?
1. Unordered: Elements do not have a fixed position or index.
2. Unique: Duplicate items are automatically removed.
3. Unindexed: Elements cannot be accessed using bracket notation `set[0]`.
Q17. How are Sets implemented internally in Python?
Sets in Python are implemented using hash tables (similar to dictionary keys without values). This
internal
structure allows membership testing ('element in set'), additions, and deletions to operate in O(1)
average time
complexity.
Q18. What is the difference between add() and update() in sets?
add(elem) adds a single element to the set. update(iterable) accepts one or multiple iterables (like lists,
tuples,
or sets) and adds all unique elements into the target set.
Q19. What is the difference between discard() and remove() in sets?
Both methods remove a specified element from a set. However, remove(elem) raises a KeyError if the
element
is not found, whereas discard(elem) silently ignores missing elements without raising an exception.
Q20. What is a frozenset in Python?
A frozenset is an immutable version of a standard Python set. Once initialized, its elements cannot be
modified.
Because it is immutable and hashable, a frozenset can be used as a dictionary key or stored inside
another set.
Q2: Explain Set mathematical operations and `frozenset`.
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
print(A | B) # Union: {1, 2, 3, 4, 5, 6}
print(A & B) # Intersection: {3, 4}
print(A - B) # Difference: {1, 2}
print(A ^ B) # Symmetric Difference: {1, 2, 5, 6}
A `frozenset` is an immutable version of a set. Because it is hashable, a `frozenset` can be used as a
dictionary key or as an element inside another set.
Dictionaries
Q21. What is a Dictionary in Python?
A Dictionary is an unordered , mutable mapping data structure stored as keyvalue pairs inside
curly braces {key: value}. Keys must be unique and hashable (immutable).
Q22. How does hash table lookup work in Python Dictionaries?
Python computes a hash code for a key using hash(key) and maps it to an internal table
index. This allows
constant time O(1) key lookups, insertions, and deletions on average.
Q23. What is the difference between dict[key] and [Link](key)?
dict[key] retrieves the value corresponding to key but raises a KeyError if the key does not
exist. [Link](key,
default) safely returns None (or a specified default value) if the key is missing, preventing
runtime errors.
Q24. What are dictionary keys restrictions in Python?
Dictionary keys must belong to an immutable and hashable data type (e.g., int, float, string,
tuple containing
immutable items). Mutable data structures like lists, sets, and standard dictionaries cannot
be used as keys.
Q25. How do keys(), values(), and items() methods work in Python Dictionaries?
keys() returns a dynamic view object of all dictionary keys, values() returns a view object of
all values, and
items() returns a view object of (key, value) tuple pairs. These view objects dynamically
update when the
dictionary changes.
Q26. How are dictionaries stored in memory, and what is their lookup performance?
Python dictionaries are implemented as Hash Tables. They use a hash function on keys to
calculate array
index positions, allowing key-based search, insertion, and deletion operations to execute in
average O(1)
time complexity.
Linear & Non-Linear Data Structures
LinkedList Data Structure
Q66. What is a Data Structure and why is it needed?
Ans: A data structure is a specialized way of organizing, processing, managing, and storing data
in a computer so that it can be accessed and modified efficiently. It forms the base for efficient
algorithm design.
Example:
# Examples include Linear types (Arrays, Linked Lists) and Non-Linear types
(Trees, Graphs)
Q67. What is the difference between Linear and Non-Linear Data Structures?
Ans: In linear data structures, elements are arranged sequentially or chronologically where each
element attaches to its previous and next element. Non-linear structures arrange elements
hierarchically or interconnectedly.
Example:
# Linear: Arrays, Lists, Stacks, Queues
# Non-Linear: Trees, Graphs, Binary Search Trees
Section 1: LINKED LIST
Q1. What is a Linked List?
A Linked List is a linear data structure where elements are not stored at contiguous memory locations.
Instead, elements are stored in 'Nodes', where each node contains two parts:
1. Data: The actual value stored.
2. Next: A reference (pointer) to the next node in the sequence.
Q2. What are the main types of Linked Lists?
1. Singly Linked List: Each node points to the next node. Traversal is forward only.
2. Doubly Linked List: Each node points to both the next and the previous nodes. Traversal is possible in
both directions.
3. Circular Linked List: The next reference of the last node points back to the first node (head), forming a
loop.
Q3. Compare Array vs. Linked List.
• Memory Allocation: Arrays use contiguous memory, while Linked Lists store nodes at dynamic,
scattered memory addresses.
• Size: Arrays have a fixed size, while Linked Lists grow and shrink dynamically.
• Insertion/Deletion: Fast in Linked Lists (O(1) time without shifting), but slow in Arrays (O(N) time due
to shifting elements).
• Access Time: Arrays offer O(1) random access via index, while Linked Lists require O(N) traversal from
the head node.
Q4. What is a Dummy Node (Sentinel Node) and why is it used?
A Dummy Node is a temporary fake node placed at the beginning of a Linked List. It simplifies edge-case
handling (like inserting or deleting at the head node) because you never have to write special logic for
when the head changes.
Q5. What are the advantages of using a Linked List over a List in
Python?
Linked lists offer fast insertions and deletions at the beginning or middle of the list in O(1) time once the
target position is reached. They do not suffer from the memory relocation overhead that happens when
dynamic arrays exceed pre-allocated memory. They utilize memory dynamically, allocating space for new
nodes only when necessary. This makes linked lists ideal for implementing complex linear data structures like
custom Stacks and Queues.
1. Stack Data Structure
Q1. What is a Stack ?
A stack is a linear data structure that follows the LIFO (Last In First Out) principle. The last element
added to the stack is the first one to be removed. Operations are restricted to the top of the stack
Q2. What are the core operations performed on a Stack?
The main operations are:
• Push: Inserts an element onto the top of the stack.
• Pop: Removes and returns the top element from the stack.
• Peek / Top: Returns the top element without removing it.
• IsEmpty: Checks whether the stack contains any elements.
• IsFull: Checks whether the stack has reached its maximum capacity (applicable in fixed-size array
implementations).
Q4. What are the common real-world and technical applications of a Stack?
Common applications include:
1. Function Call Management: Function execution stack (call stack) and recursion tracking.
2. Undo/Redo Mechanisms: Used in text editors and web browser back/forward history.
3. Expression Evaluation & Parsing: Matching parentheses, converting Infix to Postfix/Prefix expressions.
4. Algorithms: Backtracking problems (e.g., maze navigation) and Depth-First Search (DFS) on graphs.
Q5. How do you implement a Stack?
2. Queue Data Structure
Q6. What is a Queue?
A queue is a linear data structure that follows the FIFO (First In First Out) principle. The
element inserted first is the one that gets removed first. Insertion happens at the rear (enqueue)
and deletion at the front (dequeue).
Example:
from collections import deque
queue = deque()
[Link]('A') # EnqueueQ7. What are the primary operations performed on a Queue?
The main operations are:
• Enqueue: Adds an element to the rear of the queue.
• Dequeue: Removes and returns the element at the front of the queue.
• Front / Peek: Returns the front element without removing it.
• Rear: Returns the last added element at the rear.
• IsEmpty / IsFull: Checks if the queue is empty or at full capacity.
Q8. What are the main applications of a Queue?
Queue applications include:
1. Operating System Scheduling: CPU task scheduling and process queues.
2. Resource Sharing: Managing access to shared resources like printers (print spooling) and disk
requests.
3. Deque (Double-Ended Queue)
Q10. What is a Deque (Double-Ended Queue)?
A Deque (pronounced 'deck') is a generalized queue where insertion and deletion of elements can be
performed from both ends—the Front and the Rear.
Unlike a standard queue (FIFO) or stack (LIFO), a Deque can act as both a Stack and a Queue depending
on how you perform operations.
Q11. What are the core operations of a Deque?
A Deque supports four primary insertion/deletion operations:
• insertFront(): Adds an element to the front of the deque.
• insertRear(): Adds an element to the rear of the deque.
• deleteFront(): Removes an element from the front of the deque.
• deleteRear(): Removes an element from the rear of the deque.
• getFront() / getRear(): Retrieves the front or rear element without deleting it.
Q12. What are the two types of restricted Deques?
1. Input-Restricted Deque: Insertion is allowed at only one end (e.g., Rear), but deletion is allowed
from both ends (Front and Rear).
2. Output-Restricted Deque: Deletion is allowed at only one end (e.g., Front), but insertion is
allowed at both ends (Front and Rear).
2. Q20. How is a DeQueue implemented?
3.
Q13. What are common applications of a Deque?
Applications of a Deque include:
1. Undo/Redo operations in applications where actions can be inserted/removed from both ends.
2. Sliding Window Problems in coding rounds (e.g., finding maximum/minimum in all subarrays of size
K).
3. Storing web browser history (enabling forward and backward movement).
4. Checking if a word or string is a Palindrome.
4. Circular Queue
Q14. What is a Circular Queue and how does it solve the limitation of a Linear Queue?
A Circular Queue is an extended version of a linear queue where the last position is connected back to
the first position to form a circle.
It solves the memory wastage problem of a linear array queue by reusing the empty spaces created at
the front when elements are dequeued.
Q17. What are practical applications of a Circular Queue?
Common applications include:
1. CPU Traffic Scheduling: Round-Robin scheduling algorithm where processes share time slots in a
continuous cycle.
2. Memory Management: Circular buffers in audio/video streaming where old data is continuously
replaced by new streams.
3. Hardware Traffic Controllers: Managing signal lights and hardware interrupts sequentially.
5. Priority Queue
Q18. What is a Priority Queue and how does it differ from a regular Queue?
A Priority Queue is a special type of queue where each element has an associated priority value.
Key difference: In a standard Queue, elements are served on a First-In, First-Out (FIFO) basis. In a Priority
Queue, elements are served based on priority—elements with higher priority are dequeued before
elements with lower priority, regardless of their order of insertion.
Q19. What are the two types of Priority Queues?
1. Max-Priority Queue: The element with the maximum priority value is served/removed first.
2. Min-Priority Queue: The element with the minimum priority value is served/removed first.
Q20. How is a Priority Queue implemented?
Q21. What are common applications of a Priority Queue?
Key applications include:
1. Dijkstra's Shortest Path Algorithm: Finding the shortest distance in a graph.
2. Prim's Algorithm: Finding Minimum Spanning Trees (MST).
3. Huffman Coding: Data compression algorithms.
4. Real-time OS S
1. Trees & Binary Search Trees (BST)
Q1. What is a Non-Linear Data Structure and how does it differ from a Linear Data Structure?
In a Linear Data Structure (like Arrays, Linked Lists, Stacks, Queues), elements are arranged sequentially
one after another. In a Non-Linear Data Structure (like Trees, Graphs), elements are not arranged
sequentially; instead, they are connected hierarchically or as a network of nodes, allowing multiple
paths to traverse elements.
Q2. What is a Tree Data Structure and what are its core terminologies?
A Tree is a hierarchical non-linear data structure consisting of nodes connected by edges.
Core Terminologies:
• Root: The top-most node of the tree (has no parent).
• Parent & Child: A node directly connected above another is the parent; the node below is the child.
• Leaf Node: A node that has no children.
• Subtree: A tree formed by a node and all of its descendants.
• Height of Tree: The maximum number of edges from the root node to a leaf node.
• Depth of Node: The number of edges from the root node to that specific node.
Q3. What is a Binary Tree?
A binary tree is a hierarchical non-linear data structure where each node can have a maximum of two
children, traditionally referred to as the left child and the right child.
Q4. What are the different types of Binary Trees?
• Full Binary Tree: Every node has either 0 or 2 children (no node has only 1 child).
• Complete Binary Tree: All levels are completely filled except possibly the last level, which is filled from
left to right.
• Perfect Binary Tree: All internal nodes have two children and all leaf nodes are at the exact same level.
• Balanced Binary Tree: The height difference between the left and right subtrees of any node is at most
1.
Q5. What is a Binary Search Tree (BST)? What is its main property?
: A Binary Search Tree is a variant of a binary tree where the left child node value must be strictly less
than the parent value, and the right child node value must be greater than or equal to the parent node
value.
Q6. What are the time complexities for Search, Insertion, and Deletion in a BST?
• Average Case: O(log N) time complexity for Search, Insertion, and Deletion because half the tree is
eliminated at each step.
• Worst Case: O(N) time complexity when the tree becomes unbalanced/skewed (resembling a linked
list, e.g., inserting numbers 1 -> 2 -> 3 -> 4 sequentially).
Q7. What are the standard Tree Traversal techniques?
Tree traversals visit all nodes in a specific order:
1. In-Order Traversal (Left, Root, Right): Visits left child, root, then right child. (Note: Performing In-Order
traversal on a BST yields elements in sorted ascending order).
2. Pre-Order Traversal (Root, Left, Right): Visits root first, then left child, then right child. Useful for
creating a copy of a tree.
3. Post-Order Traversal (Left, Right, Root): Visits left child, right child, then root. Useful for deleting a
tree from bottom to top.
4. Level-Order Traversal (BFS): Visits nodes level by level from top to bottom, left to right, using a Queue.
2. Graphs
Q8. What is a Graph Data Structure?
A graph is a non-linear data structure consisting of a finite set of vertices (or nodes) and a set of edges
that connect these vertices together. They are widely used to map networks like social media or maps.
Example: graph = {'A': ['B', 'C'], 'B': ['A', 'D'], 'C': ['A'], 'D': ['B']}
Q9. What is the difference between a Tree and a Graph?
• A Tree is a hierarchical structure with a single root node and exactly one path between any two nodes.
It cannot contain cycles/loops.
• A Graph is a network structure with no root node, can have multiple paths between vertices, and can
contain cycles or disconnected components.
Q10. What are the main types of Graphs?
• Directed Graph (Digraph): Edges have directions (e.g., A -> B means you can travel from A to B, but not
B to A).
• Undirected Graph: Edges are bidirectional (e.g., A - B means travel is allowed in both directions).
• Weighted Graph: Edges have numerical weights or costs associated with them (e.g., distance between
cities).
• Cyclic vs. Acyclic Graph: A cyclic graph contains at least one loop/path that starts and ends at the same
vertex.
Q12. What are the two main Graph Traversal algorithms?
1. Breadth-First Search (BFS):
• Explores nodes level-by-level (outward from start vertex).
• Uses a Queue data structure and a Visited array.
• Used for finding the shortest path in unweighted graphs.
2. Depth-First Search (DFS):
• Explores as deep as possible along each branch before backtracking.
• Uses Recursion (or an explicit Stack) and a Visited array.
• Used for cycle detection, topological sorting, and solving mazes.
Q13. What is Dijkstra's Algorithm?
Dijkstra's Algorithm is a greedy algorithm used to find the shortest path from a single source vertex to all
other vertices in a weighted graph with non-negative edge weights. It uses a Priority Queue (Min-Heap)
to select the unvisited vertex with the smallest distance.
3. Heaps Data Structure
Q14. What is a Heap Data Structure?
A Heap is a specialized tree-based data structure that satisfies the Complete Binary Tree property and
the Heap Property.
Q15. What are the two types of Heaps?
A binary tree structure where the parent node is always greater than or equal to its children (Max-Heap)
or smaller than or equal to its children (Min-Heap).
Q17. What are the time complexities of Heap operations?
• Get Min/Max (Peek): O(1)
• Insert element: O(log N)
• Delete Min/Max (Extract): O(log N)
• Build Heap from an unsorted array: O(N)
4. Hash Tables & Hashing
Q18. What is a Hash Table and how does Hashing work?
: A data structure that stores key-value pairs using a hashing function to map keys to specific index
buckets for constant time lookups. Example: # Python's built-in dict type is implemented as a Hash Table
Q19. What is a Hash Collision?
A Hash Collision occurs when a hash function maps two different input keys to the exact same array
index.
Q20. What are the common methods to resolve Hash Collisions?
1. Separate Chaining (Open Hashing): Each array index stores a Linked List or Bucket. When collisions
occur, new elements are simply appended to the list at that index.
2. Open Addressing (Closed Hashing): All elements are stored inside the array itself. If a collision occurs,
it searches for another empty slot using probing:
• Linear Probing: Checks index + 1, index + 2, index + 3 sequentially.
• Quadratic Probing: Checks index + 1^2, index + 2^2, index + 3^2.
• Double Hashing: Uses a second hash function to calculate the step size.
6. Exception Handling & File I/O
Q1: How does Exception Handling work in Python? Explain `try`, `except`, `else`, and `finally`.
An exception is a runtime error that disrupts the normal sequence of code execution. It is handled
safely using the `try-except` block to prevent the program from crashing abruptly.
`try` block: Contains code that might raise an exception.
`except` block: Catches and handles specific exceptions.
`else` block: Executes if NO exception was raised in the `try` block.
`finally` block: Executes unconditionally, regardless of whether an exception occurred (used for
resource cleanup).
try:
f = open("[Link]", "r")
num = int([Link]())
except FileNotFoundError:
print("File not found!")
except ValueError:
print("Invalid integer conversion!")
else:
print("Read operation successful:", num)
finally:
print("Closing operations complete.")
: An exception is a runtime error that disrupts the normal sequence of code execution. It is
handled safely using the `try-except` block to prevent the program from crashing abruptly.
Q57. What is the difference between syntax errors and exceptions?
Ans: Syntax errors are structural mistakes discovered by the parser before running the script
(e.g., missing colons). Exceptions occur dynamically during runtime due to logical errors or data
issues.
Example:
# Syntax Error: if x = 5:
# Exception: print(10 / 0)
Q58. What is the purpose of the finally block?
Ans: The `finally` block always executes its code statements regardless of whether an exception
was raised or safely caught. It is ideal for cleanup actions like closing database connections.
Example:
try:
f = open("[Link]")
finally:
[Link]() # Always executes to free resources
Q59. How can you raise a custom exception in Python?
Ans: You can manually trigger exceptions using the `raise` keyword. To make a custom
exception, you define a new class that inherits directly from the built-in `Exception` base class.
Example:
class AgeError(Exception): pass
if age < 18: raise AgeError("Too young")
Q60. How do you open and close a file in Python?
Ans: Files are opened using the built-in `open(filename, mode)` function, which returns a file
handle object. Once processing is complete, you call the `.close()` method to release system
resources.
Example:
file = open("[Link]", "r")
content = [Link]()
[Link]()
Q62. What are the different file modes in Python (r, w, a, r+)?
Ans: `r` opens a file for reading only (default). `w` opens for writing, overwriting or creating the
file. `a` opens for appending text to the end. `r+` opens the file for both reading and writing
simultaneously.
Example:
with open("[Link]", "a") as f:
[Link]("New log entry\n")
Q63. What is the difference between read(), readline(), and readlines()?
Ans: `read()` pulls the entire file text into a single string. `readline()` reads exactly one line at a
time. `readlines()` extracts all lines sequentially and packs them into a list of strings.
Example:
with open("[Link]") as f:
lines = [Link]() # Returns list of lines
Q2: How does the `with` statement work in File Handling (Context Managers)?
The `with` statement simplifies resource management (file streams, lock acquisitions, database
connections) by automatically invoking context manager methods `__enter__()` and `__exit__()`. It
guarantees resource closure even if exceptions occur.
with open("[Link]", "w") as file:
[Link]("Hello, World!")
# File is automatically closed upon exiting the block
7. Iterators, Generators & Decorators
Q1: What is the difference between an Iterable and an Iterator?
An Iterable is the data collection itself—like a list, tuple, or string. It holds the values and implements
__iter__(). You can loop over it as many times as you want.
An Iterator is the helper object that actually steps through that collection. It uses __next__() to fetch
items one by one, keeps track of the current position, and raises StopIteration error when it reaches the
end.
Example: An Iterable is like a book, containing all the pages. An Iterator is like a bookmark, tracking
which page you're currently reading and moving forward page by page.
Q2: What is a Generator function and the `yield` keyword?
A Generator is a function that returns an iterator, producing values one at a time only when requested
—making it memory-efficient.
Instead of return, it uses yield.
return ends the function and sends back all data at once.
yield sends back one value, pauses the function, saves its state, and resumes from that exact
spot on the next call.
Q3: What is a Decorator in Python?
A Decorator is a design pattern used to extend or alter the behavior of a function or method without
permanently modifying its original source code. Decorators are higher-order functions that take a
function as an argument and return a wrapper function.
def my_decorator(func):
def wrapper():
print("Something before function execution.")
func()
print("Something after function execution.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
8. Memory Management & Garbage Collection
Q1: How does Python manage memory internally?
Python manages memory automatically using a private heap, reference counting, and garbage
collection. This allows developers to focus more on logic than manual memory handling.
Private Heap Space
All Python objects and data structures are stored in a private heap.
The Python interpreter manages this heap internally.
Reference Counting
Each object has a counter that tracks how many references point to it.
When the count reaches zero, the object becomes eligible for garbage collection.
Garbage Collector
Frees memory by collecting objects no longer in use (especially in case of circular references).
Uses a generational approach to optimize performance.