DEV Community

loading...
Cover image for Top 30 Javascript Interview Warmup Exercises

Top 30 Javascript Interview Warmup Exercises

theodesp profile image Theofanis Despoudis Originally published at codethat.today Updated on ・6 min read

Read the original in CodeThat.today

A lot of times when we have upcoming interviews there are cases when you will be asked to do a technical task in front of the reviewer in your language of choice. Because this phase is the most critical for your success, it's important to be prepared and at least be more confident with your programming skills.

So with this article we are going to list the most important warmup exercises for Javascript interviews. The type of exercises are simple, basic questions that ask you to write a simple function and expand it further if necessary.

This is not meant to be a complete interview prep because the interviewer could ask more advanced questions. They are however good enough for stretching your memory.

Here we go then. The top 30 Javascript warmup exercises for interview preparation. We list the first 10 out of 30 questions in this Part.

Questions 🤔

Here is the complete list algorithms together with detailed explanations:

  • 1. Write a function the reverses a string.

Javascript does not have a build in String Builder class so you cannot modify an existing string. What we can do is create a list that we push each character from the original string starting from the end.

Then we use Array Join to combine the characters as the reversed string.

Here is the gist of the code:

function reverseString(s) { // Create the result list const result = []; // Start from the end of the string and iterate towards the start for (let i = s.length-1; i >= 0; i -= 1) { // Push the current char in the list result.push(s[i]); } // Combine the result in a string return result.join(''); } // Examples console.log(reverseString("")) console.log(reverseString("abc")) console.log(reverseString("aaabbbcccd"))
  • 2. Write a function that filters out numbers from a list.

We can filter the list and remove anything that is not a number. How do we check if a list item is not a number? Well if we use the typeOf operator we can get:

typeof 1 // number

but if the interviewer asks that valid numbers are strings are also allowed we get:

typeof "1" // string

which is not what we need. The solution is to use isNaN function.

However if you noticed (and maybe the interviewer is picky) there are two cases where this thing fails:

isNaN('') //false
isNaN(true) //false
isNaN(null) // false

So we want to add three more checks for empty string, boolean and null check:

function isBoolean(value) {
  return typeof value === 'boolean';
}

function isEmptyString(value) {
  return typeof value === 'string' && value.trim().length === 0;
}

Here is the gist of the code:

function filterNumbers(arr) { // Create the result list const result = arr.filter(function(value, i) { // Filter based on the rules for checking the input is number if (isNaN(value) || isBoolean(value) || isEmptyString(value) || value === null) { return false; } return true; }); // Return numbers only list return result; } function isBoolean(value) { return typeof value === 'boolean'; } function isEmptyString(value) { return typeof value === 'string' && value.trim().length === 0; } console.log(filterNumbers([1, "2", " ", NaN, Number.POSITIVE_INFINITY, 66, "ab1", false, null]))
  • 3. Write a function that finds an element inside an unsorted list.

This is a typical linear search algorithm that takes Θ(n) time to complete. We need to traverse the whole list and compare the search item with the current item:

function linearSearch(arr, x) { let lo = 0; let hi = arr.length-1; // Iterate from start until the end of list while (lo <= hi) { // If item was found then return index if (arr[lo] === x) { return lo; } else { lo += 1 } } // Return -1 to denote the item was not found return -1; } let arr = [1,3,5,7,9,11,14,18,22]; console.info("Item was found at index: " + linearSearch(arr, 22));
  • 4. Write a function that showcases the usage of closures.

Please review existing dev.to articles about what is a Closure. They are better at explaining the details.

Here is a simple example:

function multiplier(first) { let a = first; return function(b) { return a * b; }; } let multiplyBy2 = multiplier(2); console.info(multiplyBy2(4)); console.info(multiplyBy2(5));

You should be able to explain where is the closure there.

  • 5. What is a Promise? Write a function that returns a Promise.

Please review existing dev.to articles regarding what is a Promise. They are better at explaining the details.

Here is a simple example of a Promise:

const resultPromise = function(idea) { return new Promise(function(resolve, reject) { if (idea.isGood) { resolve(idea); } else { reject({ idea: idea, reason: "Not Realistic" }); } }); }; resultPromise({idea: "Make Gold from Iron", isGood: false}) .then(function() { console.info("I'm Rich!") }, function(err) { console.info("Rejected as: " + err.reason); });
  • 6. Write a function that flattens a list of items.

This is a typical interview question. A list of lists can be flattened so that it contains only one level of items. For example: [1, [2,3, [4]]] should flatten into [1, 2, 3, 4].

In order to flatten we need to recurse as we may have a deep hierarchy of lists. First we create the result list. Then we iterate over all the items and check if the item is a list. If it's not a list we append to the result. Otherwise we call the calling function again but with the contents of the item instead.

Here is the gist of the code:

function flatten(arr=[]) { // Create the result list; let result = []; for (let item of arr) { // If item is an array we concat the contents if (Array.isArray(item)) { result = result.concat(flatten(item)); } else { result = result.concat(item); } } return result; } console.info(flatten([[1, 2, [3]], 4]));
  • 7. Write a function that finds an element inside a sorted list.

The question seeks to test how well can you implement binary search here. So with binary search you find the middle element and then you check if it's the target element. If it's less than the target, then we know that it is located in the first half of the input array. If it's greater, then it's located in the second right half of the input array.

Here is the complete code:

function binarySearch(arr, x) { let lo = 0; let hi = arr.length-1; while (lo <= hi) { // Find mid element let m = Math.floor((lo + hi) / 2); // Check if equal to target if (arr[m] === x) { return m; // Reduce array search space by half } else if (arr[m] < x) { lo = m + 1; } else { hi = m - 1; } } // Item not found return -1; } let arr = [1,3,5,7,9,11,14,18,22]; console.info(console.info("Item was found at index: " + binarySearch(arr, 22)));
  • 8. Write a function that accepts two numbers a and b and returns both the division of a and b and their modulo of a and b.

This is straightforward. Here we need to return two values:

a / b and a % b.

function divMod(a, b) { // Be careful for division by zero if (b !== 0 ) { return [a / b, a % b]; } return [0, 0]; } console.info(divMod(16, 5)); console.info(divMod(20, 0));
  • 9. Write a function that computes the fibonacci number of N.

In the Fibonacci sequence, every element is the sum of the previous two terms. For example, starting from 0 and 1:

0, 1, 1, 2, 3, 5, 8, ...

We can do this using either recursion or just a while loop. With recursion we may fall into the trap and do it like this:

function fib(n) {
  if (n === 0) {
    return 0;
  } else if (n === 1) {
    return 1;
  } else {
    return fib(n-1) + fib(n-2);
  }
}

And allow the interviewer to ask why is it so inefficient. Or we can just add a memoization and make it slightly better:

function memo(func) { let cache = {}; return function (x) { if (x in cache) return cache[x]; return cache[x] = func(x); }; }; let fib = memo(function(n) { if (n === 0) { return 0; } else if (n === 1) { return 1; } else { return fib(n-1) + fib(n-2); } }); console.info(fib(20))
  • 10. Write a function that accepts a string and returns a map with the strings character frequency.

To calculate the frequency we need to use a hash-table. Typically we use either an object mapping the keys to values or even more semantically a javascript Map.

We iterate over all the characters of the string and increase their char counter.

Here is the code for it:

function computeFrequency(s) { // Create the freq hashtable const freqTable = new Map(); // for each char in the string for (ch of s) { // Check if we have seen it already if (!freqTable.has(ch)) { freqTable.set(ch, 1); } else { // Just increase the existing entry freqTable.set(ch, freqTable.get(ch) + 1); } } // Return result return freqTable; } console.info(computeFrequency("abrakatabra"));

What's next

Stay put for the next part!

😉👌💖

Interested in Mentoring or Training?

Contact me via www.techway.io for more information.

Discussion

pic
Editor guide
Collapse
jonrandy profile image
Jon Randy

To reverse a string why not just...

const reverseString = s=>[...s].reverse().join('')
Collapse
theodesp profile image
Theofanis Despoudis Author

Try not to aggregate the interviewer. They need to see more than one liners. If you wrote that for example I would ask you to implement array.reverse

Collapse
jonrandy profile image
Jon Randy

You stated this was an exercise to warm up specifically for a JS interview.

There are many ways to solve the problem - each demonstrating different areas of knowledge. A good interviewer would appreciate the knowledge and use of modern JS techniques (arrow function, spread operator) - since, after all, it is a JS specific interview.

Why would you ask someone to re-implement array.reverse in a test that is about Javascript? Any implementation you could make is likely to be slower than the built in one. That question would belong in a test about algorithms

Thread Thread
theodesp profile image
Theofanis Despoudis Author

I would say that any live coding interview questions tend to test you about algorithmic thinking. It's not only about the language. Also, If you can manage to code a dynamic programming task but not a simpler one like array reverse then the interviewer might think something is fishy here.

Thread Thread
jonrandy profile image
Jon Randy

If that is what they want to test, they should ask for such. As this is framed as a JS interview it would be in the candidate's best interests to highlight their skill in Javascript over general programming ability unless asked otherwise.

If I were interviewing for a JS position, and the candidate's solution proceeded to reinvent the wheel, I would question why they had done it that way. On the basis of that answer I would decide whether or not they're a good fit for a specifically JS position

Thread Thread
theodesp profile image
Theofanis Despoudis Author

It is framed as a Javascript interview but it's not all about Javascript. Javascript may be hot now, but not tomorrow. Algorithms stay longer. That is the mindset.

Unfortunately, not all interviewers are kind to tell you what kinds of tests they will ask you. They could ask you anything. The idea is to be prepared as much as possible.

Collapse
dexygen profile image
George Jempty

If I were the interviewer and you provided your solution you would get points off for your solution for using a for loop instead of an ES5 Array method. Could it be the one-liner annoys you more than the hypothetical interviewer?

"Hello World".split('').reduce((rslt, chr) => chr + rslt, ''); // dlroW olleH
Thread Thread
theodesp profile image
Theofanis Despoudis Author

In that case I would ask you to implement array.reduce.

Or to spice things up I would ask you not to use any of:
array.reduce or array.reverse.

So the intention here is that interviewer would like to see how you write plain old for/while loops and how you explain the code as you write it.

Thread Thread
dexygen profile image
George Jempty

Asking somebody to implement Array.prototype.reduce would be absurd IMO after the interviewee had used it to successfully answer your question. And to handcuff somebody by making them use for loops is also absurd. Neither of these are real-world scenarios, and it would seem to me you are just either trying raise the bar impossibly high, or wanting to show off your seemingly superior abilities or such. In which case I'd make the decision then and there I wouldn't want to work for you. Actually a much better real world scenario would be to ask somebody how to re-implement something that relied on excessive chaining. Oftentimes the answer is reduce, but I could also live with a for loop, as long as the original data set is looped over only once.

Thread Thread
theodesp profile image
Theofanis Despoudis Author

That also depends on the company. For some array.reduce might be too simple, but for others might be a good example.

For example if, say you applied for Google and asked about to implement array.reduce you would be really lucky to have that. And if you posted your experience in Leetcode for example, everyone would ask if you are real.

You would not know what the actual bar is until you done some research or took the test.

However I think that's not the point. The main point is how you react to new change of requirements and what is your attitude towards this.

That is the most difficult test.

Thread Thread
dexygen profile image
George Jempty

You keep "moving the goalposts" IMO. Have a nice day.

Thread Thread
jonrandy profile image
Jon Randy

By the same logic, why are you returning a built in Promise in example number 5 rather than your own implementation of a Promise?

Thread Thread
theodesp profile image
Theofanis Despoudis Author

Because we don't want to test how to implement a Promise but their usage.

That would not stop anyone from asking you how Promises could be implemented, but that would fall out of the scope of the warmup. It would be a more challenging test for a more advanced scenario.

See for example:
promisejs.org/implementing/

Thread Thread
dexygen profile image
George Jempty

Again, "moving the goalposts" -- "we don't want to test how to implement a Promise but their usage". Just substitute "Array.prototype.reverse" or "Array.prototype.reduce" and then re-consider your prior arguments and whether what you had suggested "would fall out of the scope" of the warmup.

So far I think you've been very unreasonable/illogical. These are not good traits in a developer/developer-interviewer and I now know beyond a doubt there is no way I'd take a position with you, and I might even just terminate the interview abruptly. With 20 years experience I consider myself to be interviewing the company just as much as vice versa.

Feel free to have the last word but I won't be reading/responding.

Thread Thread
jonrandy profile image
Jon Randy

So you've decided not to move the goalposts on this one?

Thread Thread
theodesp profile image
Theofanis Despoudis Author

There is no hidden agenda. Again if you are condescending or arrogant with someone asking a simple question trying to understand how you think and communicate then you are responsible for yourself and your actions. Good luck with that attitude.

BTW. It only took a few answers on my part in a popular platform like dev.to to understand that from your reactions and I'm a total stranger trying to share my opinion. I'm not even a real interviewer or hiring anyone. How good is that for you?

Collapse
theodesp profile image
Collapse
alyson profile image
aly quey

Thank you for the post. 🙂

On (2) filter number,
I've just modified as following

console.log(filterNumbers([1, true, 0, "2", null, undefined, "   ", NaN, Number.POSITIVE_INFINITY, 66, "ab1", false]))
// just added true, 0, null, undefined

The output is the following.

[1, 0, "2", null, Infinity, 66]


.

It might be better to add null checking on filtering. :)

    if (isNaN(value) || isBoolean(value) || isEmptyString(value) || value === null) {

-> result [1, 0, "2", Infinity, 66]

I continue reading 3)... 🍣

Thank you.

Collapse
theodesp profile image