End-to-End Feature Design and Development Questions
The integrated "build a complete feature" interview format: taking one feature from user-facing flow through API design, backend logic, data model, and storage in a single coherent walkthrough. Tests the ability to connect the layers and make consistent trade-offs across them, rather than depth in any single layer.
Design a scalable file upload architecture for user-submitted media (images and videos). Requirements: support large files, resumable uploads, virus scanning, thumbnail/transcode processing, durable storage, and near-real-time availability for web clients. Describe ingestion, processing pipeline, retries, and how you would scale each component.
Sample Answer
Requirements (clarified):
- Accept large files (multi-GB), resumable uploads, low-latency availability for web clients, durable storage, virus scanning, thumbnailing/transcoding, retries, horizontally scalable.
High-level flow:
- Client → Upload Gateway (signed URL + resumable session) → Object Storage
- Event Notification → Message Queue → Processing Workers (virus scan → metadata store → transcode/thumbnail) → CDN + metadata update
- Client polls / websocket for near-real-time status
Ingestion:
- Use a small Upload Gateway service that authenticates, issues time-limited signed URLs (S3/MinIO presigned PUT) and a resumable upload session ID (tus-protocol or multipart with checkpoints).
- Clients upload directly to object storage to offload bandwidth from app servers; store upload manifest in a DB (upload id, chunks, status).
Resumability:
- Use chunked uploads with checksums; client retries failed chunk uploads; server-side assembly triggered when manifest marks complete.
Processing pipeline:
- On finalization, emit message to durable queue (Kafka/SQS).
- Worker 1: Virus scanning (e.g., ClamAV or cloud malware scanning) runs on the object directly (scan container mounts object or streams from storage). If infected: mark status, move to quarantine, notify user.
- Worker 2: If clean, generate thumbnails (images) and transcode (videos) via scalable worker pool (Kubernetes autoscaled jobs or serverless functions for small files). Use GPU instances for heavy transcodes.
- Each processing step writes artifacts back to storage (separate buckets/prefixes), updates metadata DB (status, URLs, versions), and emits events.
Near-real-time availability:
- Expose low-res/placeholder thumbnail immediately after thumbnail job completes. Use CDN in front of storage; invalidate or update CDN on new artifact upload.
- Use WebSocket/event stream or pub/sub to notify clients of status changes.
Retries and error handling:
- Use durable queue with DLQ for poisoned messages.
- Workers implement idempotency (process by object version or checksum) and exponential backoff retries.
- Track retry counts in message metadata; after N failures alert SRE and mark for manual review.
Durability and consistency:
- Store originals in immutable, versioned object storage with lifecycle policies; keep metadata in transactional DB (Postgres/DynamoDB) with indices for queries.
- Use eventual consistency for processed artifacts; clients read metadata first, then fetch artifact URLs.
Scaling each component:
- Upload Gateway: stateless, autoscale behind LB; minimal CPU.
- Object Storage: use managed S3 or scaled MinIO cluster with erasure coding.
- Queue: Kafka/SQS for high throughput and retention.
- Workers: Kubernetes Horizontal Pod Autoscaler based on queue depth and CPU; separate worker pools for scanning vs. heavy transcode; use spot/preemptible for cost with fallback on on-demand for reliability.
- CDN: edge caching for low latency.
Security:
- Signed URLs with short TTL, least-privilege IAM roles for workers, server-side encryption, scanning before public availability, audit logs.
Trade-offs:
- Direct-to-storage reduces app bandwidth but requires careful resumable implementation.
- Serverless speeds up small-file processing; heavy video transcodes benefit from dedicated GPU instances.
Metrics and Observability:
- Track upload success rate, scan failures, processing latency, queue depth, worker error rates; alerts on DLQ growth and SLO breaches.
Design a real-time notifications service that delivers push notifications to mobile devices, websocket updates to web clients, and falls back to email when the user is offline. Requirements: low latency for active sessions, deduplication across channels, per-user rate limits, and reliable delivery with retries.
Sample Answer
Requirements (clarify):
- Functional: push to mobile (APNs/FCM), websocket updates to web, email fallback.
- Non-functional: low latency for active sessions (<100–200ms path), dedup across channels, per-user rate limits, reliable delivery with retries and at-least-once semantics.
High-level architecture:
Client apps (mobile, web) ↔ Ingress API (REST/gRPC) → Router/Dispatcher → Delivery Workers → Channel Integrations (APNs/FCM, WebSocket gateway, SMTP service) ← Persistence/Messaging (Kafka) and Supporting services: User Presence, Dedup store, Rate limiter, Retry/Dead-letter store, Metrics.
Core components:
- Ingress API: accept notification requests (from app servers/PM), validate, enrich, write to Kafka topic partitioned by user-id for ordering.
- User Presence Service: tracks active sessions (websocket connections, mobile foreground) via heartbeat and stores session metadata in Redis.
- Router/Dispatcher: consumes Kafka, queries Presence and Rate Limiter, decides channel priority (websocket if active, else push, else email), writes delivery task to Delivery Workers.
- Delivery Workers:
- WebSocket gateway: deliver to connection pool via clustered gateway (e.g., scalable websocket servers behind LB).
- Push workers: batch/aggregate for APNs/FCM, manage token lifecycle.
- Email worker: SMTP/SES integration.
Each worker writes success/failure to persistence and publishes acknowledgement events for dedup logic.
- Dedup store: short TTL store (Redis with unique key: user:notification:content-hash) to suppress duplicates across channels.
- Rate Limiter: token-bucket per-user in Redis; Router enforces limits, queues or drops low priority notifications.
- Retry & Reliability: failed deliveries are retried with exponential backoff; persistent tasks in durable store; failed after max attempts → dead-letter queue and optional email fallback.
- Observability: metrics, tracing, and dashboards for latency, delivery rates, and errors.
Data flow (example):
- Producer posts notification → Kafka.
- Router consumes → checks presence and rate limits.
- If websocket active and dedup not set → send via WebSocket Worker → on success mark dedup key; else attempt push; if offline and push fails (or device token invalid) → send email.
Scalability & performance:
- Kafka partitions by user-id for ordering and scale.
- Redis clusters for presence, dedup, and rate limits with sharding.
- WebSocket gateways behind LB with sticky sessions or session-store in Redis.
- Push workers use batching to improve throughput.
- Autoscale workers based on queue lag and SLOs.
Deduplication strategy:
- Compute content-hash + notification-type + user-id. Use Redis SETNX with TTL (short window, e.g., 5–60s) to atomically ensure one delivery across channels. Router honors the flag.
Per-user rate-limits:
- Token-bucket in Redis; Router checks and decrements atomically; if exhausted, either queue to per-user low-priority queue or drop with logged metric.
Reliability & retries:
- Use durable queues (Kafka + task store).
- Retry with exponential backoff and capped attempts; on permanent failures move to DLQ and optionally send summary email.
- Idempotency: workers use notification-id to avoid duplicate sends.
Trade-offs:
- Strong ordering per-user achieved via Kafka partitioning; increases hot-partition risk for very active users — mitigate by further sharding by user segments.
- Dedup TTL window trades memory for dedup effectiveness; longer TTL prevents repeats but may suppress legitimate re-sends.
- At-least-once delivery simplifies retries but requires idempotent channel clients.
Security and privacy:
- Encrypt messages at rest, use auth between services, respect user notification preferences and GDPR (opt-outs).
This design delivers low-latency for active sessions (direct websocket path), deduplicates across channels, enforces per-user quotas, and provides reliable delivery with retry and DLQ handling.
Design an automated interview-assessment platform that evaluates a candidate's problem-solving communication (text or recorded voice). Define system components, data model, scoring metrics for correctness and communication, UI flows for reviewers, and explain fairness, privacy, and bias mitigation strategies. Provide a deployment and monitoring plan.
Sample Answer
Requirements & constraints:
- Functional: ingest text or recorded voice responses, evaluate correctness + communication, allow human review and feedback, exportable reports.
- Non-functional: scalable to thousands/day, latency per assessment <2 min (automated), privacy compliant (GDPR), auditable and explainable.
High-level architecture:
- Frontend (React): candidate recorder/textarea, reviewer dashboard, admin console.
- API Gateway → Auth (OAuth + mTLS) → Orchestrator service.
- Ingest service: stores raw media in object store (S3) + metadata in Postgres.
- Transcription & NLP pipeline: ASR service (custom or vendor) → punctuation/segmentation → NLU models (intent, semantic similarity, code understanding).
- Automated Scoring Engine:
- Correctness: test-case runner (for code), semantic matcher (BLEU/SBERT cosine) for open answers, rubric classifier.
- Communication: clarity score (fluency, fillers), structure score (logical flow), empathy/professionalism detectors.
- Explainability & Audit: model explanation layer (SHAP-like) + score provenance stored in immutable logs (append-only DB).
- Review UI: side-by-side candidate response, transcript with highlights, suggested scores and rationale, override + comment + vote.
Data model (simplified):
- Candidate(id), Session(id, candidate_id, job_id, timestamp)
- Response(id, session_id, prompt_id, media_url, transcript, language)
- Score(id, response_id, correctness:{score, evidence}, communication:{fluency, structure, tone}, final_score, reviewer_id, timestamps)
- AuditLog(event, actor, before, after)
Scoring metrics:
- Correctness:
- Objective tasks: pass rate of unit tests (0-100).
- Open-ended: semantic similarity via sentence embeddings + rubric classifier; normalized 0-80.
- Penalize hallucination or mismatches with evidence.
- Communication (0-20):
- Fluency (ASR confidence, filler rate), clarity (readability, sentence length), structure (intro/body/conclusion detection), tone (professionalness).
- Combine normalized sub-scores with weights; final = 0-100 composite.
- Confidence & explainability: return per-score confidence intervals and top contributing features.
Reviewer UI flows:
- Triage queue: prioritize low-confidence auto-scores and flagged bias cases.
- Review panel: play audio, edit transcript, view automated highlights (e.g., missed keywords), suggested rubric scores, quick actions (accept, adjust, add comment).
- Batch review: review multiple candidates per prompt, apply rubric templates.
- Calibration: periodic reviewer calibration mode with gold-standard responses and inter-rater agreement metrics.
Fairness, privacy, bias mitigation:
- Data minimization: store minimal PII, encrypt at rest and in transit, configurable retention.
- Differential privacy & k-anonymization for analytics.
- Bias mitigation:
- Use diverse training data across accents, languages, demographics.
- Separate content-correctness from communication scores; avoid penalizing accent/fluency for correctness in code/math tasks.
- Thresholds to route low-confidence/accented audio to human review.
- Periodic fairness audits: measure score disparities (AUC, demographic parity) and retrain with reweighted samples.
- Transparency: provide candidates with score breakdown and appeal workflow.
- Legal: consent capture, data subject rights, vendor assessments for ASR/ML components.
Deployment & monitoring:
- CI/CD: repo pipelines (unit, integration, model validation), blue-green deploys for services, canary for model updates with shadow testing.
- Infra: Kubernetes with autoscaling, S3 for media, Postgres + read replicas, Redis for queues.
- Monitoring:
- System: Prometheus/Grafana for latency, error rates, queue depths.
- ML-specific: data drift detectors, feature distributions, model performance (accuracy, calibration), per-cohort metrics.
- Alerting on SLA breaches, spike in human-review rates, fairness metric regressions.
- Rollback & governance: automated rollback on canary failure, model registry with versioning, approval gates for production promotion.
- Logging & audit: immutable logs, access controls, periodic third-party security reviews.
Trade-offs:
- Latency vs accuracy: heavier ASR/NLU models increase cost/latency — use progressive enhancement (fast model first, heavy re-score asynchronously).
- Explainability vs model complexity: prefer interpretable models for final scores; deep models behind the scenes but expose feature-level explanations.
This design supports scalable automated assessment while ensuring human oversight, privacy, and measurable fairness.
Design a URL shortening service that must support 100 million stored short URLs and 1 billion redirects per day. Provide a high-level architecture: components for short ID generation, storage schema, read/write paths, caching, analytics, and how to handle collisions, custom vanity URLs, and hot redirects. Discuss scaling, sharding, and how to protect against malicious URLs.
Sample Answer
Requirements (clarify):
- Functional: Create short URL -> redirect to long URL; support custom vanity URLs.
- Scale: 100M stored short URLs, 1B redirects/day (~11.6k reqs/sec average, peaks higher).
- Non-functional: low latency redirects (<50ms), high availability, analytics, security (malicious URL protection).
High-level architecture:
Client -> API Layer (write) / CDN+Edge Cache -> Redirect Layer (read) -> Storage (primary DB + cache) -> Async Analytics pipeline -> Admin/Scanner
- Short ID generation
- Use a two-mode generator:
- Auto-generated: Base62-encoded 64-bit or 48-bit ID from a distributed ID service (Snowflake-style or KSUID). Use node prefixes to avoid collisions; encode to Base62 to produce short slugs.
- Vanity/custom: User-specified; validated and reserved first.
- To avoid global coordination, assign ID blocks to service instances (Snowflake or HiLo). Collision risk negligible if node IDs unique.
- Storage schema
- Primary: Sharded key-value store (e.g., DynamoDB/Cassandra) with primary key = short_id (string). Columns: long_url, created_at, owner_id, ttl, redirect_count, safe_scan_status, metadata.
- Secondary index for long_url -> short_id (for deduplication, optional).
- Separate table for vanity mapping and ACLs.
- Read path (redirect):
- DNS -> CDN/Edge (CloudFront/Cloudflare) caching hot short_id -> edge returns 301 to long_url.
- If miss: edge calls Redirect API -> App server checks Redis cache -> if miss, read from KV store -> populate Redis and return redirect.
- Use 1-week TTLs; update cache on writes/edits.
- Write path (create):
- Client -> Write API validates URL (format, rate limits), checks blacklist, optionally deduplicates -> request ID generator -> write to DB -> enqueue safe-url scan and analytics events -> return short_id.
- Caching & hot redirects
- Multi-layer caching: CDN edge -> regional Redis -> primary DB.
- Hot keys: track access frequency; when a key exceeds threshold push to CDN with long TTL and pin in Redis. Use LFU eviction for in-memory caches.
- Serve from CDN to reduce origin load for popular links.
- Analytics
- Emit events to a streaming layer (Kafka). Consumers: Real-time counters (Redis/TSDB), batch aggregation (Spark/Flink) into OLAP store for dashboards.
- Store click logs in append-only storage (S3) for forensic analysis.
- Collisions & consistency
- Auto IDs: avoid collisions via distributed ID generator (unique node id + timestamp + sequence). For defensive programming, on write use conditional put (if not exists). If collision occurs, regenerate ID.
- Vanity: check atomic existence in DB using conditional write; if exists, return conflict.
- Scaling & sharding
- DB: shard by hash(short_id) across multiple partitions; use consistent hashing for rebalancing.
- Redis: clustered; partition by short_id.
- ID service: horizontally scalable; assign node IDs using service registry.
- Autoscale API servers behind load balancers. Use bulkheads and rate limiting per IP/account.
- Protect against malicious URLs
- On write: synchronous lightweight checks (URL pattern, domain blacklist).
- Async deep scan: enqueue URL to a scanner that fetches URL in sandboxed environment, runs malware/phishing detectors, uses third-party threat intel; mark unsafe and disable redirect until reviewed.
- Rate-limit account creations, CAPTCHAs for high-risk clients.
- Provide takedown workflow and remove/redirect to warning page for flagged links.
- Operational concerns & trade-offs
- Prefer KV store for reads to minimize latency; eventual consistency acceptable for analytics and counters.
- Counters: use approximate counters (HyperLogLog or Redis INCR) with background reconciliation to avoid write amplification on DB rows.
- Latency vs consistency: prioritize low-latency redirects; accept slight delay for post-creation scanning.
This design meets scale (1B/day ~ 12k/sec avg; with CDN and caching, origin load manageable), supports vanity URLs, handles hot links via CDN pinning, and defends against malicious content with layered scanning and rate-limiting.
You're assigned to deliver a medium-sized feature independently. Describe step-by-step how you would take it from requirements to production: define scope, estimate effort, communicate with stakeholders, write tests, deploy safely, and measure success. Explain assumptions you make.
Sample Answer
Assumptions: medium feature = ~2–4 weeks work, single engineer, existing service in Python/React, CI/CD and staging environment available, Product/Design stakeholders assigned, user analytics and error monitoring in place.
- Clarify scope (days 0–1)
- Meet PM/designer to capture acceptance criteria, user flows, edge cases; write 3–5 concrete acceptance tests (behavioral).
- Create a short spec (one-pager) listing in-scope vs out-of-scope items and success metrics (usage, error rate, performance).
- Break down & estimate (day 1)
- Decompose into tasks: API design, DB changes, backend logic, frontend UI, tests, docs, deploy.
- Estimate each task with RICE-style confidence (e.g., 2–8h tasks) and add 20% buffer. Share estimates with PM.
- Communication plan (ongoing)
- Daily standups + async updates in ticket comments. Weekly sync with PM/designer if scope changes.
- PRs with clear descriptions, screenshots, and labeling for review; request reviews early for unclear areas.
- Implementation & tests
- Follow TDD where practical: unit tests for logic, integration tests for API, E2E for critical user flows. Add feature flags for rollout.
- Write migration scripts and DB rollback plan if applicable.
- Safe deployment
- Deploy to staging, run automated test suite, manual exploratory testing.
- Canary behind feature flag: enable for internal users → small % of traffic → full rollout if metrics stable.
- Monitor logs, errors (Sentry), and performance (APM) during rollout; have rollback plan.
- Measure success (post-deploy, 1–2 weeks)
- Track acceptance criteria and success metrics: adoption rate, conversion, error rate, latency.
- Share results with stakeholders; iterate on feedback or roll back if negative impact.
Result: structured, low-risk delivery with measurable outcomes and clear stakeholder alignment.
Unlock Full Question Bank
Get access to all 11 End-to-End Feature Design and Development interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.