Boarding pass · JavaScript Advanced
JavaScript · Advanced interview
An AI mock interview for senior JavaScript engineers. Reason about the runtime and async internals, metaprogramming with proxies and symbols, functional patterns, and memory and performance.
- Voice interview
- Live feedback
- Browser-only
- No installation required
Your report · sample
AI Readiness Score
Finish the mock and get this report — scored on content and English, with concrete tips and a model answer for every question, plus a study plan.
Your flight path
Five steps to interview-ready.
From a quick warm-up to a personalised study plan — here's the whole loop, and what you get at each gate.
Step 01
Preparation
Skim the topics and warm up — you're briefed before takeoff.
Step 02
AI Interview
A realistic AI interviewer asks tailored questions — answer by voice or text.
Step 03
Instant Score
Finish and get a 0–100 readiness score across content and English.
Step 04
AI Feedback
Concrete tips and a rewritten model answer for every response.
Step 05
Study Plan
A personalised plan targets your weakest areas — so the next run scores higher.
Preview the AI demo
See one answer scored, end to end.
The whole loop on sample data — question, your answer, instant feedback and a study plan. Hover to pause.
Interviewer · Question 1
“Tell me about yourself.”
Who it's for
- Senior JavaScript engineers
- Devs who build libraries and frameworks
- Anyone targeting senior/lead frontend roles
- Engineers who profile and optimize JS
What you'll practice
- Event loop, generators and async internals
- Proxies, Reflect and symbols
- Currying, composition, debounce/throttle
- Memory leaks, GC and performance
Topics covered
What this level expects.
Runtime & async
- Event loop internals
- Generators & iterators
- async under the hood
Metaprogramming
- Proxy & Reflect
- Property descriptors
- Symbols
Functional
- Currying
- Composition
- Debounce vs throttle
Performance & memory
- Memory leaks & GC
- WeakMap/WeakRef
- Optimization
Practice questions
12 questions, with model answers.
Read them, then run the live mock to answer out loud and get scored. Tap any question to reveal a model answer.
01Walk through the event loop, including the call stack and rendering.Runtime & async
Synchronous code runs on the call stack. When it empties, the engine drains all microtasks (promises, queueMicrotask), then in a browser may perform rendering (style, layout, paint, often aligned with requestAnimationFrame), then takes one macrotask (timer, I/O, event) and repeats. Long synchronous tasks block both microtasks and rendering, which is why heavy work freezes the UI — you break it up or offload to a worker.
02How do generators and iterators work?Runtime & async
An iterator is an object with a next() method returning { value, done }; an iterable has a [Symbol.iterator] returning one, which is what for...of consumes. A generator function (function*) is a convenient way to write iterators: yield pauses and resumes execution, preserving local state between calls. Generators enable lazy sequences, custom iteration, and were the basis for async patterns before async/await.
function* gen() { yield 1; yield 2; }
for (const x of gen()) console.log(x);03How does async/await work under the hood?Runtime & async
async/await is syntactic sugar over promises and generator-like suspension: an async function returns a promise, and each await suspends the function, registering a continuation on the awaited promise's microtask. When the promise settles, the function resumes from where it paused. So awaiting doesn't block the thread — it yields control back to the event loop and continues later as a microtask.
04What are Proxy and Reflect used for?Metaprogramming
A Proxy wraps an object and intercepts fundamental operations (get, set, has, deleteProperty, etc.) via trap functions, enabling validation, reactivity (Vue 3's reactivity is built on Proxy), logging, and virtual objects. Reflect provides the default implementations of those operations as functions, so inside a trap you call Reflect.get/set to perform the normal behaviour cleanly. They're the toolkit for metaprogramming object behaviour.
new Proxy(obj, { get(t, k, r) { log(k); return Reflect.get(t, k, r); } });05What are property descriptors and getters/setters?Metaprogramming
Every property has a descriptor controlling its value, writable, enumerable, and configurable flags, or get/set accessor functions, set via Object.defineProperty. Getters/setters let a property run code on read/write, and the flags control enumeration and mutability. They power computed properties, immutability (writable: false), hiding internals (enumerable: false), and were how reactivity worked before Proxy.
06What are Symbols and well-known symbols?Metaprogramming
A Symbol is a unique, immutable primitive often used as a non-colliding property key — useful for adding metadata to objects without clashing with string keys. Well-known symbols like Symbol.iterator, Symbol.asyncIterator, and Symbol.toPrimitive let your objects hook into language protocols (iteration, coercion). Implementing Symbol.iterator, for example, makes a custom object usable with for...of and spread.
07What are currying and partial application?Functional
Currying transforms a function of many arguments into a chain of single-argument functions, so f(a, b, c) becomes f(a)(b)(c). Partial application fixes some arguments now and returns a function taking the rest. Both rely on closures and are used to build specialized functions from general ones and to compose pipelines.
const add = a => b => a + b; const add5 = add(5); add5(3); // 8
08What is function composition, and why prefer pure functions?Functional
Composition combines small functions so the output of one feeds the next — compose(f, g)(x) = f(g(x)) — building complex behaviour from simple, testable pieces. Pure functions (no side effects, output depends only on input) are predictable, cacheable, and easy to test and parallelize, which makes them ideal building blocks for composition and reasoning about state.
09How would you implement debounce and throttle, and when do you use each?Functional
Debounce delays running a function until a pause in calls — reset a timer on each call and only fire after N ms of quiet; good for search-as-you-type or resize end. Throttle runs at most once per interval no matter how many calls — good for scroll or mousemove handlers. Both use closures to hold the timer/last-run state.
const debounce = (fn, ms) => { let t; return (...a) => { clearTimeout(t); t = setTimeout(() => fn(...a), ms); }; };10What causes memory leaks in JavaScript and how does GC work?Performance & memory
JavaScript uses a mark-and-sweep collector: objects reachable from roots (globals, the stack) survive; unreachable ones are freed. Leaks happen when you unintentionally keep references — forgotten timers/intervals, event listeners never removed, detached DOM nodes still referenced, growing global caches, and closures holding large objects. The fix is to release references: clear timers, remove listeners, and bound caches.
11When do WeakMap and WeakRef help?Performance & memory
A WeakMap holds keys weakly, so if the only reference to a key object is the WeakMap, it can be garbage-collected — perfect for attaching metadata or caches to objects without preventing their cleanup (e.g. private data keyed by instance). WeakRef holds a weak reference to an object you can sometimes still access. They prevent the leaks that a normal Map or strong reference would cause for object-keyed caches.
12How do you optimize JavaScript performance in a hot path?Performance & memory
Measure first with the profiler to find the real hotspot. Then reduce work: avoid layout thrash by batching DOM reads then writes (and using requestAnimationFrame), minimize allocations and GC pressure in tight loops, keep object shapes stable so the JIT can optimize, debounce/throttle expensive handlers, and move heavy computation to Web Workers. Micro-optimize only what the profiler proves matters.
Preparation tips
Walk in ready.
- Be able to implement debounce and throttle from scratch
- Explain how async/await is a state machine over promises
- Have a real memory-leak cause and fix ready
- Know when a WeakMap prevents a leak
Ready for the real thing?
Run a 6-question JavaScript mock interview, answer out loud, and get a readiness score with tips and model answers.
More advanced interviews