 Command

Pranesh Nikhar's personal site. Vim-style keybinds for navigation; theme + font pickers below.

Theme
 Font Body Code
Reader
Keybinds
Navigation
j / ↓ Next item k / ↑ Previous item g First item in region G Last item in region zz Center focused item h / l Move left/right region ] / [ Next/previous heading } / { Next/previous block d / u Half-page down/up
Layout
<zh> / <zl> Toggle left/right sidebar <zr> Toggle reader view <zj> / <zk> Focus main/navbar <S-h/j/k/l> Focus left/main/navbar/right ⌃H / ⌃L Focus left/right sidebar ⌃J / ⌃K Focus main/navbar ⇧C / ⇧E Collapse / expand all sections
Dialogs
⌃P / : Command palette ⌃X Theme picker / Search ? Show keybinds Esc / ⌃C Close dialog
History
n Next document b Previous document ⌃O History back ⌃I History forward
 Search
about: Pranesh Nikhar about/more: πŸͺͺ More docs/test: Docs Test ideas: πŸ’‘ Ideas more: βž• More now: Now posts: πŸ“¬ Posts projects: πŸ“š Projects webtui: Style posts/agentic-eda: πŸ“Š AgenticEDA β€” Automated Exploratory Data Analysis with LangGraph posts/cap-theorem-outage-story: 🌐 CAP Theorem with a Real Outage Story posts/codepilot: ✈️ CodePilot β€” From Requirements to Deployable FastAPI Backend posts/common-auth-mistakes: πŸ” Common Auth Mistakes Developers Make posts/compiled-vs-jit-vs-interpreted: ⚑ Why Is X Language Fast or Slow? β€” Compiled vs JIT vs Interpreted posts/cs-degree-gaps: πŸŽ“ Things CS Degrees Don't Teach You posts/cve-2025-breach-analysis: πŸ›‘οΈ CVE-2025 Breach Analysis β€” Midnight Blizzard and the 16 Billion Credential Leak posts/fixloop: πŸ”„ FixLoop β€” AI Agent Loop for Self-Correcting Code posts/functional-vs-oop: ⚑ Functional vs OOP β€” Same Problem, Both Ways posts/getman: 🦾 Getman β€” Declarative API Tester for CLI & TUI posts/how-compilers-optimize: βš™οΈ How Compilers Actually Optimize Your Code posts/http3-quic: ⚑ HTTP/3 and QUIC β€” Why They Matter posts/leetcode-vs-engineering: 🧩 LeetCode vs Real Engineering Skills posts/llm-from-scratch: 🧠 LLM from Scratch β€” GPT-Style Transformer in PyTorch posts/lsm-trees-bloom-filters: 🌳 LSM Trees & Bloom Filters β€” Production Deep Dive posts/mcp-workflow-builder: πŸ”§ MCP Workflow Builder β€” Visual DAG for MCP Tools posts/persistent-memory: 🧠 Persistent Memory β€” Long-Term Memory for AI Agents via MCP posts/playcli: 🎬 PlayCLI β€” Terminal Video Player posts/postgres-mvcc: πŸ—„οΈ How PostgreSQL MVCC Works β€” Multi-Version Concurrency Control Deep Dive posts/raft-consensus: β›΅ Raft Consensus Algorithm Explained posts/rust-borrow-checker: πŸ¦€ Rust Borrow Checker β€” Catches Real Bugs posts/titan: πŸ€– Titan β€” Terminal AI Coding Agent posts/what-happens-url: 🌐 What Happens Between Typing a URL and Seeing the Page posts/what-happens-when-you-run-a-program: βš™οΈ What Actually Happens When You Run a Program posts/zero-knowledge-proofs: πŸ” Zero-Knowledge Proofs Explained Simply webtui/components/accordion: Accordion webtui/components/badge: Badge webtui/components/button: Button webtui/components/checkbox: Checkbox webtui/components/dialog: Dialog webtui/components/input: Input webtui/components/popover: Popover webtui/components/pre: Pre webtui/components/progress: Progress webtui/components/radio: Radio webtui/components/range: Range webtui/components/separator: Separator webtui/components/spinner: Spinner webtui/components/switch: Switch webtui/components/table: Table webtui/components/textarea: Textarea webtui/components/tooltip: Popover webtui/components/typography: Typography webtui/components/view: View webtui/contributing/contributing: Contributing webtui/contributing/contributing: ## Local Development webtui/contributing/contributing: ## Issues webtui/contributing/contributing: ## Pull Requests webtui/contributing/style-guide: Style Guide webtui/contributing/style-guide: ## CSS Units webtui/contributing/style-guide: ## Selectors webtui/contributing/style-guide: ## Documentation webtui/installation/astro: Astro webtui/installation/astro: ## Scoping webtui/installation/astro: ### Frontmatter Imports webtui/installation/astro: ### β€Ήstyleβ€Ί tag webtui/installation/astro: ### Full Library Import webtui/installation/nextjs: Next.js webtui/installation/vite: Vite webtui/plugins/plugin-dev: Developing Plugins webtui/plugins/plugin-dev: ### Style Layers webtui/plugins/plugin-nf: Nerd Font Plugin webtui/plugins/theme-catppuccin: Catppuccin Theme webtui/plugins/theme-custom: Custom Theme webtui/plugins/theme-everforest: Everforest Theme webtui/plugins/theme-gruvbox: Gruvbox Theme webtui/plugins/theme-nord: Nord Theme webtui/plugins/theme-vitesse: Vitesse Theme webtui/start/ascii-boxes: ASCII Boxes webtui/start/changelog: Changelog webtui/start/installation: Installation webtui/start/installation: ## Installation webtui/start/installation: ## Using CSS webtui/start/installation: ## Using ESM webtui/start/installation: ## Using a CDN webtui/start/installation: ## Full Library Import webtui/start/installation: ### CSS webtui/start/installation: ### ESM webtui/start/installation: ### CDN webtui/start/intro: Introduction webtui/start/intro: ## Features webtui/start/plugins: Plugins webtui/start/plugins: ## Official Plugins webtui/start/plugins: ### Themes webtui/start/plugins: ## Community Plugins webtui/start/theming: Theming webtui/start/theming: ## CSS Variables webtui/start/theming: ### Font Styles webtui/start/theming: ### Colors webtui/start/theming: ### Light & Dark webtui/start/theming: ## Theme Plugins webtui/start/theming: ### Using Multiple Theme Accents webtui/start/tuis-vs-guis: TUIs vs GUIs webtui/start/tuis-vs-guis: ## Monospace Fonts webtui/start/tuis-vs-guis: ## Character Cells
 Theme Current: Light j/k or ↑/↓ + Enter

πŸŽ“ Things CS Degrees Don't Teach You

Eight practical engineering skills that every CS graduate has to learn on the job β€” from Git workflows to debugging, testing, operations, and writing for humans.

🎯 The Gap Between School and Reality

A computer science degree teaches you beautiful things: Turing completeness, NP-completeness, the halting problem, Big-O notation, red-black trees, cache coherence protocols.

What it doesn’t teach you is how to ship software.

Not because CS theory is irrelevant β€” it’s foundational β€” but because the daily work of engineering lives in a different skill set: reading error messages, navigating legacy code, debugging race conditions, deploying without downtime, and writing PR descriptions that colleagues can actually understand.

Here are eight gaps every CS graduate encounters in their first year on the job.


1️⃣ Git Workflows

CS programs treat Git as a magical git push button. In practice, Git is a distributed DAG manipulation tool, and your university’s β€œcommit β†’ push β†’ done” workflow is dangerously incomplete.

What They Don’t Teach

ConceptWhy It Matters
Branching strategiesGit flow, trunk-based development, GitHub Flow β€” each fits different teams
Rebase vs mergeMerge preserves history; rebase rewrites it. When to use each is a team decision
Interactive rebasegit rebase -i for squashing, reordering, fixing commit messages
Cherry-pickingApplying specific commits across branches
Bisectinggit bisect to find the commit that introduced a regression
Stashinggit stash for context switching without losing work
The refloggit reflog β€” the safety net that saves you after a bad reset

The One-Liner That Changes Everything

git rebase -i main

This is the single most important Git command for keeping a clean history. Before you merge, you should be able to look at your branch and see one logical commit per change, with a clear message explaining why.

Code Review Etiquette

DoDon’t
Write descriptive PR titles and summariesLeave β€œFixed bug” or empty descriptions
Keep PRs small (<400 lines)Create 5,000-line PRs that take days to review
Respond to comments within 24 hoursIgnore feedback for weeks
Explain why in commit messagesOnly describe what changed
Use draft PRs for early feedbackWait until β€œperfect” to share
Approve with optional nits clearly labeledBlock a PR over formatting preferences

2️⃣ Debugging

University teaches you to write code. It doesn’t teach you to read code that’s broken, which is where you’ll spend most of your professional time.

Using a Debugger

Most CS graduates have never used a debugger. They use print() statements. While print-debugging works for simple cases, it fails for:

  • Multi-threaded race conditions (prints reorder, timing changes behavior)
  • Segfaults (can’t print after memory corruption)
  • Signal handlers and interrupts
  • Embedded or remote systems where stdout isn’t available
# GDB: gold standard for C/C++
gdb ./my_program
(gdb) break main
(gdb) run
(gdb) print variable_name
(gdb) backtrace
(gdb) frame 3
# PDB: Python's built-in debugger
import pdb; pdb.set_trace()  # python < 3.7
breakpoint()                  # python >= 3.7
# LLDB: modern C/C++/Swift debugger
lldb ./my_program
(lldb) breakpoint set --name main
(lldb) run
(lldb) frame variable
(lldb) thread backtrace

Reading Stack Traces

A stack trace is a gift. It tells you exactly where the program was when it broke. The top of the trace is the crash site; the bottom is the entry point.

Traceback (most recent call last):
  File "app.py", line 45, in <module>       ← entry point
    result = process_data(input_data)
  File "processor.py", line 123, in process_data
    transformed = transform(item)            ← call site
  File "transformer.py", line 67, in transform
    return apply_rules(data['value'])        ← crash site (KeyError: 'value')
KeyError: 'value'

Each frame tells you: the file, the line number, the function, and the local state. Read from bottom to top: the crash is at the bottom, the caller chain is above it.

Bisecting Regressions

When something that used to work stops working, git bisect runs a binary search through your commit history to find the exact commit that broke it:

git bisect start
git bisect bad           # current commit is broken
git bisect good v1.0     # v1.0 was working
# Git checks out a commit halfway between
# Run your test, mark good or bad
# Repeat ~log2(N) times
git bisect reset         # return to original state

For a 500-commit range, bisect finds the culprit in ~9 steps. Most engineers don’t know this exists and waste hours manually scrolling through git log.


3️⃣ Reading Other People’s Code

In university, you write your own code from scratch. In industry, you read 10x more code than you write.

How to approach a codebase you've never seen:

1. README first β€” does a setup guide exist?
2. Entry point β€” where does the program start? (main, app.py, index.js)
3. Tests β€” tests are executable documentation
4. Commit history β€” `git log --oneline` shows what changed and why
5. Architecture docs β€” if they exist, read them before any source file
6. One feature end-to-end β€” trace a single request through the system
7. Don't understand everything β€” 80% understanding of 20% of the codebase is enough

The Rubber Duck

Explain the code you’re reading to an inanimate object. If you can’t explain a function to a rubber duck, you don’t understand it well enough to modify it.


4️⃣ Testing

University teaches you to write code that works on your machine with your inputs. Industry requires code that works on every machine with every input.

The Testing Pyramid

        ╱─────╲
       β•±  E2E  β•²       ← Fewer tests, higher confidence
      ╱─────────╲
     β•±  Integration β•²   ← Service-level tests
    ╱─────────────────╲
   β•±    Unit Tests     β•²  ← Many tests, fast feedback
  ╱───────────────────────╲
Test TypeSpeedConfidenceWhat It Catches
Unit<1msLow per-test, high in aggregateLogic errors, edge cases
Integration10–500msMediumAPI contract breaks, DB issues
E2E1–30sHighPipeline failures, configuration drift

Mocking

Mocking isolates the code under test from its dependencies (databases, APIs, file systems). The skill is knowing what to mock and what to keep real:

  • Mock external APIs (you don’t control them)
  • Mock I/O (files, sockets, network calls)
  • Do NOT mock your own code (test the real thing)
  • Do NOT mock trivial dependencies (plain data transformations)

Testing in CI

A test that only passes on your machine doesn’t exist. Every test must run in CI. Every CI failure must block the merge. These are non-negotiable rules in professional engineering that are never taught in school.


5️⃣ Operations

β€œThe computer works” is an assumption at university. In industry, it’s a hypothesis you verify continuously.

Deployment

Local dev β†’ Feature branch β†’ CI β†’ Staging β†’ Production β†’ Monitoring

Each step catches a different class of error:

StageCatches
Local devSyntax errors, basic logic
Feature branchMerge conflicts, test failures
CICompilation errors, lint, regressions
StagingConfiguration drift, environment differences
ProductionReal user traffic, scale issues
MonitoringLatency regressions, error rate increases

On-Call

You will be woken up at 3 AM. Prep for it:

  1. Runbooks: Document every alert and its response. If you’re fixing the same thing twice, automate it.
  2. Escalation paths: Know who to call when you can’t fix it.
  3. Postmortems: Every incident gets a written postmortem. Blameless. What broke, how we fixed it, how we prevent it next time.

SLOs / SLIs / SLAs

TermDefinitionExample
SLI (Service Level Indicator)What you measureLatency p99, error rate
SLO (Service Level Objective)The target99.9% of requests <200ms
SLA (Service Level Agreement)The promise (with consequences)99.95% uptime, or users get credits

The goal is to measure what matters, target achievable reliability, and tradeoff reliability for velocity intentionally.


6️⃣ Writing for Humans

The most important engineering skill nobody teaches: clear writing.

Code Review Comments

Bad: "This is wrong"           β†’ Unhelpful, demotivating
Bad: "Fix this"                β†’ No context, no explanation
Good: "What happens if `user` is null here? We dereference it on line 42 without checking."
Good: "Consider extracting this validation into a helper β€” it's repeated in 3 places."

RFCs / Design Docs

A good design doc answers five questions:

  1. What problem are we solving? (Context)
  2. Why now? (Motivation)
  3. What approaches did we consider? (Options)
  4. What are we doing and why? (Decision)
  5. What are the risks? (Trade-offs)

Documentation

Write docs for your future self, who has forgotten everything about this system. A year from now, you’ll be grateful you left a comment explaining why, not just what.


7️⃣ Trade-Off Thinking

CS teaches you that there’s a β€œcorrect” answer. Real engineering teaches you that β€œit depends” is the correct answer to most questions.

QuestionCS AnswerEngineering Answer
Which database?Relational vs NoSQLIt depends on consistency needs, scale, team expertise, infra
Monolith vs microservices?MicroservicesIt depends on team size, deploy velocity, organizational structure
Which language?Pick the best oneIt depends on ecosystem, team skills, existing codebase
Test coverage target?100%It depends on risk tolerance, code criticality

The Halting Problem of Engineering Decisions

There is no algorithm to determine the β€œright” architecture. Every decision is a trade-off between:

Time-to-market  ⇄  Code quality
Developer speed ⇄  Operational simplicity
Feature count   ⇄  System reliability

Recognizing when you’re optimizing the wrong variable is the mark of a senior engineer.


8️⃣ Reading Error Messages

This sounds trivial. It’s not. Most errors tell you exactly what’s wrong, but engineers panic, scroll past the error, and start guessing.

How to Read an Error

1. Read the FIRST line  β†’ What type of error? (KeyError, NullPointer, etc.)
2. Read the LAST line   β†’ The actual message (often contains the answer)
3. Read the stack trace β†’ Where did it happen? (file, line number)
4. Read the error line  β†’ What was the program doing?
5. Read the context     β†’ What values were in play?

Example

TypeError: unsupported operand type(s) for +: 'int' and 'str'
  File "calculator.py", line 12, in add
    return a + b

The error tells you:

  • Type: TypeError (wrong type used)
  • Operation: + failed
  • Types involved: int and str (can’t add a string to an integer)
  • Location: calculator.py:12 in add
  • Variables: a is int, b is str

The fix is likely at the call site β€” maybe a str was passed where an int was expected, or b needs to be converted with int(b).

Most errors contain the answer if you read them carefully enough. The skill is staying calm and reading the full output before reaching for Stack Overflow.


πŸ’‘ Key Takeaways

  1. Git is a DAG manipulation tool, not a β€œsave” button β€” learn branching, rebasing, bisecting
  2. Debuggers are rocket fuel for problem solving β€” learn at least one (gdb, lldb, pdb)
  3. Reading code is 10x more important than writing it β€” navigational skills are learned, not taught
  4. Testing is a career, not a checkbox β€” the pyramid, mocking, and CI integration are all essential
  5. Operations is the forgotten layer β€” deployment, on-call, SLOs are half of engineering
  6. Writing is thinking β€” clear PRs, RFCs, and comments separate great engineers from good ones
  7. β€œIt depends” is a professional answer β€” trade-off reasoning is the core skill at senior+ levels
  8. Error messages tell you the answer β€” read them before guessing

CS degrees give you the theory. Real engineering is what you build on top of it.


πŸ“– Series Navigation

 praneshnikhar.site / posts / cs-degree-gaps Β· Top 1:1