<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Karuha</title>
    <description>The latest articles on DEV Community by Karuha (@karuha).</description>
    <link>https://dev.to/karuha</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3841947%2Fd1e11c25-c7f9-49c8-b876-d9ef993f9f9e.jpg</url>
      <title>DEV Community: Karuha</title>
      <link>https://dev.to/karuha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karuha"/>
    <language>en</language>
    <item>
      <title>Turn an SLO Into an Interview Answer With a Small Node.js Error-Budget Drill</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Sun, 12 Jul 2026 13:57:36 +0000</pubDate>
      <link>https://dev.to/karuha/turn-an-slo-into-an-interview-answer-with-a-small-nodejs-error-budget-drill-59lp</link>
      <guid>https://dev.to/karuha/turn-an-slo-into-an-interview-answer-with-a-small-nodejs-error-budget-drill-59lp</guid>
      <description>&lt;p&gt;Most SRE interview answers go wrong before the candidate says a word about Kubernetes, queues, or databases. They start with architecture when the interviewer is listening for a decision: what users are experiencing, how much reliability budget remains, and what you would do first.&lt;/p&gt;

&lt;p&gt;An SLO is useful in an interview because it turns a vague reliability opinion into a bounded trade-off. You do not need a production observability stack to practice that move. This tiny Node.js script calculates a monthly error budget and gives you three prompts to answer aloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage2.maoertech.cn%2Fpechka%2Fblog-covers%2Fsre-interview-ai.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage2.maoertech.cn%2Fpechka%2Fblog-covers%2Fsre-interview-ai.webp" alt="Server racks representing the infrastructure behind an SLO and error budget" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What an interviewer is actually testing
&lt;/h2&gt;

&lt;p&gt;Take a common prompt: “Latency is up and the checkout service is timing out. What do you do?” A weak answer begins with a long list of tools: dashboards, traces, logs, packet captures. Those are useful tools, but the list does not explain how you will make a decision.&lt;/p&gt;

&lt;p&gt;A stronger answer has four observable moves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;State the customer impact and scope: which journey is broken, for whom, and since when?&lt;/li&gt;
&lt;li&gt;Name the reliability guardrail: the SLO, the error budget, and the current burn rate.&lt;/li&gt;
&lt;li&gt;Choose the smallest reversible mitigation: pause a deploy, shed nonessential traffic, roll back, or add capacity.&lt;/li&gt;
&lt;li&gt;Separate mitigation from investigation: restore safety first; identify root cause and prevention second.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That order matters. A 99.9% monthly availability objective permits about 43.2 minutes of unavailability in a 30-day month. That is not a magical threshold that dictates one action, but it gives you a concrete way to explain why an action is proportionate.&lt;/p&gt;

&lt;h2&gt;
  
  
  A dependency-free error-budget drill
&lt;/h2&gt;

&lt;p&gt;Save this as &lt;code&gt;slo-interview-drill.mjs&lt;/code&gt;, then run &lt;code&gt;node slo-interview-drill.mjs 99.9 30&lt;/code&gt;. The first argument is the target percentage and the second is the window in days. It uses only Node’s standard runtime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;targetArg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;99.9&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;daysArg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;30&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;targetArg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;daysArg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;days&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Usage: node slo-interview-drill.mjs &amp;lt;target-percent&amp;gt; &amp;lt;days&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalMinutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;days&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;budgetMinutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;totalMinutes&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scenarios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checkout API&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;spent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pause a risky deploy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;spent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;roll back a cache change&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;spent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keep investigating before changing traffic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;percent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;%`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; min`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\nSLO target: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;% over &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;days&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; days`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error budget: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;budgetMinutes&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; of downtime\n`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;scenarios&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spent&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;budgetMinutes&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;remaining&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;spent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spent&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; spent`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`  Budget consumed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;percent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spent&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; | remaining: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;percent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;remaining&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`  Interview prompt: Would you &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;? Why?\n`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Answer structure: state the user impact, name the SLO/budget,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;choose the smallest safe mitigation, then describe the follow-up.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the useful part of the output for a 99.9% target over 30 days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SLO target: 99.9% over 30 days
Error budget: 43.2 min of downtime

checkout API: 9.0 min spent
  Budget consumed: 20.8% | remaining: 79.2%
  Interview prompt: Would you pause a risky deploy? Why?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not treat the calculated percentage as an automatic “yes” or “no.” Nine minutes in checkout can be more serious than 18 minutes in an internal search service. The value is in making the missing context explicit: customer path, blast radius, rate of deterioration, reversibility, and what the last deployment changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn each prompt into a spoken answer
&lt;/h2&gt;

&lt;p&gt;Use a two-minute timer. Read one generated prompt, answer it aloud, then grade the answer against this compact rubric:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;What a good answer makes clear&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;User impact&lt;/td&gt;
&lt;td&gt;The affected journey and whether the failure is partial or global&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guardrail&lt;/td&gt;
&lt;td&gt;The objective, remaining budget, and whether consumption is accelerating&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mitigation&lt;/td&gt;
&lt;td&gt;The smallest safe action that limits more harm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evidence&lt;/td&gt;
&lt;td&gt;The next metric, trace, or experiment that could change the decision&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Follow-up&lt;/td&gt;
&lt;td&gt;Ownership for root cause, alerting, and a prevention item&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For the checkout example, a concise answer might sound like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I would first confirm whether checkout failures are regional or global and freeze the deployment pipeline while I check the error rate and latency burn. We have used about one-fifth of a 43-minute monthly budget, but checkout is revenue-critical and the rate may be increasing. If the spike lines up with the cache rollout, I would roll it back because that is fast and reversible. Once the error rate stabilizes, I would compare traces before and after the rollout, write the incident timeline, and add a rollout guardrail if we did not already have one.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice what this does not do: it does not pretend the exact cause is known. It commits to an action conditional on evidence and explains why the action is safe. That is much more credible than naming every monitoring tool you have used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Change the inputs, not just the wording
&lt;/h2&gt;

&lt;p&gt;Run the script with three targets: &lt;code&gt;99.5&lt;/code&gt;, &lt;code&gt;99.9&lt;/code&gt;, and &lt;code&gt;99.99&lt;/code&gt;. For a 30-day window, their approximate budgets are 216 minutes, 43.2 minutes, and 4.32 minutes. Now repeat the same scenario. Your rollback decision may be unchanged, but the urgency, escalation path, and acceptable experiment size should not be identical.&lt;/p&gt;

&lt;p&gt;Then replace the hard-coded scenarios with incidents you have actually handled. Keep them anonymous, but use real constraints: a regional dependency, a recently changed flag, a stuck queue, an exhausted connection pool. Candidates often practice system design as if every question starts from a blank canvas. Senior reliability interviews frequently start with a running system and ask whether you can make a safe call with incomplete information.&lt;/p&gt;

&lt;h2&gt;
  
  
  A useful distinction: target versus policy
&lt;/h2&gt;

&lt;p&gt;An SLO is a target for service behavior, not a universal permission slip. A team can have budget remaining and still halt a release because the affected path is safety-critical, contractual, or rapidly worsening. Conversely, a team can exhaust budget without making every engineer stop working; the response may be to defer risky work while the service is stabilized.&lt;/p&gt;

&lt;p&gt;Say that distinction in an interview. It demonstrates that you understand error budgets as a communication mechanism between product, engineering, and operations—not a calculator that replaces judgment. The Google SRE Workbook’s chapters on service-level objectives and error budgets are a good primary reference for the underlying model.&lt;/p&gt;

&lt;p&gt;If you want a second practice format, use the same rubric in a mock session. &lt;a href="https://www.aceround.app/blog/sre-interview-ai/" rel="noopener noreferrer"&gt;aceround.app — an AI interview assistant’s SRE preparation guide&lt;/a&gt; has role-specific prompts; bring your own incident context and use it to pressure-test the reasoning rather than memorize a script.&lt;/p&gt;

&lt;h2&gt;
  
  
  A five-minute practice loop
&lt;/h2&gt;

&lt;p&gt;Before an interview, run this loop once per scenario:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Calculate the budget for the stated objective and window.&lt;/li&gt;
&lt;li&gt;Name the customer-facing symptom in one sentence.&lt;/li&gt;
&lt;li&gt;Choose one reversible mitigation and name the evidence that would make you reverse course.&lt;/li&gt;
&lt;li&gt;Explain the investigation only after the service is safer.&lt;/li&gt;
&lt;li&gt;End with one prevention change: an alert, rollout check, capacity limit, or runbook update.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The point is not to produce an SRE-sounding monologue. It is to make the decision process easy for an interviewer to follow. When you can state constraints before components, your system-design answer stops sounding like a diagram tour and starts sounding like operational judgment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Google SRE Workbook, “Service Level Objectives” and “Error Budgets”&lt;/li&gt;
&lt;li&gt;Google SRE Book, “Embracing Risk”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Disclosure: AI assisted with editing and code review. The author reviewed the final tutorial and verified the example calculations locally.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>interview</category>
      <category>javascript</category>
      <category>devops</category>
    </item>
    <item>
      <title>Practice Frontend Typeahead Interviews With AbortController and ARIA</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Fri, 10 Jul 2026 10:56:48 +0000</pubDate>
      <link>https://dev.to/karuha/practice-frontend-typeahead-interviews-with-abortcontroller-and-aria-53ic</link>
      <guid>https://dev.to/karuha/practice-frontend-typeahead-interviews-with-abortcontroller-and-aria-53ic</guid>
      <description>&lt;p&gt;Frontend interviews rarely fail because you forgot the name of one API. They fail when a small component turns into five hidden requirements: async state, stale requests, keyboard behavior, accessibility, and a clear explanation of trade-offs. A typeahead search box is a compact way to practice all five in one sitting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqz0y0922lieqyohsv3qv.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqz0y0922lieqyohsv3qv.webp" alt="Frontend typeahead interview drill: code, state, cancellation, and accessibility" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use a typeahead as an interview drill?
&lt;/h2&gt;

&lt;p&gt;A typeahead looks harmless: input in, suggestions out. That is exactly why interviewers like it. In 30-45 minutes they can watch whether you build the happy path only, or whether you notice the edge cases that show up in production.&lt;/p&gt;

&lt;p&gt;A realistic typeahead has at least seven decisions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;What the interviewer is really testing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Debounce input&lt;/td&gt;
&lt;td&gt;Do you reduce needless work without making the UI feel slow?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cancel stale requests&lt;/td&gt;
&lt;td&gt;Do you know why out-of-order responses create bugs?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loading and empty states&lt;/td&gt;
&lt;td&gt;Do you model UI states instead of sprinkling booleans?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keyboard navigation&lt;/td&gt;
&lt;td&gt;Do you think beyond mouse users?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ARIA roles&lt;/td&gt;
&lt;td&gt;Do you know the accessibility shape of a combobox?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caching&lt;/td&gt;
&lt;td&gt;Can you explain latency vs freshness?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error handling&lt;/td&gt;
&lt;td&gt;Do you degrade clearly instead of silently failing?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The point of the drill below is not to memorize a perfect answer. It is to rehearse the explanation while you build.&lt;/p&gt;

&lt;h2&gt;
  
  
  The interview prompt
&lt;/h2&gt;

&lt;p&gt;Use this prompt with a timer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build a user search typeahead. It should debounce input, cancel stale requests, show loading/empty/error states, support arrow-key navigation, and explain which production details you would add later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds like a lot, so start with a small state model before writing code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;idle -&amp;gt; loading -&amp;gt; ready
idle -&amp;gt; loading -&amp;gt; empty
idle -&amp;gt; loading -&amp;gt; error
ready -&amp;gt; loading      # query changed
loading -&amp;gt; loading    # previous request aborted, new request started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This state model gives you a clean way to talk while coding: "I am not adding a spinner boolean yet; I am modeling the component as a small state machine because loading, empty, and error are mutually exclusive."&lt;/p&gt;

&lt;h2&gt;
  
  
  A dependency-free implementation
&lt;/h2&gt;

&lt;p&gt;Paste this into an &lt;code&gt;index.html&lt;/code&gt; file and open it in a browser. It uses a fake API so you can practice the component behavior without creating a backend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"user-search"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Search teammates&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
  &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"user-search"&lt;/span&gt;
  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
  &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"combobox"&lt;/span&gt;
  &lt;span class="na"&gt;aria-autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"list"&lt;/span&gt;
  &lt;span class="na"&gt;aria-controls=&lt;/span&gt;&lt;span class="s"&gt;"user-results"&lt;/span&gt;
  &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
  &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"off"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"search-status"&lt;/span&gt; &lt;span class="na"&gt;aria-live=&lt;/span&gt;&lt;span class="s"&gt;"polite"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"user-results"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"listbox"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;USERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ada Lovelace&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alan Turing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Grace Hopper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Katherine Johnson&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Margaret Hamilton&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Edsger Dijkstra&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Barbara Liskov&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Donald Knuth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Radia Perlman&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ken Thompson&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dennis Ritchie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Frances Allen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;idle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="na"&gt;activeIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#user-search&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#user-results&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#search-status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wait&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;searchUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;250&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aborted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DOMException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Request aborted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AbortError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;USERS&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;220&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;timerId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;timerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rawQuery&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rawQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;idle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;empty&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AbortController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;searchUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;empty&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AbortError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aria-expanded&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aria-activedescendant&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`user-result-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;idle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Type at least one character.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Searching...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; result&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; found.`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No matching teammates.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Search failed. Try again.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`
      &amp;lt;li
        id="user-result-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"
        role="option"
        aria-selected="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"
      &amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/li&amp;gt;
    `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;debouncedSearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runSearch&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;debouncedSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ArrowDown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ArrowUp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activeIndex&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;idle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to explain the key decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why debounce at 220ms?
&lt;/h3&gt;

&lt;p&gt;Debounce is a product trade-off, not a magic number. Under 100ms, you still fire too many requests while someone types normally. Above 400ms, the input starts to feel sluggish. I usually say I would begin around 200-300ms, then measure real typing behavior and API latency.&lt;/p&gt;

&lt;p&gt;That answer is stronger than "I would debounce it" because it names the user experience cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use &lt;code&gt;AbortController&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;Without cancellation, you can render stale results. Type &lt;code&gt;a&lt;/code&gt;, then quickly type &lt;code&gt;ad&lt;/code&gt;. If the &lt;code&gt;a&lt;/code&gt; request returns after the &lt;code&gt;ad&lt;/code&gt; request, the UI can show results for the wrong query.&lt;/p&gt;

&lt;p&gt;The example defends against that in two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It aborts the previous request when a new query starts.&lt;/li&gt;
&lt;li&gt;It checks &lt;code&gt;controller !== state.controller&lt;/code&gt; before committing results.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The second check is intentionally defensive. In real code, not every async task respects cancellation. The identity check makes the latest request the only one allowed to update the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why not start with React?
&lt;/h3&gt;

&lt;p&gt;You can implement this in React, Vue, Svelte, or plain DOM. In an interview, plain JavaScript proves the underlying behavior without hiding it behind framework state updates.&lt;/p&gt;

&lt;p&gt;If the interviewer asks for React, translate the same model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;status&lt;/code&gt;, &lt;code&gt;results&lt;/code&gt;, and &lt;code&gt;activeIndex&lt;/code&gt; become state.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;controller&lt;/code&gt; and &lt;code&gt;cache&lt;/code&gt; belong in refs.&lt;/li&gt;
&lt;li&gt;The debounced function needs stable identity.&lt;/li&gt;
&lt;li&gt;Cleanup should abort an in-flight request when the component unmounts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That translation is a good senior-level discussion because it shows you understand both the browser primitive and the framework lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow-up questions to practice
&lt;/h2&gt;

&lt;p&gt;After you finish the first pass, ask yourself these follow-ups out loud:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What changes if the API returns 10,000 users?&lt;/li&gt;
&lt;li&gt;Where would you put analytics without making the component noisy?&lt;/li&gt;
&lt;li&gt;How would you test cancellation deterministically?&lt;/li&gt;
&lt;li&gt;Should cached results expire after 30 seconds, 5 minutes, or never?&lt;/li&gt;
&lt;li&gt;What is missing for full WAI-ARIA combobox compliance?&lt;/li&gt;
&lt;li&gt;How would you support IME input for Japanese, Chinese, or Korean users?&lt;/li&gt;
&lt;li&gt;What should happen when the network is offline?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those questions matter because frontend interviews are increasingly about systems thinking inside small UI surfaces. A typeahead is not just a typeahead; it is async control flow, accessibility, product latency, and failure handling in one component.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 25-minute practice plan
&lt;/h2&gt;

&lt;p&gt;Use this schedule if you are preparing for a frontend screen this week:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0-3 min&lt;/td&gt;
&lt;td&gt;Restate requirements and draw the state model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3-10 min&lt;/td&gt;
&lt;td&gt;Build input, fake API, debounce, and rendering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10-15 min&lt;/td&gt;
&lt;td&gt;Add cancellation and stale-response protection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15-20 min&lt;/td&gt;
&lt;td&gt;Add keyboard navigation and ARIA attributes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20-25 min&lt;/td&gt;
&lt;td&gt;Explain production upgrades and trade-offs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Record yourself once. The uncomfortable part is not the code; it is hearing whether your explanation is precise or vague. If you want another way to rehearse follow-up pressure, the related &lt;a href="https://www.aceround.app/blog/best-ai-for-technical-interview/" rel="noopener noreferrer"&gt;AceRound technical interview prep guide&lt;/a&gt; pairs well with this drill because it separates practice tools from live interview pressure and focuses on explaining trade-offs, not memorizing trivia. AceRound is an AI interview assistant, but the useful habit here is tool-agnostic: practice turning implementation choices into clear spoken reasoning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MDN: &lt;code&gt;AbortController&lt;/code&gt; and abortable async work.&lt;/li&gt;
&lt;li&gt;WAI-ARIA Authoring Practices Guide: combobox pattern.&lt;/li&gt;
&lt;li&gt;React documentation: effect cleanup and state synchronization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  AI disclosure
&lt;/h2&gt;

&lt;p&gt;I used AI assistance to draft and edit this article, then manually reviewed the code path, DEV.to fit, links, and claims before publishing.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>career</category>
      <category>interview</category>
    </item>
    <item>
      <title>Practice Frontend Performance Interviews With a Node.js Drill</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Thu, 09 Jul 2026 10:10:36 +0000</pubDate>
      <link>https://dev.to/karuha/practice-frontend-performance-interviews-with-a-nodejs-drill-2ji5</link>
      <guid>https://dev.to/karuha/practice-frontend-performance-interviews-with-a-nodejs-drill-2ji5</guid>
      <description>&lt;p&gt;Most frontend performance interview answers fail for the same reason: they jump straight to a fix. A stronger answer sounds like a debugging session: name the user-visible symptom, choose a metric, inspect the likely bottleneck, explain the trade-off, then propose the smallest safe change.&lt;/p&gt;

&lt;p&gt;Here is a small Node.js drill you can run before a frontend interview to practice that shape.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqz0y0922lieqyohsv3qv.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqz0y0922lieqyohsv3qv.webp" alt="Frontend developer interview practice visual" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why performance questions are different
&lt;/h2&gt;

&lt;p&gt;Algorithm questions usually have an expected answer. Frontend performance questions rarely do.&lt;/p&gt;

&lt;p&gt;If an interviewer says, "This product page feels slow after a React refactor," they are not waiting for the word &lt;code&gt;useMemo&lt;/code&gt;. They are checking whether you can reason from symptoms to evidence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the problem network, JavaScript execution, rendering, or layout?&lt;/li&gt;
&lt;li&gt;Which user metric changed: LCP, CLS, INP, TTFB, or something local to the app?&lt;/li&gt;
&lt;li&gt;What changed recently: bundle size, API shape, image dimensions, hydration, third-party scripts?&lt;/li&gt;
&lt;li&gt;Can you fix the issue without making accessibility, maintainability, or product behavior worse?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why rereading Web Vitals docs helps, but only up to a point. You need reps speaking the diagnostic path out loud.&lt;/p&gt;

&lt;h2&gt;
  
  
  The answer shape I practice
&lt;/h2&gt;

&lt;p&gt;For a live interview, I like this five-step answer:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;What to say&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Symptom&lt;/td&gt;
&lt;td&gt;"Users see X, and the metric that likely maps to it is Y."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First measurement&lt;/td&gt;
&lt;td&gt;"I would inspect A before changing code because it separates B from C."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Likely cause&lt;/td&gt;
&lt;td&gt;"Given the constraints, the most likely bottleneck is..."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fix path&lt;/td&gt;
&lt;td&gt;"I would try the smallest reversible change first..."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Follow-up&lt;/td&gt;
&lt;td&gt;"Then I would verify with metric Z and watch for regression W."&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That sounds basic, but it prevents the two common failure modes: guessing a favorite optimization, or listing every tool you know without making a decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  A runnable drill
&lt;/h2&gt;

&lt;p&gt;Save this as &lt;code&gt;frontend-performance-drill.mjs&lt;/code&gt; and run it with Node 18 or newer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cp"&gt;#!/usr/bin/env node
&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;readline&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:readline/promises&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;stdin&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stdout&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scenarios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Product page feels slow after a React refactor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Largest Contentful Paint moved from 2.1s to 4.8s on mid-range Android. The bundle grew by 180KB and image bytes are unchanged. Walk through your first investigation.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lcp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bundle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;code splitting&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;network&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;main thread&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;profiling&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;followUp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The React profiler shows one expensive component rendering three times before the hero appears. What do you check next?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Infinite list janks during scroll&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A feed scrolls smoothly on desktop but drops frames on mobile after 80 items. API latency is fine. Explain the likely bottleneck and a fix path.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;virtualization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dom nodes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;layout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paint&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;memo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;windowing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;followUp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The interviewer says virtualization is not allowed for accessibility reasons. What is your fallback?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Search box sends too many requests&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Typing in a search input fires a request on every keypress. Users see stale results overwrite fresh results. Design the client-side control flow.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;debounce&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;abortcontroller&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;race&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loading state&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;idempotent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;followUp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Now make the same answer safe for a flaky mobile network.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CLS spike after marketing adds a banner&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cumulative Layout Shift jumps from 0.04 to 0.21 after a campaign banner ships. You cannot remove the banner. What do you change?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cls&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reserved space&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dimensions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fonts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;animation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;measurement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;followUp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The banner height is personalized. How do you reserve space without hard-coding one number?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;pickRounds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;scenarios&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;hits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;missed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;hits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;printRubric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Rubric&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`- Coverage: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`- Signals you mentioned: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`- Signals to add: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;missed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`- Follow-up to practice: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;followUp&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;roundsArg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--rounds=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rounds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;roundsArg&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;readline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createInterface&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Frontend performance interview drill&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Answer like you would in a live interview: diagnose, trade off, then propose a safe fix.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nf"&gt;pickRounds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rounds&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Scenario: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Your answer: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;printRubric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;---&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Drill failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exitCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node frontend-performance-drill.mjs &lt;span class="nt"&gt;--rounds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The score is intentionally simple. It is not trying to judge whether your answer is "correct." It checks whether you remembered to mention the signals that usually separate a shallow answer from a senior one.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to answer one scenario well
&lt;/h2&gt;

&lt;p&gt;Take the LCP scenario:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Largest Contentful Paint moved from 2.1s to 4.8s on mid-range Android. The bundle grew by 180KB and image bytes are unchanged.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A weak answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I would use lazy loading and memoization.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A stronger answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since LCP regressed and image bytes did not change, I would first separate network delay from main-thread delay. I would compare the waterfall and the React profiler around the hero render. The 180KB bundle increase suggests parsing or hydration might be delaying the LCP element, so I would check whether the refactor pulled a heavy dependency into the critical path. If so, I would try route-level code splitting or moving non-critical logic behind interaction. Then I would verify LCP on a throttled mid-range profile, not just my laptop.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice the difference. The stronger answer has a metric, a hypothesis, a measurement path, a fix, and a verification step. You do not need perfect wording. You need a defensible sequence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add your own scenarios
&lt;/h2&gt;

&lt;p&gt;The drill becomes more useful when you add scenarios from your own projects. Good prompts usually include one metric, one constraint, and one misleading detail.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"INP is bad only on checkout. The slow interaction is a coupon field, but the API is fast."&lt;/li&gt;
&lt;li&gt;"A modal animation causes jank on low-end devices. Design wants to keep the animation."&lt;/li&gt;
&lt;li&gt;"A dashboard moved from server-rendered HTML to client rendering. TTFB improved, but users say the page feels slower."&lt;/li&gt;
&lt;li&gt;"A third-party analytics script is required by the business and blocks the main thread."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For each one, add six signals you want your answer to include. Use lowercase words because the scorer does simple substring matching.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Coupon field has poor INP&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Interaction to Next Paint is poor when users type in the coupon field. The coupon API responds in 80ms. What do you inspect?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;debounce&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;main thread&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;render&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;profiling&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;state&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nx"&gt;followUp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The input lives inside a large form provider. How do you reduce re-renders without rewriting the form?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When AI practice helps
&lt;/h2&gt;

&lt;p&gt;For frontend interviews, AI practice is most useful when it plays the annoying interviewer: it asks the follow-up you hoped nobody would ask.&lt;/p&gt;

&lt;p&gt;That is also how I use &lt;a href="https://www.aceround.app/blog/frontend-developer-interview-ai/" rel="noopener noreferrer"&gt;aceround.app - AI interview assistant&lt;/a&gt; for frontend prep: not to memorize a perfect answer, but to rehearse the moment where the interviewer says, "Okay, but what would you measure first?"&lt;/p&gt;

&lt;p&gt;Keep the tool honest. If it gives you a polished answer you would never say, rewrite it in your own voice. Interviewers can tell when a candidate is reciting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to measure in real projects
&lt;/h2&gt;

&lt;p&gt;If you want the drill to map back to production work, anchor your scenarios to real browser signals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LCP: usually hero image, heading, or large visible block delayed by network or main-thread work.&lt;/li&gt;
&lt;li&gt;CLS: usually missing dimensions, injected content, font swaps, or animations that change layout.&lt;/li&gt;
&lt;li&gt;INP: usually event handlers, synchronous state updates, expensive re-renders, or long tasks.&lt;/li&gt;
&lt;li&gt;Bundle growth: often hidden in a refactor that imports a full library for one helper.&lt;/li&gt;
&lt;li&gt;Scroll jank: often too many DOM nodes, forced layout, expensive paint, or repeated work in scroll handlers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exact thresholds change as browsers and guidance evolve, so check the current Web Vitals docs before quoting a number in an interview. But the reasoning pattern stays stable.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Should I memorize Web Vitals thresholds?
&lt;/h3&gt;

&lt;p&gt;Know the rough meaning of LCP, CLS, and INP, but do not turn the interview into trivia. A candidate who can explain how they would investigate a bad LCP is usually more convincing than a candidate who only remembers a threshold.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is &lt;code&gt;useMemo&lt;/code&gt; a good performance interview answer?
&lt;/h3&gt;

&lt;p&gt;Only after you have evidence that repeated computation or referential instability is the bottleneck. If your first answer to every performance question is &lt;code&gt;useMemo&lt;/code&gt;, it sounds like guessing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I mention Lighthouse?
&lt;/h3&gt;

&lt;p&gt;Yes, but as one input. Lighthouse is useful for lab diagnostics, while production telemetry shows what real users experience. A strong answer explains when you would use each.&lt;/p&gt;

&lt;h3&gt;
  
  
  How long should I practice this?
&lt;/h3&gt;

&lt;p&gt;Do 10 scenarios, two minutes each. Record yourself once. The recording is uncomfortable, but it shows whether you are explaining trade-offs or just naming tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and disclosure
&lt;/h2&gt;

&lt;p&gt;Useful references: Google Web Vitals documentation, MDN Performance APIs, React Profiler documentation, and the frontend interview preparation notes linked above.&lt;/p&gt;

&lt;p&gt;Disclosure: I used AI assistance to outline and edit parts of this post. The code was run locally with Node 22 before publishing.&lt;/p&gt;

</description>
      <category>career</category>
      <category>interview</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Mine Your Git Log for Better Behavioral Interview Stories</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Wed, 08 Jul 2026 02:57:36 +0000</pubDate>
      <link>https://dev.to/karuha/mine-your-git-log-for-better-behavioral-interview-stories-2ffi</link>
      <guid>https://dev.to/karuha/mine-your-git-log-for-better-behavioral-interview-stories-2ffi</guid>
      <description>&lt;p&gt;Most developers already have a better behavioral interview prep file than any blank STAR worksheet: their Git history. A year of commits shows incidents, trade-offs, migrations, reviews, deadlines, and recoveries. This tutorial turns &lt;code&gt;git log&lt;/code&gt; into a short list of interview stories you can actually remember.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmd7db8bzpnwkbnwqg4j8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmd7db8bzpnwkbnwqg4j8.jpeg" alt="Workflow: git log to interview story cards" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do behavioral interviews feel harder than technical screens?
&lt;/h2&gt;

&lt;p&gt;Technical prep has a clear loop: solve a problem, run tests, compare complexity, repeat.&lt;/p&gt;

&lt;p&gt;Behavioral prep is usually fuzzier. You stare at questions like "Tell me about a time you handled conflict" and try to remember a good story from two years ago. Under interview pressure, that memory search gets worse. You either ramble through the first project that comes to mind, or you pick a story that sounds impressive but does not answer the question.&lt;/p&gt;

&lt;p&gt;Developers should not prepare from memory alone. We have artifacts.&lt;/p&gt;

&lt;p&gt;Your commit history is not a perfect record of your work, but it is a useful index of moments where something changed. It tells you when you shipped, fixed, rewrote, migrated, reverted, optimized, or cleaned up a messy edge case. Those are the raw ingredients of strong behavioral answers.&lt;/p&gt;

&lt;p&gt;The goal is not to let Git write your answer. The goal is to use Git to recover the stories you already earned.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes a commit useful for interview prep?
&lt;/h2&gt;

&lt;p&gt;A single commit is rarely a full story. A cluster of commits often is.&lt;/p&gt;

&lt;p&gt;Look for weeks or pull requests that contain one of these signals:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal in history&lt;/th&gt;
&lt;th&gt;Interview story it might become&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;fix&lt;/code&gt;, &lt;code&gt;rollback&lt;/code&gt;, &lt;code&gt;hotfix&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Handling pressure, taking ownership, recovering from a mistake&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;migrate&lt;/code&gt;, &lt;code&gt;refactor&lt;/code&gt;, &lt;code&gt;rewrite&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Technical judgment, reducing long-term risk, influencing a team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;perf&lt;/code&gt;, &lt;code&gt;scale&lt;/code&gt;, &lt;code&gt;cache&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Problem solving, measuring impact, improving user experience&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;auth&lt;/code&gt;, &lt;code&gt;payment&lt;/code&gt;, &lt;code&gt;security&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Working on high-risk systems, quality standards, careful rollout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;launch&lt;/code&gt;, &lt;code&gt;release&lt;/code&gt;, &lt;code&gt;experiment&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Delivering results, prioritization, cross-functional execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large deletion count&lt;/td&gt;
&lt;td&gt;Simplification, reducing maintenance cost, saying no to complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is exactly the kind of material interviewers want: real context, real constraints, and a decision you personally made.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small Node.js script to mine your Git history
&lt;/h2&gt;

&lt;p&gt;The script below has no dependencies. Run it from a repository where your work history is meaningful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cp"&gt;#!/usr/bin/env node
&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;execFileSync&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;since&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;12 months ago&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;execFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;log&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;`--since=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;since&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--date=short&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--pretty=format:@@@%n%h&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;%ad&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;%s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--shortstat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signalWords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fix&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;incident&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rollback&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;migrate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;launch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;release&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;perf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;performance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scale&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;refactor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;security&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;accessibility&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a11y&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;outage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buckets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;block&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^@@@$/m&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;part&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;part&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;subjectParts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;subjectParts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sr"&gt;/files&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt; changed/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;added&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt; insertion/&lt;/span&gt;&lt;span class="p"&gt;)?.[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deleted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt; deletion/&lt;/span&gt;&lt;span class="p"&gt;)?.[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;week&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; week &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keywordScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signalWords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;added&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;deleted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;keywordScore&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;buckets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;week&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;week&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;commits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;added&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deleted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;buckets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;week&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ranked&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;buckets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;ranked&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\n## &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;week&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;commit&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`- &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (+&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;added&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deleted&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;- Context: What problem, user pain, or business risk made this work matter?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;- Action: What trade-off did you personally make?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;- Result: What shipped, improved, or got prevented?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;- Questions: conflict, ownership, failure, prioritization, impact, ambiguity?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node git-story-miner.mjs &lt;span class="s2"&gt;"18 months ago"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script uses &lt;code&gt;git log --shortstat&lt;/code&gt;, so it can see dates, subjects, and rough change size. The Git documentation has the full option list if you want to customize output with &lt;code&gt;--pretty&lt;/code&gt;, &lt;code&gt;--numstat&lt;/code&gt;, or path filters: &lt;a href="https://git-scm.com/docs/git-log" rel="noopener noreferrer"&gt;https://git-scm.com/docs/git-log&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you turn output into a STAR story?
&lt;/h2&gt;

&lt;p&gt;Take one bucket from the script and write four rough bullets. Do not make it pretty yet.&lt;/p&gt;

&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## 2026-03 week 2
- a19f31c: fix payment retry race condition (+84/-22)
- d4480aa: add idempotency key check (+46/-3)
- 70ce9aa: improve webhook logging (+31/-8)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First pass:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Situation: A payment retry path occasionally created duplicate internal events.&lt;/li&gt;
&lt;li&gt;Task: I had to stop the duplicate path without delaying a release that sales had already committed to.&lt;/li&gt;
&lt;li&gt;Action: I traced the webhook flow, added idempotency checks, improved logs, and rolled it out behind a narrow flag.&lt;/li&gt;
&lt;li&gt;Result: Duplicate events stopped, support had clearer audit logs, and the release stayed on schedule.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is not a polished answer yet. It is a memory handle.&lt;/p&gt;

&lt;p&gt;Now add the details that make it credible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What was the measurable risk: money, uptime, user trust, deadline, security?&lt;/li&gt;
&lt;li&gt;Who else was involved: product, support, another engineer, a manager?&lt;/li&gt;
&lt;li&gt;What alternatives did you reject?&lt;/li&gt;
&lt;li&gt;What would you do differently now?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good behavioral answer is usually 90 to 120 seconds. The action section should be the longest part. Interviewers are not scoring whether the project sounds dramatic. They are scoring judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a six-story bank, not thirty scripted answers
&lt;/h2&gt;

&lt;p&gt;You do not need one story for every behavioral question. You need a small bank of reusable stories with different angles.&lt;/p&gt;

&lt;p&gt;I like this minimum set for developers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A story where you fixed something under pressure.&lt;/li&gt;
&lt;li&gt;A story where you simplified or deleted complexity.&lt;/li&gt;
&lt;li&gt;A story where you disagreed on a technical direction.&lt;/li&gt;
&lt;li&gt;A story where you made a mistake and recovered.&lt;/li&gt;
&lt;li&gt;A story where you influenced people without formal authority.&lt;/li&gt;
&lt;li&gt;A story where your work had measurable user or business impact.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your Git history will usually surface candidates for the first four quickly. The last two may need calendar notes, docs, product metrics, or PR comments. That is fine. Git is the index, not the whole archive.&lt;/p&gt;

&lt;p&gt;Once you have six stories, map each one to question categories:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Story&lt;/th&gt;
&lt;th&gt;Can answer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Payment retry fix&lt;/td&gt;
&lt;td&gt;ownership, pressure, quality, ambiguity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Legacy module deletion&lt;/td&gt;
&lt;td&gt;prioritization, technical judgment, influence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accessibility audit&lt;/td&gt;
&lt;td&gt;customer empathy, details, cross-functional work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bad migration estimate&lt;/td&gt;
&lt;td&gt;failure, learning, communication&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This prevents the common mistake of memorizing 30 slightly different answers. You are not trying to sound like a FAQ page. You are trying to retrieve the right real story fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should you not do with this method?
&lt;/h2&gt;

&lt;p&gt;Do not expose private code or company-sensitive details. Commit subjects can contain customer names, incident details, or internal system names. Before using a story in an interview, rewrite it at the right abstraction level.&lt;/p&gt;

&lt;p&gt;Do not inflate a small commit into a heroic narrative. If your role was minor, say so and explain what you learned. Senior interviewers can tell when a story has been stretched.&lt;/p&gt;

&lt;p&gt;Do not let the script pick the story for you. It ranks signal, not meaning. A tiny commit that unblocked a teammate may be a better leadership story than a 2,000-line migration.&lt;/p&gt;

&lt;p&gt;And do not read a prepared answer word for word. Memorize the facts: timeline, stakes, your action, result. Let the sentences vary each time you practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI can help without making you sound fake
&lt;/h2&gt;

&lt;p&gt;After you have the raw stories, AI is useful as a pressure-testing partner. Paste your bullet version and ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What part of this answer is too vague?&lt;/li&gt;
&lt;li&gt;What follow-up would a skeptical interviewer ask?&lt;/li&gt;
&lt;li&gt;Which behavioral questions could this story answer?&lt;/li&gt;
&lt;li&gt;Is the result specific enough?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For spoken practice, an interview tool can play the interviewer and force you to answer out loud. I use this workflow with &lt;a href="https://www.aceround.app/" rel="noopener noreferrer"&gt;aceround.app — AI interview assistant&lt;/a&gt; when I want the story challenged in real time instead of polished silently in a document.&lt;/p&gt;

&lt;p&gt;The important boundary: AI should help you find gaps in a real story, not invent a better one. Interviews reward specificity. Fake specificity collapses on the first follow-up.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 30-minute practice loop
&lt;/h2&gt;

&lt;p&gt;Use this when you have an interview coming up and do not know where to start.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the script for the last 12 to 18 months.&lt;/li&gt;
&lt;li&gt;Pick five promising weeks or PR clusters.&lt;/li&gt;
&lt;li&gt;Write rough Situation, Task, Action, Result bullets for each.&lt;/li&gt;
&lt;li&gt;Delete any story where you cannot explain your personal decision.&lt;/li&gt;
&lt;li&gt;Add one number or observable outcome to each remaining story.&lt;/li&gt;
&lt;li&gt;Practice each answer once out loud with a timer.&lt;/li&gt;
&lt;li&gt;Ask one follow-up question after every answer: "Why did you choose that?"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thirty minutes will not make you fully prepared, but it will replace panic-searching your memory with a concrete story bank.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Should I include personal projects?
&lt;/h3&gt;

&lt;p&gt;Yes, especially if you are early-career or changing stacks. Personal projects still show judgment: why you chose a tool, how you handled scope, what broke, and what you learned. Just be honest about the stakes.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if my company squashes commits?
&lt;/h3&gt;

&lt;p&gt;Use PR titles, release notes, issue trackers, or your own weekly notes. The same idea applies: mine artifacts instead of relying on memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if my commits are messy?
&lt;/h3&gt;

&lt;p&gt;That is normal. You are not presenting the commits. You are using them as retrieval cues. Messy history can still point to useful stories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this only for software engineers?
&lt;/h3&gt;

&lt;p&gt;No, but it is especially natural for developers because Git already captures a timeline of decisions. Designers can use Figma versions, PMs can use launch docs, and data analysts can use notebooks or dashboard changelogs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Git documentation: &lt;code&gt;git log&lt;/code&gt; options and formatting: &lt;a href="https://git-scm.com/docs/git-log" rel="noopener noreferrer"&gt;https://git-scm.com/docs/git-log&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Disclosure: I used AI assistance to outline and edit this article, then manually checked the code, links, and claims before publishing.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>interview</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Practice Backend Incident Interviews With a 70-Line Node.js Drill</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Sun, 05 Jul 2026 14:49:36 +0000</pubDate>
      <link>https://dev.to/karuha/practice-backend-incident-interviews-with-a-70-line-nodejs-drill-4p4g</link>
      <guid>https://dev.to/karuha/practice-backend-incident-interviews-with-a-70-line-nodejs-drill-4p4g</guid>
      <description>&lt;p&gt;Backend incident questions are not trivia. They test whether you can diagnose safely under uncertainty, explain trade-offs out loud, and avoid making the outage worse. This tutorial gives you a small Node.js drill that randomizes production-style scenarios, asks the five questions interviewers care about, and scores whether your answer is evidence-led.&lt;/p&gt;

&lt;p&gt;If you are preparing for a backend, platform, SRE-adjacent, or senior full-stack interview, run this drill until your answers stop sounding like a list of tools and start sounding like an operator thinking clearly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why incident questions are different from normal backend trivia
&lt;/h2&gt;

&lt;p&gt;A normal backend question has a clean target:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does idempotency mean?&lt;/li&gt;
&lt;li&gt;When would you use a queue?&lt;/li&gt;
&lt;li&gt;How does a database index work?&lt;/li&gt;
&lt;li&gt;What is the difference between 401 and 403?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An incident question is messier:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Your API latency jumped from 180ms to 4.8s fifteen minutes after a deploy. Error rate is flat. Database CPU is 96%. Walk me through the first minute."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The interviewer is not only checking whether you know databases, caches, traces, queues, and rollbacks. They are checking your operating model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do you trust evidence before guessing?&lt;/li&gt;
&lt;li&gt;Can you scope blast radius quickly?&lt;/li&gt;
&lt;li&gt;Can you hold two hypotheses without overcommitting?&lt;/li&gt;
&lt;li&gt;Can you choose a safe test instead of poking production randomly?&lt;/li&gt;
&lt;li&gt;Can you mitigate before root cause is fully known?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why reading incident postmortems helps, but it is not enough. In an interview, you need retrieval plus narration. You have to say the process clearly while someone is evaluating you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs8ytj23njhl8wm7noo6u.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs8ytj23njhl8wm7noo6u.jpeg" alt="Five-step backend incident interview loop" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The five-step answer shape
&lt;/h2&gt;

&lt;p&gt;Use this loop when the prompt sounds like production is on fire:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;What the interviewer wants&lt;/th&gt;
&lt;th&gt;Bad answer pattern&lt;/th&gt;
&lt;th&gt;Strong answer pattern&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Detect&lt;/td&gt;
&lt;td&gt;Which signal you trust first&lt;/td&gt;
&lt;td&gt;"I check logs"&lt;/td&gt;
&lt;td&gt;"I start with service metrics, then sample traces, because one log line can lie"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;How wide the issue is&lt;/td&gt;
&lt;td&gt;"Maybe the DB is slow"&lt;/td&gt;
&lt;td&gt;"Compare region, endpoint, customer tier, deploy window, and dependency health"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hypothesize&lt;/td&gt;
&lt;td&gt;Whether you can reason under uncertainty&lt;/td&gt;
&lt;td&gt;"It is probably Redis"&lt;/td&gt;
&lt;td&gt;"If cache hit rate dropped, I expect DB QPS to rise; I would disprove it by comparing pre/post deploy cache metrics"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test&lt;/td&gt;
&lt;td&gt;Fastest safe check&lt;/td&gt;
&lt;td&gt;"I run some queries"&lt;/td&gt;
&lt;td&gt;"Sample slow traces and inspect one hot query plan before changing anything"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mitigate&lt;/td&gt;
&lt;td&gt;How you reduce harm&lt;/td&gt;
&lt;td&gt;"Fix the bug"&lt;/td&gt;
&lt;td&gt;"Rollback, disable the flag, throttle retries, or shed non-critical traffic while communicating status"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The drill below forces you through those five steps. It is intentionally small. You can paste it into a file, run it, and practice speaking your answers out loud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the Node.js incident drill
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;incident-drill.mjs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createInterface&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:readline/promises&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;stdin&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stdout&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scenarios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;API p95 latency jumped from 180ms to 4.8s after deploy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Checkout service, Node.js API, Postgres, Redis cache, 15 minutes after a release.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;clues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;p95 up, error rate flat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DB CPU 96%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cache hit rate dropped from 82% to 23%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Background jobs are delayed by 40 minutes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Queue workers process invoices. Web traffic is normal, but customers report missing receipts.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;clues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;queue depth growing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;workers restarted twice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one downstream API returns many 429s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error rate is 12% in one region only&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Multi-region backend behind a global load balancer. The incident started without a deploy.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;clues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;us-east affected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;health checks flapping&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;database replicas lagging 90 seconds&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Detect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What signal do you trust first, and why?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;metric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;log&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;trace&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alert&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Scope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;How do you narrow blast radius in 60 seconds?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;region&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;endpoint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;customer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deploy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dependency&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hypothesize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Give two likely causes and one thing that would disprove each.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;because&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;if&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;disprove&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;compare&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;baseline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What is the fastest safe check you would run?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rollback&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sample&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;feature flag&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;canary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mitigate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What do you do before you know the root cause?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rollback&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;throttle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;disable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scale&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;communicate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;demoAnswers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I trust metrics first, then dashboard traces, because one log line may lie.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Compare region, endpoint, customer tier, deploy time, and dependency health.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;If cache hit rate fell, compare to baseline; if DB changed, disprove with query plans.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sample slow traces, inspect the hot query, and consider a canary rollback.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Rollback or disable the feature flag, throttle retries, and communicate status.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;demoMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--demo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;demoMode&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createInterface&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scenarios&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n&amp;gt; `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;demoMode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;demoAnswers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;question&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;Backend incident interview drill&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Scenario:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Context:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Clues:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clue&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;scenario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clues&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;ask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`Signals heard: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Missing concrete signal. Try again with evidence.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\nScore: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/10`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Strong: structured, evidence-led, and safe.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Repeat once. Add metrics, blast radius, and a reversible mitigation.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the demo mode first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node incident-drill.mjs &lt;span class="nt"&gt;--demo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run it interactively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node incident-drill.mjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The score is deliberately crude. It is not trying to grade your engineering ability. It is checking whether your spoken answer contains the nouns interviewers listen for: metrics, traces, regions, endpoints, dependencies, baselines, queries, rollbacks, throttling, and communication.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use this in a 30-minute practice session
&lt;/h2&gt;

&lt;p&gt;Do not silently type perfect answers. That misses the point.&lt;/p&gt;

&lt;p&gt;Use this format:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the script and read the scenario out loud.&lt;/li&gt;
&lt;li&gt;Give yourself 60 seconds for the Detect and Scope answers.&lt;/li&gt;
&lt;li&gt;Give yourself 90 seconds for Hypothesize and Test.&lt;/li&gt;
&lt;li&gt;Give yourself 45 seconds for Mitigate.&lt;/li&gt;
&lt;li&gt;After the score, rewrite only the weakest answer and say it again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A good session is not one where you sound polished. A good session is one where your second attempt is more specific than your first.&lt;/p&gt;

&lt;p&gt;For example, this is vague:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I would check the logs and maybe rollback if something looks bad."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is stronger:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Because the latency spike started after a deploy and errors are flat, I would first compare p50, p95, and p99 latency by endpoint and region. If one endpoint regressed, I would sample traces for that route and compare DB query count before and after the release. If the new code path is obvious, I would roll back or disable the feature flag before digging into root cause."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice the difference: the second answer names evidence, blast radius, a falsifiable hypothesis, a safe test, and a reversible mitigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add your own scenarios
&lt;/h2&gt;

&lt;p&gt;The easiest way to make the drill useful is to add scenarios from your own work history. Keep them anonymous and remove employer-specific details.&lt;/p&gt;

&lt;p&gt;Good scenario inputs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Kafka consumer lag grows for one topic after a schema change"&lt;/li&gt;
&lt;li&gt;"Payment API is idempotent in code but duplicate charges still appear"&lt;/li&gt;
&lt;li&gt;"Search endpoint is fast for small tenants and slow for enterprise tenants"&lt;/li&gt;
&lt;li&gt;"A cron job succeeds but downstream data is missing"&lt;/li&gt;
&lt;li&gt;"A memory leak appears only after traffic doubles"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try to include three clues per scenario: one metric, one timing clue, and one dependency clue. That gives you enough evidence to reason without turning the exercise into a mystery novel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI fits without turning the prep into a shortcut
&lt;/h2&gt;

&lt;p&gt;A terminal script is useful because it makes you practice. A human mock interviewer is better because they interrupt, ask follow-ups, and notice when you are hand-waving. AI sits in the middle: good enough to create repetitions, ask follow-ups, and keep you honest when you drift into vague language.&lt;/p&gt;

&lt;p&gt;I work on &lt;a href="https://aceround.app" rel="noopener noreferrer"&gt;aceround.app — AI interview assistant&lt;/a&gt;, so I obviously care about this category. But the rule I use for my own prep is simple: use AI to create pressure and feedback, not to replace your judgment. If the tool gives you an answer you could not defend, it is not preparation. It is debt.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Should I mention rollback immediately?
&lt;/h3&gt;

&lt;p&gt;Mention it as an option, not a reflex. A strong answer says when rollback is safe: recent deploy, clear regression window, reversible change, no dangerous migration, and no evidence that rollback would worsen data consistency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I always start with logs?
&lt;/h3&gt;

&lt;p&gt;No. Logs are useful, but interviews reward signal hierarchy. Start with high-level metrics and user impact, then use traces and logs to explain why the metric moved.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if I have never handled a real production incident?
&lt;/h3&gt;

&lt;p&gt;Use open-source postmortems and your own side projects. The interview skill is not pretending you were on-call for a massive system. It is showing disciplined reasoning: evidence, scope, hypothesis, test, mitigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is the keyword score too easy to game?
&lt;/h3&gt;

&lt;p&gt;Yes, and that is fine. The score is a practice constraint, not an evaluation system. Once you consistently score 8 or above, stop caring about the number and focus on whether your answer sounds natural under time pressure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final take
&lt;/h2&gt;

&lt;p&gt;Backend incident interviews are stressful because they compress production judgment into a few minutes. You do not need a memorized answer for every outage. You need a repeatable loop: detect, scope, hypothesize, test, mitigate.&lt;/p&gt;

&lt;p&gt;Run the drill five times. Record one answer. Listen for vague phrases like "check things" or "look into the database." Replace them with specific signals and safe actions. That one habit will improve more backend interview answers than another night of passive reading.&lt;/p&gt;




&lt;p&gt;Disclosure: I used AI assistance to draft and edit this article, then manually reviewed the technical flow, ran the Node.js script in &lt;code&gt;--demo&lt;/code&gt; mode, checked the generated images, and rewrote the promotional section to keep the article primarily instructional.&lt;/p&gt;

</description>
      <category>career</category>
      <category>interview</category>
      <category>javascript</category>
      <category>backend</category>
    </item>
    <item>
      <title>Turn Any Job Description Into a Mock Interview Pack With 70 Lines of Node.js</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Sat, 04 Jul 2026 12:06:03 +0000</pubDate>
      <link>https://dev.to/karuha/turn-any-job-description-into-a-mock-interview-pack-with-70-lines-of-nodejs-4695</link>
      <guid>https://dev.to/karuha/turn-any-job-description-into-a-mock-interview-pack-with-70-lines-of-nodejs-4695</guid>
      <description>&lt;p&gt;Most interview prep fails because it starts from generic question lists. Start from the job description instead: extract role signals, turn them into technical and behavioral prompts, then rehearse the gaps. Below is a small dependency-free Node.js script that turns any JD into a focused mock interview pack.&lt;/p&gt;

&lt;p&gt;If you are applying to developer roles, you have probably seen the same prep advice recycled everywhere: grind more LeetCode, memorize STAR, read system design notes, repeat.&lt;/p&gt;

&lt;p&gt;That advice is not wrong. It is just too broad.&lt;/p&gt;

&lt;p&gt;A frontend platform role, a backend payments role, and a data engineering role can all say “Software Engineer” while testing completely different things. The job description is the closest public artifact you have to the interview rubric. It contains repeated nouns, required technologies, soft-skill verbs, and business outcomes. Those signals are enough to build a better practice plan than a generic checklist.&lt;/p&gt;

&lt;p&gt;Let’s build a tiny local tool for that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are we building?
&lt;/h2&gt;

&lt;p&gt;A CLI that reads a job description from a &lt;code&gt;.txt&lt;/code&gt; file and prints a JSON practice pack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the most common role keywords&lt;/li&gt;
&lt;li&gt;technical questions mapped to detected skills&lt;/li&gt;
&lt;li&gt;behavioral questions mapped to role signals&lt;/li&gt;
&lt;li&gt;risk areas you should prepare concrete examples for&lt;/li&gt;
&lt;li&gt;a 7-day prep schedule&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No API key. No package install. No model call. The point is not to “AI-generate perfect answers.” The point is to create a structured rehearsal surface from the exact role you are applying for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Save a job description
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;jd.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Senior Frontend Engineer

We use React, TypeScript, GraphQL, Jest, accessibility, performance budgets,
design systems, and mentoring. You will own checkout flow reliability and
collaborate with product and design.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use a real JD when you run this. Keep the responsibilities, requirements, and nice-to-have sections. Delete salary, benefits, and boilerplate company text unless it contains role-specific language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create the script
&lt;/h2&gt;

&lt;p&gt;Save this as &lt;code&gt;interview-pack.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cp"&gt;#!/usr/bin/env node
&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;inputPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Usage: node interview-pack.js &amp;lt;job-description.txt&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;STOP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a an and are as at be by for from has have in into is it of on or our the this to we with you your will&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SKILL_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Explain a time you reduced unnecessary React re-renders.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Build a controlled input and explain state ownership.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;typescript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;When would you use a discriminated union instead of optional fields?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;How do you model API errors without losing type safety?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;How would you debug an over-fetching GraphQL query?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Design a pagination strategy for a GraphQL list.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;performance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What metrics would you check before optimizing a slow page?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Walk through your first 15 minutes debugging a p95 latency spike.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;accessibility&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;How do you test keyboard navigation in a custom component?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What ARIA usage have you removed rather than added?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What makes a test valuable instead of brittle?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;How would you test a debounced search box?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;design system&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;How do you introduce a breaking component API change?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What belongs in a design system and what should stay app-specific?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GENERIC_TECH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Describe the most production-like bug you fixed in this area.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What trade-off would you make if delivery speed and reliability conflict?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;How would you explain this technical decision to a non-engineer?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BEHAVIORAL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ownership&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tell me about a time you owned a project with unclear requirements.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;collaborate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tell me about a disagreement with product, design, or another engineer.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mentor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tell me about a time you helped another engineer level up.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reliability&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tell me about a production incident or near miss you learned from.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lead&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tell me about a time you led without formal authority.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[^&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9+#&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;STOP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;matchingSkills&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lower&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;SKILL_MAP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;makePack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;skills&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;matchingSkills&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;technicalQuestions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;skills&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;questions&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;questions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;question&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;behavioralQuestions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BEHAVIORAL&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;question&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;question&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;technicalQuestions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;technicalQuestions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;technicalQuestions&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GENERIC_TECH&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;skill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;role&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;question&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
    &lt;span class="na"&gt;behavioralQuestions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;behavioralQuestions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;behavioralQuestions&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BEHAVIORAL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;question&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;question&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
    &lt;span class="na"&gt;riskAreas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyword&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Prepare a concrete story or project detail for "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;keyword&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;".`&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;sevenDayPlan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Day 1: rewrite the JD into 5 role outcomes.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Day 2: answer every technical question out loud, no notes.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Day 3: implement one small exercise related to the top skill.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Day 4: build 4 STAR stories mapped to the JD signals.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Day 5: run a 45-minute mock interview and record it.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Day 6: fix the two weakest answers, not all answers.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Day 7: rehearse setup, questions for interviewer, and opening pitch.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;makePack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node interview-pack.js jd.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"accessibility"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"budgets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"collaborate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"design"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"engineer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"flow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"frontend"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"graphql"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"mentoring"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"performance"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"technicalQuestions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"skill"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"question"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Explain a time you reduced unnecessary React re-renders."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"skill"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"typescript"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"question"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"When would you use a discriminated union instead of optional fields?"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"behavioralQuestions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"signal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"collaborate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"question"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tell me about a disagreement with product, design, or another engineer."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your full output will include more questions and the 7-day plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this works better than a generic list
&lt;/h2&gt;

&lt;p&gt;A generic interview list optimizes for coverage. A JD-derived pack optimizes for relevance.&lt;/p&gt;

&lt;p&gt;If a role repeats “reliability,” “checkout,” “payments,” and “incident response,” you should not spend the same amount of time on abstract frontend trivia as someone applying to a design-system role. You need production stories, failure-mode thinking, and clear examples of trade-offs under pressure.&lt;/p&gt;

&lt;p&gt;If a role mentions “mentoring,” “cross-functional,” and “roadmap,” you should prepare behavioral stories about influence, disagreement, and ambiguity. A technically strong answer can still miss the rubric if the role is really asking whether you can operate at senior scope.&lt;/p&gt;

&lt;p&gt;The keyword list is not magic. It is a forcing function. It makes you ask: “Can I tell a real story about this word?”&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use the pack without sounding scripted
&lt;/h2&gt;

&lt;p&gt;Do not write perfect paragraphs for every question. That is how candidates start sounding like they are reading from a document.&lt;/p&gt;

&lt;p&gt;Use this format instead:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prep item&lt;/th&gt;
&lt;th&gt;What to write&lt;/th&gt;
&lt;th&gt;What to rehearse&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Technical question&lt;/td&gt;
&lt;td&gt;3 bullets: context, trade-off, result&lt;/td&gt;
&lt;td&gt;Explain it out loud in 90 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Behavioral question&lt;/td&gt;
&lt;td&gt;STAR outline, not full prose&lt;/td&gt;
&lt;td&gt;Tell it twice: structured, then conversational&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Risk area&lt;/td&gt;
&lt;td&gt;One project or bug that proves it&lt;/td&gt;
&lt;td&gt;A follow-up question you hope they ask&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7-day plan&lt;/td&gt;
&lt;td&gt;One deliverable per day&lt;/td&gt;
&lt;td&gt;Stop when the deliverable is done&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The “structured, then conversational” part matters. Structured practice makes the story coherent. Conversational practice keeps you human.&lt;/p&gt;

&lt;h2&gt;
  
  
  A better technical exercise
&lt;/h2&gt;

&lt;p&gt;For developer interviews, add one more field to each technical question: a tiny build task.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buildTasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;react&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Build a controlled search box with loading, empty, and error states.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;typescript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Model a success/error API response as a discriminated union.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sketch a cursor pagination response and explain the edge cases.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Measure and reduce one unnecessary render in a small demo.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;accessibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Make a custom dropdown keyboard navigable.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interviewers rarely only test whether you know a definition. They test whether you can move between code, trade-offs, and explanation. A good prep session should do the same:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build something small.&lt;/li&gt;
&lt;li&gt;Explain the decisions out loud.&lt;/li&gt;
&lt;li&gt;Ask yourself what breaks at scale.&lt;/li&gt;
&lt;li&gt;Turn the answer into a shorter version.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last step is underrated. In a live interview, a correct 6-minute answer can feel worse than a clear 90-second answer with room for follow-up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI fits, and where it does not
&lt;/h2&gt;

&lt;p&gt;This script intentionally avoids calling an AI API because the first pass should be deterministic. You want to see the raw signals in the JD before a model smooths them out.&lt;/p&gt;

&lt;p&gt;After that, AI can be useful in three narrow ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ask follow-up questions for the weakest items&lt;/li&gt;
&lt;li&gt;convert a rough STAR outline into clearer spoken English&lt;/li&gt;
&lt;li&gt;run a timed mock interview so you practice under pressure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not use AI to invent experience. Interviewers notice when a story has no operational detail: no constraints, no trade-off, no metric, no human friction. Use AI to pressure-test your real material, not replace it.&lt;/p&gt;

&lt;p&gt;If you want a dedicated tool for the mock-interview step, &lt;a href="https://aceround.app" rel="noopener noreferrer"&gt;aceround.app — AI interview assistant&lt;/a&gt; is one option. I would still run the local JD pass first; the better your input material is, the better any practice tool becomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to extend the script
&lt;/h2&gt;

&lt;p&gt;A few useful extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add skill packs for your stack: Python, Go, Java, SQL, cloud, data engineering.&lt;/li&gt;
&lt;li&gt;Add company-level signals: “startup,” “enterprise,” “regulated,” “global,” “on-call.”&lt;/li&gt;
&lt;li&gt;Export Markdown instead of JSON so you can keep the pack in your notes.&lt;/li&gt;
&lt;li&gt;Add a scoring pass after mock practice: clarity, specificity, trade-off, result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep it small. The goal is not to build an applicant tracking system. The goal is to walk into the interview with sharper reps than “I read 200 questions last night.”&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Should I paste the whole job description?
&lt;/h3&gt;

&lt;p&gt;Yes, but remove generic company boilerplate. The responsibilities and requirements sections are the most useful. If the same word appears in both sections, treat it as high priority.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is keyword matching too simple?
&lt;/h3&gt;

&lt;p&gt;It is simple by design. For interview prep, explainability beats cleverness. If the script says “reliability” is a risk area, you can immediately decide whether you have a story for it. A black-box score is less useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if the JD is vague?
&lt;/h3&gt;

&lt;p&gt;Use the generic questions, then add signals from the recruiter screen. Vague JDs are common. After the first call, update &lt;code&gt;jd.txt&lt;/code&gt; with the recruiter’s language and rerun the script.&lt;/p&gt;

&lt;h3&gt;
  
  
  How long should each answer be?
&lt;/h3&gt;

&lt;p&gt;Aim for 60-120 seconds for most behavioral and technical explanation answers. Senior system design answers can run longer, but even there your opening should be short and structured.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use this for every application?
&lt;/h3&gt;

&lt;p&gt;Use it for roles you actually care about. For low-priority applications, it is enough to scan the keywords and update your story bank.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and disclosure
&lt;/h2&gt;

&lt;p&gt;Further reading: the Node.js file system documentation for &lt;code&gt;fs.readFileSync&lt;/code&gt;, DEV Community editor guidance for post metadata, and the DEV Community Code of Conduct for disclosure expectations.&lt;/p&gt;

&lt;p&gt;Disclosure: this post was drafted with AI assistance, then edited and checked by a human. The code path above was run locally with Node.js before publishing.&lt;/p&gt;

</description>
      <category>career</category>
      <category>interview</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>## The Interview You Keep Failing Without Knowing Why</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Sun, 05 Apr 2026 06:17:48 +0000</pubDate>
      <link>https://dev.to/karuha/-the-interview-you-keep-failing-without-knowing-why-2l5h</link>
      <guid>https://dev.to/karuha/-the-interview-you-keep-failing-without-knowing-why-2l5h</guid>
      <description>&lt;h2&gt;
  
  
  The Interview You Keep Failing Without Knowing Why
&lt;/h2&gt;

&lt;p&gt;A friend of mine — genuinely one of the best backend engineers I've ever worked with — got rejected from Stripe last year after passing the technical rounds. The recruiter's feedback was four words: "Not a culture fit." He'd optimized for six weeks. LeetCode, system design, the whole grind. And then lost to something he couldn't study for, or so he thought.&lt;/p&gt;

&lt;p&gt;I've seen this happen more times than I can count. Strong engineers — people who can design distributed systems in their sleep — getting quietly filtered out in a round that feels vague and almost insulting in how little feedback it generates. So I started paying closer attention to what these rounds actually test, because "culture fit" as a phrase is doing a lot of heavy lifting.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's Not About Being Likable
&lt;/h2&gt;

&lt;p&gt;The first misconception is that culture fit is a vibe check — interviewers deciding if they'd enjoy getting a beer with you. That does happen, and it's real and unfair in ways worth acknowledging. But at most serious engineering orgs, the culture round is actually testing something much more specific: &lt;strong&gt;can you operate effectively inside our particular decision-making environment?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stripe, for example, has a strong writing culture. Documents over meetings. Precision in communication. When they assess culture fit, they're partly asking: does this person think clearly enough to write a six-page doc that changes a technical direction? That's not personality — that's a skill.&lt;/p&gt;

&lt;p&gt;Meta's version of this round often probes something different — how do you handle working in a massive org where your project might get cancelled by someone three levels above you? They want to know if you'll stay motivated and constructive when the incentive structures feel arbitrary. Again, not personality. Operational maturity.&lt;/p&gt;

&lt;p&gt;So when you fail a culture round, it's worth asking: which specific cultural attribute did I miss? Not "why didn't they like me?" but "what operating mode was I not demonstrating?"&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Things Being Tested
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Communication under ambiguity&lt;/strong&gt; is the big one. Most culture interviews involve questions like "tell me about a time you disagreed with a technical decision" or "describe a project that failed." These are deceptively hard. Engineers who are used to having a correct answer tend to either over-justify themselves ("I was right and here's the proof") or deflect into vagueness. Neither reads well.&lt;/p&gt;

&lt;p&gt;What interviewers actually want to see: you can hold uncertainty comfortably, you can articulate multiple valid perspectives, and you can explain what you did &lt;em&gt;given&lt;/em&gt; the ambiguity rather than pretending it wasn't there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handling conflict with stakeholders&lt;/strong&gt; is another area where strong individual contributors often fumble. A lot of great engineers have built a mental model where technical correctness wins arguments. That works fine when you're junior. As you get more senior, or when you're interviewing at companies with flat hierarchies, the actual question is: what do you do when you're right but the org is going a different direction? If your answer is "I push until I win or I leave," that's going to land badly at companies that operate by consensus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calibration on scope and ownership&lt;/strong&gt; also comes up constantly. Companies like Shopify or Linear (both with strong individual ownership cultures) are listening for whether you proactively define the problem, or whether you wait to be told what to build. A candidate who talks exclusively about executing against a spec — even brilliantly — signals that they might need more management than those orgs want to provide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Smart Engineers Specifically Struggle Here
&lt;/h2&gt;

&lt;p&gt;There's a particular failure mode I've noticed among very technically skilled candidates. They've been rewarded throughout their career for precision and correctness. In technical interviews, you get points for being right. In culture rounds, being technically precise about your stories can actually hurt you.&lt;/p&gt;

&lt;p&gt;A concrete example: someone describing a conflict they navigated might give a perfectly accurate, complete account of what happened — but structure it like a post-mortem rather than a narrative. Dates, decision trees, the root cause. The interviewer walks away thinking "this person is methodical but weirdly cold." That's not a personality flaw. It's a communication framing problem that's entirely fixable.&lt;/p&gt;

&lt;p&gt;The other trap is &lt;strong&gt;over-preparing the wrong content&lt;/strong&gt;. I went into a culture round at a fintech startup a few years ago with polished STAR-format answers to every behavioral question I could find. I sounded like a training manual. The interviewer — to her credit — told me afterward that I seemed rehearsed in a way that made it hard to trust what I was actually like to work with. What she was really asking for was &lt;em&gt;spontaneous&lt;/em&gt; evidence of judgment, not recited examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Helps
&lt;/h2&gt;

&lt;p&gt;Practicing behavioral questions out loud is still useful, but the goal should be fluency, not memorization. There's a difference between knowing your stories well enough to tell them naturally, versus drilling until you've sanded off all the texture.&lt;/p&gt;

&lt;p&gt;I've used a few tools to practice this kind of thing. Pramp and Interviewing.io are good for peer feedback, though they skew heavily toward technical rounds. AceRound AI has a behavioral mock interview mode that I found decent for getting initial reps in — not as a replacement for talking to real humans, but useful when you want to stress-test whether your stories make sense before you inflict them on a friend. Interview Kickstart runs structured programs with coaches if you want a more guided approach, though the time commitment is significant.&lt;/p&gt;

&lt;p&gt;But honestly, the most useful thing I did was ask three people who'd worked with me to describe a time they'd seen me handle conflict or navigate ambiguity. Their framing was almost always more useful than what I would have said myself. You find out pretty quickly which stories actually land versus which ones only make sense if you already know the full context.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Structural Problem You Can't Fully Solve
&lt;/h2&gt;

&lt;p&gt;I want to be honest about something: culture fit interviews are also genuinely biased in ways that aren't about your preparation. There's real research showing that interviewers use "culture fit" as a proxy for "reminds me of people already here," which systematically disadvantages people who didn't come from the same schools, networks, or communication styles as the existing team.&lt;/p&gt;

&lt;p&gt;This doesn't mean you can't prepare or improve. It means you should also be realistic about the signal. If you're consistently passing technical rounds and failing culture rounds across &lt;em&gt;different&lt;/em&gt; types of companies, that's worth examining closely. If it's one specific company type — say, every VC-backed Series B startup — that might tell you something about fit that's worth taking seriously rather than trying to optimize around.&lt;/p&gt;

&lt;p&gt;Some mismatches are real. I'm genuinely not a good fit for highly consensus-driven orgs where everything goes through a committee. I've tried. I've optimized my stories. I still interview poorly for those roles because I actually don't enjoy that working style, and experienced interviewers can sense the tension between what I'm saying and what I actually believe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reframing the Prep
&lt;/h2&gt;

&lt;p&gt;The shift that helped me most was stopping to think about culture fit as a test of &lt;em&gt;my communication about the past&lt;/em&gt; and starting to think about it as a test of &lt;em&gt;my operating model for the future&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Companies aren't really asking "did you handle this 2019 conflict well?" They're asking "given how you handled that 2019 conflict, how will you handle the 2025 conflict we already know is coming?" &lt;/p&gt;

&lt;p&gt;Once I started answering with that frame — connecting past behavior explicitly to how I'd approach the specific challenges of the new role — the rounds started going differently. Not perfectly. But differently.&lt;/p&gt;

&lt;p&gt;My friend from Stripe eventually got an offer at Plaid, which turned out to be a much better fit for how he actually works. He didn't change who he was. He got clearer about what operating environment he was selling himself into — and where his natural style was already a feature rather than something to hide.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want real-time interview assistance? &lt;a href="https://aceround.app" rel="noopener noreferrer"&gt;AceRound AI&lt;/a&gt; works live during Zoom/Meet interviews.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>interview</category>
      <category>career</category>
      <category>jobsearch</category>
      <category>ai</category>
    </item>
    <item>
      <title>Six Months, Fourteen Rejections, and Finally a Job Offer I Didn't Have to Talk Myself Into</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Sun, 05 Apr 2026 06:16:05 +0000</pubDate>
      <link>https://dev.to/karuha/six-months-fourteen-rejections-and-finally-a-job-offer-i-didnt-have-to-talk-myself-into-306o</link>
      <guid>https://dev.to/karuha/six-months-fourteen-rejections-and-finally-a-job-offer-i-didnt-have-to-talk-myself-into-306o</guid>
      <description>&lt;p&gt;The lowest point wasn't the rejection from Cloudflare. It was two weeks after that, when I drove to my brother-in-law's place for Thanksgiving and lied to his face about how the job search was going.&lt;/p&gt;

&lt;p&gt;"Oh yeah, things are moving. Just evaluating a few offers." I said it with the confidence of someone who had received zero offers and had a phone screen with a mid-sized SaaS company scheduled for the following Monday that I was quietly terrified about. That was November 2023. I'd been searching since June.&lt;/p&gt;

&lt;p&gt;Let me back up.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Was Even Looking
&lt;/h2&gt;

&lt;p&gt;I'd spent three years at a fintech startup in Austin doing infrastructure work — Kubernetes on EKS, Terraform for basically everything, CI/CD pipelines in GitHub Actions and occasionally Jenkins when someone made questionable architectural decisions before I joined. The work was good. The team was small. I learned a lot.&lt;/p&gt;

&lt;p&gt;Then the company went through a round of layoffs in May 2023, and I survived the first cut but not the second. Forty percent of the engineering org, gone in an afternoon. I had thirty days of runway on my employment before the severance kicked in, and I spent roughly twenty-nine of those days in denial.&lt;/p&gt;

&lt;p&gt;By June I was actively job hunting. I figured: three years of real DevOps experience, comfortable with AWS, decent with GCP, could hold a conversation about observability without embarrassing myself. How hard could this be?&lt;/p&gt;

&lt;p&gt;Very hard, as it turned out.&lt;/p&gt;




&lt;h2&gt;
  
  
  June–August: The Confidence Phase (And Its Collapse)
&lt;/h2&gt;

&lt;p&gt;The first two months were almost encouraging. I got responses. I got phone screens. I got through a first round at HashiCorp (remote, which I wanted badly) and made it to a technical interview at a Series B company in Denver before stalling out.&lt;/p&gt;

&lt;p&gt;The HashiCorp process was humbling in a specific way. I'd used Terraform for years. I thought that meant I'd be comfortable in their technical rounds. But their questions weren't just "do you know Terraform" — they were "do you understand the architectural decisions behind how Terraform works, and can you reason about them under pressure." I fumbled a question about state management in multi-team environments and I could feel the conversation shift. They were polite about the rejection. It still stung.&lt;/p&gt;

&lt;p&gt;The Denver company rejection hurt differently because it came after a three-hour technical take-home that I'd spent an entire weekend on. No feedback. Just a form email that said they'd decided to move forward with other candidates.&lt;/p&gt;

&lt;p&gt;August ended with four rejections and one ghost. I wasn't panicking yet, but I was starting to question whether my skills were actually marketable or whether I'd just gotten lucky with my previous job.&lt;/p&gt;




&lt;h2&gt;
  
  
  September–October: The Spiral
&lt;/h2&gt;

&lt;p&gt;This was the bad stretch.&lt;/p&gt;

&lt;p&gt;I applied to somewhere around thirty positions in these two months. I got twelve responses. Most of those didn't make it past the recruiter screen. The ones that did — a couple of companies I was genuinely excited about, including Datadog and a well-funded infrastructure startup out of New York — rejected me at the technical stage.&lt;/p&gt;

&lt;p&gt;I started doing that thing where you refresh your email constantly and then feel slightly sick when there's actually something there.&lt;/p&gt;

&lt;p&gt;The Datadog rejection was the Cloudflare I mentioned at the top, in terms of emotional weight. I'd prepped for it. I'd done mock system design interviews with a friend. I'd reviewed my distributed systems knowledge. But their technical bar was high, and I think I tried to sound smarter than I actually was in the system design round instead of just reasoning through the problem clearly. I overcomplicated a question about designing a metrics ingestion pipeline and then couldn't pull it back when the interviewer tried to redirect me.&lt;/p&gt;

&lt;p&gt;I also bombed a behavioral round at a company I'd rather not name, which was embarrassing in a different way because I'd assumed that part would be easy. It wasn't. I rambled. I gave vague answers. I used the phrase "we achieved significant improvements" without any numbers, which is exactly the kind of answer that communicates nothing to anyone.&lt;/p&gt;

&lt;p&gt;Around October I started actually changing my approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed (Honestly)
&lt;/h2&gt;

&lt;p&gt;A few things shifted in parallel, and I can't cleanly separate which one mattered most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt;, I started doing structured mock interviews instead of just reading about interview prep. I'd been using Pramp here and there for peer mocks, which was useful but inconsistent — you'd sometimes get paired with someone who was also struggling and the sessions didn't push me hard enough. I tried Interviewing.io for a paid mock with a Stripe engineer, which was expensive but worth it. That person pointed out that I had a habit of narrating what I was &lt;em&gt;about&lt;/em&gt; to do rather than just doing it, which ate up time and made me sound less confident than I probably was.&lt;/p&gt;

&lt;p&gt;I also spent some time with AceRound AI for async practice on behavioral and situational questions, specifically because I could do it on my schedule at weird hours when I was anxious and couldn't sleep. It's not a replacement for talking to a real engineer who's going to challenge your assumptions, but it helped me tighten answers and stop using filler phrases I didn't even realize I was using.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second&lt;/strong&gt;, I got more honest about what I was actually good at. My Terraform knowledge was solid, but my Kubernetes expertise was more "functional" than "deep." I'd been applying to roles that wanted a Kubernetes expert and then trying to fake my way through technical rounds, which wasn't working and wasn't really fair to anyone. I narrowed my focus to roles where the job description actually matched what I knew, which meant fewer applications but better fit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third&lt;/strong&gt; — and this took me too long to admit — I asked for help. I had a former colleague who'd gone through a DevOps job search the year before and landed well. I bought him coffee and made him tell me everything. He pointed out that my resume had responsibilities written where it needed outcomes, and that some of my listed experience was vague in ways that would make a hiring manager nervous. I spent a weekend rewriting it.&lt;/p&gt;




&lt;h2&gt;
  
  
  November–December: Things Started Clicking
&lt;/h2&gt;

&lt;p&gt;The Thanksgiving lie I told my brother-in-law came right before a stretch where things genuinely started moving.&lt;/p&gt;

&lt;p&gt;That Monday phone screen I was terrified about went well. The company was a mid-sized logistics tech firm — not the sexiest brand name in the world, but the infrastructure problems were interesting and the team seemed thoughtful. I made it through three rounds in about three weeks, which felt fast compared to everything that had come before.&lt;/p&gt;

&lt;p&gt;Simultaneously I had a process going with a fully remote infrastructure-as-a-service company that had found me through a referral. That one moved slower. By mid-December I had two offers on the table within the same week.&lt;/p&gt;

&lt;p&gt;One paid more. One had better scope and a team I'd enjoyed talking to. I took the one with better scope and a slightly lower base, which felt like a very mature decision and also made me briefly question whether I was being an idiot.&lt;/p&gt;

&lt;p&gt;I started in January 2024.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Actually Learned
&lt;/h2&gt;

&lt;p&gt;Six months felt like forever while it was happening. Looking at it now, I think it was mostly a calibration problem on my end — I had real skills, but I was applying in ways that didn't reflect them accurately, and I was doing interview prep that felt like work but wasn't actually making me better at interviews.&lt;/p&gt;

&lt;p&gt;The behavioral stuff being a weak point surprised me. I'd mentally categorized that as the easy part and focused almost entirely on technical prep. But a lot of DevOps interviews care deeply about how you handle incidents, how you communicate with non-technical stakeholders, how you've navigated disagreements about architectural decisions. Those questions require actual stories, not abstract explanations of what you'd hypothetically do. I didn't have my stories organized, and it showed.&lt;/p&gt;

&lt;p&gt;The companies where I made it furthest were the ones where I'd done the most specific research — not just "here's what they build" but "here's a problem they've probably encountered at their scale, and here's how I'd think about it." That prep is tedious and doesn't transfer between companies, which is why most people don't do it. I think it's also why most people plateau at the second or third round.&lt;/p&gt;

&lt;p&gt;Would I have gotten to an offer faster if I'd started with a more structured approach in June instead of coasting on confidence? Probably, yeah. I lost maybe two months just assuming I'd interview my way through on experience alone.&lt;/p&gt;

&lt;p&gt;The job's been good, for what it's worth. The infrastructure problems are real, the team argues about the right things, and I haven't lied to a family member about my employment situation since Thanksgiving 2023. That's enough.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want real-time interview assistance? &lt;a href="https://aceround.app" rel="noopener noreferrer"&gt;AceRound AI&lt;/a&gt; works live during Zoom/Meet interviews.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>interview</category>
      <category>career</category>
      <category>jobsearch</category>
      <category>ai</category>
    </item>
    <item>
      <title>What Interviewers Actually Want in System Design (A Candidate Who's Been On Both Sides)</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Sun, 05 Apr 2026 06:14:22 +0000</pubDate>
      <link>https://dev.to/karuha/what-interviewers-actually-want-in-system-design-a-candidate-whos-been-on-both-sides-31c8</link>
      <guid>https://dev.to/karuha/what-interviewers-actually-want-in-system-design-a-candidate-whos-been-on-both-sides-31c8</guid>
      <description>&lt;p&gt;Last year I bombed a system design round at Stripe. Not because I didn't know distributed systems — I'd been building them for six years. I bombed it because I spent 40 minutes designing the perfect thing nobody asked me to build.&lt;/p&gt;

&lt;p&gt;I've now done somewhere around 30 system design interviews across companies like Shopify, DoorDash, Cloudflare, and a handful of Series B startups. I've also been the person running them on the other side of the table. And I'm tired of the advice that boils down to "just draw boxes and say 'it depends' a lot." That's not wrong exactly, but it's not useful either.&lt;/p&gt;

&lt;p&gt;Here's what I actually think interviewers are evaluating — and it's more specific than most prep guides will tell you.&lt;/p&gt;




&lt;h2&gt;
  
  
  They're Checking If You Can Narrow Scope Without Being Told To
&lt;/h2&gt;

&lt;p&gt;The classic mistake: candidate hears "design Twitter" and immediately starts talking about 300 million daily active users, multi-region replication, and machine learning ranking algorithms. Meanwhile the interviewer is sitting there waiting for you to ask a single clarifying question.&lt;/p&gt;

&lt;p&gt;The trap isn't that you don't know the content. It's that you haven't demonstrated you can figure out &lt;em&gt;what&lt;/em&gt; to actually build before building it. In real jobs, requirements are almost never handed to you fully formed. So when you jump straight into the whiteboard, you're actually failing a test you didn't realize you were taking.&lt;/p&gt;

&lt;p&gt;The interviewers I've spoken to — both formally and in post-interview debrief conversations — care a lot about whether you push back appropriately. Not aggressively, but surgically. "Is this read-heavy or write-heavy? Are we prioritizing consistency or availability here? What's the SLA we're targeting?" Two or three sharp questions beats ten vague ones.&lt;/p&gt;

&lt;p&gt;I started using a 5-minute rule: no drawing anything until I've established at least the expected load profile and the top one or two user-facing requirements. It felt awkward at first. Now it's automatic.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Depth Test Usually Happens Around the 25-Minute Mark
&lt;/h2&gt;

&lt;p&gt;Every system design interview I've done has had a moment — usually around 20-30 minutes in — where the interviewer pivots and asks you to go deeper on one specific component. This is almost always deliberate. They want to see if you actually understand the thing you drew on the whiteboard or if you just know how to draw it.&lt;/p&gt;

&lt;p&gt;At Cloudflare's interview process, I was designing a CDN edge caching system and had been breezing through the high-level pretty confidently. Then the interviewer asked: "Walk me through what actually happens when you get a cache miss in a high-concurrency situation." That question was the whole interview. Everything else was preamble.&lt;/p&gt;

&lt;p&gt;If you can't go deep on at least two or three components of your design — I mean actually explain the tradeoffs at the implementation level — you will get filtered out at senior and staff levels regardless of how clean your high-level diagram looks.&lt;/p&gt;

&lt;p&gt;The components worth being able to go deep on, in my experience: your data model, your caching strategy (including invalidation), and your failure modes. If you designed a queue, you should know what happens when the consumer falls behind. If you put a load balancer in there, know what health checking actually does and what happens during a rolling deployment.&lt;/p&gt;




&lt;h2&gt;
  
  
  "It Depends" Is Only Acceptable If You Then Pick One
&lt;/h2&gt;

&lt;p&gt;This is the thing that tripped me up early. I thought hedging with tradeoffs was the smart move — it showed I understood nuance. And it does. But only if you follow it up with an actual decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"It depends on your consistency requirements — for this use case, I'd go with eventual consistency because writes will be far more frequent than reads, and we can tolerate a short staleness window."&lt;/strong&gt; Good.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"It depends... so you could go either way really."&lt;/strong&gt; Not good. That's just intellectual cowardice dressed up as nuance.&lt;/p&gt;

&lt;p&gt;The interviewers I've talked to are looking for someone who can make defensible calls under ambiguity. That's the entire job. The tradeoff awareness matters, but the decision-making matters more. When I realized this, I started forcing myself to end every "it depends" with "and for this scenario, I'd pick X because Y." Even if I was wrong, the structure impressed people more than the endless hedging.&lt;/p&gt;




&lt;h2&gt;
  
  
  They're Watching How You React When You're Wrong
&lt;/h2&gt;

&lt;p&gt;This one took me a while to appreciate. I used to get defensive when an interviewer pushed back on my design choices. Not combative, but I'd double down subtly — reframe my original point rather than actually engaging with their concern.&lt;/p&gt;

&lt;p&gt;The better interviewers are often intentionally introducing wrong constraints or pushing you toward a suboptimal design to see how you handle being challenged. They want to see if you can separate your ego from your architecture.&lt;/p&gt;

&lt;p&gt;At a DoorDash loop I did in 2022, the interviewer suggested I use a relational database for something where I'd proposed a document store. My instinct was to defend my choice. Instead I said "Let me think about that — what's your concern with the document store approach?" and it turned into the best part of the interview. We ended up with a hybrid model that was genuinely better than what either of us initially proposed.&lt;/p&gt;

&lt;p&gt;Interviewers like people who can think collaboratively. That sounds obvious, but under pressure, most candidates (including me, historically) treat pushback as an attack.&lt;/p&gt;




&lt;h2&gt;
  
  
  Full-Stack Candidates Have a Specific Problem
&lt;/h2&gt;

&lt;p&gt;As someone who's spent the last decade doing everything from React to distributed job queues, I've noticed a pattern in my own interviews: I default to the operational concerns and neglect the client-side and API surface entirely. Other full-stack candidates I've talked to do the opposite — they'll detail the frontend component architecture while hand-waving the backend with "and then some microservices handle this."&lt;/p&gt;

&lt;p&gt;The interviewer at a senior full-stack role is usually looking to see that you can hold both ends of the system in your head simultaneously. You should be able to talk about your API contract (not just REST vs. GraphQL as a buzzword fight, but actual endpoint design and data shape), your auth strategy, your caching at the CDN and application layers, &lt;em&gt;and&lt;/em&gt; your database schema — within the same conversation.&lt;/p&gt;

&lt;p&gt;I've used mock interviews on platforms like Pramp and Interviewing.io to specifically practice this boundary, because it's easy to drift into comfort zones. AceRound AI has a mode where you get targeted feedback on which parts of a system design you skipped or under-explained, which I found useful for identifying my own blind spots. Final Round AI covers similar ground if you want a different style of feedback.&lt;/p&gt;

&lt;p&gt;The point isn't the tool — it's deliberately stress-testing the full stack of your design rather than the parts you already know well.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Non-Functional Requirements Are the Real Interview
&lt;/h2&gt;

&lt;p&gt;Latency targets, throughput estimates, availability requirements, storage growth projections. Most candidates mention these in passing and then get on with the "real" design. But in almost every debrief conversation I've had or heard about, the senior engineers on the panel are paying close attention to whether you can ground your decisions in actual numbers.&lt;/p&gt;

&lt;p&gt;This doesn't mean you need to be a back-of-envelope math genius. It means you should be doing rough calculations and letting them influence your choices. "If we expect 10 million daily active users and each generates three events per day, we're looking at roughly 350 events per second on average, with maybe a 10x spike — so we need a message queue that can handle around 3,500 messages per second at peak." That kind of thinking out loud signals a certain engineering maturity that the "draw boxes, say it depends" approach never does.&lt;/p&gt;

&lt;p&gt;I've bombed this exact thing. At Stripe, I designed an event processing system without ever establishing what the expected event volume was. I built something unnecessarily complex for a problem that was actually quite modest in scale. The interviewer let me run with it for a while before pointing this out, and by then I'd dug myself into a hole.&lt;/p&gt;




&lt;h2&gt;
  
  
  What "Senior" Actually Means in This Context
&lt;/h2&gt;

&lt;p&gt;At junior levels, interviewers are checking: can you design something coherent? Do you understand the basic building blocks?&lt;/p&gt;

&lt;p&gt;At senior levels, they're checking: can you identify where the system will break before it breaks?&lt;/p&gt;

&lt;p&gt;That shift in framing changed how I approach these interviews. I now explicitly build in a "where will this fall apart" phase — after I've done the initial design, I walk through failure scenarios. What happens if the database goes down? What happens if this service gets 10x traffic unexpectedly? What's the recovery path?&lt;/p&gt;

&lt;p&gt;This isn't pessimism for its own sake. It's a demonstration that you've operated real systems and watched real things go wrong. If you haven't, at least simulate it — because the interviewers who've been building infrastructure for 10 years will absolutely push you there.&lt;/p&gt;

&lt;p&gt;The best system design interviews I've had felt like a real engineering conversation between two people who both care about building something that doesn't fall over at 2am. That's the vibe you're going for. Not a performance, not a memorized framework — just two engineers figuring out what to build and why.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want real-time interview assistance? &lt;a href="https://aceround.app" rel="noopener noreferrer"&gt;AceRound AI&lt;/a&gt; works live during Zoom/Meet interviews.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>interview</category>
      <category>career</category>
      <category>jobsearch</category>
      <category>ai</category>
    </item>
    <item>
      <title>My phone screen with Google was at 9am on a Tuesday, and I'd spent the previous</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Sun, 05 Apr 2026 06:12:43 +0000</pubDate>
      <link>https://dev.to/karuha/my-phone-screen-with-google-was-at-9am-on-a-tuesday-and-id-spent-the-previous-4dl6</link>
      <guid>https://dev.to/karuha/my-phone-screen-with-google-was-at-9am-on-a-tuesday-and-id-spent-the-previous-4dl6</guid>
      <description>&lt;p&gt;My phone screen with Google was at 9am on a Tuesday, and I'd spent the previous night testing three different AI overlay tools to see which one wouldn't get me killed. None of them were perfect. One crashed mid-sentence. One gave me an answer that was technically correct but about three versions out of date. One whispered the right thing in my ear about four seconds after I'd already started answering wrong.&lt;/p&gt;

&lt;p&gt;That was early 2025. By 2026 the landscape has matured a bit, but "matured" doesn't mean "solved." It means the tradeoffs have gotten clearer and more honest, which is at least something.&lt;/p&gt;

&lt;p&gt;Here's what I've actually learned from using these tools myself, talking to other engineers who use them, and watching people torch their chances by trusting the wrong one.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Tools Worth Actually Talking About
&lt;/h2&gt;

&lt;p&gt;The main players in 2026 are &lt;strong&gt;Final Round AI&lt;/strong&gt;, &lt;strong&gt;AceRound&lt;/strong&gt;, &lt;strong&gt;Interview Kickstart&lt;/strong&gt; (which is more of a coaching program that now has an AI layer), &lt;strong&gt;Pramp&lt;/strong&gt;, and &lt;strong&gt;Interviewing.io&lt;/strong&gt;. There are also a dozen smaller tools that have basically cloned Final Round AI's interface, most of which I wouldn't trust with my Netflix password let alone my job search.&lt;/p&gt;

&lt;p&gt;I'm going to skip the clones and focus on the ones I've either used for real interviews or seen friends use with real outcomes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Round AI
&lt;/h2&gt;

&lt;p&gt;This is the one everyone's heard of because their marketing is relentless. And to their credit, the core product is solid. The real-time audio transcription and suggestion pipeline has gotten noticeably faster — we're talking about 1.5 to 2 seconds of latency on a decent connection in most cases I've tested, which is usable. A year ago it was closer to 3–4 seconds and you could feel the gap.&lt;/p&gt;

&lt;p&gt;Accuracy is decent for common patterns — STAR format behavioral questions, standard system design prompts, LeetCode medium-level problems. Where it struggles is anything niche or domain-specific. I had a friend doing interviews for a fintech role that involved some very specific knowledge about FIX protocol and settlement windows, and Final Round kept confidently hallucinating details. He caught it, thankfully. But that's the thing: &lt;strong&gt;you still have to be the editor of everything it gives you&lt;/strong&gt;, which means you still need to actually know your stuff.&lt;/p&gt;

&lt;p&gt;Detection risk is where things get complicated. Final Round uses an audio capture approach that doesn't require a separate browser window visible to the interviewer, but screen-sharing situations are still risky if the interviewer asks you to share your whole screen or uses a platform that monitors background processes. I know one person who got flagged during an Articulate assessment that detected unusual audio routing. Final Round isn't magic.&lt;/p&gt;

&lt;p&gt;Pricing: around $29–39/month depending on what tier you want, which is reasonable if you're actively interviewing.&lt;/p&gt;




&lt;h2&gt;
  
  
  AceRound
&lt;/h2&gt;

&lt;p&gt;AceRound (aceround.app) came up in a conversation I had with someone who'd been bouncing between tools and was frustrated with Final Round's response quality for system design specifically. The pitch is that it's more focused on senior-level and staff-level interviews rather than trying to cover everything.&lt;/p&gt;

&lt;p&gt;In practice, I found the latency to be roughly comparable to Final Round — maybe slightly faster on behavioral questions, slightly slower on technical ones where it's clearly doing more reasoning. The accuracy on system design scenarios felt more considered to me, less like it was pattern-matching to a template and more like it was engaging with the actual constraints of the problem. That said, I haven't used it in a live high-stakes interview, just in practice sessions, so take that with appropriate skepticism.&lt;/p&gt;

&lt;p&gt;The detection profile is similar to Final Round — same general category of risk. It's not going to get you through a proctored assessment that's actively scanning for audio anomalies. No tool will.&lt;/p&gt;

&lt;p&gt;The pricing is slightly lower than Final Round at this point, which matters if you're doing a long job search on a budget.&lt;/p&gt;




&lt;h2&gt;
  
  
  Interview Kickstart
&lt;/h2&gt;

&lt;p&gt;This one is different because it's fundamentally a coaching program that has added AI tooling on top. The AI assistance isn't their core product the way it is for Final Round or AceRound. What IK actually does well is the human coaching and the structured curriculum, especially for people trying to break into FAANG-tier companies from non-traditional backgrounds.&lt;/p&gt;

&lt;p&gt;The AI layer they've added is more of a practice companion than a live interview assistant. Latency is kind of irrelevant here because it's not designed to help you in real-time. It's more of a feedback tool after mock sessions. Accuracy is decent because they've trained it on their own curriculum, which is pretty rigorous.&lt;/p&gt;

&lt;p&gt;The big honest tradeoff: &lt;strong&gt;Interview Kickstart is expensive&lt;/strong&gt;. We're talking $3,000–6,000 for their full programs. If you have that budget and you're targeting a significant salary jump, the ROI math can work out. If you're a student or in a difficult financial situation, it's not the right tool regardless of quality.&lt;/p&gt;

&lt;p&gt;Detection risk: not really applicable since it's a preparation tool, not a live crutch.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pramp and Interviewing.io
&lt;/h2&gt;

&lt;p&gt;I'm grouping these because they serve a similar purpose: peer and professional mock interview practice. Neither is trying to be an AI overlay that helps you in real interviews. They're trying to make you good enough that you don't need one.&lt;/p&gt;

&lt;p&gt;Pramp is free and peer-to-peer, which means quality is inconsistent. Sometimes you get a great mock interviewer who gives you real signal. Sometimes you get someone who's nervous and awkward and neither of you learns much. The AI-assisted feedback they've added is fine — it'll tell you that you didn't use the STAR format, that your time complexity was off, basic stuff. Latency, accuracy, detection risk — all irrelevant in the same way as IK.&lt;/p&gt;

&lt;p&gt;Interviewing.io is better quality because a lot of the interviewers are actual FAANG engineers, and you can pay for sessions with vetted people. Their AI feedback layer is newer and I've heard mixed things about it. The core product is still the human practice sessions.&lt;/p&gt;

&lt;p&gt;My honest take: &lt;strong&gt;these two should be part of your prep regardless of what else you use&lt;/strong&gt;. They build actual skills in a way that AI overlay tools don't.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Detection Risk Question Nobody Answers Honestly
&lt;/h2&gt;

&lt;p&gt;Let me be direct about this because I see a lot of hand-waving. &lt;/p&gt;

&lt;p&gt;Most video interview platforms in 2026 cannot directly detect that you're using an AI audio tool if you're careful about how it's routed. Zoom, Teams, Google Meet — they see your video feed and your audio, and they're not scanning your processes unless you've consented to something like an integrity browser that locks down your environment.&lt;/p&gt;

&lt;p&gt;The risk is not primarily technical. The risk is behavioral. &lt;strong&gt;If you're reading from suggestions instead of thinking, interviewers notice.&lt;/strong&gt; The slight delay, the eyes that aren't quite tracking the conversation, the answers that are technically perfect but emotionally flat. Senior engineers who interview a lot have developed a feel for this. I've noticed it myself when interviewing candidates.&lt;/p&gt;

&lt;p&gt;The second risk is platforms that do actively monitor — HackerRank's proctoring mode, Codility with monitoring enabled, some custom assessment platforms large companies use. These can detect unusual audio routing, browser extensions, multiple applications running. No AI tool vendor is being fully honest about which specific platforms they can't protect you from, because they don't always know.&lt;/p&gt;

&lt;p&gt;The third risk is that you pass the interview and fail the job. If you got through your system design rounds leaning heavily on an AI and you actually don't understand distributed systems, that's going to become clear within your first month on the team.&lt;/p&gt;




&lt;h2&gt;
  
  
  How I'd Actually Choose
&lt;/h2&gt;

&lt;p&gt;If I were actively job searching right now:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For real-time assistance during live interviews&lt;/strong&gt;, Final Round AI or AceRound are the credible options. I'd use whichever one's response quality felt better for the type of roles I was targeting — AceRound felt sharper for senior technical content in my limited testing, Final Round has more polish and a bigger user community. The latency difference between them is marginal and will vary by your network and hardware anyway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For practice&lt;/strong&gt;, I'd use Pramp for volume and Interviewing.io for quality feedback sessions on the roles I cared most about. Neither will make you dependent on a tool in an actual interview.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For structured learning&lt;/strong&gt;, Interview Kickstart if the budget exists and the salary target justifies it. Otherwise, Neetcode, system design resources, and doing actual mock interviews with friends who work at the companies you're targeting.&lt;/p&gt;

&lt;p&gt;The deeper honest answer is that I think a lot of people reach for AI tools because preparation is uncomfortable and they're looking for a shortcut. The tools have gotten good enough that they can help at the margins — a jogged memory on an API you blanked on, a structure suggestion when you're nervous and losing the thread. But the people I know who consistently land good offers are the ones who've done hundreds of practice problems and dozens of mock interviews, and the AI tool is maybe 10% of their edge, not 90%.&lt;/p&gt;

&lt;p&gt;The 9am Google phone screen I mentioned at the start? I didn't use any of the tools I'd tested the night before. I was too nervous to manage two conversations at once and I figured if I bombed, I wanted to know it was actually me bombing. I passed. Didn't get the offer eventually, for unrelated reasons, but I passed the screen.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want real-time interview assistance? &lt;a href="https://aceround.app" rel="noopener noreferrer"&gt;AceRound AI&lt;/a&gt; works live during Zoom/Meet interviews.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>interview</category>
      <category>career</category>
      <category>jobsearch</category>
      <category>ai</category>
    </item>
    <item>
      <title>What Actually Happens in an Amazon System Design Interview (And Why Most Prep Misses the Point)</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Sun, 05 Apr 2026 06:11:18 +0000</pubDate>
      <link>https://dev.to/karuha/what-actually-happens-in-an-amazon-system-design-interview-and-why-most-prep-misses-the-point-1ani</link>
      <guid>https://dev.to/karuha/what-actually-happens-in-an-amazon-system-design-interview-and-why-most-prep-misses-the-point-1ani</guid>
      <description>&lt;p&gt;I bombed my first Amazon system design round in 2021. Not because I didn't know distributed systems — I'd been building them for six years. I bombed it because I spent the first 20 minutes designing the perfect architecture in my head before saying a word. The interviewer finally interrupted me with "so what are you thinking?" and I'd lost the thread completely.&lt;/p&gt;

&lt;p&gt;That experience taught me something no blog post had: these interviews aren't a knowledge test. They're a collaboration simulation. Amazon is checking whether you can be the person in the room who moves ambiguous problems forward without freezing up or steamrolling everyone else.&lt;/p&gt;

&lt;p&gt;Here's what the 45 minutes actually look like, and what's really being graded.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Clock Breakdown (How Interviewers Actually Run It)
&lt;/h2&gt;

&lt;p&gt;Amazon SDEs and senior engineers I've talked to describe roughly the same flow, even if they'd never write it down this explicitly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minutes 0–5: Requirements gathering.&lt;/strong&gt; The prompt is intentionally vague. "Design a notification system for Amazon" tells you almost nothing. How many users? Push or email or both? Reliability guarantees? You're expected to ask. The trap here is asking too many questions and stalling, or asking too few and charging ahead into the wrong design. Aim for 3–5 targeted clarifying questions, then summarize what you've decided to build. Something like: "I'm going to focus on a push notification system handling 10 million daily active users, prioritizing delivery reliability over strict ordering. Sound right?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minutes 5–15: High-level design.&lt;/strong&gt; Sketch the components. User hits an API gateway, goes through a notification service, something queues the work, workers dispatch to Firebase or APNs, you need some kind of fan-out logic for large subscriber lists. Don't go deep yet. Just establish the skeleton. This is where a lot of people over-architect — trying to solve every problem before they've even committed to a shape.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minutes 15–35: Deep dives.&lt;/strong&gt; The interviewer picks what interests them. Maybe it's the fan-out problem for a celebrity with 50 million followers. Maybe it's failure handling when APNs is down. Maybe it's exactly-once delivery semantics. You don't get to control which thread they pull. This is the real interview. Everything before was setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minutes 35–45: Wrap-up and questions.&lt;/strong&gt; There's usually a brief discussion of what you'd do differently, what you'd prioritize if you had another week, and your questions for them. Don't skip this part — it signals engineering maturity.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Interviewer Is Actually Writing Down
&lt;/h2&gt;

&lt;p&gt;Amazon uses a structured feedback form tied to their Leadership Principles, and the system design rubric maps onto a few specific things. I've seen enough interview loops from both sides to say with some confidence what matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ownership and scope judgment.&lt;/strong&gt; Did you immediately try to build a globally distributed, multi-region, CRDT-synchronized masterpiece? Or did you scope the problem pragmatically, call out what you'd defer to V2, and justify the tradeoffs? Amazon interviewers — probably more than Google or Meta — respond well to engineers who think about what actually needs to be built versus what could theoretically be built.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Communication while thinking.&lt;/strong&gt; This is underrated. When you're working through whether to use Kafka or SQS, they want to hear the reasoning out loud, including the wrong turns. "I was thinking Kafka here, but actually our throughput requirement is low enough that SQS would reduce operational overhead significantly" is a good answer. Staring at the whiteboard for 90 seconds and then saying "SQS" is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handling pushback.&lt;/strong&gt; Interviewers will challenge your choices. Sometimes it's genuine — they see a real flaw. Sometimes it's probing to see if you'll collapse or defend defensibly. The goal isn't to always be right. It's to engage with "have you thought about X?" like a real engineering conversation rather than either capitulating immediately or getting defensive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concrete numbers.&lt;/strong&gt; Rough capacity estimation, back-of-envelope math for storage or bandwidth, latency requirements for different tiers — these signal that you've shipped real systems. You don't need exact answers, but "around 100MB per user per year for message metadata, so at 10M users that's roughly 1TB, easily fits in a managed RDS instance for now" is miles better than "we'd need some storage layer."&lt;/p&gt;




&lt;h2&gt;
  
  
  The Topics Amazon Consistently Goes Deeper On
&lt;/h2&gt;

&lt;p&gt;Based on patterns I've seen and what I've heard from people who've been through the loop recently:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fan-out at scale&lt;/strong&gt; keeps showing up in any feed, notification, or messaging design. The naive approach (loop through all followers, send each a message) breaks around 10K followers and shatters at celebrity scale. You need to know the hybrid fan-out pattern — pre-compute for regular users, pull on read for high-follower accounts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exactly-once vs at-least-once delivery&lt;/strong&gt; and why true exactly-once is expensive. Most real systems accept at-least-once and build idempotency keys into the consumer side.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database choice reasoning.&lt;/strong&gt; Not just "I'd use DynamoDB because it scales" — that's a non-answer. Why DynamoDB versus Aurora versus a combination? What access patterns drive the choice?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Failure modes.&lt;/strong&gt; What happens when your notification worker dies mid-batch? When the downstream provider (APNs, Firebase) is degraded? Interviewers at Amazon specifically probe resilience because AWS services power so much infrastructure that an engineer who hasn't thought through failure modes is a liability.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting Stuck: What to Actually Do
&lt;/h2&gt;

&lt;p&gt;Everyone gets stuck. The difference is what you do with it.&lt;/p&gt;

&lt;p&gt;The worst thing you can do is go silent and stare. The second worst is pretend you're not stuck and start talking in circles. I've done both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Name the problem explicitly.&lt;/strong&gt; "I'm not immediately sure how to handle the case where a user's device token has rotated but we haven't refreshed it in our database yet — let me think through this." That sentence buys you 30 seconds and signals self-awareness. Interviewers almost universally respond better to transparency than to watching someone spiral.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fall back to first principles.&lt;/strong&gt; If you're stuck on a specific mechanism, step back to the requirement. "What we actually need here is a way to know that a message was received — so either we need acknowledgment from the client, or we accept that we won't know and handle retries differently." Sometimes just re-stating the goal unsticks you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ask a pointed question.&lt;/strong&gt; Not a desperate one. Something like "In your system, does the product requirement allow for eventual delivery with a retry window, or does it need near-real-time guarantees?" shows you're trying to scope rather than flounder. Interviewers can distinguish between genuine clarification and stalling, but pointed questions are usually welcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Offer a partial answer and flag it.&lt;/strong&gt; "I can handle the happy path here — messages delivered to online users — but I'd need to think more carefully about the durable offline queue mechanism. Want me to proceed with the online case and come back?" That's a reasonable engineering conversation, not a failure.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Prep That Actually Helps vs. The Prep That Doesn't
&lt;/h2&gt;

&lt;p&gt;Watching YouTube videos of people designing Twitter or URL shorteners is fine for getting vocabulary. It's not sufficient for the parts that actually matter.&lt;/p&gt;

&lt;p&gt;What helps more is practicing out loud with someone who will interrupt you. Pramp does this for free, though the peer feedback quality varies wildly depending on who you're matched with. Interviewing.io is better for senior-level practice because the interviewers are actual engineers who'll push back with real follow-up questions. Interview Kickstart has structured curriculum that's good if you're starting from scratch but it's expensive and paced slowly for experienced engineers.&lt;/p&gt;

&lt;p&gt;I've also used AceRound AI for solo practice runs when I couldn't schedule a human session — it's useful specifically for talking through your reasoning without judgment, which is a different kind of practice than getting challenged. Not a substitute for real pushback, but good for building the habit of narrating your thinking.&lt;/p&gt;

&lt;p&gt;Final Round AI is popular but I find the coaching feel of it a bit rigid for system design specifically — it's better suited to behavioral prep.&lt;/p&gt;

&lt;p&gt;The single most valuable thing I did before my re-attempt at Amazon was run 8 mock system designs in three weeks, recording audio each time. Listening back, I could hear exactly where I went quiet, where I repeated myself, where I jumped to solutions before establishing requirements. That feedback loop is hard to get any other way.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Part Nobody Talks About: Amazon Specifically
&lt;/h2&gt;

&lt;p&gt;Google and Meta system design interviews share DNA with Amazon's, but Amazon has some quirks worth knowing.&lt;/p&gt;

&lt;p&gt;The Leadership Principles bleed into technical rounds. An interviewer might explicitly ask "how would you handle the case where product changes the requirements halfway through?" — that's partly a system design question and partly an Ownership / Bias for Action question. You need to engage with both layers.&lt;/p&gt;

&lt;p&gt;Amazon also has a stronger operational culture than, say, Google. Questions about monitoring, alarming, rollout strategy, and "how would you know if this thing is broken in production" come up more at Amazon than anywhere else I've seen. If you design a beautiful system and say nothing about observability, that's a gap.&lt;/p&gt;

&lt;p&gt;And the bar for written communication (design docs, PRFAQs) is real — some interviewers will ask you to sketch a brief narrative of the system's goals and non-goals as part of the exercise. It's not a writing test, but structured thinking about problem framing matters.&lt;/p&gt;




&lt;p&gt;The honest summary is that Amazon's system design interviews reward engineers who can think out loud, make scoped decisions under ambiguity, and engage with failure like it's a normal part of the problem space — not a threat. The 45 minutes is tight enough that if you get lost in the weeds or lose momentum early, you won't recover. But if you know the rhythm going in, it's a much more manageable conversation.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want real-time interview assistance? &lt;a href="https://aceround.app" rel="noopener noreferrer"&gt;AceRound AI&lt;/a&gt; works live during Zoom/Meet interviews.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>interview</category>
      <category>career</category>
      <category>jobsearch</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Cheated on My Google Interview (Sort Of)</title>
      <dc:creator>Karuha</dc:creator>
      <pubDate>Sun, 05 Apr 2026 06:10:41 +0000</pubDate>
      <link>https://dev.to/karuha/i-cheated-on-my-google-interview-sort-of-3ilk</link>
      <guid>https://dev.to/karuha/i-cheated-on-my-google-interview-sort-of-3ilk</guid>
      <description>&lt;p&gt;Last spring I had a final round with a mid-sized fintech company — four Zoom calls back to back, starting at 9am. By the third one, a system design interview, I had a second laptop open to my left with an AI assistant running. The interviewer never knew. I'm still not sure how I feel about it.&lt;/p&gt;

&lt;p&gt;Let me back up.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Even Got There
&lt;/h2&gt;

&lt;p&gt;I'd been prepping for about six weeks. Leetcode grind, the usual. I'd used Pramp a few times for mock interviews with real humans, which I genuinely think is underrated — there's something about another person watching you that no tool replicates. I'd also done a few sessions on interviewing.io, which is better for senior-level practice because the interviewers are actually ex-FAANG.&lt;/p&gt;

&lt;p&gt;But I kept hitting the same wall. System design. Every time I'd get a prompt like "design a payments notification system" my brain would go blank for the first 90 seconds. Not because I didn't know the material — I've been building distributed systems for eight years. It was pure anxiety narrowing my field of vision.&lt;/p&gt;

&lt;p&gt;A friend who'd done his interview circuit a few months earlier mentioned he'd used an AI assistant during a couple of his Zoom calls. Not to answer for him, more as a... prompt on the side. Something to glance at if he froze. He got the job, for what that's worth.&lt;/p&gt;

&lt;p&gt;I spent a week trying different tools. Final Round AI has a real-time interview mode that overlays suggestions — it's slick but felt aggressive to me, like it was trying to drive the conversation rather than assist. I tried AceRound AI (aceround.app) which does a similar real-time thing but felt lighter, less intrusive. I practiced with both for a few days before deciding what I'd actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Day Of
&lt;/h2&gt;

&lt;p&gt;The system design interview was my third call. By that point I'd already done a behavioral round and a technical deep-dive on my past work, both of which went fine without any assistance. I had the second laptop positioned just below my webcam sight line.&lt;/p&gt;

&lt;p&gt;The prompt was something like: design a fraud detection pipeline that needs to process transactions in near real-time.&lt;/p&gt;

&lt;p&gt;I knew this space. I'd literally worked on something adjacent to this. And yet — the first 30 seconds I felt that familiar tunnel vision.&lt;/p&gt;

&lt;p&gt;I glanced at the assistant. It had already started generating a rough scaffold: clarify scale requirements, discuss streaming vs batch tradeoffs, Kafka for ingestion, feature store considerations, model serving latency...&lt;/p&gt;

&lt;p&gt;Here's the honest thing: I already knew all of that. Seeing it written out didn't teach me anything. What it did was break the anxiety loop. Like a tap on the shoulder that says &lt;em&gt;you know this, start talking&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I talked for probably 40 minutes, drew out the architecture, got into a good back-and-forth with the interviewer about consistency tradeoffs. I glanced at the second screen maybe four times total. Once at the beginning, once when I blanked on what to say about the feature store, once to check if I'd missed anything major at the end.&lt;/p&gt;

&lt;p&gt;The interview went well. I got the offer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Worked
&lt;/h2&gt;

&lt;p&gt;The scaffold effect was real. Having something to look at during that initial freeze — even if I mostly ignored it — functioned like a security blanket. The knowledge was mine. The structure was something I'd internalized from weeks of prep. The AI just reflected it back when my brain was being stupid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-time prompting on specific sub-questions was occasionally useful.&lt;/strong&gt; When the interviewer asked a curveball about handling schema evolution in Kafka, I glanced over and the tool had pulled up a quick note about schema registries. Again — I knew about schema registries. But in that moment it was a useful nudge.&lt;/p&gt;

&lt;p&gt;The best use was honestly just preventing spiraling. When you feel like you're rambling, seeing bullet points on the side tells you whether you've actually covered the bases or whether you're burning time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Was Awkward
&lt;/h2&gt;

&lt;p&gt;Oh, plenty.&lt;/p&gt;

&lt;p&gt;The eye contact thing is real and it's weird. I'm a pretty natural interviewer — I make good eye contact, I'm expressive. Glancing left at a second screen even subtly changes your energy. I think I seemed slightly more distracted than usual. The interviewer didn't comment on it but I noticed it in my own pacing.&lt;/p&gt;

&lt;p&gt;There were two moments where the AI suggested something slightly off. Early on it flagged "consider CQRS pattern" — technically not wrong but completely overkill for what we were discussing and would have taken the conversation in a bad direction. I ignored it. But it created a half-second of internal debate that I didn't need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The tool is working from the transcript of what's being said, and transcription lag is real.&lt;/strong&gt; There were a few seconds of latency between the interviewer finishing a question and the assistant having something relevant. For behavioral questions that's probably fine. For a fast-moving technical discussion, you sometimes glance over and what you see is already stale.&lt;/p&gt;

&lt;p&gt;The cognitive overhead of managing two screens during an already intense 45-minute conversation was non-trivial. It's like trying to listen to someone while also reading a book. Your working memory is genuinely split.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Part I Keep Thinking About
&lt;/h2&gt;

&lt;p&gt;Is this cheating?&lt;/p&gt;

&lt;p&gt;I've gone back and forth on this more than I expected. My honest take: for a coding interview, I think it crosses a line. If someone else's code or algorithm is solving the problem, that's not your skill. But for system design? I'm not sure. System design interviews are supposed to evaluate how you think through tradeoffs and communicate architecture, not test whether you can recite a list of components unprompted. The knowledge was mine. The judgment calls were mine.&lt;/p&gt;

&lt;p&gt;But I also know I'm rationalizing a little. The interviewer presumably wanted to see my unassisted reasoning. They didn't consent to me having a tool open. That matters.&lt;/p&gt;

&lt;p&gt;My friend's take was sharper than mine: "Every senior engineer has references open during their actual job. Why should the interview simulate a context that doesn't exist?" I find this somewhat convincing and somewhat convenient.&lt;/p&gt;

&lt;p&gt;What I'd say is this: using it as a crutch to compensate for knowledge you actually don't have is a bad idea beyond the ethics — you'll get the job and then drown. Using it to manage anxiety when you genuinely know the material is a different thing. Still arguably questionable, but different.&lt;/p&gt;

&lt;h2&gt;
  
  
  Would I Do It Again
&lt;/h2&gt;

&lt;p&gt;Probably not in the same way.&lt;/p&gt;

&lt;p&gt;The anxiety management problem is real, but I think the better fix is more reps with tools like Interview Kickstart's mock sessions or interviewing.io before the real thing — get desensitized enough that you don't need the security blanket. That's what I should have done with an extra two weeks of prep.&lt;/p&gt;

&lt;p&gt;If I were going to use an AI assistant again, I'd want it more purely for prep. Running practice sessions where it plays interviewer and gives me feedback after, not during. That's where I've seen the most legitimate value — the post-session analysis of where I rambled, what I forgot to mention, where I should have asked clarifying questions.&lt;/p&gt;

&lt;p&gt;The live assist mode is a cool piece of engineering. I'm just not sure the tradeoff — slightly better answers, split attention, ethical weirdness — is actually worth it for someone who's put in the prep work. If you're the kind of person who's done 80 hours of preparation, you probably don't need it in the room. If you haven't done the prep, it won't save you.&lt;/p&gt;

&lt;p&gt;The fintech job, for what it's worth, I'm still at. Six months in. The fraud pipeline we built looks nothing like what I designed in that interview, which maybe says something about how much any of this matters.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want real-time interview assistance? &lt;a href="https://aceround.app" rel="noopener noreferrer"&gt;AceRound AI&lt;/a&gt; works live during Zoom/Meet interviews.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>interview</category>
      <category>career</category>
      <category>jobsearch</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
