20 Most Frequent Coding Questions in Interviews: From Debounce to Promise Complete Collection

Coding InterviewAuthor: BeautyResume Team

A comprehensive collection of the 20 most frequently asked hand-written coding questions in frontend interviews, including debounce, throttle, Promise, deep clone, LRU cache, currying, virtual DOM, and more, with key concepts and solution approaches for each

20 Most Frequent Coding Questions in Interviews: From Debounce to Promise Complete Collection

Background

I've done over 20 frontend interviews, and one thing is certain: regardless of company size, the hand-written coding round is almost 100% guaranteed. Some questions I was asked 4 out of 5 times — debounce/throttle, Promise, deep clone — they're truly evergreen. At first, I was terrified of hand-writing code. I was so used to IDE auto-completion that writing on a whiteboard or online editor was a disaster of typos and missed edge cases. Later, I compiled every hand-written question I'd been asked and practiced them repeatedly until I could write most from memory on sight. This article collects the 20 most frequently asked coding questions, each annotated with key concepts and solution approaches to help you avoid the same pitfalls.

Interview Process Review

The hand-written coding round typically comes in the middle-to-late part of the interview, lasting 15-30 minutes. Big tech companies usually use online editors (like HackerRank, CoderPad), while smaller companies may ask you to write on a whiteboard. My takeaways:

1. Clarify input/output first — Many problem descriptions are ambiguous. For example, "implement debounce" — you need to ask: immediate execution or delayed? Should it return a value?

2. Write core logic first — Don't start with edge case handling. Implement the core functionality, then add boundary conditions.

3. Think out loud — The interviewer isn't watching you transcribe code; they're listening to you think. Briefly explain your reasoning for each line.

4. Self-test after writing — Run through a few test cases mentally, especially edge cases: empty input, null/undefined, extremely large values.

Question 1: Debounce

Key Concepts: Closures, timers, this binding

Solution Approach: The core of debounce is "delay execution; if triggered again during the delay, restart the timer." Use a closure to hold the timer reference; each invocation clears the previous timeout before setting a new one.

Key details: 1. Save this and arguments, bind context with apply/call; 2. Return the closure function; 3. Provide a cancel method.

Follow-up: What if you need immediate execution on the first call? — Add an immediate parameter; execute on the first trigger, then debounce subsequent ones.

Question 2: Throttle

Key Concepts: Closures, timers, timestamps

Solution Approach: The core of throttle is "execute at most once per fixed time interval." Two implementations: timestamp-based (check last execution time) and timer-based (use setTimeout). The timestamp version executes immediately on first call; the timer version delays the first call.

Key details: 1. The timestamp version won't execute a final call after triggers stop; 2. The timer version will execute the last call after triggers stop; 3. Combining both gives "leading + trailing" throttle.

Follow-up: How to implement leading and trailing parameters? — leading controls whether the first call executes immediately; trailing controls whether the last call executes after the interval.

Question 3: Promise

Key Concepts: State machine, microtasks, chaining

Solution Approach: Promise has three states: pending, fulfilled, rejected. The core invariant: state can only transition from pending to fulfilled or rejected, and it's irreversible. The then method returns a new Promise to enable chaining.

Key details: 1. Use queueMicrotask to simulate async microtask execution for resolve/reject; 2. then callbacks must execute asynchronously after state changes; 3. Value passthrough — when then has no callback, the value passes through to the next then.

Follow-up: Why is Promise.then a microtask? — To guarantee deterministic execution order; microtasks run after the current macrotask completes but before the next one starts.

Question 4: Promise.all

Key Concepts: Concurrency control, error handling, counters

Solution Approach: Accept an array of Promises; when all succeed, return the results array in order; if any fail, immediately reject with that reason. Use a counter to track completed Promises; resolve when all are done.

Key details: 1. Empty array resolves immediately with []; 2. Results must be in original order, not completion order; 3. Use index rather than push to guarantee ordering.

Follow-up: How to implement Promise.allSettled? — Collect all results regardless of success/failure, using a status field to distinguish.

Question 5: call/apply/bind

Key Concepts: this binding, function as object method

Solution Approach: The core of call/apply is invoking the function as a method on the target object, leveraging the "this refers to the object" behavior. bind returns a new function with this pre-bound.

Key details: 1. call takes an argument list, apply takes an array; 2. When this is null/undefined, it points to the global object (non-strict mode); 3. A bound function can be called with new — in that case, this points to the instance, not the bound object.

Follow-up: How to handle new calls on bound functions? — Check this instanceof boundFunction; if true, it's a new call, so ignore the bound this.

Question 6: Deep Clone

Key Concepts: Recursion, type checking, circular references

Solution Approach: Recursively traverse all object properties. For each value: primitives are copied directly; reference types are recursively cloned. Use WeakMap to track already-cloned objects for circular references.

Key details: 1. Type checking with Object.prototype.toString.call; 2. Initialize arrays with [], objects with {}; 3. WeakMap for circular references avoids infinite recursion; 4. Special objects (Date, RegExp, Map, Set) need special handling.

Follow-up: Why WeakMap instead of Map? — WeakMap keys are weakly referenced and don't prevent garbage collection, avoiding memory leaks.

Question 7: EventEmitter

Key Concepts: Pub/Sub pattern, event management

Solution Approach: Maintain an event map {eventName: [callback1, callback2, ...]}. on registers events, emit triggers events, off removes events, once registers one-time events.

Key details: 1. Multiple listeners can be registered for the same event; 2. emit executes listeners in registration order; 3. once listeners auto-remove after execution; 4. off without a callback removes all listeners for that event.

Question 8: LRU Cache

Key Concepts: Hash map + doubly linked list, O(1) read/write

Solution Approach: Hash map stores key-to-node mapping (O(1) lookup); doubly linked list maintains access order (O(1) insert/delete). On get, move the node to the head; on put, if capacity is exceeded, remove the tail node.

Key details: 1. Sentinel nodes (dummy head/tail) simplify boundary handling; 2. Mind pointer order when deleting and moving nodes; 3. Map's size property can check capacity.

Question 9: Virtual DOM

Key Concepts: Tree structure, diff algorithm, render function

Solution Approach: Virtual DOM is essentially using JS objects to describe DOM structure. Contains three core properties: tag, props, children. The render method recursively creates real DOM nodes.

Key details: 1. Event properties in props need addEventListener binding; 2. children can be strings or virtual nodes; 3. Simplified diff only compares nodes at the same level.

Question 10: Currying

Key Concepts: Closures, functional programming, argument collection

Solution Approach: Convert a multi-argument function into a series of single-argument functions. Use closures to collect arguments; when the collected count equals the original function's parameter count, execute; otherwise, return a new function to continue collecting.

Key details: 1. Use Function.prototype.length to get the original function's parameter count; 2. Each call can pass 0 or more arguments; 3. Placeholder support (e.g., _ for pending arguments).

Question 11: Array Flattening

Key Concepts: Recursion, reduce, iteration

Solution Approach: Recursive version uses reduce + concat; when encountering an array, recursively flatten. Iterative version uses a stack; pop elements one by one; if an element is an array, push its items onto the stack.

Key details: 1. Control flattening depth with a depth parameter; 2. Skip empty array slots; 3. Native flat() flattens one level; flat(Infinity) flattens completely.

Question 12: Pub/Sub Pattern

Key Concepts: Design patterns, decoupling

Solution Approach: Similar to EventEmitter but emphasizes decoupling publishers and subscribers. Add an EventCenter as the intermediary — publishers only publish, subscribers only subscribe.

Key details: 1. Support namespaces (e.g., "user:login"); 2. Support wildcard subscriptions; 3. Error isolation — one listener's error shouldn't affect others.

Question 13: AJAX

Key Concepts: XMLHttpRequest, Promise wrapper

Solution Approach: Create XHR object → open with request config → set headers → send → listen for onreadystatechange → wrap async result with Promise.

Key details: 1. readyState 4 and status 200-299 means success; 2. GET params go on the URL; 3. Timeout handling with xhr.timeout + ontimeout; 4. Modern alternative: use fetch.

Question 14: Template Engine

Key Concepts: Regex replacement, with statement, new Function

Solution Approach: Replace {{expression}} in template strings with corresponding data values. Use regex to match {{}}, with(data) to create a data scope, and new Function to dynamically generate the render function.

Key details: 1. Escape HTML special characters to prevent XSS; 2. Support conditionals and loops (e.g., {{if}}, {{each}}); 3. Compilation caching to avoid recompilation.

Question 15: Frontend Router

Key Concepts: History API, hashchange, route matching

Solution Approach: Hash routing listens for hashchange events; History routing uses pushState/replaceState + popstate events. Maintain a route table that maps the current path to the corresponding component.

Key details: 1. History routing requires server-side support (all paths return index.html); 2. Route parameter parsing (e.g., /user/:id); 3. Nested route implementation.

Question 16: new Operator

Key Concepts: Prototype chain, constructor, this binding

Solution Approach: 1. Create an empty object; 2. Set its __proto__ to the constructor's prototype; 3. Bind the constructor's this to the new object and execute; 4. If the constructor returns an object, return that; otherwise, return the new object.

Key details: 1. Handling when the constructor explicitly returns an object; 2. The prototype chain establishment process; 3. Difference from Object.create.

Question 17: instanceof

Key Concepts: Prototype chain lookup

Solution Approach: Walk up the object's prototype chain to check if the constructor's prototype can be found. Use a while loop to traverse __proto__ until reaching null.

Key details: 1. Primitives always return false for instanceof; 2. Handling null and undefined; 3. Symbol.hasInstance for custom behavior.

Question 18: Object.create

Key Concepts: Prototypal inheritance, property descriptors

Solution Approach: Create a new object and set its __proto__ to the passed-in prototype. If the second argument exists, use Object.defineProperties to add properties.

Key details: 1. When prototype is null, the created object has no prototype; 2. Property descriptor format for the second argument; 3. Difference from new — doesn't execute the constructor.

Question 19: Async Concurrency Limiter

Key Concepts: Promise, concurrency control, queue

Solution Approach: Maintain an execution queue and a counter for in-progress tasks. When in-progress count is less than the concurrency limit, dequeue and execute a task; when a task completes, decrement the counter and dequeue the next task.

Key details: 1. Callback handling after task completion; 2. Errors shouldn't affect other tasks; 3. Support dynamically adding tasks.

Question 20: Binary Tree Traversal

Key Concepts: Recursion, stack, Morris traversal

Solution Approach: Recursive pre/in/post-order is simplest; interviewers typically ask for iterative versions. Pre-order and in-order use a stack to simulate recursion; post-order uses double-stack or marker methods. Level-order uses a queue (BFS).

Key details: 1. Iterative post-order is the most error-prone — mind the visit timing; 2. Morris traversal uses O(1) space but modifies the tree; 3. Common variants: validate BST, find max depth, lowest common ancestor.

Key Takeaways

1. Practice by category: Group the 20 questions into closure-based (debounce/throttle, currying), async-based (Promise, AJAX), data structure-based (LRU, binary tree), and utility-based (deep clone, call/apply/bind). Tackle each group together.

2. Don't memorize code: Understand the core approach for each question, then write it yourself. Memorized code vanishes under interview stress; understanding lets you derive details on the spot.

3. Mind edge cases: Interviewers care less about whether you can write the core logic and more about whether you handle boundary conditions. After writing each solution, proactively say "Let me consider the edge cases."

4. Practice handwriting: Write code on paper or a whiteboard regularly — don't rely solely on IDEs. No auto-completion in interviews; typos cost points.

5. Time allocation: Easy questions 5 min, medium 10 min, hard 15 min. If you're running over, communicate with the interviewer — don't get stuck on one question.

FAQ

Q: Can I use ES6+ syntax in hand-written coding interviews?

A: Most companies allow it, but some interviewers require ES5. Prepare both versions and ask at the start of the interview.

Q: What if I can't write the solution?

A: Don't stay silent. Explain your thinking out loud — the interviewer may give you hints. Partial completion is far better than a blank page.

Q: Do I need to write test cases?

A: You're not expected to write full test code, but after finishing, walk through a few test cases verbally to demonstrate your verification mindset.

#Live Coding#Frontend Interview#Debounce & Throttle#Promise#Deep Clone#LRU Cache#Currying#Virtual DOM