Software developer job interview questions to ask

After finishing up my previous article about how to not let the software development process become too cumbersome with time, I thought that I'd also write about another topic that's relevant right now. I'm leaving my current workplace to take a bit of a sabbatical and upskill myself, but before then I want to do my due diligence and finish up my current ongoing tasks. As a part of all of it, I was actually invited to help interview a few potential candidates who might serve as my successors.

Hiring software developers is a bit of a tricky process. You typically want to make sure that they are both good people that would fit into your corporate culture, as well as test their technical acumen, to make sure that they're actually as qualified as you need the people in your organization to be. And that's even before you get to things like salary negotiations and the like. Because the stakes are high (given that an unsuitable hire can negatively impact the whole team), it can be difficult to decide how to interview people and what to ask!

software developer job interview questions to ask

While I primarily work as a developer myself, I've actually previously helped out with the technical aspects of some interviews as well and thus have gained some experience. Thus, I'd like to share which methods and approaches have worked for me and which I personally find to be not entirely suited for the task of figuring out how good of a developer someone is. Of course, what has worked for me might not work for someone else and vice versa, as well as might depend on factors like how many people you have to interview, so do keep that in mind.

For now, let's go over them, one by one!

LeetCode, code tests and whiteboarding, the flawed standard

This is the first set of approaches that many companies take and is not unlike a competitive programming exercise. You essentially take a developer, put them in front of a whiteboard, or a computer and tell them to solve a problem of your choosing, typically with a time limit, without allowing them to freely research the problem. Frankly, this approach is so unlike what one's day to day job looks like, that it's surprising that it's used by many of the larger companies:

whiteboarding

(it's hard to find Creative Commons images of people writing code on whiteboards, so just assume that the people are intently looking at some Python code)

In a sense, you do a lot of things that would sabotage most of the developers out there, when compared to their everyday way of working:

  • they no longer have an IDE with auto-completion (including what methods are available in the packages they want to use) or type hints
  • they no longer have the ability to pull up documentation for methods they want to use, or look it up online
  • they no longer have the ability to research neither the problems themselves, nor implementations of various solutions
  • they no longer have access to a compiler, that would tell them when something is wrong, or even suggestions on how to fix issues
  • they no longer have access to a test framework or a debugger that would let them step through the code

And with all of that, companies still are set on using this approach. Some will even go as far as to get the code in a Google Docs text file, throw it at a compiler or a runtime and reject the candidate if the code doesn't work as expected. Why would anyone do something like that? I actually think that the answer here is pretty simple - the companies in question typically have so many applicants that they only want those who are capable of "running" code in their heads and are familiar with the languages to the point of being able to write valid and accurate code without any tools. Rejecting people who don't work that way doesn't impact them as much, because they will always have more candidates.

They might use this as a loose predictor of someone's mental abilities, however if you take the majority of the developers out there and put them in these circumstances, throw in a problem that they might not be familiar with at them and then add a little bit of stress about the interview itself, you have a recipe for disaster from the individual's point of view. What's worse, if you wanted to do well in these sorts of interviews, you'd need to not just prepare for this mode of "programming", but also familiarize yourself with a variety of data structures and algorithms that might not coincide with what you're actually going to be doing daily - and not just being able to use a ready made library, but write your own implementations from scratch.

For the majority of companies out there, who just need decent developers for their CRUD apps or SaaS services, this will not be a good option and for the developers that aren't excellent at competitive programming or might experience stress when placed in situations like these (no tools, no support, no search engines), this will feel downright unfair. Unless you need to hire people who are good at solving these exact sorts of algorithmic problems (which you sometimes might, depending on the domain), perhaps whiteboards should remain as a tool for design meetings in the remainder of the cases.

Take home exercises, high risk but high reward

So how can you check whether someone can write code? My answer to that will be fairly simple - by letting them write some code for you! Now, the approach that I'm about to recommend also has problems associated with it, I'll get into those in a bit.

For the most part, the idea itself is fairly simple: you give the developer an example problem, maybe even a particular tech stack to utilize and tell them to solve it for you. Maybe you need a small RESTful API with a SPA app so that they can demonstrate that they're capable of creating one. Perhaps you're interested in seeing them create a DB schema for you, to later discuss the design decisions behind it. Either way, it should be something that they can work on for a bit and send you a Git repo link:

repository 1

(just a random example of one of my repos here, you get the idea)

Maybe, if time and willingness permit, at the end of it you're going to have an MVP for a system. Say, two or three forms with data input and validations, the ability for users to log in with a backing database for it, something that you can run locally in a single Docker Compose command and test out. This is an excellent approach, because they get to write code with whatever tools they're comfortable with, at their own pace and with less stress, whereas you get whatever is their standard for finished work, even for a small problem, in addition to actually getting to see what their code is like. If there are algorithms at play (say, some temporal algebra for a reservation system), you can even see whether they considered the requirements in detail, as well as whether they wrote any validations and tests.

So why isn't everyone doing this? Because sometimes the job market is full of people who are interviewing at multiple places at once, or are unable to invest a seemingly significant amount of time in something like this. It might not be as much of an issue if companies actually paid for their candidates' time, or at the very least provided a simple scaffolding project to get started with in their preferred tech stack, but I've heard horror stories of companies just taking these interview tasks and using the code for their own projects, without attribution or as much as acknowledgment. Furthermore, there's also the problem of making sure that the candidate is actually the same person who wrote the code. A discussion about it might help in some cases, but not always, nor is everyone capable of setting up OBS or a similar solution and recording their development process (which might also be stressful for some).

What's my solution for this? For people to work on side projects themselves (be it for upskilling themselves, or for profit in their spare time) and then just offer up those codebases for discussion. Why couldn't the candidate offer up a small side project or a similar repo where they solved a problem of their own choosing, as long as it's similarly easy to run and test out? That could be an excellent example of solving real world problems, while at the same time being able to also discuss the code with a potential employer. Then again, some developers are adamantly against side projects - while I don't quite understand why some feel strongly about this, I have to respect that stance as well, for example, if they focus more on their private lives and families, and just don't have the time.

So while this approach could be better and will be better than LeetCode in many cases, it's not perfect either. Do offer something like that to your candidates, if possible, however.

Just having a conversation instead

What other options are there? Personally, I do think that there should be writing of code regardless of the particulars, in some cases where you don't have lots of time, a conversation can also give you a rough idea about the candidate in question. If you have an hour or two to put aside and sit down together, you can probably talk about any number of topics and figure them out after a bit of back and forth. Ideally you'd find a balance between asking about technical aspects and also letting them speak freely, to see how they reason.

To demonstrate this, I actually have a template that I used in one such interview recently, to briefly chat with a candidate for a full-stack developer position (with a slight skew towards back end development). I'd actually like to share a slightly edited and generalized template for something like that with you. It won't be meant for very senior positions, but should prove sufficient for you to get an idea about what kind of a person you're dealing with, what they're good at and what they're interested in:

Back end

• Suppose you have a system that has products, their prices and taxes in %. How would you avoid a situation, in which after some calculations the final price is suddenly 14.0003 or something like that? What could cause this? Where would you try to fix this, in the app or DB?
• What's the difference between server side rendering and using an API? What frameworks/libraries (in a given language) for each are you familiar with?
• What are the typical things one might pay attention to when developing a RESTful API? When might you want to use an API Gateway?
• If you saw a page working slowly, what is the order in which you'd look for the cause of it? In your experience, what are the most typical causes for degraded performance? What metrics might describe that?
• What tools have you used for debugging issues? Have you looked into additional instrumentation for looking into issues after they've happened?
• What has your experience been with writing unit tests or other types of code tests? What is the use in writing them in the first place? What issues might you run into when developing integration tests, or load tests?
• What authentication/authorization solutions have you used? What has your experience been with implementing basicauth, API tokens, OAuth2, OIDC or others?
• Have you worked with ORMs that focus on objects, or maybe some that let you write SQL directly? Which approach do you prefer, what problems does each of the approaches have?
• Microservices vs monoliths. Which architecture has what advantages and disadvantages? Which approach would you use for starting a new project, what would affect your choice?

Front end

• What would you say are the problems with responsive design? What are your favorite approaches for making your sites look good on all sorts of devices?
• How would you compare JavaScript and TypeScript? What are the advantages or disadvantages of either in your experience?
• What are the typical advantages or possible disadvantages of developing single page applications?
• Have you used React, Angular or Vue? Maybe something older back in the day, like jQuery or AngularJS? What are your opinions on the current options for front end development? What do you like or dislike about them? Any favorites? Why?
• Have you needed to use state management solutions like Redux, Vuex, MobX, Pinia or others? When would you add something like that to a project?
• What about design systems? Bootstrap seems to be pretty popular, but what about the alternatives, like Foundation, or maybe CSS only options, or semantic HTML?
• What about tools like TailwindCSS? Or perhaps you've used Sass?

DBs

• When would you use a FOREIGN KEY constraint? Can you think of a case when you wouldn't want to use it?
• What about creating indices with CREATE INDEX? Why don't we put them on every column?
• What would be a good use case for in-database processing with CREATE PROCEDURE? What might be the problems with storing lots of logic in the database?
• What about triggers, with CREATE TRIGGER? What situations would you use them for?
• When would sequential IDs be good, when would you consider using UUIDs? What about the impact on the UX of something like that?
• Would you have your application generating complicated SQL queries itself, or would you consider making a view in the database instead and then query against that? When would you go from doing one to the other?
• When would you create materialized views, what problems could you run into?
• What about partitioning tables? Have you needed to do that? What partitioning criteria would you consider?
• What about key-value stores, like Redis? Why might you want to use something like that, instead of storing things in application memory? What are the benefits or disadvantages of this?
• What about message queue solutions, like RabbitMQ? When might you want to use those in your projects? What would they help you achieve, what failure modes might become less of a problem for your system under load?
• What are your opinions on non-relational stores, like MongoDB, or specialized solutions for blob storage, like the typical S3 compatible ones (for example, MinIO)? When would you use them? When would you absolutely not use them?

Development practices and DevOps

• What version control systems or platforms for that have you used? What about code review and various branching schemes?
• What has your experience with SSL/TLS certificates been for HTTPS? Have you used Let's Encrypt or another ACME provider? Why do we use HTTPS? What are your thoughts about something like mTLS and JWT?
• Can you tell me how DNS works? What do we use it for and why is it important?
• How much have you worked with web servers like Apache, Nginx or Caddy, or specialized load balancing solutions? What do you think about the reverse proxy concept?
• What delivery mechanisms have you utilized? How much have you embraced various CI/CD solutions, like Jenkins, GitLab CI, GitHub Actions and others?
• What about hosting the software that you've developed? Have you used virtual machines, virtual private servers, or shared hosting? What about using containers or container orchestrators?
• Have you worked with GNU/Linux distributions like Debian, Ubuntu, RHEL, CentOS, Rocky Linux or Alma Linux? What are your thoughts on them?
• What about writing shell scripts? Have you used Bash or PowerShell, or just Batch? What do you think about those shell scripting languages or the utility and risks of typical shell scripts?
• What about managing infrastructure as code, with something like Terraform or Ansible? Should everything be automated, why or why not?
• If you wanted to host something online, what would the full process for you doing that look like?

Culture

• Do you work on personal projects or contribute to open source?
• How do you keep learning about new technologies and improving your skills? Where do you learn new things about improving code quality, how systems are developed, what architectures are suited for what problems and so on?
• How will you ensure that X years of experience won't just be "one year repeated X times"? What new technologies or practices would you like to learn in the near future, what are you interested in?
• Which achievement are you the most proud of? Which situations in your career have been the most challenging up until now?
• What about working as a part of a team? What makes being a part of a team easier for you, or what might cause friction?
• Do you prefer to attempt to estimate how much time tasks could take up-front, or not? What makes estimation and organization hard in your experience, what can make it easier?

This should be a decent variety of questions to consider asking, though of course you have to read the room - I've had cases where the person appears to be a bit more on the junior side and instead we mostly talked about the things that they felt comfortable sharing or discussing, especially about how they've been learning about development so far and what they're interested in. If such a discussion goes well, you might even let the person pick up on a few technologies that might be relevant in your area or job market, or aspects of development that they haven't paid much attention to previously themselves.

Should you only hire a person who can answer all of these correctly? Not at all! Instead, you can write down the things that they struggled with or simple chose to avoid talking about and then perhaps pay a bit more attention to those - maybe if they're not familiar with web servers and reverse proxies, you might want to have the mentor that you'll assign to them to go over that setup and briefly explain how something like that might be used in your company, or maybe you'll note that they have good back end development skills, but their DB aptitude might need a bit more work, so someone might help them out a bit with that, which will let them get up to speed with your projects more easily.

Doing some design work together

Ideally, the above wouldn't be all - sometimes you might want to do some design together, depending on what kinds of design work they might have to do, if hired.

You don't just need to draw a bunch of cloud related boxes on a whiteboard or something like Excalidraw either - you can talk about API design, or wireframe how a front end UI might look like and what the transitions between the different forms would be like in Figma or whatever, you might design a database schema together with MySQL Workbench EER diagrams or a similar tool:

MySQL Workbench

The goal here could be to see how they think and collaborate with someone, how well they take advice or even constructive critique, as well as what the end results of this design process are. And given that you're not looking for a very particular algorithmic solution, this can be a valuable creative experience regardless, even if you go through many different iterations and don't necessarily agree about everything:

design meeting

What's more, if you or they want to use whatever tools you like, go ahead! Want to research how some cloud service deals with backpressure briefly? Of course. Want to check what the differences are between how MySQL and PostgreSQL might automatically create (or not) indices for foreign keys, while talking about the schema? Use whatever search engine you want. The candidate recommends that you use a particular tool for UI design? Great, maybe you'll learn something new as well!

Writing and/or reviewing some code together

While the above methods might be helpful in the hiring process, sometimes you'll just want to sit down and have the candidate write some code with you, provided that you have enough time for that. I'd say that the typical problems one could encounter with this would concern setting up an environment, or quite possibly having the candidate either familiarize themselves with any sort of pre-existing codebase, or setting everything up from scratch.

Ideally, if you did the take-home task portion, it might quite naturally translate into a pair programming exercise: "Hey, how about we take this simple system with 3 forms and add another form to it? Or perhaps let's sit down and refactor it a bit, to make it work differently." That way the candidate will be familiar with the environment, will be able to bring the interviewer up to speed and discuss the code in more detail, as well as probably be able to be more productive in their codebase overall, since they wrote it:

pair programming

If you do not hate that much time, it's also perfectly viable for you to instead sit down with some self-contained example code, together with the candidate and chat with them about it. They might have to explain what the code tries to do, as well as just discuss it with: are the naming conventions good or not, would they say that the code is readable and whether they'd like to change it and improve it somehow, whether there should be more comments or less comments present. Perhaps you can get into a brief discussion about coupling and abstractions, to see how well their views align with those of the rest of your team.

Here's an example Java snippet from another blog post of mine, which I wrote as a bit of throwaway code. I'm sure that most developers might have a thing or two to say about it, about how they'd re-write it, if presented with the chance:

/**
 * We are going to create versions for blobs, the table with most of the data.
 */
private void generateVersionsForBlob(PidgeotTestDataConfiguration testDataConfiguration, PidgeotTestDataCounter pidgeotTestDataCounter, LocalDateTime blobCreatedAt, String blobId) {
    BlobVersionDao blobVersionDao = PidgeotDependencyContainer.INSTANCE.getBlobVersionDao();
    PidgeotMinIOClient minIOClient = PidgeotDependencyContainer.INSTANCE.getMinIOClient();
    Long blobVersionCount = testDataConfiguration.getBlobVersionCountPerBlob();
    Mutable<LocalDateTime> currentVersionCreatedAt = new MutableObject<>(blobCreatedAt);
    LongStream.range(0, blobVersionCount).forEach(streamIndex -> {
        long currentIndex = pidgeotTestDataCounter.getBlobVersionCounter().getAndIncrement();
        TestDataTimes.addAFewSecondsToTime(currentVersionCreatedAt);
        String fileContentsText = String.format("This is a test file #%d for blob: %s", currentIndex, blobId);
        byte[] fileContentsTextBytes = fileContentsText.getBytes(StandardCharsets.UTF_8);
        String filename = String.format("test-file-%d.txt", currentIndex);
        BlobVersion blobVersion = new BlobVersion(
                null,
                blobId,
                filename,
                "text/plain",
                TestFiles.getMD5Hex(fileContentsTextBytes),
                streamIndex,
                (long) fileContentsTextBytes.length,
                currentVersionCreatedAt.getValue()
        );
        String blobVersionId = blobVersionDao.insert(blobVersion);
        uploadToMinIOForBlobVersion(minIOClient, currentVersionCreatedAt, fileContentsTextBytes, filename);
    });
}

Again, you don't have to agree with every suggestion, but rather figure out whether you or your team could work together with such a developer. If the development process is largely collaborative, then you should make interviews like that as well, whether you're just chatting about your experience, are working on designing something, or want to write some code. The closer what you're doing is to what someone's actual day at work might look like, the better your evaluation of how much of a good fit they are will be. Furthermore, if you end up giving the same task to multiple people, the results won't be too hard to compare either.

Summary

This might be a different set of suggestions than what many of the larger companies view as a viable approach, but then again, many smaller companies end up shooting themselves in the foot by trying to replicate what the ones that get 10 - 100 times as many candidates for every position have to deal with. But for when you have 5 - 10 people that have gotten to the technical interview part, sitting down with each of them and spending an hour or two chatting or working together can definitely be worth it and leave everyone feeling like they've had a good experience.

This is not the only way to do interviews, but I've had people also recommend their friends to interview with the company due to having a good impression. Plus, you can adapt these steps to your particular set of circumstances - if the candidates don't have the time for a take home task or would just prefer not to do that, you might put more attention into the in-person interview part, or writing code together. They don't feel comfortable writing code in a completely new codebase? Well, you can also offer them to review some code together at the very least and also be more attentive while doing some design work together.

Or, if you are really short on time, you could stick to just the discussion part of the interview. I've seen senior developers with twice the amount of years that I've personally worked in the industry reveal that they're only good with back end development and can't really talk much about the database portion or front end portion, or explain TLS in the level of detail that one might expect, when they're going for a full stack developer position. That doesn't necessarily disqualify them altogether, however it might give me an idea about the areas that they need a bit of support with, as well as where their strengths lie.

I've also seen a whole spectrum of different attitudes: some more junior folks (by experience, not always by age) might have a passion for learning, might be working on side projects, experimenting with robotics and Raspberry Pi clusters at home. Even though they might not do all of that in their job position, that passion for learning and curiosity is definitely a boon in my eyes! At the same time, someone staying in this line of work for many years won't always mean that they've learnt to be humble or professional, and are a team player. I actually used the character of Gilfoyle from the Silicon Valley show as the title image for this post and he's an example of this stereotype - a supposed genius that's also absolutely painful to work together with at the same time.

I guess what I'm saying is that we should all be accommodating towards others within reason. Furthermore, we might benefit greatly (both the candidates and interviewers) from a humane approach, where we find ways to let the candidate's strengths shine, while also discovering more about them in the process - what their goals are, what areas they might need to work more on, in addition to exploring their technical acumen. While I typically didn't have the final word in whether someone gets hired or not, I was definitely able to provide some internal feedback about all of these things.

By the way, want an affordable VPN or VPS hosting in Europe?
Personally, I use Time4VPS for almost all of my hosting nowadays, including this very site and my homepage!
(affiliate link so I get discounts from signups; I sometimes recommend it to other people, so also put a link here)
Maybe you want to donate some money to keep this blog going?
If you'd like to support me, you can send me a donation through PayPal. There won't be paywalls for the content I make, but my schedule isn't predictable enough for Patreon either. If you like my blog, feel free to throw enough money for coffee my way!