Table of Contents

Overview

Here are some of the interview questions I've come up with over the years that I thought were good enough to write down. Unless I can't think of anything to ask next, I don't actually use questions from a pre-set list like this. Usually, it goes the other way, with me thinking of a question, then recording it here. If your job involves interviewing programmers and you'd like to borrow some of these questions, go right ahead. I know some people have already.

I generally hate trivia-type questions unless it's something very fundamental to a language or technology that you'd have to know if you've spent any time thinking about it or working within it. Therefore, most of these are more abstract than most of the question lists I've seen online (which are quite terrible, by the way). If it were entirely my criteria, I'd shift things even further in that direction, but when you're hiring software engineers, often you want a baseline of practical skills.

Before even starting the questioning, the first thing to do is establish the tone of the interview in a more conversational manner. If the interview has a quiz show feel to it, you're doing it wrong. Introduce yourself and let them know you're an engineer or researcher yourself. If no one else has done so yet, tell them about the company and position. Remind them this is a technical interview and that the purpose is just to get a rough estimate of their abilities and establish the boundaries thereof.

I'll add questions as I think of them here. I might also add a list of programming tests later.

Touchy-Feely

What kind of stuff do you consider yourself most skilled at?

These need to be both true and not just the same boring stuff everyone knows. Of course, everything mentioned here will be verified.

What type of position and level are you looking for (alternatively, what level do you see yourself at)?

We'll be checking their actual competence against their perceived/claimed competence.

Can you talk a little about one or two cases where you had a principle role in doing something technically note-worthy (i.e. designed something unique or complex, solved a tough problem, or otherwise saved the day)?

Whether it's work-related, a side project, or even something from school, everyone should have something impressive to say here. Unfortunately, very few do. A lot of them will just start telling you about participating in a cool project, but we don't care about the amazing people they worked for/with. We want to know what they themselves did. Working at NASA or Google means nothing if you were just a code monkey.

Computer Science

Trees are a popular type of data structure. Can you name a type of tree and describe how it is implemented?

Binary tree, B tree, B+ tree, red/black tree, finger tree, etc., with appropriate details.

What's the difference between a static and dynamic type system?

Static: type checking performed during compile-time; Dynamic: type checking at run-time.

What would be a data structure that could model something like train stations and the tracks of varying distances that connect them, given that my program wants to be able to compute shortest routes between any two stations?

A graph with weighted edges. A matrix would also work, but be considerably less efficient and complicate the shortest path algorithm needlessly.

A graph with weighted edges. A matrix would also work, but be considerably less efficient and complicate the shortest path algorithm needlessly.

This allows for recursive functions that would otherwise fill up the call stack to be optimized by the compiler or interpreter in a way that only uses the space of an iterative solution.

I want to choose a data structure to store a large series of items that I will be inserting tons of values into, should I choose an array or a linked list given only that the items need to remain sorted?

The linked list, since inserts are considerably less expensive.

What's parametric polymorphism?

Functions defined over a range of types, acting the same for each type. Examples include map, generics with type parameters, fold, etc.

I modeled the workflow of my program with a state machine, but then changed the code to randomly choose one of two state transitions at several points. What kind of state machine do I have now?

A nondeterministic finite state machine.

Why do I think the letters S and K are the most important to computer scientists? I also sometimes like the letter I.

All of lambda calculus can be reduced to compositions of S and K combinators (I is optional).

How can I write an entire program free of mutable state?

Ensure that all functions in a program are referentially transparent and thereby purely functional. Several methods exist to then manage non-local state transformation, the most obvious being structures like monads, but there are other methods, such as those from type theory, like uniqueness types.

I want a function that, based on the input given, returns another function which is a representation of some mathematical formula. The formula represented by the returned function can vary as much as the input (effectively near-infinitely), so its logic needs to be constructed programmatically. How can I go about doing such a thing? An example might be: A function that takes some data structure representing the edges of a polygon and a transformation type, and then returns a function that computes the area of polygons of that shape, given a specific transformation.

In most mainstream languages, this isn't possible to do in one function. One could almost do it in any language it was possible to create a quine in, but in something like C, for example, this would mean compiling the output of it before you could run it. We get closer to the desired result in interpreted languages that provided some kind of eval function. However, it is completely possible in any language that has the ability to treat its own code as data. Really CompSci-literate types will be able to list several possibilities along these lines.

How can I conclusively prove that a program is "functionally correct"?

In trivial programs only capable of taking limited input, this is obvious, and can be done by ad hoc methods that enumerate all input values. One method to do this for complex programs is to first define the program's "formal specification." There exists a field of computer science known as formal methods, where at the highest level of formal verification, the program semantics can be machine-checked by a theorem prover against this specification using various forms of logical calculi and type systems.

Algorithms

Given a string, how would you go about counting the number of occurrences of each character that appears in that string? (Maybe ask about the runtime complexity of that as a follow up.)

Simplest answer is to just create a hashmap with the letter being the key and the value being the count, but there's other solutions that are okay, provided they don't require a lot of extra looping or are otherwise greater than O(n) or have a ton of constant time operations.

The Fibonacci sequence is a recurrance of the form: F(n) = F(n - 1) + F(n - 2) with F(0) = 0 and F(1) = 1. Is there any problem with this implementation (apart from n < 0):

int fib(int n) {
  if (n < 2) return n;
  else return fib(n - 1) + fib(n - 2);
}

High computational complexity, high recursive depth, repetition of computation.

What kind of algorithmic modifications can we make to improve the runtime of this solution?

Tail recursion, population of matrices/lookup tables, memoization, iterative population of an infinite sequence, etc.

Say I have a binary tree of some depth, and I run searches to locate some element stored therein. What could you tell me about the complexity of such a problem?

Its runtime is O(log n).

Say I have two algorithms that do the same thing, but one of them is O(n log n) and the other is O(2^n), which algorithm will perform better on the first run?

Unknown. All that is given here is the upper bound.

Software Engineering

What are some fundamental features of OOP?

Abstraction, encapsulation, subtype polymorphism, inheritance, message passing, etc.

What kind of pluses and downsides are there between <their favorite language> and <some other language that's close but has some fundamental differences>?

Anything that shows they think of programming languages in a formal way, and not just a finite bag of tricks they can use.

How would you change your favorite programming language to make it better?

This is probably a better version of the previous question.

What's the difference between a compiler and an interpreter?

Compiler: generates executable binary; Interpreter: translates and immediately executes source.

Besides object oriented programming, what other programming paradigms are there?

Procedural, declarative, functional, logical, stack, etc.

Alternatively, one could say there are really only three paradigms: imperative, functional, and logical.

What do you think about the use of design patterns?

Hopefully they at least know what they are. Really smart candidates will not only have opinions on when to use them, but maybe mention their misuse, anti-patterns, or have some fundamental criticisms of the concept.

What design patterns are you familiar with? (Maybe ask to define Singleton, Strategy, MVC, Visitor, or some other one they know.)

They should at least be able to describe one or two of them, with implementation details.

Are you familiar with unit testing, unit test frameworks, or TDD? If so, what kinds of goals do you keep in mind when creating automated unit tests?

There's a lot of common misconceptions about unit tests. A lot of people think they understand the concept, but due to never actually writing any, say incorrect things about them. They should at least mention edge cases and code coverage. Some thought about the goals and trade-offs of unit tests are also a good sign. On the other hand, be wary of True Believers regarding some aspects of testing, particularly TDD.

Knowing the limitations of unit testing, are there any tools or tactics one could use to get more reliability out of software?

Foremost here is generative (or property-based) testing, popular in FPLs. There are also more SE-centric methods, like integration and simulation testing.

Clojure

Implement a function to create identity matrices of arbitrary size. An identity matrix of size 4x4 modelled with lists might look like this:

'((1 0 0 0)
  (0 1 0 0)
  (0 0 1 0)
  (0 0 0 1))

This is a pretty straight-forward problem of medium interview difficulty. Here's an acceptable solution using infinite sequences:

(defn identity-matrix
  "Create an identity matrix, of size n x n." [n]
  (->> (concat [1] (repeat n 0))
       (repeat)
       (apply concat)
       (partition n)
       (take n)))

Implement get and put functions for a simulated hashmap, without using {}. These functions should be callable like this (if using a vector-based implementation):

(my-get [[:a 1] [:b 2]] :b)   ;; Returns 2.
(my-put [[:a 1]] :b 2)        ;; Returns [[:a 1] [:b 2]].
(my-put [[:a 1] [:b 2]] :b 3) ;; Returns [[:a 1] [:b 3]].

First make them think of how they're going to model their hashmap before proposing an implementation. If using the proposed nested vectors, here's the naïve solution:

(defn my-get
  "Retrieve element `e` from map `m`." [m e]
  (second (first (filter #(= e (first %)) m))))

(defn my-put
  "Put key-value pair, `k` and `v`, into map `m`.  Overwrite current value at
  key `k` if it already exists." [m k v]
  (cond (empty? m) [[k v]]
        (= k (ffirst m)) (concat [[k v]] (rest m))
        :else (concat [(first m)] (my-put (rest m) k v))))

This is a good question for a follow-up discussion on efficiency and implementation trade-offs.

When should you use macros?

A good question for former CL programmers claiming to have made the transition. One of the differences with Clojure is macros in practice. These should be avoided in use for syntactic abstraction, and generally only used when controlling evaluation or creating APIs and (e)DSLs. Outside of these use cases, macros should only be used when data structures and functions won't suffice (which is very rare).

What are lazy sequences and when are they useful?

A sequence that when evaluated only realizes values and caches up to the point evaluation ends. These are super useful and appear everywhere in Clojure. For one, they're efficient when not all elements of a sequence are known to be needed. Another use for them is creating iterative versions of algorithms commonly implemented recursively.

When should I use a map versus a record?

This is an opinion-solicitation. A good answer here demonstrates intermediate-level understanding of program design in Clojure, at least as it relates to internal program data modeling. There are some wrong answers, the most obvious being suggesting that you should always use one or the other.

Clojure is a dynamically-typed functional language. While this has many benefits, what are some drawbacks of this and how can we mitigate it?

Clojure dynamic-typing has mostly the same drawbacks as in other languages. Some mechanisms available to reduce the negatives are pre-conditional asserts on functions, a strong testing story, naming parameters appropriately, unification of program control data structures that are passed around, constraint-based design, and optional typing libraries (though the latter comes with its own downsides).

Haskell

Implement a function to create identity matrices of arbitrary size. An identity matrix of size 4x4 modelled with lists might look like this:

[[1, 0, 0, 0],
 [0, 1, 0, 0],
 [0, 0, 1, 0],
 [0, 0, 0, 1]]

This is a pretty straight-forward problem of medium interview difficulty. Unlike with the Clojure solution for this same question above, there's a larger number of more elegant solutions for this. Here's an acceptable solution using infinite sequences:

split :: Int -> [a] -> [[a]]
split n [] = []
split n xs = w : split n ws
  where (w, ws) = splitAt n xs

idMatrix :: Int -> [[Int]]
idMatrix n = split n $ take (n*n) $ cycle $ 1 : (take n $ cycle [0])

.Net Framework/Languages

Without a lot of details, what kind of .Net languages and components of the .Net framework do you consider yourself skilled at?

For languages, hopefully they'll at least know C#, VB.Net, or C++/CLI. Extra points if they've spent time on F# or some of the many ported languages. For components, they should be able to rattle off a few they're fond of, like LINQ, WPF, WCF, etc. With the .Net ecology so massive, this gives you a starting point of stuff to verify competence in.

What's a delegate? What's a multi-cast delegate?

A delegate is a type that references a method, allowing it to be passed around, such as in an argument list. A multi-cast delegate is a delegate that can have multiple elements in its invocation list, typically used for event handlers.

What's reflection all about?

Allows run-time retrieval of information about an object, such as its type.

In C++/CLI, what's this syntax mean?

ArrayList ^arr = gcnew ArrayList;

^ is a managed pointer, gcnew instantiates .Net reference types.

What's LINQ and what's so great about it?

Language Integrated Query, a library added to the .Net framework in 3.5 and recently extended with PLINQ. It allows for query operations to be performed natively within the language itself. The main great thing about it is that it allows for compile time checking of query operations, but there's several other pluses.

What kind of stuff can I query with LINQ?

Native to the .Net framework, just SQL Server databases, DataSets, XML, and objects that implement IEnumerable.

What's WCF all about?

Should probably mention something about SOA, the concept of providing/consuming services, service/data contracts, etc.

What's a lambda expression in C#?

An anonymous (unnamed) method, declared inline, applied against a collection, such as a list.

One of the overloads for the Array.Sort method has a type signature like this:

public static void Sort(Array, IComparer);

How do I actually call this?

Even if they didn't know what IComparer was, it should be obvious that this means you'll need to create a class implementing IComparer that defines some method that would implement comparison logic.

I want to write a .Net program that does a bunch of different stuff at the same time (i.e. a large quantity of simultaneous computation), what are some options I have to do this?

Using threads, you could manage them yourself using various lock and signal synchronization methods. You could also just use a ThreadPool if it makes sense for your problem (like if the operations are asynchronous). There's also the Task Parallel Library.

Java

Can the static indexer "this" be used inside of a static method? Why/why not?

No, since static methods don't require an instance of the object.

What's special about a static variable?

A variable local to a class where only one instance of it exists for all instances of the class.

JavaScript

What is your opinion of JavaScript as a language?

Anyone who's programmed in JavaScript some will have plenty of very specific complaints about it, but most likely also a few things they really like. JavaScript is a common filler item on resumes, so this is a good question to ask first.

What is NaN?

Not a Number. This is returned when a numeric operation is performed on a non-numeric type and type coercion cannot extract a valid number. NaN is actually of type "number".

Tell me a little about web application frameworks you're familiar with.

Some non-erroneous info about React, AngularJS, Vue.js, etc. Most front-end developers have one of these as their primary framework, so maybe deep-dive on it a bit to see how much that is the case.

What's Ajax do?

Allows the client side to retrieve data from the server asynchronously with a request in the background.

What's JSON?

JavaScript Object Notation. A data representation standard that is typically used for serializing and transmitting structured data. It has a few benefits over XML like being easier to read and being legal JavaScript code.

What's the difference between == and ===?

The former allows JavaScript to type coerce prior to checking the equality, the latter does not.

How should I output content to an HTML page in JavaScript?

Modifying element.innerHTML is the preferred method in pretty much every scenario. document.write can work, but has potential pitfalls.

What kind of type system does JavaScript have?

Loose/weak, dynamic.

If I'm not sure whether a certain variable exists or not in some function I'm writing, how do I check that before using it?

Something like:

if (typeof someVar !== 'undefined' && someVar !== null) {
  // ...
}

What does it mean to say that JavaScript supports higher-order functions?

Functions can be passed around like any other object in JavaScript, e.g. they can be passed as arguments or returned from other functions.

What kind of scope rules does JavaScript have?

Function scope, but not block scope.

What is the effect of adding a method to some object type's prototype property?

It would immediately append that method to all objects covered by that type, even those declared prior to this augment.

How are objects passed in JavaScript?

By reference.

What does eval() do and when should you use it?

Executes a string of JavaScript code, with direct access to the JavaScript compiler. You should almost never use eval(), as there are almost always better ways of doing things.

How do for...in loops work in JavaScript?

This loops through all properties of an object (including all members from prototypal inheritance.)

JavaScript has closures. What are those?

The ability of a function to have access to the scope within which it was declared, despite possibly no longer being in that scope.

If I have some function that throws various kinds of exceptions in different error conditions, how do I write code to do different things to handle them?

JavaScript try...catch blocks don't support exception type checking as part of the language. You would have to do this manually within a single catch block.

What are promises in JavaScript?

An object that represents a value that may be available now or in the future. They are often used in asynchronous computation.

Is it possible for an object to have private members with accessors and mutators in JavaScript?

Yes. Something like this will do it:

var stuff = function () {
  var secret = 0;
  return {
    get_secret: function () {
      return secret;
    }
  };
};

C/C++

If I gave you an std::set containing n integers with values of 1 to n (non-repeating, meaning each number appears exactly once), then I removed one of those integers randomly, how could you tell which one was missing if you only had 2 registers to work with?

There's two answers to this. The more obvious one is to sum up all numbers from 1 to n (there's also a formula for this which can save time), then remove each integer from the set and subtract it from the sum. The remaining amount will be the missing integer. The other solution is to simply XOR all of the integers.

Python

Write a program that takes lists like this, and returns the sum of ages of all adults (those over 18).

people = [{'name': 'Barry',
           'age': 12},
          {'name': 'Larry',
           'age': 18},
          {'name': 'Gary',
           'age': 43}]

Here's an acceptable implementation. The point is to give the candidate the chance to use some FP functions. The non-FP solution isn't as nice to look at.

def sum_adult_ages(lst):
    adults = filter(lambda p: p['age'] >= 18, lst)
    return reduce(lambda x, y: x + y['age'], adults, 0)

Databases/SQL

Generally speaking, for what reasons would someone normalize a relational model to a higher normal form?

Higher normal forms guarantee lower vulnerability to data inconsistency, reduce data duplication, and reduce the of the number of unused columns.

If I have a schema like:

+--------------+    +--------------+
| table A      |    | table B      |
+---------+----+    +---------+----+
| data    | ID |    | data    | ID |
+---------+----+    +---------+----+
| A1      | 1  |    | B1      | 1  |
| A2      | 2  |    | B2      | 2  |
+---------+----+    +---------+----+

What are the results of the query:

select * from A, B where A.ID = B.ID;

or (for those who prefer join syntax):

select * from A inner join B on A.ID = B.ID;

It's amazing how many people screw this up. The result set would be:

A1, 1, B1, 1
A2, 2, B2, 2

How would you model a many-to-many relationship (M:N cardinality) between two tables (i.e. a situation where employees can have multiple managers and managers can have multiple employees)?

Junction table.

Say you needed to model some massive (like 100s of GBs) quantity of data in a database (e.g. customer data for a book store or something), but queries for most of the data needs to happen instantaneously, what are some approaches for optimizing the database, assuming you had the ability to design the schema from scratch?

Lots of good answers here, but probably should mention indexes, denormalization, star/snowflake schemas, fact tables, data marts/warehousing, materialized views (indexed views in SQL Server), or maybe even NoSQL solutions.

Closing

What kind of technical stuff are you interested in (and do you have any side projects or do any other technical stuff outside of work)?

A critical question if you want a quality candidate. Almost everyone that's any good at programming will be genuinely interested in it enough to do stuff on their own time or have some areas that they're especially fond of. If this is the case, you can get them to tell you about it with obvious enthusiasm.

Anything else that we didn't cover that you'd like to add?

This is where they can tell you how they're a genius in some obscure field of math, science, or engineering.

Do you have any questions?

Most people do. If not, no big deal.

There's a rolled up job offer in my pocket, reach in there and grab it.

When the candidate get his hand around it, he won't be able to pull it out. Tell him to keep trying.