Junior developer interview prep in one week

Junior developer interview prep with only a week left: reread the job ad, split prep into three groups, a 7-day plan, coding practice and questions to ask back.

What should junior developer interview prep look like with only a week left? Don't review everything you've ever learned. Reread the job ad, split the work into three groups (your project, fundamentals and live coding), then fit them into seven days. Have you ever studied everything and remembered nothing? Let's see how Minh does it.

Minh has exactly one week

In the previous post, Minh sent ten applications after reading and scoring each job ad carefully. Minh is a made-up character, pieced together from situations familiar to new IT graduates in Vietnam, and so is company A in this post. Two weeks later, company A invited Minh to a technical interview the following Thursday. Minh messaged me: "I've got exactly one week. What should I study first?".

Minh's reflex was to open a list of "100 JavaScript interview questions" and start reading from number 1. I understand that reflex, because it feels like work. But a week isn't enough to learn 100 questions, and most of them have nothing to do with company A. Skim-reading has a bigger problem too. Reading an answer is completely different from saying that answer out loud in front of someone, and in an interview you only get to do the second.

So I suggested Minh do it the other way round. Start from what company A will ask, then decide what to study.

What do you look for when you reread the email and the ad?

Minh has two sources of information. The first is company A's job ad, which the previous post scored 10 out of 10. This is the requirements part, copied from the previous post's example:

Ad A, requirements (example)
The job: build features for a web app for managing expenses; write tests for your own work;
  take part in code review with a team of 4 frontend developers.
Requirements: React, TypeScript, Git; understanding of REST APIs; 0–1 year of experience or an equivalent personal project.
Preferred: Next.js; has written unit tests.

The second is the interview invitation. It says the interview lasts 60 minutes and takes place online. It doesn't say what the parts are.

The first thing Minh did, the same day he got the email, was reply to confirm the time and ask three more things: who would interview him, whether there'd be live coding, and if so, which tool. Many people hesitate to ask, afraid it looks like they aren't prepared.

I think it's the opposite. Asking about the format shows you're serious, and recruiters are usually happy to answer because they want you to do your best. The reply said a frontend team lead would interview him, and the session would cover his project, some knowledge questions and a small coding task of about 20 minutes in an online code editor.

With that answer, Minh knew the week had to be split between three things, and none of them was "read 100 questions".

How many groups should you split your prep into?

Minh split everything into three groups, matching the three parts of the interview, and wrote them in a file called study-list.md.

The first group is Minh's own project. This is how the interviewer finds out what you've really done, and it's the only part nobody can prepare for you. Minh's main project is an app for logging expenses by text message, the one the portfolio projects post picked and scored.

The second group is fundamentals, and this is where it's easiest to spread yourself thin. Minh didn't take questions from the list of 100; he took them from each requirement in ad A. Each requirement produced a few questions, 15 in total:

study-list.md (group 2)
JavaScript / TypeScript
1. How do `let`, `const` and `var` differ?
2. `==` vs `===`.
3. Promises and `async/await`: in what order does this code run?
4. `map`, `filter`, `reduce`: rewrite a `for` loop with them.
5. What is a closure? An example from my own code.
6. `type` vs `interface` in TypeScript.
7. How `unknown` differs from `any`.
8. Reading a stack trace: find the first line that belongs to my code.
React / Next.js
9. Why not mutate state directly?
10. When does `useEffect` run, and what is the dependency array for?
11. What is `key` for in a list?
12. Server Components and Client Components in Next.js.
Git / REST / tests
13. What makes a good pull request?
14. GET, POST, PUT, DELETE and status codes 200, 400, 401, 404, 500.
15. What is a unit test, and how do you know a test actually works?

Fifteen sounds like very few. But Minh has to be able to answer each one in about a minute, with an example from his own code, and that takes several attempts. For study material I recommend official docs, like React's Learn section and MDN's JavaScript Guide, because interviewers often ask in the same terms the docs use. A few questions on the list are also in this blog's question bank, such as let, const and var and how do you know a unit test works.

The third group is live coding. You can't prepare for this by reading, only by doing, so Minh gave it a whole day.

How do you talk about your project in two minutes?

"Tell me about your project" is almost certain to come up, and it's often the first question. Minh wrote his answer in project-story.md, not to memorize it, but to know which points he wanted to make and in what order:

project-story.md (example)
# Project story, 2 minutes (example: Minh)

The problem: I kept forgetting to log my spending because opening an expense app took too many steps.
I built an app where you log an expense with one text message, like "coffee 35k", and see the month's
total with the /total command.

What I did: I built it with Next.js and TypeScript. Reading the amount was the hardest part, because people
write "35k", "35.000", "1tr2" or "35 nghìn". I wrote 21 unit tests for it before connecting the UI.

Technical decisions (pick 1 if asked to go deeper):
1. Keep the message-reading function separate from the UI, so it can be tested without a browser.
2. If a message has more than one amount, reject it and ask again instead of guessing.
3. Work out the month in Vietnam time, because the server runs on UTC.

Hardest bug: An expense at 6:30 a.m. on 1 December was counted in November. It was right on my machine and
wrong on the server, because the server runs on UTC, and 6:30 a.m. in Vietnam is 11:30 p.m. the day before in UTC.
I reproduced it by running the tests with TZ=UTC, then fixed it to always use Vietnam time for the month.

If I did it again: I'd store the data in a database from the start instead of keeping it in memory.

("1tr2" and "35 nghìn" are how Vietnamese people write 1.2 million and 35 thousand.)

This outline has five parts, and each answers a question the interviewer would otherwise ask next. "The problem" says why the project exists. "What I did" says which part is yours.

"Technical decisions" is where the interviewer can dig deeper, and Minh prepared three for them to choose from. "Hardest bug" shows how you handle things when nothing works. "If I did it again" shows you can see your own weak spots.

The hardest bug deserves the most preparation. A good bug story has a concrete symptom ("an expense at 6:30 a.m. on 1 December counted in November"), a cause you can explain, a way you reproduced it, and the fix. If you just say "I had a time zone bug and fixed it", the interviewer can't tell you apart from someone who copied a fix from the internet.

On the second day of the week, Minh did something that seems unnecessary. He opened his project's code again, reran the tests, and read the README as if he were a stranger. He finished the project a few weeks ago, and details fade fast. Being asked "how does your amount parser handle '1tr2'" and having to open the code to remember is an uncomfortable moment, and it's completely avoidable. The project you're proud of question in the question bank has more tips on this part.

How do you practice live coding without knowing the task?

Minh didn't know what the 20-minute task would be. But for a junior frontend role at a company building an expense app, it's likely to be a small data-processing task: filter, group or sort a list. Minh set himself a task of exactly that size, timed 20 minutes, and talked out loud about what he was thinking as he worked.

The task: given a list of expenses, each with a date and an amount, return the total for each month, newest month first. This is Minh's first version, with test data at the bottom:

practice/first-try.ts
// Minh's first version, written in 20 timed minutes. Run: node practice/first-try.ts
type Expense = { date: string; amount: number };

function totalsByMonth(expenses: Expense[]) {
  const totals: Record<number, number> = {};
  for (const { date, amount } of expenses) {
    const month = new Date(date).getMonth() + 1; // only the month number
    totals[month] = (totals[month] ?? 0) + amount;
  }
  return totals;
}

// Two expenses in December of two different years, and one in January.
console.log(totalsByMonth([
  { date: "2025-12-31", amount: 10000 },
  { date: "2026-01-01", amount: 20000 },
  { date: "2026-12-05", amount: 30000 },
]));
node practice/first-try.ts
{ '1': 20000, '12': 40000 }

The result has December with 40,000, meaning the December 2025 and December 2026 expenses were added together, because the key is only the month number. The order isn't what the task asked for either, because JavaScript objects order numeric keys ascending on their own. Minh's 20 minutes ran out without him noticing either bug, because he only tested with data from a single year.

The lesson of that session isn't syntax. It's the habit of asking about the task before coding. One question in the first minute, "can the data span more than one year?", would have prevented both bugs. In a real interview, that question also shows the interviewer how you think, which they weigh more than whether the code runs on the first try.

The fixed version uses a "year-month" string as the key, and Minh wrote tests for exactly the case he got wrong:

practice/totals-by-month.ts
// A 20-minute practice task: given a list of expenses, return the total for each month, newest month first.
// Minh picked this task because it's close to company A's product (an expense management app).
export type Expense = { date: string; amount: number }; // date like "2026-11-03"

export function totalsByMonth(expenses: Expense[]): { month: string; total: number }[] {
  const totals = new Map<string, number>();
  for (const { date, amount } of expenses) {
    const month = date.slice(0, 7); // "2026-11-03" → "2026-11"
    totals.set(month, (totals.get(month) ?? 0) + amount);
  }
  // "YYYY-MM" strings sort alphabetically in the same order as time, so sorting the strings is enough.
  return [...totals].map(([month, total]) => ({ month, total })).sort((a, b) => b.month.localeCompare(a.month));
}
practice/totals-by-month.test.ts
// Run: node practice/totals-by-month.test.ts   (Node.js 22.18+, nothing to install)
import assert from "node:assert/strict";
import { test } from "node:test";

import { totalsByMonth } from "./totals-by-month.ts";

test("an empty list has no months", () => {
  assert.deepEqual(totalsByMonth([]), []);
});

test("adds up expenses in the same month, newest month first", () => {
  const result = totalsByMonth([
    { date: "2026-10-30", amount: 50000 },
    { date: "2026-11-03", amount: 35000 },
    { date: "2026-11-15", amount: 32000 },
  ]);
  assert.deepEqual(result, [
    { month: "2026-11", total: 67000 },
    { month: "2026-10", total: 50000 },
  ]);
});

test("December of last year comes after January of this year", () => {
  const result = totalsByMonth([
    { date: "2025-12-31", amount: 10000 },
    { date: "2026-01-01", amount: 20000 },
  ]);
  assert.deepEqual(result.map((row) => row.month), ["2026-01", "2025-12"]);
});
node practice/totals-by-month.test.ts (result lines)
ok 1 - an empty list has no months
ok 2 - adds up expenses in the same month, newest month first
ok 3 - December of last year comes after January of this year
# pass 3
# fail 0

The fix gets the month by slicing the string instead of using new Date. The dates here are already in the "2026-11-03" format, so slicing is both simpler and avoids time zone issues, the very kind of bug Minh hit in his project. Each test has a reason: an empty list is an edge case everyone should try, the second test checks the sums and the order, and the third locks in the first version's bug.

Minh did two tasks like this on Sunday. What he told me afterwards was that talking out loud was harder than coding. Typing in silence felt normal, but typing while explaining kept making him lose track of which line he was on. That's exactly why you practice beforehand. Live coding gets its own detailed look in the next posts.

What does the seven-day plan look like?

This is the plan Minh stuck on his desk. About two hours a day, because Minh still has a part-time job, and I think two focused hours a day are worth more than eight hours crammed into the last day.

seven-day-plan.md (example)
# 7-day plan before the technical interview (example: Minh, company A)

Interview: Thursday, 60 minutes, online. About 2 hours a day.

Thursday (the day the email arrives)
- Reply to confirm the time. Ask: who's interviewing, is there live coding, which tool.
- Copy ad A's requirements into `study-list.md`, split into three groups.

Friday — my project
- Write `project-story.md`: a 2-minute intro, 3 technical decisions, 1 hard bug I fixed.
- Reopen the code, rerun the tests, read the README like a stranger.

Saturday — fundamentals, part 1
- 8 questions from `study-list.md` (JavaScript, TypeScript). Answer out loud, record it, listen back.

Sunday — live coding
- 2 tasks of 20 minutes, timed, talking out loud. Write tests after each task.

Monday — fundamentals, part 2
- The other 7 questions (React, Git, REST, tests). Any answer that stumbles: rewrite it as a 3-line summary.

Tuesday — mock interview
- Ask a friend to interview you for 30 minutes: 1 intro question, 4 knowledge questions, 1 small coding task.
- Write down 3 weak answers, and review exactly those 3.

Wednesday — logistics, early night
- Test the meeting link, mic, camera, screen sharing, have the code editor open.
- Write `questions-to-ask.md`. Don't learn anything new.

Three things in this plan deserve an explanation, because people often skip them.

The first is recording yourself. Listening to your own voice is awkward, but it's the fastest way to find out how many times you say "um", or that a simple answer takes you three minutes. Minh found that his answer about useEffect circled around for almost two minutes without reaching the point.

The second is a mock interview with a real person. A classmate is enough; they don't need to be better than you. The point isn't for them to grade right and wrong, but for you to get used to being watched while you think. Write down exactly three weak spots and review only those, instead of reviewing everything again.

The third is learning nothing new on the last day. Knowledge crammed in the night before rarely gets used, while a full night's sleep definitely helps. The last day is for logistics. An online interview can go wrong because the mic isn't detected, the browser blocks screen sharing or the meeting link wants you to install software, and all of that can be checked the day before.

What should you ask the interviewer at the end?

Almost every interview ends with "do you have any questions for us?". Saying "no, thank you" isn't wrong, but it wastes a chance. Your questions show what you care about, and their answers help you decide whether you want to work there. Minh prepared five, planning to pick two or three depending on time:

questions-to-ask.md (example)
# Questions to ask the interviewer (pick 2–3, example for ad A)

About the work
- In the first three months, what does a junior usually work on?
- How does the frontend team review code: who reviews, and how long does a PR take to get merged?

About learning
- How often would the mentor meet me during the first 2 months?
- In your view, what does a junior who's doing well look like at the end of probation?

About the process
- Are there more rounds after today, and when could I expect to hear back?

Each question ties to a detail in ad A. The ad says "a mentor for the first 2 months", so Minh asks how often that mentor meets him, because a mentor who only exists on paper doesn't help. The ad says "take part in code review with a team of 4", so Minh asks how review works. "What does a junior doing well look like" is my favorite, because the answer is exactly what you'll be judged on at the end of probation.

Two kinds of questions are best avoided at this stage. One is anything the ad already answers, because it shows you didn't read it carefully. The other is salary questions in a technical round, when the person in front of you is a team lead rather than HR. Salary has a better time and a better person to ask.

Thursday morning, an empty code editor

On Thursday, Minh joined the call five minutes early. His project intro went more smoothly than he expected, because he'd said it out loud four times that week. Two knowledge questions were on his list of 15, one wasn't, and Minh answered half of it and then said honestly that he wasn't sure about the rest.

Then the frontend team lead shared their screen. On it was an online code editor, a four-line task description and a 20-minute countdown. The interviewer said: "Just talk out loud as you go, I want to hear how you think". How to get through those 20 minutes, from reading the task to writing the last line, is the subject of the next posts.

You can follow the whole journey in the Junior journey series. To practice beforehand, try the tell me about yourself in one minute question and others in the interview question bank.

Get the next post by email.

One email a week, only when there is something worth reading. No spam.