How to impress me in an interview
In the past few years, I've interviewed dozens of candidates for JavaScript-heavy roles. Over that time, I've identified a few key areas that seem to be pretty good indicators of overall proficiency – and I focus on these pretty much exclusively in my technical interviews.
First and foremost, this post is about what to expect if you're interviewing with me. But it's also about how to conduct a technical interview of JS candidates, and which areas offer the best signal-to-noise ratios.
This is Not a Test
The most important thing that I try to stress in any technical interview is that I'm not administering a test. What I'm really interested in is using questions as a tool for facilitating a conversation about code.
So if I ask you to write a memoize()
function, what I really want is to give us a starting point to talk about higher-order functions and closures. I don't really care if you can write that function off the top of your head. Instead, what I'm really looking for is whether or not you can arrive at a solution with a little bit of guidance, and if you understand the underlying concepts.
If you get stuck along the way, ask for some help. And if you flat out don't know an answer, that's okay too. I'll do my best to explain it, and we'll work on another example together.
One of the most impressive things you can do in an interview is learn something new and then apply it. It lets me see how you think about problems and assimilate new information.
Anyway, the point is: not knowing things is totally okay.
Whiteboards
There seems to be a lot of anxiety these days about whiteboarding during interviews. Every couple weeks, I see an article on Hacker News about what a terrible, outmoded practice this is.
And for the most part, I agree.
That said, if you interview with me, you should expect to walk in to a room with a whiteboard on the wall. And you should expect that we'll use it.
Whiteboards are great for quick examples. If I ask you what an IIFE is, or how to write a ternary expression, I expect you to be able to jot that down on a whiteboard. Or maybe I'll write a function on the board and ask you what its return value is given a certain set of arguments.
What I won't ever do – and what I think is the primary cause of apprehension about whiteboarding – is ask you to write some big, 20-line function on a whiteboard. It's unnatural, it's slow, and frankly, it's pretty hard for me to read your code that way anyway.
Frameworks & Libraries
Don't care.
As JavaScript engineers, we use third-party code all day, every day. On the front-end, there's jQuery, Underscore, Backbone, Ember, Angular, React, Moment, D3, Bluebird, THREE, and a million others. With Node, there are currently something like 166,000 packages on npm.
We're all learning new APIs constantly, and it's totally unreasonable to expect that you happen to know the same ones that I do. I will almost never ask specific questions about libraries or frameworks.
If you've got a strong understanding of fundamental JS concepts, you'll learn the libraries we're using pretty quickly.
I'm just not that worried about it.
Closures and First-Class Functions
Super important. I expect everyone I interview to be very comfortable with these concepts.
Here's a typical example that I might present to a candidate:
// write a function called `partial` that makes
// the following snippet work
function add( a, b ) {
return a + b;
}
var add5 = partial( add, 5 );
add5( 4 ); // 9
If that elicits a deer-in-the-headlights look, I might steer the discussion like this:
"Okay, so it looks like partial
accepts two arguments. One is a function, and the other is a number."
That'll usually get us at least to this point:
function partial( fn, num ) {
}
"Great. And partial
must return a function, because we're assigning its return value to add5
and then calling add5()
".
partial( fn, num ) {
return function() {
};
}
"Cool. That's the basic idea. So, if add5
is the function that partial
returns and it expects a number as an argument, where does that go?"
Usually, this is the point where a light bulb turns on.
partial( fn, a ) {
return function( b ) {
return fn( a, b );
};
}
Again, the point here is not necessarily that you can do this without any help (although that's great, and it's what I'd expect from a more senior candidate). What I'm really hoping is that you can get there with a little bit of direction.
Prototypal Inheritance
This is definitely an area that tends to separate junior devs from more senior ones, although in my mind, it's something everyone applying for a JS role should know.
Here's a problem that I might give to a candidate:
// make a class called `Square` that inherits from
// `Rectangle` and satisfies the following snippet
function Rectangle( width, height ) {
this.width = width;
this.height = height;
}
Rectangle.prototype.area = function() {
return this.width * this.height;
};
// your code here
var square = new Square( 4 );
square.area(); // 16
Square.prototype.area === Rectangle.prototype.area; // true
If this looks foreign to you, I would strongly recommend brushing up on prototypal inheritance. It's really not very hard once you get the hang of it, and it's an extremely powerful and important feature of JavaScript.
Oh, and here's the answer:
function Square( length ) {
Rectangle.call( this, length, length );
}
Square.prototype = Object.create( Rectangle.prototype );
What's this
?
There's probably no other feature in JS with a worse simplicity-to-confusion ratio than the this
keyword. You can basically learn everything about it in an hour, but so many JS developers never do.
You should know how Function#call()
and Function#apply()
work. They are absolutely essential to writing JS at a high level, and they're super easy to wrap your head around.
This is low-hanging fruit.
Async
Another big one, especially if you're applying for a job where you'll be using Node.
Here's a question I might ask:
// write a function called `shout` that accepts
// a string and a callback function, and uses
// `exclaim` and `yell` to transform its input
function exclaim( value, fn ) {
setTimeout(function() {
fn( value + '!' );
}, 100 );
}
function yell( value, fn ) {
setTimeout(function() {
fn( value.toUpperCase() );
}, 100 );
}
shout( 'hello', function( shouted ) {
console.log( shouted ); // 'HELLO!'
});
Again, this is really something that I expect every JS candidate to be comfortable with. If you're about to interview for a JS gig and you're not familiar with this stuff, drop what you're doing and spend some time practicing. It's that important.
Oh, and the solution to that problem:
function shout( value, fn ) {
exclaim( value, function( exclaimed ) {
yell( exclaimed, fn );
});
}
Trick Questions
Personally, not a fan.
In the rare occasion that I do ask a trick question, I'll call it out beforehand, and I won't really care if you miss the "trick". What I'm really trying to accomplish in cases like this is to start a conversation.
"Not quite. Remember, variables get hoisted in JavaScript..."
"That's actually a ReferenceError
. Can you see why?"
Questions like this can be really useful, but I use them pretty sparingly because nobody likes to feel like they've been set up for failure.
Advanced Stuff
Okay, so you were able to breeze through closures, prototypal inheritance, and async functions. Now what?
At this point in an interview, I'm usually pretty confident that a candidate has an intermediate to advanced understanding of the language, and my goals for the interview start to shift a little.
What I really want to know now is how much you know. I'm trying to get a sense of the shape and depth of your JavaScript knowledge.
This is where we start to move away from core concepts and I might start asking about specific language features or more advanced functional programming.
I might ask you to use Object.defineProperty
or to write a curry
function. Maybe we'll talk about promises or recursion.
These are things that you don't really have to know, per se, but since you've got the basic stuff down, I need to ask these types of questions to get a better sense of how advanced you are.
Think of this as extra credit. It's an opportunity to impress me. Anything we talk about at this point is essentially just bonus material.
Memorization
This is sort of a tricky area, and I'm a little bit conflicted.
I expect a senior level JS person to know the argument signatures for Array#splice()
or Function#bind()
.
At the same time, I have never worked in an office without an Internet connection – and looking something up on MDN takes about 20 seconds.
I never explicitly quiz candidates on stuff like this, because it just doesn't strike me as being particularly important. That said, if I realize during the course of our interview that you don't know how to use a common method like Array#push()
, that's a pretty good indicator that you haven't been writing JS for very long.
In short: Learn the most commonly used stuff, but don't feel like you need to memorize the entire EcmaScript spec.
Ask Questions
If you only take one thing away from this post, let it be this:
If you don't know something, or you aren't sure, ask me.
Not knowing something is a problem with a very simple solution. Lacking intellectual curiosity is much harder to fix.
I love hiring candidates who need a bit of mentoring. It's fun for me, and it's great for the team. One of the best ways to crystalize your own understanding of a concept is to explain it to someone else, and fostering a team environment where we're all teachers and students is the best way I know to continually raise the bar for everyone.
We all have plenty more to learn, myself included. My goal has always been to hire people who embrace that fact, and who are genuinely excited about learning new things and becoming stronger engineers.
I'm Hiring
Is this hypothetical interview sounding pretty fun to you? Are you in the Boston area?
Shoot me an email, and come work on crazy, top-secret things at Project Decibel.