This blog post is a small collection of questions I asked as a technical interviewer when we had canidadates for software developer positions. This might be helpful for you if you are preparing for a job interview. I will more or less concentrate on C#/.NET and omit everything to specific for databases and frontend.
Setup
Before I go into detail, a small disclaimer. The experience I share here is my personal one: That means it is not representative of all interviews at my former employer or the world in general. I asked those questions, but that doesn't mean that company XYZ will ask them. I had the opportunity to interview people for my former company as well as for clients I worked for.
Questions
In general, it was always very important for me to understand how someone tackles a problem rather than the answer alone. I was looking for a conversation, not a Q&A session. I wanted to see how someone thinks, how he or she approaches a problem and how he or she communicates. I will show some of the questions I asked and to some extent what I was looking for. Normally I approach the topic that I ask about past experience and let me explain the concepts in that way. Anyway here are some questions and they are not in any particular order.
What are the SOLID principles and what do they mean to you?
This is a very open question itself. Obviously it is straigntforward to answer that SOLID stands for Single responsibility, Open/closed, Liskov substitution, Interface segregation and Dependency inversion. But what does that mean to you? How do you apply them? Why do you think they are "there"? This is the most interesting part for me. For example, you could argue that SOLID is great because it helps you to have guidelines to create a decoupled system that is easily testable.
What is asynchronous programming and why is it important (async/await)?
Now this question is less open, because for me it is important that someone understands the core principles of a language. Where I worked, we are often building Web-API so async
/await
is definitely something you should know. And I am less interested in the "how" (e.g., Task
/Task<T>
), but more in the "why". For example, if you have a request that needs to call the database and wait for its result, you want to make sure that the thread is not blocked and that all the resources are utilized in the best possible way. On top of that, you have the beauty of CancellationToken
s that allows you to cancel a request if it takes too long or the client cancels it.
IEnumerable<T>
/IQueryable<T>
in combination with the database
This is a very simple question, but I was surprised how many people didn't know the answer. I like to ask this one, especially for juniors. So if you have something like this:
public IEnumerable<Customer> GetCustomers()
{
return _dbContext.Customers;
}
What happens if you call this method and then call ToList()
on the result? What happens if you call this method and then call ToList()
on the result and then call Count()
on the same function?
var allElements = GetCustomers().ToList();
var elementCount = GetCustomers().Count();
You can see where I am going here - it is about understanding the lazy behavior of those types and the implications it can have. For example, calling ToList
and Count
after each other would result in two requests to the database. Of course, that also happens with in-memory collections, but it is more obvious (and more impactful) with the database.
Middleware in ASP.NET Core
In every major project I worked on, we had some kind of middleware. It is a very powerful concept and I like to ask about it. For example, what is middleware? What is the difference between middleware and a filter? Why would you need one in the first place? The answers could be very different, but I am looking for an understanding of the concept. For example, you could argue that middleware is a way to intercept a request and do something with it. For example, you could log the request, or you could check if the user is authenticated. You could also argue that middleware is a way to add functionality to your application without changing the core logic. Many folks know stuff like AddAuthentication
or AddAuthorization
in ASP.NET Core, but they don't know that this is just a middleware that is added to the pipeline. The problem I also saw on projects if you don't know such stuff: You have mighty base controllers that do all the work - testing impossible - extension very tricky - and so on!
Testing
Testing plays a big role in software engineering - so this is a obvious candidate. So it's natural to ask about that stuff. But more how the candidates experience with testing was - the good, the bad and the ugly so to speak. What kinds of testing the candidate did in his last roles (unit testing, integration testing, UI testing, ...). What was the experience with testing? What was the experience with testing legacy code?
Inheritance vs. Composition
This is a very interesting topic and I like to ask about it. For example, what is the difference between inheritance and composition? What are the advantages and disadvantages of both? When would you use one over the other? I am looking for an understanding of the concepts and their implications. For example, you could argue that inheritance is a way to reuse code, but it is very rigid. You can only inherit from one class, you can't change the behavior at runtime and so on. Composition on the other hand is more flexible, but it is also more work to implement. A lot of you might have heard of the quote: "Favor composition over inheritance".
Design patterns
I know, I know, I know - some people like it and some people hate it. But in both cases, you need to have an understanding of the underlying principles behind design patterns (like decorator, factory, ...) to know when or when not to use it. And if you hate them (that is absolutely fine), then at least I want to understand why.
IDisposable
Of course, this is not your everyday question - but from time to time, I like to throw in the question of what basically IDisposable
is and how to use it. The target is that I understand whether or not the candidate understands managed and unmanaged resources. Imagine a request that opens a connection to the database but doesn't clean up!? Well, that is not great and can lead to very subtle bugs. Of course, in times of DI-containers, that isn't as prominent anymore because the container, more often than not, takes care of it, but still, a fundamental understanding is key.
Dependency Injection
Going directly again to the SOLID direction - you find in the majority of projects Dependency Injection (short DI). For me it is interesting to know, what candidates experienced with DI. Why someone might take a DI or not. One of the obvious reasons is the decoupling mechanism it inherits. But there are also other reasons. For example, you could argue that DI is a way to make your code more testable.
Conclusion
Here you have it - a very small selection of questions I did ask in my past and still think they are worth knowing.