Part 1 — Software Engineering & Interviews

Build stronger engineering skills, then practise demonstrating them in software/backend interviews. About 25 weeks at ten hours a week as a starting estimate. ML begins in Part 2 after the readiness check.

Engineering first, interviews next, ML later

Part 1 prepares you to build, debug, test and explain backend software, then demonstrate those skills in software-engineering interviews. Part 2 is a separate ML curriculum for after the readiness check.

Build reliable software → demonstrate interview readiness → begin ML

Keep your current job10 hrs/week maximumOne backend project~25 weeks / ~250 hours initially

StageStarting estimateOutcome
E — Engineering13 weeks / 130 hoursA working backend with evidence of correctness, debugging, performance and recovery, then a first AI demo
I — Interview practice12 weeks / 120 hoursUnaided coding, practical debugging, SQL, system design and clear explanations of your work
Readiness checkMocks from I8, recorded in I12Evidence reviewed by another engineer; repeat weak areas before starting Part 2
Watch outThis is a starting estimate, not a six-month guarantee. Ten hours includes reading, setup, debugging, reviews and mock feedback. If you average seven hours, 250 hours takes about 36 weeks. Check actual time at E4, E9 and I4; move dates when needed. Finishing the calendar does not establish readiness.

Target: general software/backend interviews at your experience level. In E1, spend 90 minutes on 20 relevant local or eligible remote postings. For each, note the backend language and framework, whether the role is backend-only or full-stack, any cloud provider it names (AWS, GCP, Azure), the interview format, whether it asks for experience with AI coding tools or LLM features, and the education line — including whether it says "or equivalent experience". Save the file: E1 uses it to confirm the language, and E9 to choose where the shop runs. Use that evidence to adjust Stage I; add a topic only by replacing another within the cap. You do not need to start applying or get an offer before ML.

First study session: spend 60 minutes tracing one endpoint in an existing app: explain a database rule, the result of a repeated request, the cost of one loop and the test you would use to catch a failure. Record what you can explain and what needs practice. This session and the posting scan together take 2½ of E1's ten hours; unavailable access means untested. If the app is your employer's, keep its code out of AI tools — see the data boundary.

Week tracker

Tick a week when it is done, or skipped on purpose. Ticks are saved in this browser only; the sidebar shows your progress and links to the first unticked week.

Stage I — Interview practice

I1–I3 · arrays, strings, two pointers, sliding windows

  1. I1 Shop change, unaided
  2. I2 Shop change with an AI agent
  3. I3 Shop change, unaided

I4–I6 · stacks, queues, linked lists, binary search, trees

  1. I4 Agent change · checkpoint · book the mocks
  2. I5 Coding mock
  3. I6 Debugging mock

I7–I9 · heaps, graphs, backtracking, 1-D DP

  1. I7 System design mock
  2. I8 Coding mock · checkpoint
  3. I9 Debugging mock · start the CV

I10–I12 · mixed unseen problems

  1. I10 Design mock · readiness evidence
  2. I11 Coding mock · readiness evidence
  3. I12 Project/behavioral mock · readiness check

Stage E — Software engineering fundamentals

Duration: Weeks E1–E13 — about 130 hours at ten a week; extend when a layer needs more practice

Build and operate one backend application, one layer at a time, then ship a first AI demo in E13. The goal is independent implementation, debugging and explanation. Interview practice follows in Stage I; ML starts only after the Part 1 readiness check.

Why one app, built layer by layer

These skills support your current engineering work: data correctness, tests, API behavior, security, concurrency and diagnosing failures. One app built layer by layer makes you maintain earlier decisions as requirements grow. The app is practice; sustained work on real systems continues to develop these skills after this plan.

NoteThe app. Python, FastAPI, SQLAlchemy and Postgres — Python is the default for the app and coding practice, so one language carries through both parts. Use the official Python tutorial alongside E1 when syntax is unfamiliar; that time comes from the same ten hours. The domain is a small shop: users, products with stock, orders with totals. It forces the hard parts: totals a join can double-count, stock two requests can oversell, a confirmation the customer must get once, even when a worker retries or crashes. One public repository, one pull request per change even when working alone. fastapi.tiangolo.com's tutorial is the framework reference for the whole stage; the source column below is the week's topic.
The database layer is the SQLAlchemy 2.0 ORM, used synchronously — not async. Alembic runs on SQLAlchemy, and async sessions raise an error on a lazy load instead of quietly running one query per row, which would hide the N+1 you fix in E8. FastAPI's tutorial uses SQLModel for its database pages; skip those and use SQLAlchemy's Unified Tutorial instead, one part at a time in E2, E4 and E8.
WeekTopicBuild — done whenSource
Git: branches, rebase, bisect, revert. Docker Compose for the local stackFastAPI skeleton and Postgres in Docker Compose, with a health endpoint that queries the database — starts with one command from a fresh clonemissing.csail.mit.edu — the Git lecture; docs.docker.com — Compose quickstart
Data modelling: keys, normalization, constraints, migrations — as SQLAlchemy models and Alembic migrationsUsers, products, orders and order items as SQLAlchemy models and Alembic migrations, with a constraint for every rule the database can enforce — stock never negative, email unique, no orphaned order itemspostgresql.org — Data Definition; docs.sqlalchemy.org — Unified Tutorial: Working with Database Metadata; alembic.sqlalchemy.org — Tutorial
Testing: unit vs integration, fixtures, test databases, what not to mock. The weekday reading also covers the shell: processes, pipes, environment variables, permissionsTests against a real Postgres, not mocks, run with one command — including one that fails if an E2 constraint is droppeddocs.pytest.org — getting started and fixtures; missing.csail.mit.edu — the shell lectures
HTTP and API design: methods, status codes, validation, error format, pagination, idempotency keysProduct and order endpoints with validation, one error format, cursor pagination, and an idempotency key on order creation — tested by sending the same request twicedeveloper.mozilla.org — HTTP; docs.sqlalchemy.org — Unified Tutorial: Working with Data, and Data Manipulation with the ORM
Auth and security: password hashing, sessions vs tokens, authorization, the OWASP Top 10, secretsSign-up, login, and orders scoped to their owner. The test that matters: user A asking for user B's order gets a 404owasp.org — Top 10
The browser side: HTML, CSS, JavaScript, fetch, cookies, CORS, CSRFOne plain HTML page, no framework, that logs in, lists products and places an order. Break CORS on purpose once and read the browser's errordeveloper.mozilla.org — Using Fetch
Transactions and concurrency: isolation levels, lost updates, row locks, optimistic locking; async vs threads in PythonWrite the naive version first: read the stock, check it in Python, write the new value back — product.stock -= qty in the ORM does exactly this. An atomic stock = stock - 1 would let E2's stock >= 0 rule hide the race. A test fires 20 concurrent orders at the last 5 items, each on its own session, with a delay patched in between the read and the write so they overlap on every run. It asserts that at most 5 orders succeed and that the final stock is 5 minus the orders that did — and it fails on the naive version. Fix it twice — a row lock, then a conditional update — and keep the testpostgresql.org — Concurrency Control
Performance: indexes, EXPLAIN ANALYZE, N+1 queries, the cost of your own loopsSeed a million rows. Fix one N+1, one missing index, and one list scan that should be a dict or set. Before/after timings in the READMEuse-the-index-luke.com; docs.sqlalchemy.org — Unified Tutorial: Working with ORM Related Objects (loader strategies)
Redis for background jobs: queues, at-least-once delivery, retries with backoff, idempotent consumers, dead letters; the transactional outboxOrder confirmations sent by an RQ worker with retries, passing the order ID as an idempotency key to a fake email sender that ignores repeats. The order and an outbox row commit in one transaction, and a relay queues unsent outbox rows. Tests: the same job delivered twice, a worker killed after sending but before recording success, and the API stopped right after the commit each end with one email; an order that rolls back ends with none. The queue only gives at-least-once; the outbox makes sure a job exists, and the key makes it one email. Also choose and check the E12 host — see belowpython-rq.org; microservices.io — Transactional outbox
Networking and external calls: DNS, TCP, TLS, what happens when you type a URL; timeouts, and what a retry can repeat. Cache-aside and invalidationCall one external API (exchange rates, say) with a timeout and bounded retries, with tests for the slow and failing paths. Inspect the call with curl -v, dig and openssl s_client. Cache one read path from E8 in Redis with a written invalidation rule, and time ithpbn.co — the networking chapters
Observability and debugging: structured logs, request IDs, metrics, traces, profiling, the debuggerA request ID in every log line; request rate, errors and latency exposed; one slow path found with a profiler and fixed. Inject one bug and write a short incident note: symptom, how you found it, fixsre.google — Monitoring Distributed Systems
CI/CD and running it: pipelines, migrations on deploy, secrets, backupsGitHub Actions runs the tests against Postgres on every push and deploys on merge to the host chosen in E9; the app is live within the spending cap; a backup restored into a separate database and checkeddocs.github.com — Actions
A first AI demo: an LLM API, embeddings and naive retrieval — no ML theory neededA command-line tool over a folder of documents: chunk them naively, embed them, store them in the simplest vector store you can find, and answer questions with an LLM. It prints the passages it retrieved with each answer and reads model names from environment variables. No auth, database, UI, tests or Docker. Pushed to its own public repository with a README and an honest known-limitations section, then tagged v0 and never edited againYour chosen LLM provider's documentation
DecideIn E1, let the posting scan confirm the language. Python is the default because Part 2 needs it — a reason that comes from the optional half of the plan. Count the backend languages in your 20 postings. If Python is among the two most common, keep it. If it barely appears, choose in writing. Keep Python, because the layers below are about data, HTTP and failure rather than syntax, and every source in the table works as written. Or build the shop in the language the postings ask for: you find its equivalent of each tool yourself — framework, ORM, migrations, test runner, job queue — expect the E4 pace check to show slower weeks, and start Part 2 with its Python review. Anything in between stays with Python. Do not build the shop twice.
DecideCheck the pace at the end of E4. Count the hours E1–E4 actually took. If they fit in ten a week, carry on. If they did not, stretch E5–E12 to two layers every three weeks — the layers stay whole; the calendar moves. E13 follows them. Write the decision and the new end date down.
DecideBy the end of E4, name your reviewer. The E12 review, the Stage I mocks and the readiness check each need another engineer, and without one every item stays untested. Ask while nothing depends on the answer: a colleague, a former classmate, someone from a local meetup or an online community — or a paid mock-interview service for the mocks alone. Say how much you are asking for: one README-and-walkthrough review at E12, then up to eight 45–60 minute mocks from I5, which more than one person can share. Write the name down at the pace check. If you have none, finding one is the first task of E5, not of I4. Asking costs a message, not study hours.
DecideCheck the pace again at the end of E9. E1–E4 are the lightest layers, so the first check runs optimistic; E7 and E9 are the densest. Count the hours E5–E9 actually took. If they ran past the pace you set at E4, give each of E10–E12 half a week more than it has now — E12 carries the deploy, the restore check and the peer review — and write the new end date down.
DecideIn E9, choose and check the E12 host. It has to run the API, the worker, Postgres and Redis within your spending cap — free tiers often leave out background workers or expire free databases, and E12 is too late to find out. Let the E1 posting scan decide the kind of host. If the postings name a cloud (AWS, GCP or Azure), run the Compose stack on one VM there: managed databases and container services do not fit in E12's hours, and budget alerts are not a cap, so use a credit-only account or take the deployment down after E12's checks. Otherwise, use a hosting service with a hard spending cap. Write the choice, its monthly cost and its limits in the README.
RuleEach week ends with its layer working and committed — tests green from E3 on. A layer that does not work is finished before the next one starts; if that happens twice, the stage extends rather than skipping a layer.
RuleAI: learning mode — see AI: two modes. You write each layer; AI explains and reviews. Docker Compose files and CI YAML are fair game for professional mode, and you still explain every line of them at the E12 review. From E5 to E11, each weekend ends with an agent replay of the layer you just built.
OptionalAlready know a week's topic? Build its layer first, in under two hours. Official documentation is allowed; tutorials, AI and copied code are not. If its checks pass and you can explain every part of it, commit it and start the next week early — evidence, rather than familiarity with the topic name, is what lets you shorten the stage.
NoteFrontend stops at E6. One plain page is enough to understand what the browser does to your API. Learn a framework only if your E1 scan shows your target roles are full-stack.
RuleBefore E13's first API call: set a monthly ceiling and a hard spend limit in the provider console, keep the API key in an environment variable, add .env to .gitignore, and confirm git status is clean of the key before the first push. Every chunk you embed goes to a third-party API, so choose documents inside the data boundary: public documentation, an open dataset or your own writing. Use the weekdays to read the provider documentation, so the weekend is pure building.
NoteWhy an AI demo now, and why v0 is frozen. Application engineering — calling an LLM API and wiring up retrieval — needs no ML theory, and E10's timeouts and retries apply directly to LLM calls. Building it now gives you something concrete to talk about in Stage I, a real reason to care about Part 2's evaluation and retrieval material, and proof that the transition is achievable, months earlier than Part 2 would. It will be mediocre; that is the point. Part 2's Weeks 30 and 33 teach you why, and Week 30 starts Project #3 from a copy of this repository, so every improvement happens there. Printing the retrieved passages and reading model names from environment variables is what lets Part 2 Week 33 still score v0 after its models are retired — neither can be added once the tag is frozen. Shown side by side in Part 2 Week 40, the naive first attempt and the measured rebuild tell a story about your growth that neither tells alone.
Done whenBefore Stage I: another engineer can start the app from its README, run its tests, and ask you to explain a request from HTTP through the database and worker. Explain every line of the Compose file, the Dockerfile and the CI workflow to them — Part 2 reuses all three and assumes they are familiar. Address their feedback in a small pull request. Use E12 time; if it does not fit, extend E12. Keep the repo for the interview exercises.

Stage I — Software-engineering interview practice

Duration: Weeks I1–I12 after Stage E — about 120 hours. Run this block before ML whether or not you have chosen an application date. The purpose is to demonstrate your engineering skills before moving to ML.

Practise problem-solving, design, runnable code, testing and explanations of previous work. These are covered in Microsoft's technical interview guidance; each employer's format still needs checking. No problem count guarantees a pass.

Coding and data structures — 4 hours each week

Use NeetCode's free problem list and LeetCode. Python is the default because Stage E has given you practice in it. If an upcoming interview requires another language, use that language in these same hours.

WeeksCoding practiceEngineering and design practice
I1–I3Big O; arrays, strings, dicts/sets; sorting, two pointers, sliding windowsTrace the shop's requests; SQL joins and aggregates without double-counting; data constraints; basic design of the shop API
I4–I6Stacks/queues, linked lists, binary search, recursion and treesIndexes and query plans, transactions and locks, HTTP/TLS, processes vs threads vs async; design a URL shortener
I7–I9Heaps, graph BFS/DFS, backtracking and introductory 1-D dynamic programmingRetries, idempotency, caching, replication and consistency; design a rate limiter and notification service
I10–I12Mixed unseen problems, timed mocks and re-solving weak patterns; no new topic quotaUnfamiliar-code debugging, project explanation, mock feedback and the readiness check

Two two-hour sessions per week. In I1–I6, attempt two easy problems per session, 20 minutes each — or one medium for 35–45 minutes once you can explain the pattern behind it. From I7, attempt one new problem per session for 35–45 minutes. No AI or solution open during an attempt. Clarify examples, explain a simple approach, implement, test and state time/space complexity. Use the remaining time for the editorial, a corrected solution and a re-solve of an earlier problem. Log assistance honestly in dsa/solved.md. Completion of NeetCode 150 is not required.

Fundamentals and system design — 2 hours each week

Use one hour to revisit a Stage E concept using its existing source and your own code. Use the other for a small design: requirements → rough scale → API → data model → components → one failure case. Consult the concept sections of the System Design Primer when needed. Begin with one service and one database; justify each added component. Save the diagram and unanswered questions in system-design/.

Start with the shop, then practise the shortener, rate limiter and notification service from the table. Defend constraints, consistency, retries and trade-offs before adding scale. Design alone first; another engineer or AI acting only as interviewer can ask follow-ups afterward.

Practical work and mocks — 3 hours each week

I1–I4: make one bounded change to the shop, reproduce a bug or review a small diff. Clarify the requirement, find the relevant code, make the smallest fix, add a meaningful regression test and explain the result. Request another engineer's review where possible and address it. In I2 and I4, make that week's shop change with an AI agent instead — see professional mode.

I5–I12: replace part of that slot with one 45–60 minute mock plus feedback and correction. Rotate coding (I5, I8, I11), practical debugging (I6, I9), system design (I7, I10), and a project/behavioral interview (I12). In I4, book the dates with the reviewer you named in E4; if no human interviewer is available, record the rehearsal and obtain feedback before counting the readiness check as passed. The mocks from I8 on are also the readiness evidence.

For debugging, use a small unfamiliar public repository or a peer-prepared change: reproduce → investigate → patch → regression test → explain. Do one attempt unaided. If your target interview allows AI, use the next debugging mock to practise bounded AI assistance and independent verification. Ask the recruiter which tools are allowed; do not assume every interview permits them.

Communication and experience — 1 hour each week

Explain one technical decision aloud and practise stories about a bug, a trade-off, collaboration or feedback, and ownership of a result. State the situation, your action, evidence of the outcome and what you would change. Use actual work, the shop or the v0 demo; distinguish measured results from assumptions. From I9, use part of this hour for a concise CV and a five-minute project walkthrough.

CheckpointI4 and I8 checkpoints: review actual hours, unaided solutions, unresolved concepts and mock feedback. If the current patterns remain unclear, repeat them and move the remaining dates. Do not rush through graphs or DP to meet I12. The four allocations total ten hours; extra practice replaces another activity.

Weekly routine

StageWeekly allocationTotal
E1–E13Weekdays: 5 hours reading and small exercises. Weekend: 5 hours building, testing and reviewing the current layer; from E5 to E11 the last 45 minutes are the agent replay. The first assessment and the posting scan use 2½ of E1's hours.10 hours
I1–I124 hours coding + 2 hours fundamentals/design + 3 hours practical work/mocks and corrections + 1 hour communication10 hours
Short weekA week with only three hours: during E, use all three on the current layer. During I, use two on coding and one on the most important outstanding correction. Resume from there; two consecutive reduced weeks trigger a new end-date estimate. Lost hours are never added to next week's cap.
NoteTake one thing back to work. Your job is most of your engineering hours, and paid work on a real system counts for more with an employer than the shop does. At the end of each week, write one private line: where does this week's layer appear in the system you work on? At E4, E9 and E12, turn one of those lines into a request — a backend ticket, a slow query, a failing test, a code review, a shift shadowing on-call. If your employer has approved AI tools, or is building anything on an LLM, ask to be near that work too: doing it for a current employer is often how the Backend Engineer — AI title in Part 2 is earned. Those requests are also where Stage I's communication hour gets its stories. The line takes five minutes of the weekend; the work itself happens in work hours and work tools. The data boundary still holds, and these notes stay out of the public repository.

AI: two modes and a data boundary

Know which mode you are in before you open an AI tool. Part 2 keeps both modes and adds its own limits.

RuleLearning mode is the default. Attempt the task yourself before asking for explanations or review. Implement the correction yourself and explain why it works; if AI gives you code, you are not done until you can explain every important line in an interview. Unaided coding practice and solo design attempts stay unaided.
NoteProfessional mode is a separate skill. Scoping work for agentic coding tools, giving them the right context, reviewing what comes back and knowing where they are reliably wrong is an increasingly explicit hiring signal — most of what "AI-capable software engineer" means to the people writing job descriptions. Use it on the parts that are not the learning objective, such as Docker Compose files, CI YAML and scaffolding, and still run and explain what it produced. Practise it on purpose, in two places.
E5–E11, the agent replay. Once your own layer is working and committed, cut a branch from the commit before it and have an AI agent build the same layer, or one bounded part of it: write the task, give it the context, run your layer's tests against its branch, and read its diff beside yours. Log in ai/agent-log.md what it got wrong, what it did better and what your task left out. Never merge that branch. About 45 minutes, taken from the weekend's five hours; if the layer is not working by then, the layer wins and that week's replay is skipped, not owed.
I2 and I4, the real change. Make that week's shop change with the agent instead of by hand: write the task, give it the context, review the diff, merge only what you can explain, and log it the same way.
If the agent is billed by usage, set a hard spend limit before its first run in E5, as E13 does for the LLM API. In interviews, practise it only in a debugging mock whose target interview allows AI. It is the one AI skill that pays off whether or not you move into ML.
RuleData boundary — write it down in E1. Only public or personal non-sensitive material goes into AI tools and third-party APIs: the shop, public documentation, open datasets, your own writing. No employer code, no internal documents, no customer data, nothing covered by your employment agreement or an NDA — including the existing app in the first study session, if it is your employer's. Your current job is the asset this whole plan is built on; do not put it at risk for practice work.

Ready for Part 2 when

Collect this evidence from the second round of mocks: coding in I8 and I11, debugging in I9, design in I10 and the project interview in I12. If I9 was your AI-assisted debugging mock, the unaided attempt in I6 is the one that counts for item 2. These are local readiness criteria for the roles you selected, not a guarantee of passing every employer's interview. A job offer is not required.

  1. Build and operate: a reviewer can run the shop and its tests from the README. You demonstrate authorization, duplicate-request handling, concurrent stock correctness, one measured performance fix and the checked restore. Explain the limitations.
  2. Debug and change code: in an unfamiliar-code exercise, reproduce a failure, explain its cause, make a small fix and show a regression test. At least one reviewed attempt is unaided; documentation is allowed.
  3. Solve coding problems: in two separate reviewed mocks, solve an unseen problem appropriate to the target role without hints, explain complexity and test edge cases. Repeated solutions from memory do not count. If the target uses medium problems, practise and assess at that level.
  4. Explain a system: complete a 35–45 minute design discussion covering requirements, API, data model, a failure scenario and a justified trade-off. Explain one SQL query and why its result and access path are correct.
  5. Communicate your work: give the five-minute project walkthrough and concrete examples of debugging, ownership and collaboration; another engineer's material feedback has been addressed.
RuleRecord pass, needs practice, or untested for each item. Missing access or a reviewer means untested. Repeat only the weak areas in two-week blocks within the same ten-hour cap, then recheck with a fresh task. Start Part 2 — ML / Applied AI when all five are recorded as pass and you choose to begin. Set its Week 0 date then.

Applications are optional; preparation is part of Part 1

After the readiness check, choose whether to apply for software/backend roles, start Part 2, or continue building engineering experience. You do not need ML projects to finish this plan.

If you start applying, use ten hours as a cap: 4 hours applications and interviews, 3 hours coding, 2 hours practical/design refresh and 1 hour communication. A take-home or extra interview replaces those practice hours; extend the calendar if necessary. Refresh your target postings and confirm each employer's interview format.

If you start Part 2, its Week 0 opens with a fresh market scan and a decision about order — the Applied AI weeks can run before the ML theory — and its budget includes maintenance practice. If a search begins during Part 2, pause ML or explicitly give it only the hours left after interview work. Before a later search, run fresh mocks and refresh the weak areas; interview readiness is not permanent.

DecideIf the job ends before the readiness check, change the plan that week rather than finishing the calendar. Get the current layer working and committed, then start the search: the CV and five-minute walkthrough move up from I9, and applications begin as soon as both exist. The ten-hour cap was set for study beside a full-time job, so choose a weekly figure you can sustain and split it in the proportions above — applications and interviews first, then coding, then practical and design work, then communication. Unfinished Stage E layers continue in order, in the hours left over. Part 2 waits until you are working again.

Progress checkpoints

E4: product/order API, database constraints and integration tests work; actual hours recorded, pace adjusted and a reviewer named.
E9: the stock race fixed and kept under test, before/after timings in the README, each confirmation sent once; hours for E5–E9 recorded, pace re-checked and the E12 host chosen.
E12: shop deployed, tests green, concurrency/performance evidence, incident note and restore checked; peer feedback addressed, with every line of the Compose file, Dockerfile and CI workflow explained.
E13: v0 demo public, tagged and frozen, with its known limitations; API spend cap set.
I4: coding log, a shop design and reviewed changes exist; book the mocks with your reviewer and check the pace.
I8: four mocks completed with corrections recorded; explain your SQL, API and concurrency decisions without reading a tutorial.
I12 or later: all five readiness items recorded as pass, each with reviewed evidence. Decide whether to apply or begin Part 2.

Next action: schedule the first 60-minute endpoint assessment from the overview.