- Implement a utility function/class commonly found in popular libraries.
There's more to these functions than meets the eye. Let's take the innocent
Array.prototype.map for example. Are you aware that:
- It passes 4 arguments to the callback, including the
- It keeps the "holes" in sparse arrays, aka
[1, 2, , 4].map(val => val * val) === [1, 4, , 16].
- The range of elements processed by
map is set before the first call to callbackfn. Elements which are appended to the array after the call to
map begins will not be visited by callbackfn. If existing elements of the array are changed, their value as passed to callbackfn will be the value at the time
map visits them; elements that are deleted after the call to
map begins and before being visited are not visited. Source:
Array.prototype.map ECMAScript specification
Your implementation doesn't have to handle all of these cases, especially the array mutation one. However, it's a positive signal if you mentioned these cases. The closer your implementation is to the specification, the more senior/experienced you will appear to be.
If you take a look at the source code of these libraries, you might find some of the implementation to be quite complex. This is because there are lots of obscure real world use cases that the library has to support. Similar to the standard functions, you're not expected to handle all of these edge cases within an interview setting but you get points for calling them out.
- Find out what platform you are coding on and familiarize yourself with the coding environment:
- The supported editor shortcuts.
- Whether you can execute code.
- Whether you can install 3rd party dependencies.
- Make your self introduction under a minute. Unless requested, do not take longer than this otherwise you might not have enough time to code.
- Ask clarifying questions upon receiving the question. Clarify the following:
- Whether the code is meant to run in the browser or on the server (e.g. Node.js).
- Browser support, as this will affect the browser APIs you can use.
- Code out your solution and explain your code to your interviewer while you are coding.
- After coding, read through your code once and try to spot basic errors like typos, using variables before initializing them, using APIs incorrectly, etc.
- Outline some basic test cases and some edge cases. Test your code with these cases and determine if your code passes them. If it fails, debug the issue(s) and fix them.
- Optional: Explain the time/space complexity if the code involved algorithmic optimizations and smart choice of data structures.
- Explain any tradeoffs you made, cases you explicitly didn't handle, and how you would improve the code if you had more time.
- The interview might not end here, the interviewer might have follow-up questions for you on this question or give you another question. Be prepared for them.
|Data Structures||Arrays, Maps, Stacks, Trees, Sets|
|Algorithms||Binary Search, Breadth-first Search, Depth-first Search, Recursion|
Promise, Handling variadic arguments
|DOM||DOM traversal, DOM creation, DOM manipulation, Accessing element/node properties, Event delegation|
|Runtime APIs||Timer (|
- Problem Solving: Use a systematic and logical approach to understanding and addressing a problem. Break down the problem into smaller independent problems. Evaluate different approaches and their tradeoffs.
- Software Engineering Foundation: Familiarity with data structures, algorithms, runtime complexity analysis, use of design patterns, design solution with clean abstractions.
- Communication: Ask questions to clarify details and clearly explaining one's approach and considerations.
- Verification: Identify various scenarios to test the code against, including edge cases. Be able to diagnose and fix any issues that arise.
- Pure functions. Aim to write pure functions which have the benefit of reusability and modularity, aka functions which don't rely on state outside of the function and doesn't cause side effects.
this matters. If a function accepts a callback function as a parameter, consider how the
this variable should behave. For many built-in functions,
this is provided as one of the arguments the callback function is invoked with.
- Mutations within callback functions. Beware of callback functions mutating the data structure it is operating on. You probably do not need to handle this case during interviews but you should explicitly mention such cases if it's relevant.
- Recursion edge cases.
- If you have identified that solving the question requires recursion, ask about the input size and how to handle the case of recursion stack overflow. Usually you won't have to handle it but raising this issue is a good signal.
- Nested deep data structures can have recursive references to itself, which makes certain operations like serialization much trickier. Ask the interviewer if you have to handle such cases. Usually you won't have to handle it but raising this issue is a good signal.
Note that we are intentionally vague in some of the questions and don't present the full requirements upfront in the question description. However, we'll cover as much ground as possible in the solution. It may be frustrating while reading the solutions to see that you've missed out some things, but this trains you to think ahead and consider what are the possible areas you have to take note of when working on the solution. Better to find out during practice than during actual interviews.