← ALL GUIDES

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.

Dragos and Bogdan Nedelcu, founders of theSeniorDev

THE QUESTIONS

Real questions, senior answers

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
A preview of the free Senior training

Free Senior Training.

One session, the whole system: the fundamentals, the interview strategy, and the plan to the offer. Watch it free.