Katkat

Explain Python Concurrency, HTTP Update Semantics, Garbage Collection, and Deadlocks

J.P. MorganSoftware Engineer II · Onsite

Last updated

Assess core backend engineering fundamentals including Python concurrency tradeoffs, RESTful update semantics, runtime garbage collection mechanisms, and deadlock prevention strategies.

Scenario

You are reviewing the technical architecture of an account management and transaction processing service. The service exposes HTTP endpoints for account updates, interacts with external banking rails, performs periodic fraud risk scoring, and executes fund transfers between accounts.

Address the following four engineering fundamentals with clear technical explanations and concrete architectural decisions:

1. Python Concurrency Models

  • Compare threading, multiprocessing, and asyncio in the context of CPython.
  • Explain how the Global Interpreter Lock (GIL) impacts execution across multiple CPU cores.
  • Recommend which model to choose for: (a) waiting on multiple third-party payment gateway HTTP calls, and (b) calculating real-time cryptographic transaction hashes or Monte Carlo risk metrics.

2. HTTP Update Semantics & Data Integrity

  • Contrast the semantic differences between PUT and PATCH methods regarding resource replacement, partial modification, and idempotency.
  • Explain the "lost update" problem when two clients attempt to update the same account profile concurrently.
  • Propose an HTTP-standard mechanism (e.g., using ETag and conditional headers such as If-Match) to enforce optimistic concurrency control.

3. Python Memory Management & Garbage Collection

  • Explain how CPython manages memory allocation and deallocation using reference counting.
  • Describe why reference counting alone fails in the presence of reference cycles (e.g., two objects holding references to each other).
  • Explain how Python's generational cyclic garbage collector identifies unreachable cyclical data structures, and how you would diagnose memory leaks caused by circular references in long-running services.

4. Deadlock Analysis and Prevention

  • State the four Coffman conditions required for a deadlock to occur.
  • Illustrate a classic deadlock scenario where two concurrent threads execute transfers between Account A and Account B.
  • Detail a deterministic locking strategy (e.g., resource ordering) and write pseudocode demonstrating how to acquire locks safely without deadlocking.

Hints

Hint 1

Consider how the GIL releases control during system calls and socket I/O, but serializes bytecode execution for CPU-intensive loops.

Hint 2

Recall that `PUT` requires sending the full resource representation and is idempotent by specification, whereas `PATCH` applies a delta and is not inherently idempotent.

Hint 3

To prevent deadlocks in bilateral resource transfers, sort the resource identifiers (e.g., account IDs) and always acquire locks in that consistent global order.

Follow-up questions

  • How does the introduction of free-threaded Python (PEP 703) in newer Python versions impact concurrency strategies for CPU-bound tasks?
  • What exact HTTP status code and response payload should your API return when an optimistic lock check via `If-Match` fails?
  • How can you inspect and debug a suspected deadlock or memory leak in a running production Python process without terminating it?