Software engineering is one of the most in-demand careers of the decade — and you can enter it from almost any background. This roadmap gives you a concrete, opinionated path from zero to your first software engineering job, with time estimates and the reasoning behind every choice.
At a glance
| Phase | Topics | Time estimate |
|---|---|---|
| 0 | How computers and the internet work | 1–2 weeks |
| 1 | Programming fundamentals (Python) | 6–10 weeks |
| 2 | Data structures and algorithms | 8–12 weeks |
| 3 | Version control with Git | 1–2 weeks |
| 4 | Web development or backend focus | 8–12 weeks |
| 5 | Databases — SQL and one NoSQL | 4–6 weeks |
| 6 | Systems and software design basics | 4–6 weeks |
| 7 | Testing, tooling, and DevOps basics | 3–4 weeks |
| 8 | Portfolio projects | 6–10 weeks |
| 9 | Job search, interviews, and offers | 4–12 weeks |
| Total to first job | ~12–18 months |
Software engineer vs related roles
| Role | Focus | Typical stack |
|---|---|---|
| Software Engineer | Build products end-to-end | Python, Java, TypeScript, Go |
| Frontend Developer | UI and user experience | HTML, CSS, JavaScript, React |
| Backend Developer | APIs, databases, business logic | Node.js, Python, Java, Go |
| Full-Stack Developer | Both frontend and backend | Node.js + React, Django + Vue |
| DevOps / SRE | Infrastructure, reliability, CI/CD | Bash, Python, Terraform, Kubernetes |
| Data Engineer | Data pipelines and warehousing | Python, SQL, Spark, Airflow |
| ML Engineer | Train and deploy models | Python, PyTorch, TensorFlow, MLflow |
| Mobile Engineer | iOS and Android apps | Swift, Kotlin, Flutter, React Native |
Phase 0 — Computer and internet basics (Weeks 1–2)
Before writing code, understand how the underlying system works.
How a computer works
CPU ←→ RAM (fast, temporary)
↕
Storage (slow, permanent)
↕
I/O ←→ Network
Key concepts:
- CPU executes instructions
- RAM holds running programs — data disappears on restart
- Storage (SSD/HDD) persists data
- OS manages hardware resources and gives programs a safe sandbox
- Process vs thread — a process is a running program; a thread is a lighter unit of execution inside a process
How the internet works
Browser → DNS → Server IP → TCP connection → HTTP request → Response → Render
Key concepts:
- IP address uniquely identifies a device on a network
- DNS maps human-readable domains to IP addresses
- HTTP/HTTPS is the application protocol for web communication
- TCP ensures reliable, ordered delivery of packets
- Client sends requests; server sends responses
Phase 1 — Programming fundamentals (Weeks 1–10)
Start with Python. It has clear syntax, a massive ecosystem, and is used in web, data, AI, and automation. You can switch to another language later — fundamentals transfer.
Core concepts to master
| Concept | What it means |
|---|---|
| Variables and types | Store and name values (int, str, bool, list, dict) |
| Control flow | if/elif/else, for, while |
| Functions | Reusable blocks of code |
| Scope | Where variables are accessible |
| Recursion | Functions that call themselves |
| Error handling | try/except, raising exceptions |
| Modules | Organising code across files |
| OOP basics | Classes, objects, inheritance, encapsulation |
| File I/O | Reading and writing files |
First programs to build
- Calculator — arithmetic with user input
- Guessing game — random numbers, loops, conditionals
- To-do list (CLI) — file persistence, CRUD logic
- Contact book — dictionaries, search, update, delete
- Simple web scraper —
requests+BeautifulSoup
# To-do list with JSON persistence
import json, os
TASKS_FILE = "tasks.json"
def load_tasks():
if not os.path.exists(TASKS_FILE):
return []
with open(TASKS_FILE) as f:
return json.load(f)
def save_tasks(tasks):
with open(TASKS_FILE, "w") as f:
json.dump(tasks, f, indent=2)
def add_task(description):
tasks = load_tasks()
tasks.append({"id": len(tasks) + 1, "desc": description, "done": False})
save_tasks(tasks)
def list_tasks():
for t in load_tasks():
status = "✓" if t["done"] else "○"
print(f"[{t['id']}] {status} {t['desc']}")
Phase 2 — Data structures and algorithms (Weeks 6–18)
DSA is tested in every technical interview and makes you a better programmer regardless of role.
Essential data structures
| Structure | Use case | Time complexity (key ops) |
|---|---|---|
| Array / List | Ordered elements, index access | Access O(1), Insert O(n) |
| Hash Map / Dict | Key-value lookup | Get/Set O(1) avg |
| Stack | LIFO — undo, call stack, DFS | Push/Pop O(1) |
| Queue | FIFO — BFS, task queues | Enqueue/Dequeue O(1) |
| Linked List | Dynamic insert/delete | Access O(n), Insert O(1) |
| Binary Tree | Hierarchical data | Search O(log n) balanced |
| Heap | Priority queues, top-K | Insert O(log n), Min/Max O(1) |
| Graph | Networks, relationships | Varies |
| Trie | Prefix search, autocomplete | Insert/Search O(m) |
Essential algorithms
| Algorithm | Category | Key idea |
|---|---|---|
| Binary search | Search | Halve the search space each step |
| BFS | Graph | Level-by-level exploration (queue) |
| DFS | Graph | Deep exploration (stack / recursion) |
| Merge sort | Sorting | Divide, sort halves, merge — O(n log n) |
| Quick sort | Sorting | Partition around pivot — O(n log n) avg |
| Dynamic programming | Optimisation | Cache subproblem results |
| Two pointers | Array | Solve in O(n) what naively needs O(n²) |
| Sliding window | Array/String | Variable-size subarray problems |
Study approach
- Understand Big-O before solving problems — know what O(n²) means for n=10,000
- LeetCode order: Arrays → Strings → Hash Maps → Two Pointers → Sliding Window → Stacks → BFS/DFS → Trees → Dynamic Programming
- Solve 100–150 problems (focus: Easy 40%, Medium 55%, Hard 5%)
- Explain your approach out loud — crucial for interviews
# Binary search — O(log n)
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# Two Sum — O(n) with hash map
def two_sum(nums, target):
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return []
Phase 3 — Git and version control (Weeks 8–10)
Every professional software engineer uses Git daily. Learn it early.
Essential Git commands
# Setup
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
# Daily workflow
git status # See what changed
git add <file> # Stage specific file
git add . # Stage all changes
git commit -m "feat: add login" # Commit with message
git push # Push to remote
# Branching
git checkout -b feature/login # Create + switch branch
git merge feature/login # Merge into current branch
git pull origin main # Pull latest from remote
# History and inspection
git log --oneline # Compact log
git diff # Unstaged changes
git stash # Stash changes temporarily
Git workflow for solo projects
main (production-ready)
└── feature/login
└── feature/profile
└── bugfix/typo-in-header
Commit message format
<type>: <short description>
feat: add user authentication
fix: correct off-by-one error in pagination
docs: update API reference for /users endpoint
refactor: extract email validation to helper
test: add unit tests for cart calculation
Phase 4 — Web development or backend (Weeks 10–22)
At this point, choose a focus. Most jobs are in web development.
Option A — Backend focus (APIs and systems)
# FastAPI — modern Python web framework
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
email: str
users_db = {}
@app.post("/users", status_code=201)
def create_user(user: User):
if user.email in users_db:
raise HTTPException(status_code=400, detail="Email already exists")
users_db[user.email] = user
return {"message": "User created", "user": user}
@app.get("/users/{email}")
def get_user(email: str):
if email not in users_db:
raise HTTPException(status_code=404, detail="User not found")
return users_db[email]
Option B — Full-stack focus
Learn HTML + CSS + JavaScript first, then a framework like React:
// React — fetch and display users
import { useState, useEffect } from "react";
export function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("/api/users")
.then((r) => r.json())
.then((data) => {
setUsers(data);
setLoading(false);
});
}, []);
if (loading) return <p>Loading…</p>;
return (
<ul>
{users.map((u) => (
<li key={u.id}>{u.name} — {u.email}</li>
))}
</ul>
);
}
Which language after Python?
| Language | Best for | Demand |
|---|---|---|
| JavaScript / TypeScript | Web frontend + full-stack Node.js | Very high |
| Java | Enterprise backend, Android, Spring Boot | Very high |
| Go | High-performance backend, microservices, cloud tools | High, growing |
| Rust | Systems programming, WebAssembly, embedded | Growing |
| C# | .NET/Azure ecosystem, Windows, Unity | High |
| Kotlin | Android (replacing Java), server-side JVM | Growing |
Phase 5 — Databases (Weeks 14–20)
Every application stores data. Know both SQL and one NoSQL database.
SQL essentials
-- Create table
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
-- CRUD
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
SELECT id, name, email FROM users WHERE email = 'alice@example.com';
UPDATE users SET name = 'Alice Smith' WHERE id = 1;
DELETE FROM users WHERE id = 1;
-- Join
SELECT orders.id, users.name, orders.total
FROM orders
JOIN users ON orders.user_id = users.id
WHERE orders.total > 100;
-- Aggregate
SELECT status, COUNT(*) as count, SUM(total) as revenue
FROM orders
GROUP BY status
ORDER BY count DESC;
SQL vs NoSQL
| Dimension | SQL (PostgreSQL) | NoSQL (MongoDB) |
|---|---|---|
| Structure | Fixed schema, tables | Flexible documents |
| Relationships | Foreign keys, joins | Embedded or referenced |
| ACID | Full ACID | Eventual consistency (configurable) |
| Scaling | Vertical + read replicas | Horizontal sharding |
| Best for | Structured business data | Documents, JSON, flexible schemas |
| Query language | SQL | MongoDB Query Language |
Key database concepts to understand
- Indexes — speed up reads, slow down writes
- Transactions — atomic groups of operations (ACID)
- N+1 problem — querying in a loop vs joining once
- Connection pooling — reuse connections instead of opening new ones
- Migrations — version control for your database schema
Phase 6 — Systems and software design (Weeks 18–24)
Even junior engineers benefit from understanding how systems fit together.
Foundational design patterns
| Pattern | Problem it solves |
|---|---|
| Repository | Abstract data access from business logic |
| Factory | Create objects without specifying exact class |
| Observer | Notify multiple objects when state changes |
| Strategy | Swap algorithms at runtime |
| Decorator | Add behaviour without subclassing |
| Singleton | Guarantee one instance of a class |
System design concepts (for interviews)
Client
↓
Load Balancer (distribute traffic)
↓
App Servers (stateless, horizontally scalable)
↓ ↓
Cache Database (primary)
(Redis) ↓
Read Replicas
CDN serves static assets (images, CSS, JS)
Message Queue (Kafka/RabbitMQ) decouples heavy work
Key topics:
- Load balancing — round-robin, least connections, sticky sessions
- Caching — Redis, Memcached; cache-aside, write-through patterns
- Horizontal vs vertical scaling — more servers vs bigger server
- Database sharding — partition data across multiple databases
- CAP theorem — Consistency, Availability, Partition tolerance (pick two)
- Microservices vs monolith — start monolith, split when necessary
- API design — REST, GraphQL, gRPC; versioning; rate limiting
Phase 7 — Testing, tooling, and DevOps basics (Weeks 22–26)
Professional code is tested and deployed reliably.
Testing pyramid
/\
/ \
/ E2E \ ← Few, slow, expensive
/--------\
/ Integration\ ← Some
/--------------\
/ Unit Tests \ ← Many, fast, cheap
/------------------\
# Unit test with pytest
import pytest
from myapp.cart import calculate_total
def test_calculate_total_with_discount():
items = [{"price": 100, "qty": 2}, {"price": 50, "qty": 1}]
total = calculate_total(items, discount_pct=10)
assert total == 225.0 # (200 + 50) * 0.9
def test_empty_cart():
assert calculate_total([], discount_pct=0) == 0.0
def test_invalid_discount():
with pytest.raises(ValueError):
calculate_total([{"price": 10, "qty": 1}], discount_pct=110)
Docker basics
# Multi-stage Dockerfile for a Python app
FROM python:3.12-slim AS base
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM base AS production
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
docker build -t myapp .
docker run -p 8000:8000 myapp
CI/CD pipeline (GitHub Actions)
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install -r requirements.txt
- run: pytest --cov=myapp tests/
- run: mypy myapp/
Phase 8 — Portfolio projects (Weeks 20–30)
Your portfolio is your proof of ability. Two or three strong projects beat ten half-finished ones.
Project ideas by difficulty
| Project | Difficulty | What it demonstrates |
|---|---|---|
| CLI to-do app | ⭐ | Basic CRUD, file I/O, Python |
| REST API (books, tasks, etc.) | ⭐⭐ | HTTP, databases, validation |
| Auth system (JWT) | ⭐⭐ | Security, sessions, tokens |
| Real-time chat | ⭐⭐⭐ | WebSockets, async, state |
| E-commerce backend | ⭐⭐⭐ | Complex domain, payments, queues |
| URL shortener | ⭐⭐ | Hashing, redirects, analytics |
| Job board with search | ⭐⭐⭐ | Full-stack, search, pagination |
| CI/CD pipeline tool | ⭐⭐⭐⭐ | DevOps, automation, scripting |
What makes a strong portfolio project
- Solves a real problem (even a small one)
- Has a
README.mdwith setup instructions and a description - Includes tests (even basic ones)
- Is deployed and accessible via a URL
- Code is clean, well-structured, and uses meaningful names
- Has a git history showing iterative progress
Where to deploy for free
| Platform | Best for |
|---|---|
| Vercel | Next.js, React, static sites |
| Railway | Backend APIs, databases |
| Render | Web services, cron jobs |
| Fly.io | Docker containers |
| Supabase | PostgreSQL + auth |
| Cloudflare Workers | Edge functions |
Technology map
Core Languages Web / API
───────── ───────────── ────────────────
Python Python FastAPI / Django
Algorithms JavaScript/TS Node.js + Express
Data Structures Java React / Vue
Git Go Next.js
Databases Infrastructure Observability
───────── ────────────── ─────────────
PostgreSQL Docker Logging (structlog)
Redis GitHub Actions Metrics (Prometheus)
MongoDB Linux/Bash Tracing (OpenTelemetry)
Nginx
18-month timeline
| Month | Focus | Milestone |
|---|---|---|
| 1–2 | Python fundamentals | Can write basic programs |
| 3–4 | OOP, modules, packages, error handling | CLI to-do app with file persistence |
| 4–6 | Data structures and algorithms | Solving Easy LeetCode |
| 5–7 | Git, HTTP, REST basics | First REST API (FastAPI or Express) |
| 6–8 | SQL, PostgreSQL, database design | API connected to a database |
| 7–9 | Intermediate algorithms | Solving Medium LeetCode |
| 8–10 | Auth, security, testing | Auth system with JWT + tests |
| 9–12 | Choose specialisation (web/backend/mobile) | Deployed portfolio project |
| 11–13 | System design fundamentals | Can explain basic system design |
| 12–15 | Second portfolio project | Two shipped, deployed projects |
| 14–16 | LeetCode grinding (100–150 problems) | Mock interview practice |
| 15–18 | Job applications, interviews | Job offers |
Software engineer salary 2025
| Level | Years exp | US Median | FAANG Total Comp | Remote (non-US) |
|---|---|---|---|---|
| Intern | 0 | $50–80k/yr | $80–120k/yr | $15–40k/yr |
| Junior (L3/E3) | 0–2 | $95–130k | $180–250k | $40–80k |
| Mid (L4/E4) | 2–5 | $130–170k | $250–380k | $60–120k |
| Senior (L5/E5) | 5–10 | $170–220k | $350–600k | $80–160k |
| Staff (L6/E6) | 8–15 | $220–280k | $500k–$1M+ | $120–200k |
Software engineer vs related fields
| Aspect | SE | Data Scientist | ML Engineer | DevOps |
|---|---|---|---|---|
| Primary language | Python, Java, Go, TS | Python, R | Python | Bash, Python, Go |
| Primary output | Software products | Insights, models | Deployed models | Reliable systems |
| Math required | Low | High | High | Low |
| CS fundamentals | High | Medium | High | Medium |
| Avg salary (US) | $140k | $130k | $155k | $145k |
| Demand | Very high | High | Very high | High |
Common mistakes
| Mistake | Why it hurts | Fix |
|---|---|---|
| Tutorial hell | Watching without building | Force yourself to code after every tutorial |
| Learning multiple languages at once | Dilutes fundamentals | Master one language first (Python) |
| Skipping data structures | Fails interviews | DSA is mandatory — no shortcut |
| No version control | Can't collaborate | Use Git from day one, even for solo projects |
| No deployed projects | Can't prove skills | Deploy at least two projects with real URLs |
| Ignoring testing | Fragile code | Add tests to every portfolio project |
| Applying before ready | Wastes early chances | Apply after 2 deployed projects + 100 LC problems |
| Undervaluing soft skills | Gets filtered in interviews | Practice explaining your thinking out loud |
Software engineering vs related terms
| Term | What it actually means |
|---|---|
| Software Engineer | Builds software; umbrella term covering frontend, backend, full-stack |
| Software Developer | Often used interchangeably with Software Engineer |
| Programmer | General term — person who writes code |
| Computer Scientist | Studies theory — algorithms, complexity, formal systems |
| DevOps Engineer | Bridges development and operations; focuses on CI/CD and reliability |
| Solutions Architect | Designs high-level system architecture, often vendor-specific |
| Technical Lead | Senior engineer who guides a team's technical direction |
| CTO | Chief Technology Officer — executive who owns technical strategy |
FAQ
Q: Do I need a computer science degree?
No. Many working software engineers are self-taught or bootcamp graduates. A degree helps at large companies (FAANG) but is not required everywhere. What matters most: your portfolio, your interview performance, and your ability to learn quickly.
Q: How long does it realistically take?
With consistent daily study (2–4 hours), expect 12–18 months to land a junior role. Full-time focus shortens this to 8–12 months. Part-time (1–2 hours/day) takes 18–24 months.
Q: Which language should I start with?
Python for most people. It has clean syntax, immediate usefulness (web, data, scripting), massive community, and is used in interviews. JavaScript is a good second choice if you want to build web UIs from the start.
Q: Should I do a bootcamp?
Only if you need accountability and structure. Self-study is free and just as effective if you're disciplined. Bootcamps cost $10–20k and vary wildly in quality. Research hiring outcomes before paying.
Q: What specialisation should I choose?
- Web (frontend/full-stack) — fastest path to a job, most positions available
- Backend / APIs — strong salaries, needed everywhere
- Data / ML — more math required, higher ceiling
- Mobile — smaller but stable market (iOS or Android)
- DevOps/Cloud — infrastructure-focused, strong demand
Q: How many LeetCode problems do I need to solve?
Aim for 100–150 before applying. Focus on Easy and Medium in these categories: Arrays, Strings, Hash Maps, Trees, BFS/DFS, Dynamic Programming. Quality over quantity — understand each solution deeply rather than memorising it.