Threads vs Processes, the Python GIL, Multiprocessing and Async I/O

Read the full interview experience this question came from →

Quick Overview

A Python concurrency interview question covering how threads and processes differ, including their memory spaces, when to reach for multiprocessing, what the Global Interpreter Lock is and how it limits CPU-bound threads, and why async I/O is a good fit for network and other I/O-bound workloads.

Threads vs Processes, the Python GIL, Multiprocessing and Async I/O

Company: Engelhart

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

Explain the difference between threads and processes, what Python's Global Interpreter Lock (GIL) is, and why async I/O suits network-bound work. These came as a rapid oral sequence in the fundamentals half of a technical screen for a junior quantitative developer role, with follow-ups that pushed on why each answer is true. ### Clarifying Questions - Should the answer assume the standard CPython interpreter with the GIL, or also cover the newer free-threaded build? - Is the workload in mind mostly waiting on the network and disk (fetching data from APIs, reading files), mostly computation in pure Python, or computation inside libraries such as NumPy? - Is the question limited to one machine, or does it include spreading work across machines? ### Part 1 — Threads and processes 1. What is the difference between a thread and a process? 2. How do their memory spaces differ? 3. When would you use `multiprocessing`? ```hint What is shared List what two threads of one program share and what two processes share. Then ask what that implies when they need to exchange data, and when one of them crashes. ``` #### What This Part Should Cover - Address space, creation cost and communication cost for each - Fault isolation, and the synchronization that shared memory requires - When multiprocessing is the right tool in Python, and what it costs ### Part 2 — The GIL 1. What is the Python GIL? 2. Why are Python threads usually not the way to get true multi-core parallelism for a CPU-bound workload? ```hint Who may run bytecode Ask what a thread must hold in order to execute Python bytecode, and how many threads can hold it at the same moment. ``` #### What This Part Should Cover - What the GIL protects and why CPython has it - Its effect on CPU-bound versus I/O-bound threads - When the GIL is released, and what it does not guarantee about thread safety ### Part 3 — Async I/O 1. What are the benefits of async I/O? 2. Why does async suit network and other I/O-bound workloads? ```hint Who decides when to switch Compare a thread blocked on a socket with a coroutine awaiting one: who decides when another task gets to run, and what does each waiting task cost? ``` #### What This Part Should Cover - How an event loop and cooperative switching at `await` points work - The cost of a waiting coroutine compared with a waiting thread - Why async does not help CPU-bound code, and what happens when a coroutine blocks ### What a Strong Answer Covers - Accurate distinctions between threads, processes and coroutines, beyond "processes are heavier" - A correct account of the GIL, including that it is released during blocking I/O and by many C extensions - A clear rule for choosing threads, processes or async for a given workload - Awareness of each option's costs: pickling and start-up for processes, races for threads, blocking calls for async - Short concrete examples, such as a process pool for simulations and an event loop for API calls ### Follow-up Questions - A job downloads a few thousand files from a vendor API and then parses each one with heavy pure-Python computation. How would you structure it? - Four threads running large NumPy matrix multiplications finish faster than one thread. Does that contradict what you said about the GIL? - What happens if a coroutine calls `time.sleep(5)`, or uses a synchronous HTTP client, inside the event loop? - Python 3.13 introduced an optional free-threaded build without the GIL. What does it change, and what does it cost?

Overview: A Python concurrency interview question covering how threads and processes differ, including their memory spaces, when to reach for multiprocessing, what the Global Interpreter Lock is and how it limits CPU-bound threads, and why async I/O is a good fit for network and other I/O-bound workloads.

Read the full Engelhart Software Engineer interview experience this question came from

Engelhart logo
Engelhart
Sep 19, 2026
mediumSoftware EngineerTechnical ScreenSoftware Engineering Fundamentals
1
0

Explain the difference between threads and processes, what Python's Global Interpreter Lock (GIL) is, and why async I/O suits network-bound work. These came as a rapid oral sequence in the fundamentals half of a technical screen for a junior quantitative developer role, with follow-ups that pushed on why each answer is true.

Clarifying Questions Guidance

  • Should the answer assume the standard CPython interpreter with the GIL, or also cover the newer free-threaded build?
  • Is the workload in mind mostly waiting on the network and disk (fetching data from APIs, reading files), mostly computation in pure Python, or computation inside libraries such as NumPy?
  • Is the question limited to one machine, or does it include spreading work across machines?

Part 1 — Threads and processes

  1. What is the difference between a thread and a process?
  2. How do their memory spaces differ?
  3. When would you use multiprocessing ?

What This Part Should Cover Guidance

  • Address space, creation cost and communication cost for each
  • Fault isolation, and the synchronization that shared memory requires
  • When multiprocessing is the right tool in Python, and what it costs

Part 2 — The GIL

  1. What is the Python GIL?
  2. Why are Python threads usually not the way to get true multi-core parallelism for a CPU-bound workload?

What This Part Should Cover Guidance

  • What the GIL protects and why CPython has it
  • Its effect on CPU-bound versus I/O-bound threads
  • When the GIL is released, and what it does not guarantee about thread safety

Part 3 — Async I/O

  1. What are the benefits of async I/O?
  2. Why does async suit network and other I/O-bound workloads?

What This Part Should Cover Guidance

  • How an event loop and cooperative switching at await points work
  • The cost of a waiting coroutine compared with a waiting thread
  • Why async does not help CPU-bound code, and what happens when a coroutine blocks

What a Strong Answer Covers Guidance

  • Accurate distinctions between threads, processes and coroutines, beyond "processes are heavier"
  • A correct account of the GIL, including that it is released during blocking I/O and by many C extensions
  • A clear rule for choosing threads, processes or async for a given workload
  • Awareness of each option's costs: pickling and start-up for processes, races for threads, blocking calls for async
  • Short concrete examples, such as a process pool for simulations and an event loop for API calls

Follow-up Questions Guidance

  • A job downloads a few thousand files from a vendor API and then parses each one with heavy pure-Python computation. How would you structure it?
  • Four threads running large NumPy matrix multiplications finish faster than one thread. Does that contradict what you said about the GIL?
  • What happens if a coroutine calls time.sleep(5) , or uses a synchronous HTTP client, inside the event loop?
  • Python 3.13 introduced an optional free-threaded build without the GIL. What does it change, and what does it cost?