The (JavaScript) Question I Bombed In An Interview With a Y Combinator Startup
nathanleclaire.com
nathanleclaire.com
The code is pretty simple - very similar to what you did:
function (func, wait, immediate) {
var timeout, args, context, timestamp, result;
return function() {
context = this;
args = arguments;
timestamp = new Date();
var later = function() {
var last = (new Date()) - timestamp;
if (last < wait) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) result = func.apply(context, args);
}
};
var callNow = immediate && !timeout;
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (callNow) result = func.apply(context, args);
return result;
};
}But obviously, in this case, the interviewer specifically outlined requirements that would make debounce the better choice than throttle.
In that case, showing live updates in the window during resizing might not be worth it.
_.debounce: [...] Useful for implementing behavior that
should only happen after the input has stopped arriving.
http://underscorejs.org/#debounceRight after your quote, the docs add: "For example: rendering a preview of a Markdown comment, recalculating a layout after the window has stopped being resized..." These operations can both be very expensive on the client side — layout is slow — and can also distract the user if they make stuff jump around on the page. The downsides of doing these updates too often are more clear than for a simple autocomplete.
Empirically, I can't type fast enough (sustained) for throttle to be better than debounce here — there are frequent 200ms gaps in my key presses. This is part of why I was confused. I thought I was typing very quickly, definitely faster than 43wpm == five keystrokes per second, but apparently I slow down to think now and then. My code seemed to behave like _.throttle already, but changing the timeout from 200ms to 2sec made it clear that it wasn't.
But I'm switching to _.throttle, partly in case someone is a faster typist than me, and partly because it makes a leading-edge call, which may give a feeling of greater responsiveness.
1. http://drupalmotion.com/article/debounce-and-throttle-visual...
Don't be afraid to use you're own notebook/laptop to Google a solution, or keep asking questions about the desired solution.
Be free in not having all the answers either, be confident you can find the answers. An interview shouldn't be about vague technical hurdles you have to jump through.
It's about proving competence & compatibility of character.
If your interviewer is willing to end the interview because of one dropped ball, call them on it.
I think you got lucky by avoiding to work with these type of people before it got too late.
Given it took Nathan a reasonably small amount of time to research and learn the correct answer, what disqualifies him from being (or quickly becoming) a skilled developer for your startup?
In other words, what's the minimum skill and knowledge level you'd accept, given that the applicant know how to learn the rest? Is that level arbitrary?
For one, setTimeout is pretty run of the mill. If you haven't come across a situation where you need to wait a period of time before initiating some event, you simply haven't coded much. If someone else had just nailed the question in the interview before him than—hoop or not—they've proven a skill he hasn't.
Even if we ignore this, the "What Really Happened" area sounds like he only admitted he doesn't know, and worse, that he doesn't know how to proceed. Another comment above asks if one small set back is really a deal breaker, but in my opinion, not attempting to overcome a problem you haven't seen before shows more about a candidate's abilities than simple knowledge. Prove you can find a solution when all you have is a basic idea of the problem. Take a hint and run with it. (The interviewer gave the method name as a hint!) Google the answer.
This post hints that the position was closer to entry level, so I would suspect that curiosity and autonomous problem solving are fundamental requirements for the role. When you're green a lot is going to be brand new, so you have to be able to learn on the spot and run with it.
In fact, this is the primary reason I'm trying to move away from 'vanilla' front-end to more heavy js or backend stuff.
Completely agree. They'll toss the resume of someone who is an expert in graph theory, because they really need someone who knows machine learning, completely unaccepting of the fact that someone willing and able to become an expert in graph theory can probably do the same on machine learning.
This all plays into the current trend of businesses not being willing to train employees.
"Ok, draw me a square"
[proceeds to fail at squiggling something resembling a triangle]
For every job there is a hard, arbitrary skill floor.
Heck, we can't even decide what a web developer actually does, as opposed to a web designer, or "growth hacker", or UI/UX "expert", or back-end programmer.
How can we set a minimum when we can't clearly define the task beforehand?
This is not even testing an obscure application of closures. I mean, the trick here is not knowing about closures, but about knowing the details of the setTimeout function -- specifically, that there is a corresponding clearTimeout function (which, as a non-specifically frontend developer, I had long forgotten if I ever knew it).
That's not testing programming competency, that's testing knowledge of the JS standard library, and secondarily knowledge of closures. I mean, it's a legitimate thing to test for, but let's not pretend it's somehow analogous to fizz buzz.
Edit: And none of you even mentioned the error in his code, which another commenter pointed out: wrong function. It should have been clearTimeout
I've been asked similar questions in interviews, and when I haven't known the little bit of factual information required (in this case the existence of setTimeout and clearTimeout), I've asked to Google it, and my interviewers have always been more than happy to let me. I've passed interviews doing this. I've even had friends who do interviews tell me that 'googling an answer' is often the correct answer.
I personally think the choice of setTimeout/clearTimeout was a really good one because almost all JS devs will know it, but it's also really easy to find online if you know what you're looking for. This test is really about coming up with a good way to solve a problem.
setTimeout is something I had to learn about very early in my web development career. The essentials of jQuery too. Callbacks too, unless all you need is someone who does mainly html+css with a bit of jQuery. The interviewer asked exactly the kind of question that I'd consider a 'minimum'.
Of course, as others have pointed out, it also depends on what you're looking for. If you're okay with someone who can learn a lot on the job, and if you don't mind that this person has some basic things to pick up on, you'll probably be focusing more on how the interviewee approaches the problem, and how they interact with you as the interviewer.
The OP's takeaway seems to be that he should have known setTimeout well enough to walk through a solution. With that approach I think anyone will have a similar experience, only it would be some other random question. The lesson learned should be to actually make the attempt and try anything at your disposal. Ask questions. Ask for hints. Don't just say "um, I don't know."
This is neater than using a variable defined outside of the closure, but I was under the impression that attaching arbitrary data to DOM nodes was bad form.
Thoughts?
The typical situation is creating a variable to a dom node, and then attaching an event handler to that dom node. The event handler has a reference to the dom node through its closure object, and the dom node has the reference to the event handler creating the circular reference. You must be careful to null out the event handler when you are done with it.
For arbitrary data, jquery provides a data() function that does the cleanup stuff for you. for event handlers, well, jquery's bind() (now renamed to on() ) is one of the first things you learn in jquery, and it (i assume) also deals with the IE bug.
I'm mainly curious about this in terms of programming style/best practices. Beside implications to the namespace of that node (which could be avoided with data()), it seems to me that it would be best to separate the setTimeout ID to a variable defined outside of that closure simply to make the code maintainable, for if there ever was another reason to interrupt the setTimeout.
However, due to the mention of closure at all by the interviewer, it seems that he felt that attaching it to the DOM node was the "best solution". Would you agree?
$(document).ready((function() {
$('input').keypress((function() {
var timeoutId = null;
return function() {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(function() {
$.ajax({ /* ... * /});
}, 200);
};
})());
});
// NB: this solution only works if there is one input.
// If there are more than one, you need to create a new closure for each one.On a broader level, an interesting question is: when is it good practice to attach a variable to a DOM node? I would say very rarely except perhaps in the case where what you are doing is assembling some kind of interface widget out of HTML elements. Then storing information about the widget's state with the dom node is what makes the most sense.
Since in the question, the task at hand is constructing an autocomplete widget, apparently from scratch without recourse to the many easily available robust and tested existing libraries, it does indeed make some sense to store the timeout state with the DOM node. If your goal is a robust reusable component, you want something that can cope with having many instances on a page. to do that and maintain the behavior of one on its own, you can either attach the state with the dom node, or create a framework that simulates doing that, but implements it in some other overly clever way.
Unfortunately, this is really easy to do with closures. For instance, patterns like this are pretty common:
var domElement = $("#someId");
domElement.click(function () {
domElement.style.color = "red";
});You use clearInterval with setInterval, and clearTimeout with setTimeout.
INTERVIEWER: So, you may be able to guess, that there is a
problem with this code. It is very inefficient. If you
type a string with 30 characters into the text box, the
server gets called 30 times. Not good, we are having all
kinds of issues with scalability so we can’t afford to be
writing code like this.
Calling code 30 times is a problem. Sure there's a few places that might be true. Is this a device driver ? A video decoder maybe, or something else that's horribly complex ? Nope, just the most basic MVP website. Oh my fucking god. I remember programming on windows in Delphi, and on linux in QT. In both cases doing autocomplete the naive way just fucking works. Even with millions of possible completes.I remember implementing a function plotter that just completely refreshed a canvas pixel-by-pixel upon keydown. Not a problem. Even re-rendering a robot's simulated environment every keypress was nowhere near problematic.
And now we're worried about a 30 times called dead simple function, in the most basic of websites. Wow.
Progress.
(I understand why this happens. Server latency ... just works that way I guess. But I don't have to like it. HTML page layout is another peeve of mine. Resizable layouts are a solved problem in every single GUI toolkit except for one. Custom components are another seriously lacking web thing. It is a major javascript accomplishment to display a custom temperature-like gauge ... wtf ?)
This problem is not unique at all to the browser environment. You should probably throttle/debounce autocomplete events any time a server is involved.