0% found this document useful (0 votes)
123 views23 pages

One Stop Frontend Interview Questions (Preview)

The document outlines various coding challenges and implementations related to JavaScript functions, including debounce, throttle, currying, and custom promise handling. It provides specific problem statements, example implementations, and test cases for each challenge. The document serves as a guide for developers preparing for technical interviews, showcasing common questions asked by major tech companies.

Uploaded by

skywalkertabish
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
123 views23 pages

One Stop Frontend Interview Questions (Preview)

The document outlines various coding challenges and implementations related to JavaScript functions, including debounce, throttle, currying, and custom promise handling. It provides specific problem statements, example implementations, and test cases for each challenge. The document serves as a guide for developers preparing for technical interviews, showcasing common questions asked by major tech companies.

Uploaded by

skywalkertabish
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

Table of Content

01. Implement Debounce - Easy


//// Asked in Meta, Google, Flipkart, IBM, MakeMyTrip

02. Implement Throttle - Medium


//// Asked in Google, Meta, Tekion

js
03. Implement Currying - Easy

w.
//// Asked in Intuit, Tekion, Adobe, MakeMyTrip, Jio, Paytm

04. Implement Currying with Placeholders - Medium


//// Asked in Amazon, Flipkart, Yandex, Xiaomi, Vimeo, Gojek, Zeta
e
05. Deep Flatten I - Medium
vi
//// Asked in Roblox, Disney+ Hotstar, Rippling

06. Deep Flatten II - Medium


r
//// Asked in CoinSwitch
te

07. Deep Flatten III - Easy

08. Deep Flatten IV - Hard


In

//// Asked in Meta, TikTok, Google, Apple, Yandex, Flipkart

09. Negative Indexing in Arrays (Proxies) - Medium

10. Implement a Pipe Method - Easy


//// Asked in Adobe

11. Implement Auto-retry Promises - Medium


//// Asked in Amazon, Flipkart, Adobe, Paypal, Swiggy
12. Implement Promise.all - Medium
//// Asked in TikTok, Lyft, Snapchat, Disney+ Hotstar, MakeMyTrip, Jio,
MindTickle, Zepto

13. Implement Promise.allSettled - Medium


//// Asked in Tekion, Adobe

14. Implement Promise.any - Medium

js
//// Asked in Zepto

15. Implement Promise.race - Easy

w.
//// Asked in Yandex

16. Implement Promise.finally - Medium


//// Asked in Google e
17. Implement Custom Javascript Promises - Super Hard
vi
//// Asked in Amazon, Airbnb, Tekion, Cars24
r
18. Throttling Promises by Batching - Medium
te

19. Implement Custom Deep Equal - Hard


//// Asked in Google, Tekion
In

20. Implement Custom Object.assign - Medium


//// Asked in ServiceNow, Flipkart

21. Implement Custom JSON.stringify - Hard


//// Asked in Meta

22. Implement Custom JSON.parse - Super Hard


//// Asked in Meta
23. Implement Custom typeof operator - Medium

24. Implement Custom lodash _.get() - Medium


//// Asked in TikTok, Amazon, Quizizz, MindTickle

25. Implement Custom lodash _.set() - Medium

26. Implement Custom lodash _.omit() - Medium

js
27. Implement Custom String Tokenizer - Medium

w.
28. Implement Custom setTimeout - Medium
//// Asked in Swiggy, Disney+ Hotstar

29. Implement Custom setInterval - Medium


e
//// Asked in Meta, TikTok, Swiggy
vi
30. Implement Custom clearAllTimers - Easy
//// Asked in Meta
r
31. Implement Custom Event Emitter - Medium
te

//// Asked in Meta, Flipkart, Adobe, Jio, Tekion

32. Implement Custom Browser History - Medium


In

33. Implement Custom lodash _.chunk() - Medium

34. Implement Custom Deep Clone - Medium


//// Asked in Adobe, Tekion, Navi

35. Promisify the Async Callbacks - Easy


//// Asked in Amazon
36. Implement 'N' async tasks in Series - Hard
//// Asked in Jio, MakeMyTrip, Tekion

37. Implement 'N' async tasks in Parallel - Medium


//// Asked in Zepto, Paytm, BookMyShow

38. Implement 'N' async tasks in Race - Easy

js
39. Implement Custom Object.is() method - Easy

w.
40. Implement Custom lodash _.partial() - Medium
//// Asked in Meesho

41. Implement Custom lodash _.once() - Medium


e
42. Implement Custom trim() operation - Medium
vi
43. Implement Custom reduce() method - Medium
//// Asked in Amazon, Apple, Expedia, Paytm, ByteLearn
r
te

44. Implement Custom lodash _.memoize() - Medium


//// Asked in Meta, Intuit, Gameskraft
In

45. Implement Custom memoizeLast() method - Medium

46. Implement Custom call() method - Medium


//// Asked in Meesho

47. Implement Custom apply() method - Medium

48. Implement Custom bind() method - Medium


//// Asked in Rippling, Flipkart, BookMyShow
49. Implement Custom React "classnames" library - Medium
//// Asked in Meta

50. Implement Custom Redux used "Immer" library - Medium

51. Implement Custom Virtual DOM - I (Serialize) - Hard


//// Asked in Meta

js
52. Implement Custom Virtual DOM - II (Deserialize) - Medium
//// Asked in Meta

w.
53. Implement Memoize/Cache identical API calls - Hard
//// Asked in Facebook

e
r vi
te
In
Throttling Promises by Batching

Problem Statement

Implement a function `throttlePromises()` which takes an


array of functions as input and each of those functions return
a promise object. We also pass a number `max` which
denotes the maximum promises that need to be processed
concurrently.

Scenario

To understand this problem statement more clearly let’s


imagine this scenario first -

As said, the function `throttlePromises()` will take an array of


functions which returns a promise.

Now, assume each of the function calls make an API call and
return a promise which either resolves/rejects. If you have a
scenario you need to make 50 API calls concurrently. It would
be a bad practice since we’re overloading the server by
making 50 API calls instantly.

So, a better approach is to throttle it. Basically, we can make


API calls in batches. The input `max` passed to our function
would be our batch size.

2024 © Interview.js 113


Example

throttlePromises(listOfAPIsToCall, 5)
.then(data => {
// data - If all the API calls processed in batches succeeds
})
.catch(error => {
// error - If any of the API call fails
})

Implementation

`throttlePromises()` function takes an array of functions (each


func returns a promise) as input and also a number `max` as
input.

1. The `throttlePromises()` will also return a promise


a. Returned Promise resolves when all of the promises
of input functions are resolved
b. Returned Promise rejects when any of the promise
of input functions is rejected
2. Batch functions into a size of `max` and process
concurrently using the utility of `Promise.all()`

Now, let’s move on to see the full implementation in code:

function throttlePromises(funcsArr, max) {


const result = [];
let nextAPIBatch = 0;

2024 © Interview.js 114


// We return a new promise which waits until all API calls
are batched and made
// If any of API call fails, we reject the promise
// If all API calls made in batches succeed, we resolve the
promise
return new Promise((resolve, reject) => {
// Using IIFE since the function needs to be called
immediately once after declared (Basically triggering)
(function fetchAPICalls () {
const start = nextAPIBatch;
const end = nextAPIBatch + max;

const nextAPICallsToMake = funcsArr.slice(start,


end);
const nextAPICallsPromises =
nextAPICallsToMake.map(fn => fn());

// We make use of Promise.all since it will parallely


execute all the batch of promises and collectively return the
results if all fulfilled, else returns error if any failure
Promise.all(nextAPICallsPromises)
.then(data => {
result.push(...data);

if (result.length === funcsArr.length) {


// If all API calls fulfilled, resolve
immediately
resolve(result);
}
else {
// Continue to batch and make nextAPICalls
nextAPIBatch = end;
fetchAPICalls();
}
})
.catch(error => {

2024 © Interview.js 115


// If any API fails, reject immediately
reject(error);
})
})();
})
}

Test Cases

// Just a utility to get random timer for setTimeout


// So that we can mock promises in async fashion
const getRandomTimer = () => Math.round(Math.random() * 1000);

const getFulfillingPromise = (value) => {


return new Promise(resolve => {
setTimeout(() => resolve(value), getRandomTimer())
})
}

const getRejectingPromise = (value) => {


return new Promise((resolve, reject) => {
setTimeout(() => reject(value), getRandomTimer())
})
}

const input1 = new Array(10).fill(null).map((elem, index) => ()


=> getFulfillingPromise(index));

const input2 = new Array(10).fill(null).map((elem, index) => {


if (index === 6)
return () => getRejectingPromise(index);
else
return () => getFulfillingPromise(index);
})

2024 © Interview.js 116


throttlePromises(input1, 5)
.then(data => console.log('Resolved with', data))
.catch(error => console.log('Rejected with', error))
// Resolved with [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

// ---------------------------------------

throttlePromises(input1, 3)
.then(data => console.log('Resolved with', data))
.catch(error => console.log('Rejected with', error))
// Resolved with [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

// ---------------------------------------

throttlePromises(input2, 4)
.then(data => console.log('Resolved with', data))
.catch(error => console.log('Rejected with', error))
// Rejected with 6

2024 © Interview.js 117


Implement Custom lodash _.get()

Problem Statement

Implement a function `get()` which is your own version of the


lodash’s `_.get()` method. This method is used to get the
value from the object based on the path given as input.

The `get()` method accepts 3 parameters as input - object,


path, defaultValue.

➔object - the actual object from which the value has to be


retrieved
➔path - (Array/String) denoting the path to access the
property (key) from the object
➔defaultValue - An optional value used to be returned from
the `get()` method when no property is found in the
object based on the path

// Syntax
function get(obj, path, defaultValue) {}

Example

const obj = {
a: {
b: 'Hello',
c: null,

2024 © Interview.js 191


d: [1, 2, 'World'],
e: [
{ name: 'Peter Parker' },
{ work: 'Spiderman' }
],
h: {
i: {
j: 'Iron Man',
k: 'Batman'
}
}
},
f: {
g: undefined
}
}

get(obj, 'a.h.i.j', 'Key Not Found');


// Iron Man

get(obj, 'a.c', 'Key Not Found');


// null

get(obj, 'f.g.h.i', 'Key Not Found');


// Key Not Found

get(obj, ['a', 'e', '1', 'work'], 'Key Not Found');


// Spiderman

get(obj, 'a.d[2]', 'Key Not Found');


// World

get(obj, 'f[g]', 'Key Not Found');


// undefined

2024 © Interview.js 192


Note: The path is either a string with dot notations or square
bracket notations (applicable for both arrays and objects) as
well. Or the path can also be an array of keys passed in array
positions.

Implementation

Let’s go ahead with implementing the solution :

➔The first thing you have to do is parse the path making it


a valid array of keys.
➔Then evaluate the current key for its existence in the
object.
➔If all the keys are traversed or processed in the object,
return the value, else recursively continue processing to
get the value.

The first thing we need to do is to parse the input to a


common notation. That is, we don’t want square brackets, so
replace them with dot notation.

function get(obj, path, defaultValue) {


// if the input is not an array and instead a string
if (!Array.isArray(path)) {
// Below 2 lines replaces all the square bracket notation
`[]` with dot notation `.`
// This makes our job of parsing easy
// Example : 'a.b[c]' -> 'a.b.c', 'a.b.c[0][1]' ->
'a.b.c.0.1', 'a[1].b.c' -> a.1.b.c
path = path.replaceAll('[', '.');

2024 © Interview.js 193


path = path.replaceAll(']', '');
}
}

Now let’s move to the full implementation :

function get(obj, path, defaultValue) {


// The `obj` passed should be a valid object
// Note: Array is also an object
if (obj === null || typeof obj !== 'object') {
return defaultValue;
}

// First step is to replace all of the square bracket


notation [] with dot notation
// This will work for accessing values from both Objects and
arrays
let keys = [];
if (!Array.isArray(path)) {
path = path.replaceAll('[', '.');
path = path.replaceAll(']', '');
keys = path.split('.');
}
else {
keys = path;
}

const currKey = keys[0];

// Means we have processed all the keys in the path, so just


return the value for the key
if (keys.length === 1) {
// We use `hasOwnProperty` method to check if a key
exists on the object

2024 © Interview.js 194


// Using `obj[currKey]` is not good, since there can be a
falsy value as well like null, undefined, '' (which are
completely valid)
// So the aim should be to check if the property was
defined on the object or not
return obj.hasOwnProperty(currKey) ? obj[currKey] :
defaultValue;
}
else {
// Recursively continue traversing the path on the object
to get the value
if (obj.hasOwnProperty(currKey)) {
return get(obj[currKey], keys.slice(1),
defaultValue);
}

return defaultValue;
}
}

Test Cases

const obj = {
a: {
b: 'Hello',
c: null,
d: [1, 2, 'World'],
e: [
{ name: 'Peter Parker' },
{ work: 'Spiderman' }
],
h: {
i: {
j: 'Iron Man',

2024 © Interview.js 195


k: 'Batman'
}
}
},
f: {
g: undefined
}
}

console.log(get(obj, 'a.b', 'Key Not Found'));


// Hello

console.log(get(obj, ['a', 'h', 'i', 'k'], 'Key Not Found'));


// Batman

console.log(get(obj, 'a[b]', 'Key Not Found'));


// Hello

console.log(get(obj, ['a', 'e', '1', 'work'], 'Key Not Found'));


// Spiderman

console.log(get(obj, 'a[d].1', 'Key Not Found'));


// 2

console.log(get(obj, 'a.d.2', 'Key Not Found'));


// World

console.log(get(obj, 'a.d.3', 'Key Not Found'));


// Key Not Found

console.log(get(obj, 'a[d][0]', 'Key Not Found'));


// 1

console.log(get(obj, 'a.e.0.name', 'Key Not Found'));


// Peter Parker

2024 © Interview.js 196


console.log(get(obj, 'f.g', 'Key Not Found'));
// undefined

console.log(get(obj, 'f.g.h.i.j.k', 'Key Not Found'));


// Key Not Found

2024 © Interview.js 197


Implement Custom setTimeout

Problem Statement

Implement a custom function `mySetTimeout()` and


`myClearTimeout()` which are polyfills for the in-built
`setTimeout` and `clearTimeout` functions.

And you should not use the built-in function directly for the
problem, instead write your own version.

The `setTimeout` function is utilized to introduce a delay to


execute a function call after a specified amount of time has
passed.

The `setTimeout` function returns a distinct identifier that can


be used to pass as input to the `clearTimeout` function, where
the `clearTimeout` function stops the execution of that
function call which was scheduled to be called after the
specified delay.

At last we can pass any number of parameters to our


`setInterval` function which needs to be passed to the
callback function.

// Syntax

// Schedule a timer for the function `fn` to be executed after

2024 © Interview.js 220


the `delay` (delay in milliseconds)
const id = setTimeout(fn, delay, param1, param2, ..., paramN);

// clearTimeout(id) accepts the unique identifier `id` of the


scheduled timer which needs to be cleared before executing
clearTimeout(id);

Example

const startTime = Date.now();

const id = mySetTimeout(() => console.log(`Timer executed after


${Date.now() - startTime} ms`), 4000)
// Timer executed after 4001 ms

myClearTimeout(id);
// Note : The time `4001 ms` is not equal to the delay=4000 we
passed. This is because by design, setTimeout only guarantees to
execute "after" specified delay, but doesn't guarantee that it
will execute exactly at delay=4000. So don't expect timer to be
executed exactly at the specified `delay`

Implementation

Let’s breakdown on how we can implement the solution:

➔We would need to maintain a map `timerMap`, where we


can store the unique identifiers `id` for the timers
scheduled. Later we can use this to check if the timer
was cleared by `clearTimeout`.

2024 © Interview.js 221


➔The `mySetTimeout` implements the timer logic to delay
the execution of the callback function call and returns the
unique identifier `id`.
➔The `clearTimeout` is passed `id` of the registered timer,
where we just delete the `id` from the `timerMap`.

Note: `requestIdleCallback` is a method in JavaScript that


allows to schedule a function to be executed during the
browser's idle periods. The browser's idle periods occur when
the browser is not busy performing other tasks, such as
handling user input or rendering a web page. During these
idle periods, the browser can execute any functions that have
been scheduled using `requestIdleCallback`

Below is our full implementation of `setTimeout` in code:

function createMySetTimeout() {
// this unique `timerID` helps to identify the
registered/scheduled timer
let timerID = 0;
// `timerMap` which maintains all the unique identifiers `id`
for the timer scheduled/registered
const timerMap = {};

function mySetTimeout(callback, delay, ...args) {


// helper func to register/schedule a timer
const id = scheduleTimer();

const startTime = Date.now();


function check() {
// If the scheduled/registered callback is deleted,

2024 © Interview.js 222


just skip away
if (!timerMap[id]) return;

if (Date.now() - startTime >= delay) {


// If the `delay` threshold is crossed, means we
can now execute the callback
callback(...args);
}
else {
// Since `delay` threshold is not crossed yet, we
wait until next idle period
requestIdleCallback(() => check());
}
}

// We know the fact that native `setTimeout` funcs are


asynchronous in nature
// Also the fact that, the callback won't be executed
unless the Javascript call stack is free/idle
// So we use, `requestIdleCallback` which makes sure that
your callback will be called when there is some idle time
requestIdleCallback(() => check());

// returns the unique identifier `id` for the registered


timer
return id;
}

function myClearTimeout(id) {
// If a timer is registered/scheduled for the `id` -
delete it
if (timerMap[id]) delete timerMap[id];
}

function scheduleTimer() {
// create unique id

2024 © Interview.js 223


const id = ++timerID;
// register the callback the unique `id` in our
`timerMap`
timerMap[id] = true;

return id;
}

return { mySetTimeout, myClearTimeout }


}

Test Cases

const { mySetTimeout, myClearTimeout } = createMySetTimeout();

const print = () => console.log(`Timer executed after


${Date.now() - startTime} ms`);

const startTime = Date.now();


const id1 = mySetTimeout(print, 4000)
// Timer executed after 4001 ms

const id2 = mySetTimeout(print, 1000)


// Timer executed after 1001 ms

const id3 = mySetTimeout(print, 1000)


// Timer executed after 1008 ms

// Case : Clear timers before execution


const id4 = mySetTimeout(print, 3000)
const id5 = mySetTimeout(print, 1000)
const id6 = mySetTimeout(print, 2000)

// We use `mySetTimeout` to call `myClearTimeout` just before

2024 © Interview.js 224


the scheduled timers `id4, id5, id6` are executed
mySetTimeout(() => myClearTimeout(id4), 2750)
mySetTimeout(() => myClearTimeout(id6), 1900)
// Timer executed after 1001 ms
// Note : id4, id6 timers are cleared, so only id5 timer is
executed

2024 © Interview.js 225

You might also like