Monday, July 27, 2026

Spec‑Driven Development

 

πŸ”΅ What Spec‑Driven Development actually is

Spec‑Driven Development is a development methodology where:

  • You write a detailed spec first

  • The spec defines behavior, interfaces, and acceptance criteria

  • Implementation strictly follows the spec

  • Tests are derived from the spec

  • The spec becomes the contract

It’s closer to:

  • TDD (Test‑Driven Development)

  • BDD (Behavior‑Driven Development)

  • API‑first development

But with more emphasis on formal specification.

Here’s exactly how we use it.

⭐ 1. We start with a spec, not code

Every feature, improvement, or change begins with a spec document — not a PR, not a prototype, not a meeting.

Our spec includes:

  • Problem statement

  • Customer scenario

  • Constraints (latency, cost, reliability, compliance)

  • Success metrics

  • Failure modes

  • Open questions

  • Design options

  • Recommended approach

This ensures everyone understands why we’re building something before discussing how.

⭐ 2. AI helps generate the first-pass spec

This is where your team is ahead of most engineering orgs.

Instead of starting from a blank page, we use AI to produce a first-pass spec draft based on:

  • Product requirements

  • Customer feedback

  • Existing architecture

  • Known constraints

  • Historical issues

Example from our workflow:

We fed AI a requirement like:

“Improve search latency for new users.”

AI generated a structured spec draft including:

  • Hot paths to investigate

  • Suggested caching strategies

  • Proposed SLO targets

  • Integration points

  • Edge cases

  • Risks and trade-offs

We didn’t accept it blindly — but it gave us a strong starting point.

⭐ 3. We refine the spec collaboratively

Engineers, PMs, and sometimes designers refine the AI-generated spec.

We clarify:

  • What’s in scope

  • What’s out of scope

  • What assumptions are wrong

  • What constraints matter most

  • What trade-offs we’re willing to accept

This step transforms the spec from “AI-generated text” into a team-owned engineering contract.

⭐ 4. We break the spec into structured tasks 

Once the spec is approved, we convert it into structured, atomic tasks inside the repo.

Each task includes:

  • Description

  • Acceptance criteria

  • Dependencies

  • Priority

  • Due date

  • Owner

  • Links back to the spec

Example:

From the search latency spec, AI helped generate tasks like:

  • Add tracing to search pipeline

  • Identify slowest percentile queries

  • Propose caching layer for onboarding flow

  • Add metrics for cold-start latency

  • Validate improvements against SLO targets

This is where Spec‑Driven Development becomes execution-ready.

⭐ 5. AI assists with implementation scaffolding

AI doesn’t write the final code — but it accelerates the boring parts.

Examples from your team:

  • Generating test scaffolding

  • Drafting PR descriptions

  • Suggesting integration test cases

  • Creating initial API contract stubs

  • Summarizing large diffs for reviewers

This keeps engineers focused on architecture, correctness, and reliability.

⭐ 6. The spec becomes the single source of truth

During implementation, the spec is the reference for:

  • Design decisions

  • Edge-case handling

  • Testing strategy

  • Acceptance criteria

  • Cross-team alignment

If something changes, we update the spec — not just the code.

This prevents “tribal knowledge” and keeps the project maintainable.

⭐ 7. We validate the implementation against the spec

Before closing a feature, we check:

  • Did we meet the constraints?

  • Did we solve the customer problem?

  • Did we hit the success metrics?

  • Did we address failure modes?

  • Did we follow the recommended design?

This is the “spec-driven” part — the spec guides the validation, not just the code.

⭐ 8. We use the spec for retros, onboarding, and future work

Specs become:

  • Documentation

  • Onboarding material

  • Architecture references

  • Future iteration guides

  • Lessons learned

This is why your team moves fast without losing clarity — the spec is a living artifact.

πŸ”΅ Why Spec‑Driven Development works so well for our team

✔ It reduces ambiguity

No more “What exactly are we building?”

✔ It aligns engineering + product

Everyone sees the same blueprint.

✔ It accelerates design

AI gives us a strong starting point.

✔ It improves execution

Tasks are structured, scoped, and measurable.

✔ It increases reliability

Failure modes and constraints are defined early.

✔ It scales across teams

Specs are readable, shareable, and reviewable.

Sunday, July 5, 2026

My linkedln posts

 


1. Distributed systems lessons I wish I learned earlier

There are a few distributed systems lessons I wish I learned much earlier in my career. They would’ve saved me countless outages, late‑night incidents, and “why is this happening” moments.

Here are the big ones:

1. The network is always the bottleneck. 2. Everything fails eventually. 3. Consistency is a tax. 4. Latency is a feature. 5. Observability is not optional.

Distributed systems aren’t about complexity. They’re about humility.

The sooner you accept that the system will misbehave, the better you’ll design it.

Primary hashtags: #DistributedSystems #SystemDesign #SoftwareEngineering #Scalability #TechLeadership

Boost hashtags: #CloudNative #BackendEngineering #HighAvailability #SRE #TechCareers

πŸ”₯ 2. How to design systems that survive failure

The real test of a system isn’t how it behaves when things go right — it’s how it behaves when everything goes wrong.

Here’s how I design systems that survive failure:

1. Assume every dependency will fail. 2. Build graceful degradation paths. 3. Add timeouts everywhere. 4. Retry with backoff, not brute force. 5. Make failure visible.

Resilience isn’t an add‑on. It’s a mindset.

Systems don’t need to be perfect. They need to be prepared.

Primary hashtags: #ResilienceEngineering #SystemDesign #SRE #DistributedSystems #TechLeadership

Boost hashtags: #CloudArchitecture #DevOpsCulture #HighAvailability #EngineeringBestPractices

πŸ”₯ 3. Why simplicity is the ultimate architecture

The longer I’ve been an engineer, the more I’ve realized one truth:

Simplicity is the ultimate architecture.

Simple systems:

  • Fail less

  • Scale better

  • Are easier to debug

  • Age gracefully

Complex systems:

  • Fail in weird ways

  • Require tribal knowledge

  • Slow teams down

The best architects weren’t the ones who drew the most boxes — they were the ones who removed the most.

Simplicity isn’t the absence of features. It’s the absence of unnecessary friction.

Primary hashtags: #Architecture #EngineeringLeadership #SoftwareEngineering #Simplicity #TechCulture

Boost hashtags: #CleanCode #DesignPrinciples #TechStrategy #DeveloperExperience

πŸ”₯ 4. How to scale a service from 1k to 1M users

Scaling from 1k to 1M users isn’t magic — it’s discipline.

1. Measure everything. 2. Cache aggressively. 3. Reduce synchronous calls. 4. Split hot paths from cold paths. 5. Optimize for the 99th percentile. 6. Automate recovery.

Scaling isn’t about servers. It’s about strategy.

Primary hashtags: #Scalability #HighPerformanceSystems #CloudNative #DistributedSystems #BackendEngineering

Boost hashtags: #SystemDesign #TechLeadership #PerformanceEngineering #DevOps

πŸ”₯ 5. The trade-offs behind microservices nobody talks about

Microservices are powerful — but the trade-offs are real.

1. You trade simplicity for autonomy. 2. You trade local bugs for distributed bugs. 3. You trade single deployments for orchestration complexity. 4. You trade monolithic performance for network latency. 5. You trade shared ownership for fragmented accountability.

Microservices aren’t bad. They’re just expensive. Choose them intentionally.

Primary hashtags: #Microservices #Architecture #SystemDesign #SoftwareEngineering #TechLeadership

Boost hashtags: #CloudArchitecture #DistributedSystems #DevOpsCulture #EngineeringBestPractices

πŸ”₯ 6. Caching strategies that actually work in production

Caching looks simple until you run it in production.

1. Cache the result, not the object. 2. Use TTLs that match business reality. 3. Cache at the edge whenever possible. 4. Bust caches intentionally. 5. Monitor cache hit ratios.

Caching isn’t a performance hack. It’s a design decision.

Primary hashtags: #Caching #PerformanceEngineering #BackendEngineering #DistributedSystems #Scalability

Boost hashtags: #SystemDesign #CloudNative #HighPerformanceSystems #TechLeadership

πŸ”₯ 7. What I learned after applying to 100+ roles

After applying to 100+ roles, here’s what I learned:

1. Your resume matters less than your narrative. 2. Recruiters respond to momentum. 3. Referrals outperform applications by 10x. 4. You need a system, not hope. 5. Rejection is not feedback — conversations are.

Job searching is a skill. And like any skill, it gets better with structure.

Primary hashtags: #JobSearch #CareerGrowth #TechCareers #SoftwareEngineering #JobHunt

Boost hashtags: #CareerAdvice #InterviewTips #LinkedInTips #VancouverTech

πŸ”₯ 8. The truth about technical interviews in 2026

Technical interviews in 2026 have changed.

1. AI hasn’t replaced interviews — it’s raised the bar. 2. System design is now the real differentiator. 3. Communication matters more than correctness. 4. Companies want engineers who can reason. 5. Collaboration beats performance.

Interviews aren’t harder. They’re just different.

Primary hashtags: #TechInterviews #SoftwareEngineering #CareerGrowth #SystemDesign #TechCareers

Boost hashtags: #InterviewPreparation #EngineeringLeadership #AIInTech #VancouverTech

πŸ”₯ 9. How I track my job applications (with a custom dashboard)

One of the biggest unlocks in my job search was building my own job application dashboard.

It tracks:

  • Stage

  • Due date

  • Next action

  • Recruiter

  • Follow-ups

  • Notes

Why it works:

  • It removes chaos

  • It creates momentum

  • It makes follow-ups effortless

  • It turns job searching into a system

If you’re job searching, build a dashboard. Your future self will thank you.

Primary hashtags: #JobSearch #Productivity #CareerGrowth #TechCareers #SoftwareEngineering

Boost hashtags: #DashboardDesign #OrganizationTips #VancouverTech #LinkedInTips

πŸ”₯ 10. Why rejection is data, not failure

Rejection used to feel personal. Now it feels like data.

1. Every rejection tells you something about the market. 2. Every rejection sharpens your narrative. 3. Every rejection improves your targeting. 4. Every rejection builds resilience.

Rejection isn’t failure. It’s feedback. And feedback is fuel.

Primary hashtags: #CareerGrowth #Mindset #JobSearch #TechCareers #Resilience

Boost hashtags: #Motivation #ProfessionalDevelopment #VancouverTech #CareerAdvice



One of the most meaningful engineering shifts I’ve experienced recently was integrating AI directly into our GSD (Get Stuff Done) project. Not as a bolt‑on feature. Not as a “cool demo.” But as a core engineering capability.

Here’s what AI actually enabled for us:

1. Turning vague requirements into actionable tasks We used AI to break down high‑level product ideas into structured, prioritized work items. No more guessing. No more misalignment. Just clarity.

2. Automating the “glue work” engineers usually hate AI handled:

  • Drafting PR descriptions

  • Generating test scaffolding

  • Suggesting edge cases

  • Creating initial API contracts This freed us to focus on architecture, reliability, and customer impact.

3. Making system design faster — and better We used AI to explore alternative designs, compare trade-offs, and validate assumptions. It didn’t replace our judgment. It amplified it.

4. Improving developer experience inside the repo AI became part of the workflow:

  • Inline code suggestions

  • Automated documentation updates

  • Intelligent linting

  • Real-time reasoning about code changes The repo became a place where engineers could move faster without sacrificing quality.

5. Creating a feedback loop between engineering and product AI helped us map customer pain → engineering tasks → measurable outcomes. It made the team more customer‑obsessed, not less.

The biggest lesson?

AI didn’t make us better engineers. It made us more effective engineers.

The GSD repo wasn’t an AI experiment. It was proof that AI can be a force multiplier when it’s embedded into the engineering process — not slapped on top of it.

And this is just the beginning.

#AI #SoftwareEngineering #DeveloperExperience #SystemDesign #TechLeadership #Productivity #VancouverTech #EngineeringCulture In our GSD workflow, AI didn’t replace any engineer — but it did replace hours of repetitive work. For example, instead of manually drafting PR descriptions or writing boilerplate tests, AI generated the first pass. We still reviewed everything, but the time savings were massive. It let us focus on architecture, reliability, and customer impact — the things AI can’t do. 
Once we started writing prompts like design docs — with constraints, context, and trade-offs — the quality jumped.“Latency must be under 200ms.”“Cost must stay under X.”“No new dependencies.”AI thrives when the boundaries are clear.Constraint thinking is the new engineering superpower. AI generated scaffolding, tests, documentation, and alternative designs. It felt less like automation and more like having a junior engineer who works at superhuman speed



One of the most meaningful engineering shifts I’ve experienced recently was integrating AI directly into our GSD (Get Stuff Done) project. Not as a bolt‑on feature. Not as a “cool demo.” But as a core engineering capability that changed how we design, plan, and execute work.

Here’s what AI actually enabled for us — with real examples from the repo:

1. Turning vague requirements into actionable tasks

We often start with high‑level product ideas like: “Improve onboarding flow” or “Optimize search relevance.”

Before GSD, this meant long meetings, clarifications, and manual breakdowns.

With AI, we fed the requirement into our workflow and got back a structured task breakdown:

  • User scenarios

  • Edge cases

  • Dependencies

  • API touchpoints

  • Suggested acceptance criteria

Example: AI took a vague requirement — “Improve search latency” — and produced a first-pass breakdown including:

  • Identify slowest query paths

  • Add tracing to search pipeline

  • Propose caching layer options

  • Suggest percentile-based SLO targets

We still refined it, but the clarity boost was huge.

2. Automating the “glue work” engineers usually hate

AI handled the repetitive but necessary engineering tasks that slow teams down.

Examples from GSD:

  • Drafting PR descriptions based on diffs

  • Generating initial unit test scaffolding

  • Suggesting integration test cases

  • Creating API contract stubs

  • Writing first-pass documentation updates

This wasn’t about replacing engineers — it was about removing friction.

3. Making system design faster — and better

When we explored new features, AI generated multiple architecture options for us to evaluate.

Example: For a new service integration, AI proposed three designs:

  • A synchronous API call path

  • An event-driven queue-based path

  • A hybrid model with caching + async fallback

We didn’t blindly accept any of them. But reviewing them helped us surface trade-offs faster.

AI didn’t design the system. It accelerated our thinking.

4. Improving developer experience inside the repo

AI became part of the repo’s workflow itself.

Examples:

  • Inline suggestions for refactoring

  • Auto-generated comments explaining complex logic

  • Intelligent linting based on project patterns

  • Summaries of large PRs for faster reviews

Engineers spent less time deciphering context and more time making decisions.

5. Creating a feedback loop between engineering and product

AI helped us map customer pain → engineering tasks → measurable outcomes.

Example: For onboarding friction, AI analyzed user feedback and produced:

  • A list of top pain points

  • Suggested UX improvements

  • Technical tasks tied to each pain point

  • Metrics to track improvement

This made our team more customer‑obsessed, not less.

πŸ”΅ The biggest lesson?

AI didn’t make us better engineers. It made us more effective engineers.

The GSD repo wasn’t an AI experiment. It was proof that AI can be a force multiplier when it’s embedded into the engineering process — not slapped on top of it.

And this is just the beginning.

#AI #SoftwareEngineering #DeveloperExperience #SystemDesign #TechLeadership #Productivity #VancouverTech #EngineeringCulture

Spec‑Driven Development is a development methodology where:

  • You write a detailed spec first

  • The spec defines behavior, interfaces, and acceptance criteria

  • Implementation strictly follows the spec

  • Tests are derived from the spec

  • The spec becomes the contract

It’s closer to:

  • TDD (Test‑Driven Development)

  • BDD (Behavior‑Driven Development)

  • API‑first development

But with more emphasis on formal specification.

Structured Design Docs — a Microsoft‑style engineering practice focused on:

  • Customer problem definition

  • Constraints

  • Multiple design options

  • Trade‑off analysis

  • Failure modes

  • North Star outcomes

  • Alignment across PM + Eng + Leadership

It’s essentially a thinking framework that forces clarity before implementation.

Saturday, June 13, 2026

Interview Preparation

 1️⃣ NeetCode (https://neetcode.io) – The Ultimate DSA Question Bank

Recognizing problem-solving patterns is key to acing interviews. NeetCode nails it with well-structured topics and video solutions.

2️⃣ Aditya Verma (YouTube) – The Dynamic Programming Guru
If DP feels like a black box, his playlists are your flashlight:
πŸ”Ή Dynamic Programming: https://lnkd.in/dWPNDCze
πŸ”Ή Recursion: https://lnkd.in/dHtZvKmm
πŸ”Ή Stacks: https://lnkd.in/dntYkAxV
πŸ”Ή Binary Search: https://lnkd.in/dGUB644J
πŸ”Ή Sliding Window: https://lnkd.in/dkbPtXmQ


3️⃣ Striver’s Graph Series – FAANG-Level Graphs, Demystified
πŸŽ₯ Graph Playlist: https://lnkd.in/dWS93mNq
One of the best visual breakdowns of graph concepts I’ve ever seen.


4️⃣ FreeCodeCamp (https://lnkd.in/drE_WNxx) – For Dev Skills on Demand
Anytime I wanted to explore a new dev topic in detail, FreeCodeCamp had my back.


5️⃣ C++ Basics
For language fundamentals:
• W3Schools: https://lnkd.in/dh4rC78h
• GeeksforGeeks: https://lnkd.in/dnYcn5Fh


6️⃣ System Design (ByteByteGo) – Next-Level Prep
Check out this gem: https://lnkd.in/djX6_tHm


7️⃣ Core CS Topics – InterviewBit Sheets
These were my go-to for last-minute prep:
OOPS: https://lnkd.in/dC7nzATy
DBMS: https://lnkd.in/dp8F_X42
CN: https://lnkd.in/dwkgz4mz
OS: https://lnkd.in/dvCtEXMw

Saturday, June 6, 2026

Ravi' leetcode questions

 1. https://leetcode.com/problems/merge-sorted-array/ 

2. https://leetcode.com/problems/daily-temperatures/ 

3. https://leetcode.com/problems/longest-consecutive-sequence/

4. https://leetcode.com/problems/two-sum

5.https://leetcode.com/problems/longest-substring-without-repeating-characters/

6. https://leetcode.com/problems/palindromic-substrings

7. https://leetcode.com/problems/longest-palindromic-substring

8. https://leetcode.com/problems/clone-graph

Dynamic programming k liye isse accha koi bhi nhi 

https://youtu.be/nqowUJzG-iM?si=3Ez1-q2qn7TOIrRe

Palindromic subsequence problem ka special case hai ye number 6 problem.

Longest common subsequence is root problem of all questions

https://youtu.be/4dMlCZTONj8?si=_iReKEsA4OyI8aMc


Wednesday, June 3, 2026

Design questions - Ritesh

leetcode number 
linked list, 328

binary search, 34

string, 151

backtracking, 17

siding window, 3

hash table, 146

 
1. Design a Rate Limiter Every company covered this.

Know: Sliding window algorithms, Redis, race condition handling, token bucket vs. leaky bucket models.


2. Design a Chat Application A WhatsApp-style typing indicator alone can drive a 45-minute discussion.

Know: WebSockets, Redis Pub/Sub, message queues, offline message delivery.


3. Design a URL Shortener Appears straightforward. Becomes complex quickly.

Know: Base62 encoding, collision resolution, analytics tracking, Redis-based caching.


4. Design a Notification System

Know: Push vs. pull architecture, Kafka for asynchronous delivery, retry mechanisms, user preference management.


5. Design a Payment System JPMorgan asked this. So did multiple others.

Know: Idempotency keys, Saga pattern, ACID transactions vs. eventual consistency.


6. Design an API Rate Limiter Different from #1. This focuses on distributed system design.

Know: Token bucket algorithms, Redis INCR, Lua scripting, multi-node coordination.


7. Design a Video Streaming Platform

Know: CDN architecture, chunked uploads, adaptive bitrate streaming, large-scale storage systems.


8. Design a Ride-Hailing Application

Know: Real-time location tracking, matching algorithms, surge pricing strategies, live event processing.


9. Design an E-commerce Checkout System

Know: Inventory reservation, flash-sale scalability, payment retry workflows, order state management.


10. Design a Search Autocomplete System

Know: Trie data structures, frequency-based ranking, result caching, sub-100ms latency optimization.


- ⁠How do you train LLMs

- ⁠⁠Why LLM is decoder only architecture

- ⁠Sampling in LLM

- ⁠Providing Context to LLM (needle in haystack problem)

- ⁠LLM Evaluation

- ⁠MCPs/Skills/Workflows/Agents/Plugin in LLM - Design / Implement

- ⁠Prompt Engineering / Guided Genaration

- LLM Inference

- ⁠⁠Preference alignment in LLM

- ⁠(Optional) Jail break in LLMs/Claude Mythos


AI related design 

- Design a document intelligence platform for alternative investment documents.Design a RAG system for financial advisors with source-grounded answers.

Design an agent that automates operations workflows but requires human approval for risky actions.

Design an eval platform for LLM prompts, models, and tools.

Design a model-monitoring system for production AI.

Design cost/latency routing across GPT/Claude/open-source models.

Design a secure AI platform for PII-heavy financial documents.

Design a system to compare OCR + LLM extraction accuracy across vendors.

Design a rollout plan for an AI assistant used by internal operations teams.

Design prompt/model versioning and rollback for production AI workflows.


1. How you train LLMs


Beginner: An LLM is just a next-token predictor. You show it enormous amounts of text and nudge its weights so it gets better at guessing the next word. That’s it at the core.


The three stages:


1. Pretraining — self-supervised next-token prediction over a huge corpus (web, books, code). The model learns grammar, facts, and reasoning patterns. This is the expensive part (thousands of GPUs, millions of dollars). The output is a base model: great at continuing text, bad at following instructions.

2. Supervised fine-tuning (SFT / instruction tuning) — train on curated (instruction, ideal-response) pairs so it behaves like a helpful assistant instead of an autocomplete.

3. Preference alignment — shape outputs toward human preferences (helpful, honest, harmless). Covered in topic 9.


Senior depth: The loss is cross-entropy on the next token. Data quality and mixture matter as much as quantity (dedup, filtering, balancing code vs prose). Scaling laws (Chinchilla) tell you the compute-optimal balance of parameters vs training tokens — more isn’t always better, it’s about the ratio. Tokenization (usually byte-pair encoding) determines how text is chopped into units. Context length is a training-time choice with cost implications. You can also do continued pretraining to adapt a base model to a domain.


Interview tie-in: The classic follow-up is “fine-tune or RAG?” Rule of thumb: RAG for knowledge that’s fresh, private, or changes often; fine-tuning for behavior — format, tone, domain style, structured output. For most RAG systems you don’t fine-tune the base model at all. Saying that confidently signals maturity (and avoids the “over-engineering” pitfall on your list).


2. Why LLMs are decoder-only


Beginner: The original Transformer had two halves — an encoder (reads/understands) and a decoder (generates). That spawned three families: encoder-only (BERT, for understanding/classification), decoder-only (GPT-style, for generation), and encoder-decoder (T5, for translation-style tasks).


Why decoder-only won for general LLMs:


One simple objective that scales: next-token prediction. Any task — translation, Q&A, summarization, coding — can be cast as “continue this text,” so you don’t need task-specific architectures.

Causal (autoregressive) attention: each token attends only to tokens before it, which is exactly what generation needs.

In-context learning emerges: a big enough decoder-only model can do a new task just from examples in the prompt, no retraining. This is the entire foundation of prompting and RAG.


Senior depth: Causal masking means past tokens never need recomputing, which enables clean KV caching (topic 8) and efficient generation. Encoder-decoder models still win for some pure seq2seq tasks, but decoder-only generalizes via prompting, so it scaled better and became the default. The deep point for your interview: because everything is text-to-text, RAG is just “paste the retrieved text into the prompt.” That’s why it works at all.


9. Preference alignment (covering it here, near training)


Beginner: SFT makes a model follow instructions, but you also want it to prefer good answers over bad ones. Alignment teaches that preference.


RLHF (Reinforcement Learning from Human Feedback):


1. Start with the SFT model.

2. Collect human comparisons (given two answers, which is better?) and train a reward model to predict that preference.

3. Optimize the model (policy) with RL — typically PPO — to maximize reward, with a KL penalty that keeps it from drifting too far from the SFT model.


DPO (Direct Preference Optimization): Skips the separate reward model and RL loop — it optimizes directly on preference pairs with a classification-style loss. Simpler, more stable, very popular now.


Other variants: RLAIF / Constitutional AI (Anthropic’s approach) uses an AI to generate preference labels against a written set of principles, reducing the human-labeling bottleneck.


Senior depth: The big failure modes are reward hacking (the model games the reward model), over-optimization (the KL constraint exists to prevent this), and sycophancy (telling users what they want to hear). There’s an inherent helpful-vs-harmless tension.


Interview tie-in: Usually you consume an already-aligned model, so the relevant question is “how do we get the model to follow our policies / refuse our disallowed requests?” — which is partly alignment and partly system design (guardrails, prompts). You can also do lightweight preference tuning on your own task data.


3. Sampling


Beginner: At each step the model outputs a probability distribution over the next token. Sampling is how you pick one.


The controls:


Greedy — always take the most likely token. Deterministic but repetitive and dull.

Temperature — scales the distribution. Low temp → sharper, more deterministic; high temp → flatter, more random/creative. Temp 0 ≈ greedy.

Top-k — sample only from the k most likely tokens.

Top-p (nucleus) — sample from the smallest set whose cumulative probability ≥ p.

Repetition / frequency / presence penalties — discourage repeating tokens.

Beam search — keeps several candidate sequences; more for translation/seq2seq than open-ended chat.


Senior depth: Even at temperature 0 you’re not guaranteed bit-for-bit reproducibility (floating-point and batching effects). Self-consistency is a useful trick: sample several reasoning chains and take the majority answer. Constrained/structured decoding (topic 7) overlaps here.


Interview tie-in: For a RAG or extraction system you want low temperature — you’re after faithful, grounded, reproducible answers, not creativity. Stating “I’d run generation at low/zero temperature to reduce hallucination” is a clean, correct design choice.


8. LLM inference


Beginner: Inference is running the trained model to generate text (as opposed to training, which updates weights). This is where most of your production cost and latency live.


Two phases:


Prefill — process the entire prompt in parallel, producing the first token and the KV cache. Compute-bound.

Decode — generate tokens one at a time, each reusing the cache. Memory-bandwidth-bound.


Key concepts and levers:


KV cache — stored key/value vectors for past tokens so they aren’t recomputed. It grows with sequence length × layers × batch size, so it’s a major memory consumer and the reason long contexts get expensive.

Latency metrics — TTFT (time to first token), inter-token latency, and throughput (tokens/sec). These trade off against each other.

Batching — continuous/in-flight batching (e.g., vLLM) keeps the GPU busy across many requests.

Quantization — running weights at INT8/INT4 instead of FP16 to shrink memory and cost.

Speculative decoding — a small “draft” model proposes tokens, the big model verifies them in parallel; speeds up decode.

Prefix caching — reuse the KV cache for a shared prompt prefix across requests. This is huge for RAG, where you have a big fixed system prompt every call.


Interview tie-in: Cost is roughly proportional to tokens (input + output), and context length drives KV-cache memory. Expect questions like “how do you cut latency/cost?” Good answers: prefix-cache the system prompt, cap output length, retrieve fewer/better chunks instead of stuffing, use a smaller model for easy queries (routing), batch requests.


4. Providing context / RAG / needle-in-a-haystack


This is the heart of your interview, so it gets the most space.


Beginner: A model only “knows” two things: what’s frozen in its weights (training data, with a cutoff) and what’s in the current prompt. To give it fresh, private, or company-specific knowledge, you put that knowledge in the prompt. RAG automates finding the right knowledge to insert.


The RAG pipeline (maps directly to their loop):


Ingest/index — split documents into chunks, convert each chunk into an embedding (a vector capturing meaning), store in a vector database.

Retrieve — embed the user’s query, find the nearest chunks (semantic search), often combined with keyword search, then rerank to keep the best few.

Reason — put the top chunks + the question into a prompt; the model answers grounded in them, ideally with citations.


The needle-in-a-haystack problem: A test where you hide one specific fact (the needle) inside a very long context (the haystack) and ask the model to find it. The well-known result is “lost in the middle” — models reliably use information at the start and end of the context but degrade in the middle. The implication is critical: even with million-token context windows, dumping everything in is unreliable. Good retrieval plus smart ordering (put the most important chunk first or last) beats brute-force stuffing — and it’s cheaper and faster.


Senior depth — this is where you win the interview:


Chunking strategy — size and overlap matter. Too large adds noise and cost; too small loses context. Prefer semantic/structure-aware chunking over fixed character counts.

Hybrid search — dense (embeddings, for meaning) + sparse (BM25/keyword, for exact terms like error codes, names, IDs). Each covers the other’s blind spot.

Reranking — a cross-encoder reorders the initial candidates for much better precision before they hit the prompt.

Query transformation — rewrite vague queries, decompose multi-part questions, or use techniques like multi-query / HyDE to improve recall.

Metadata filtering — filter by date, source, and especially permissions/access control (so users only retrieve what they’re allowed to see — a privacy point interviewers love).

Context-budget management — under a token limit you must allocate space across system prompt, retrieved chunks, conversation history, and the output. Techniques: rank, truncate, dedupe, compress/summarize.

Grounding & citations — instruct the model to answer only from retrieved context, cite sources, and say “I don’t know” when the answer isn’t there. This is your main hallucination defense.

Failure modes — retrieval miss (right doc never retrieved), distractors, conflicting sources, stale index.


Interview tie-in (their Copilot hint): For an AI coding tool, “context gathering” = the open file, imported/related files, symbols, and repo structure; the codebase is the haystack. RAG over code (plus the cursor’s local context) is exactly this pattern.


7. Prompt engineering / guided generation


Beginner: The prompt is your main steering wheel for a frozen model. How you ask changes what you get.


Core techniques:


Clear instructions, a role/system prompt, explicit output format, and delimiters around inputs.

Zero-shot vs few-shot — adding examples in the prompt (in-context learning).

Chain-of-thought — “think step by step” for reasoning tasks (newer reasoning models do this internally).

ReAct — interleave reasoning with tool calls (reason → act → observe).


Guided / constrained generation: When a downstream system needs parseable output (JSON, a specific schema), you don’t want to hope the model complies — you constrain it. Grammar/schema-constrained decoding only allows tokens that keep the output valid against a grammar. In practice this shows up as function-calling / tool-use APIs, JSON mode, or libraries that enforce a schema. This guarantees structure instead of relying on luck.


Senior depth: Treat prompts as code — version them, test them, and run evals, because a model upgrade or prompt tweak can silently cause regressions. Watch token cost (few-shot examples aren’t free). And critically, retrieved/untrusted content in the prompt can contain malicious instructions (prompt injection — topic 10).


Interview tie-in: In RAG, the prompt template — “answer only from the context below, cite the source, respond ‘not found’ if absent” — is your primary grounding mechanism. Guided generation matters when the system must emit structured output (e.g., a config patch or a JSON action).


6. MCP / Skills / Workflows / Agents / Plugins


This layer is about extending an LLM from “writes text” to “does things.” Define each clearly — interviewers test whether you can distinguish them.


Tools / function calling — you give the model a set of functions with schemas; it decides when to call one; you execute it and feed the result back. This is the foundation under everything else.

Plugins — an older term (e.g., ChatGPT plugins): packaged tools the model can call, usually via an API spec.

MCP (Model Context Protocol) — an open standard for connecting models to external tools and data through a uniform interface. Instead of building a bespoke integration per app, an MCP server exposes its tools/resources in a standard way that any MCP-compatible host can use. Think “USB-C for tool integrations” — it decouples tool providers from model providers.

Skills — packaged, reusable units of capability (instructions + sometimes code/scripts) that an agent loads only when relevant — progressive disclosure to save context (e.g., a “build a PowerPoint” skill loaded only for slide tasks).

Workflows — you design a fixed sequence of LLM + tool steps. The control flow is predetermined; the model fills in the steps.

Agents — the model decides the steps: it plans, picks tools, observes results, and loops until the goal is met. More autonomous, less predictable.


The senior distinction (workflows vs agents): Workflows are predictable, testable, debuggable, and cheaper — use them when the task is well-understood and decomposable. Agents are flexible and handle open-ended tasks but are harder to control and evaluate, more expensive, and can loop or fail surprisingly. The standard guidance (and a direct hit on your “over-engineering” pitfall): start simple — single prompt → add retrieval → add tools → workflow → reach for a full agent only when flexibility genuinely requires it. Common patterns to name-drop: prompt chaining, routing, parallelization, orchestrator-workers, evaluator-optimizer.


Senior depth: Tool design needs clear schemas, error handling, and human-in-the-loop approval for risky/side-effecting actions. Add tracing/observability, retries, timeouts, and a cap on iterations for cost. Agents that act need permission scoping and sandboxing.


Interview tie-in: For a coding tool, the agent decides which files to read, runs the linter/tests (tools), reads the errors, and iterates — while predictable steps (“always run tests after an edit”) stay as a fixed workflow. This is the “LLM as Actor” and “Validation” themes on your list.


5. LLM evaluation


Beginner: You can’t ship on vibes — you need to measure whether the system is actually good, and catch regressions.


For RAG specifically, evaluate two stages:


Retrieval — recall@k, precision@k, MRR, NDCG (did the right chunks get retrieved, and ranked well?).

Generation — faithfulness/groundedness (is the answer supported by the retrieved context?), answer relevance, completeness.


Methods:


Reference-based — exact match, F1, or older overlap metrics (BLEU/ROUGE) against gold answers.

LLM-as-judge — a strong model grades outputs against a rubric. Scalable but biased (position bias, verbosity bias, self-preference); mitigate with pairwise comparison, clear rubrics, and calibration against human labels.

Human eval — gold standard, expensive, used for a sample.

Cheap objective validators — does the code compile? do tests pass? is the JSON valid? These are perfect for the “Validate” loop.


Senior depth: Build a golden eval set early from real queries and grow it from observed failures. Separate offline eval (pre-deploy) from online eval (A/B tests, thumbs up/down, and implicit signals like suggestion-acceptance rate for a coding tool). Run regression tests so a model/prompt change doesn’t silently break things, and include guardrail evals for safety, PII leakage, and injection resistance.


Interview tie-in: This is the “Validate” + “Learn” stages, and explicitly a “key habit of strong candidates.” For a coding tool: % of suggestions accepted, % that compile, % that pass tests.


10. Jailbreaks / adversarial robustness (optional)


I’ll treat this as the safety and security design topic — I won’t cover techniques for actually bypassing safeguards, but the defensive framing is exactly what an interviewer wants under “Safety & Operations.”


Beginner: Aligned models refuse harmful requests. Jailbreaking is adversarial prompting that tries to get a model to violate its own safety policy. The closely related and arguably bigger system risk is prompt injection — untrusted input (a web page, a retrieved document, a tool’s output) contains instructions that hijack the model’s behavior. In RAG and agents this is especially dangerous because retrieved content and tool results get fed back into the prompt (this is “indirect prompt injection”).


Design-level defenses to cite:


Input/output moderation classifiers.

Keep trusted instructions (system prompt) separate from untrusted data, and never let retrieved content be treated as instructions (delimit/“spotlight” it).

Least privilege for tools, human-in-the-loop for high-risk actions, and sandboxing.

Validate outputs before acting on them (critical for agents).

Red-teaming and adversarial evals, with defense in depth — no single layer is enough.


Interview tie-in: Mentioning indirect prompt injection via retrieved docs in a RAG/agent design is a strong maturity signal.

Spec‑Driven Development

  πŸ”΅ What Spec‑Driven Development actually is Spec‑Driven Development is a development methodology where: You write a detailed spec first T...