Here is my typical multi-part interview question.

## Compute factorial of N using recursion

All I am looking for is simple code like this

1 | function factorial(n) { |

## Can you verify this code computes the correct factorial?

I am looking for something quick and dirty

1 | console.assert(factorial(1) === 1, '1!'); |

If a person writes actual QUnit / Mocha / anything unit tests that is a plus.

## Can you find the largest N the system can compute factorial for?

I am looking for the value of N where the max size of the stack is exhausted. The candidate should know that when using recursion the previous call remains on the stack, so computing factorial of 5 means there are five calls at once at some point

1 | factorial(5) { |

The candidate should try different values of N, probably starting with 1000, 10k, 100k, etc. On my machine, the stack is exhausted for n = 100k.

## Can you write factorial using iteration?

Change code to a loop, and I am looking for the candidate to reuse the unit tests from before.

## Can you write asynchronous version of factorial function using promises?

I am looking for recursive (simpler) version of the code, something like this using Q library

1 | var Q = require('q'); |

## Can you write unit tests for your asynchronous factorial?

I am looking for something like this, quick and dirty, but the candidate should know how to handle the error.

1 | factorial(5).then(function (result) { |

## Can you test multiple numbers, for example [1, 2, 3] at once?

I am looking for the candidate to know how to execute multiple promises in parallel. Q, Bluebird and $q libraries have this feature

1 | Q.all([ |

## Does the recursive async version crash for large N?

Yes, the candidate should just try running the same large N found earlier against the promise-returning factorial.

## Advanced: rewrite async factorial to avoid stack exhaustion

I am looking for understanding the different between creating a chain of promises and executing a function. A simple solution is to build the chain first without using recursion and then execute it.

1 | var Q = require('q'); |

Notice there is no call to `factorial`

anywhere inside this code. The only detail is binding the value of `n`

when creating the `then`

callback function.

This function can "compute" factorial for n = 100k. I am putting the word *compute* in quotes because the actual
value quickly reaches `Infinity`

. But the stack is never exhausted!

## Advanced: write async factorial using native ES6 promises

Native promises are already in V8 and the syntax is very simple. To avoid using Q when building promise chain one can write

1 | function valuePromise(n) { |

## Advanced: write tail call optimized version of recursive sync function

If the candidate is familiar with the tail call optimization, he / she could write the ES6 version and show the 6to5 transpiler transforming recursive code to the imperative one.

1 | function factorial(n, acc = 1) { |

Notice the accumulator parameter that replaced `n * factorial(n - 1)`

expression. The recursive call
is by itself at the *tail* of the function.

## Advanced: write factorial using generators

Generators exit the function AND keep the internal state after each `yield`

. Thus we can keep multiplying
the number without growing the stack.

1 | function* Factorial() { |

## How to prepare for these interviews?

- Read a few of my favorite JavaScript books.
- Read my other blog posts.
- Follow me on twitter @bahmutov
- Read about upcoming ES6 features