HTML · CSS · JS · API
Fullstack Interview Reference — 7 Sections · 62 Cards
Section Cards Interview Weight
HTML 6 7.5 / 10
CSS 7 7 / 10
JavaScript 12 6.5 / 10
API & Fullstack 11 8 / 10
JS Advanced ★ NEW 10 +2 boost
Backend Depth ★ NEW 8 +1.5 boost
Performance ★ NEW 6 +1 boost
[ HTML ] HTML
01 Basic Structure 02 Text & Formatting
DOCTYPE h1 to h6
Always first line. Tells browser this is HTML5. Server sends this in every Headings. h1 = biggest. Only one h1 per page for SEO.
HTML response.
p
html / head / body Paragraph. Block-level — starts on new line.
html wraps everything. head = invisible metadata. body = visible content.
strong vs b
title strong = bold + semantic importance. b = just bold styling.
Sets the browser tab name. Goes inside head. Important for SEO.
em vs i
meta charset em = italic + emphasis (semantic). i = just italic.
meta charset=UTF-8 supports all characters. Always include in head.
br / hr
link stylesheet br = line break. hr = horizontal divider line.
Links your CSS file. In production points to a bundled/minified file.
span
script src Inline container for styling part of text.
Links JS file. Place at end of body. In fullstack, served by the backend.
03 Links & Media 04 Lists
a href ul — Unordered
Creates a link. target=_blank opens in new tab. In SPAs, frontend routing Bullet list. Often dynamically generated from API data using map().
handles links.
ol — Ordered
img src alt Numbered list. Same structure but shows numbers.
Embeds image. alt = accessibility and SEO. src often points to API or
li
cloud storage.
List item. In fullstack, each li often represents one database record.
video / audio
dl / dt / dd
Embed media. Add controls attribute to show play button.
Definition list. dt = term, dd = definition. Good for API key/value pairs.
Relative vs Absolute
Relative: ./img/[Link] (local). Absolute: [Link] (external or API
endpoint).
05 Forms ★ 06 Semantic Tags
form action method header / nav
action = API endpoint. method = POST for submitting data to server. Top of page. Nav contains links that trigger frontend route changes.
input type main / section
Types: text, email, password, number, checkbox, radio, file, submit. main = primary content (one per page). section = thematic group.
label for article
Links text to input. Clicking label focuses the input. Standalone content. Often one article = one database record.
textarea footer
Multi-line text input. Bottom of page. Copyright, links, contact.
select / option div vs semantic
Dropdown menu. Options often loaded dynamically from an API. div = generic container. Semantic tags improve accessibility and SEO
ranking.
placeholder / required
placeholder = hint text. required = browser validation before API call.
[ CSS ] CSS
01 Selectors 02 Box Model
Element — p { } Content
Targets all matching tags. p {} styles every paragraph. The actual text or image inside the element.
Class — .box { } Padding
Targets elements with that class. Reusable. Most common selector. Space inside the border. padding: 10px 20px (top/bottom left/right).
ID — #header { } Border
Targets one unique element. High specificity — use sparingly. border: 1px solid black. Set width, style, and color.
Descendant — div p Margin
Targets p inside div, any level deep. Space outside the border. margin: auto centers block elements.
:hover / :focus box-sizing: border-box
Interaction styles. a:hover, input:focus, li:first-child. Padding and border included in total width. Always add to * globally.
03 Colors & Background 04 Typography
color font-family
Text color. Values: red, #ff0000, rgb(255,0,0), rgba(255,0,0,0.5). Sets typeface. Always provide fallback: 'Roboto', sans-serif.
background-color font-size
Fills element background. px = fixed. rem = relative to root (16px default). em = relative to parent.
background-image font-weight
background-image: url(). URL often comes from an API response. 400 = normal, 700 = bold.
opacity line-height
0 = invisible, 1 = visible. Affects whole element including children. Space between lines. 1.5 or 1.6 is comfortable.
text-align
left, center, right, justify.
05 Layout ★ 06 Hover & Effects
display :hover
block = full width. inline = flows with text. none = hidden. Toggle after API button:hover { background: blue } — applies when mouse is over.
response.
transition
Flexbox Smoothly animates changes. transition: all 0.3s ease. Add to base
display: flex on parent. justify-content = horizontal. align-items = vertical. element.
flex values transform
justify-content: center, space-between. align-items: center, flex-start. scale(1.1) grows. translateX(10px) moves. rotate(45deg) spins.
Grid box-shadow
display: grid + grid-template-columns. Great for dashboards and data box-shadow: 2px 4px 10px rgba(0,0,0,0.2).
layouts.
position
static (default). relative. absolute = to nearest parent. fixed = on screen.
z-index
Controls stack order. Higher = on top. Only on positioned elements.
07 Responsive Design
Media Queries
@media (max-width: 768px) { } — styles apply only on screens 768px or
smaller.
Breakpoints
480px = mobile, 768px = tablet, 1024px = desktop.
Viewport meta
meta name=viewport content=width=device-width — required for mobile.
Fluid units
% = relative to parent. vw/vh = % of screen. Better than fixed px.
[ JS ] JavaScript
01 Basics 02 Functions
let / const / var Function Declaration
const = no reassign (default). let = can reassign. var = old, avoid. function greet() { } — hoisted, can call before defined.
Data Types Arrow Function
String, Number, Boolean, null, undefined, Object, Array. Use typeof to const greet = () => { } — modern shorter. One-liner: const double = x => x
check. *2
if / else Template Literal
Runs code conditionally. Use === for strict equality. Backticks embed JS: `Hello ${[Link]}, total: ${total}`
switch Parameters & Return
Matches value to cases. Useful for handling different API response status Parameters are inputs. return sends value back. Without return =
codes. undefined.
Loops Scope
for = known count. while = condition. for...of = great for arrays from API. Global = anywhere. Local = inside function. let/const are block-scoped.
03 DOM Manipulation ★ 04 Events ★
getElementById() onclick
Gets single element by its id. Fires when clicked. Commonly triggers an API call.
querySelector() onchange
Gets first match by CSS selector: .box, #id, input[type=email]. Fires when input changes. Can trigger live search API calls.
.innerHTML addEventListener()
Gets/sets HTML. Used to render API data into the page. [Link]('click', fn). Supports multiple listeners.
.textContent submit event
Gets/sets plain text. Safer than innerHTML. Intercept form submit to send data to API instead of page reload.
.value
Gets current value of form inputs. Read before sending to API.
classList
[Link]/remove/toggle — show/hide loading spinners and error
states.
05 Arrays 06 Objects
push / pop Object Creation
push adds to end. pop removes from end. const user = { name: 'Ali', age: 20 }. API responses are usually objects.
map() Dot Notation
Transforms every item. Used to turn API response arrays into UI [Link] returns 'Ali'. Most common way to read API response fields.
elements.
Destructuring
filter() const { name, age } = user — pulls values out cleanly.
[Link](x => [Link]) — filter API results client-side.
Spread operator
reduce() const updated = { ...user, age: 21 } — copy and override fields.
[Link]((acc, x) => acc + x, 0) — summarise API data like totals.
forEach()
Loops over array. Good for rendering each API result into the DOM.
07 Storage 08 ES6 Modules ★
localStorage export
Saves data with no expiry. Used to store auth tokens after login API call. export const add = (a, b) => a + b — shares a function from a file.
sessionStorage import
Like localStorage but clears when tab closes. import { add } from './moduleName' — brings it into another file.
[Link]() Why modules?
Object to string before saving: [Link](user). In fullstack: [Link] handles fetch calls, [Link] handles helpers, [Link] ties
together.
[Link]()
String back to object: [Link]([Link]('user')). toFixed()
(3.14159).toFixed(2) returns '3.14'. Format prices from API data.
09 JSON 10 Fetch API ★
What is JSON? fetch()
Text format for data exchange between frontend and backend. Keys must Makes HTTP request to a backend API. Returns a Promise.
use double quotes.
GET Pattern
[Link]() fetch(url).then(res => [Link]()).then(data => { }).catch(err => { })
JS object to JSON string. Use before sending in fetch POST body.
POST with body
[Link]() fetch(url, { method:'POST', headers:{'Content-Type':'application/json'},
JSON string back to JS object. Use after receiving API response. body: [Link](data) })
JSON Array [Link]()
Most APIs return arrays of objects. Loop with map(). Parses raw response as JSON. Always first step inside .then().
Pretty Print Check status
[Link](obj, null, 2) — readable format for logging API responses. if (![Link]) throw new Error('Failed') — always check before using data.
11 Sync vs Async ★ 12 Threads & Event Loop
Synchronous Single-Threaded JS
Runs line by line. Blocks until done. Never use for API calls — would JS has one thread. Hands off async tasks to browser, comes back when
freeze the page. done.
Asynchronous Call Stack
Starts task and moves on. All API calls must be async. Tracks current function. Pushed on when called, popped off when done.
async function Event Loop
async function getData() { } — always returns a Promise. Checks if stack is empty. If yes, runs next queued task (like an API
callback).
await
Inside async only. const data = await fetch(url) — pauses until response Web Workers
arrives. Background thread for heavy tasks. Keeps UI responsive with large API
payloads.
try / catch
Always wrap await in try/catch to handle network errors.
[ API ] API & Fullstack
01 What is an API? ★ 02 HTTP Methods ★
Definition GET
Application Programming Interface. Frontend asks, backend answers. Fetch data. No body. GET /api/products returns list. Safe and idempotent.
REST API POST
Most common type. Uses HTTP methods (GET, POST, PUT, DELETE) Create new data. Body = new record as JSON. POST /api/users with {
and URLs. name, email }.
Endpoint PUT
A specific URL. /api/users = all users. /api/users/1 = user with id 1. Replace entire record. PUT /api/users/1 with full updated user object.
Request PATCH
What frontend sends: method, URL, optional headers, optional body. Update part of record. PATCH /api/users/1 with just { email:
'new@[Link]' }.
Response
What backend returns: status code + JSON body with data or error. DELETE
Remove a record. DELETE /api/users/1. Usually no body.
Client vs Server
Client = browser/frontend (sends). Server = backend (processes and
responds).
03 Status Codes ★ 04 Headers
200 OK Content-Type
Request succeeded. Data is in the response body. Tells server format of body. Set to application/json when sending JSON.
201 Created Authorization
New record created. Returned after successful POST. Authorization: Bearer yourToken — required for protected routes.
204 No Content Accept
Success but no data. Common after DELETE. Tells server what format you want back. Usually application/json.
400 Bad Request CORS headers
Invalid data sent. Check request body and headers. Backend must send Access-Control-Allow-Origin to allow cross-domain
calls.
401 Unauthorized
Not logged in. Send a valid auth token.
403 Forbidden
Logged in but no permission for this resource.
404 Not Found
Endpoint or record does not exist.
500 Server Error
Something crashed on the backend. Not a frontend problem.
05 Making API Calls ★ 06 Authentication ★
GET async/await JWT Token
const res = await fetch('/api/users'); const users = await [Link](); Server sends after login. Store in localStorage, send with every request.
POST async/await Login flow
fetch('/api/users', { method:'POST', headers:{...}, body: POST /api/login -> server returns token -> store token -> send in
[Link](data) }) Authorization header.
Check status Protected routes
if (![Link]) throw new Error('Failed: ' + [Link]) Backend checks Authorization header. Missing or invalid = 401.
Error handling Logout
Wrap in try/catch. Show user-friendly messages. Log details for [Link]('token'). Redirect to login page.
debugging.
Token expiry
Tokens expire (e.g. 24h). When 401 received, redirect to login.
07 REST URL Patterns 08 Fullstack Data Flow ★
Collection Full cycle
GET /api/users = all. POST /api/users = create new. Click -> JS event -> fetch() -> backend -> DB query -> JSON response ->
DOM update.
Single resource
GET /api/users/1. PUT /api/users/1. DELETE /api/users/1. Loading state
Show spinner before fetch. Hide after. Toggle a CSS class on the
Nested resource
container.
GET /api/users/1/posts = all posts by user 1.
Error state
Query params
Catch errors and show user-friendly messages. Never show raw server
GET /api/products?category=shoes&sort;=price — filter without changing errors.
endpoint.
CRUD on frontend
Versioning
Create = POST + push. Read = GET + render. Update = PUT + replace.
GET /api/v1/users — old clients don't break when API changes. Delete = DELETE + filter.
Environment URLs
Dev: localhost:3000/api. Production: [Link]/api. Use env variables.
09 Backend — Node/Express 10 Database Basics
[Link] SQL vs NoSQL
JS runtime outside the browser. Write backend code in JavaScript. SQL (PostgreSQL) = tables, strict schema. NoSQL (MongoDB) =
documents, flexible.
Express
const app = express() then define routes and listen on a port. CRUD in DB
Create = INSERT. Read = SELECT. Update = UPDATE. Delete =
Route
DELETE.
[Link]('/api/users', (req, res) => { [Link](users) })
ORM
req / res
Write JS to query DB instead of raw SQL. Examples: Prisma, Sequelize.
[Link], [Link], [Link]. [Link](data),
[Link](404).json({error}). ID field
Every record has unique id. Frontend uses it in URLs like /api/users/1.
Middleware
[Link]() parses incoming JSON. cors() allows cross-origin Relationships
requests. One-to-many: one user has many posts. Linked via foreign keys.
11 CORS & Security
CORS
Browser blocks frontend on :3000 calling backend on :5000 unless
backend allows it.
Fix CORS
In Express: use cors() middleware. Allows cross-origin requests.
Never trust frontend
Always validate on backend. Frontend validation is UX only — anyone
can bypass.
Env variables
Store secrets in .env file. Never commit to git.
HTTPS
Always use in production. Encrypts data between browser and server.
[ JS+ ] JS Advanced
01 Closures ★ 02 this Keyword ★
What is a closure? In regular function
A function that remembers variables from its outer scope even after the this = object that called the function. In strict mode = undefined. In
outer function has finished. browser = window.
Example In arrow function
function counter() { let count = 0; return function() { count++; return count; Arrow functions have NO own this. They inherit this from surrounding
}} scope. Cannot be changed with bind/call/apply.
Why it matters In object method
Used for data privacy, factory functions, callbacks, module patterns. Very const obj = { greet() { [Link]([Link]) } } — this = obj. Breaks with
commonly asked. arrow function.
Common interview Q bind / call / apply
Loop with var + setTimeout prints same value for all — fix with let or IIFE. bind returns new function with fixed this. call invokes immediately. apply
Closure captures reference not value. same but args as array.
Real use case Common trap
API call wrappers, debounce/throttle, React useState hooks — all use setTimeout(() => [Link]) vs setTimeout(function() { [Link] }) —
closures internally. arrow keeps outer this, regular loses it.
03 Prototypes & Inheritance 04 Event Loop Deep Dive ★
What is a prototype? Macrotasks
Every JS object has __proto__ link to another object. Property lookup setTimeout, setInterval, DOM events. Go into macrotask queue. One at a
walks up the chain until found or null. time after each render.
Prototype chain Microtasks
[Link]() — obj doesn't have it, looks in obj.__proto__ Promise .then/.catch, async/await continuations. ALL microtasks run
([Link]), finds it there. before next macrotask.
class in JS Order of execution
class is syntactic sugar over prototype. class Dog extends Animal { } sets 1. Run sync code. 2. Run ALL microtasks. 3. Render. 4. Run ONE
up prototype chain automatically. macrotask. 5. Repeat.
hasOwnProperty() Interview Q
[Link]('name') — true only if property is directly on object, [Link](1); setTimeout(log(2),0); [Link]().then(log(3));
not inherited. log(4) — Output: 1, 4, 3, 2
Interview tip Why this matters
class is syntax sugar, prototype is the actual mechanism. Know both. Promises are faster than setTimeout. Microtasks run immediately after
sync code, not delayed.
05 Debounce & Throttle ★ 06 Hoisting & TDZ ★
Debounce var hoisting
Waits until user STOPS doing something. Search input: don't call API on var declarations moved to top of function scope. Access before declare =
every keystroke, wait until pause (300ms). undefined (not error).
Debounce code let / const TDZ
function debounce(fn, delay) { let timer; return (...args) => { Temporal Dead Zone. let/const hoisted but NOT initialized. Access before
clearTimeout(timer); timer = setTimeout(() => fn(...args), delay); } } declare = ReferenceError.
Throttle Function hoisting
Fires at most once per time window. Scroll event: run at most every Function declarations fully hoisted — function and body. Arrow functions
100ms no matter how fast user scrolls. are NOT hoisted.
Throttle code Interview trap
function throttle(fn, limit) { let last=0; return (...args) => { [Link](x); var x=5 = undefined. [Link](y); let y=5 =
if([Link]()-last>=limit){last=[Link]();fn(...args)} } } ReferenceError. Very commonly asked.
When to use
Debounce = search bars, form validation. Throttle = scroll handlers,
resize, button spam prevention.
07 Shallow vs Deep Copy ★ 08 CSS Specificity ★
Shallow copy What is specificity?
Copies top-level only. Nested objects still share same reference. When multiple rules target same element, specificity decides which wins.
Changing nested in copy changes original.
Specificity order
Shallow methods inline style (1000) > #id (100) > .class/:pseudo (10) > element tag (1) > *
[Link]({}, obj), spread {...obj}, [Link]() — all shallow. Safe for (0).
flat, dangerous for nested.
Calculation
Deep copy #nav .menu a:hover = 100 + 10 + 1 + 10 = 121. Higher always wins
Copies everything recursively. New nested objects created. Changes regardless of order.
don't affect original.
!important
Deep copy methods Overrides everything. Use as last resort only. Makes CSS hard to
[Link]([Link](obj)) = simple. structuredClone(obj) = maintain. Avoid in production.
modern best. Lodash cloneDeep() = popular.
visibility vs display
Interview tip visibility:hidden = invisible but takes up space. display:none = removed
const b=a (reference). const b={...a} (shallow). structuredClone(a) (deep). from layout completely.
Know all three.
Inheritance
color, font inherit by default. margin, padding, border do NOT inherit. Use
inherit keyword to force it.
09 Promise Patterns 10 Memory & Performance
[Link]() Memory leaks
Runs multiple promises simultaneously. Waits for ALL to resolve. One Forgotten event listeners, closures holding large objects, global variables,
failure = everything fails. detached DOM nodes still referenced.
[Link]() Remove listeners
Runs all, waits for ALL to finish. Returns results even if some failed. Good Always removeEventListener when component unmounts. Not doing this
when you need all results. keeps element in memory.
[Link]() Garbage collection
Returns result of whichever resolves or rejects FIRST. Useful for JS automatically frees memory for objects with no references. Set large
timeouts. objects to null when done.
Chaining WeakMap / WeakSet
.then() returns a new Promise. fetch().then(res=>[Link]()).then(data=>p Hold weak references. If object has no other references, GC can collect
rocess(data)).catch(err=>handle(err)). it. Good for caching without leaks.
async/await vs .then()
Both do same thing. async/await is cleaner to read. .then() is useful for
short one-liners.
[ BE ] Backend Depth
01 Password Hashing ★ 02 Middleware Chain ★
Never store plain text What is middleware?
If DB is breached, attacker gets all passwords. Always hash before Function that runs between request and route handler. Has req, res, next.
storing. Critical security rule. Call next() to continue.
bcrypt Middleware order
[Link](password, saltRounds) — saltRounds = 10-12 is standard. Request -> cors() -> [Link]() -> authMiddleware -> routeHandler ->
Slow by design to resist brute force. errorMiddleware -> Response.
Salt Auth middleware
Random string added before hashing. Prevents rainbow table attacks. Check Authorization header, verify JWT, attach user to [Link], call
bcrypt generates salt automatically. next(). If invalid, return 401.
Comparing Error middleware
[Link](inputPassword, storedHash) returns true/false. Never 4 arguments: (err, req, res, next). Must be defined LAST. Catches errors
decrypt — always re-hash and compare. thrown in any route.
Full flow next(err)
Register: hash password -> store hash. Login: [Link] -> if true, Calling next(err) skips all normal middleware and jumps straight to
generate JWT -> return token. error-handling middleware.
03 Error Handling Patterns 04 DB Indexing ★
Operational vs programmer What is an index?
Operational = expected (invalid input, DB down). Programmer = bugs. Data structure that speeds up queries on a column. DB jumps directly to
Handle operational gracefully, fix bugs. matching rows instead of scanning all.
Global error handler When to index
Express error middleware catches unhandled errors. Also add Columns used in WHERE, JOIN, ORDER BY, and frequently searched
[Link]('uncaughtException') for safety. fields. Primary key is auto-indexed.
HTTP error classes Trade-off
class AppError extends Error { constructor(message, statusCode) { Indexes speed up reads but slow down writes. INSERT/UPDATE must
super(message); [Link] = statusCode; } } update the index too. Don't index everything.
Async error catching Compound index
Wrap async routes in try/catch or use wrapper: const catchAsync = fn => Index on multiple columns. Useful when queries filter on both columns
(req,res,next) => fn(req,res,next).catch(next) together.
Never expose internals Interview Q
In production, never send stack traces or DB errors to client. Log SELECT * WHERE email='x' slow without index = full table scan O(n).
server-side. Send user-friendly message only. With index = O(log n) lookup.
05 DB Transactions ★ 06 N+1 Problem ★
What is a transaction? What is N+1?
Group of DB operations that all succeed together or all fail together. Fetch N records, then make 1 extra query per record = N+1 queries total.
Guarantees data consistency. Classic performance killer with ORMs.
ACID Example
Atomicity (all or nothing), Consistency (DB stays valid), Isolation (no Get 100 users, then get each user's posts = 1 + 100 = 101 queries.
interference), Durability (persists). Should be 2.
Example Fix: eager loading
Bank transfer: deduct from A AND add to B. If step 2 fails, step 1 must roll Load related data in one query. In Prisma: include: { posts: true }. In SQL:
back or A loses money. JOIN.
In SQL Fix: DataLoader
BEGIN; UPDATE accounts SET bal=bal-100 WHERE id=1; UPDATE ... Batches multiple single-item queries into one. Common in GraphQL.
COMMIT; — or ROLLBACK if error.
Interview tip
In Prisma Always mention N+1 when discussing ORM performance. Shows
prisma.$transaction([update1, update2]) — both run or neither does. real-world backend awareness.
07 Refresh Tokens & Auth ★ 08 BEM & CSS Architecture
Access token What is BEM?
Short-lived JWT (15min-1hr). Sent with every request. If stolen, damage Block Element Modifier. Naming convention for CSS. Prevents naming
limited by short expiry. conflicts, self-documenting.
Refresh token Block
Long-lived (7-30 days). Stored in httpOnly cookie. Used only to get new Standalone component. .card, .nav, .button.
access token when expired.
Element
Flow Part of a block. Separated by __. .card__title, .card__body, .nav__link.
Login -> access token + refresh token. Access expires -> send refresh ->
Modifier
get new access token. Logout -> invalidate refresh.
Variation. Separated by --. .button--primary, .card--featured,
httpOnly cookie .nav__link--active.
JS cannot access httpOnly cookies. Protects refresh token from XSS
Why it matters
attacks.
Shows you write maintainable CSS. Avoids deep nesting and specificity
Token blacklist battles. Used in large codebases.
On logout, store invalidated token in DB/Redis. Check on each refresh.
Prevents reuse of stolen tokens.
[ PERF ] Performance
01 Lazy Loading ★ 02 CDN & Caching
What is it? CDN
Only load resources when needed, not all at once. Improves initial load Content Delivery Network. Static files copied to servers worldwide. User
time and saves bandwidth. downloads from nearest server = faster.
Images Browser caching
Add loading='lazy' to img tags. Browser downloads only when about to Cache-Control header tells browser how long to keep file.
enter viewport. Native HTML — no JS needed. max-age=31536000 = 1 year.
Code splitting Cache busting
Split JS bundle into chunks. Load only code needed for current page. Include file hash in name: [Link]. New content = new hash =
Vite/Webpack do this automatically. new URL = fresh download.
Dynamic import() Service Worker
const module = await import('./[Link]') — loads JS file on JS file that intercepts network requests. Can serve cached responses
demand. when offline. Foundation of PWA.
[Link]() ETag
const Chart = [Link](() => import('./Chart')) — component only Server sends hash of file. Browser sends it back. If unchanged, server
loaded when rendered. Wrap in Suspense. sends 304 Not Modified instead of full file.
03 Core Web Vitals ★ 04 Performance Techniques
LCP — Largest Contentful Paint Minification
How long until largest visible element loads. Target: under 2.5s. Improve Remove whitespace, comments, shorten variable names. Tools: Terser
with CDN, optimised images, preload. (JS), cssnano (CSS). Build tools do this.
INP — Interaction Tree shaking
How quickly page responds to interaction. Target: under 100ms. Improve: Build tool removes unused code. Only works with ES modules. Don't use
less JS on main thread, defer non-critical JS. require() for tree-shakeable code.
CLS — Cumulative Layout Shift Image optimisation
How much content moves unexpectedly. Target: under 0.1. Fix: set Use WebP or AVIF instead of JPEG/PNG (30-50% smaller). Use srcset
width/height on images, don't insert above existing content. for different screen sizes.
Why it matters Preload / Preconnect
Google uses Core Web Vitals as SEO ranking factor. Product companies preload = fetch critical resource early. preconnect = establish connection
track these closely. early. Both in head tag.
defer vs async script
defer = download in parallel, run after HTML parsed (maintains order).
async = run immediately when ready (no order).
05 Security Essentials ★ 06 Interview Must-Know Q&A; ★
XSS — Cross Site Scripting URL to render — full flow
Attacker injects malicious JS. Fix: never use innerHTML with user input, DNS -> TCP connection -> TLS handshake -> HTTP request -> server ->
sanitize all input, use CSP header. HTML response -> parse HTML -> fetch CSS/JS -> render.
CSRF — Cross Site Request Forgery HTTP vs HTTPS
Attacker tricks browser into making request. Fix: CSRF tokens, SameSite HTTP = plain text, insecure. HTTPS = encrypted with TLS. Required for
cookies, check Origin header. production, service workers, and some APIs.
SQL Injection REST vs GraphQL
Attacker puts SQL in form input. Fix: always use parameterized queries REST = multiple endpoints, fixed shape. GraphQL = single endpoint,
or ORM. Never concatenate user input into SQL. client requests exactly what it needs.
Content Security Policy Monolith vs Microservices
HTTP header that blocks XSS by preventing inline scripts and untrusted Monolith = one app does everything. Microservices = small services each
domains. doing one thing. Monolith simpler to start.
OWASP Top 10 What is a webhook?
Industry standard list of web security risks. Know XSS, SQL injection, Server calls YOUR endpoint when something happens. Opposite of
broken auth, insecure direct object references. polling. e.g. payment provider calls /api/payment-success.