Skip to content

euronone/python-developer-interview-guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 

Repository files navigation

Python Developer Interview Playbook

Comprehensive, chapter-wise preparation guide covering 200 Python developer interview questions with step-by-step answers.


Chapter 1: Core Language Foundations (Q1–Q20)

Q1. What are Python’s key features?

  1. Interpreted execution eases debugging.
  2. Dynamic typing infers types at runtime.
  3. High-level abstractions manage memory and data structures.
  4. Extensive standard library covers I/O, networking, parsing.
  5. Multi-paradigm support spans procedural, OOP, functional styles.
  6. Portability across platforms through multiple interpreters.
  7. Vibrant ecosystem of packages and community support.

Q2. How do CPython, PyPy, and Jython differ?

  1. CPython compiles to bytecode executed by C-based VM.
  2. PyPy includes a JIT for faster execution of many workloads.
  3. Jython runs on JVM for Java interoperability.
  4. IronPython targets .NET CLR.
  5. Choose interpreter based on interoperability and performance needs.

Q3. Explain Python’s execution model from source to runtime.

  1. Parser converts source to abstract syntax tree (AST).
  2. Compiler transforms AST to bytecode (.pyc).
  3. Python Virtual Machine executes bytecode.
  4. Compiled bytecode cached in __pycache__ for reuse.

Q4. What are PEPs and why are they important?

  1. Python Enhancement Proposals document language changes.
  2. Categories include Standard, Informational, and Process PEPs.
  3. Key examples: PEP 8 (style guide), PEP 20 (Zen of Python), PEP 3333 (WSGI).
  4. Workflow involves drafting, discussion, and acceptance or rejection.

Q5. Describe Python namespaces and scope resolution.

  1. Namespaces map identifiers to objects (e.g., module dictionaries).
  2. Scope lookup follows LEGB: Local, Enclosing, Global, Built-in.
  3. locals() and globals() expose current scope mappings.
  4. Namespace packages and modules maintain separate __dict__ mappings.

Q6. How does pass differ from continue and break?

  1. pass is a no-op placeholder.
  2. continue skips to next loop iteration.
  3. break exits the nearest loop.
  4. Use pass in stubs, continue for filtering, break for termination.

Q7. How does Python handle indentation?

  1. Significant indentation defines code blocks.
  2. Mixing tabs and spaces raises TabError.
  3. PEP 8 recommends four spaces per indent level.
  4. Formatters (black, autopep8) enforce consistent indentation.

Q8. Distinguish expressions, statements, and declarations.

  1. Expressions return values (e.g., 2 + 3).
  2. Statements perform actions (e.g., if, for).
  3. Python uses assignments as statements rather than declarations.
  4. Dynamic typing eliminates explicit declarations.

Q9. Explain name binding and rebinding.

  1. Binding associates identifiers with objects.
  2. Rebinding assigns new objects to existing names.
  3. Mutation changes object state without rebinding.
  4. Immutable types require rebinding to represent new values.

Q10. What is duck typing?

  1. Behavior determined by available methods and attributes.
  2. Example: any object with __iter__ acts as iterable.
  3. Encourages flexible polymorphism.
  4. May raise runtime errors if expected interface missing.

Q11. Describe truthiness rules.

  1. Falsy values include False, None, zeros, and empty containers.
  2. bool(obj) calls __bool__, falling back to __len__.
  3. Truthiness drives conditionals and loops.
  4. Custom classes can define boolean evaluation behavior.

Q12. What is short-circuit evaluation?

  1. Logical operators stop once outcome determined.
  2. A and B returns B if A truthy, else A.
  3. A or B returns A if truthy, else B.
  4. Enables guard expressions to prevent errors.

Q13. What is the difference between == and is?

  1. == invokes __eq__ for value equality.
  2. is checks object identity (same memory).
  3. Interning may reuse objects but should not be relied upon.
  4. Use is for singletons like None.

Q14. Explain chained comparisons.

  1. a < b < c evaluates once per operand.
  2. Equivalent to a < b and b < c.
  3. Supports mixed operators (a < b == c).
  4. Improves clarity when checking ranges.

Q15. How do import statements work?

  1. Search built-ins, then sys.modules, then paths in sys.path.
  2. Imports execute module top-level code once.
  3. Cache prevents re-execution on subsequent import.
  4. Avoid from module import * for clarity.

Q16. What is the difference between a module and a package?

  1. Module is a single .py file.
  2. Package is a directory with __init__.py (or namespace package).
  3. Subpackages nest directories.
  4. Namespace packages can span multiple locations.

Q17. How do docstrings work?

  1. Triple-quoted string after definition stored in __doc__.
  2. Applies to modules, classes, and functions.
  3. Access via help() and documentation tools.
  4. Follow PEP 257 formatting.

Q18. What is the purpose of if __name__ == "__main__":?

  1. Distinguishes script execution from module import.
  2. Code under guard runs only when executed directly.
  3. Enables CLI entry points without import side effects.
  4. Supports module reuse.

Q19. How are command-line arguments handled?

  1. sys.argv lists script name and arguments.
  2. argparse provides structured parsing and validation.
  3. Libraries like click and typer add higher-level ergonomics.
  4. Document CLI usage and defaults.

Q20. How does Python manage memory?

  1. Reference counting frees objects with zero references.
  2. Cyclic garbage collector handles reference cycles.
  3. pymalloc manages small object allocation.
  4. Manual GC control via gc module rarely needed.

Chapter 2: Built-in Data Types & Operations (Q21–Q40)

Q21. How are lists implemented and when to use them?

  1. Lists are dynamic arrays supporting amortized O(1) append.
  2. Ideal for ordered, mutable collections.
  3. Provide slicing, comprehension, and in-place mutations.
  4. Prefer sets or dicts for heavy membership checks.

Q22. Explain tuple characteristics and uses.

  1. Tuples are immutable sequences.
  2. Hashable when containing hashable elements, suitable as dict keys.
  3. Support packing/unpacking semantics.
  4. Namedtuples or dataclasses improve readability when fields named.

Q23. Distinguish list comprehension versus generator expression.

  1. List comprehensions eagerly build lists in memory.
  2. Generator expressions yield items lazily with constant memory.
  3. Syntax differs by brackets ([] vs ()).
  4. Choose based on need for a list versus streaming consumption.

Q24. How do sets work internally?

  1. Sets use hash tables to store unique elements.
  2. Provide average O(1) membership tests.
  3. Support set algebra operations (|, &, -).
  4. frozenset supplies an immutable, hashable counterpart.

Q25. What are dictionaries and why are they powerful?

  1. Hash-table-based mappings from keys to values.
  2. Preserve insertion order in CPython 3.7+.
  3. Methods include get, setdefault, update, items.
  4. Fit configuration, caching, and object-like storage scenarios.

Q26. Explain dictionary view objects.

  1. keys(), values(), and items() return dynamic views.
  2. Views reflect live changes in dictionaries.
  3. Set operations supported on keys and items.
  4. Views avoid copying large collections.

Q27. When to use collections.defaultdict vs dict.setdefault?

  1. defaultdict auto-creates default values for missing keys.
  2. setdefault inserts defaults manually per access.
  3. defaultdict cleaner for frequent default insertions.
  4. Use setdefault for finer control with varying defaults.

Q28. Describe collections.Counter.

  1. Specialized dict mapping elements to counts.
  2. Provides most_common, arithmetic operations, and elements.
  3. Efficient for frequency analysis.
  4. Combine counters via addition/subtraction.

Q29. How do slicing rules work for sequences?

  1. seq[start:stop:step] returns subsequences.
  2. Start inclusive, stop exclusive.
  3. Defaults: start=0, stop=len, step=1.
  4. Negative indices reference from end; negative step reverses.

Q30. Explain shallow vs deep copies.

  1. Shallow copies recreate container but reference same items.
  2. Deep copies recursively duplicate nested objects.
  3. Use copy.copy and copy.deepcopy.
  4. Override __copy__ when custom copy behavior required.

Q31. What is a memoryview and when useful?

  1. Exposes buffer interface without duplicating data.
  2. Works with bytes-like objects for zero-copy slices.
  3. Use for IO-heavy operations to reduce allocations.
  4. Supports casting formats and slicing.

Q32. How do bytearray and bytes differ?

  1. bytes immutable; bytearray mutable.
  2. Both represent sequences of integers (0–255).
  3. bytearray allows in-place modifications.
  4. Convert via .encode() / .decode().

Q33. How are strings stored and manipulated?

  1. Strings are immutable Unicode sequences.
  2. CPython uses flexible internal representation (1/2/4 bytes per char).
  3. Methods include strip, split, join, format, casefold.
  4. Encode/decode for conversions to bytes.

Q34. Explain join vs concatenation.

  1. ''.join(iterable) efficiently concatenates multiple strings.
  2. Repeated + or += creates intermediate objects.
  3. Prefer StringIO for incremental building when necessary.

Q35. Discuss in operator semantics.

  1. Calls __contains__ if defined; otherwise iterates.
  2. For dicts, checks keys.
  3. Strings use substring search.
  4. Performance depends on underlying data structure.

Q36. How do sorted and .sort() differ?

  1. sorted(iterable) returns new list.
  2. list.sort() sorts in place and returns None.
  3. Both employ stable Timsort with key and reverse options.
  4. Avoid assigning result of .sort() to a variable.

Q37. Explain bisect module usage.

  1. Provides binary search helpers for sorted lists.
  2. bisect_left and bisect_right find insertion points.
  3. insort inserts while preserving order.
  4. Maintains sorted lists without re-sorting.

Q38. Describe array module vs list.

  1. Arrays store uniform numeric data with less memory.
  2. Use type codes ('i', 'f') for element types.
  3. Faster numeric operations than lists of Python objects.
  4. Useful when NumPy unavailable.

Q39. When to use deque?

  1. Double-ended queue with O(1) append/pop on both ends.
  2. Methods include appendleft, popleft, rotate.
  3. Excellent for BFS and sliding windows.
  4. Optional maxlen creates fixed-size buffers.

Q40. What is heapq good for?

  1. Implements priority queue as min-heap.
  2. Operations include heappush, heappop, heapreplace.
  3. nlargest and nsmallest extract top elements efficiently.
  4. Custom ordering via tuples or decorated values.

Chapter 3: Functions & Functional Style (Q41–Q60)

Q41. How do default arguments work and what pitfalls exist?

  1. Defaults evaluated once at function definition.
  2. Mutable defaults persist between calls causing bugs.
  3. Use sentinel (e.g., None) and assign inside function.
  4. Document behavior of optional parameters.

Q42. Explain positional-only and keyword-only parameters.

  1. Use / to mark positional-only parameters.
  2. Use * to mark keyword-only parameters.
  3. Helps enforce API usage and clarity.
  4. Example: def func(a, /, b, *, c): ....

Q43. How does *args and **kwargs work?

  1. *args captures extra positional arguments as tuple.
  2. **kwargs captures keyword arguments as dict.
  3. Expand sequences with * and mappings with **.
  4. Validate arguments to avoid silent errors.

Q44. What are function annotations used for?

  1. Provide metadata in __annotations__ (often type hints).
  2. Not enforced at runtime.
  3. Works with tools like mypy and IDEs.
  4. Can support documentation or custom processing.

Q45. How to create higher-order functions?

  1. Functions accept or return other functions.
  2. Utilize closures to capture state.
  3. Example factory pattern multiplies input by constant.
  4. Enables flexible composition and callbacks.

Q46. Explain closures.

  1. Inner functions retain access to enclosing scope variables.
  2. Stored in function’s __closure__.
  3. Use nonlocal to modify captured variables.
  4. Implement factories and stateful behaviors.

Q47. When to use lambda?

  1. Concise anonymous functions for simple expressions.
  2. Avoid complex logic; prefer def for readability.
  3. Common in callbacks, sorting keys.
  4. Lambdas return expression results automatically.

Q48. How does map, filter, reduce compare to comprehensions?

  1. map applies transformation lazily.
  2. filter selects items based on predicate.
  3. reduce folds iterable with binary function.
  4. Comprehensions often clearer but functions integrate with existing callables.

Q49. Explain partial application with functools.partial.

  1. Pre-binds arguments to functions, returning new callable.
  2. Simplifies repeated function calls with fixed parameters.
  3. Maintains original metadata via partial.func.
  4. Cleaner alternative to small lambdas.

Q50. What is functools.lru_cache?

  1. Decorator caches function results keyed by arguments.
  2. Controls cache size with maxsize.
  3. typed=True differentiates arguments by type.
  4. Inspect performance via .cache_info() and reset with .cache_clear().

Q51. How to implement function decorators?

  1. Decorator receives function and returns wrapper.
  2. Use functools.wraps to preserve metadata.
  3. Inside wrapper handle pre/post logic then call original.
  4. Apply via @decorator syntax above function definition.

Q52. Explain decorator order when stacking.

  1. Decorators apply bottom-up; nearest to function runs first.
  2. @A above @B means A(B(func)).
  3. Order affects behavior when decorators interact.
  4. Document stacking expectations to avoid surprises.

Q53. What is functools.singledispatch?

  1. Provides generic functions dispatching on first argument type.
  2. Use @singledispatch on base implementation.
  3. Register specialized implementations via .register(Type).
  4. singledispatchmethod extends pattern to class methods.

Q54. How do generators differ from iterators?

  1. Generators defined with yield produce values lazily.
  2. Generators automatically implement iterator protocol.
  3. Iterators require __iter__ and __next__.
  4. Use generators for large or infinite sequences.

Q55. Explain generator expressions vs generator functions.

  1. Expressions offer concise inline generators.
  2. Functions allow complex logic, multiple yields, state.
  3. Choose expression for simple transformations.
  4. Prefer function when control flow or readability demands.

Q56. How does yield from work?

  1. Delegates part of generator to sub-iterator.
  2. Eliminates manual loops yielding from nested iterables.
  3. Propagates send, throw, close calls.
  4. Simplifies coroutine composition.

Q57. What is the difference between return and yield inside generators?

  1. yield emits next value and suspends execution.
  2. return value raises StopIteration(value) with final result.
  3. yield maintains generator state; return terminates.
  4. Access return value via generator.value in Python 3.3+.

Q58. How do context managers relate to functions?

  1. with statement ensures setup/teardown around block.
  2. contextlib.contextmanager turns generator into context manager.
  3. yield splits enter and exit logic.
  4. Guarantees cleanup of resources (files, locks).

Q59. Explain recursion limits and tail recursion.

  1. Python sets recursion depth limit to prevent overflow.
  2. No tail-call optimization; tail recursion still consumes stack.
  3. Convert deep recursion to iterative approach when possible.
  4. Adjust limit cautiously via sys.setrecursionlimit.

Q60. How to document functions effectively?

  1. Use docstrings describing purpose, parameters, returns, exceptions.
  2. Follow style guides (Google, NumPy, reST).
  3. Pair with type hints for clarity.
  4. Keep documentation consistent across codebase.

Chapter 4: Object-Oriented Programming (Q61–Q80)

Q61. How are classes created and what is __init__?

  1. class statement executes to build class namespace.
  2. __init__ runs post-instantiation to initialize attributes.
  3. __new__ controls object creation if overridden.
  4. Python 3 implicitly inherits from object.

Q62. Explain inheritance in Python.

  1. Subclasses extend base classes using class Sub(Base):.
  2. Multiple inheritance supported; follow MRO.
  3. Use super() to access parent implementations.
  4. Design mixins for reusable behaviors.

Q63. What is method resolution order (MRO)?

  1. Determines attribute lookup order in inheritance hierarchy.
  2. Python uses C3 linearization.
  3. Inspect via Class.__mro__ or Class.mro().
  4. Ensures predictable lookup with multiple inheritance.

Q64. How do class and static methods differ?

  1. @classmethod receives class (cls).
  2. @staticmethod receives no implicit arguments.
  3. Instance methods receive self.
  4. Use classmethods for alternate constructors or class-level operations.

Q65. Explain properties and descriptors.

  1. property converts methods into managed attributes.
  2. Descriptors implement __get__, __set__, __delete__.
  3. Data descriptors override instance dictionaries.
  4. Enable validation, caching, computed attributes.

Q66. What is __slots__?

  1. Declares fixed attribute set to avoid per-instance __dict__.
  2. Reduces memory usage and speeds attribute access.
  3. Syntax: __slots__ = ('x', 'y').
  4. Limits dynamic attribute creation; impacts inheritance.

Q67. Explain operator overloading.

  1. Implement special methods (__add__, __eq__, etc.) for operators.
  2. Return NotImplemented when operation unsupported.
  3. Ensure behavior remains predictable and consistent.
  4. functools.total_ordering can derive comparison methods.

Q68. How does __repr__ differ from __str__?

  1. __repr__ yields unambiguous developer-facing representation.
  2. __str__ produces user-friendly string.
  3. repr(obj) calls __repr__; str(obj) falls back to __repr__.
  4. Provide informative diagnostics in __repr__.

Q69. Describe dynamic attribute access.

  1. __getattr__ called for missing attributes.
  2. __getattribute__ intercepts all accesses; use carefully.
  3. __setattr__ and __delattr__ manage assignment/deletion.
  4. Useful for proxies, lazy loading, and dynamic APIs.

Q70. What are metaclasses?

  1. Classes of classes controlling class creation.
  2. Default metaclass type can be customized by overriding __new__.
  3. Declare via class Foo(metaclass=Meta):.
  4. Apply to enforce interfaces or auto-register subclasses.

Q71. How does multiple inheritance using mixins work?

  1. Mixins provide focused functionality combined with other bases.
  2. Conventionally named SomethingMixin.
  3. Ensure mixin methods call super() to cooperate.
  4. Document dependencies and expected attributes.

Q72. Explain abstract base classes (ABCs).

  1. Defined with abc module and @abstractmethod.
  2. Prevent instantiation until abstract methods implemented.
  3. Support virtual subclassing via register.
  4. Enforce interface contracts.

Q73. How does dataclasses simplify class creation?

  1. @dataclass auto-generates init, repr, eq, etc.
  2. Fields configured via field (defaults, metadata).
  3. Supports default factories and post-init hooks.
  4. Works with type hints to document structure.

Q74. When to use __post_init__?

  1. Executes after dataclass-generated __init__.
  2. Ideal for validation or derived attribute assignment.
  3. Pair with init=False fields to set computed values.

Q75. Compare namedtuple vs dataclass.

  1. namedtuple lightweight, immutable, tuple-based.
  2. dataclass mutable by default with richer feature set.
  3. Choose based on mutability and method needs.
  4. typing.NamedTuple adds type hints using class syntax.

Q76. Explain method overriding and super().

  1. Subclass redefines method from base class.
  2. super() invokes next method in MRO chain.
  3. Use especially in __init__ for cooperative initialization.
  4. Zero-argument super() preferred in modern Python.

Q77. How to implement singleton pattern?

  1. Override __new__ to return existing instance.
  2. Alternatively use module-level singletons.
  3. Ensure thread safety if accessed concurrently.
  4. Evaluate whether dependency injection is better alternative.

Q78. Explain composition vs inheritance.

  1. Composition assembles behavior via contained objects (has-a).
  2. Inheritance extends behavior via parent classes (is-a).
  3. Favor composition to reduce coupling and increase flexibility.
  4. Use inheritance when substitutability requirements exist.

Q79. Describe polymorphism in Python.

  1. Objects with shared interface can be used interchangeably.
  2. Duck typing allows polymorphism without inheritance.
  3. ABCs and Protocols formalize interfaces when needed.
  4. Enables decoupled, modular code design.

Q80. How to serialize custom objects?

  1. Implement __getstate__/__setstate__ for pickle control.
  2. Convert to dictionaries for JSON serialization.
  3. Utilize libraries (marshmallow, pydantic) for validation and schemas.
  4. Never unpickle untrusted data due to security risks.

Chapter 5: Modules, Packaging & Environments (Q81–Q100)

Q81. How to structure a Python project?

  1. Adopt src/ or flat layout with clear package boundaries.
  2. Include pyproject.toml, README, tests, and docs.
  3. Separate application logic from configuration/resources.
  4. Follow modern packaging best practices.

Q82. Explain __init__.py role.

  1. Marks directory as package (unless using namespace packages).
  2. Executes during package import.
  3. Re-export public API elements for convenience.
  4. Avoid expensive side effects in package initialization.

Q83. What is a virtual environment?

  1. Isolated interpreter environment with independent dependencies.
  2. Create with python -m venv env.
  3. Activation adjusts PATH to use environment-specific Python.
  4. Prevents dependency conflicts across projects.

Q84. Compare pip, pipenv, and poetry.

  1. pip installs packages using requirements files.
  2. pipenv combines pip and virtualenv with Pipfile/lock.
  3. poetry manages dependencies, lockfiles, and builds in one tool.
  4. Select tool aligning with team workflow.

Q85. How does dependency resolution work?

  1. Installer computes compatible versions to satisfy requirements.
  2. Lockfiles capture resolved versions for reproducibility.
  3. Semantic version specifiers guide upgrade boundaries.
  4. Regular updates mitigate security risks.

Q86. Describe packaging with pyproject.toml.

  1. PEP 518/621 define build-system configuration in TOML.
  2. [build-system] specifies backend (setuptools, poetry).
  3. [project] holds metadata like name, version, dependencies.
  4. Replaces setup.py for many modern packages.

Q87. How to publish a package to PyPI?

  1. Prepare metadata, README, and license.
  2. Build distribution via python -m build.
  3. Upload using twine upload dist/*.
  4. Test on TestPyPI before full release.

Q88. What are entry points?

  1. Configure console scripts in packaging metadata.
  2. Map command names to module callables.
  3. Powers plugin systems (e.g., pytest).
  4. Example: [project.scripts] cli = pkg.module:main.

Q89. How does module caching work?

  1. sys.modules stores loaded modules.
  2. Re-importing returns cached module object.
  3. importlib.reload re-executes module code when needed.
  4. Understand for plugin management and hot reloading.

Q90. When to use relative vs absolute imports?

  1. Absolute imports (from package import module) preferred for clarity.
  2. Relative imports (from .submodule import name) reduce repetition inside packages.
  3. Avoid deep relative paths to maintain readability.
  4. Stay consistent within project.

Q91. Explain importlib utilities.

  1. import_module dynamically imports modules by string name.
  2. importlib.resources accesses package data files.
  3. importlib.metadata retrieves installed package metadata.
  4. Useful for plugin systems and runtime configuration.

Q92. How to manage configuration?

  1. Use environment variables, config files, or dedicated modules.
  2. Libraries such as configparser, pydantic, dynaconf provide structure.
  3. Separate config per environment.
  4. Store secrets securely and avoid hardcoding.

Q93. How does logging configuration work?

  1. logging module manages hierarchical loggers.
  2. Configure via basicConfig, dictConfig, or fileConfig.
  3. Handlers, formatters, and filters control output.
  4. Prefer logging over print for production diagnostics.

Q94. Explain environment management across OSes.

  1. python -m venv works cross-platform.
  2. Activation scripts differ on Windows vs Unix.
  3. For Python versions, use pyenv (Unix) or installs via official sources on Windows.
  4. Document setup steps for contributors.

Q95. What is site-packages?

  1. Directory containing installed third-party packages.
  2. Virtual environments maintain isolated site-packages directories.
  3. Inspect paths via site.getsitepackages().
  4. pip install --target installs to custom locations.

Q96. How to handle namespace packages?

  1. Omit __init__.py to allow package spanning multiple directories.
  2. Native namespace packages require PEP 420 support.
  3. Useful for large projects split across repos.
  4. Manage to avoid import collisions.

Q97. Explain __all__ usage.

  1. Defines public names exported by from module import *.
  2. Controls module API surface.
  3. Documentation tools may respect __all__.
  4. Optional but helpful for clarity.

Q98. How to create reusable CLI tools?

  1. Encapsulate entry logic in main() function.
  2. Use argparse, click, or typer for argument parsing.
  3. Provide console script entry points in metadata.
  4. Include --help messages and usage examples.

Q99. How to version a package?

  1. Follow semantic versioning (MAJOR.MINOR.PATCH).
  2. Store version in module (__version__) or metadata.
  3. Automate bumps with setuptools_scm or bumpversion.
  4. Maintain changelog synchronized with releases.

Q100. What is a wheel file?

  1. Binary distribution format with .whl extension.
  2. Enables fast installs without build step.
  3. Pure Python wheels universal; binary wheels platform specific.
  4. Generate via python -m build.

Chapter 6: Advanced Language Features (Q101–Q120)

Q101. How do decorators work under the hood?

  1. Function object passed to decorator at definition time.
  2. Decorator returns wrapper replacing original function.
  3. Equivalent to assignment func = decorator(func).
  4. Parameterized decorators return decorator factory.

Q102. Explain descriptor protocol.

  1. Objects implementing __get__, __set__, __delete__ control attribute access.
  2. Data descriptors define both __get__ and __set__.
  3. Non-data descriptors (like functions) only implement __get__.
  4. Foundation for properties, methods, and managed attributes.

Q103. What is monkey patching?

  1. Runtime modification of modules or classes by reassignment.
  2. Useful in testing or compatibility fixes.
  3. Risky due to hidden side effects.
  4. Use unittest.mock.patch to scope patches safely.

Q104. How does __call__ enable callable objects?

  1. Defining __call__ makes instances behave like functions.
  2. Supports stateful operations with function interface.
  3. Combine with functools.update_wrapper to mimic function metadata.
  4. Useful in strategy patterns and configurables.

Q105. Explain context manager protocol.

  1. __enter__ executes at block start, returning value.
  2. __exit__ handles cleanup and receives exception info.
  3. Returning True from __exit__ suppresses exception propagation.
  4. Manage resources reliably with with statements.

Q106. What is contextlib.ExitStack?

  1. Manages dynamic stacks of context managers.
  2. Allows programmatic entering of contexts.
  3. Guarantees LIFO cleanup even with variable resources.
  4. Supports registering arbitrary callbacks via callback().

Q107. How do slots interact with inheritance?

  1. Subclasses must define their own __slots__ including inherited names.
  2. Without __slots__, subclass gains __dict__.
  3. Multiple inheritance requires careful slot configuration.
  4. Include '__weakref__' if instances need weak references.

Q108. Explain interplay of method decorators.

  1. @property applies only to instance methods.
  2. @classmethod and @staticmethod cannot combine with @property.
  3. For class-level properties, use metaclass or descriptors.
  4. Decorator order affects resulting descriptor type.

Q109. What is the __prepare__ method in metaclasses?

  1. Called before class body execution to provide custom namespace.
  2. Returns mapping used for class attributes (e.g., OrderedDict).
  3. Useful for DSLs or tracking declaration order.
  4. Allows validation during class creation.

Q110. How does enum module work?

  1. Enum defines symbolic names bound to constant values.
  2. Members are unique and comparable by identity.
  3. auto() assigns incremental values automatically.
  4. IntEnum and Flag provide numeric interoperability and bit flags.

Q111. Explain typing module basics.

  1. Type hints annotate variables and functions.
  2. Use List, Dict, Optional, Union, Callable.
  3. Python 3.9+ supports builtin generic types (list[int]).
  4. Type hints aid static analysis, documentation, IDE assistance.

Q112. How do Protocols support structural typing?

  1. typing.Protocol defines required methods/attributes.
  2. Classes implementing structure implicitly satisfy protocol.
  3. Enables duck typing with static type checking.
  4. Use runtime_checkable for runtime isinstance checks.

Q113. Explain typing.NewType.

  1. Creates distinct type alias for static checking.
  2. UserId = NewType("UserId", int) differentiates from plain int.
  3. Runtime value equals underlying type.
  4. Enhances type safety without runtime cost.

Q114. What is covariance and contravariance?

  1. Covariant types allow substitution with subtypes.
  2. Contravariant types allow substitution with supertypes.
  3. Python generics default to invariance unless declared.
  4. Use TypeVar('T_co', covariant=True) for covariance.

Q115. How does typing.Any differ from object?

  1. Any disables static type checking for value.
  2. object enforces explicit casting or attribute checks.
  3. Overuse of Any reduces type safety.
  4. Reserve Any for truly dynamic interfaces.

Q116. Explain typing.TypedDict.

  1. Defines dict-like structures with fixed key types.
  2. Supports optional keys and total/partial modes.
  3. Ideal for JSON payloads and configuration schemas.
  4. Works with type checkers to validate dict shape.

Q117. What is pattern matching (PEP 634)?

  1. match/case enable structural pattern matching.
  2. Supports literals, sequences, mappings, class patterns.
  3. Guard clauses add conditional filters.
  4. case _ acts as default fallback.

Q118. Explain dataclasses.field options.

  1. default and default_factory specify default values.
  2. Flags like init, repr, compare, hash customize behavior.
  3. metadata stores arbitrary information.
  4. Use init=False for computed fields set in __post_init__.

Q119. How does functools.cache differ from lru_cache?

  1. cache is unlimited-size variant introduced in Python 3.9.
  2. Equivalent to lru_cache(maxsize=None).
  3. Simplified decorator when eviction unnecessary.
  4. Manage unbounded growth carefully.

Q120. What is weakref module for?

  1. Maintains references without preventing garbage collection.
  2. Supports caches, observer patterns, and avoidance of cycles.
  3. WeakKeyDictionary and WeakValueDictionary auto-remove collected objects.
  4. Objects need __weakref__ support to be weakly referencable.

Chapter 7: Concurrency & Parallelism (Q121–Q140)

Q121. Describe the Global Interpreter Lock (GIL).

  1. Mutex in CPython allowing one thread to execute bytecode at a time.
  2. Simplifies memory management but limits CPU-bound threading.
  3. I/O operations release GIL, enabling concurrency for blocking IO.
  4. Alternatives include multiprocessing, asyncio, or C extensions.

Q122. When to use threading module?

  1. Best for I/O-bound tasks (network, disk).
  2. Provides Thread, Lock, Event, Condition, Semaphore.
  3. Protect shared state with synchronization primitives.
  4. GIL restricts CPU-bound scaling.

Q123. How does queue.Queue help concurrency?

  1. Thread-safe FIFO structure for producer-consumer patterns.
  2. put, get, task_done, join manage coordination.
  3. Supports blocking operations with timeouts.
  4. Variants include LifoQueue and PriorityQueue.

Q124. Compare multiprocessing to threading.

  1. multiprocessing launches separate processes bypassing GIL.
  2. Ideal for CPU-intensive workloads.
  3. Overhead includes inter-process communication and process startup.
  4. Provides Process, Pool, Manager.

Q125. What is concurrent.futures?

  1. High-level API for parallel execution.
  2. ThreadPoolExecutor and ProcessPoolExecutor.
  3. Futures represent asynchronous results with callbacks.
  4. Methods: submit, map, as_completed.

Q126. How does asyncio event loop function?

  1. Manages scheduling of coroutines and callbacks.
  2. asyncio.run starts and manages event loop lifecycle.
  3. Coroutines yield control via await, enabling cooperative multitasking.
  4. Single-threaded but handles massive concurrent I/O.

Q127. Explain coroutines and async/await.

  1. async def defines coroutines returning awaitable objects.
  2. await pauses coroutine until awaited task completes.
  3. Coroutines integrate with event loop for non-blocking operations.
  4. Compose with tasks, futures, and gather patterns.

Q128. How to create asynchronous context managers?

  1. Implement __aenter__ and __aexit__.
  2. Use async with for asynchronous resource management.
  3. contextlib.asynccontextmanager simplifies generator-based contexts.
  4. Ensure proper cleanup of async resources.

Q129. When to use asyncio.TaskGroup?

  1. Python 3.11 structured concurrency primitive.
  2. Groups related tasks with automatic cancellation on failure.
  3. Ensures deterministic cleanup of child tasks.
  4. Use async with TaskGroup() as tg: to spawn tasks.

Q130. How does async exception propagation work?

  1. Exceptions raised inside coroutine surface when awaited.
  2. Background tasks log unhandled exceptions; inspect via task.exception().
  3. Use asyncio.gather with return_exceptions=True to collect failures.
  4. Structured concurrency simplifies error handling.

Q131. Explain asyncio.Queue.

  1. Asynchronous FIFO for coroutine communication.
  2. await queue.put() and await queue.get() operations.
  3. Supports maxsize, task_done, join.
  4. Useful in producer-consumer coroutine patterns.

Q132. How to integrate blocking code in async context?

  1. Offload to thread with asyncio.to_thread() (Py3.9+).
  2. Alternatively use loop.run_in_executor.
  3. Prevents blocking event loop.
  4. For CPU-bound work, consider process pool.

Q133. Explain actor model with multiprocessing.

  1. Actors encapsulate state and communicate via messages.
  2. Use queues or pipes for inter-process messaging.
  3. Avoid shared mutable state.
  4. Simplifies reasoning about concurrency and failure isolation.

Q134. What is Gevent/eventlet?

  1. Third-party libraries using greenlets for cooperative multitasking.
  2. Monkey patch blocking operations for async behavior.
  3. Suited for network servers requiring large concurrency.
  4. Not part of standard library; evaluate compatibility implications.

Q135. How to manage concurrency in web frameworks?

  1. Async frameworks (FastAPI, aiohttp) for I/O scalability.
  2. Understand server concurrency models (WSGI vs ASGI).
  3. Offload CPU-heavy tasks to background workers.
  4. Configure database pools for concurrent access.

Q136. What is asyncio.Lock and when needed?

  1. Async mutual exclusion primitive.
  2. Use async with lock: to guard shared state.
  3. Prevents simultaneous coroutine access to critical sections.
  4. Avoid unnecessary locking to maintain throughput.

Q137. Explain cancellation in asyncio.

  1. task.cancel() requests cancellation raising CancelledError.
  2. Coroutines should catch and handle for cleanup.
  3. asyncio.shield protects tasks from cancellation.
  4. Task groups propagate cancellation to child tasks.

Q138. How do deadlines and timeouts work?

  1. asyncio.wait_for enforces timeout on awaitables.
  2. Python 3.11 asyncio.timeout context simplifies usage.
  3. Threads use timeouts on blocking calls (e.g., queue.get).
  4. Unix-only signal module allows alarm-based timeouts.

Q139. Discuss concurrency pitfalls.

  1. Race conditions arise from unprotected shared state.
  2. Deadlocks occur with circular lock acquisition.
  3. Starvation happens when tasks are perpetually deferred.
  4. Data corruption results from non-atomic operations.

Q140. When to choose reactive frameworks like RxPY?

  1. Suitable for event-driven, stream-processing applications.
  2. Offers composable operators for transformation and filtering.
  3. Integrates with asyncio for async streams.
  4. Beware of steep learning curve and complexity.

Chapter 8: Testing, Debugging & Quality (Q141–Q160)

Q141. How to structure unit tests?

  1. Use unittest or pytest frameworks.
  2. Follow Arrange-Act-Assert pattern.
  3. Keep tests deterministic and isolated.
  4. Name tests descriptively for readability.

Q142. Why prefer pytest fixtures?

  1. Provide reusable setup and teardown logic.
  2. Support scopes (function, module, session).
  3. Enable parametrization for input variations.
  4. Simplify dependency injection.

Q143. How does mocking work with unittest.mock?

  1. patch replaces objects during tests (target where used).
  2. Mock/MagicMock auto-create attributes.
  3. Assert behavior with assert_called_once_with.
  4. Use context managers or decorators to limit patch scope.

Q144. Explain property-based testing.

  1. Use hypothesis to generate test cases automatically.
  2. Define invariants rather than specific examples.
  3. Reveals edge cases beyond manual tests.
  4. Combine with unit tests for thorough coverage.

Q145. How to test asynchronous code?

  1. Use pytest.mark.asyncio or event loop fixtures.
  2. Await coroutines within async tests.
  3. Mock async functions with AsyncMock.
  4. Ensure event loop cleanup between tests.

Q146. How do you profile Python code?

  1. cProfile profiles function call statistics.
  2. Analyze with pstats or visualize via snakeviz.
  3. timeit evaluates micro-benchmarks.
  4. Profile realistic workloads to identify bottlenecks.

Q147. Explain debugging with pdb.

  1. Launch via python -m pdb script.py or pdb.set_trace().
  2. Commands: n (next), s (step), c (continue), l (list).
  3. Set breakpoints with break.
  4. Enhanced debuggers (ipdb, pudb) add usability.

Q148. What are linters and formatters?

  1. Linters (flake8, pylint) detect style and logical issues.
  2. Formatters (black, yapf) enforce consistent style automatically.
  3. Integrate via pre-commit hooks or CI.
  4. Combine tools to maintain code quality.

Q149. How to enforce type checking?

  1. Run mypy, pyright, or pytype.
  2. Configure settings via config files.
  3. Address warnings incrementally to improve coverage.
  4. Use typing.cast sparingly for legitimate overrides.

Q150. Explain continuous integration best practices.

  1. Automate tests, linters, and type checks on commits.
  2. Use hosted CI (GitHub Actions, GitLab, Jenkins).
  3. Maintain deterministic environments with lockfiles.
  4. Fail fast and provide actionable feedback.

Q151. How to test CLI tools?

  1. Invoke via subprocess.run or CLI testing helpers.
  2. Mock environment variables and file system as needed.
  3. Capture stdout/stderr with pytest’s capsys.
  4. Validate exit codes and side effects.

Q152. What is mutation testing?

  1. Intentionally modify code (mutants) to ensure tests detect changes.
  2. Tools like mutmut or cosmic-ray automate process.
  3. Measures robustness of test suite.
  4. Resource-intensive but uncovers weak tests.

Q153. How to debug memory leaks?

  1. Use tracemalloc to track allocations.
  2. Inspect object graphs with objgraph.
  3. Identify reference cycles and caches.
  4. Break cycles or use weak references to resolve leaks.

Q154. Explain coverage analysis.

  1. coverage.py measures executed lines and branches.
  2. Integrate with pytest via pytest --cov.
  3. Aim for meaningful coverage, not just high percentages.
  4. Review reports for critical untested paths.

Q155. How to test database interactions?

  1. Use fixtures to prepare test databases.
  2. Apply transactions with rollback per test.
  3. Mock ORM layers when unit testing logic.
  4. Separate integration tests for full stack validation.

Q156. What is regression testing?

  1. Ensures new changes do not reintroduce past bugs.
  2. Maintain regression suite containing previous failures.
  3. Automate execution to catch regressions early.
  4. Pair with bug tracking to document coverage.

Q157. How to handle flaky tests?

  1. Diagnose underlying flakiness (timing, dependencies).
  2. Stabilize with deterministic setup or isolation.
  3. Use retries sparingly as temporary mitigation.
  4. Monitor CI to ensure flakiness resolved.

Q158. Explain test-driven development (TDD).

  1. Write failing test (red).
  2. Implement minimal code to pass (green).
  3. Refactor while keeping tests passing.
  4. Encourages design clarity and regression safety.

Q159. How to organize test directories?

  1. Place tests in dedicated tests/ directory.
  2. Mirror application structure for clarity.
  3. Use conftest.py for shared fixtures.
  4. Mark integration tests for selective runs.

Q160. How to document debugging sessions?

  1. Record steps, hypotheses, and commands executed.
  2. Store notes in issue tracker or log.
  3. Share findings for team knowledge.
  4. Helps future troubleshooting.

Chapter 9: Data Handling, IO & External Systems (Q161–Q180)

Q161. How to work with files safely?

  1. Use with open(path, mode) as f to ensure closure.
  2. Specify encoding (e.g., utf-8).
  3. Prefer pathlib for cross-platform paths.
  4. Stream large files to avoid memory pressure.

Q162. What is pathlib advantage?

  1. Object-oriented path manipulations.
  2. Methods like .read_text(), .iterdir(), .resolve().
  3. Interoperable with standard library using str(path).
  4. Simplifies cross-platform path operations.

Q163. How to perform JSON serialization?

  1. Use json.dump/load for files and json.dumps/loads for strings.
  2. Provide custom encoders for non-standard types.
  3. Set ensure_ascii=False and indent for readability.
  4. Validate data before serialization.

Q164. Explain CSV handling best practices.

  1. Use csv module with explicit dialects.
  2. Iterate row-by-row for large files.
  3. Consider pandas for complex transformations.
  4. Validate and convert data types explicitly.

Q165. How to connect to databases?

  1. Use DB-API compliant drivers (sqlite3, psycopg2).
  2. Manage connections with context managers or pools.
  3. Parameterize queries to prevent SQL injection.
  4. Consider ORMs for abstraction layers.

Q166. What is SQLAlchemy?

  1. Comprehensive ORM and SQL toolkit.
  2. Declarative models map tables to classes.
  3. Sessions handle transactions and unit-of-work patterns.
  4. Alembic manages migrations.

Q167. How to consume REST APIs?

  1. Use requests with timeouts and error handling.
  2. Manage authentication via headers or sessions.
  3. Parse JSON responses and validate schema.
  4. For async, use httpx or aiohttp.

Q168. Explain streaming large downloads.

  1. Enable streaming with requests.get(..., stream=True).
  2. Iterate using iter_content to process chunks.
  3. Write to disk incrementally to save memory.
  4. Handle interruptions with resume logic if necessary.

Q169. How to perform web scraping responsibly?

  1. Respect robots.txt and site terms.
  2. Use BeautifulSoup, lxml for parsing.
  3. Manage rate limits and caching.
  4. Handle dynamic content with headless browsers (Selenium, Playwright).

Q170. How to parse XML?

  1. xml.etree.ElementTree handles simple parsing.
  2. lxml offers XPath and better performance.
  3. Mitigate vulnerabilities (XXE) by disabling external entities.
  4. Validate against schema when available.

Q171. Explain working with configuration formats (YAML, TOML).

  1. YAML via PyYAML, TOML via tomllib (Py3.11+) or tomli.
  2. Be cautious of YAML features that execute code.
  3. Document schema and defaults.
  4. Validate configuration before use.

Q172. How to use sqlite3 module?

  1. Connect with sqlite3.connect('file.db') or :memory:.
  2. Execute parameterized queries with placeholders.
  3. Manage transactions explicitly (commit, rollback).
  4. Enable foreign keys via PRAGMA foreign_keys = ON.

Q173. What is subprocess module used for?

  1. Spawn and manage external processes.
  2. Use subprocess.run with lists to avoid shell injection.
  3. Capture output using capture_output=True.
  4. Handle errors with check=True.

Q174. How to handle time zones?

  1. Use timezone-aware datetime objects.
  2. zoneinfo (Py3.9+) provides IANA time zone support.
  3. Store times in UTC; convert at boundaries.
  4. For older versions, use pytz.

Q175. Explain scheduling tasks.

  1. Standard sched for basic scheduling.
  2. Production use APScheduler, Celery beat, or cron.
  3. Ensure job idempotency and logging.
  4. Monitor for missed or failed executions.

Q176. How to handle binary protocols?

  1. Use struct to pack and unpack binary data.
  2. Specify endianness with format characters.
  3. For complex protocols, consider libraries like construct.
  4. Validate payload sizes and integrity.

Q177. Explain caching strategies.

  1. In-memory caches using dict or LRU.
  2. Distributed caches (Redis, Memcached) for multi-process scenarios.
  3. Establish invalidation policies (TTL, explicit purge).
  4. Consider consistency and staleness impacts.

Q178. How to work with message queues?

  1. Use libraries (kombu, pika, celery).
  2. Understand delivery semantics (at-most-once, at-least-once).
  3. Serialize messages with JSON, Protobuf, or Avro.
  4. Implement retry and dead-letter handling.

Q179. Explain file locking.

  1. Unix uses fcntl; Windows uses msvcrt.
  2. portalocker offers cross-platform abstraction.
  3. Acquire locks using context managers to ensure release.
  4. Choose advisory vs mandatory locking per requirement.

Q180. How to handle large data processing?

  1. Process in streams or chunks to limit memory usage.
  2. Parallelize with multiprocessing or distributed frameworks (Dask, Spark).
  3. Profile IO and CPU to balance resources.
  4. Optimize algorithms before scaling hardware.

Chapter 10: Architecture, Performance & Best Practices (Q181–Q200)

Q181. How to design modular systems in Python?

  1. Apply Single Responsibility Principle for cohesive modules.
  2. Define interfaces via ABCs or Protocols.
  3. Use dependency injection for testability.
  4. Document boundaries and contracts.

Q182. What is Clean Architecture in Python?

  1. Layers: Entities, Use Cases, Interface Adapters, Frameworks.
  2. Inner layers independent from outer layers.
  3. Implement via packages representing each layer.
  4. Use adapters to interact with external systems.

Q183. How to apply SOLID principles?

  1. Single Responsibility ensures focused classes.
  2. Open/Closed encourages extension without modification.
  3. Liskov Substitution maintains substitutability.
  4. Interface Segregation and Dependency Inversion promote decoupling.

Q184. Explain microservices vs monolith decisions.

  1. Monoliths simpler initially; microservices aid team scaling.
  2. Evaluate deployment complexity and data consistency needs.
  3. Python supports both with frameworks (Flask, FastAPI, Django).
  4. Plan service communication (REST, gRPC) and observability.

Q185. How to design RESTful APIs in Python?

  1. Use frameworks (FastAPI, Flask, Django REST Framework).
  2. Model endpoints around resources and HTTP verbs.
  3. Validate input via pydantic or serializers.
  4. Provide pagination, error handling, and versioning.

Q186. What is asynchronous web architecture?

  1. ASGI servers (uvicorn, hypercorn) execute async views.
  2. Async frameworks leverage event loop for concurrency.
  3. Offload long-running work to background tasks.
  4. Contrast with WSGI’s synchronous model.

Q187. How to optimize performance?

  1. Profile first to locate hotspots.
  2. Use appropriate data structures and algorithms.
  3. Apply caching/memoization.
  4. Employ C extensions or vectorized libraries when necessary.

Q188. When to use Cython or CPython extensions?

  1. Suitable for CPU-bound sections needing C-like speed.
  2. Cython compiles annotated Python-like code to C.
  3. ctypes and cffi interface with existing C libraries.
  4. Balance performance gains against build complexity.

Q189. How to handle configuration secrets securely?

  1. Store secrets outside source control.
  2. Use environment variables or secret managers (Vault, AWS Secrets Manager).
  3. Encrypt at rest and restrict access.
  4. Rotate credentials regularly.

Q190. What is observability stack in Python apps?

  1. Metrics (Prometheus), logs (JSON/structured), traces (OpenTelemetry).
  2. Instrument code for distributed tracing.
  3. Provide health and readiness endpoints.
  4. Correlate logs with request IDs.

Q191. Explain graceful shutdown.

  1. Handle termination signals (SIGTERM) for cleanup.
  2. For asyncio, cancel tasks and close loop.
  3. Ensure resources (files, DB connections) close properly.
  4. Implement idempotent cleanup handlers.

Q192. How to handle configuration for multiple environments?

  1. Layer configs (base + environment overrides).
  2. Keep secrets separate from general config.
  3. Document environment variables and defaults.
  4. Validate configuration during startup.

Q193. What is feature flagging?

  1. Toggle features at runtime via configuration.
  2. Support gradual rollouts and A/B testing.
  3. Implement with config files or services (LaunchDarkly).
  4. Remove stale flags to reduce complexity.

Q194. How to integrate CI/CD pipelines?

  1. Automate build, test, lint, and deployment.
  2. Use Infrastructure as Code tools to manage environments.
  3. Adopt deployment strategies (blue/green, canary).
  4. Monitor post-deployment metrics for regressions.

Q195. Explain containerizing Python apps.

  1. Write Dockerfile using official Python base image.
  2. Install dependencies via requirements.txt or poetry export.
  3. Use multi-stage builds for smaller images.
  4. Manage configuration through environment variables.

Q196. How to ensure thread-safety in web apps?

  1. Avoid shared mutable global state.
  2. Configure WSGI/ASGI server workers and threads appropriately.
  3. Use thread-safe connection pools.
  4. Leverage external caches or databases for shared state.

Q197. What is domain-driven design (DDD) in Python?

  1. Focus on domain model with ubiquitous language.
  2. Entities, value objects, aggregates structure domain logic.
  3. Repositories abstract persistence.
  4. Combine with dataclasses and type hints for clarity.

Q198. How to manage migrations?

  1. Use Alembic or Django migrations for schema changes.
  2. Version migrations and run in CI.
  3. Handle data migrations carefully with scripts or management commands.
  4. Prepare rollback plans for failures.

Q199. How to implement background processing?

  1. Use task queues (Celery, RQ, Dramatiq).
  2. Run workers separate from web servers.
  3. Manage retries, backoff, and idempotency.
  4. Monitor queues and task health.

Q200. What are best practices for code reviews?

  1. Prioritize correctness, readability, maintainability.
  2. Use review checklists (tests, docs, security).
  3. Provide specific, constructive feedback.
  4. Encourage small PRs and automate quality checks.

Usage Tips

  • Review chapters aligned with target job requirements.
  • Implement practice projects and exercises for reinforcement.
  • Rehearse explanations aloud to build confidence.
  • Pair study with mock interviews or timed practice sessions.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published