<?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: Vishnu KN</title>
    <description>The latest articles on DEV Community by Vishnu KN (@vishnukn01).</description>
    <link>https://dev.to/vishnukn01</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%2F3524716%2Ff6d6f0bb-6f4a-4ef0-940b-38a1b5212170.png</url>
      <title>DEV Community: Vishnu KN</title>
      <link>https://dev.to/vishnukn01</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vishnukn01"/>
    <language>en</language>
    <item>
      <title>TIL: Temp table vs CTE</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Mon, 03 Nov 2025 05:01:14 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-temp-table-vs-cte-1j25</link>
      <guid>https://dev.to/vishnukn01/til-temp-table-vs-cte-1j25</guid>
      <description>&lt;p&gt;Simple Analogy&lt;/p&gt;

&lt;p&gt;Imagine you’re a chef preparing dishes for a party.&lt;/p&gt;

&lt;p&gt;🍲 Using a Temp Table&lt;/p&gt;

&lt;p&gt;You chop a big bowl of onions once and keep them in a bowl (#TempTable).&lt;br&gt;
Then, whenever a recipe needs onions, you just scoop some out.&lt;br&gt;
✅ Efficient and fast — prep once, reuse many times.&lt;/p&gt;

&lt;p&gt;🍳 Using a CTE&lt;/p&gt;

&lt;p&gt;Instead of keeping the chopped onions, you follow the “chop onions” step every single time a recipe calls for onions.&lt;br&gt;
❌ Wasteful — you repeat the same work multiple times.&lt;/p&gt;




&lt;p&gt;IMPORTAN NOTE: A CTE that is created exists only for the duration of the execution of one statement and within the scope of that statement. So if you are executing multiple statements within a query the use of CTE can bloat up the memory resources used.&lt;/p&gt;




&lt;p&gt;Going back to the chef analogy, there is one instance where the CTE option of “chopping onions” step every single time trumps the temp table option of chopping a big bowl of onions once and keeping them in a bowl. That is, if you are cooking just one dish.&lt;br&gt;
In SQL terms, if your derived data is being used just once, then it does not make sense to create a temporary table.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>beginners</category>
      <category>sql</category>
      <category>database</category>
    </item>
    <item>
      <title>TIL: Transactions in .NET</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Fri, 17 Oct 2025 18:02:20 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-transactions-in-net-1b9n</link>
      <guid>https://dev.to/vishnukn01/til-transactions-in-net-1b9n</guid>
      <description>&lt;p&gt;When your app talks to a database, it might have to do multiple things at once. Sometimes, these things might be connected, and separating them can cause problems.&lt;/p&gt;

&lt;p&gt;Consider an online store where the user purchases something from his balance. For a single purchase, we might want to &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Deduct from the user's balance in one table  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a record of the order to another. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If one of these actions fail, it does not make sense to proceed with the other since it leads to data inconsistencies and confusion. In such cases, transactions come in handy.&lt;/p&gt;

&lt;p&gt;A transaction is like a promise to the database: "Do all of these actions together. If they succeed, great! If even one of them fails, undo everything and pretend like nothing happened" &lt;/p&gt;

&lt;p&gt;In other words, a transaction is a set of database operations, either performed on one table or across multiple tables, which are designed to either succeed as a whole or to fail as a whole. If it succeeds it is 'committed' (the changes are saved) , if it fails it is 'rolled back' (the changes are undone).&lt;/p&gt;

&lt;p&gt;Code example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Data.SqlClient;

class Program
{
    static void Main()
    {
        string connectionString = "your-connection-string-here";

        int userId = 1;
        decimal purchaseAmount = 100;

        using (SqlConnection conn = new SqlConnection(connectionString))
        {
            conn.Open();

            // Start the transaction
            SqlTransaction transaction = conn.BeginTransaction();

            try
            {
                // Step 1: Deduct from User Balance
                SqlCommand deductCmd = new SqlCommand(@"
                    UPDATE Users
                    SET Balance = Balance - @Amount
                    WHERE UserId = @UserId", conn, transaction);
                deductCmd.Parameters.AddWithValue("@Amount", purchaseAmount);
                deductCmd.Parameters.AddWithValue("@UserId", userId);
                deductCmd.ExecuteNonQuery();

                // Step 2: Add to OrderHistory
                SqlCommand insertOrderCmd = new SqlCommand(@"
                    INSERT INTO OrderHistory (UserId, Amount, OrderDate)
                    VALUES (@UserId, @Amount, @OrderDate)", conn, transaction);
                insertOrderCmd.Parameters.AddWithValue("@UserId", userId);
                insertOrderCmd.Parameters.AddWithValue("@Amount", purchaseAmount);
                insertOrderCmd.Parameters.AddWithValue("@OrderDate", DateTime.Now);
                insertOrderCmd.ExecuteNonQuery();

                // Everything succeeded, commit the transaction
                transaction.Commit();
                Console.WriteLine("Purchase completed successfully.");
            }
            catch (Exception ex)
            {
                // Something went wrong, roll back everything
                transaction.Rollback();
                Console.WriteLine("Purchase failed. Transaction rolled back.");
                Console.WriteLine("Error: " + ex.Message);
            }
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>beginners</category>
      <category>database</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>TIL: Adapter Design Pattern</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Thu, 02 Oct 2025 13:48:24 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-adapter-design-pattern-45h7</link>
      <guid>https://dev.to/vishnukn01/til-adapter-design-pattern-45h7</guid>
      <description>&lt;p&gt;Sometimes there are two parts of your code that you want to work together, but they cannot because they are incompatible. This is where the Adapter Design Pattern comes in handy.&lt;/p&gt;

&lt;p&gt;Imagine a large car manufacturing factory with multiple departments. The engineering department and the testing departments need to co-ordinate and work together, but that is not happening. The engineering team's output does not match what the testing department expects, on many levels. For example, the engineering department designs parts using imperial measurements (inches, pounds) while the testing departments expects metric measurements (centimeters, kilograms). Like this, there are many aspects which are leading to incompatibility and not understanding each other's language and expectations. To solve this, the factory introduces a small Adapter department whose whole job is to receive parts or data from Engineering, convert the measurements (e.g., inches to centimeters), and hand them off to Testing in the format it expects.&lt;/p&gt;

&lt;p&gt;Code example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Engineering Department (old interface)
class EngineeringDepartment {
  provideMeasurements() {
    return { length: 20, unit: "inches" };
  }
}

// Testing Department (expects metric)
class TestingDepartment {
  testPart(part) {
    console.log(`Testing part of length ${part.length} ${part.unit}`);
  }
}

// Adapter Department
class EngineeringToTestingAdapter {
  constructor(engineeringDept) {
    this.engineeringDept = engineeringDept;
  }

  getMetricMeasurements() {
    const imperial = this.engineeringDept.provideMeasurements();
    return {
      length: imperial.length * 2.54, // inches to cm
      unit: "cm"
    };
  }
}

// Usage
const engineering = new EngineeringDepartment();
const adapter = new EngineeringToTestingAdapter(engineering);
const testing = new TestingDepartment();

const partForTesting = adapter.getMetricMeasurements();
testing.testPart(partForTesting);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>learning</category>
    </item>
    <item>
      <title>TIL: Facade Design Pattern</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Thu, 02 Oct 2025 09:54:59 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-facade-design-pattern-51do</link>
      <guid>https://dev.to/vishnukn01/til-facade-design-pattern-51do</guid>
      <description>&lt;p&gt;The Facade design pattern comes in handy when your code is complex and you are dealing with a lot of sub-systems and "wheels within wheels" in your code. It provides a way of navigating all this by creating an interface which takes in the request and behind the scenes, sets the relevant wheels in motion, talks to the relevant sub-systems and delivers the request.&lt;/p&gt;

&lt;p&gt;Imagine a large car manufacturing factory. Inside the factory, there are specialized departments which work on specialized aspects of building a car. There might be a chassis department, engine department, paint shop, interior department, quality control department etc. If, as a customer, you tried to co-ordinate with each of these departments to get the car built, it would be a nightmare. To prevent this problem, the factory has a manager or a front-office. All that the customer has to do is to walk in and state his requirement "I want a red sedan with leather seats." and the manager/front-office sets the relevant departments in motion at the right times and delivers on the request.&lt;/p&gt;

&lt;p&gt;Code example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Subsystems (Departments inside the factory)

class ChassisDepartment {
  buildChassis(type) {
    console.log(`🔩 Building a ${type} chassis...`);
  }
}

class EngineDepartment {
  installEngine(engineType) {
    console.log(`⚙️ Installing a ${engineType} engine...`);
  }
}

class PaintDepartment {
  paint(color) {
    console.log(`🎨 Painting the car ${color}...`);
  }
}

class InteriorDepartment {
  installInterior(interiorType) {
    console.log(`🪑 Installing ${interiorType} interior...`);
  }
}

class QualityControlDepartment {
  inspect() {
    console.log(`🧪 Performing final inspection...`);
  }
}

// 🧑‍💼 Facade (Front Office)/Manager
class CarFactoryFacade {
  constructor() {
    this.chassis = new ChassisDepartment();
    this.engine = new EngineDepartment();
    this.paint = new PaintDepartment();
    this.interior = new InteriorDepartment();
    this.qc = new QualityControlDepartment();
  }

  // High-level method that hides the complexity
  orderCar({ type, engine, color, interior }) {
    console.log("📋 Order received at Front Office. Processing...\n");

    this.chassis.buildChassis(type);
    this.engine.installEngine(engine);
    this.paint.paint(color);
    this.interior.installInterior(interior);
    this.qc.inspect();

    console.log(`\n🚗 Your ${color} ${type} with a ${engine} engine and ${interior} interior is ready!`);
  }
}

// 👨‍💻 Client code
const frontOffice = new CarFactoryFacade();

// The client just places an order — doesn't deal with each department individually
frontOffice.orderCar({
  type: "Sedan",
  engine: "V8",
  color: "Red",
  interior: "leather"
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>learning</category>
    </item>
    <item>
      <title>TIL: Singleton Design Pattern</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Thu, 02 Oct 2025 09:21:54 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-singleton-design-pattern-l1d</link>
      <guid>https://dev.to/vishnukn01/til-singleton-design-pattern-l1d</guid>
      <description>&lt;p&gt;Sometimes, having multiple instances of a class makes things confusing, wasteful or logically wrong. In such instances, the factory design pattern comes handy.&lt;/p&gt;

&lt;p&gt;In the construction of a car, each car has only one chassis. One set of workers may request access to the chassis to add wheels, the other set might want the chassis to work on gears and an other set of workers might want to work on the windshield. But they all get the same chassis. When it is first requested, the chassis is created. For all subsequent requests, the same chassis is returned.&lt;/p&gt;

&lt;p&gt;Here is how it look like in code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Chassis {
  constructor() {
    if (Chassis.instance) {
      return Chassis.instance;
    }
    console.log("🚗 New chassis created");
    Chassis.instance = this;
  }
}

const teamA = new Chassis(); // 🚗 New chassis created
const teamB = new Chassis(); // returns existing chassis
const teamC = new Chassis(); // same instance

console.log(teamA === teamB &amp;amp;&amp;amp; teamB === teamC); // true

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>javascript</category>
      <category>learning</category>
    </item>
    <item>
      <title>TIL: Builder Design Pattern</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Thu, 02 Oct 2025 05:53:08 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-builder-design-pattern-272c</link>
      <guid>https://dev.to/vishnukn01/til-builder-design-pattern-272c</guid>
      <description>&lt;p&gt;In scenarios where the object creation logic is complex AND you need need fine-grained control over HOW the object is assembled, the builder pattern comes in handy.&lt;/p&gt;

&lt;p&gt;Imagine someone walking up to, say, a car manufacturing factory, with a highly specific request for a car of a certain type (red color, sedan, 818 total horsepower etc) and the factory appoints a builder who in-turn builds the car, accepting inputs at every step of the process and building it accordingly. That is the builder pattern in a nutshell.&lt;/p&gt;

&lt;p&gt;With the builder pattern, the end goal is to have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const myObject = new ObjectBuilder() 
  .setFeature1("feature1") 
  .setFeature2("feature2") 
  .setFeature3("feature3") 
  .build();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a full example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Product class
class Car {
  constructor(brand, color, engine, sunroof, wheels) {
    this.brand = brand;
    this.color = color;
    this.engine = engine;
    this.sunroof = sunroof;
    this.wheels = wheels;
  }

  describe() {
    console.log(
      `${this.color} ${this.brand} with a ${this.engine} engine, ` +
      `${this.sunroof ? "with sunroof" : "no sunroof"}, ` +
      `${this.wheels} wheels.`
    );
  }
}

// Builder class
class CarBuilder {
  constructor() {
    // default values
    this.brand = "Generic";
    this.color = "white";
    this.engine = "standard";
    this.sunroof = false;
    this.wheels = 4;
  }

  setBrand(brand) {
    this.brand = brand;
    return this;
  }

  setColor(color) {
    this.color = color;
    return this;
  }

  setEngine(engine) {
    this.engine = engine;
    return this;
  }

  addSunroof() {
    this.sunroof = true;
    return this;
  }

  setWheels(number) {
    this.wheels = number;
    return this;
  }

  build() {
    return new Car(this.brand, this.color, this.engine, this.sunroof, this.wheels);
  }
}

// Usage
const myCar = new CarBuilder()
  .setBrand("Ferrari")
  .setColor("Red")
  .setEngine("V8")
  .addSunroof()
  .setWheels(4)
  .build();

myCar.describe();
// 👉 Output: Red Ferrari with a V8 engine, with sunroof, 4 wheels.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So to sum up, builder pattern is like requesting a builder, since you have a very specific and complex request and you want fine-grained control over &lt;em&gt;how&lt;/em&gt; the car is built. The builder builds the car step by step, taking your inputs at every stage.&lt;/p&gt;

&lt;p&gt;The builder class is the builder and the methods defined within builder represent the things the builder is capable of doing, his skillset, so to speak. The instantiation of the builder class and calling specific set methods is like talking to the builder and giving step by step instructions. The final build() call is like telling the builder "I am satisfied with the build. Please hand me the car".&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>javascript</category>
    </item>
    <item>
      <title>TIL: Factory Design Pattern</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Tue, 30 Sep 2025 18:53:47 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-factory-design-pattern-1lab</link>
      <guid>https://dev.to/vishnukn01/til-factory-design-pattern-1lab</guid>
      <description>&lt;p&gt;In scenarios where the object creation logic is complex or dynamic, the factory design pattern comes in handy.&lt;/p&gt;

&lt;p&gt;Imagine someone walking up to, say, a car manufacturing factory, with a request for a car of a certain type (red color, sedan, 818 total horsepower etc) and the factory accepts the request, figures out how to makes it and delivers a concrete product back to the user.&lt;/p&gt;

&lt;p&gt;That is the whole idea behind the factory pattern.&lt;/p&gt;

&lt;p&gt;So basically, with the factory design pattern, the end result that we want as developers is a way to create objects using a factory class and an abstract instruction like:&lt;/p&gt;

&lt;p&gt;objectFactory.createObject(objectType);&lt;/p&gt;

&lt;p&gt;So, in order to do something like this, objectFactory should, of necessity, have a static method of the same name.&lt;/p&gt;

&lt;p&gt;The reason why it should be static is that we do not want the factory to create a sub-factory and then create the object requested because that would be inefficient &lt;/p&gt;

&lt;p&gt;The static method should be very flexible, in the sense that it can take the parameter passed into it and return a concrete instance of an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ObjectFactory {
  static createObject(type) {
    switch (type) {
      case "car":
        return new Car();
      case "bike":
        return new Bike();
      default:
        throw new Error("Invalid object type");
    }
  }
}

class Car {
  drive() {
    console.log("Driving a car");
  }
}

class Bike {
  ride() {
    console.log("Riding a bike");
  }
}

// Usage
const myCar = ObjectFactory.createObject("car");
myCar.drive(); // Output: Driving a car

const myBike = ObjectFactory.createObject("bike");
myBike.ride(); // Output: Riding a bike

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The factory pattern is like submitting a token at a glass covered token which is then accepted by a faceless hand which then picks the right model/variant based on the request, quickly builds/assembles the car and hands it back to the requester.&lt;/p&gt;

&lt;p&gt;The factory is the factory class. The faceless hand is the static method and the right model/variant that it picks represent the classes it uses to create the object.&lt;/p&gt;

&lt;p&gt;You are just saying to the factory - "Here is my request - hand me the appropriate car" and the factory figures out the how and does just that.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>learning</category>
    </item>
    <item>
      <title>TIL: Optimistic concurrency</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Sat, 27 Sep 2025 07:12:12 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-optimistic-concurrency-5h8m</link>
      <guid>https://dev.to/vishnukn01/til-optimistic-concurrency-5h8m</guid>
      <description>&lt;p&gt;Concurrency, in DB management, is a situation where a row or a piece of data living in a database, is being accessed by multiple users at the same time with the purpose of reading/updating/deleting it.&lt;/p&gt;

&lt;p&gt;This obviously can lead to conflicts and inconsistencies.&lt;/p&gt;

&lt;p&gt;There are 2 broad ways of dealing with such conflicts: Optimistic concurrency and Pessimistic concurrency.&lt;/p&gt;

&lt;p&gt;Simply put, Optimistic concurrency means allowing concurrent edits/updates without blocking it just because some else is working on it, with the &lt;em&gt;optimism&lt;/em&gt; that it will all work out in the end with proper conflict handling.&lt;/p&gt;

&lt;p&gt;Pessimistic concurrency means NOT allowing concurrent edits/updates by blocking it because some else is working on it, with the &lt;em&gt;pessimism&lt;/em&gt; that it will all NOT work out in the end.&lt;/p&gt;

&lt;p&gt;AI generated analogy:&lt;/p&gt;




&lt;h2&gt;
  
  
  📚 &lt;strong&gt;The Setting&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Lila and Mohan are librarians working in the same library.&lt;br&gt;
They both need to &lt;strong&gt;update the same library book card&lt;/strong&gt; — the card for &lt;em&gt;“The Hobbit”&lt;/em&gt;.&lt;br&gt;
The library allows two different ways of handling such situations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pessimistic concurrency&lt;/strong&gt; 🔒&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimistic concurrency&lt;/strong&gt; 🌿&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔒 &lt;strong&gt;1. Pessimistic Concurrency — Lock First, Work Alone&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Lila goes to update the card for &lt;em&gt;“The Hobbit.”&lt;/em&gt;&lt;br&gt;
She &lt;strong&gt;takes the original card&lt;/strong&gt; from the filing cabinet, puts it on her desk, and &lt;strong&gt;locks it in her drawer&lt;/strong&gt; while she works.&lt;/p&gt;

&lt;p&gt;Mohan comes by a few minutes later. He also wants to make a change to &lt;em&gt;“The Hobbit.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The librarian says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“❌ Sorry, Lila is working on that card. You’ll have to wait until she’s done.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So Mohan just stands by until Lila finishes.&lt;br&gt;
When she’s done, she puts the card back, unlocks it, and now Mohan can take it and make his edits.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Key idea:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Only one person can work on the card at a time.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Conflicts are &lt;strong&gt;prevented upfront&lt;/strong&gt; because nobody else is allowed to touch the card while it’s “checked out.”&lt;/li&gt;
&lt;li&gt;But it means others (like Mohan) might have to &lt;strong&gt;wait&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧠 &lt;strong&gt;This is pessimistic concurrency&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Let’s &lt;strong&gt;lock the data&lt;/strong&gt; immediately so no one else can mess with it while I’m working.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🌿 &lt;strong&gt;2. Optimistic Concurrency — Work Freely, Check Later&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now imagine a different approach.&lt;/p&gt;

&lt;p&gt;Lila goes to update the same card. Instead of taking the original, she &lt;strong&gt;photocopies&lt;/strong&gt; it. She works on the copy at her desk.&lt;/p&gt;

&lt;p&gt;At the same time, Mohan also goes to update the same card. He too takes &lt;strong&gt;his own photocopy&lt;/strong&gt; and works on it independently.&lt;/p&gt;

&lt;p&gt;Neither of them blocks the other. They both happily make their edits at the same time.&lt;/p&gt;

&lt;p&gt;Later, both return to the librarian to apply their changes to the &lt;strong&gt;original card&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mohan returns first and updates the original card. The librarian &lt;strong&gt;stamps the card “Version #6.”&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Lila comes a bit later with her changes based on the &lt;strong&gt;older Version #5&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The librarian checks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Hmm, this card is already at Version #6.&lt;br&gt;
Lila, you’re trying to apply edits to Version #5. Someone else has changed this in the meantime.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, there are three possible ways the librarian handles this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;🚫 &lt;strong&gt;Reject Lila’s update&lt;/strong&gt; — “Please take the latest card and reapply your changes.”&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Ask Lila to manually merge&lt;/strong&gt; her edits with the new Version #6.&lt;/li&gt;
&lt;li&gt;🤖 &lt;strong&gt;Automatically merge&lt;/strong&gt; the changes if they don’t conflict (e.g., Lila changed the title, Mohan changed the author).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;👉 &lt;strong&gt;Key idea:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multiple people can work simultaneously.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Conflicts are &lt;strong&gt;detected later&lt;/strong&gt; when they try to save.&lt;/li&gt;
&lt;li&gt;Nobody is blocked while editing, but the system must &lt;strong&gt;check versions&lt;/strong&gt; to catch conflicts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧠 &lt;strong&gt;This is optimistic concurrency&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Let’s &lt;strong&gt;trust&lt;/strong&gt; that things will work out, let everyone work in parallel, and handle any conflicts &lt;em&gt;after&lt;/em&gt; they happen.”&lt;/p&gt;
&lt;/blockquote&gt;




</description>
    </item>
    <item>
      <title>TIL: Clustered and Non-clustered indices in SQL</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Thu, 25 Sep 2025 08:33:38 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-clustered-and-non-clustered-indices-in-sql-4ndh</link>
      <guid>https://dev.to/vishnukn01/til-clustered-and-non-clustered-indices-in-sql-4ndh</guid>
      <description>&lt;p&gt;The tables that we see in SQL server are not the stored data but the "presentation" of it. When a table is created and rows are inserted, behind the scenes, SQL stores the actual data relating to that table on what is known as data pages.  This behind the scenes stuff is called SQL internals. And the way it is stored may be "clustered" or "non-clustered" (based on what is specified) or "heap" (if nothing is specified)&lt;/p&gt;

&lt;p&gt;Heap is like haphazardly dumping the data wherever space is available, like an unorganized phone book. In SQL server, if no index is defined, heap is the default approach.&lt;/p&gt;

&lt;p&gt;Clustered index is when you organize that phone book according to some parameter (like first name, etc). That means, when clustered index is defined, the heap is organized as per the parameter defined in the clustered index (and thus it is no longer a heap, it is eliminated).&lt;/p&gt;

&lt;p&gt;Heap and clustered index are thus opposites of each other.&lt;/p&gt;

&lt;p&gt;And non clustered index is like a yellow pages book which references the phone book (organized or un-organized).&lt;/p&gt;




&lt;p&gt;In SQL server, IF primary key is defined, it automatically becomes the clustered index key. If not defined, there will be no clustered index key. And any column can be defined as the clustered index key or as the non clustered index key.&lt;/p&gt;




&lt;p&gt;AI Visulaization:&lt;/p&gt;

&lt;h2&gt;
  
  
  1️⃣ Heap (no clustered index)
&lt;/h2&gt;

&lt;p&gt;Rows are just placed wherever there’s space. No particular order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Data Pages
+-------------------+   +-------------------+
| StudentID=3,Ravi  |   | StudentID=2,Meera |
| StudentID=1,Anil  |   |                   |
+-------------------+   +-------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 To find &lt;code&gt;Name='Meera'&lt;/code&gt;, SQL has to &lt;strong&gt;scan everything&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Clustered Index on &lt;code&gt;StudentID&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Rows are physically &lt;strong&gt;sorted by StudentID&lt;/strong&gt; across data pages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Data Pages (clustered on StudentID)
+-------------------+   +-------------------+
| StudentID=1,Anil  |   | StudentID=3,Ravi  |
| StudentID=2,Meera |   |                   |
+-------------------+   +-------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 To find &lt;code&gt;StudentID=2&lt;/code&gt;, SQL can go straight to it (fast).&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ Non-Clustered Index on &lt;code&gt;Name&lt;/code&gt; (table has clustered index on StudentID)
&lt;/h2&gt;

&lt;p&gt;Separate structure, sorted by &lt;code&gt;Name&lt;/code&gt;, pointing back to rows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Non-Clustered Index (sorted by Name)
+--------------------+
| Anil   → StudentID=1
| Meera  → StudentID=2
| Ravi   → StudentID=3
+--------------------+

Clustered Data Pages (sorted by StudentID)
+-------------------+   +-------------------+
| 1,Anil,22         |   | 3,Ravi,20         |
| 2,Meera,21        |   |                   |
+-------------------+   +-------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Steps when you query &lt;code&gt;WHERE Name='Meera'&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SQL looks in the &lt;strong&gt;non-clustered index&lt;/strong&gt; → finds &lt;code&gt;Meera → StudentID=2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Uses the &lt;strong&gt;clustered index on StudentID&lt;/strong&gt; → fetches row &lt;code&gt;2,Meera,21&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  4️⃣ Non-Clustered Index on &lt;code&gt;Name&lt;/code&gt; (table is a heap)
&lt;/h2&gt;

&lt;p&gt;If there’s &lt;strong&gt;no clustered index&lt;/strong&gt;, the non-clustered index points to the physical address (RID):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Non-Clustered Index (sorted by Name)
+--------------------+
| Anil   → Page1,Slot2
| Meera  → Page2,Slot1
| Ravi   → Page1,Slot1
+--------------------+

Heap Data Pages (unordered)
+-------------------+   +-------------------+
| Page1: Ravi(3)    |   | Page2: Meera(2)   |
| Page1: Anil(1)    |   |                   |
+-------------------+   +-------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Here, SQL jumps directly to the physical location.&lt;/p&gt;




&lt;p&gt;✅ Summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Heap&lt;/strong&gt; = unordered, non-clustered indexes point to physical row location.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clustered&lt;/strong&gt; = ordered by clustered key, non-clustered indexes point to clustered key.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Optimizing how SQL stores data behind the scenes (internals) can make a huge difference in performance and scalability.&lt;/p&gt;

&lt;p&gt;Non clustered indexes come in useful in scenarios where a column which is not a clustered index is frequently being queried.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Example
&lt;/h3&gt;

&lt;p&gt;Suppose you have a table clustered on &lt;code&gt;EmployeeID&lt;/code&gt; (so rows are stored ordered by ID):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;EmployeeID&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Department&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Anil&lt;/td&gt;
&lt;td&gt;IT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Meera&lt;/td&gt;
&lt;td&gt;Finance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Ravi&lt;/td&gt;
&lt;td&gt;HR&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Query 1:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Employees&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;EmployeeID&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Fast because clustered index is on &lt;code&gt;EmployeeID&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Query 2:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Employees&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Meera'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Without non-clustered index, SQL must scan every row (slow).&lt;br&gt;
  👉 With a non-clustered index on &lt;code&gt;Name&lt;/code&gt;, SQL can directly use the sorted &lt;code&gt;Name&lt;/code&gt; list and jump to the right row.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ Analogy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clustered index&lt;/strong&gt; = phone book sorted by last name (only one order possible).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-clustered index&lt;/strong&gt; = an extra list, say sorted by phone number or by city, pointing back to the entries in the main book.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, a non-clustered index is useful when you want &lt;strong&gt;fast lookups or sorts based on a column other than the clustered key&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;In the above example, SQL can directly jump to the M's and that reduces the volume of scanning that needs to be done.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>TIL: Temporary tables and CTE's in SQL</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Wed, 24 Sep 2025 19:04:09 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-temporary-tables-in-sql-1ooh</link>
      <guid>https://dev.to/vishnukn01/til-temporary-tables-in-sql-1ooh</guid>
      <description>&lt;p&gt;Temporary tables are makeshift tables that you can create and store data in for temporary reference. One you are done with querying and you close your ssms, the temp table gets deleted.&lt;/p&gt;

&lt;p&gt;You use the # symbol as a prefix to create one.&lt;/p&gt;

&lt;p&gt;There are 2 types: local and global. If you create a local one, it is accessible only to you and if you create a global one, it is accessible to all active sessions on ssms.&lt;/p&gt;

&lt;p&gt;AI generated analogy:&lt;/p&gt;

&lt;p&gt;For local temporary tables (#table_name)&lt;br&gt;
A personal scratchpad: Think of a local temp table as a private notepad you create for yourself to use during a single work session.&lt;br&gt;
The session is the key: The "session" starts when you connect to the database and ends when you disconnect or close the query window.&lt;br&gt;
It vanishes with the session: When you close the SSMS window, your connection to the database ends, and SQL Server automatically erases your temporary table. &lt;/p&gt;

&lt;p&gt;For global temporary tables (##table_name)&lt;br&gt;
A shared whiteboard: A global temp table is a bit different. It's like a whiteboard that everyone in the office can see and write on.&lt;br&gt;
It outlives your session (sometimes): The global temp table stays around as long as at least one person is still using it. If you close your SSMS window but someone else is still running a query against that same table, it will not be deleted.&lt;br&gt;
The last person to leave turns out the light: It is only automatically deleted once the very last connection that has been referencing that table closes. &lt;/p&gt;

&lt;p&gt;CTE's, (Common Table Expressions) on the other hand, only holds that data with a nickname in the SQL internals/data pages (the behind the scenes storage of SQL) for the duration of the query and then deletes it.&lt;/p&gt;




&lt;p&gt;Table variables are the middle ground between temp tables and CTEs. In temp tables, once you create the table and run your SQL code, SQL server destroys the table after your session ends whereas in case of table variables, SQL server destroys the table after the chunk of SQL code referencing the table variable is done executing.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>TIL: Angular OnPush</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Tue, 23 Sep 2025 13:34:03 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-angular-onpush-2ni0</link>
      <guid>https://dev.to/vishnukn01/til-angular-onpush-2ni0</guid>
      <description>&lt;p&gt;The OnPush change detections strategy triggers change detection only&lt;br&gt;
1) when @Input data is updated and that too, with conditions&lt;br&gt;
  a) If The update is a reference type and not a mutation (pushed in and not slipped in)&lt;br&gt;
  b) in case of observables as @Input() data, if it uses async pipe&lt;br&gt;
2) User interactions/events are set in motion&lt;br&gt;
3) when it is manually triggered&lt;/p&gt;

&lt;p&gt;I can use OnPush when my component's data is mostly coming in from the outside and I am not changing the data via mutation (ie., I am only using immutable patterns to make changes). It is also an excellent choice when I am using async pipe in my component and all its data comes from observables&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>angular</category>
      <category>frontend</category>
      <category>performance</category>
    </item>
    <item>
      <title>TIL: Repository pattern</title>
      <dc:creator>Vishnu KN</dc:creator>
      <pubDate>Tue, 23 Sep 2025 13:32:26 +0000</pubDate>
      <link>https://dev.to/vishnukn01/til-repository-pattern-2k1n</link>
      <guid>https://dev.to/vishnukn01/til-repository-pattern-2k1n</guid>
      <description>&lt;p&gt;Repository pattern: A  domain specific storage of database manipulation methods containing method names that are in the language of the business rather than in the language of SQL.&lt;/p&gt;

&lt;p&gt;The whole point of the repository pattern is to have a place where the database logic defined in the language of the business, rather than the technical language.&lt;/p&gt;

&lt;p&gt;The repository pattern cannot work by itself. It needs to communicate with an ORM like EF core or Dapper to work.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
