35 companies, 50+ interviews, 8 offers
A data scientist’s seven-month job search across 35 companies, ending in eight offers and a Google SWE III role in AI/ML. The funnel, the timeline and the system that held it together.
Contents
On March 24, 2026, I filled in a 28-question self-assessment before building an interview plan. Dynamic programming: five problems, five marked “can’t start.” Statistics and A/B testing: four topics, four marked “can’t start.” SQL retention patterns: zero. The only area I could honestly rate as interview ready was generative AI, the thing I had spent the previous year building. I was aiming at Google-level machine learning roles, and the assessment said I could not yet pass the coding round of a mid-tier startup.
On August 31, I signed an offer from Google for a Software Engineer III role in AI/ML. Between those two dates sat 35 companies, more than 50 interview rounds, four take-home assignments, four rejections and eight offers.
This post is the map of the whole search: the funnel, the timeline, and the system that kept it from collapsing under its own weight. Every other post in the series zooms into one part of it, and each is linked from the index at the end.
Some context on where I started. I am a data scientist turned ML engineer with about four years in production machine learning: user-level ranking and personalization at Cars24, entity resolution and computer vision at 6sense, and a first-author NLP paper in Springer LNAI. The search ran from February to August 2026, from Bengaluru, mostly for senior ML, applied scientist and AI engineer roles.
The headline numbers:
- Companies in conversation: 35, of which 32 reached at least one round
- Interview rounds: 54 live rounds plus 4 take-home assignments
- Outcomes: 8 offers, 4 rejections, 20 processes I chose to stop
- Google loop: Strong Hire on the ML domain and Googleyness rounds, Hire on both coding rounds
- Dynamic programming: 0 of 5 problems startable in March → two Google coding rounds at Hire in July
Background: what was broken in March#
The baseline was the obvious problem, but it was not the only one. Three things were wrong at the start, and each one shaped a part of the system that followed.
A resume that tried to be four people. My first resume opened with a title block that claimed data science, ML engineering, applied science and backend engineering at once. A deliberately harsh review scored it 3.5 out of 10 on a “BS factor” scale: how much of each section a hiring manager would discount on sight. The fixes over three revisions were less about wording and more about which claims could survive a follow-up question. That got it down to 2.2.
No coding fluency where it mattered. I had solved 234 LeetCode problems over the years, but almost none of them in the categories Google and most product companies lean on for ML engineers: dynamic programming, graphs beyond breadth-first search, intervals, and data structure design. My strengths (ranking systems, LLM infrastructure, production debugging) showed up in conversation, not in a 45-minute coding round.
No pipeline. I had a long list of companies I admired and no idea which of them were hiring for my profile, what their loops tested, or how I would prepare for five different interview formats in the same week. A one-off push of applications would have produced a burst of calls followed by silence.
None of these problems were about knowledge I lacked entirely. They were about converting what I knew into signal an interviewer could score in 45 minutes.
That last point is the theme of the whole series. Google’s own guidance on structured interviewing describes interviewers scoring candidates against predefined rubrics. A rubric only rewards what you make visible. Most of my preparation went into making existing skill visible, not into acquiring new skill.
The shape of the search#
The funnel below shows the whole search in aggregate. I deliberately keep it at this level: the point is the shape, not any single company’s process.
graph TD
A["35 companies<br/>in conversation"] --> B["32 reached<br/>a first round"]
A --> C["3 stopped at<br/>recruiter contact"]
B --> D["8 offers"]
B --> E["4 rejections"]
B --> F["20 processes<br/>I stopped"]
D --> G["Google SWE III<br/>accepted"]
D --> H["7 other offers"]
class A,B amber
class C,F gray
class D,G,H green
class E redThe numbers that stand out are at the bottom. I had a first round with 32 companies, and only four of them rejected me. Twenty processes ended because I stopped them: the role drifted from what was advertised, the team was not a fit, the pay band was below where I was heading, or a better process made it not worth the preparation time. Eight ended in an offer.
That ratio says more about the search strategy than about interview performance. Running many processes in parallel made it cheap to walk away. Every process I dropped bought preparation time for the ones that mattered, and walking away from a weak fit early is the most underrated move in a job search.
The offers came from a deliberately mixed set of companies: Google, Vieu, Hexalog, Parspec, AI Fiesta, Deeptune, RazorpayX and Winmore. They ranged from seed-stage AI startups to a fintech business unit to a large tech company, and from founding-team roles to an L4 software engineering role. Rejections came from Nykaa, Sequoia, Almedia and Glance, and the post on rejections covers what each one taught me.
The timeline#
The search was not evenly spread. The number of live interview rounds by month tells most of the story: 3 in February, 10 in March, 24 in April, 5 in May, 6 in June, 4 in July and 2 in August.
graph LR
A["Feb<br/>3 rounds"] --> B["Mar<br/>10 rounds"]
B --> C["Apr<br/>24 rounds"]
C --> D["May<br/>5 rounds"]
D --> E["Jun<br/>6 rounds"]
E --> F["Jul<br/>Google loop"]
F --> G["Aug<br/>team match"]
G --> H["Aug 31<br/>offer signed"]
class A,B gray
class C amber
class D,E violet
class F,G amber
class H greenFebruary and March: warm-up. The first calls were exploratory. By late March I had mapped a universe of about 50 target companies, rebuilt the resume, set up the portfolio site you are reading this on, and taken the baseline assessment. The first Google recruiter conversation happened on March 30.
April: the blitz. Twenty-four live rounds in one month. On April 15 alone I had three interviews in one afternoon, at 12:30, 3:00 and 4:00. Most of the non-Google offers trace back to processes that peaked in April. I joined Vieu as a graph ML engineer in this period, which is the work behind my entity resolution post.
May and June: the tail. Fewer, deeper processes. Several of these were three-round loops spread over weeks, which made each one easier to prepare for properly. By the end of June I had seven offers. On May 31 the Google invite arrived, which changed the shape of everything after it.
July and August: Google. The interview dates moved several times before settling. The ML domain round was on July 9, Googleyness and Leadership on July 15, and two back-to-back coding rounds on July 29. After the loop came a team-specific round on August 12 focused on agentic AI, a team fitment call on August 17, hiring committee approval and the offer call. I signed on August 31.
The system: treating the search as a pipeline#
The first deep dive is about logistics, because logistics is where a search like this fails first. At the April peak I was preparing for five or six different companies at once, each with a different loop and a different definition of “senior.”
Every company got a brief. Before a first round, I researched the company, the role and, where possible, the interviewer’s background. An interviewer who came from backend engineering would probe production architecture and APIs; one with a quantitative research background would probe probability and causal inference. Knowing which one I was walking into changed what I revised that morning.
Every process had an explicit keep or drop decision. After each round I asked the same three questions: does the role match what was advertised, would I take this offer today, and is the next round worth the preparation it needs? A “no” on any of them ended the process, politely and quickly. The post on running 17 interview processes in one month goes into how I made those calls.
The calendar was the source of truth. Every round, reschedule and follow-up lived in one calendar. When I reconstructed the search for this series, that calendar was the only reason I could date most of it.
The system: a debrief after every round#
The second deep dive is the habit that compounded the most. After every round I sat down with Claude and reconstructed the interview from memory while it was fresh: what was asked, what I said, where I hesitated, where the interviewer pushed. Then we scored it against the same three buckets every time: content, communication and the signals a rubric would capture.
Patterns appeared within the first two weeks. I hedged my own numbers (“as far as I remember”) about systems I had built. I opened answers with “So” and buried the conclusion at the end. I volunteered weaknesses nobody asked about. Under pressure I swapped the metrics of two different ranking systems I had built. I named a model before defining the data schema.
I kept these in a running table of ten habits, each with a one-line fix, and every later debrief checked against it. Some habits died within weeks: approval-seeking “right?” at the end of statements disappeared by mid-April. Others never fully went away; the metric swap showed up again in a team-matching conversation in August. The post on the ten habits covers all of them.
The debrief worked for the same reason retrieval practice works in learning research. Roediger and Karpicke (2006) showed that actively recalling material produces better long-term retention than re-reading it. Reconstructing an interview from memory, then checking it against a fixed rubric, is retrieval practice applied to my own behavior.
The system: one prep engine, many loops#
The third deep dive is the preparation itself. Rather than preparing separately for each company, I built one preparation system and pointed it at whichever loop was next.
A baseline before a plan. The March self-assessment produced a priority map: gaps that would cause a “no hire” got fixed first, gaps that would cost a “strong hire” came next, and confirmed strengths went on a do-not-restudy list. The plan was rebuilt every time a date moved.
Source-of-truth documents. For the Google loop I kept a set of numbered documents: ML implementation from scratch, ML theory, system design, LLM internals, pipelines and experimentation, a resume-defence bank, and a behavioral story bank. Every mock interview patched these documents instead of producing a new one.
Rules for the AI coach. Across the search I ran more than 500 conversations with Claude. The ones that worked followed written rules: never name the algorithm pattern before I attempt a problem, give me a cold attempt before any hint, debrief in fixed buckets, and flag a wrong answer flatly without commentary. The coach was also wrong in instructive ways: it rated my Googleyness round a Hire when it came back Strong Hire, and in the final days before the coding rounds it leaked solutions despite the rules.
A coding sprint with a fixed end date. The final stretch before the onsite was 18 days and 102 questions, every question mapped to a date: seven days of acquiring the patterns I still lacked, then timed mixed practice, then simulation and a taper.
Results#
The eight offers, and what I did with each, are below. I am not publishing compensation for any of them.
| Company | Role type | Outcome |
|---|---|---|
| Software Engineer III, AI/ML | Accepted | |
| Vieu | Graph ML engineer | Accepted |
| Hexalog | AI engineer | Declined |
| Parspec | Machine learning engineer | Declined |
| AI Fiesta | AI engineer | Not taken |
| Deeptune | Member of technical staff | Not taken |
| RazorpayX | AI generalist | Not taken |
| Winmore | Senior software engineer, AI/ML | Not taken |
For the Google loop, the recorded results were Strong Hire on the ML domain round, Strong Hire on Googleyness and Leadership, and Hire on both coding rounds. One of those coding rounds involved an approach I later found was wrong for the problem. The packet passed anyway, which is a useful reminder that a loop is evaluated as a whole.
Two numbers matter more to me than the offer count. Only four of 32 companies that interviewed me said no. And the two coding rounds I passed in July sat squarely in categories I had flagged as gaps in March.
What I’d do differently#
Start the coding preparation in February, not March. Dynamic programming and graph fluency were the long pole in every loop that had a coding round. Every week of delay showed up as a week of compressed preparation later, and the final sprint would have been less frantic with a two-month runway.
Track where every conversation came from. When I sat down to analyse the funnel, I could not reliably say which processes came from a recruiter, which from an application and which from my own outreach. That is the single most useful number for planning the next search, and I did not record it.
Fewer processes in April. Twenty-four rounds in a month meant some preparation was shallow, and a few of the processes I stopped were ones I should never have started. A tighter filter at the recruiter-call stage would have bought back several days.
Write the metric bank before the first interview. My most persistent mistake was attributing a result from one ranking system to the other. A one-page sheet of every number on my resume, with its exact definition and system, would have fixed in March what I was still fixing in August.
Trust self-assessment less. One of my offers came after a system design round I was certain I had failed; the interviewer called the design “very basic.” One rejection came after a round I left feeling fine. The debrief process made my read more accurate, but it never made it reliable.
Conclusion#
The search worked because I treated it as a system with feedback loops rather than as a series of exams. Each interview produced data, each debrief turned that data into a specific fix, and one preparation engine served every loop. The offer count follows from that structure, not from any single brilliant round.
If you take one idea from this series, take this one: the gap between knowing something and getting credit for it in an interview is a skill of its own, and it improves fastest when you measure it after every attempt.
The series, in the order it will be published:
- 35 companies, 50+ interviews, 8 offers (this post)
- From “can’t start” to a plan: baselining for a Google loop
- The 10 habits that cost me interview signal
- Running 17 interview processes in one month
- Running my interview prep on Claude
- Rebuilding a resume that scored 3.5 out of 10
- Eighteen days, 102 questions: a DSA sprint
- The rejections, and the round I thought I had failed
- Preparing for the Google ML domain round
- Getting interviews: recruiters, outreach and applications
- Preparing for Googleyness and Leadership
- Four take-home assignments, one workflow
- Learning agentic AI for an interview in a week
- The Google loop, round by round
- Choosing between eight offers
- Negotiating with Google without a competing offer
Part 1 of the 35 companies, 8 offers series. I join Google as a Software Engineer III, AI/ML, in October 2026.
Responses
Select any passage to highlight it or comment on that line. Highlights stay private, in this browser.