
The (JavaScript) Question I Bombed In An Interview With a Y Combinator Startup - zenlikethat
http://nathanleclaire.com/blog/2013/11/16/the-javascript-question-i-bombed-in-an-interview-with-a-y-combinator-startup/
======
mdkess
Underscore has a nifty function, _.debounce, which given a function f, returns
a version of the function that behaves as the one in your interview question.
[http://underscorejs.org/#debounce](http://underscorejs.org/#debounce) Even if
not using libraries, it would be nice to abstract that into its own function
when you inevitably want to use it again in some other control.

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;
    	    };
    	  }

~~~
rvivek
I'm guessing underscore's throttle function would be the better way, if
underscore is available.

~~~
STRML
As other comments have pointed out, `_.debounce` is the correct answer. Here's
the bit from the docs that always reminds me when to use `_.debounce` over
throttle:

    
    
      _.debounce: [...] Useful for implementing behavior that
      should only happen after the input has stopped arriving.
    

[http://underscorejs.org/#debounce](http://underscorejs.org/#debounce)

~~~
graue
That bit from the Underscore docs is only a suggestion, and one that Google,
for example, certainly doesn't follow. Try typing a search query so fast you
don't get suggestions until you're finished. It's hard to do!

Right 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.

------
1qaz2wsx3edc
This is a terrible interviewer, it has nothing to do with you. They know what
they want, but they don't know how to find it properly.

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.

~~~
ricardobeat
Really? I don't think there was anything wrong with the interviewer at all, he
just wasn't at the level of experience they were looking for. There is no
point in extending the interview beyond that point if you know it's not going
anywhere.

------
adyus
This is more of a question for the startup that Nathan was applying to:

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?

~~~
eshvk
Maybe it is not about him being disqualified, maybe it is about the fact that
the other people they interviewed were able to jump through their hoops and do
all the tricks _and_ were equally as qualified?

~~~
halisaurus
Why not both?

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.

~~~
jdmichal
I would say they've proven a knowledge, not a skill. setTimeout is not a
skill, it is a knowledge. Analytical thinking is a skill -- one that he failed
to prove when, given the knowledge, he still could not find an answer.

~~~
eshvk
The problem is that a lot of people in Industry think they are hiring for
analytical skill but they are really hiring for knowledge. Seriously, let us
take questions in anything from graph theory to dynamic programming. All that
proves is that you have studied these problems well enough to be able to spot
them during the interview and then solve them. And you know what? You don't
necessarily need abstract knowledge less analytical skills to be successful in
most programming jobs so I guess they are okay with what they are doing.

~~~
mercer
I'd say perhaps especially in front-end, knowledge is much more important than
analytic skill. Most of the challenges I face in html and css seem to be more
about hacks to get something to work as desired than about properly reasoning
about the problem.

In fact, this is the primary reason I'm trying to move away from 'vanilla'
front-end to more heavy js or backend stuff.

------
drewblaisdell
The solution in the post attaches a setInterval reference to the "this"
object, a reference to the input box.

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?

~~~
TheZenPsycho
attaching arbitrary data to DOM nodes is fine in theory, except that older
versions of IE have a bug in their garbage collector that doesn't cope with
cyclical references. Cyclical references are very easy to unintentionally
create in javascript because of closures.

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.

~~~
drewblaisdell
Thanks for the reply.

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?

~~~
TheZenPsycho
Attaching an event handler to a dom node is the /only/ way to handle events.
As for where to put the setTimeout variable, I would say best practice is just
use underscore's debounce function, and you avoid the question of where to
store that variable altogether. (it's kept inside the closure of a wrapped
function. secretly. But you don't really care where it is since all we are
interested in is the external observable behaviour of the debounced function)

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.

~~~
drewblaisdell
Apologies for the ambiguous wording: I meant attaching the timeout ID
specifically to the DOM node. dmbass posted a solution above that handles all
style issues I had with the answer in the post.

~~~
TheZenPsycho
yes I see. I suppose it's javascript's version of private instance properties,
versus public properties. The timeout ID doesn't need to be public, and
probably shouldn't be since what you actually want is an encapsulated self
contained widget. You don't really want to have to reach inside of it to touch
some implementation detail. So hiding it in a closure takes care of that. If
you want the widget to have the capability of cancelling, you should add a
cancel method to it.

------
ultimatedelman
after you gave him your "clever" answer, you should have followed up with
mentioning that keypress is the wrong event to use, but rather "keyup", since
keypress varies across browsers and doesn't account for the holding down of
keys. try holding down a key in your demo to see what happens :)

~~~
Hengjie
Keyup doesn't account for holding down keys either. It's keydown that is what
you're after for that one.

~~~
dmbass
You want the oninput event, but IE < 10 has horrible support for it. Figuring
out when the input value has changed is a lot more complicated than picking
one of onkeyup/down/pressed.

------
TheSisb2
There's an error in your good solution. window.clearInterval(this.timeoutId);
should be window.clearTimeout(this.timeoutId);

You use clearInterval with setInterval, and clearTimeout with setTimeout.

------
nickbauman
Any stupid can interview for someone who is an exact fit with all the
experience needed to do the job. Unfortunately very few people who fit the
bill like that are even available let alone affordable.

------
Afforess
I would have mentioned the Jquery-UI built in autocomplete function...

[http://jqueryui.com/autocomplete/](http://jqueryui.com/autocomplete/)

~~~
yen223
Does Jquery's autocomplete function support retrieving Ajax data on the fly?

~~~
tmzt
Having jQuery doesn't mean having jQuery UI.

------
jbeja
I was touch and related by this post since some weeks ago it happened the same
thing to me in a PHP interview, i will bookmark and whole this post dearly and
read it every time that i remember that futile day and feeling suicidal
instincts towards myself.

------
gotofritz
Well, it was a pretty basic Javascript question

------
dccoolgai
lodash.throttle() is a nice one for stuff like this sometimes.

------
donatj
In my eyes its a server side problem. Set a decent cache header. Problem
solved.

~~~
TheZenPsycho
huh? so your solution is to create cache entries for 30 separate unique
requests in a second, which are unlikely to be cache hits in the future?

------
waps
This makes me so very very glad I'm not a web javascript guy :

    
    
      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
?)

~~~
drewblaisdell
> And now we're worried about a 30 times called dead simple function. Wow.

This problem is not unique at all to the browser environment. You should
probably throttle/debounce autocomplete events any time a server is involved.

~~~
waps
True. In those toolkits, generally no server was involved.

