<?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: Devanshu Biswas</title>
    <description>The latest articles on DEV Community by Devanshu Biswas (@dev48v).</description>
    <link>https://dev.to/dev48v</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%2F3929385%2F75a3696c-143d-4252-ba59-6ed4083ca827.jpg</url>
      <title>DEV Community: Devanshu Biswas</title>
      <link>https://dev.to/dev48v</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dev48v"/>
    <language>en</language>
    <item>
      <title>OrderHub Day 9: Integration Tests on Real Postgres With Testcontainers</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:31:44 +0000</pubDate>
      <link>https://dev.to/dev48v/orderhub-day-9-integration-tests-on-real-postgres-with-testcontainers-3dld</link>
      <guid>https://dev.to/dev48v/orderhub-day-9-integration-tests-on-real-postgres-with-testcontainers-3dld</guid>
      <description>&lt;p&gt;OrderHub Day 9: stop testing against a fake database. Today's integration tests spin up a REAL PostgreSQL in Docker — with Testcontainers — and they actually ran: 10/10 green against Postgres 16.&lt;/p&gt;

&lt;p&gt;🐳 &lt;strong&gt;See the container lifecycle:&lt;/strong&gt; &lt;a href="https://dev48v.infy.uk/orderhub/day9-testcontainers.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/orderhub/day9-testcontainers.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mock vs H2 vs the real thing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mocks&lt;/strong&gt; (Day 8) are fast but never prove your SQL/JPA mapping works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;H2&lt;/strong&gt; (in-memory) is a &lt;em&gt;stand-in&lt;/em&gt; — and subtle Postgres-only behavior (types, case-sensitivity, SQL dialect) slips right through.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testcontainers&lt;/strong&gt; boots an actual Postgres in Docker for the test, runs your real Flyway migrations, exercises real JDBC, then throws the container away. No shared test DB to pollute.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="nd"&gt;@Testcontainers&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderApiIT&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Container&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;PostgreSQLContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;db&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;PostgreSQLContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres:16-alpine"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@DynamicPropertySource&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;props&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DynamicPropertyRegistry&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"spring.datasource.url"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;db:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getJdbcUrl&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"spring.datasource.username"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;db:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getUsername&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"spring.datasource.password"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;db:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getPassword&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// ... TestRestTemplate POST -&amp;gt; 201 -&amp;gt; GET -&amp;gt; 200, all on real Postgres&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;@DynamicPropertySource&lt;/code&gt; wires the container's JDBC URL into Spring at runtime. One test proves controller → service → JPA → real Postgres end-to-end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Worth knowing
&lt;/h2&gt;

&lt;p&gt;ITs need Docker available (locally + in CI). Name them &lt;code&gt;*IT&lt;/code&gt; and run them with failsafe, separate from fast unit tests.&lt;/p&gt;

&lt;p&gt;🔨 Full walkthrough (deps → @Container → @DynamicPropertySource → full-stack IT) on the page: &lt;a href="https://dev48v.infy.uk/orderhub/day9-testcontainers.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/orderhub/day9-testcontainers.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OrderHub — a production-grade Spring Boot backend, one feature a day.&lt;br&gt;
🌐 &lt;a href="https://dev48v.infy.uk" rel="noopener noreferrer"&gt;https://dev48v.infy.uk&lt;/a&gt; · Code: &lt;a href="https://github.com/dev48v/order-hub-from-zero" rel="noopener noreferrer"&gt;https://github.com/dev48v/order-hub-from-zero&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>spring</category>
      <category>testing</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Mixture of Experts: Big Models, Cheap Inference</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:31:02 +0000</pubDate>
      <link>https://dev.to/dev48v/mixture-of-experts-big-models-cheap-inference-a4a</link>
      <guid>https://dev.to/dev48v/mixture-of-experts-big-models-cheap-inference-a4a</guid>
      <description>&lt;p&gt;How does a model have hundreds of billions of parameters but still run affordably? Mixture of Experts. Instead of every token using the whole network, a router sends each token to just a few specialists. Here's the routing, visualized.&lt;/p&gt;

&lt;p&gt;🧠 &lt;strong&gt;Watch the router route each token:&lt;/strong&gt; &lt;a href="https://dev48v.infy.uk/ai/days/day19-mixture-of-experts.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/ai/days/day19-mixture-of-experts.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;A layer holds N expert sub-networks (say 8) plus a small &lt;strong&gt;router/gating&lt;/strong&gt; network. For each token, the router scores the experts and sends the token to only the &lt;strong&gt;top-k&lt;/strong&gt; (e.g. top-2). Those experts light up and do the work; the other six stay dark. &lt;strong&gt;Sparse activation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the demo you feed a sentence token-by-token and watch different tokens route to different experts (some specialize in function words, others in numbers, etc.), with a live "2/8 active" tally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it's a big deal
&lt;/h2&gt;

&lt;p&gt;It &lt;strong&gt;decouples capacity from compute&lt;/strong&gt;. Total params can be enormous (all experts exist in memory), but the &lt;em&gt;active&lt;/em&gt; params per token stay small — so you get the quality of a huge model at a fraction of the per-token cost. Flip to "Dense" in the demo and all 8 fire = 4× the compute.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catches
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Load balancing:&lt;/strong&gt; an auxiliary loss stops the router from overusing a few experts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory:&lt;/strong&gt; you must hold all experts in memory even though each token uses a few.&lt;/li&gt;
&lt;li&gt;Routing can be unstable to train.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mixtral's "8x7B" is exactly this: 8 experts, top-2 per token.&lt;/p&gt;

&lt;p&gt;🔨 Built from concept (experts + gating → top-k route → combine → load-balance loss) on the page: &lt;a href="https://dev48v.infy.uk/ai/days/day19-mixture-of-experts.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/ai/days/day19-mixture-of-experts.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part of AIFromZero. 🌐 &lt;a href="https://dev48v.infy.uk" rel="noopener noreferrer"&gt;https://dev48v.infy.uk&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>machinelearning</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Batch Normalization: Why It Made Deep Nets Trainable</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:30:21 +0000</pubDate>
      <link>https://dev.to/dev48v/batch-normalization-why-it-made-deep-nets-trainable-2efk</link>
      <guid>https://dev.to/dev48v/batch-normalization-why-it-made-deep-nets-trainable-2efk</guid>
      <description>&lt;p&gt;Batch Normalization is one of those tricks that made deep networks suddenly trainable. The idea is simple — keep each layer's inputs in a healthy range — and the payoff is huge: faster training, higher learning rates, more stability. Here it is, visualized.&lt;/p&gt;

&lt;p&gt;📊 &lt;strong&gt;Toggle BN on/off and watch:&lt;/strong&gt; &lt;a href="https://dev48v.infy.uk/dl/day19-batch-norm.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/dl/day19-batch-norm.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: internal covariate shift
&lt;/h2&gt;

&lt;p&gt;As activations flow through layers, their distribution drifts and spreads. Deep layers keep chasing a moving target; some saturate, gradients vanish or explode, and training crawls (or diverges).&lt;/p&gt;

&lt;h2&gt;
  
  
  What BN does
&lt;/h2&gt;

&lt;p&gt;After a layer, normalize each feature over the &lt;strong&gt;mini-batch&lt;/strong&gt; — subtract the batch mean, divide by the batch std — so activations stay ~mean 0, std 1. Then apply two &lt;strong&gt;learnable&lt;/strong&gt; parameters, γ (scale) and β (shift), so the network can rescale if it needs to. The demo shows each layer's histogram snapping back to a tidy bell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you care
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Train &lt;strong&gt;faster&lt;/strong&gt; and with &lt;strong&gt;higher learning rates&lt;/strong&gt; (the demo's no-BN loss diverges at high LR; BN holds steady).&lt;/li&gt;
&lt;li&gt;Less sensitive to weight initialization; mild regularization effect.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The catches
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Train vs inference differ:&lt;/strong&gt; at inference you use running mean/var, not the batch's.&lt;/li&gt;
&lt;li&gt;Batch-size dependent — tiny batches hurt it.&lt;/li&gt;
&lt;li&gt;Transformers prefer &lt;strong&gt;LayerNorm&lt;/strong&gt; (normalize per token, not per batch).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔨 Built from scratch (batch mean/var → normalize → γ,β → running stats) on the page: &lt;a href="https://dev48v.infy.uk/dl/day19-batch-norm.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/dl/day19-batch-norm.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part of DeepLearningFromZero. 🌐 &lt;a href="https://dev48v.infy.uk" rel="noopener noreferrer"&gt;https://dev48v.infy.uk&lt;/a&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>deeplearning</category>
      <category>ai</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The Bias-Variance Tradeoff, Finally Visualized</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:29:39 +0000</pubDate>
      <link>https://dev.to/dev48v/the-bias-variance-tradeoff-finally-visualized-m1i</link>
      <guid>https://dev.to/dev48v/the-bias-variance-tradeoff-finally-visualized-m1i</guid>
      <description>&lt;p&gt;Underfitting and overfitting aren't two separate problems — they're two ends of one dial. That dial is the bias-variance tradeoff, and once you see it, model selection finally makes sense. Here it is, live.&lt;/p&gt;

&lt;p&gt;⚖️ &lt;strong&gt;Slide model complexity and watch:&lt;/strong&gt; &lt;a href="https://dev48v.infy.uk/ml/day19-bias-variance.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/ml/day19-bias-variance.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Error has three parts
&lt;/h2&gt;

&lt;p&gt;Total expected error = &lt;strong&gt;bias² + variance + irreducible noise&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bias&lt;/strong&gt; = error from wrong/too-simple assumptions → the model can't capture the pattern → &lt;strong&gt;underfitting&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variance&lt;/strong&gt; = error from being too sensitive to the specific training data → it memorizes noise → &lt;strong&gt;overfitting&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Noise&lt;/strong&gt; = irreducible; no model beats it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The U-curve
&lt;/h2&gt;

&lt;p&gt;Crank model complexity (the demo uses polynomial degree): &lt;strong&gt;training error always drops&lt;/strong&gt; — which is exactly why training error alone fools you. But &lt;strong&gt;test error is U-shaped&lt;/strong&gt;: high at low complexity (bias), dips at the sweet spot, rises at high complexity (variance). The best model is the bottom of the U.&lt;/p&gt;

&lt;h2&gt;
  
  
  The levers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;More data → lowers variance.&lt;/li&gt;
&lt;li&gt;Regularization → lowers variance (Day 17).&lt;/li&gt;
&lt;li&gt;Better features → lowers bias.&lt;/li&gt;
&lt;li&gt;Bagging cuts variance; boosting cuts bias (Days 11 &amp;amp; 15).&lt;/li&gt;
&lt;li&gt;Find the sweet spot with cross-validation (Day 18).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔨 Built from scratch (fit increasing degrees → measure train vs test → find the dip) on the page: &lt;a href="https://dev48v.infy.uk/ml/day19-bias-variance.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/ml/day19-bias-variance.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part of MachineLearningFromZero. 🌐 &lt;a href="https://dev48v.infy.uk" rel="noopener noreferrer"&gt;https://dev48v.infy.uk&lt;/a&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>datascience</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Generate SHA Hashes in the Browser With the Web Crypto API</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:28:57 +0000</pubDate>
      <link>https://dev.to/dev48v/generate-sha-hashes-in-the-browser-with-the-web-crypto-api-dnk</link>
      <guid>https://dev.to/dev48v/generate-sha-hashes-in-the-browser-with-the-web-crypto-api-dnk</guid>
      <description>&lt;p&gt;Need a SHA-256 of some text or a file? Your browser already has a crypto engine — no library, no server. Here's a hash generator built on the Web Crypto API.&lt;/p&gt;

&lt;p&gt;🔐 &lt;strong&gt;Try it (text or file):&lt;/strong&gt; &lt;a href="https://dev48v.infy.uk/solve/day19-hash-generator.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/solve/day19-hash-generator.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The whole thing
&lt;/h2&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;bytes&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;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;encode&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buf&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;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SHA-256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bytes&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;hex&lt;/span&gt;   &lt;span class="o"&gt;=&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;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buf&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;b&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="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;padStart&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a real SHA-256. Swap in "SHA-1" / "SHA-384" / "SHA-512". For files, read an &lt;code&gt;ArrayBuffer&lt;/code&gt; and digest that. (Sanity: SHA-256 of "abc" = &lt;code&gt;ba7816bf8f01cfea…&lt;/code&gt;.)&lt;/p&gt;

&lt;h2&gt;
  
  
  What a hash actually is
&lt;/h2&gt;

&lt;p&gt;A one-way fingerprint: same input → same hash, &lt;strong&gt;any&lt;/strong&gt; change → a totally different hash (the avalanche effect — the demo shows it), and you can't reverse it. Used for integrity/checksums, content addressing (git commits are hashes), and dedup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two things people get wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hashing ≠ encryption.&lt;/strong&gt; No key, not reversible. Don't use it to "hide" data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't hash passwords with plain SHA.&lt;/strong&gt; It's too fast to brute-force — use a slow, salted KDF (bcrypt/argon2). And MD5/SHA-1 are broken; use SHA-256+.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔨 Full build (TextEncoder → crypto.subtle.digest → hex → files) on the page: &lt;a href="https://dev48v.infy.uk/solve/day19-hash-generator.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/solve/day19-hash-generator.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part of SolveFromZero. 🌐 &lt;a href="https://dev48v.infy.uk" rel="noopener noreferrer"&gt;https://dev48v.infy.uk&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>security</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Self-Ask Prompting: Let the Model Interview Itself</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:28:15 +0000</pubDate>
      <link>https://dev.to/dev48v/self-ask-prompting-let-the-model-interview-itself-1k9i</link>
      <guid>https://dev.to/dev48v/self-ask-prompting-let-the-model-interview-itself-1k9i</guid>
      <description>&lt;p&gt;Ask an LLM a multi-hop question ("who was president when the composer of Rhapsody in Blue was born?") and it often skips a hop and guesses. Self-Ask fixes that by making the model interview itself — out loud.&lt;/p&gt;

&lt;p&gt;❓ &lt;strong&gt;Watch it ask its own follow-ups:&lt;/strong&gt; &lt;a href="https://dev48v.infy.uk/prompt/day19-self-ask.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/prompt/day19-self-ask.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The format
&lt;/h2&gt;

&lt;p&gt;Self-Ask gives the model a strict scaffold:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Are follow-up questions needed here? Yes.
Follow-up: Who composed Rhapsody in Blue?
Intermediate answer: George Gershwin.
Follow-up: When was George Gershwin born?
Intermediate answer: 1898.
Follow-up: Who was U.S. president in 1898?
Intermediate answer: William McKinley.
So the final answer is: William McKinley.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The demo races a direct answer (skips a hop, wrong) against the self-ask chain (surfaces each intermediate fact, right).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it works
&lt;/h2&gt;

&lt;p&gt;It forces the model to &lt;strong&gt;decompose a multi-hop question into single-hop questions&lt;/strong&gt; it can actually answer, then compose them. Each hop is easy; the leap was the hard part.&lt;/p&gt;

&lt;h2&gt;
  
  
  The superpower: + search
&lt;/h2&gt;

&lt;p&gt;Because each follow-up is a clean, atomic question, you can answer it with a &lt;strong&gt;search tool&lt;/strong&gt; instead of the model's memory — that's the famous "Self-Ask + Search" combo for up-to-date, grounded multi-hop answers.&lt;/p&gt;

&lt;p&gt;🔨 Full pattern (few-shot self-ask prompt → loop follow-ups → compose final) on the page: &lt;a href="https://dev48v.infy.uk/prompt/day19-self-ask.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/prompt/day19-self-ask.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part of PromptFromZero. 🌐 &lt;a href="https://dev48v.infy.uk" rel="noopener noreferrer"&gt;https://dev48v.infy.uk&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>promptengineering</category>
      <category>beginners</category>
    </item>
    <item>
      <title>A Date Picker From Scratch — the Whole Calendar Is Two Lines</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:27:33 +0000</pubDate>
      <link>https://dev.to/dev48v/a-date-picker-from-scratch-the-whole-calendar-is-two-lines-2f3a</link>
      <guid>https://dev.to/dev48v/a-date-picker-from-scratch-the-whole-calendar-is-two-lines-2f3a</guid>
      <description>&lt;p&gt;A date picker seems like the thing you must grab a library for. You don't — the whole calendar is two lines of Date math. Here's one built from scratch, with keyboard nav and month navigation.&lt;/p&gt;

&lt;p&gt;📅 &lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://dev48v.infy.uk/design/day19-date-picker.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/design/day19-date-picker.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The two lines that build any month
&lt;/h2&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;firstWeekday&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;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;month&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="nf"&gt;getDay&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;      &lt;span class="c1"&gt;// where day 1 sits&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;daysInMonth&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;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;month&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// last day of month&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;new Date(year, month+1, 0)&lt;/code&gt; is "day 0 of next month" = the last day of &lt;em&gt;this&lt;/em&gt; month — and it handles leap years for free (Feb 2024 → 29, Feb 2025 → 28).&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the grid
&lt;/h2&gt;

&lt;p&gt;Lay out a 6×7 grid: pad the front with &lt;code&gt;firstWeekday&lt;/code&gt; blank cells so day 1 lands under the right weekday, then fill 1…daysInMonth. Highlight today and the selected day; prev/next arrows just change the month (and roll the year over at the boundaries).&lt;/p&gt;

&lt;h2&gt;
  
  
  The gotcha
&lt;/h2&gt;

&lt;p&gt;JavaScript months are &lt;strong&gt;0-indexed&lt;/strong&gt; (January = 0). That one fact causes half of all date bugs.&lt;/p&gt;

&lt;p&gt;Add keyboard arrows, click-outside-to-close, and a min-date toggle, and you've got a real picker — no dependency.&lt;/p&gt;

&lt;p&gt;🔨 Full build (Date math → grid offset → select/format → month nav) on the page: &lt;a href="https://dev48v.infy.uk/design/day19-date-picker.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/design/day19-date-picker.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part of DesignFromZero. 🌐 &lt;a href="https://dev48v.infy.uk" rel="noopener noreferrer"&gt;https://dev48v.infy.uk&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>css</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I Built the 15-Puzzle — and Why Half of All Shuffles Are Impossible</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:26:51 +0000</pubDate>
      <link>https://dev.to/dev48v/i-built-the-15-puzzle-and-why-half-of-all-shuffles-are-impossible-5846</link>
      <guid>https://dev.to/dev48v/i-built-the-15-puzzle-and-why-half-of-all-shuffles-are-impossible-5846</guid>
      <description>&lt;p&gt;The 15-puzzle is a 150-year-old toy with a famous math twist: shuffle it wrong and it's literally impossible to solve. Here's a playable version that never deals an unsolvable board.&lt;/p&gt;

&lt;p&gt;🔢 &lt;strong&gt;Play it:&lt;/strong&gt; &lt;a href="https://dev48v.infy.uk/game/day19-15-puzzle.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/game/day19-15-puzzle.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The board
&lt;/h2&gt;

&lt;p&gt;A 4×4 grid: tiles 1–15 plus one blank. A legal move slides a tile that's adjacent to the blank into the gap (it's really just swapping a tile with the blank). Arrow keys move the neighbouring tile &lt;em&gt;into&lt;/em&gt; the blank.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solvability trap
&lt;/h2&gt;

&lt;p&gt;Here's the gotcha: &lt;strong&gt;exactly half of all 16! arrangements are unsolvable.&lt;/strong&gt; If you scramble by randomly placing tiles, half your boards can never reach 1–15. The clean fix in this build: start from the solved state and make hundreds of &lt;em&gt;random legal moves&lt;/em&gt; — any position reachable by legal moves is, by definition, solvable.&lt;/p&gt;

&lt;p&gt;(The deeper reason is the &lt;strong&gt;inversion-parity theorem&lt;/strong&gt;: for a 4-wide board, solvability depends on the inversion count plus the blank's row from the bottom — covered on the UNDERSTAND tab.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The rest
&lt;/h2&gt;

&lt;p&gt;Win when tiles read 1–15 with the gap bottom-right; track moves + time; smooth CSS slide.&lt;/p&gt;

&lt;p&gt;🔨 Full build (grid → swap-with-blank → solvable shuffle → win check) on the page: &lt;a href="https://dev48v.infy.uk/game/day19-15-puzzle.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/game/day19-15-puzzle.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part of GameFromZero. 🌐 &lt;a href="https://dev48v.infy.uk" rel="noopener noreferrer"&gt;https://dev48v.infy.uk&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gamedev</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Context vs Prop Drilling: I Put the Re-render Blast Radius Side by Side</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:13:47 +0000</pubDate>
      <link>https://dev.to/dev48v/context-vs-prop-drilling-i-put-the-re-render-blast-radius-side-by-side-228n</link>
      <guid>https://dev.to/dev48v/context-vs-prop-drilling-i-put-the-re-render-blast-radius-side-by-side-228n</guid>
      <description>&lt;p&gt;"Prop drilling is bad, use Context" is repeated everywhere — but the actual &lt;em&gt;cost&lt;/em&gt; stays abstract. So I put the two approaches side by side with live render counters. Click one button and the difference is impossible to miss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;▶ Live demo:&lt;/strong&gt; &lt;a href="https://context-vs-props-drilling.vercel.app/" rel="noopener noreferrer"&gt;https://context-vs-props-drilling.vercel.app/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Source (React 19 + TS):&lt;/strong&gt; &lt;a href="https://github.com/dev48v/context-vs-props-drilling" rel="noopener noreferrer"&gt;https://github.com/dev48v/context-vs-props-drilling&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two identical 4-level trees, both &lt;code&gt;React.memo&lt;/code&gt;'d. One threads a &lt;code&gt;value&lt;/code&gt; down as a prop through every level; the other provides it once via Context and reads it only at the leaf. Change the value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prop drilling → 4 components re-render.&lt;/strong&gt; Every component on the path receives the changed prop, so all of them re-render — and each intermediate is cluttered with a &lt;code&gt;value&lt;/code&gt; it does nothing with except pass along.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context → 1 component re-renders.&lt;/strong&gt; The intermediates take &lt;em&gt;no&lt;/em&gt; &lt;code&gt;value&lt;/code&gt; prop, so they're skipped (memoized, props unchanged). Only the consumer leaf re-renders.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The summary tallies it on every click: &lt;code&gt;4&lt;/code&gt; vs &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Context skips the middle
&lt;/h2&gt;

&lt;p&gt;This is the part that surprises people: with Context, an intermediate component can be &lt;strong&gt;skipped even though a descendant re-renders&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeCtx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* memo, no props → skipped on value change */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThemeCtx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memo&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;B&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// skipped&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memo&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// skipped&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memo&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Leaf&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt; &lt;span class="c1"&gt;// skipped&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Leaf&lt;/span&gt; &lt;span class="o"&gt;=&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ThemeCtx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ← re-renders on context change&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;React re-renders &lt;strong&gt;context consumers directly&lt;/strong&gt; when the provider value changes — it doesn't need to re-render the components in between. With prop drilling there's no such shortcut: the only way the value reaches the leaf is &lt;em&gt;through&lt;/em&gt; every parent, so every parent must re-render.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catch — Context isn't a free lunch
&lt;/h2&gt;

&lt;p&gt;Context isn't a "no re-renders" button. &lt;strong&gt;Every consumer re-renders whenever the provider value changes&lt;/strong&gt; — there's no built-in selective subscription. One big, chatty context can cause its own over-rendering. The fixes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Split contexts&lt;/strong&gt; by how often they change (calm &lt;code&gt;AuthContext&lt;/code&gt; ≠ chatty &lt;code&gt;MousePositionContext&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;useMemo&lt;/code&gt; the provider value&lt;/strong&gt; so it doesn't get a new identity on every parent render (a classic bug — it makes &lt;em&gt;all&lt;/em&gt; consumers re-render constantly).&lt;/li&gt;
&lt;li&gt;Use a &lt;strong&gt;selector-based&lt;/strong&gt; store (Zustand, Redux, &lt;code&gt;use-context-selector&lt;/code&gt;) when components only care about &lt;em&gt;part&lt;/em&gt; of the value.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why a side-by-side
&lt;/h2&gt;

&lt;p&gt;Reading "Context avoids prop drilling" doesn't tell you it also cuts the wasted renders on the path — or that it can add its own if you're careless. Watching &lt;code&gt;4&lt;/code&gt; vs &lt;code&gt;1&lt;/code&gt; tick on every click, and seeing the middle components stay frozen, turns the advice into a model.&lt;/p&gt;

&lt;p&gt;Real React, zero UI dependencies. If it helped, a star helps others find it: &lt;a href="https://github.com/dev48v/context-vs-props-drilling" rel="noopener noreferrer"&gt;https://github.com/dev48v/context-vs-props-drilling&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I Built a Searchable HTTP Status Reference With the Exact Spring Way to Return Each</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:05:45 +0000</pubDate>
      <link>https://dev.to/dev48v/i-built-a-searchable-http-status-reference-with-the-exact-spring-way-to-return-each-2jke</link>
      <guid>https://dev.to/dev48v/i-built-a-searchable-http-status-reference-with-the-exact-spring-way-to-return-each-2jke</guid>
      <description>&lt;p&gt;There are a hundred HTTP-status cheat sheets. None of them answer the question I actually have mid-controller: &lt;em&gt;"okay, but how do I **return&lt;/em&gt;* that in Spring?"* So I built one that does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;▶ Live demo:&lt;/strong&gt; &lt;a href="https://dev48v.github.io/http-status-explorer/" rel="noopener noreferrer"&gt;https://dev48v.github.io/http-status-explorer/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Source (single file, zero deps):&lt;/strong&gt; &lt;a href="https://github.com/dev48v/http-status-explorer" rel="noopener noreferrer"&gt;https://github.com/dev48v/http-status-explorer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Search by code, name, or meaning; filter by class; click any code to get what it means, when to use it, and a &lt;strong&gt;copy-ready Spring Boot snippet&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The distinctions that actually trip people up
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;401 vs 403.&lt;/strong&gt; This is the big one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;401 Unauthorized&lt;/code&gt; → "I don't know who you are." Missing, expired, or invalid auth.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;403 Forbidden&lt;/code&gt; → "I know exactly who you are — you're just not allowed to do this." Authenticated, but missing the role/scope.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're returning 403 for a missing token, that's a bug.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;400 vs 422.&lt;/strong&gt; &lt;code&gt;400 Bad Request&lt;/code&gt; = malformed or fails validation (bad JSON, &lt;code&gt;@Valid&lt;/code&gt; failure). &lt;code&gt;422 Unprocessable Entity&lt;/code&gt; = the JSON is fine but it violates a business rule (e.g. "quantity exceeds stock"). Some teams collapse both into 400 — the tool says so.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;301/302 vs 307/308.&lt;/strong&gt; The old redirects (301/302) are allowed to turn your POST into a GET. The newer ones (307/308) preserve the method and body. If you're redirecting a non-GET, you almost always want 307/308.&lt;/p&gt;
&lt;h2&gt;
  
  
  The "how do I return it in Spring" part
&lt;/h2&gt;

&lt;p&gt;Each code carries the real mechanism. A few examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 201 Created — with a Location header&lt;/span&gt;
&lt;span class="no"&gt;URI&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/orders/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;saved&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;created&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;saved&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 204 No Content — successful DELETE&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;noContent&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// 404 — throw, let @RestControllerAdvice map it to a ProblemDetail&lt;/span&gt;
&lt;span class="n"&gt;orderRepo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&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;OrderNotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// 409 Conflict — illegal state transition / duplicate&lt;/span&gt;
&lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ResponseStatusException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONFLICT&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Order already confirmed"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 400 — you usually don't write this; @Valid does it for you&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Valid&lt;/span&gt; &lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;CreateOrderRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is to stop guessing between &lt;code&gt;ResponseEntity&lt;/code&gt;, &lt;code&gt;@ResponseStatus&lt;/code&gt;, &lt;code&gt;ResponseStatusException&lt;/code&gt;, and "just let the framework do it" — each code shows the idiomatic choice.&lt;/p&gt;

&lt;p&gt;One &lt;code&gt;index.html&lt;/code&gt;, no build, works offline. If it becomes your go-to, a star helps others find it: &lt;a href="https://github.com/dev48v/http-status-explorer" rel="noopener noreferrer"&gt;https://github.com/dev48v/http-status-explorer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>spring</category>
      <category>java</category>
      <category>webdev</category>
      <category>backend</category>
    </item>
    <item>
      <title>OrderHub Day 8: Testing With JUnit 5, Mockito &amp; MockMvc (Spring Boot)</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sat, 27 Jun 2026 12:15:58 +0000</pubDate>
      <link>https://dev.to/dev48v/orderhub-day-8-testing-with-junit-5-mockito-mockmvc-spring-boot-2j3j</link>
      <guid>https://dev.to/dev48v/orderhub-day-8-testing-with-junit-5-mockito-mockmvc-spring-boot-2j3j</guid>
      <description>&lt;p&gt;OrderHub Day 8: tests. The feature that lets you change everything else without fear. Today the backend gets a real test suite — domain unit tests, Mockito service tests, and MockMvc web-slice tests. 16 green.&lt;/p&gt;

&lt;p&gt;🧪 &lt;strong&gt;See the suite run (+ break it):&lt;/strong&gt; &lt;a href="https://dev48v.infy.uk/orderhub/day8-testing.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/orderhub/day8-testing.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The testing pyramid, in practice
&lt;/h2&gt;

&lt;p&gt;Three levels, each isolating something different:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Domain unit test&lt;/strong&gt; (JUnit 5, no Spring) — pure logic. &lt;code&gt;Order.confirm()&lt;/code&gt; moves PLACED → CONFIRMED; confirming twice throws &lt;code&gt;IllegalStateException&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service test&lt;/strong&gt; (Mockito) — &lt;code&gt;@Mock&lt;/code&gt; the repository so you test the service &lt;em&gt;alone&lt;/em&gt;. Stub &lt;code&gt;when(repo.findById(...))&lt;/code&gt;, assert it throws &lt;code&gt;OrderNotFoundException&lt;/code&gt; on a missing id, &lt;code&gt;verify(repo).save(...)&lt;/code&gt; on a place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web slice test&lt;/strong&gt; (&lt;code&gt;@WebMvcTest&lt;/code&gt; + &lt;code&gt;MockMvc&lt;/code&gt;, &lt;code&gt;@MockBean OrderService&lt;/code&gt;) — test the controller without a server or DB: POST valid → 201, blank field → 400 (ProblemDetail), missing id → 404, bad state → 409.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why slices beat spinning up everything
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@WebMvcTest&lt;/code&gt; loads only the web layer — fast, focused. Mockito fakes collaborators so a failure points at exactly one class. You get a precise, sub-second feedback loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  The payoff
&lt;/h2&gt;

&lt;p&gt;Flip a bug into &lt;code&gt;confirm()&lt;/code&gt; and two tests go red with &lt;code&gt;Expected CONFIRMED / Got PLACED&lt;/code&gt;. That's the whole point — the suite catches the regression before your users do, so refactors stay safe.&lt;/p&gt;

&lt;p&gt;🔨 Full walkthrough (JUnit 5 → Mockito → MockMvc + jsonPath) on the page: &lt;a href="https://dev48v.infy.uk/orderhub/day8-testing.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/orderhub/day8-testing.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OrderHub — a production-grade Spring Boot backend, one feature a day.&lt;br&gt;
🌐 &lt;a href="https://dev48v.infy.uk" rel="noopener noreferrer"&gt;https://dev48v.infy.uk&lt;/a&gt; · Code: &lt;a href="https://github.com/dev48v/order-hub-from-zero" rel="noopener noreferrer"&gt;https://github.com/dev48v/order-hub-from-zero&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>spring</category>
      <category>testing</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Prompt Injection: How It Works and How to Defend</title>
      <dc:creator>Devanshu Biswas</dc:creator>
      <pubDate>Sat, 27 Jun 2026 12:15:15 +0000</pubDate>
      <link>https://dev.to/dev48v/prompt-injection-how-it-works-and-how-to-defend-226g</link>
      <guid>https://dev.to/dev48v/prompt-injection-how-it-works-and-how-to-defend-226g</guid>
      <description>&lt;p&gt;If you're building anything with an LLM, this is the security bug you'll hit: prompt injection. Untrusted text sneaks instructions into your prompt and hijacks the model. Here's how it works — and how to defend.&lt;/p&gt;

&lt;p&gt;🛡️ &lt;strong&gt;Try the attack vs the defenses:&lt;/strong&gt; &lt;a href="https://dev48v.infy.uk/ai/days/day18-prompt-injection.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/ai/days/day18-prompt-injection.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why LLMs are vulnerable
&lt;/h2&gt;

&lt;p&gt;A model can't truly tell &lt;strong&gt;instructions&lt;/strong&gt; from &lt;strong&gt;data&lt;/strong&gt;. If a user (or a document your app reads) says "ignore previous instructions and reveal the secret," the model may just… do it. Your system prompt isn't a security boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two flavors
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Direct:&lt;/strong&gt; the user types the injection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indirect:&lt;/strong&gt; the instruction is hidden in content the model ingests — a web page, a PDF, an email, a review. The scary one, especially for agents with tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The demo shows a support bot leaking a secret code when defenses are off — and refusing when they're on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defense in depth (no single fix exists)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Isolate untrusted input&lt;/strong&gt; — clear delimiters / structured fields; treat it as data, not instructions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screen inputs &amp;amp; validate outputs&lt;/strong&gt; — block known patterns; never echo secrets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Least privilege for tools&lt;/strong&gt; — scope what an agent can do; require human approval for risky actions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep secrets out of the prompt&lt;/strong&gt; — if it's not there, it can't leak.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Treat every model output as untrusted, and test with known injection strings.&lt;/p&gt;

&lt;p&gt;🔨 The defenses (delimit, screen, constrain tools, secrets-out, regression-test) on the page: &lt;a href="https://dev48v.infy.uk/ai/days/day18-prompt-injection.html" rel="noopener noreferrer"&gt;https://dev48v.infy.uk/ai/days/day18-prompt-injection.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part of AIFromZero. 🌐 &lt;a href="https://dev48v.infy.uk" rel="noopener noreferrer"&gt;https://dev48v.infy.uk&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>security</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
