How to Conduct a Fair and Meaningful Technical Interview

Cho S. Kim
Tweet

When I began searching for my first job as a web developer, I applied to, and received interviews with, several companies. Some of my interviews were with Fortune 500 companies; some of my interviews were with fledgling start ups. Regardless of the size of a company, the interview process was very similar: phone screening, technical challenge, and cultural screening.

The technical challenge informed me about a company’s character. If the questions being asked were fair and meaningful, then I, regardless if I passed or failed the technical interview, would leave with a favorable impression of a company. At worst, I would leave without a job but with some new and useful knowledge.

If the questions I was being asked were out of the scope for a particular position or merely a trick, then a company risked alienating me and other applicants. I can still recall an interview I had with a CTO of a start up in Manhattan, New York. This person asked me to describe the difference between prototypal inheritance and prototipal inheritance. The second inheritance pattern didn’t exist. After my interview, I talked to a few of the other applicants, and we all agreed – we would never work for that company.

So what’s considered fair and meaningful? Fair is considered asking questions that are appropriate for an applicant’s prospective position. Meaningful is considered asking questions that reveal some level of understanding of a fundamental concept. When a question is fair and meaningful, both the interviewee and interviewer benefit.

I believe that both of these objectives can be meet with these three concepts:

  1. Callbacks
  2. Binding
  3. Event Emitters & Inheritance

Each of these concepts are integral to a web developer’s knowledge; these topics, however, are disconnected enough to give an interviewee who incorrectly answers a question an opportunity to correctly answer the other questions.

A rubric for grading a technical interview is located after these three concepts.

Callbacks

Interviewers should always ask an interviewee to define a concept. This initial step confirms that the interviewee understands what’s being asked. If the interviewer fails to ask this question, then the interviewee should volunteer to share their understanding of the concept. Without a mutual definition, the interviewee is unlikely to solve a given task.

After a mutual definition is reached, the interviewer should present a question involving code: I want to explore your understanding of callbacks, so please create an implementation of a well-known function called reduce. At this point, the interviewer should present an invocation of reduce with example input and output data.

// input
reduce([1,2,3], function(total, value) {
  return total + value;
}, 0);

// output 
6

Prior to an interviewee creating their implementation, an interviewer should ask the interviewee to talk aloud during this process. This step enables an interviewer to understand how an interviewee thinks and to also prevent an interviewee from going too far down an incorrect path.

The interviewee will create, based on my experience, an implementation of reduce using a for loop:

var reduce = function(array, callback, base) {
  for (var i = 0, length = array.length; i < length; i++) {
    base = callback(base, array[i]);
  }

  return base; 
};

The next step of this process is add a bit of complexity to the question. Prompt the interviewee to refactor their implementation of reduce to include another well known function called each. This request will require the interviewee to use two callbacks, each nested inside of reduce:

var each = function(array, callback) {
  for (var i = 0, length = array.length; i < length; i++) {
    callback(array[i], i, array);
  }
};

var reduce = function(array, callback, base) {
  each(array, function(current, i, array) {
    base = callback(base, current);
  });

  return base;  
};

Binding

Repeat the same steps of the previous question. Ask an interviewee to define the concept of binding, ask the interviewee to create an implementation of bind, and ask the interviewee to talk aloud.

In regards to bind, the interviewee can create an implementation with or without using a prototype. Interviewers should allow the interviewee to create the simpler implementation first – without a prototype. This approach enables the interviewee to build confidence when asked for the more advanced implementation.

Here’s an example of input and output data for bind without a prototype:

// input: 
bind({name: "Cho"}, function() { 
  return this.name; 
});

// output: 
"Cho" 

Here’s an implementation of bind without a prototype:

var bind = function(context, func) {
  return func.apply(context);
};

The next step is to ask the interviewee to implement bind using prototype. Here’s an example of input and output data for bind with a prototype:

// input: 
var myFunc = function() { 
  return this.name; 
}; 
   
myFunc.bind({name: "Cho, again!"}); 
   
// output: 
"Cho, again!"

Here’s an implementation of bind with a prototype:

Function.prototype.bind = function(context) {
  var func = this;

  return func.apply(context);
};

If an interviewer wants to further increase the difficulty of bind, then ask the interviewee to refactor their implementations of bind to accept arguments.

Event Emitters and Inheritance

The concept of event emitters will be less familiar to an interviewee than callbacks and binding. Due to this reason, interviewers should clarify to the interviewee that many phrases are used to describe this concept, such as eventing system and eventing library. Once the interviewee has agreed to a mutual definition, present some restrictions for a desired implementation.

An interviewer can achieve this goal with a prepared example of input and output data:

// input:
eventEmitter.on("greet", function() {
  return "Hello, Cho.";
});

eventEmitter.trigger("greet");

// output:
"Hello, Cho."

The interviewee is now ready to write some code.

var EventEmitter = function() {
  this.events = {};
};

EventEmitter.prototype.on = function(event, callback) {
  this.events[event] = callback;
};

EventEmitter.prototype.trigger = function(event) {
  if (!this.events[event]) {
    throw new Error("Event doesn't exist");
  }

  return this.events[event]();
};

If the interviewee has made it this far into the technical challenge, then ask them to use a different inheritance pattern for their implementation of event emitter. This additional step will test the interviewee’s comfort with different implementations of code.

var makeEventEmitter = function() {
  var obj = Object.create(prototype);
  
  obj.events = {};

  return obj;
};

prototype = {};

prototype.on = function(event, callback) {
  this.events[event] = callback;
};

prototype.trigger = function(event) {
  if (!this.events[event]) {
    throw new Error("Event doesn't exist");
  }

  return this.events[event]();
};

A Rubric for a Technical Interview

There are many factors to consider when evaluating an interviewee’s performance on the technical challenge. I consider the following factors when I interview:

  • Consistency: Is the use of indentation or white space consistent?
  • Naming conventions: Are the names for variables descriptive?
  • Testing: Is more than one use case considered?
  • Questions: Has the interviewee defined the scope of a question?
  • Code familiarity: Is the applicant using native methods and not recreating them?

Conclusion

A technical interview can leave a lasting impression on an interviewee. If an interviewer’s goal is to make the technical interview beneficial for them and an interviewee, then the best approach is to ask questions that are both fair and meaningful. If an interviewer can achieve this goal, the worst outcome for an interviewee is that they are not offered a job but they leave with some new and useful knowledge. That’s a decent proposition for everyone involved.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • joolythomas

    $97/hr pavivdv by Google, I am making a good salary from home $5500-$7000/week , which is amazing, under a year ago I was jobless in a horrible economy. I thank God every day I was blessed with these instructions and now it’s my duty to pay it forward and share it with Everyone,

    Here ­­­­­­­­­is ­­­­­­­­­I ­­­­­started>>>>>>>>>➜➜➜➜➜➜➜

    ➜➜➜➜ W­W­W­.­P­A­Y­R­A­P­.ℭ­ℴ­m

    —————————————————–

    GO TO THE SITE –>>>CLICK NEXT TAB FOR MORE INFO AND HELP

  • http://www.tailormadesolutions.com.au Bradly Sharpe

    In the second code block under Callbacks is it supposed to return base?

    • Cho S. Kim

      Bradly, you’re correct. That’s a typo on my part.

  • Cho S. Kim

    jnotnull, you’re correct. That’s a typo on my part.

  • Per Flitig

    I think you have another typo in your third code example under Callbacks. Your refactored reduce function

    var reduce = function(array, callback, base) {
    each(array, function(array[i], i, array) {
    base = callback(base, array[i]);
    });

    return base;
    };

    should probably be

    var reduce = function(array, callback, base) {
    each(array, function(current, i, array) {
    base = callback(base, current);
    });

    return base;
    };

    or even

    var reduce = function(array, callback, base) {
    each(array, function(current) {
    base = callback(base, current);
    });

    return base;
    };

    • Cho S. Kim

      Thanks, Per. I’m correcting this and others that may appear. I’ll update this post once the changes have been made.

  • M S

    OK, so i guess i wouldn’t get hired then…

    Because i have never ever heard of this ” well-known function called reduce”.
    Not in any programming-language i know,
    not in any programming or algorithm-courses,
    not while reading about programming on the web, which i do every day.

    Zero, zilch, zip, nada, nothing!

    Even Googling the term now, Im not sure what its supposed to be for.
    An obtuse way to say “add things up”, yes?

    I have to say, as someone who is currently looking for a job, i *really* hate reading articles like this :(

    • M S

      Because disqus is useless, i will answer the comment above here.

      Thanks, but the first example makes no sense at all.

      I have read it over and over, and there is no way it makes sense.

      As far as i can see, there is an example of simple crystal clear code.

      And then they want me to instead do the same thing using a syntax where there is no way to understand by just looking at it what it does.

      That’s worse than useless.

      The second example seems to try to explain reduce, using a pile of equally obscure functions, that i also never heard of, that in turn need extensive research to understand.

      And since I don’t need any new better ways to obfuscate my code, fuck it.

      • Cho S. Kim

        Can you tell me which lines of code in the code snippets appear unclear to you? I’m happy to explain anything, but I want to make one point clear: The code is written well, follows good design practices, and works as intended.

    • Cho S. Kim

      M S, thanks for leaving a comment. I’m surprised that you couldn’t find any articles about reduce when searching Google?

      I just typed in the term “reduce function” into Google Chrome, and it returned to me 428 million results. The first article in the suggestions clearly shows that reduce is provided as native method for arrays in JavaScript. The third article, which references the documentation for underscore.js, also lists reduce as a provided method. Ruby and Python also have their own implementation of reduce….

      • http://timseverien.nl/ Tim Severien

        First I’d like to say that I love *each* of these tests. The first one however was rather hard for me, but I think I know why.

        Unlike M S, I did hear of reduce() before, but I can’t remember using it and so I can’t remember what it does or is supposed to do.

        Because of the naming, my first guess would be something similar to filter(); simply reducing the amount of array items. I would have utterly failed that test.
        However, if someone would ask to “write a function where all (numeric) array items are added to a final number,” I’d probably call it sum(), as that’s the function I’m familiar with and which I personally find less obfuscated.

        To prove my point, ‘reduction’ (redirected from ‘reduce’) is not known to be the sum of several numbers*. Not in computing and algorithms, not in mathematics. ‘Summation’ however is the actual English word for that operation.

        So, why do I think this question was so hard for me? I think it’s a combination between me not being too familiar with common (but pretty specific) implementations, and this particular function name being slightly confusing.

        Luckily, I am prepared if businesses adapt your tests ;)

        * On Wikipedia. Though it’s debatable whether Wikipedia should be used as resource, if ‘reduce’ was a thing, it would be listed. But it’s not.

  • Gerald Wolfe

    reduce’s function in the first example should be called like this [1,2,3].reduce(function(total, value…)…

    • Cho S. Kim

      Hey, Gerald. That’s one approach, which involves adding a method to Array’s prototype. Many developers would suggest, however, not modifying native objects.

      In the context of this article, I could ask an interviewee to create an implementation of reduce using the approach you’ve described and the approach used in this article. Then ask questions about the possible advantages and disadvantages of both. There’s always more than one way to write code. The more pertinent question here is understanding what’s the trade-off between different implementations.

      • Gerald Wolfe

        Thank you Cho,
        Your response and takeway are both helpful and educational.

  • John

    Thanks for this article. What if a non technical person wants to employ the right developer within his company? What sort of tests would he need to give out and how can he determine if the candidate is up to standard ?

    Thanks

    • Cho S. Kim

      John,
      This is a good but hard question to answer. Regardless of which questions a non-technical person asks a prospective developer, the non-technical person is unqualified to evaluate the quality of the answers.

      In fact, the answers hold marginal value. To gain a meaningful understanding of a developer’s skills, you need to understand how that developer thinks. Did the developer, for instance, use a logical approach in solving a problem–even if that developer didn’t get the correct solution? Did the developer understand the trade-offs between two or more potential solutions? Without a technical background, it’s difficult to evaluate any of this information.

      My suggestion for you is to employee the assistance of another developer. If this is impossible, see if the developer you want to potential hire has made any contributions to popular repositories on Github. But even then, quantity is far less meaningful than quality. You need know how to gauge the merit of the contributions.