🚀 FAANG-Level Performance & Security Guide

Complete Interview Preparation for 13+ Years Experience

React JS Node JS SQL/NoSQL Performance Security

📊 PART 1: PERFORMANCE OPTIMIZATION

🎯 Use This Framework: "CRISP-LOAD" (Easy to Remember)

  • C - Code Optimization
  • R - Rendering Optimization
  • I - Image/Asset Optimization
  • S - State Management
  • P - Progressive Enhancement
  • L - Lazy Loading
  • O - Output Caching
  • A - API Optimization
  • D - Database Optimization

🎨 FRONTEND PERFORMANCE (React Focus)

1. Code Optimization (C)

Answer to interviewer:
"After 13 years, I've found code optimization starts at the component level. Here's my approach:"

❌ BAD: Re-renders on every parent update

const UserCard = ({ user }) => {
    return <div>{user.name}</div>;
};

✅ GOOD: Memoized component

const UserCard = React.memo(({ user }) => {
    return <div>{user.name}</div>;
}, (prevProps, nextProps) => {
    return prevProps.user.id === nextProps.user.id;
});

✅ BETTER: useMemo for expensive calculations

const Dashboard = ({ data }) => {
    const sortedData = useMemo(() => {
        return data.sort((a, b) => b.value - a.value);
    }, [data]);
    
    return <Chart data={sortedData} />;
};

✅ BEST: useCallback for function props

const ParentComponent = () => {
    const handleClick = useCallback((id) => {
        updateUser(id);
    }, []); // Dependencies array
    
    return <ChildComponent onClick={handleClick} />;
};

Key Points to Mention:

  • React.memo for pure components (prevents re-renders)
  • useMemo for expensive computations (10ms+ calculations)
  • useCallback for function props passed to children
  • Code splitting with React.lazy() and Suspense
  • Tree shaking (remove unused code)
  • Bundle analysis with webpack-bundle-analyzer
Impressive metric to mention: "In my last project, implementing React.memo reduced re-renders by 60%, dropping Time to Interactive from 4.2s to 1.8s."

2. Rendering Optimization (R)

Answer to interviewer:
"React 18 concurrent features changed how I optimize rendering. Here's my strategy:"

✅ Virtual Scrolling for large lists

import { FixedSizeList } from 'react-window';

const LargeList = ({ items }) => (
    <FixedSizeList
        height={600}
        itemCount={items.length}
        itemSize={50}
        width="100%"
    >
        {({ index, style }) => (
            <div style={style}>{items[index].name}</div>
        )}
    </FixedSizeList>
);

✅ Debouncing expensive operations

import React, { useState, useDeferredValue } from "react";

const bigList = Array.from({ length: 10000 }, (_, i) => `Item ${i}`);

export default function SearchExample() {
  const [query, setQuery] = useState("");

  // 👇 Defer the expensive value
  const deferredQuery = useDeferredValue(query);

  const filteredList = bigList.filter(item =>
    item.toLowerCase().includes(deferredQuery.toLowerCase())
  );

  return (
    <div>
      <input
        type="text"
        placeholder="Search..."
        value={query}
        onChange={(e) => setQuery(e.target.value)}
      />

      <ul>
        {filteredList.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}
Answer to interviewer:
“I use useDeferredValue to prioritize urgent updates like user input and defer non-urgent updates like rendering large filtered lists.”

✅ startTransition for non-urgent updates

import { useState, useTransition } from 'react';

function SearchComponent({ list }) {
  const [input, setInput] = useState('');
  const [filtered, setFiltered] = useState(list);
  const [isPending, startTransition] = useTransition();

  const handleChange = (e) => {
    const value = e.target.value;
    setInput(value); // urgent update

    startTransition(() => {
      const result = list.filter(item =>
        item.toLowerCase().includes(value.toLowerCase())
      );
      setFiltered(result); // non-urgent update
    });
  };

  return (
    <div>
      <input value={input} onChange={handleChange} />

      {isPending && <p>Loading...</p>}

      <ul>
        {filtered.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}
Answer to interviewer:
💡 What’s Happening Here • setInput → urgent (user typing should never lag) • setFiltered → non-urgent (heavy work, can wait) • startTransition → tells React: “This can be interrupted if user types again”
“If I already have a value and want React to delay its effect, I use useDeferredValue. But if I want to explicitly mark some updates as low priority and also show a pending UI state, I use useTransition.”

Key Points to Mention:

  • Virtual scrolling (react-window) for 1000+ items
  • Pagination/infinite scroll vs loading all data
  • useDeferredValue for input-heavy UI
  • startTransition for non-blocking updates
  • Web Workers for heavy computations
  • RequestIdleCallback for low-priority tasks
Impressive metric: "Implemented virtual scrolling for a 10,000-row table, reduced initial render from 8s to 200ms."

3. Image/Asset Optimization (I)

Answer to interviewer:
"Images typically account for 50% of page weight. My optimization stack:"

✅ Next.js Image component (automatic optimization)

import Image from 'next/image';

<Image
    src="/profile.jpg"
    width={400}
    height={400}
    alt="Profile"
    loading="lazy"
    placeholder="blur"
    quality={85}
/>

✅ Responsive images with srcset

<img
    src="hero-800.webp"
    srcset="
        hero-400.webp 400w,
        hero-800.webp 800w,
        hero-1200.webp 1200w
    "
    sizes="(max-width: 600px) 400px, 800px"
    alt="Hero"
/>

Images Optimization

  • WebP/AVIF format (30% smaller than JPEG)
  • Lazy loading (loading="lazy")
  • CDN with image optimization
  • Responsive images (srcset)
  • Compress images
  • Remove EXIF data

Assets Optimization

  • SVG for icons (vs icon fonts)
  • Inline critical SVGs
  • Minify CSS/JS
  • Remove unused CSS (PurgeCSS)
  • Tree-shake libraries
Impressive metric: "Converted images to WebP + lazy loading reduced LCP from 3.8s to 1.2s, moved from 'Needs Improvement' to 'Good' in Core Web Vitals."

4. State Management (S)

Answer to interviewer:
"Poor state management is the #1 cause of React performance issues. Here's how I handle it:"

❌ BAD: Global state causing unnecessary re-renders

const App = () => {
    const [appState, setAppState] = useState({
        user: {},
        cart: [],
        notifications: []
    });
    
    // Every update re-renders entire app!
};

✅ GOOD: Separate contexts

const UserContext = createContext();
const CartContext = createContext();
const NotificationsContext = createContext();

✅ BETTER: Zustand for granular updates

import create from 'zustand';

const useStore = create((set) => ({
    user: null,
    cart: [],
    updateCart: (items) => set({ cart: items })
}));

// Only components using cart re-render
const Cart = () => {
    const cart = useStore(state => state.cart);
    // ...
};

State Management Options:

  • Context API: Split by domain (don't use one giant context)
  • Zustand: Simple, fast, no providers needed
  • Jotai: Atomic, bottom-up state
  • Redux Toolkit: For complex apps (with RTK Query)
  • React Query: Server state management (caching, refetching)
  • LocalStorage: Persist cart, theme, preferences
Impressive statement: "Migrated from Context API to Zustand, reduced re-renders by 70%. Combined with React Query for server state, eliminated 90% of loading spinners through smart caching."

5. Progressive Enhancement (P)

Answer to interviewer:
"Modern web should work for everyone. My progressive enhancement strategy:"

✅ SSR/SSG for initial load

// Next.js example
export async function getStaticProps() {
    const data = await fetchData();
    return { props: { data } };
}

✅ Hydration optimization

import dynamic from 'next/dynamic';

const HeavyComponent = dynamic(
    () => import('./HeavyComponent'),
    { ssr: false } // Skip SSR for client-only components
);

✅ Prefetch critical resources

<link rel="preload" href="/font.woff2" as="font" crossorigin />
<link rel="prefetch" href="/next-page.js" />
<link rel="preconnect" href="https://api.example.com" />

Progressive Enhancement Stack:

  • SSR/SSG: Next.js, Remix, Astro
  • Streaming SSR: React 18 Suspense
  • Critical CSS: Inline above-the-fold styles
  • Font optimization: font-display: swap
  • Service Workers: Workbox for caching
  • HTTP/2 Server Push: Critical resources
  • Resource hints: preload, prefetch, preconnect
Impressive metric: "Implemented SSR + service worker strategy. Time to First Byte dropped from 800ms to 120ms. Offline mode increased engagement by 23%."

6. Lazy Loading (L)

Answer to interviewer:
"Lazy loading is essential for modern SPAs. My implementation:"

✅ Component lazy loading

const Profile = lazy(() => import('./Profile'));
const Dashboard = lazy(() => import('./Dashboard'));

<Suspense fallback={<Spinner />}>
    <Routes>
        <Route path="/profile" element={<Profile />} />
        <Route path="/dashboard" element={<Dashboard />} />
    </Routes>
</Suspense>

✅ Image lazy loading

const LazyImage = ({ src, alt }) => {
    const [imageSrc, setImageSrc] = useState(placeholder);
    const imgRef = useRef();
    
    useEffect(() => {
        const observer = new IntersectionObserver(([entry]) => {
            if (entry.isIntersecting) {
                setImageSrc(src);
                observer.disconnect();
            }
        });
        
        observer.observe(imgRef.current);
        return () => observer.disconnect();
    }, [src]);
    
    return <img ref={imgRef} src={imageSrc} alt={alt} />;
};

Lazy Loading Strategy:

  • Route-based code splitting (automatic with Next.js)
  • Component lazy loading (React.lazy)
  • Library lazy loading (import() for heavy libs)
  • Image lazy loading (IntersectionObserver)
  • Below-the-fold content lazy loading
  • Defer non-critical JS (defer/async attributes)

⚙️ BACKEND PERFORMANCE (Node.js Focus)

7. Output Caching (O)

Answer to interviewer:
"Caching is the biggest performance multiplier on the backend. My caching strategy:"

✅ Redis for application cache

import Redis from 'ioredis';
const redis = new Redis();

app.get('/api/user/:id', async (req, res) => {
    const cacheKey = `user:${req.params.id}`;
    
    // Try cache first
    const cached = await redis.get(cacheKey);
    if (cached) {
        return res.json(JSON.parse(cached));
    }
    
    // Cache miss: fetch from DB
    const user = await User.findById(req.params.id);
    
    // Cache for 5 minutes
    await redis.setex(cacheKey, 300, JSON.stringify(user));
    
    res.json(user);
});

✅ Cache invalidation

app.put('/api/user/:id', async (req, res) => {
    const user = await User.findByIdAndUpdate(req.params.id, req.body);
    
    // Invalidate cache
    await redis.del(`user:${req.params.id}`);
    
    res.json(user);
});

✅ HTTP caching headers

app.get('/api/posts', (req, res) => {
    res.set({
        'Cache-Control': 'public, max-age=300', // 5 minutes
        'ETag': generateETag(posts),
        'Last-Modified': posts.updatedAt
    });
    res.json(posts);
});

Caching Layers:

  1. Layer 1: Browser Cache (Cache-Control headers)
  2. Layer 2: CDN Cache (CloudFront, Cloudflare)
  3. Layer 3: Application Cache (Redis, Memcached)
  4. Layer 4: Database Query Cache
  5. Layer 5: Database Connection Pool

Cache Strategy:

  • Static assets: 1 year cache
  • API responses: 5-60 minutes cache
  • User-specific data: No cache or private cache
  • Public data: Aggressive caching
Impressive metric: "Implemented 3-tier caching (CDN + Redis + query cache). API response time dropped from 450ms to 12ms for cached data. Cache hit rate: 87%. Server load reduced by 65%."

8. API Optimization (A)

Answer to interviewer:
"API design directly impacts frontend performance. My optimization approach:"

✅ Pagination (don't load all data)

app.get('/api/posts', async (req, res) => {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 20;
    const skip = (page - 1) * limit;
    
    const posts = await Post.find()
        .skip(skip)
        .limit(limit)
        .lean(); // MongoDB: skip Mongoose overhead
    
    res.json({
        data: posts,
        page,
        totalPages: Math.ceil(totalCount / limit)
    });
});

✅ Field filtering (don't send unnecessary data)

app.get('/api/users', async (req, res) => {
    const fields = req.query.fields?.split(',').join(' ') || '';
    
    const users = await User.find()
        .select(fields || 'name email avatar')
        .lean();
    
    res.json(users);
});

✅ Compression

import compression from 'compression';
app.use(compression()); // gzip responses

API Optimization Checklist:

  • Pagination: Limit 20-50 items per page
  • Field filtering: Let client specify fields
  • Batch endpoints: Combine multiple requests
  • GraphQL: For complex data requirements
  • Response compression: gzip/brotli
  • HTTP/2: Multiplexing
  • Connection pooling: Reuse DB connections
  • Async/await: Non-blocking operations
  • Streaming: For large responses
  • Rate limiting: Prevent abuse
Impressive metric: "Implemented GraphQL + field filtering. Average API response size dropped from 150KB to 18KB (88% reduction). Combined with pagination, initial page load improved from 2.8s to 0.9s."

9. Database Optimization (D)

Answer to interviewer:
"Database is often the bottleneck. My optimization strategy:"

✅ Indexing (most critical)

// MongoDB
db.users.createIndex({ email: 1 }, { unique: true });
db.posts.createIndex({ userId: 1, createdAt: -1 });
db.posts.createIndex({ tags: 1 }); // Array field index

// PostgreSQL
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_posts_user_date ON posts(user_id, created_at DESC);
CREATE INDEX idx_posts_tags ON posts USING GIN(tags); // JSON index

✅ Query optimization - Avoid N+1 problem

// BAD: N+1 query problem
const users = await User.find();
for (let user of users) {
    user.posts = await Post.find({ userId: user.id }); // N queries!
}

// GOOD: Use joins/populate
const users = await User.find().populate('posts'); // 1 query

✅ Select only needed fields

// BAD
const users = await User.find(); // Gets all fields

// GOOD
const users = await User.find().select('name email avatar');

SQL Optimization

  • Indexes on frequently queried columns
  • Composite indexes for multi-column queries
  • EXPLAIN ANALYZE to identify slow queries
  • Avoid SELECT *, specify columns
  • Use JOINs instead of multiple queries
  • Connection pooling (pg-pool)
  • Read replicas for scaling reads
  • Materialized views for complex aggregations

NoSQL (MongoDB) Optimization

  • Compound indexes for common queries
  • Projection (select specific fields)
  • .lean() to skip Mongoose overhead
  • Aggregation pipeline for complex queries
  • Sharding for horizontal scaling
  • Read preference: secondary for reads
Impressive metric: "Added indexes on user_id and created_at. Query time dropped from 2.3s to 48ms (98% improvement). Implemented read replicas, scaled read throughput from 1K to 10K queries/second."

🌐 NETWORK OPTIMIZATION

Answer to interviewer:
"Network is often overlooked but critical. My optimization approach:"

✅ Resource hints

<link rel="preconnect" href="https://api.example.com" />
<link rel="dns-prefetch" href="https://fonts.googleapis.com" />
<link rel="preload" href="/critical.css" as="style" />
<link rel="prefetch" href="/next-page.js" />

✅ Service Worker for offline

// sw.js
self.addEventListener('fetch', event => {
    event.respondWith(
        caches.match(event.request).then(response => {
            return response || fetch(event.request);
        })
    );
});

✅ WebSocket for real-time (vs polling)

const ws = new WebSocket('wss://api.example.com');
ws.onmessage = (event) => {
    updateUI(JSON.parse(event.data));
};

Network Optimization Checklist:

  • CDN: CloudFront, Cloudflare (edge caching)
  • HTTP/2: Enabled by default with HTTPS
  • HTTP/3 (QUIC): Faster than TCP
  • Compression: gzip (older) or brotli (better)
  • Minification: JS, CSS, HTML
  • Resource hints: preconnect, prefetch, preload
  • Service Workers: Offline-first strategy
  • WebSocket: For real-time (not polling)
  • Keep-Alive: Reuse TCP connections
  • Reduce redirects: Each adds latency

📏 PERFORMANCE METRICS TO MENTION

Core Web Vitals (Google's standards)

LCP (Largest Contentful Paint)

  • Target: < 2.5 seconds
  • Measures: Loading performance
  • Fix: Optimize images, use CDN, lazy load

FID (First Input Delay)

  • Target: < 100 milliseconds
  • Measures: Interactivity
  • Fix: Minimize JS, code splitting

CLS (Cumulative Layout Shift)

  • Target: < 0.1
  • Measures: Visual stability
  • Fix: Set image dimensions, avoid dynamic content

Tools to mention:

  • Lighthouse (Chrome DevTools)
  • WebPageTest (detailed analysis)
  • Chrome DevTools Performance tab
  • React DevTools Profiler
  • webpack-bundle-analyzer
  • New Relic / Datadog (production monitoring)
Impressive statement:
"In my last project, we achieved all 'Good' Core Web Vitals scores: LCP 1.8s, FID 45ms, CLS 0.05. This moved us from page 3 to page 1 in Google search results, increasing organic traffic by 145%."

🔒 PART 2: WEBSITE SECURITY

🎯 Use This Framework: "SAFE-COAST" (Easy to Remember)

  • S - SQL Injection Protection
  • A - Authentication & Authorization
  • F - Frontend Security (XSS, CSRF)
  • E - Encryption (HTTPS, Data)
  • C - CORS Configuration
  • O - Output Encoding
  • A - API Security
  • S - Security Headers
  • T - Third-party Dependencies

🛡️ FRONTEND SECURITY

1. XSS (Cross-Site Scripting) Prevention

Answer to interviewer:
"XSS is the #1 frontend security risk. Here's how I prevent it:"

❌ VULNERABLE: Direct HTML injection

const UserComment = ({ comment }) => {
    return <div dangerouslySetInnerHTML={{ __html: comment }} />;
};
// Attacker comment: "<script>alert('XSS')</script>"

✅ SAFE: React escapes by default

const UserComment = ({ comment }) => {
    return <div>{comment}</div>; // Automatically escaped
};

✅ SAFE: Sanitize if HTML needed

import DOMPurify from 'dompurify';

const UserComment = ({ comment }) => {
    const sanitized = DOMPurify.sanitize(comment);
    return <div dangerouslySetInnerHTML={{ __html: sanitized }} />;
};

✅ Content Security Policy (CSP)

<meta 
    http-equiv="Content-Security-Policy"
    content="
        default-src 'self';
        script-src 'self' 'unsafe-inline' https://cdn.example.com;
        style-src 'self' 'unsafe-inline';
        img-src 'self' data: https:;
    "
/>

XSS Prevention Checklist:

  • Never use dangerouslySetInnerHTML (unless sanitized)
  • Sanitize user input (DOMPurify, sanitize-html)
  • Content Security Policy (CSP) headers
  • HTTPOnly cookies (JS can't access)
  • Validate input on client AND server
  • Escape output in templates
  • Use textContent instead of innerHTML

2. CSRF (Cross-Site Request Forgery) Prevention

Answer to interviewer:
"CSRF tricks users into executing unwanted actions. My prevention:"

✅ CSRF Token (Backend generates, frontend sends)

// Backend (Express)
import csrf from 'csurf';
app.use(csrf({ cookie: true }));

app.get('/form', (req, res) => {
    res.json({ csrfToken: req.csrfToken() });
});

// Frontend
const deleteAccount = async () => {
    const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
    
    await fetch('/api/account', {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-Token': csrfToken
        }
    });
};

✅ SameSite Cookies

res.cookie('session', token, {
    httpOnly: true,
    secure: true,
    sameSite: 'strict' // or 'lax'
});

CSRF Prevention Checklist:

  • CSRF tokens for state-changing operations
  • SameSite cookies (Strict or Lax)
  • Verify Origin/Referer headers
  • Use POST for state changes (not GET)
  • Double-submit cookies pattern
  • Custom headers (AJAX requests)

🔐 BACKEND SECURITY

3. SQL Injection Prevention

Answer to interviewer:
"SQL injection can expose entire database. Here's my protection:"

❌ VULNERABLE: String concatenation

app.get('/user', async (req, res) => {
    const { email } = req.query;
    const query = `SELECT * FROM users WHERE email = '${email}'`;
    const users = await db.query(query);
    // Attacker: email = "' OR '1'='1"
    // Returns ALL users!
});

✅ SAFE: Parameterized queries (PostgreSQL)

app.get('/user', async (req, res) => {
    const { email } = req.query;
    const query = 'SELECT * FROM users WHERE email = $1';
    const users = await db.query(query, [email]);
});

✅ SAFE: ORM (Mongoose, Sequelize, Prisma)

app.get('/user', async (req, res) => {
    const { email } = req.query;
    const user = await User.findOne({ email }); // Mongoose
});

✅ Input validation

import { body, validationResult } from 'express-validator';

app.post('/user',
    body('email').isEmail().normalizeEmail(),
    body('age').isInt({ min: 1, max: 120 }),
    async (req, res) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() });
        }
        // Safe to process
    }
);

SQL Injection Prevention:

  • Always use parameterized queries
  • Use ORM (Mongoose, Sequelize, Prisma)
  • Never concatenate user input into queries
  • Validate and sanitize input
  • Principle of least privilege (DB user permissions)
  • Escape special characters
  • Input validation library (express-validator, joi)

4. Authentication & Authorization

Answer to interviewer:
"Proper auth is critical. My implementation:"

✅ JWT with refresh tokens

import jwt from 'jsonwebtoken';

// Login
app.post('/login', async (req, res) => {
    const { email, password } = req.body;
    
    // Verify user
    const user = await User.findOne({ email });
    const isValid = await bcrypt.compare(password, user.password);
    
    if (!isValid) {
        return res.status(401).json({ error: 'Invalid credentials' });
    }
    
    // Generate tokens
    const accessToken = jwt.sign(
        { userId: user.id },
        process.env.JWT_SECRET,
        { expiresIn: '15m' }
    );
    
    const refreshToken = jwt.sign(
        { userId: user.id },
        process.env.REFRESH_SECRET,
        { expiresIn: '7d' }
    );
    
    res.json({ accessToken, refreshToken });
});

✅ Authentication middleware

const authenticateToken = (req, res, next) => {
    const token = req.headers['authorization']?.split(' ')[1];
    
    if (!token) {
        return res.status(401).json({ error: 'No token' });
    }
    
    jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
        if (err) {
            return res.status(403).json({ error: 'Invalid token' });
        }
        req.user = user;
        next();
    });
};

✅ Password hashing

import bcrypt from 'bcrypt';

const hashPassword = async (password) => {
    const salt = await bcrypt.genSalt(10);
    return bcrypt.hash(password, salt);
};

✅ Rate limiting (prevent brute force)

import rateLimit from 'express-rate-limit';

const loginLimiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 5, // 5 attempts
    message: 'Too many login attempts, try again later'
});

app.post('/login', loginLimiter, async (req, res) => {
    // Login logic
});

Authentication Security Checklist:

  • Bcrypt for password hashing (cost factor 10+)
  • JWT with short expiration (15 min access token)
  • Refresh tokens (7 days, stored in DB)
  • HTTPOnly cookies for tokens
  • Rate limiting on login endpoint
  • Account lockout after N failed attempts
  • Password requirements (length, complexity)
  • 2FA/MFA (TOTP, SMS)
  • Session management (logout all devices)
  • Password reset with token expiration

5. Encryption

Answer to interviewer:
"Data encryption at rest and in transit. My approach:"

✅ Encrypt sensitive data at rest

import crypto from 'crypto';

const algorithm = 'aes-256-gcm';
const key = Buffer.from(process.env.ENCRYPTION_KEY, 'hex');

const encrypt = (text) => {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(algorithm, key, iv);
    
    let encrypted = cipher.update(text, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    
    const authTag = cipher.getAuthTag();
    
    return {
        encrypted,
        iv: iv.toString('hex'),
        authTag: authTag.toString('hex')
    };
};

✅ Store sensitive config in env variables

// .env file (never commit to git)
JWT_SECRET=your-super-secret-key-here
DATABASE_URL=postgresql://user:pass@host:5432/db
ENCRYPTION_KEY=64-char-hex-key-here

Encryption Checklist:

  • HTTPS everywhere (TLS 1.2+)
  • Strong ciphers (AES-256-GCM)
  • Encrypt PII at rest (credit cards, SSN)
  • Environment variables for secrets
  • Secrets management service (AWS Secrets Manager)
  • Key rotation (change encryption keys regularly)
  • Certificate pinning (mobile apps)
  • HSTS header (force HTTPS)

6. Security Headers

Answer to interviewer:
"Security headers protect against common attacks. My configuration:"

✅ Using Helmet.js

import helmet from 'helmet';

app.use(helmet({
    // Content Security Policy
    contentSecurityPolicy: {
        directives: {
            defaultSrc: ["'self'"],
            scriptSrc: ["'self'", "'unsafe-inline'", "cdn.example.com"],
            styleSrc: ["'self'", "'unsafe-inline'"],
            imgSrc: ["'self'", "data:", "https:"],
            connectSrc: ["'self'", "api.example.com"],
            fontSrc: ["'self'", "fonts.googleapis.com"],
            objectSrc: ["'none'"],
            upgradeInsecureRequests: []
        }
    },
    // Strict Transport Security (force HTTPS)
    hsts: {
        maxAge: 31536000,
        includeSubDomains: true,
        preload: true
    },
    // Prevent clickjacking
    frameguard: {
        action: 'deny'
    },
    // Disable browser MIME sniffing
    noSniff: true,
    // XSS Protection
    xssFilter: true
}));

Security Headers Checklist:

  • Content-Security-Policy (CSP)
  • Strict-Transport-Security (HSTS)
  • X-Frame-Options (prevent clickjacking)
  • X-Content-Type-Options (prevent MIME sniffing)
  • X-XSS-Protection (XSS filter)
  • Referrer-Policy (privacy)
  • Permissions-Policy (feature control)
  • CORS configuration (controlled access)

7. API Security

Answer to interviewer:
"APIs are attack vectors. My security approach:"

✅ Rate limiting

import rateLimit from 'express-rate-limit';

const apiLimiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100, // 100 requests per windowMs
    message: 'Too many requests, please try again later'
});

app.use('/api/', apiLimiter);

✅ Input validation

import Joi from 'joi';

const userSchema = Joi.object({
    email: Joi.string().email().required(),
    password: Joi.string().min(8).required(),
    age: Joi.number().integer().min(1).max(120)
});

app.post('/api/user', async (req, res) => {
    const { error } = userSchema.validate(req.body);
    
    if (error) {
        return res.status(400).json({ error: error.details[0].message });
    }
    
    // Safe to process
});

✅ Request size limits

app.use(express.json({ limit: '10kb' })); // Max 10KB body
app.use(express.urlencoded({ extended: true, limit: '10kb' }));

API Security Checklist:

  • Authentication (JWT, API keys)
  • Rate limiting (per IP, per user)
  • Input validation (Joi, express-validator)
  • Request size limits
  • Timeout handling
  • CORS configuration
  • API versioning (/api/v1/)
  • Error handling (no info leakage)
  • Logging & monitoring
  • API documentation (OpenAPI/Swagger)

8. CORS Configuration

Answer to interviewer:
"CORS misconfiguration is a common vulnerability. Here's my setup:"

✅ Restrictive CORS (production)

import cors from 'cors';

const corsOptions = {
    origin: ['https://myapp.com', 'https://www.myapp.com'],
    methods: ['GET', 'POST', 'PUT', 'DELETE'],
    allowedHeaders: ['Content-Type', 'Authorization'],
    credentials: true, // Allow cookies
    maxAge: 86400 // Cache preflight for 24 hours
};

app.use(cors(corsOptions));

✅ Dynamic origin validation

const corsOptions = {
    origin: (origin, callback) => {
        const allowedOrigins = ['https://myapp.com', 'https://admin.myapp.com'];
        
        if (!origin || allowedOrigins.includes(origin)) {
            callback(null, true);
        } else {
            callback(new Error('Not allowed by CORS'));
        }
    },
    credentials: true
};

app.use(cors(corsOptions));

⚠️ NEVER in production:

app.use(cors()); // Allows ALL origins!

9. Third-Party Dependencies

Answer to interviewer:
"Dependencies can introduce vulnerabilities. My security process:"

✅ Regular security audits

npm audit
npm audit fix

# Automated dependency scanning
npm install -g snyk
snyk test
snyk monitor

# Keep dependencies updated
npm outdated
npm update

Dependency Security Checklist:

  • npm audit before every deploy
  • Snyk or Dependabot for monitoring
  • Review dependencies before adding
  • Update regularly (monthly)
  • Lock file committed (package-lock.json)
  • Remove unused dependencies
  • Use npm ci (not npm install) in CI/CD
  • Check license compatibility

🎯 HOW TO ANSWER IN INTERVIEW

Performance Question

Interviewer: "How do you optimize website performance?"


Your answer (2-3 minutes):

"I approach performance holistically across frontend, backend, and network layers.

Frontend: I start with React optimization—React.memo for preventing re-renders, useMemo for expensive calculations, and code splitting with React.lazy. For a recent project, this reduced Time to Interactive from 4.2s to 1.8s.

Images are typically 50% of page weight, so I use WebP format, lazy loading, and CDN with automatic optimization. This improved our Largest Contentful Paint from 3.8s to 1.2s.

Backend: I implement 3-tier caching—CDN, Redis for application cache, and database query cache. This dropped API response time from 450ms to 12ms for cached data with an 87% cache hit rate.

Database: I ensure proper indexing—this alone improved a slow query from 2.3s to 48ms. I also use connection pooling and read replicas to scale reads from 1K to 10K queries/second.

Network: CDN is critical. I serve static assets from edge locations worldwide, reducing latency from 300ms to 20ms for international users.

I measure everything using Core Web Vitals and Lighthouse. In my last project, we achieved all 'Good' scores: LCP 1.8s, FID 45ms, CLS 0.05. This moved us from page 3 to page 1 in Google search, increasing organic traffic by 145%."

Security Question

Interviewer: "How do you secure a website?"


Your answer (2-3 minutes):

"Security is multi-layered. I follow the OWASP Top 10 and implement defense in depth.

Frontend: I prevent XSS by never using dangerouslySetInnerHTML unless the content is sanitized with DOMPurify. I implement Content Security Policy headers to block unauthorized scripts. For CSRF, I use SameSite cookies and CSRF tokens for state-changing operations.

Backend: SQL injection prevention is critical—I always use parameterized queries or ORMs like Prisma. Never string concatenation. I implement input validation with Joi or express-validator on every endpoint.

Authentication: I use JWT with short-lived access tokens (15 min) and longer refresh tokens (7 days) stored in HTTPOnly cookies. Passwords are hashed with bcrypt at cost factor 10. I implement rate limiting on login endpoints—5 attempts per 15 minutes—to prevent brute force attacks.

Encryption: All data in transit uses HTTPS with TLS 1.2+. Sensitive data at rest like credit cards are encrypted with AES-256-GCM. Secrets are stored in environment variables, never in code.

Security Headers: I use Helmet.js to set all security headers—CSP, HSTS, X-Frame-Options, etc. This protects against clickjacking, XSS, and other attacks.

API Security: Every API endpoint has rate limiting (100 requests per 15 min), authentication, and input validation. I also limit request body size to 10KB to prevent DoS.

Monitoring: I run npm audit before every deploy and use Snyk for continuous dependency scanning. I also implement logging and alerting for suspicious activities—multiple failed logins, unusual API patterns, etc.

In my last project, we passed a security audit with zero critical vulnerabilities and achieved SOC 2 Type II compliance."

📝 QUICK REFERENCE CHEAT SHEET

Performance (CRISP-LOAD)

  • C - Code: React.memo, useMemo, code splitting
  • R - Rendering: Virtual scrolling, startTransition
  • I - Images: WebP, lazy loading, CDN
  • S - State: Zustand, React Query, context splitting
  • P - Progressive: SSR/SSG, service workers
  • L - Lazy: Component/route lazy loading
  • O - Output: Redis cache, CDN cache, query cache
  • A - API: Pagination, field filtering, compression
  • D - Database: Indexes, connection pooling, replicas

Security (SAFE-COAST)

  • S - SQL: Parameterized queries, ORM
  • A - Auth: JWT, bcrypt, rate limiting, 2FA
  • F - Frontend: XSS prevention, CSRF tokens
  • E - Encryption: HTTPS, AES-256, env variables
  • C - CORS: Restrictive origin policy
  • O - Output: Encoding, sanitization
  • A - API: Rate limiting, validation, auth
  • S - Security Headers: CSP, HSTS, X-Frame-Options
  • T - Third-party: npm audit, Snyk monitoring

💪 Confidence Boosters

When talking about performance:

  • "In my 13 years, I've optimized applications serving millions of users..."
  • "I've reduced page load time by 70% multiple times by..."
  • "Core Web Vitals are my benchmark—I always aim for all 'Good' scores..."

When talking about security:

  • "Security is not optional—I follow OWASP Top 10 religiously..."
  • "I've helped companies pass SOC 2 audits by implementing..."
  • "Zero critical vulnerabilities in production is my standard..."

Impressive closing:

"I believe performance and security aren't afterthoughts—they're core to the development process. I build them in from day one, measure continuously, and iterate based on real metrics. That's how I've consistently delivered fast, secure applications in my 13 years of experience."
🎯 Practice this framework, and you'll impress any FAANG interviewer! 🚀