Getting ready for a live coding interview

Introduction
Hi everyone! Nowadays, live-coding is everywhere: during interviews, you are often given one or two tasks to solve within a certain time limit. The tasks themselves might not be too complex (not super algorithmic), but beginners can get nervous and fail to complete them.
Therefore, in this article, I would like to outline typical tasks encountered in this section for frontend or backend developer positions (if the backend is in JS). This will help you get a general idea of what to expect.
Understanding JavaScript
To solve these tasks, you need a solid grasp of JS fundamentals. I would like to highlight the following topics:
- Variables, data types (especially strings).
- Simple operators (+, -, *, /, %, >, <, etc.) and bitwise operators (&, |, ~, <<, >>, >>>).
- Conditional operators, loops (especially being able to use while and for).
- Functions. Recursion is a very important concept. Sometimes you will encounter tasks that can only be solved using it. It is equally important to understand closures, execution context, and scopes.
- Data structures - arrays (80% of tasks), objects/maps/hash tables.
- Regular expressions.
Problem-Solving Approaches in Live-Coding
Let's look at the core algorithm for solving tasks:
- Understand the task - make sure you understand the task, the input data, and the constraints. If these details are missing, ask questions; you will definitely be evaluated on how you gather requirements.
- Plan the solution - quickly draft the structure of your solution, some algorithm. Be sure to explain your solution out loud so the interviewer can follow along.
- Solve the task head-on - check if it works with the initial data. If everything is fine, only then try to optimize it.
- Think about edge cases immediately: empty inputs, large volumes, minimum and maximum values.
- Test again - use the provided examples and create your own test cases.
- Fix, refactor, and test.
- Announce that you are done.
The key is not to panic and to ask questions if anything remains unclear. By the way, this will also help you determine if you would want to work with this person in the future. If your questions are met with heavy sighs or complete silence, that's already a red flag.
Tasks
Let's move on to the most interesting part - the tasks. I have prepared a solution for each task, but I highly recommend trying to solve them first before looking at the solution. All source code is located on GitHub (link at the end of the article).
Simple Tasks
The function
sumRangetakes two numbersstartandend. You need to find the sum of all numbers in the given range.
// Test data
console.log(sumRange(1, 5)); // 15
console.log(sumRange(0, 10)); // 55
console.log(sumRange(-3, 3)); // 0
Write a function that reverses the digits of a number, keeping its sign intact.
// Test data
console.log(reverseNumber(123)); // 321
console.log(reverseNumber(-456)); // -654
console.log(reverseNumber(1000)); // 1
console.log(reverseNumber(0)); // 0
Write a function that determines if a given number is a perfect square.
// Test data
console.log(isPerfectSquare(16)); // true
console.log(isPerfectSquare(14)); // false
console.log(isPerfectSquare(0)); // true
console.log(isPerfectSquare(25)); // true
Arrays
Implement a
minMax()function that takes an array and returns the maximum and minimum values. Solve this without usingMath.min()andMath.max().
// Test data
console.log(findMinMax([4, 3, 5, 3, 2])); // {min: 2, max: 5}
console.log(findMinMax([4, 4, 7, 2, 1, 10])); // {min: 1, max: 10}
console.log(findMinMax([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); // {min: 1, max: 10}
Find the second largest number in an array.
// Test data
console.log(secondLargest([10, 20, 4, 45, 99])); // 45
console.log(secondLargest([5, 5, 5])); // null
console.log(secondLargest([1])); // null
Write a function that returns all pairs of numbers from an array that sum up to a given target sum.
// Test data
console.log(findPairs([2, 4, 3, 7, 8, 1], 9)); // [[7, 2], [8, 1]]
console.log(findPairs([1, 2, 3, 4, 5], 10)); // []
console.log(findPairs([0, -1, -2, 2, 1], 0)); // [[-1, 1], [-2, 2]]
Strings
Check if a given string is a palindrome. Ignore spaces, punctuation, and case.
// Test data
console.log(isPalindrome("A man, a plan, a canal, Panama!")); // true
console.log(isPalindrome("No 'x' in Nixon")); // true
console.log(isPalindrome("Was it a car or a cat I saw?")); // true
console.log(isPalindrome("Eva, I see bees in a cave")); // false
Write a function that checks if two strings are anagrams of each other (case-insensitive).
// Test data
console.log(isAnagram("finder", "Friend")); // true
console.log(isAnagram("hello", "bye")); // false
console.log(isAnagram("listen", "silent")); // true
console.log(isAnagram("rail safety", "fairy tales"));
Write a function to find the first non-repeating character in a string. Return
nullif all characters repeat.
// Test data
console.log(firstNonRepeatingChar("swiss")); // "w"
console.log(firstNonRepeatingChar("aabbcc")); // null
console.log(firstNonRepeatingChar("javascript")); // "j"
Write a function to count the number of vowels and consonants in a string.
// Test data
console.log(countVowelsAndConsonants("hello")); // { vowels: 2, consonants: 3 }
console.log(countVowelsAndConsonants("JavaScript")); // { vowels: 3, consonants: 7 }
console.log(countVowelsAndConsonants("12345")); // { vowels: 0, consonants: 0 }
Recursion
Write a function that calculates the factorial of a number.
// Test data
console.log(factorial(0)); // 1
console.log(factorial(1)); // 1
console.log(factorial(2)); // 2
console.log(factorial(3)); // 6
Write a function that flattens a multi-dimensional array into a one-dimensional array.
// Test data
console.log(_flatten([1, 2, 3]));
console.log(_flatten([1, [2, 3], 4]));
console.log(_flatten([[1, 2], [3, 4]]));
console.log(_flatten([1, [2, [3, [4, 5]]]]));
console.log(_flatten([]));
// [1, 2, 3]
// [1, 2, 3, 4]
// [1, 2, 3, 4]
// [1, 2, 3, 4, 5]
// []
Write a function that returns the Fibonacci number.
// Test data
console.log(fibonacci(0)); // 0
console.log(fibonacci(1)); // 1
console.log(fibonacci(2)); // 1
Write a recursive function to determine the length of a string.
// Test data
console.log(stringLength("hello")); // 5
console.log(stringLength("JavaScript")); // 10
console.log(stringLength("")); // 0
Write a recursive function to find the maximum element in an array.
// Test data
console.log(findMax([1, 5, 3, 9, 2])); // 9
console.log(findMax([-1, -5, -3])); // -1
console.log(findMax([10])); // 10
Async Operations
Implement a
fetchRetryer()function that makes a request to a specified API and retries it up to 5 times until it receives a response (status 200). If the server does not respond after 5 retries, return an error.
// Usage example
fetchRetryer("https://jsonplaceholder.typicode.com/posts/1")
.then((res) => res.json())
.then((data) => console.log("Success:", data))
.catch((err) => console.error("Failed:", err.message));
fetchRetryer("https://invalid-url.example")
.then((res) => res.json())
.catch((err) => console.error("Failed after retries:", err.message));
Implement the
_promiseAllfunction.
// Test data
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
const promise4 = new Promise((resolve) => setTimeout(resolve, 100, 4));
_promiseAll([promise1, promise2, promise3, promise4])
.then((results) => {
console.log(results); // Output: [1, 2, 3, 4]
})
.catch((error) => {
console.error(error);
});
const promise5 = Promise.reject("Error occurred");
customPromiseAll([promise1, promise2, promise5])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error); // Output: Error occurred
});
Write a function that takes two arguments: an asynchronous function and a time limit in milliseconds. This function should return a new version of the asynchronous function whose execution is constrained by the specified time limit. The following conditions must be met: • If the execution time of the original function is less than the time limit, the new function should return the result of the asynchronous function. • If the execution time of the original function exceeds the time limit, the new function should return the message: "Execution limit exceeded".
// Test data
const fn = async (n) => {
await new Promise((res) => setTimeout(res, 100));
return n * n;
};
console.log(asyncLimit(fn, 50)(5)); // rejected limit exceeded
console.log(asyncLimit(fn, 150)(5)); // resolve 25
const fn2 = async (a, b) => {
await new Promise((res) => setTimeout(res, 120));
return a + b;
};
console.log(asyncLimit(fn2, 100)(1, 2));
console.log(asyncLimit(fn2, 150)(1, 2));
Implementation of Built-in Functions (Polyfills)
Implement the
_filtermethod for arrays.
// Test data
console.log([1, 2, 3, 4, 5]._filter(n => n % 2 === 0)); // [2, 4]
console.log(["apple", "banana", "cherry"]._filter(fruit => fruit.includes("a"))); // ["apple", "banana"]
console.log([10, 20, 30]._filter((num, index) => index % 2 === 0)); // [10, 30]
Implement the
_mapmethod for arrays.
// Test data
console.log([1, 2, 3]._map(n => n * 2)); // [2, 4, 6]
console.log(["a", "b", "c"]._map(letter => letter.toUpperCase())); // ["A", "B", "C"]
console.log([10, 20, 30]._map((num, index) => num + index)); // [10, 21, 32]
Implement the
_reducemethod for arrays.
// Test data
console.log([1, 2, 3, 4]._reduce((acc, num) => acc + num)); // 10
console.log([1, 2, 3, 4]._reduce((acc, num) => acc + num, 10)); // 20
console.log(["a", "b", "c"]._reduce((acc, char) => acc + char)); // "abc"
console.log([2, 3, 4]._reduce((acc, num) => acc * num, 1)); // 24
Implement the
EventEmitterclass.
// Usage example
const emitter = new EventEmitter();
function responseToEvent(data) {
console.log(`Event received with data: ${data}`);
}
emitter.on('dataReceived', responseToEvent);
emitter.emit('dataReceived', { id: 1, message: 'Hello, World!' });
emitter.off('dataReceived', responseToEvent);
emitter.emit('dataReceived', { id: 2, message: 'This will not be logged.' });
// Register a one-time event listener
emitter.once('dataReceivedOnce', (data) => {
console.log(`One-time event received: ${data}`);
});
emitter.emit('dataReceivedOnce', 'This will be logged once.');
emitter.emit('dataReceivedOnce', 'This will not be logged.');
Regular Expressions
Write a function that takes a string as an argument and returns the number of vowels contained in that string. The vowels are "a", "e", "i", "o", "u".
// Test data
console.log(countVowels("hello")); // 2
console.log(countVowels("JavaScript")); // 3
console.log(countVowels("xyz")); // 0
Write a function to extract domain names from URLs using regular expressions.
// Test data
console.log(extractDomain("https://www.google.com")); // "google.com"
console.log(extractDomain("http://example.org")); // "example.org"
console.log(extractDomain("https://sub.domain.com/path")); // "sub.domain.com"
console.log(extractDomain("invalid-url")); // null
Additional Tasks
Write a function that checks a string and returns
trueorfalsedepending on whether the bracket sequence is valid.
// Test data
console.log(isValidParentheses("()[]{}")); // true
console.log(isValidParentheses("([{}])")); // true
console.log(isValidParentheses("(]")); // false
console.log(isValidParentheses("([)]")); // false
console.log(isValidParentheses("{[]}")); // true
Design a stack that supports
push,pop,top, and retrieving the minimum element in constant time O(1).
// Usage example
const minStack = new MinStack();
minStack.push(5);
minStack.push(3);
minStack.push(7);
console.log(minStack.getMin());
minStack.pop();
console.log(minStack.getMin());
minStack.pop();
console.log(minStack.getMin());
Write a function that takes an array of strings (logs) and returns the users who interacted with the system the most.
// Usage example:
const logs = [
"user1 login",
"user2 login",
"user1 click",
"user3 login",
"user1 logout",
"user2 click",
"user2 logout",
"user3 click",
"user3 logout",
];
console.log(analyzeLogs(logs));
// { user1: 3, user2: 3, user3: 3 }
Implement a function that runs tasks with a limit on the number of concurrently executing tasks.
// Usage example:
const tasks = [
() => new Promise((res) => setTimeout(() => res("Task 1"), 1000)),
() => new Promise((res) => setTimeout(() => res("Task 2"), 500)),
() => new Promise((res) => setTimeout(() => res("Task 3"), 1200)),
() => new Promise((res) => setTimeout(() => res("Task 4"), 300)),
];
parallelTaskRunner(tasks, 2).then(console.log);
// ["Task 1", "Task 2", "Task 3", "Task 4"]
Of course, this is far from everything you might encounter in an interview. I plan to add more tasks to this repository, so follow the link and bookmark it!
Don't forget that successfully solving live-coding tasks requires constant practice and persistence. The formula is simple: the more you practice, the more confident you will feel during interviews.
Comments
Log in to join the conversation
Sign In