HackerRank Test Questions: What to Expect and How to Prepare
A breakdown of the actual question formats you will see on a HackerRank test, what each one is really checking, and how to spend your prep time before the timer starts.

A Python candidate who cannot write a decorator is easy to spot in ten minutes. A Python candidate who cannot work out why the worker process has grown to six gigabytes overnight is not, and that is the one who costs you.
Python is a forgiving language to look competent in. The syntax is small, the standard library is friendly, and a weekend of practice makes anyone fluent in the shapes that show up in interview questions. That forgiveness is exactly why a syntax-shaped interview sorts candidates badly: it measures the part of Python that a capable engineer picks up in a month, and skips the part that takes years.
This post is about the second part, and how to put a candidate in front of it.
Ask for a decorator, a generator, a context manager, a comprehension that flattens a nested list. Every one of these is a real feature and a bad discriminator, for the same reason: they have canonical shapes. A candidate either has written that shape recently or has not, and recency is not the signal you want.
The same goes for the trivia band. Explain the GIL. What is the difference between a list and a tuple. What does __init__ do versus __new__. These sort people by what they revised last night. We have watched candidates recite the GIL correctly and then, twenty minutes later, put a blocking database call inside an async def handler and wonder why throughput collapsed. Knowing the fact and acting on the fact are different skills, and only one of them ships.
1. The environment is part of the language. More Python incidents come from packaging than from Python. A pinned transitive dependency that resolves differently on the build box. A package that compiles a wheel on one machine and falls back to source on another. A virtualenv that is not the virtualenv the service runs under. An engineer who has operated Python services treats the environment as part of the program. An engineer who has only written scripts treats it as somebody else's problem.
2. Reading a traceback before rewriting the function. This is the single cheapest tell we get. Show a candidate a failure and watch the first thirty seconds. The strong ones read the trace bottom up, find the actual raising frame, and check what the value was. The weak ones scroll past it and start editing the function they assume is at fault. Same time budget, opposite information.
3. Knowing which concurrency model they are inside. Threads for IO, processes for CPU, asyncio for many sockets, and the failure modes of mixing them. The common real-world bug is not exotic: a synchronous call inside an async path, blocking the loop for everything else. A candidate who asks "is this handler async" before touching it has been burned; a candidate who does not, has not yet.
4. Object lifetime and memory. Python hides allocation until it cannot. A cache with no bound, a default mutable argument holding state between calls, a closure capturing a dataframe, a generator materialised by an innocent list(). These are the six-gigabyte bugs, and they are invisible in any interview without a running process.
Run each of these on a real machine with a real service on it. The point is that the candidate can run things, and that you can see what they ran.
The service that grows. A worker that processes a queue and leaks. Give them the process, the queue, and a load source. What you watch: do they measure before theorising. tracemalloc, objgraph, or just resident memory over time against input rate. A candidate who guesses the cause and starts editing may well be right and has still shown you nothing repeatable. The one who plots memory against work done, then bisects, is showing you their method.
The dependency that will not install. A service that fails to start because a package resolves to a version its neighbour cannot accept, or needs a build toolchain that is not there. What you watch: whether they read the resolver output. Most of the answer is printed on screen and most candidates skim past it. This task is unglamorous and it predicts a large share of the real annoyance of the job.
The endpoint that is fast alone and slow under load. Async handler, blocking call inside. What you watch: whether they suspect the shape of the code rather than the size of the machine. The reflex to add workers before finding the block is very common and very expensive.
The test that passes locally. Order dependence, module-level state, a fixture that leaks between tests. What you watch: whether they can isolate by running the suite in a different order rather than reading all of it. Related reading: how to assess debugging skill.
Twenty-five minutes on any one of these tells you more than an hour of questions.
Do not ban the model. A candidate with an assistant will get a fluent, correct, general explanation of Python memory behaviour in seconds, and it will not tell them which object in this process is retaining which reference. Watch whether they go and get the evidence anyway, whether they check what the model produced against the running process, and whether they notice when a confident suggestion is wrong for this codebase. That gap is the whole of how to review AI generated code, and Python makes it especially visible because so much plausible-looking Python is subtly wrong at runtime.
Fluent. Writes idiomatic Python, knows the standard library, names the right concepts. Would be productive on a well-behaved codebase and stalls when the environment misbehaves.
Operates it. Reads tracebacks properly, measures before changing, treats packaging as part of the system, knows which concurrency model is in play and why. This is the working level and the one most teams actually need.
Has carried the pager. Everything above, plus the questions that only come from production: what is the restart behaviour, is this worker idempotent if it dies mid-message, what happens to the queue while we deploy, is this cache bounded. They tend to ask what "fixed" means before fixing.
Do not make the fix the pass condition. Several of these tasks have more than one defensible fix. A candidate who finds the cause, explains the tradeoff, and runs out of time has passed. Write that into the rubric before the first interview, not after a disagreement: see how to write a technical interview rubric.
Do not test the parts of Python nobody writes. Metaclasses and descriptor protocol questions feel deep and select for people who read language internals for fun. That is a real and narrow population, and usually not the one you are hiring.
Do not use a puzzle when you have a codebase. If you have any service in Python, a broken copy of it is a better interview than anything you can invent, because the candidate's confusion is the same confusion a new hire will have in week one.
What was the last Python failure on your system that a syntax question would have caught?
Run live coding sessions and take-home challenges in real production environments. Watch sessions back, score consistently, and hire with confidence.
More posts you might like
A breakdown of the actual question formats you will see on a HackerRank test, what each one is really checking, and how to spend your prep time before the timer starts.
A live system design interview lives or dies on structure, not on which question you pick. Here is a minute-by-minute run sheet for keeping it a conversation, plus when a take-home design doc is actually the better call.
Read moreMost backend engineers can write SQL and far fewer can work out why a query got slow last Tuesday. Here is how to interview for that, on a real database with real data volume, and what separates the three levels of answer.
Read more