Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
The (JavaScript) Question I Bombed In An Interview With a Y Combinator Startup (nathanleclaire.com)
42 points by zenlikethat on Nov 16, 2013 | hide | past | favorite | 62 comments


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


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


Thanks for posting this. I'd written my own ad-hoc version of _.debounce for a web app, but the difference between throttle and debounce was totally lost on me. (If anyone else is slow today and doesn't immediately get it from reading the Underscore docs, there's a very clear comparison here[1].)

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


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


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.


Throttle is different, it's a rate limiter, whereas debounce just measures delays between calls. With throttle, the server request would be made every 200ms rather than 200ms after the user stops typing. From a user experience though, throttle feels like a better way to approach this, since it would let you update the list at a measured pace, but it would be incorrect for the problem as described.


Right, from a UX perspective, throttle makes more sense due to more constant feedback. You want the user to realize that it is a live search before they finish typing. Else, they'll just type the entire query.

But obviously, in this case, the interviewer specifically outlined requirements that would make debounce the better choice than throttle.


Good point. I've generally used debounce for live search, and throttle for window resizing, among other things. In hindsight throttle is perhaps better for live search as well.


For window resizing, i'd actually use debounce. Most times, a user resizes a window with a predetermined size in mind -- they want to show something behind the window, or want to make the window fill an existing space.

In that case, showing live updates in the window during resizing might not be worth it.


This is precisely what I would have suggested I would use if I were asked such a question.


Libraries are the solution, +1. A handcoded solution to this would make me cry.


Wow. A library to wrap setinterval or settimeout? Given the use of "this" in his answer is painful, core JavaScript is already loaded and in IMO more maintainable than 3rd party libraries. In this thread alone there are arguments about what to use from the library. If I were the interviewer I wouldn't hire that answer either. I want a developer who can code his way out of a box, not ignore the box.


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.


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.


Completely agree. Interviewer deserves personal performance review after making such conclusions.

I think you got lucky by avoiding to work with these type of people before it got too late.


It would depend on whether they're looking for a promising candidate or somebody who is already experienced. If they wanted the later then it would be obvious this was not the guy. Still, I think spending 5 extra minutes of your life with a young person to help them not feel like a failure - I don't think is too much to ask either.


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?


"I am a skilled painter"

"Ok, draw me a square"

[proceeds to fail at squiggling something resembling a triangle]

For every job there is a hard, arbitrary skill floor.


Completely agree. But we still haven't figured out what that hard skill floor is for web developers.

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?


I think the interview question detailed in the post makes a fine web development Fizz Buzz Test. It may not define the hard skill floor but not being able to answer this question correctly clearly identifies a candidate that has not written or read much Javascript at all. Basic JS experience and skill is a requirement for web development work today.


I'm sorry, I'm going to step in here and call you on this. This is nowhere near the skill level of a Fizz Buzz test. I mean, it may be a legitimate question to ascertain the presence of an intermediate-to-advanced web developer, but fizz buzz is something any reasonably competent beginner-to-intermediate programmer can figure out, even if they haven't run into it before.

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 disagree with you on this. The point of the interview as I read it was to test an understanding of closures, scoping, and really basic programming logic.

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.


I don't know if I agree - I've done plenty of setTimeouts in my life, but I can't remember if I've ever needed to cancel one before it fired, though. It seems slightly esoteric. (Then again, I don't sell myself as a front-end developer)


Agreed. I use setTimeout a lot, but generally don't need to cancel it. But the failure of the interviewee was not the part where he doesn't know how to cancel it, I think, but rather that he didn't know about setTimeout at all.


Assuming the interviewer is also a web developer, I think a good 'minimum' would be problems that the interviewer himself often came across. The kind of stuff that you put in some base_functions.js file for all your project, or that you use a library like underscore or lo-dash for.

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 admits that he didn't even try to answer the question. The interviewer basically gave him the answer, but he didn't ask for help or ask if he could look up setTimeout.

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


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?


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.


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.


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.


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.


> The problem is that a lot of people in Industry think they are hiring for analytical skill but they are really hiring for knowledge.

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.


Understanding closures properly, understanding JavaScript scoping, and being able to solve problems however are all skills, and I think were the point of this interview.


The transcript implies he was disqualified because of this question. Of course he may have bombed other questions and this was just the last chance saloon.


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?


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.


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?


Capture the timeoutId in a closure.

  $(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.


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.


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.


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.


Just for clarification: Older versions of IE have two garbage collectors, one for DOM elements and one for JavaScript. The issues arise when the circular dependency loops across these two collectors, so that the DOM collector is waiting for the JavaScript object to free and vice versa.

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


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


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


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.


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.


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.


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

http://jqueryui.com/autocomplete/


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


Having jQuery doesn't mean having jQuery UI.


ya. click the "remote datasource" link on the right.


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.


Well, it was a pretty basic Javascript question


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


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


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?


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


Uhhh isn't making 30 seperate network connections in a second a scalability problem regardless of language or platform? if the target server is apache, that's spinning up a thread for every keystroke, for one user, and you think this is a problem unique to javascript, why?


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


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


It can be a huge problem depending on the query that the server is running and the amount of traffic on the site. Avoiding completely useless auto-complete queries is fairly low-hanging fruit since it's so easy to fix.


Calling a function 30 times isn't the problem. It's calling the server 30 times that is the problem.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: