INTERVIEW PREP · THE TOP 25
The 25 Most Asked Technical Interview Questions
Every question in this list is real: our mentees faced them in actual technical interviews in 2026.
Eight frontend, eight fullstack, nine backend. If you can answer all 25, you're interviewing at a different level than most candidates.

THE QUESTIONS
Real questions, senior answers
- 01
What's the difference between async and defer on a <script> tag?
- Incorrect option:async blocks HTML parsing while it downloads and executes; defer downloads in parallel and runs immediately after download
- Correct answer:Both download in parallel; async executes on download, defer waits for the parsed document
- Incorrect option:defer executes in random order; async preserves source order
- Incorrect option:They are aliases — modern browsers treat them identically
WHY
Both download the script in parallel with HTML parsing. async executes the moment the download finishes; defer waits until the whole document is parsed.
Use defer for scripts that need the DOM (like the bundle that renders your app). Use async for scripts that don't — analytics, for instance.
Script loadingRender-blocking - 02
Is JavaScript pass-by-reference or pass-by-value?
- Incorrect option:Pass-by-reference for everything
- Incorrect option:Pass-by-reference for objects and arrays, pass-by-value for primitives like numbers and strings
- Correct answer:Always pass-by-value — for objects the copied value is a pointer
- Incorrect option:It depends on strict mode
WHY
JavaScript is pass-by-value. Arguments are copied into the function; reassigning them doesn't touch the original.
The confusion is objects: what gets copied is a pointer to the object. The copy still points at the original, so mutating the object inside a function mutates the original. Pass-by-value — even when it feels like pass-by-reference.
Memory modelObjects vs primitives - 03
What resource do closures make JavaScript consume more of?
- Incorrect option:CPU — every closed-over variable is re-computed on each call
- Correct answer:Memory
- Incorrect option:Network bandwidth
- Incorrect option:Disk I/O
WHY
Memory. A closure means the function remembers the lexical scope it was created in, so the garbage collector can't reclaim anything still reachable from it.
That's heap memory — RAM. It's a big part of why JavaScript is a memory-heavy language.
ClosuresGarbage collectionHeap - 04
How can you improve a bad CLS (Cumulative Layout Shift)?
- Incorrect option:Move all JavaScript into web workers so the main thread never blocks while the page renders
- Correct answer:Critical CSS, explicit image dimensions and skeleton placeholders
- Incorrect option:Server-side rendering alone eliminates layout shift entirely
- Incorrect option:Lazy-load every image, above and below the fold
WHY
CLS happens when elements get added to the DOM as you render, or change size as CSS, fonts and images arrive late.
Three fixes: extract critical CSS for the above-the-fold view, set explicit width and height on images (the browser reserves the space before the file loads), and use skeleton placeholders for data-dependent elements.
CLSCritical CSSSkeletons - 05
Which web performance metric suffers most from excessive re-renders?
- Incorrect option:LCP — Largest Contentful Paint
- Correct answer:INP — Interaction to Next Paint
- Incorrect option:TTFB — Time To First Byte
- Incorrect option:CLS — Cumulative Layout Shift
WHY
INP — Interaction to Next Paint: the time from a user interaction to the repaint. Google's bar for good is under 200ms.
Unnecessary re-renders are the usual cause. Fix with React.memo, useMemo, useCallback — and the early-return pattern in component design.
INPRe-rendersMemoization - 06
What can class components do that functional components can't?
- Incorrect option:Hold local state between renders
- Incorrect option:Subscribe to React context and re-render automatically whenever any provider value changes in the tree
- Correct answer:Hook into componentDidCatch — the error-boundary machinery
- Incorrect option:Perform side effects after the component mounts
WHY
Hook into lifecycle methods like componentDidCatch and getDerivedStateFromError — the error-boundary machinery.
Rarely needed, but if you're building something like a logging library (react-sentry style), that's the escape hatch.
Error boundariesLifecycle methods - 07
Which performance metric improves most with SSR?
- Incorrect option:FID — First Input Delay
- Correct answer:LCP — Largest Contentful Paint
- Incorrect option:TTFB — Time To First Byte
- Incorrect option:FCP — First Contentful Paint
WHY
LCP. The server pre-renders the component tree to HTML, so the browser paints the largest element as soon as it arrives instead of waiting for JavaScript.
CLS improves too — pre-rendered elements don't shift — and the white screen of death disappears.
The lineup: FCP = first element painted; FID = time until the page responds to input; TTFB = first byte from the server; LCP = largest element painted.
SSRLCPTTFB - 08
What are TypeScript generics, and when do you use them?
- Incorrect option:Utility types built into the standard library, like Partial and Pick, used to transform existing types
- Correct answer:Code constructs that take type arguments — like `useState<number>(0)`
- Incorrect option:A way to cast unknown values to a concrete type at runtime
- Incorrect option:Types generated automatically from your API schema
WHY
Code constructs that take type arguments — flexibility without giving up strict checking.
You use one daily: React's useState. `useState<number>(0)` fixes the state's type via a generic type argument.
GenericsTypeScript - 09
What's the difference between git rebase and git merge?
- Incorrect option:merge rewrites your commits on top of the target branch; rebase preserves history and adds a merge commit
- Correct answer:rebase replays your commits on top of the target — linear history; merge keeps history as it happened
- Incorrect option:rebase only works on remote branches; merge only on local ones
- Incorrect option:They produce identical history — the difference is speed
WHY
Both integrate branches. git rebase rewrites history, replaying your commits on top of the target branch — a linear, cleaner log. git merge preserves history as it happened, with a merge commit.
GitHistory - 10
Which HTTP status code means forbidden access?
- Incorrect option:401
- Correct answer:403
- Incorrect option:404
- Incorrect option:429
WHY
403. Client errors are the 4xx range: 401 means no credentials were provided (unauthorized); 403 means credentials were provided but this resource is off-limits.
HTTP status codes - 11
What is a preflight request?
- Incorrect option:The DNS lookup the browser performs before any HTTP request
- Correct answer:An OPTIONS request the browser sends before the real one, to check CORS
- Incorrect option:A HEAD request the browser sends to warm the server cache before downloading a large resource
- Incorrect option:The TLS handshake that precedes every HTTPS request
WHY
An OPTIONS request the browser sends automatically before the real one, to check CORS: the server answers with the allowed origins, methods and headers.
It fires whenever you fetch a domain other than your own.
CORSOPTIONS - 12
What is content negotiation?
- Incorrect option:Load balancers negotiating which server handles a request
- Incorrect option:The browser and server agreeing on TLS ciphers before an encrypted session starts
- Correct answer:Serving the same resource in different formats based on request headers
- Incorrect option:Microservices agreeing on an API version at runtime
WHY
Serving the same resource in different formats based on request headers. The browser says `Accept: gzip, br` and the server returns the compressed variant if it has one.
That's what enables end-to-end compression — a CSS file shipped as .css.gzip instead of raw.
Accept headersgzip / brotli - 13
What are valid ways to version an API for breaking changes?
- Correct answer:URI versioning — `api.com/v2`
- Correct answer:A query parameter — `?version=v2`
- Correct answer:The Accept header
- Incorrect option:Semantic versioning in the response body
WHY
URI (api.com/v2), query parameter (?version=v2), or the Accept header.
URI versioning is the most common: cleaner separation, fewer caching surprises, and frontend developers switch versions by switching a URL.
API versioningREST - 14
Which REST methods are idempotent?
- Correct answer:GET
- Incorrect option:POST
- Correct answer:PUT
- Incorrect option:PATCH
- Correct answer:DELETE
WHY
GET, PUT and DELETE. POST and PATCH are not.
Idempotent means repeating the action changes nothing further — multiplying by one, not adding one. It matters in microservices, where flaky networks make clients retry requests that already succeeded.
IdempotencyRESTRetries - 15
WebSockets vs Server-Sent Events — what's the difference?
- Incorrect option:SSE is bidirectional; WebSockets only push from the server to the client
- Correct answer:WebSockets are bidirectional; SSE streams one way — server to client
- Incorrect option:WebSockets require HTTP/2; SSE works on any HTTP version
- Incorrect option:SSE is deprecated in favor of WebSockets
WHY
WebSockets are bidirectional: both sides push events. Right for live chat.
Server-sent events are one-directional — the server streams, the client listens. That's ChatGPT-style LLM apps and live tickers.
WebSocketsSSEReal-time - 16
What is cyclomatic complexity?
- Incorrect option:The maximum depth of nesting in a function
- Correct answer:The number of linearly independent paths through the code
- Incorrect option:The ratio of comment lines to code lines in a module
- Incorrect option:How many dependencies a module imports
WHY
A code-quality metric counting the linearly independent paths through code — an if/else has complexity 2.
Tools like SonarQube measure it per commit and flag functions that have grown too branchy to test.
Code qualitySonarQube - 17
How does a database index make queries faster?
- Incorrect option:It caches query results in memory so repeated queries skip the table entirely
- Correct answer:It builds a B-tree over the column — logarithmic lookups instead of a full scan
- Incorrect option:It compresses the table so scans read fewer pages from disk
- Incorrect option:It partitions the table across multiple servers
WHY
It builds a B-tree over the indexed column, so lookups run in logarithmic time instead of a full table scan — for a million rows, ~19 lookups instead of a million.
The trade: writes and updates get slower, because the tree has to be maintained too.
IndexesB-treeO(log n) - 18
What prevents a DDoS attack?
- Incorrect option:Rate limiting alone — throttle every client to a fair budget
- Correct answer:Traffic filtering plus load balancing
- Incorrect option:Switching all traffic to HTTPS
- Incorrect option:Vertically scaling the application server
WHY
Traffic filtering plus load balancing: block known-bad IPs and absorb the spike without falling over.
Rate limiting helps against a single abusive client, but a distributed attack rotates sources — it's not the primary defense.
DDoSRate limitingTraffic filtering - 19
In the Open-Closed Principle, what does 'closed' mean?
- Incorrect option:The component's public API can never change after release
- Correct answer:Closed for modification — behavior extends without touching internals
- Incorrect option:The module hides its implementation behind an interface so consumers can't depend on internals
- Incorrect option:No new dependencies may be added to the module
WHY
Closed for modification, open for extension: you can change a component's behavior without touching its internals.
React version: a dropdown that takes an onSelect callback prop is open for extension — new behavior, zero edits to the component. That's SOLID in the frontend.
SOLIDOpen-closed - 20
Which deployment strategy has zero downtime?
- Incorrect option:Rolling restart on the same instances
- Correct answer:Blue/green deployment
- Incorrect option:Recreate — tear the old environment down, then deploy fresh
- Incorrect option:Maintenance-window deploys at 3 a.m.
WHY
Blue/green: build a fresh environment, verify it's healthy, then switch traffic. The old environment stays warm for instant rollback.
Blue/greenDeployments - 21
How do you prevent a man-in-the-middle attack?
- Incorrect option:Strong password hashing with bcrypt
- Correct answer:TLS — encrypt the traffic end to end
- Incorrect option:Rate limiting requests from suspicious IPs
- Incorrect option:Storing session tokens in httpOnly cookies
WHY
TLS — HTTPS — encrypting the traffic between the two parties end to end. Everything else is secondary.
TLSHTTPS - 22
Which of these qualify as reverse proxies?
- Correct answer:A load balancer
- Correct answer:A CDN
- Correct answer:An API gateway
- Incorrect option:A VPN
WHY
Load balancers, CDNs and API gateways — they all act on behalf of the server.
A VPN is a regular proxy: it acts on behalf of the client.
Reverse proxyAPI gatewayCDN - 23
What's the drawback of round-robin load balancing?
- Incorrect option:It requires sticky sessions to work at all
- Correct answer:It distributes blindly — a heavy request can land on an already-busy server
- Incorrect option:It only works with an even number of servers
- Incorrect option:It can't detect and route around a server that went down
WHY
Unfair distribution: it rotates blindly, assuming every server and every request is equal. A heavy request lands on an already-busy instance anyway.
Better: least connections, or balancing on APM metrics like CPU and memory.
Load balancingLeast connections - 24
What is the 'microservices tax'?
- Incorrect option:The extra cloud bill from running more containers
- Correct answer:The added complexity: service-to-service auth, security, networking
- Incorrect option:License fees for orchestration platforms like Kubernetes
- Incorrect option:The latency an API gateway adds to every request
WHY
The extra complexity of running a microservices architecture: service-to-service auth, security, networking.
You pay it in engineering effort long before you pay it in cloud bills.
MicroservicesComplexity - 25
Garbage collection and memory leaks — which statements are true?
- Correct answer:Memory leaks still happen in garbage-collected languages
- Correct answer:Circular references can keep memory from being reclaimed
- Incorrect option:GC frees memory the instant a value becomes unreachable
- Incorrect option:A garbage-collected language cannot leak memory
WHY
Two things are true: memory leaks still happen in garbage-collected languages (see closures in JavaScript), and circular references can keep the collector from reclaiming memory.
GC is neither complete nor real-time — it frees what's unreachable, when it gets around to it.
Garbage collectionMemory leaks

Free Senior Training.
One session, the whole system: the fundamentals, the interview strategy, and the plan to the offer. Watch it free.
MORE GUIDES
Dive Deeper Into The Senior Developer Mental Models

INTERVIEW PREP · FRONTEND
30 Frontend Interview Questions for Mid and Senior Developers

INTERVIEW PREP · BACKEND
Backend Interview Questions for Junior and Mid Developers

INTERVIEW PREP · FULL STACK
Full Stack Interview Questions for Junior and Mid Developers