Skip to content

Latest commit

 

History

History
75 lines (63 loc) · 4.13 KB

File metadata and controls

75 lines (63 loc) · 4.13 KB
layout default
title Interview Problems
parent Practice and Projects
nav_order 3
permalink /practice/interview-problems/

Intermediate Interview Problems

Complete these after the numbered lessons. In an interview, explain the input, edge cases, plan, and trade-offs before writing code. A readable correct solution is better than a clever unfinished one.

Problems

  1. Group order records by customer while preserving the original order.
  2. Flatten a nested list whose depth is not known in advance.
  3. Build a fixed-capacity least-recently-used cache.
  4. Write a retry decorator with a maximum attempt count and injectable delay function.
  5. Create an iterator that reads valid records from a large text file.
  6. Merge several already-sorted iterables without loading every value at once.
  7. Design a repository interface and SQLite implementation for a task service.
  8. Test a notification service without sending a real email.
  9. Parse an API response while reporting missing and invalid fields clearly.
  10. Process many files concurrently and return successes and failures in input order.
  11. Detect repeated words in text with punctuation and mixed letter case.
  12. Design a command-line tool with subcommands and meaningful exit codes.
  13. Explain and fix a circular import between two modules.
  14. Compare a list comprehension, generator expression, and normal loop for one task.
  15. Investigate a race condition in a shared counter and redesign the communication.
Show hints
  1. A dictionary can map each customer to a list.
  2. Decide whether strings count as nested collections; recursion or an explicit stack can help.
  3. Combine a key lookup with a structure that records recent use.
  4. The wrapper needs *args, **kwargs, a loop, and a narrow exception policy.
  5. Open the file in a generator and yield one validated record.
  6. Study a heap or heapq.merge() after writing a two-iterable version.
  7. Keep business rules independent of SQL details.
  8. Inject an object with a send() method and record its calls.
  9. Separate transport failure, JSON decoding, shape validation, and field conversion.
  10. Associate each future with its input position.
  11. Normalize case and define what counts as a word.
  12. Let each subparser select a handler function.
  13. Move shared definitions, delay an import, or redesign module responsibilities.
  14. Compare readability, eager memory use, and one-time iteration.
  15. Do not assume a compound read-modify-write operation is one safe step.
Show solution directions
  1. Use setdefault() or defaultdict(list) and append each record.
  2. Recursively yield nested values while treating strings as atomic values.
  3. Use a dictionary plus OrderedDict, or explain why a custom doubly linked list gives constant-time updates.
  4. Use functools.wraps; retry only expected temporary exceptions and re-raise the final one.
  5. Put with open(...) inside the generator function so iteration controls its lifetime.
  6. heapq.merge() provides a lazy standard-library implementation.
  7. Define small repository operations, inject the repository into the service, and parameterize every query.
  8. A fake sender stores messages in a list that the test can inspect.
  9. Raise or return distinct domain errors for each boundary instead of one vague failure.
  10. Store index-to-result mappings and assemble the final list after all futures finish.
  11. Use a suitable regular expression or explicit character normalization, then count with a dictionary.
  12. Use argparse subparsers and a main(arguments) -> int function.
  13. Extract common types into a third module when both original modules truly need them.
  14. Choose based on intent: a list for reuse, a generator for streaming, and a loop for complex branching.
  15. Protect the update with a lock or avoid shared updates by returning partial counts and reducing them.

Self-review

For every answer, test empty input, one item, duplicate values, malformed input, and a larger case. State approximate time and memory growth in plain language, then identify one alternative design and its trade-off.