Skip to main content

Junior

A junior answer names the rule and the bug it prevents.

What is the difference between a list and a tuple?

A list is mutable. A tuple is not. Use a list when the collection changes, and a tuple for a fixed record. A tuple can be a dict key only when every item in it is hashable. A list never can.

When should code use is, and when should it use ==?

== asks whether two values are equal, through __eq__. is asks whether two names point at the same object. Use is for None. Do not use is to compare numbers or strings, even when a small integer happens to share an object.

What happens if a function default argument is a list or a dict?

The default object is created once, when the function is defined, and reused on later calls. A caller that appends to it changes the default for every later caller. Use None as the default and create a new list or dict inside the function.

How should a function handle an exception it can recover from, and one it cannot?

Catch the specific type when the function can recover or add context and raise again. Let it propagate when the caller must decide. A bare except also catches KeyboardInterrupt and SystemExit. Catch Exception, or a narrower type, on purpose.

What does a list comprehension build, and when is a loop clearer?

A comprehension builds a new list. It is an expression, so it fits a filter and a transform. A loop is clearer when the body has several steps or a side effect. A comprehension that hides a network call is harder to read than the loop.

What problem does a virtual environment solve?

It gives one project its own interpreter and installed packages, separate from other projects on the machine. Install that project's dependencies into the environment and record them, so a later install can rebuild the same set.

Mid

A mid-level answer names the mechanism and a failure mode.

What does the GIL limit, and what does it leave alone?

In the default CPython build, the GIL lets one thread run Python bytecode at a time. CPU-bound threads do not speed up across cores. Threads that spend their time waiting on I/O can still overlap. CPU parallelism uses processes. A good answer names the runtime, because a free-threaded build changes that limit.

How do you share mutable state between threads without corrupting it?

Prefer not to share it. Pass work through a queue.Queue, which is safe for threads. If threads must share a structure, protect every read-modify-write with a lock, and acquire locks in one order so two threads cannot deadlock. The GIL does not make a compound update atomic.

When do you use a class method, a static method, and an instance method?

An instance method receives the instance. A class method receives the class, which is how an alternate constructor stays overridable in a subclass. A static method receives neither. It is a function stored on the class. Use a class method when the subclass must be part of the result.

How is async code different from a thread?

An async function runs on an event loop and yields at await. It does not add a thread. A blocking call inside it stalls every other task on that loop. Move blocking work with asyncio.to_thread, or to a process, when the wait is not an awaitable.

Why annotate a read-only parameter as Mapping rather than dict?

Mapping, from collections.abc, says the function only reads. A dict annotation rejects other mappings and promises that mutation is allowed. Return a dict when the function creates one. Annotate the parameter with the narrowest capability it uses.

What must a context manager do if the block raises?

It must release the resource in __exit__ whether the block returns or raises. Files, locks, and transactions are the usual cases. contextlib.contextmanager can wrap a generator that acquires, yields once, and releases in a finally. Swallowing the error inside __exit__ hides a failure the caller needed.

Senior

A senior answer names the tradeoff, the failure, and what to measure.

How do you change a public function without breaking callers?

Keep the documented signature, return value, and exceptions stable. Add a new parameter as keyword-only, with a default that preserves the old behavior. Deprecate a behavior before removing it. Tests should pin the contract callers use, not the private helpers.

How do you track down a memory leak in a long-running service?

Take tracemalloc snapshots over time and compare what is still referenced. Look for a cache with no bound, a global registry, and a cycle that a __del__ method keeps alive. Growth that tracks traffic and never falls back after a quiet period is the symptom. Measure before rewriting the cache.

When do you pick processes instead of asyncio?

Use processes when the work is CPU-bound and the jobs do not need a shared mutable object. Use asyncio when the work is many waits on one thread. A service that does both can run an event loop for sockets and a process pool for the CPU jobs. Processes pay for startup and for copying data across the boundary.

How do a property and a descriptor relate?

A descriptor is an object on the class that implements __get__, __set__, or __delete__. A property is a descriptor. Reading the attribute on an instance calls those methods. A data descriptor on the class overrides an entry in the instance dictionary. A non-data descriptor does not.

When is a frozen dataclass safe to use as a dict key?

Equality and the hash follow the fields, so every field must itself be hashable and should be immutable; frozen=True only blocks assigning to the dataclass's own fields.

Why is it a bug to catch Exception and return success to the caller?

The caller cannot tell a failure from a result. Log the traceback and let an unexpected error surface. Catching Exception does not catch BaseException, so it is not a reason to turn bugs into a normal return. A request handler that does this reports success for a failed write.

Check that the candidate can code without AI

These questions show how a candidate talks about Python. They do not show the candidate writing the next change with no assistant. How to tell if a developer can code without AI explains the watched session.

What the candidate shows us is proctored tests, watched by a real person: a coding test with no AI allowed, a 2-hour build project with AI allowed, the Fire Drill (a live pair-programming session on a real-world problem), an English test, a thinking-skills test and a typing test. It also covers recorded reference checks. The menu is on Proctored tests. You pay for the tests you order. A real person watches.

When the answers are strong, Hire backend developers. Arca.ph is a network of remote engineers. Your own AI agent, such as Grok, Claude, or ChatGPT, searches and sorts that network. On the marketplace, the fee is a one-time 15% fee of first-year pay, only on hire, with a 3-month free replacement. Done for you is 35% of first-year pay, charged once on hire. Details are on pricing and how it works.

FAQ

How should these questions be used in an interview?

Ask two or three questions from the level you are hiring, then ask what would break. A useful interview is a conversation about a real constraint. It is not a recital of every question on this page. Use the watched coding check before you decide to hire.

What is the difference between a junior answer and a senior answer?

A junior answer names the rule and the common bug. A mid-level answer names the mechanism and one failure mode. A senior answer names a tradeoff, a failure they have seen, and what they would measure. Hire for the work the role will own, not for a perfect score on every question.

How do I check that the candidate can code without AI?

Questions do not show the candidate writing code. What the candidate shows us is proctored tests, watched by a real person: a coding test with no AI allowed, a 2-hour build project with AI allowed, the Fire Drill (a live pair-programming session on a real-world problem), an English test, a thinking-skills test and a typing test. It also covers recorded reference checks. The guide How to tell if a developer can code without AI explains the watched session.

Where do I look for engineers after the interview?

Open the backend developer hire page linked on this page. Python is one of the stacks listed for that role. Your own AI agent searches and sorts the Arca.ph network. You choose who to test and who to interview. Profiles are free to view once you sign up and sign the Arca.ph Client Agreement.

What does Arca.ph charge when I hire?

Arca.ph is a network of remote engineers. Your own AI agent, such as Grok, Claude, or ChatGPT, searches and sorts that network. On the marketplace, the fee is a one-time 15% fee of first-year pay, only on hire, with a 3-month free replacement. Done for you is 35% of first-year pay, charged once on hire.

Get started.

Profiles are free to view once you sign up and sign the Arca.ph Client Agreement.