Skip to content
Question Vault?
Free to readNo accountNo email wallNo invented statisticsNo partial listsCopy or print any set and take it with you

Questions to Ask a Programmer

These are interview questions to ask a computer programmer when you are the hiring manager, tech lead or founder across the table, and they work just as well as technical questions to ask a software engineer you are about to build something with. The 62 questions run in the order a technical interview does: background, fundamentals, debugging, design, shipping and teamwork. None of them is a whiteboard puzzle, so each can be answered from work the person has really done.

62 questions

Want questions from the whole vault instead? Try the random question generator.

The questions

Each question, and why to ask it

Background

What have you built or maintained most recently, and which parts of it did you write yourself?

Why ask it

Start here, because it gives every later question a real system to refer back to. A clear answer draws the line between their own code and what the framework, a teammate or a previous owner supplied. If it is 'we' all the way through, ask which pull request of theirs was hardest to get merged.

How much of your last job was writing new code, and how much was changing code that already existed?

Why ask it

Most programming is changing what is already there, and people who have only started projects from an empty folder are often surprised by it. Neither history is a fault, but match it to your job: a ten-year-old codebase needs someone who finds old code interesting, not insulting.

Which programming language are you most at home in, and where does it get in your way?

Why ask it

Anyone can praise their favorite language. Naming where it hurts, such as slow builds, loose typing, awkward concurrency or painful packaging, takes real hours spent in it. If your stack is different, ask how long it took them to be productive the last time they changed languages.

If I could read one file you wrote in the past year, which would you pick, and why that one?

Why ask it

The reason tells you what they think good code is: easy to change, hard to misuse, well tested, or merely clever. If their work is private, having them describe the file is enough. Be a little wary when the pride is all in how few lines it took.

How did you learn to program, and what did that route leave out?

Why ask it

A degree, a bootcamp and teaching yourself all leave gaps, and a candidate who can name theirs has usually started filling them. Self-taught programmers often mention theory, and graduates often mention working inside a team's codebase. No route is a grade here: the question is about self-knowledge.

What have you learned recently, and what made you go and learn it?

Why ask it

The trigger matters more than the topic. Learning driven by a problem they actually hit tends to show up in their work; learning driven by novelty usually stops at a tutorial.

How is your local setup put together, and what part of it still annoys you?

Why ask it

This measures the friction between having an idea and seeing it run. The useful detail is what they automated versus what they still do by hand every morning, which is a fair proxy for how they treat repeated work generally.

What is a small tool you have written just for yourself?

Why ask it

A script that renames a folder of files, a shortcut around a slow deploy, a bot that nags about stale branches: the tool shows what they found repetitive and that they fixed it instead of putting up with it. Nobody rehearses an answer to this, so it tends to be the most relaxed few minutes of the interview.

What kind of programming problem do you enjoy most, and which kind do you keep putting off?

Why ask it

Some people come alive on performance work, some on tidy interfaces, some on untangling old systems, and nearly everyone avoids something, often build tooling, layout or writing things down. Compare both halves with what this job contains in an ordinary week, and say so if the part they put off is most of it.

Fundamentals

Pick a system you have worked on and trace one request through it, from the user's action to the stored data and back.

Why ask it

This stands in for a dozen definition questions. Where they slow down and add detail is where they have real experience, and where they wave a hand is where someone else on the team did the work. Interrupt once with 'what happens if that step fails?' and see whether the answer stays specific.

How do you choose between a list, a map and a set when you have a collection of things to keep?

Why ask it

It is the data structure question without the textbook. You want the choice tied to how the data is used: looked up by key, checked for membership, kept in order, or walked from start to finish. The names differ between languages (array, dictionary, hash), so accept whichever vocabulary they bring.

A function is fine with a hundred items and unusable with a million. What do you look for first?

Why ask it

Complexity, asked as a bug instead of as notation. The usual finds are a loop inside a loop, a search through a list that should have been a lookup, or a database query fired once per item. Someone who can say 'that is quadratic' but cannot say where it would hide in real code has learned the vocabulary only.

What does a database index do, and what does it cost you?

Why ask it

The first half is common knowledge: it lets the database find rows without reading the whole table. The cost is what separates candidates, since every index slows writes and takes space, and one that does not match the query goes unused. Ask how they would check whether a slow query is using an index at all.

Two requests try to change the same record at the same moment. What can go wrong, and how do you stop it?

Why ask it

The classic example is two people buying the last seat. A transaction, a lock, a version number checked on write or a database constraint that refuses the second change will each do, as long as they can say why they would pick it. A candidate who says it is too unlikely to matter has not yet had to explain a double booking to a customer.

How do you decide whether to handle an error where it happens or pass it up to the caller?

Why ask it

The reasoning to hope for is that an error belongs wherever something useful can be done about it: retry, tell the user, or stop cleanly. Catching everything and carrying on is the answer to worry about, because it turns a crash you would have noticed into wrong data you will not.

A service your code calls stops answering. What should your code do while it waits, and when is it safe to try again?

Why ask it

Three things should come up: a timeout, so one stuck call does not hold up everything behind it; a limit on retries, with a growing pause between them; and whether sending the request twice is harmless. The last is the one people miss, because a retried 'charge the card' is a second charge unless the request carries a key the other side can recognize.

When would you cache something, and how do you find out the cached copy has gone stale?

Why ask it

A cache is a second copy of the truth, and the hard part is deciding when it stops being true. The careful candidate asks first whether the slow thing can simply be made fast, and only then talks about expiry, clearing on change, and what the user sees in the gap. Ask for a bug of theirs that turned out to be an old cached value.

How do you use version control from day to day, and what do you do when a merge goes badly?

Why ask it

Small commits with messages that say why, short-lived branches and reading their own diff before pushing are the habits of someone who has shared a repository. For the bad merge, the calm answer involves understanding both sides of the conflict, not picking 'mine' and hoping. From a junior candidate, a basic working routine is enough.

When is a relational database the right home for data, and when would you pick something else?

Why ask it

Most business data has relationships and fits tables well, so 'relational unless there is a reason' is a sound default. Reasons that hold up are specific: a queue, a search index, large files, a cache. Choosing a store because it is new, or because the last team had one, is worth a follow-up about what it cost them.

In the language you use most, who frees memory, and what does a leak look like when it happens?

Why ask it

In C the programmer frees it, in Rust the compiler enforces who owns it, and in Java, Python, Go or JavaScript a garbage collector does the work. Leaks still happen in the collected languages, usually through a cache, a listener or a list that only ever grows. Scale the depth you expect to the job: it matters far more for a game engine than for a web form.

Debugging

When you inherit code you have never seen, what do you do in the first hour?

Why ask it

Watch whether they run the thing first or read it top to bottom. Getting it running and tracing one real behavior is what separates people who orient in a morning from people who read for a day and still guess.

A feature that worked in the last release is broken in this one. How do you find the change that broke it?

Why ask it

The efficient answers narrow the search instead of reading everything: compare the two versions, check what was deployed in between, or bisect the history until one commit is left. Ask whether they have used git bisect or done the same by hand. Rereading the feature's code from the top is the slow road.

A bug appears in production and you cannot reproduce it on your own machine. What now?

Why ask it

The difference is somewhere: data, configuration, load, timing, a version of something. Strong candidates list those and say how they would compare each, then add logging to the live system to catch the next occurrence. 'It works for me' as a stopping point leaves the customers holding the bug.

Which bug cost you the most days, and what was the cause when you finally saw it?

Why ask it

Everyone who has programmed for a few years has one, and the telling shows their method: what they ruled out, what they assumed wrongly, what gave it away. The cause is often small, a time zone, a stale cache, a typo in configuration. The best versions end with something they changed so that kind of bug would be found faster.

How do you work out why something is slow?

Why ask it

The right instinct is to measure before touching anything: a profile, a trace, timings either side of the suspect call. Anyone who opens by naming the likely culprit is guessing, and performance guesses have a way of pointing at code that turns out to be innocent.

What do you put in a log line, and what do you keep out of it?

Why ask it

Useful logs carry enough to follow one request: an identifier, what was attempted, what came back. What stays out matters as much: passwords, tokens, card numbers and personal details. Someone who has been woken by an alert and then had nothing to search for tends to answer this one at length.

When do you reach for a debugger, and when do you add print statements instead?

Why ask it

There is no wrong tool here, only people who own just one. A debugger suits stepping through state on your own machine, while prints and logs suit timing problems and systems you cannot pause. You are checking that they pick deliberately and can set a breakpoint when a print would take ten tries.

A test fails about one run in twenty. What do you do with it?

Why ask it

An intermittent failure is usually a real fault in the test or the code: shared state, an assumption about order, a clock, a slow network call. The disciplined answer is to find out which before touching it. Rerunning until it passes teaches the whole team to ignore red builds, and deleting it unread throws away the one test that noticed something.

How long do you stay stuck on a problem before you bring someone in, and what do you bring them?

Why ask it

Both extremes cost a team: the person who asks after five minutes and the one who disappears for three days. A good answer has a rough limit and, more usefully, a habit of arriving with what they tried, what they expected and what happened instead. Writing that summary often solves the problem before anyone reads it.

Design

You are handed a one-line feature request. What do you ask before you write anything?

Why ask it

You are grading the questions: who uses it, what happens in the odd cases, what it replaces, how anyone will know it worked. A programmer who starts typing straight away builds the wrong thing quickly. Try it with a real request from your backlog, such as 'let users export their data', and count the questions.

How do you decide what to name a function, and when one has grown enough to be split in two?

Why ask it

A name chosen for what the code does for its caller survives a rewrite of the insides, while a name that describes how it works goes stale the day the implementation changes. On splitting, a reasoned rule beats a line count: one job per function, or the moment the only honest name has 'and' in it.

When other programmers will call your code, what do you do to make it hard to use wrongly?

Why ask it

An interface is a promise that is expensive to take back once people have built on it, so the care goes in before it is published. Concrete habits include making required things impossible to leave out, errors that say what to fix, and writing the calling code first to feel what it is like. Ask about something of theirs that people kept misusing, and what the misuse had in common.

How do you decide when code should be made general, and when to leave it written for one case?

Why ask it

Generalizing too early builds a framework for needs that never arrive, and too late leaves the same fix to make in five places. A common rule of thumb is to wait until the third time something is needed. Whatever their rule, ask for an abstraction of theirs that turned out to be wrong and what removing it involved.

What should a comment say that the code cannot say for itself?

Why ask it

Code shows what happens. A comment earns its place by saying why: the bug this odd line works around, the reason the obvious approach was rejected, the link to the decision. A candidate who says good code needs no comments should be asked where, in that case, the reasons live.

How do you design the data model for something new, and what do you usually get wrong on the first try?

Why ask it

Tables and fields outlive the code around them, so this is where early mistakes are most expensive. Listen for someone who starts from the questions the data must answer and knows what is hard to change later: identifiers, how deletion works, anything stored twice. 'I usually forget history, so now I ask whether we need to know what a value used to be' is a very good sign.

When do you add a dependency, and when do you write it yourself?

Why ask it

Look for costs beyond the install: transitive updates, security advisories, the day the maintainer walks away. A library for every small job and a hand-rolled version of everything each hand the team a bill later.

How do you decide between fixing something properly and shipping a workaround?

Why ask it

The weighing should be audible: who is hurt today, how easily the shortcut can be undone, and whether anyone will really come back to it. Then ask for a workaround of theirs that is still running, since most people who have shipped against a deadline can name one.

When have you argued for deleting code?

Why ask it

Deleting takes more nerve than adding, and the good version is specific: a feature nobody used, a config branch no one could explain. People who cannot remember removing anything tend to work in systems that only grow.

What is a design decision you regret, and what would you do instead now?

Why ask it

Hold out for the second half. Regret with no alternative attached is only self-criticism, while a concrete different design means they went back and thought it through.

At what point in a project do you think about keyboard users, screen readers and people reading in another language?

Why ask it

The early habits are easy to name: every control reachable by keyboard, inputs with labels, no text baked into images, no sentences glued together from fragments that will not survive translation. When it only ever arrives as an audit, every screen has to be opened a second time.

Which security habits are part of how you write code every day, before any reviewer or scanner sees it?

Why ask it

You are hoping for defaults, not heroics: parameterized queries, secrets kept out of the repository, the least access that does the job, personal data kept out of logs. If the whole answer is the name of a security team, then in their mind it is someone else's job.

Shipping

What has to be true before you call a piece of work done?

Why ask it

Merged is the weakest definition, and 'in front of users and confirmed working' is the strongest. In between sit tests, review, documentation and a way to switch the thing off. Have them describe the last piece they finished, then ask how they knew it worked for real users and not only in the demo.

Think of a task you expected to take two days that took two weeks. Where did the time go?

Why ask it

Estimates slip for a small set of reasons: an unknown part of the system, a dependency on another team, work that only appeared once the first version ran. A candidate who can name which it was has learned from it. Then ask what they say now when someone wants a date for something they have never done before.

Which tests would have to pass before you were comfortable deploying on a Friday afternoon?

Why ask it

This separates what they trust from what they write for coverage numbers. Naming a small set, usually a few end-to-end paths plus a verified rollback, is a stronger signal than any coverage percentage.

How do you test code that depends on something you do not control, such as a payment provider, an email service or the clock?

Why ask it

The workable approach puts the outside thing behind a small interface so a stand-in can replace it in tests, with a handful of checks against the real service or its sandbox. Ask what their stand-in got wrong the last time, because a fake that drifts from the real service passes tests for code that fails in production.

How do you roll out a change that could break something?

Why ask it

Flags, a percentage rollout, a dark launch, running old and new side by side. The revealing follow-up is who removed the flag afterwards, since forgotten flags quietly become a category of bug on their own.

How do you change a database table that is in use without taking the system down?

Why ask it

The safe pattern goes in steps: add the new column or table, write to both, move the old data across, switch the reads, and only then remove the old one. Each step can be undone, which is the point. A candidate who would do it in one migration during a quiet hour may have worked only on small systems, so ask how big their largest table was.

You have just deployed and something is clearly wrong. What do you do in the first five minutes?

Why ask it

Roll back first and investigate afterwards is the answer of someone who has been there. The pull is to debug in place while users are affected, and that nearly always takes longer than expected. A second thing to hear is that they tell someone: a short message to the team or the support desk costs seconds and stops three people chasing the same problem.

How do you deal with the differences between your own machine, a test environment and production?

Why ask it

Settings should live outside the code, and the environments should be as alike as the budget allows. The honest part of a good answer is a list of what still differs, typically the size of the data, the traffic and the third-party accounts. Someone who believes their test environment matches production has not yet been surprised by it.

After you deploy, which numbers do you actually look at?

Why ask it

A latency percentile instead of an average, an error rate, and one business number that would notice a silent failure, such as orders per minute, make a solid trio. If the list stops at CPU and memory, ask who was watching whether the product still worked.

Tell me about an outage you were part of. What changed afterwards?

Why ask it

The change is the signal: an alert that would have caught it, a test, a removed footgun, a safer default. If the answer is that everyone was more careful afterwards, the same outage is still sitting there waiting.

Have you been on call for code you wrote, and what did it change about how you write it?

Why ask it

Being paged at night by your own software is a fast education. People who have done it tend to talk about clearer error messages, timeouts on every outside call, and alerts that say what to do next. Plenty of good programmers never have, so in that case ask who did get the call and what those people asked them to change.

Teamwork

What makes a code review useful to you, on both sides of it?

Why ask it

As an author, a useful review catches what they could not see themselves; as a reviewer, it means understanding the change before remarking on its style. Then ask what they do with a comment they disagree with. Giving in every time and escalating every time both wear a team down, so hope for a short conversation away from the thread and the decision written back into it.

Tell me about a technical argument you lost. What did you do afterwards?

Why ask it

Losing well is a skill a team depends on. You hope to hear that they built the other approach properly, with an honest account of whether it turned out fine. Notice how they describe the person who won: someone still relitigating a framework choice from three jobs ago will do the same with yours.

When one feature is split between several people for several weeks, how do you keep the pieces from drifting apart?

Why ask it

Merging often, agreeing early on the interface between the pieces, and a written plan someone else could pick up are what hold it together. One long-lived branch merged at the very end is behind a good share of the worst weeks programmers describe.

How do you make a breaking change to something other teams depend on?

Why ask it

It should come out as steps in order: announce it, run both versions, measure who is still calling the old one, then remove it. Skipping the measurement is how migrations end up half done for years.

What documentation do you wish existed on the teams you have worked on?

Why ask it

Expect something unglamorous: a runbook for the alert that fires at night, the reason behind an old decision, how to get a working environment on day one. Follow up on whether they wrote any of it, which is the difference between a complaint and a habit.

What do you do when a client or product manager asks for something you believe is a mistake?

Why ask it

There are two ways to get this wrong: building it in silence, and refusing. The useful middle is saying what it will cost, offering a cheaper way to reach the same goal, and then accepting the decision if it stands. Ask for a real case and whether, looking back, they were right.

Pick something technical you worked on this year and explain it to me as if I had never written a line of code.

Why ask it

Programmers spend much of the job explaining limits and trade-offs to people who do not code, so this is a work sample and not a party trick. A good explanation borrows an everyday comparison, leaves out what does not matter, and checks that you are following. For a non-technical interviewer, your own understanding at the end is the score.

How do you help a less experienced programmer without doing the work for them?

Why ask it

Asking before telling, pairing with the junior person at the keyboard, and review comments that give the reason are all signs they have done this. Taking the keyboard is the quick fix that teaches nothing. With a junior candidate, turn it around and ask which kind of help has taught them the most.

When an AI assistant writes code for you, how do you check it before it goes into the codebase?

Why ask it

Rules on these tools vary by employer, so say what yours allows before asking. The answer you want treats generated code like a stranger's pull request: read every line, run it, test the edges, and confirm that the functions it calls exist. A candidate who cannot recall it ever being wrong is either not using it much or not checking.

What would you want to know about our codebase before you agreed to work in it?

Why ask it

Close with this one and answer truthfully. Questions about the tests, how often you deploy, the oldest part of the system or who is on call tell you what has hurt them before. A candidate with nothing to ask about code they might spend years in may care more about the offer than the work.

Running the conversation

Practical guidance for the conversation itself

Choosing from the six groups

Ten questions fill an hour

Nobody gets through 62. With follow-ups, an hour has room for about ten, so take one or two from each group and decide beforehand on three that every candidate will hear. Those three are what you compare afterwards. Background is the place to start whoever is in the chair, because the system they describe there is the one you will keep pointing back to.

Junior, senior, or somewhere between

For a graduate or a first-job programmer, stay mostly in Background, Fundamentals and the first half of Debugging, and take 'I have not had to do that yet' as a fair answer to anything in Shipping. For a senior engineer, skip whatever a definition would answer and spend the time on Design, Shipping and Teamwork, where the trade-offs should arrive without you asking for them.

Checking a particular language or stack

Nothing in the list depends on a language, on purpose. If the job needs someone productive in your stack from the first week, add two or three questions of your own after Fundamentals, each built from a bug or a design choice in your codebase. 'Here is a query that got slow last spring, what would you look at?' tells you more than a quiz on syntax.

When it is a conversation and not an interview

These also work as questions to ask coders you already know: a new teammate, a mentor, the engineers at a meetup. Drop the judging and offer your own answer in return. The small tool, the bug that cost the most days, the argument for deleting code and the design regret all start good conversations between people who program.

A workable hour

  • Five minutes: what they built most recently, in their own words, with no interruptions. The first Background question opens it.
  • Fifteen minutes: one system they know well, using the trace-one-request question from Fundamentals. Ask for a sketch and interrupt with "what happens if this part goes down?"
  • Fifteen minutes: a bug or an outage they chased, from Debugging or Shipping. Follow the steps in the order they happened instead of accepting the summary.
  • Fifteen minutes: a Design question with no clean answer, set in your own codebase. You are listening for what they ask before they answer.
  • Ten minutes: their questions for you, opened with the last question on the list. What they ask about shows what they have been burned by before.

What the strong answers have in common

  • They involve a specific system, a date, and a consequence, not a general philosophy.
  • They mention measurement before action: a profile, a log line, a metric that moved.
  • They give credit and blame accurately, including their own part in a mess.
  • They name a downside of their own preferred approach without being prompted.
  • They say "I do not know" and then describe how they would find out.

Mistakes interviewers make here

  • Grading on familiarity with your stack. Someone who has debugged hard problems in another language can pick up your syntax on the job, and fluent syntax never taught anyone to debug.
  • Mistaking fluency for skill. Confident, well-rehearsed answers about best practice can sit on top of very little delivery.
  • Rewarding the person who fights fires over the person whose systems do not catch fire. Ask what they changed so the problem could not recur.
  • Letting a single puzzle decide the outcome. One bad half hour on an unfamiliar problem tells you less than a coherent account of work they finished.
  • Filling silence. The pause after a hard question is usually where the honest answer comes from.

If you are not a programmer yourself

You can judge most of this without following the technical detail. Ask them to explain one decision as though to a new teammate, and notice whether they simplify without becoming vague. Ask what it would cost to change later, and whether anyone disagreed with them at the time. Ask who else was involved and what those people did. Answers that never mention another human being, a cost, or a user are worth a second opinion from someone technical, and so is any answer that leaves you unable to repeat the gist of it afterwards.

More on this topic