<?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>Forem: Arpit Godghate</title>
    <description>The latest articles on Forem by Arpit Godghate (@irishcheezecake).</description>
    <link>https://forem.com/irishcheezecake</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3871664%2F5a939bb5-92b8-49e7-8aef-917787acdf64.png</url>
      <title>Forem: Arpit Godghate</title>
      <link>https://forem.com/irishcheezecake</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/irishcheezecake"/>
    <language>en</language>
    <item>
      <title>Invitation to contribute to ArchScope</title>
      <dc:creator>Arpit Godghate</dc:creator>
      <pubDate>Wed, 15 Apr 2026 12:59:36 +0000</pubDate>
      <link>https://forem.com/irishcheezecake/invitation-to-contribute-to-archscope-4gkl</link>
      <guid>https://forem.com/irishcheezecake/invitation-to-contribute-to-archscope-4gkl</guid>
      <description>&lt;p&gt;Inviting collaborators to contribute to ArchScope, an architecture analysis tool to test your system designs. &lt;/p&gt;

&lt;p&gt;find more details in this blog - &lt;a href="https://lnkd.in/dTNmy5G6" rel="noopener noreferrer"&gt;https://lnkd.in/dTNmy5G6&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Github - &lt;a href="https://github.com/arpitg24/ArchScope" rel="noopener noreferrer"&gt;https://github.com/arpitg24/ArchScope&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;try it yourself and let me know what you think - &lt;br&gt;
&lt;a href="https://lnkd.in/d-VggTsr" rel="noopener noreferrer"&gt;https://lnkd.in/d-VggTsr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please comment on any bugs or features that should be addressed.&lt;/p&gt;

&lt;p&gt;PS: please try it on a pc, layouts would overlap over a mobile&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>ArchScope Engineering Update: Multi-Selection &amp; Undo/Redo Implementation (April 14, 2026)</title>
      <dc:creator>Arpit Godghate</dc:creator>
      <pubDate>Tue, 14 Apr 2026 19:55:54 +0000</pubDate>
      <link>https://forem.com/irishcheezecake/archscope-engineering-update-multi-selection-undoredo-implementation-april-14-2026-1i53</link>
      <guid>https://forem.com/irishcheezecake/archscope-engineering-update-multi-selection-undoredo-implementation-april-14-2026-1i53</guid>
      <description>&lt;h1&gt;
  
  
  Implementing Multi-Selection and Undo/Redo in ReactFlow: A Technical Deep Dive
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Today, we are implementing a comprehensive multi-selection system with undo/redo functionality. This was a technical challenge that tested our understanding of ReactFlow's internal state management.&lt;/p&gt;

&lt;p&gt;The requirement was to make a box to select and move multiple components, the kind present in file systems, where, when you click and drag, a box appears and whatever is inside the box is selected and moves like a single unit.&lt;/p&gt;

&lt;p&gt;These design requirements were as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual selection box with Shift+drag interaction&lt;/li&gt;
&lt;li&gt;Multi-component selection with visual feedback&lt;/li&gt;
&lt;li&gt;Group movement capabilities&lt;/li&gt;
&lt;li&gt;Keyboard shortcuts for productivity&lt;/li&gt;
&lt;li&gt;Undo/redo functionality for all operations&lt;/li&gt;
&lt;li&gt;Copy/paste support for selected components&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: The Selection Box Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Initial Challenges
&lt;/h3&gt;

&lt;p&gt;Our first hurdle was implementing the selection box without interfering with ReactFlow's built-in interactions. ReactFlow has its own panning, node selection, and event handling systems that can conflict with custom implementations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: The selection box wasn't appearing or was triggering ReactFlow's pan instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;: ReactFlow's event system captures mouse events at multiple levels, making it difficult to inject custom selection logic without breaking existing functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution Approach&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// We needed precise event target detection&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isReactFlowPane&lt;/span&gt; &lt;span class="o"&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;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&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-flow__pane&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;isNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&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-flow__node&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;isHandle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&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-flow__handle&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;isControl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&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-flow__controls&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;isMiniMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closest&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-flow__minimap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Only start selection on empty canvas with Shift key&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;button&lt;/span&gt; &lt;span class="o"&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;isReactFlowPane&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isNode&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isHandle&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isControl&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isMiniMap&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;shiftKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Start selection logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Coordinate Transformation Hell
&lt;/h3&gt;

&lt;p&gt;The second major challenge was coordinate transformation. ReactFlow uses its own coordinate system with viewport transformations (zoom and pan), but mouse events provide screen coordinates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Selection bounds weren't matching actual component positions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: We implemented manual coordinate transformation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;viewport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;reactFlowRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;getViewport&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;nodeScreenX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;viewport&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;zoom&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;viewport&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;x&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;nodeScreenY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;viewport&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;zoom&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;viewport&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;y&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: The Undo/Redo Nightmare
&lt;/h2&gt;

&lt;p&gt;This became the most challenging part of the implementation. Our initial attempts at implementing undo/redo were plagued by state management issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 1: Simple State Snapshots
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Approach&lt;/strong&gt;: Store snapshots of nodes and edges in a history array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: ReactFlow's internal state management interfered with our manual state setting, causing race conditions and inconsistent state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code That Failed&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saveToHistory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nf"&gt;setHistory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&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;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentState&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;nodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;edges&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;undo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prevState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;historyIndex&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="nf"&gt;setNodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// This caused conflicts with ReactFlow&lt;/span&gt;
  &lt;span class="nf"&gt;setEdges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;edges&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;history&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;historyIndex&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Attempt 2: Debounced State Saving
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Approach&lt;/strong&gt;: Use setTimeout to delay state saves and avoid conflicts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: This created timing issues and still didn't solve the core problem of ReactFlow's state interference.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 3: ReactFlow Instance Access
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Approach&lt;/strong&gt;: Use ReactFlow's instance methods to get current state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Still faced race conditions and state inconsistency.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Breakthrough: External State Management
&lt;/h3&gt;

&lt;p&gt;After multiple failed attempts, we realized the fundamental issue was trying to work within ReactFlow's state management system. The solution was to implement a completely external state management system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SimpleUndoRedo class - completely independent&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleUndoRedo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HistoryState&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="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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="nf"&gt;saveState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;currentState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HistoryState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;nodes&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;parse&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="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="na"&gt;edges&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;parse&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="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="c1"&gt;// ... history management logic&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;undo&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;HistoryState&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentIndex&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentIndex&lt;/span&gt;&lt;span class="o"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentIndex&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;nodes&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;parse&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="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="na"&gt;edges&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;parse&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="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;edges&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;return&lt;/span&gt; &lt;span class="kc"&gt;null&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Insights&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deep Cloning&lt;/strong&gt;: Using &lt;code&gt;JSON.parse(JSON.stringify())&lt;/code&gt; to create true copies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;External Storage&lt;/strong&gt;: Keeping history outside React's state system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct State Setting&lt;/strong&gt;: Setting nodes/edges directly without ReactFlow interference&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timing Control&lt;/strong&gt;: Using setTimeout to ensure state changes complete&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 3: Performance Optimization
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Infinite Loop Crisis
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Our implementation caused "Maximum update depth exceeded" errors due to infinite re-renders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;: The nodes array was being recreated on every render, causing ReactFlow to continuously update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Memoization&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;memoizedNodes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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;nodes&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;n&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&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;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;highlighted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;highlightedNodeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;isMultiSelected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;selectedNodes&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;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;selectedNodes&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;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;selectedNode&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;id&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;nodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;highlightedNodeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;selectedNodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;selectedNode&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;
  
  
  Technical Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. State Management Is Harder Than It Looks
&lt;/h3&gt;

&lt;p&gt;ReactFlow's internal state management is complex and not easily extensible. Sometimes the best solution is to work around it rather than with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Deep Cloning Is Essential
&lt;/h3&gt;

&lt;p&gt;JavaScript object references can cause subtle bugs. Deep cloning ensures true state independence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bad: Shallow copy&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;edges&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Good: Deep copy&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;good&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;nodes&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;parse&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="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; 
  &lt;span class="na"&gt;edges&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;parse&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="nx"&gt;edges&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;h3&gt;
  
  
  3. Performance Requires Memoization
&lt;/h3&gt;

&lt;p&gt;In React applications with complex state, memoization isn't optional - it's essential for preventing infinite loops and performance issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. User Experience Matters More Than Perfect Code
&lt;/h3&gt;

&lt;p&gt;Sometimes a "hacky" solution that works well for users is better than a "perfect" solution that's brittle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Final Architecture
&lt;/h2&gt;

&lt;p&gt;Our final implementation consists of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SelectionBox Component&lt;/strong&gt;: Handles visual selection box rendering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SimpleUndoRedo Class&lt;/strong&gt;: Independent state management for history&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Simulator Component&lt;/strong&gt;: Main orchestration with all features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Selection Logic&lt;/strong&gt;: Shift+drag and Shift+click interactions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyboard Shortcuts&lt;/strong&gt;: Comprehensive shortcut system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual Indicators&lt;/strong&gt;: CSS-based feedback for selected components&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Performance Metrics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory Usage&lt;/strong&gt;: ~50 history states (configurable)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rendering Performance&lt;/strong&gt;: Optimized with memoization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event Response Time&lt;/strong&gt;: &amp;lt;16ms for all interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out ArchScope - &lt;a href="https://archscope-app.vercel.app/" rel="noopener noreferrer"&gt;https://archscope-app.vercel.app/&lt;/a&gt;&lt;br&gt;
Its an architecture analysis tool that can be used to evaluate your High level designs under varying loads.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Introducing ArchScope: Visual System Architecture Simulator</title>
      <dc:creator>Arpit Godghate</dc:creator>
      <pubDate>Mon, 13 Apr 2026 12:25:47 +0000</pubDate>
      <link>https://forem.com/irishcheezecake/introducing-archscope-visual-system-architecture-simulator-41m2</link>
      <guid>https://forem.com/irishcheezecake/introducing-archscope-visual-system-architecture-simulator-41m2</guid>
      <description>&lt;p&gt;What is ArchScope?&lt;br&gt;
ArchScope is an interactive web-based tool that lets you design, visualise, and test system architectures with real-time performance simulations. Think of it as a digital playground for architects and engineers to experiment with different system designs before committing to expensive infrastructure decisions.&lt;/p&gt;

&lt;p&gt;Core Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Visual Architecture Design&lt;br&gt;
Real-time connections with animated data flow visualization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Performance Simulation Engine&lt;br&gt;
Accurate metrics including latency, throughput, utilization, and cost calculations&lt;br&gt;
Time-series visualization showing system behavior over time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Comprehensive Analytics&lt;br&gt;
Bottleneck detection with actionable suggestions&lt;br&gt;
Cost analysis per hour and per month&lt;br&gt;
Latency breakdown by component&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced Configuration&lt;br&gt;
Rate limiting algorithms: Token bucket, fixed window, sliding window, leaky bucket&lt;br&gt;
Cache configuration: TTL, hit rates, Redis integration&lt;br&gt;
Queue settings: Max messages, processing times&lt;br&gt;
Custom cost overrides: Override default pricing with real-world rates&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Technology Stack:&lt;/p&gt;

&lt;p&gt;Next.js 16 with TypeScript for robust development&lt;br&gt;
React Flow for interactive diagram visualisation&lt;br&gt;
TailwindCSS for clean, responsive UI&lt;br&gt;
Recharts for performance charts&lt;br&gt;
Lucide React for minimalist icons&lt;/p&gt;

&lt;p&gt;What Makes ArchScope Different?&lt;br&gt;
Unlike static diagramming tools, ArchScope brings your architecture to life. While existing tools help you document existing infrastructure, ArchScope lets you test hypothetical designs and predict performance before deployment.&lt;/p&gt;

&lt;p&gt;Real-World Use Cases: &lt;/p&gt;

&lt;p&gt;Capacity Planning: Test if your current architecture can handle Black Friday traffic&lt;br&gt;
Cost Optimisation: Compare serverless vs. container-based approaches&lt;br&gt;
Migration Planning: Simulate moving from monolith to microservices&lt;br&gt;
Performance Debugging: Identify bottlenecks before they impact users&lt;/p&gt;

&lt;p&gt;Try It Out&lt;br&gt;
Visit &lt;a href="https://archscope-app.vercel.app" rel="noopener noreferrer"&gt;ArchScope&lt;/a&gt;: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with a preset architecture or build from scratch&lt;/li&gt;
&lt;li&gt;Configure simulation parameters (users, requests, duration)&lt;/li&gt;
&lt;li&gt;Hit "Run Simulation" and watch your system come to life&lt;/li&gt;
&lt;li&gt;Analyse the results and iterate on your design&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'd love to hear your thoughts on ArchScope:  &lt;/p&gt;

&lt;p&gt;What architectures did you design?&lt;br&gt;
How did the simulation results help your planning?&lt;br&gt;
What features would you like to see added?&lt;br&gt;
Any feedback on the user experience or pricing accuracy?&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Built a 20-Hour DBMS Interview Prep System Using LLMs — Does It Actually Work?</title>
      <dc:creator>Arpit Godghate</dc:creator>
      <pubDate>Fri, 10 Apr 2026 11:49:57 +0000</pubDate>
      <link>https://forem.com/irishcheezecake/i-built-a-20-hour-dbms-interview-prep-system-using-llms-does-it-actually-work-3bm6</link>
      <guid>https://forem.com/irishcheezecake/i-built-a-20-hour-dbms-interview-prep-system-using-llms-does-it-actually-work-3bm6</guid>
      <description>&lt;p&gt;I used LLMs to build a complete DBMS interview prep system. Here's exactly how - and I want your honest feedback.&lt;/p&gt;

&lt;p&gt;Instead of randomly Googling "DBMS interview questions", I ran an experiment using LLMs as my study partner. The results surprised me.&lt;/p&gt;

&lt;p&gt;Step 1: Curate the right questions&lt;br&gt;
I asked the LLM: "What are the most frequently asked DBMS questions in senior backend interviews?", not once, but iteratively. I cross-referenced across difficulty levels, topics, and interview formats until I had a distilled list of 100 questions spanning 10 modules - from basics like normalisation all the way to replication, sharding, and MVCC.&lt;/p&gt;

&lt;p&gt;Step 2: Find the minimal set of resources&lt;br&gt;
Here's where it got interesting. I gave the LLM my 100 questions and asked: "What is the smallest set of resources that covers all of these with zero overlap?" It mapped every question to exactly 3 resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;InterviewBit DBMS/SQL articles (free) - for fundamentals + SQL practice&lt;/li&gt;
&lt;li&gt;DDIA by Martin Kleppmann (only 5 specific chapters) - for the deep "why" behind transactions, indexing, replication, and storage&lt;/li&gt;
&lt;li&gt;LeetCode Top SQL 50 - for hands-on query practice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total estimated time: ~20 hours. No fluff, no 40-hour courses.&lt;/p&gt;

&lt;p&gt;Step 3: Interview-style learning&lt;br&gt;
This was the game-changer. After studying, I asked the LLM to act as an interviewer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It asked me each question one by one&lt;/li&gt;
&lt;li&gt;I answered as if I were in a real interview&lt;/li&gt;
&lt;li&gt;It evaluated my response - not just for correctness, but for what a recruiter at a senior level would actually want to hear (trade-offs, real-world examples, depth vs. rambling)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This feedback loop forced me to articulate answers clearly instead of just "knowing" the concept in my head.&lt;/p&gt;

&lt;p&gt;Why I'm sharing this:&lt;br&gt;
I genuinely don't know if this approach is better or worse than traditional prep. It felt efficient, but I want to pressure-test it with people who've been on the other side of the table.&lt;/p&gt;

&lt;p&gt;A few specific questions for you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If you've interviewed candidates, does this kind of structured prep actually show in interviews, or does it come across as rehearsed?&lt;/li&gt;
&lt;li&gt;Are there blind spots in using an LLM as both curriculum designer and mock interviewer?&lt;/li&gt;
&lt;li&gt;What would you add or change to this method?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'll share the full 100-question study guide with the 7-day plan in the comments if anyone wants it.&lt;/p&gt;

&lt;p&gt;Would love to hear what's worked (or not worked) for you.&lt;/p&gt;

</description>
      <category>interview</category>
      <category>database</category>
      <category>backend</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
