How non-technical recruiters can screen senior Python developers: 18 questions with strong vs weak answers and follow-ups — no coding required.
You can screen a senior Python developer without writing code yourself. You need questions that force ownership, tradeoffs, and production judgment — plus a plan for what “strong” vs “weak” sounds like when you are not the engineer.
This playbook is for non-technical recruiters and TA partners running a 25–40 minute pre-screen before the specialist round. It will not replace a coding interview. It will stop obvious juniors and bluffers from burning senior engineer time.
“Senior Python signal is rarely trivia. It is whether they have broken production systems and can explain how they think when something is on fire.”
What “senior” should mean on a Python screen
Titles lie. On a recruiter screen, treat “senior” as a cluster of behaviors: they can explain failure modes, choose tools with reasons, describe personal decisions (not only “we”), and survive one depth follow-up without collapsing into buzzwords.
- Owns production pain: incidents, migrations, performance, memory
- Explains tradeoffs (async vs threads, offset vs cursor, mock vs real DB)
- Names constraints: scale, team size, compliance, deadline
- Separates what they did from what the team did
- Improves after failure (tests, alerts, runbooks) — not only heroics
How to run the call without coding
- Ask the hiring manager for 3 must-true themes (e.g. APIs + Postgres + incidents)
- Pick 6–8 questions from the bank below that match those themes
- For every answer, ask one follow-up from the same row
- Score evidence / not observed / risk — never “sounded smart”
- Pass to specialist only if at least two must-true themes showed concrete evidence
If an answer is short, protect the pause, then use the follow-up. If an answer is fluent and empty, the follow-up is how you catch bluffing — see also 12 signs a candidate is bluffing.
18 Python questions that separate junior from senior
You do not need all 18. Use them as a bank. Each row gives you the question, what strong vs weak sounds like, and a follow-up you can read verbatim.
1. What happens when you use a mutable default argument in a Python function?
| Sounds like |
|---|
| Strong | Explains the default is evaluated once at definition time; shared list/dict across calls; gives a fix with None + create inside. |
| Weak | Says “defaults are bad” or “use dataclasses” with no mechanism. |
| Follow-up | How would you rewrite the function safely? |
2. How do you decide between a list, tuple, set, and dict for a problem?
| Sounds like |
|---|
| Strong | Talks ordered vs unordered, uniqueness, key lookup cost, mutability, and a concrete example from their work. |
| Weak | Lists the types from a tutorial with no decision criteria. |
| Follow-up | Give an example where a set beat a list in production. |
3. What is the GIL, and when does it matter for your service?
| Sounds like |
|---|
| Strong | Global Interpreter Lock limits CPU-bound threads; I/O-bound work often fine; multiprocessing/async/native extensions as escapes; ties to their workload. |
| Weak | “GIL is why Python is slow” with no I/O vs CPU distinction. |
| Follow-up | Was your last bottleneck CPU-bound or I/O-bound? How did you know? |
4. Walk me through debugging a memory leak or steadily rising RSS in a Python service.
| Sounds like |
|---|
| Strong | Mentions metrics, reproducing, tracemalloc/objgraph/heapy, common causes (caches, unbounded queues, circular refs with __del__), and a fix they shipped. |
| Weak | “I restart the pod” or “add more RAM” as the whole answer. |
| Follow-up | What metric first told you it was memory, not CPU? |
5. How do asyncio and multithreading differ in the problems they solve?
| Sounds like |
|---|
| Strong | Async for concurrent I/O on one thread; threads for blocking libs / some parallelism; warns about blocking the event loop; real example. |
| Weak | Uses async/await and thread interchangeably. |
| Follow-up | Have you ever blocked an event loop? What did it look like in latency? |
6. Explain generators vs returning a full list. When did you choose generators?
| Sounds like |
|---|
| Strong | Lazy evaluation, memory, pipelines; itertools; a case with large files/streams. |
| Weak | “Generators are just for loops with yield.” |
| Follow-up | What broke when something forced full materialization? |
7. How do you structure packaging and environments for a team service?
| Sounds like |
|---|
| Strong | venv/poetry/uv/pip-tools, lockfiles, reproducible CI, optional extras; why they picked the tool. |
| Weak | “pip install on the server” with no lockfile story. |
| Follow-up | How do you stop “works on my machine” dependency drift? |
8. What testing pyramid do you use for Python APIs, and what do you mock?
| Sounds like |
|---|
| Strong | Unit vs integration boundaries, pytest fixtures, what not to mock (DB contracts), flaky-test discipline. |
| Weak | “We have 90% coverage” with no risk story. |
| Follow-up | Which test failed last week in CI, and what did it catch? |
9. How do you handle migrations and backward compatibility for a Django/SQLAlchemy schema change?
| Sounds like |
|---|
| Strong | Expand/contract, dual-write or nullable columns, deploy order, rollback plan. |
| Weak | “Run migrate then deploy” with no compatibility window. |
| Follow-up | Tell me about a migration that scared you and how you de-risked it. |
10. Describe how you would design pagination and filtering for a large list endpoint.
| Sounds like |
|---|
| Strong | Cursor vs offset tradeoffs, index implications, stable ordering, abuse limits. |
| Weak | “Use limit and offset” only. |
| Follow-up | What goes wrong with offset on a hot table? |
11. How do you approach authentication and authorization in a Python backend?
| Sounds like |
|---|
| Strong | AuthN vs AuthZ, tokens/sessions, permission checks at the right layer, least privilege, audit. |
| Weak | Confuses login with permissions; “JWT is secure” as a slogan. |
| Follow-up | Where do you enforce “can this user edit this object?” |
12. What observability do you expect in a production Python service?
| Sounds like |
|---|
| Strong | Structured logs, metrics, traces, error budgets/alerts that are actionable; libraries they used. |
| Weak | “We have logs” without cardinality or alert quality. |
| Follow-up | Give an alert you deleted because it was noise. |
13. How do you choose between Celery/RQ/Arq/cloud queues for background jobs?
| Sounds like |
|---|
| Strong | Durability, retries/idempotency, visibility timeout, poison messages, when sync is enough. |
| Weak | Names Celery because “everyone uses it.” |
| Follow-up | How do you make a job safe to run twice? |
14. Explain dataclasses, Pydantic, or attrs — when each earns its place.
| Sounds like |
|---|
| Strong | Boilerplate vs validation vs performance; where schema validation belongs (edges). |
| Weak | “Pydantic is modern so we use it everywhere.” |
| Follow-up | Where did validation save you from a bad deploy? |
15. How do you profile a slow Python endpoint before changing code?
| Sounds like |
|---|
| Strong | Reproduce, measure (cProfile/py-spy/APM), find hot frame, change one thing, re-measure. |
| Weak | Immediately rewrites to microservices or adds cache “just in case.” |
| Follow-up | What was the actual hot line last time you profiled? |
16. What is your approach to typing in Python codebases?
| Sounds like |
|---|
| Strong | Gradual typing, mypy/pyright in CI, where types pay off (public APIs), pragmatism on legacy. |
| Weak | “Types slow us down” or “100% typed” dogma without tradeoffs. |
| Follow-up | Show a bug types would have caught — or did catch. |
17. Tell me about a production incident you owned in a Python system.
| Sounds like |
|---|
| Strong | Timeline, hypothesis, blast radius, fix, prevention; personal decisions clear. |
| Weak | Vague “we had downtime” with no role or learning. |
| Follow-up | What did you change afterward so it could not repeat the same way? |
18. How do you mentor or raise the bar for junior Python engineers?
| Sounds like |
|---|
| Strong | Code review habits, design docs, pairing on incidents, standards that scale. |
| Weak | “I tell them to read docs” with no practice. |
| Follow-up | What’s one standard you introduced that stuck? |
Quick junior vs senior pattern table
| Topic | Junior-leaning | Senior-leaning |
|---|
| Defaults / gotchas | Memorizes “don’t use mutable defaults” | Explains why + safe pattern + when it bit them |
| Concurrency | Buzzwords: async, threads, GIL | Matches tool to I/O vs CPU with evidence |
| Data stores | “We used Postgres” | Indexes, migrations, pagination failure modes |
| Jobs / queues | Names Celery | Retries, idempotency, poison messages |
| Incidents | Team story | Personal timeline + prevention |
| Testing | Coverage % | What is mocked and why risk lives there |
Scorecard you can paste into the ATS
- Production ownership (incident / migration / performance): strong / partial / missing
- Tradeoff quality on one core topic: strong / partial / missing
- Follow-up survival (depth without collapsing): strong / partial / missing
- Communication clarity for this role’s stakeholders: note separately from technical depth
- Overall: advance / hold for specialist judgment / reject with reason
Where Hireduce helps on follow-ups
The hard part for non-technical recruiters is not reading the question — it is noticing that the answer was shallow and knowing the next probe in the moment. That is exactly the job of live follow-up assistance.
With Hireduce open beside Zoom, Meet, or Teams, you can keep role criteria visible and get suggested follow-ups when an answer matches “weak” patterns above — mutable-default handwaving, GIL slogans without workload context, Celery name-drops without idempotency. You still own the conversation and the pass/fail call; the tool reduces blank-page panic mid-screen.
Related reading
FAQ
Do I still need a coding round?
Usually yes for senior IC roles. This screen decides whether that round is worth scheduling.
What if the candidate is a silent senior?
Protect pauses and lean on concrete prompts (“last production bug you diagnosed”). See the silent candidate problem.
How many questions in 30 minutes?
Six to eight with follow-ups beats fifteen trivia hits. Depth over coverage.