<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Ashutosh Writes]]></title><description><![CDATA[Ashutosh Writes is a tech-focused blog where practical learning connects with real-world development. It features clear, engaging articles on web development, Python, Java, artificial intelligence, and modern software engineering. From hands-on project tutorials and coding guides to AI concepts and development insights, the blog is designed to simplify complex topics and help developers learn, build, and grow at every stage of their journey.]]></description><link>https://blog.ashutoshkrris.in</link><image><url>https://cdn.hashnode.com/uploads/logos/61c1acb4a90dea775da8262b/e011bc46-99ec-4290-a669-b54baa250960.png</url><title>Ashutosh Writes</title><link>https://blog.ashutoshkrris.in</link></image><generator>RSS for Node</generator><lastBuildDate>Sun, 06 Sep 2026 21:28:24 GMT</lastBuildDate><atom:link href="https://blog.ashutoshkrris.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Rethinking Expense Validation: From Hardcoded If Statements to Pluggable Engines in Java]]></title><description><![CDATA[You are sitting in a system design interview, or worse, staring at a pull request where a junior engineer has just added their fourteenth nested conditional statement to a reimbursement service. Softw]]></description><link>https://blog.ashutoshkrris.in/designing-extensible-expense-validation-platform-java</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/designing-extensible-expense-validation-platform-java</guid><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Java]]></category><category><![CDATA[software development]]></category><category><![CDATA[System Design]]></category><category><![CDATA[interview]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sat, 05 Sep 2026 04:30:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/564b2353-3bba-47b5-990a-a3e1057a408d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You are sitting in a system design interview, or worse, staring at a pull request where a junior engineer has just added their fourteenth nested conditional statement to a reimbursement service. Software architecture rarely fails because of a single catastrophic decision. It rots slowly through the accumulation of small, expedient shortcuts taken under deadline pressure.</p>
<p>Modern enterprise backend development often forces us to build systems that must adapt to rules we cannot predict in advance. When an application starts out, requirements feel bounded. You write a few clean methods, deploy your service, and move on to the next ticket. Within a year, the business grows, new regional offices open, compliance regulations shift, and the simple validation logic you wrote on day one becomes a monolithic bottleneck.</p>
<p>Reimbursement platforms are a classic battleground for this architectural decay. Employees submit expenses for hotel stays, client dinners, equipment purchases, and travel. The validation engine needs to evaluate these requests against a constantly expanding matrix of corporate policies.</p>
<h2>The Problem Statement</h2>
<p>The core engineering challenge in designing an expense validation platform revolves around policy volatility and tenant scale. An organization needs the ability to define and enforce diverse validation rules without constantly modifying the core source code.</p>
<p>Consider the typical policy constraints demanded by finance departments:</p>
<ul>
<li><p>No single expense can exceed fifty thousand rupees.</p>
</li>
<li><p>Travel expenses require prior manager approval.</p>
</li>
<li><p>Certain vendors are completely blacklisted.</p>
</li>
<li><p>Different departments have distinct spending limits for meals.</p>
</li>
<li><p>Regional offices have unique currency restrictions and tax validation rules.</p>
</li>
<li><p>Employee seniority alters approval thresholds and override privileges.</p>
</li>
</ul>
<p>The central design question is straightforward. How do we allow organizations to introduce new expense rules without constantly modifying the core validation code and triggering a full redeployment every time a policy tweak occurs?</p>
<h2>The Naive Approach</h2>
<p>Most engineering teams start with the most obvious approach. You write a service class, inject a repository, and write a series of conditional statements over the incoming request object. It works on day one. It is easy to debug, and you can write unit tests in your sleep.</p>
<pre><code class="language-java">public class ExpenseValidator {

    public ValidationResult validate(Expense expense, List&lt;String&gt; restrictedVendors) {
        // Hardcoded limit check for amount
        if (expense.getAmount().compareTo(new BigDecimal("50000")) &gt; 0) {
            return ValidationResult.fail("Amount exceeds the allowed limit of 50000");
        }

        // Hardcoded category-specific rule for travel
        if (expense.getCategory() == Category.TRAVEL &amp;&amp; !expense.isManagerApproved()) {
            return ValidationResult.fail("Travel expenses require manager approval");
        }

        // Hardcoded check against a list of blacklisted vendors
        if (restrictedVendors.contains(expense.getVendor())) {
            return ValidationResult.fail("Vendor is restricted");
        }

        // Hardcoded limit check for meals
        if (expense.getCategory() == Category.MEAL &amp;&amp; expense.getAmount().compareTo(new BigDecimal("2000")) &gt; 0) {
            return ValidationResult.fail("Meal expenses cannot exceed 2000");
        }

        return ValidationResult.success();
    }
}
</code></pre>
<p>This code directly evaluates incoming expense parameters using raw conditional blocks inside a single method. While straightforward initially, it mixes orchestration logic with direct policy enforcement, setting the stage for tight coupling.</p>
<h3>Problems with the Naive Approach</h3>
<p>This code looks clean enough when you only have four rules. Give it six months. Now the finance department wants to restrict software purchases to approved vendors only. The human resources team wants different rules for interns versus full-time employees. The regional office in Mumbai has a different currency limit than the office in London. Department heads want custom approval workflows based on project codes.</p>
<p>Your conditional block swells to two hundred lines. Every new business policy requires modifying the core validation class. Every modification risks breaking existing rules that were written by someone who left the company nine months ago. Cyclomatic complexity climbs into the stratosphere. Testing every permutation becomes a combinatorial nightmare where changing one line of code breaks tests in an entirely unrelated module.</p>
<p>The problem is not that if statements are inherently evil. The real issue is that business policy has become tightly coupled to the core execution engine. Whenever business rules change, code has to change. That is a structural bottleneck.</p>
<h2>Approach 1: Rules as Java Implementations</h2>
<p>To decouple policy from execution, we need to encapsulate individual rules into discrete units. Instead of one giant method knowing about every business nuance, we define a common contract for a rule.</p>
<pre><code class="language-java">public interface ExpenseRule {
    ValidationResult validate(Expense expense);
}
</code></pre>
<p>This interface establishes a <em>single contract</em> for all rules. Any policy implementation must accept an expense and return a validation result, hiding its internal validation logic behind this common method.</p>
<p>Now, every business policy becomes its own class implementing this interface. Let us look at a few concrete examples written in modern Java.</p>
<pre><code class="language-java">public class MaxAmountRule implements ExpenseRule {
    private final BigDecimal maxAmount;

    public MaxAmountRule(BigDecimal maxAmount) {
        this.maxAmount = maxAmount;
    }

    @Override
    public ValidationResult validate(Expense expense) {
        if (expense.getAmount().compareTo(maxAmount) &gt; 0) {
            return ValidationResult.fail("Amount exceeds the allowed limit");
        }
        return ValidationResult.success();
    }
}
</code></pre>
<p>This class encapsulates a single responsibility: checking whether an expense amount exceeds a configured threshold, keeping the numeric limit safely encapsulated as an immutable field.</p>
<pre><code class="language-java">public class ManagerApprovalRule implements ExpenseRule {
    @Override
    public ValidationResult validate(Expense expense) {
        if (expense.getCategory() == Category.TRAVEL &amp;&amp; !expense.isManagerApproved()) {
            return ValidationResult.fail("Travel expenses require manager approval");
        }
        return ValidationResult.success();
    }
}
</code></pre>
<p>Here, the rule isolates travel-specific validation logic, checking workflow approval flags only when the expense category matches travel.</p>
<pre><code class="language-java">public class RestrictedVendorRule implements ExpenseRule {
    private final Set&lt;String&gt; restrictedVendors;

    public RestrictedVendorRule(Set&lt;String&gt; restrictedVendors) {
        this.restrictedVendors = restrictedVendors;
    }

    @Override
    public ValidationResult validate(Expense expense) {
        if (restrictedVendors.contains(expense.getVendor())) {
            return ValidationResult.fail("Vendor is restricted: " + expense.getVendor());
        }
        return ValidationResult.success();
    }
}
</code></pre>
<p>This rule manages blacklisted vendors by performing an efficient set lookup against the expense vendor attribute.</p>
<p>The orchestrator, our <code>ExpenseValidator</code>, no longer knows anything about meals, travel, or vendor blacklists. It simply accepts a collection of rules and executes them sequentially.</p>
<pre><code class="language-java">public class ExpenseValidator {
    private final List&lt;ExpenseRule&gt; rules;

    public ExpenseValidator(List&lt;ExpenseRule&gt; rules) {
        this.rules = rules;
    }

    public ValidationResult validate(Expense expense) {
        for (ExpenseRule rule : rules) {
            ValidationResult result = rule.validate(expense);
            if (!result.isValid()) {
                return result;
            }
        }
        return ValidationResult.success();
    }
}
</code></pre>
<p>The orchestrator operates entirely against the abstract <code>ExpenseRule</code> interface, meaning it can iterate over an injected collection of rules without knowing their concrete types or business implementations.</p>
<p>This design gives us code-level extensibility. If we need to introduce a <code>MealApprovalRule</code>, we write a new class implementing <code>ExpenseRule</code>. We do not touch <code>ExpenseValidator</code>. We are adhering to the Open/Closed Principle without needing to recite software design textbooks.</p>
<h2>Can We Further Improve This?</h2>
<p>This object-oriented abstraction feels satisfying, but it exposes a glaring limitation once you build software for actual enterprises.</p>
<p>What does "adding a new rule" mean in production?</p>
<p>To a developer, it means writing a class, writing unit tests, opening a pull request, waiting for code review, merging, and deploying a new version of the artifact to production.</p>
<p>To a finance administrator, that definition is absurd. When the CFO decides on a Tuesday morning that the hotel limit needs to increase from fifty thousand rupees to seventy-five thousand rupees, they expect to click a button in an admin portal and see the change take effect immediately. They do not want to wait for a sprint deployment cycle, a staging verification, or a zero-downtime rolling update managed by the infrastructure team.</p>
<p>This distinction separates a basic CRUD application from a true enterprise policy platform. If business users need to create or modify policies without a code deployment, Java classes compiled into a JAR file will not cut it. We need configuration-driven rules.</p>
<h2>Approach 2: Configuration-Driven Rules</h2>
<p>To let administrators manage policies dynamically, rule definitions must live outside the codebase, typically in a relational database or a distributed configuration store.</p>
<p>Consider a database table designed to hold rule definitions:</p>
<pre><code class="language-sql">CREATE TABLE expense_rules (
    id VARCHAR(64) PRIMARY KEY,
    organization_id VARCHAR(64) NOT NULL,
    expense_category VARCHAR(32) NOT NULL,
    rule_type VARCHAR(64) NOT NULL,
    configuration JSON NOT NULL,
    priority INT NOT NULL,
    enabled BOOLEAN NOT NULL
);
</code></pre>
<p>This relational schema stores rule metadata and flexible JSON configuration payloads per tenant organization, allowing dynamic policy updates at runtime.</p>
<p>In this table, individual rows represent active policies for specific tenants.</p>
<table>
<thead>
<tr>
<th>organization_id</th>
<th>expense_category</th>
<th>rule_type</th>
<th>configuration</th>
<th>priority</th>
<th>enabled</th>
</tr>
</thead>
<tbody><tr>
<td>ORG_123</td>
<td>ALL</td>
<td>MAX_AMOUNT</td>
<td>{"limit": 50000}</td>
<td>10</td>
<td>true</td>
</tr>
<tr>
<td>ORG_123</td>
<td>TRAVEL</td>
<td>MANAGER_APPROVAL</td>
<td>{"required": true}</td>
<td>20</td>
<td>true</td>
</tr>
<tr>
<td>ORG_123</td>
<td>MEAL</td>
<td>MAX_AMOUNT</td>
<td>{"limit": 2000}</td>
<td>10</td>
<td>true</td>
</tr>
<tr>
<td>ORG_123</td>
<td>ALL</td>
<td>RESTRICTED_VENDOR</td>
<td>{"vendors": ["ABC"]}</td>
<td>30</td>
<td>true</td>
</tr>
</tbody></table>
<p>Now, changing a hotel or meal limit is simply an update statement or an API call that modifies the JSON payload in the database. No code deployment required.</p>
<p>To execute these database-backed rules, we invert our architecture. Instead of hardcoded rule classes containing both logic and configuration, we separate the evaluation logic from the rule metadata using a generic evaluator interface.</p>
<pre><code class="language-java">public interface RuleEvaluator {
    ValidationResult evaluate(Expense expense, Rule ruleRecord);
}
</code></pre>
<p>This generic evaluator interface decouples the execution algorithm from the database record, accepting both the incoming expense and the raw rule configuration.</p>
<p>We implement specific evaluators that know how to parse the JSON configuration for a given rule type.</p>
<pre><code class="language-java">public class MaxAmountEvaluator implements RuleEvaluator {
    @Override
    public ValidationResult evaluate(Expense expense, Rule rule) {
        BigDecimal limit = new BigDecimal(rule.getConfiguration().get("limit").asText());
        if (expense.getAmount().compareTo(limit) &gt; 0) {
            return ValidationResult.fail("Amount exceeds configured limit of " + limit);
        }
        return ValidationResult.success();
    }
}
</code></pre>
<p>This evaluator parses the database JSON payload dynamically to extract the specific threshold limit set by the administrator for that tenant.</p>
<p>A registry or factory pattern maps a string or enum representation of the rule type to its corresponding evaluator implementation.</p>
<pre><code class="language-java">public class RuleEvaluatorRegistry {
    private final Map&lt;RuleType, RuleEvaluator&gt; evaluators;

    public RuleEvaluatorRegistry(Map&lt;RuleType, RuleEvaluator&gt; evaluators) {
        this.evaluators = evaluators;
    }

    public RuleEvaluator getEvaluator(RuleType type) {
        RuleEvaluator evaluator = evaluators.get(type);
        if (evaluator == null) {
            throw new IllegalArgumentException("Unsupported rule type: " + type);
        }
        return evaluator;
    }
}
</code></pre>
<p>The registry maps rule type identifiers to their corresponding evaluator implementations, allowing the engine to dynamically resolve the correct logic handler at runtime.</p>
<p>The runtime validation flow changes from executing hardcoded objects to fetching database configurations and routing them through the appropriate evaluators.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/984d873e-f056-415d-bb39-320b9bfb59ea.png" alt="" style="display:block;margin:0 auto" />

<h2>Architectural Trade-Offs and Operational Realities</h2>
<p>Both approaches carry distinct operational costs. Choosing the right one depends entirely on who owns the rules and how often they change.</p>
<p>Approach one gives you strong compile-time type safety. Refactoring is trivial because your IDE can trace usages instantly. Unit testing is straightforward since everything is pure code. The downside is rigidity. Every policy tweak requires an engineering resource and a deployment pipeline.</p>
<p>Approach two provides runtime flexibility and empowers non-technical users. It fits multi-tenant platforms where Company A wants a fifty thousand rupee limit and Company B wants one hundred thousand. The catch is complexity. You are essentially building an interpreter. You now have to validate user input stored in JSON, handle malformed rule configurations, manage versioning, and protect against infinite loops or overly broad rules that accidentally block legitimate business operations.</p>
<p>Configuration-driven systems can easily devolve into badly designed mini programming languages. Keep your rule types focused and specific. Do not try to build a full general-purpose scripting engine inside your database columns.</p>
<h3>Caching and Performance</h3>
<p>When rule execution relies on database-backed configuration, performance becomes a concern. Hitting the database for rule definitions on every single incoming request adds unnecessary latency and puts immense pressure on connection pools.</p>
<p>An active enterprise platform can process hundreds of requests per second. To prevent database exhaustion, rules should be cached using distributed stores like Redis or in-memory caches like Caffeine with proper cache eviction triggers whenever an administrator updates a policy.</p>
<h3>Multi-Tenancy and Isolation</h3>
<p>In a multi-tenant environment, data leakage is an existential threat. The <code>organization_id</code> must flow unalterably from the incoming request context, through the repository layer, into the cache keys, and down to the rule evaluator. Tenant boundaries must be strictly enforced at every query level.</p>
<h3>Execution Semantics and Auditability</h3>
<p>Decide early how your engine handles failures. Do you stop at the first failed rule or collect all violations in a single response so employees can fix them at once? Furthermore, financial systems live under strict regulatory scrutiny. When an internal auditor asks why an expense request was rejected, stating that a rule failed is unacceptable. Your system must capture deep contextual metadata, including rule IDs, active versions, evaluation timestamps, and configuration snapshots.</p>
<h2>Practical Engineering Takeaways</h2>
<p>Start simple. Do not build a massive rules engine on day one if your company only has three static policies managed by the engineering team.</p>
<p>Begin with the clean Java interface approach. It provides immediate decoupling and keeps your validation logic organized without operational overhead. As your business grows, as non-technical stakeholders demand autonomy, and as multi-tenant requirements multiply, migrate the rule definitions into storage while keeping the evaluator registry pattern intact.</p>
<p>Good system design is rarely about picking the most advanced pattern available. It is about matching your architectural complexity directly to the actual velocity and demands of the business.</p>
]]></content:encoded></item><item><title><![CDATA[Demystifying Number Systems: An Engineer's Guide to Binary, Octal, and Hexadecimal]]></title><description><![CDATA[Imagine you were born with only two fingers, one on each hand. How would your everyday life change? When you went to the store to buy apples, how would you count them? You might count "zero, one, two,]]></description><link>https://blog.ashutoshkrris.in/demystifying-number-systems-an-engineer-s-guide-to-binary-octal-and-hexadecimal</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/demystifying-number-systems-an-engineer-s-guide-to-binary-octal-and-hexadecimal</guid><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Java]]></category><category><![CDATA[number system]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sun, 02 Aug 2026 16:03:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/ed47e823-78b7-46da-a154-9b10be35d1a9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Imagine you were born with only two fingers, one on each hand. How would your everyday life change? When you went to the store to buy apples, how would you count them? You might count "zero, one, two," but you would run out of physical fingers almost instantly. To count higher, you would have to invent a system where a single mark in a new position represents a bundle of items you have already counted.</p>
<p>Humans settled on a base 10 number system primarily because we evolved with ten fingers. We count in groups of tens, hundreds, and thousands without giving it a second thought. But computers do not have fingers. They are built out of millions of subatomic electronic switches known as transistors. A transistor can exist reliably in only two physical states: fully off or fully on.</p>
<p>Because a switch has only two stable states, computers naturally operate using a base 2 number system, which we call binary. Everything you see on a digital screen, including high definition video, complex 3D graphics, sound files, and software programs, boils down to millions of tiny switches turned ON or OFF.</p>
<p>Understanding how computers represent numbers is one of the most important foundational skills in software engineering. Whether you are debugging memory leaks, working with low level networking protocols, manipulating graphics pixels, or configuring system permissions, number systems appear everywhere in software engineering.</p>
<h2>What is a Number System?</h2>
<p>At its core, a number system is a structured framework for counting, representing quantities, and performing mathematical operations. It defines a set of symbols and rules for combining those symbols to express values.</p>
<p>To understand any number system, you need to understand three core terms:</p>
<ul>
<li><p><strong>Symbols</strong>: The individual graphics or characters used to represent values. In our everyday language, we use symbols like 0, 1, 2, 3 and so on.</p>
</li>
<li><p><strong>Digits</strong>: The specific symbols used within a given number system.</p>
</li>
<li><p><strong>Base (Radix)</strong>: The total number of unique digits or symbols available in that system.</p>
</li>
</ul>
<p>What does the base actually mean? The base tells you how many unique single digit symbols exist before you run out of digits and must combine them to create larger numbers.</p>
<p>Consider how you count in our everyday decimal system (base 10):</p>
<p>$$0, 1, 2, 3, 4, 5, 6, 7, 8, 9$$</p>
<p>Once you reach 9, you have used every available single digit symbol in base 10. To represent the next quantity, you wrap back around to \(0\) in the current position and place a 1 to the left of it, giving you \(10\). The \(1\) in \(10\) represents one complete bundle of ten items.</p>
<p>Now imagine a number system with a base of 4. Its available digits would only be:</p>
<p>$$0,1,2,3$$</p>
<p>Counting in base 4 looks like this:</p>
<p>$$0,1,2,3,10,11,12,13,20,21..$$</p>
<p>Notice how after reaching 3, the system runs out of symbols. The next number is written as \( 10_4 \) (read as "one zero in base 4"), which represents four total items. The base defines the grouping size of the number system.</p>
<ul>
<li><p>Base 10 (Decimal): Groups of 10 → [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</p>
</li>
<li><p>Base 4: Groups of 4 → [0, 1, 2, 3]</p>
</li>
<li><p>Base 2 (Binary): Groups of 2 → [0, 1]</p>
</li>
</ul>
<h2>Understanding Positional Value</h2>
<p>Why can we express gigantic numbers like one billion using only ten digits? The answer lies in positional notation.</p>
<p>In a positional number system, the value of a digit depends not only on the symbol itself, but also on its position or place within the sequence of digits. The position determines the power of the base by which that digit is multiplied.</p>
<h3>Positional Values in Decimal</h3>
<p>Let us examine the decimal number \(375\). We read this as three hundred seventy five. Why?</p>
<p>The rightmost position represents the base raised to the power of \(0\), which is \(10_0 = 1\). Moving left, each position multiplies the place value by the base (\(10\)).</p>
<table>
<thead>
<tr>
<th>Digit Position</th>
<th>2</th>
<th>1</th>
<th>0</th>
</tr>
</thead>
<tbody><tr>
<td>Base Power</td>
<td>\(10^2\)</td>
<td>\(10^1\)</td>
<td>\(10^0\)</td>
</tr>
<tr>
<td>Place Value</td>
<td>100</td>
<td>10</td>
<td>1</td>
</tr>
<tr>
<td>Digit</td>
<td>3</td>
<td>7</td>
<td>5</td>
</tr>
</tbody></table>
<p>Mathematically, we calculate the total value as:</p>
<p>$$375 = (3 \times 100) + (7\times10) + (5\times1) = 300 + 70 + 5 = 375$$</p>
<h3>Positional Values in Binary</h3>
<p>Binary follows the exact same positional rule. The only difference is that the base is \(2\) instead of \( 10 \) . Each position to the left increases by a power of \(2\).</p>
<p>Consider the binary number \(1101_2\):</p>
<table>
<thead>
<tr>
<th>Digit Position</th>
<th>3</th>
<th>2</th>
<th>1</th>
<th>0</th>
</tr>
</thead>
<tbody><tr>
<td>Base Power</td>
<td>\(2^3\)</td>
<td>\(2^2\)</td>
<td>\(2^1\)</td>
<td>\(2^0\)</td>
</tr>
<tr>
<td>Place Value</td>
<td>8</td>
<td>4</td>
<td>2</td>
<td>1</td>
</tr>
<tr>
<td>Binary Digit</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>1</td>
</tr>
</tbody></table>
<p>We evaluate its value in decimal by summing the products of each digit and its position weight:</p>
<p>$$1101_2 = (1\times2^3) + (1\times2^2) + (0\times2^1) + (1\times2^0)$$</p>
<p>$$1101_2 = (1\times8) + (1\times4) + (0\times2) + (1\times1) = 8+4+0+1 = 13_{10}$$</p>
<p>Positional notation is extraordinarily powerful because it allows a small, finite set of symbols to represent infinitely large values simply by extending digits to the left. Ancient systems like Roman numerals lacked a true positional place value system, which made arithmetic complex and cumbersome.</p>
<h2>Types of Number Systems</h2>
<p>While you can construct a number system for any integer base, software engineering relies heavily on four specific systems: Decimal, Binary, Octal, and Hexadecimal.</p>
<h3>Decimal (Base 10)</h3>
<ul>
<li><p><strong>Base</strong>: \(10\)</p>
</li>
<li><p><strong>Allowed Digits</strong>: \(0, 1, 2, 3, 4, 5, 6, 7, 8, 9\)</p>
</li>
<li><p><strong>Usage</strong>: Everyday human communication, financial calculations, and high level application inputs/outputs.</p>
</li>
</ul>
<h3>Binary (Base 2)</h3>
<ul>
<li><p><strong>Base</strong>: \( 2 \)</p>
</li>
<li><p><strong>Allowed Digits</strong>: \(0, 1\)</p>
</li>
<li><p><strong>Usage</strong>: Machine level hardware operation, digital logic circuits, CPU registers, low level protocols, and boolean logic.</p>
</li>
</ul>
<h3>Octal (Base 8)</h3>
<ul>
<li><p><strong>Base</strong>: \(8\)</p>
</li>
<li><p><strong>Allowed Digits</strong>: \(0, 1, 2, 3, 4, 5, 6, 7\)</p>
</li>
<li><p><strong>Usage</strong>: Unix file permission representations (for example <code>chmod 755</code>), legacy computing systems, and shorthand for 3-bit binary groups.</p>
</li>
</ul>
<h3>Hexadecimal (Base 16)</h3>
<ul>
<li><p><strong>Base</strong>: \(16\)</p>
</li>
<li><p><strong>Allowed Digits</strong>: \(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F\)</p>
</li>
<li><p><strong>Digit Mapping</strong>: \(A = 10, B = 11, C = 12, D = 13, E = 14, F = 15\)</p>
</li>
<li><p><strong>Usage</strong>: Memory address formatting, color representation in web applications (<code>#FF5733</code>), assembly language, inspection of binary data in hex editors, and network configuration (IPv6, MAC addresses).</p>
</li>
</ul>
<h3>Value Comparison Table (0 to 31)</h3>
<p>The following reference table maps values from \(0\) through \(31\) across all four core number systems.</p>
<table>
<thead>
<tr>
<th>Decimal (Base 10)</th>
<th>Binary (Base 2)</th>
<th>Octal (Base 8)</th>
<th>Hexadecimal (Base 16)</th>
</tr>
</thead>
<tbody><tr>
<td>0</td>
<td>000000</td>
<td>00</td>
<td>00</td>
</tr>
<tr>
<td>1</td>
<td>000001</td>
<td>01</td>
<td>01</td>
</tr>
<tr>
<td>2</td>
<td>000010</td>
<td>02</td>
<td>02</td>
</tr>
<tr>
<td>3</td>
<td>000011</td>
<td>03</td>
<td>03</td>
</tr>
<tr>
<td>4</td>
<td>000100</td>
<td>04</td>
<td>04</td>
</tr>
<tr>
<td>5</td>
<td>000101</td>
<td>05</td>
<td>05</td>
</tr>
<tr>
<td>6</td>
<td>000110</td>
<td>06</td>
<td>06</td>
</tr>
<tr>
<td>7</td>
<td>000111</td>
<td>07</td>
<td>07</td>
</tr>
<tr>
<td>8</td>
<td>001000</td>
<td>10</td>
<td>08</td>
</tr>
<tr>
<td>9</td>
<td>001001</td>
<td>11</td>
<td>09</td>
</tr>
<tr>
<td>10</td>
<td>001010</td>
<td>12</td>
<td>0A</td>
</tr>
<tr>
<td>11</td>
<td>001011</td>
<td>13</td>
<td>0B</td>
</tr>
<tr>
<td>12</td>
<td>001100</td>
<td>14</td>
<td>0C</td>
</tr>
<tr>
<td>13</td>
<td>001101</td>
<td>15</td>
<td>0D</td>
</tr>
<tr>
<td>14</td>
<td>001110</td>
<td>16</td>
<td>0E</td>
</tr>
<tr>
<td>15</td>
<td>001111</td>
<td>17</td>
<td>0F</td>
</tr>
<tr>
<td>16</td>
<td>010000</td>
<td>20</td>
<td>10</td>
</tr>
<tr>
<td>17</td>
<td>010001</td>
<td>21</td>
<td>11</td>
</tr>
<tr>
<td>18</td>
<td>010010</td>
<td>22</td>
<td>12</td>
</tr>
<tr>
<td>19</td>
<td>010011</td>
<td>23</td>
<td>13</td>
</tr>
<tr>
<td>20</td>
<td>010100</td>
<td>24</td>
<td>14</td>
</tr>
<tr>
<td>21</td>
<td>010101</td>
<td>25</td>
<td>15</td>
</tr>
<tr>
<td>22</td>
<td>010110</td>
<td>26</td>
<td>16</td>
</tr>
<tr>
<td>23</td>
<td>010111</td>
<td>27</td>
<td>17</td>
</tr>
<tr>
<td>24</td>
<td>011000</td>
<td>30</td>
<td>18</td>
</tr>
<tr>
<td>25</td>
<td>011001</td>
<td>31</td>
<td>19</td>
</tr>
<tr>
<td>26</td>
<td>011010</td>
<td>32</td>
<td>1A</td>
</tr>
<tr>
<td>27</td>
<td>011011</td>
<td>33</td>
<td>1B</td>
</tr>
<tr>
<td>28</td>
<td>011100</td>
<td>34</td>
<td>1C</td>
</tr>
<tr>
<td>29</td>
<td>011101</td>
<td>35</td>
<td>1D</td>
</tr>
<tr>
<td>30</td>
<td>011110</td>
<td>36</td>
<td>1E</td>
</tr>
<tr>
<td>31</td>
<td>011111</td>
<td>37</td>
<td>1F</td>
</tr>
</tbody></table>
<h2>Why Computers Use Binary</h2>
<p>Why do computers use base 2 instead of base 10? Wouldn't a decimal computer be much more convenient for humans?</p>
<p>To answer this, we must look at the hardware components inside modern microprocessors. At the silicon level, computer memory and processors consist of billions of microscopic transistors that act as electronic switches.</p>
<ul>
<li><p>High Voltage State (~5V or ~3.3V) ----&gt; Represents '1' (ON)</p>
</li>
<li><p>Low Voltage State (~0V or ~0.5V) ----&gt; Represents '0' (OFF)</p>
</li>
</ul>
<p>In physical hardware, precise electric voltages fluctuate constantly due to temperature variations, manufacturing flaws, and electromagnetic interference.</p>
<p>If engineers built a base 10 computer, the hardware would need to distinguish between 10 distinct voltage levels (for instance, 0V, 0.5V, 1.0V, up to 4.5V). A small electrical spike or drop of just 0.3 volts could cause the computer to misread a digit \(4\) as a \(3\) or \(5\), leading to corrupted data and crashes.</p>
<p>Binary eliminates this problem. By defining only two states (a high voltage threshold for \(1\) and a low voltage threshold for \(0\)), hardware components gain immense noise tolerance. The system only needs to determine whether a voltage level is "generally high" or "generally low". This simple distinction makes modern digital computing extraordinarily reliable and scalable.</p>
<h2>Why Octal and Hexadecimal Exist</h2>
<p>Although binary is ideal for electronic hardware, it is difficult for human engineers to read, write, and remember.</p>
<p>Imagine inspecting a computer's system memory and seeing a raw string of binary data like this:</p>
<p>$$11011110101011010110101110001111_2$$</p>
<p>It is nearly impossible for a human to spot a mistake or communicate this number verbally to a colleague without making a mistake.</p>
<p>This is where Octal and Hexadecimal come to the rescue. They act as human readable shortcuts for binary strings.</p>
<p>Because \(8\) and \(16\) are exact integer powers of \( 2 \) , there is a direct mathematical relationship between binary bits and octal/hexadecimal digits:</p>
<p>$$2^3 = 8 \implies \text{3 binary bits correlate exactly to 1 octal digit}$$</p>
<p>$$2^4 = 16 \implies \text{4 binary bits correlate exactly to 1 hexadecimal digit}$$</p>
<p>Let us look at how much simpler the previous 32-bit binary number becomes when grouped into 4-bit clusters (nibbles) and written in hexadecimal:</p>
<table>
<thead>
<tr>
<th>Binary</th>
<th>1101</th>
<th>1110</th>
<th>1010</th>
<th>1101</th>
<th>0110</th>
<th>1011</th>
<th>1000</th>
<th>1111</th>
</tr>
</thead>
<tbody><tr>
<td>Hexadecimal</td>
<td>D</td>
<td>E</td>
<td>A</td>
<td>D</td>
<td>6</td>
<td>B</td>
<td>8</td>
<td>F</td>
</tr>
</tbody></table>
<p>The long, unreadable string of 32 binary digits collapses into just 8 hexadecimal characters: <code>DEAD6B8F</code>. It takes up far less space on a monitor and reduces human errors.</p>
<h3>Real World Applications of Hexadecimal and Octal</h3>
<ul>
<li><p><strong>Memory Addresses</strong>: Operating systems display RAM locations as hexadecimal numbers (e.g., <code>0x7FFF5FBFF010</code>).</p>
</li>
<li><p><strong>HTML/CSS Colors</strong>: Web colors use 24-bit hexadecimal values representing Red, Green, and Blue channels (<code>#FF0000</code> for pure red).</p>
</li>
<li><p><strong>MAC Addresses</strong>: Hardware network card identifiers use six pairs of hex digits (<code>00:1A:2B:3C:4D:5E</code>).</p>
</li>
<li><p><strong>IPv6 Addresses</strong>: Next generation Internet Protocol addresses use 128-bit values split into eight 16-bit hexadecimal blocks (<code>2001:0db8:85a3:0000:0000:8a2e:0370:7334</code>).</p>
</li>
<li><p><strong>Unix File Permissions</strong>: File access modes in Unix systems use octal flags (e.g., <code>777</code> grants read, write, and execute permissions).</p>
</li>
<li><p><strong>Hex Editors</strong>: Developers use hex editors to inspect binary files, executable code, and raw disk sectors.</p>
</li>
</ul>
<h2>Number Conversion Fundamentals</h2>
<p>Before memorizing algorithmic formulas for conversions, it helps to understand the underlying logic.</p>
<p>Converting a number from one base to another is simply a re-packaging process. You are taking a fixed quantity of items and re-grouping them according to the rules of a new base.</p>
<p>When converting <strong>from Decimal to another base</strong>, you are answering the question: "How many bundles of size \( Base^k, \dots, Base^2, Base^1, Base^0 \) can I pull out of this number?" This is why the standard algorithm relies on <strong>repeated division</strong>. Division extracts remainder values that become digits in the new base from right to left.</p>
<p>When converting <strong>from another base to Decimal</strong>, you are working in reverse: evaluating positional weights and summing them up. This requires <strong>positional multiplication</strong>.</p>
<h3>Decimal to Binary</h3>
<p>To convert a decimal whole number into binary, we use the <strong>repeated division-by-2 method</strong>.</p>
<h4>Algorithm Steps</h4>
<ol>
<li><p>Divide the decimal number by \( 2 \) .</p>
</li>
<li><p>Record the integer quotient and the remainder (\(0\) or \(1\)).</p>
</li>
<li><p>Take the quotient and divide it by \( 2 \) again.</p>
</li>
<li><p>Repeat this process until the quotient becomes \(0\).</p>
</li>
<li><p>Write out the remainders in <strong>reverse order</strong> (from the last remainder calculated to the first).</p>
</li>
</ol>
<h4>Worked Example: Convert \(43_{10}\) to Binary</h4>
<p>43÷2=21remainder 1(Least Significant Bit - LSB)21÷2=10remainder 110÷2=5remainder 05÷2=2remainder 12÷2=1remainder 01÷2=0remainder 1(Most Significant Bit - MSB)</p>
<p>Reading the remainders from bottom to top (MSB to LSB), we get:</p>
<h4>Code Implementation</h4>
<pre><code class="language-java">public class DecimalToBinary {
    public static String convertDecimalToBinary(int decimal) {
        if (decimal == 0) {
            return "0";
        }
        
        StringBuilder binaryResult = new StringBuilder();
        int currentNumber = decimal;
        
        // Loop until the quotient becomes 0
        while (currentNumber &gt; 0) {
            int remainder = currentNumber % 2; // Calculate remainder (0 or 1)
            binaryResult.append(remainder);   // Append remainder to result string
            currentNumber = currentNumber / 2; // Divide quotient by 2
        }
        
        // Reverse string to order remainders from MSB to LSB
        return binaryResult.reverse().toString();
    }

    public static void main(String[] args) {
        int number = 43;
        System.out.println("Decimal " + number + " in Binary is: " + convertDecimalToBinary(number));
    }
}
</code></pre>
<h3>Binary to Decimal</h3>
<p>To convert a binary number back to decimal, we use <strong>positional expansion</strong>. Multiply each binary digit by \( 2 \) raised to the power of its zero-indexed position (counting from right to left), then add all the products together.</p>
<h4>Worked Example: Convert \(110101_2\) to Decimal</h4>
<p>Write down the positional powers of \( 2 \) for each digit:</p>
<h4>Code Implementation</h4>
<pre><code class="language-java">public class BinaryToDecimal {
    public static int convertBinaryToDecimal(String binaryStr) {
        int decimalSum = 0;
        int length = binaryStr.length();
        
        // Iterate through each character in the string from left to right
        for (int i = 0; i &lt; length; i++) {
            char bitChar = binaryStr.charAt(i);
            int bitValue = Character.getNumericValue(bitChar);
            
            // Exponent corresponds to distance from the rightmost edge
            int power = length - 1 - i;
            decimalSum += bitValue * Math.pow(2, power);
        }
        
        return decimalSum;
    }

    public static void main(String[] args) {
        String binary = "110101";
        System.out.println("Binary " + binary + " in Decimal is: " + convertBinaryToDecimal(binary));
    }
}
</code></pre>
<h3>Decimal to Octal</h3>
<p>Decimal to octal conversion follows the exact same pattern as decimal to binary, but we divide by \(8\) instead of \( 2 \) .</p>
<p>Worked Example: Convert \(175_{10}\) to Octal</p>
<p>175÷8=21remainder 7(LSB)21÷8=2remainder 52÷8=0remainder 2(MSB)</p>
<p>Reading remainders from bottom to top:</p>
<h4>Code Implementation</h4>
<pre><code class="language-java">public class DecimalToOctal {
    public static String convertDecimalToOctal(int decimal) {
        if (decimal == 0) return "0";
        
        StringBuilder octalResult = new StringBuilder();
        int current = decimal;
        
        while (current &gt; 0) {
            int remainder = current % 8; // Remainder when dividing by 8
            octalResult.append(remainder);
            current /= 8;               // Reduce quotient by factor of 8
        }
        
        return octalResult.reverse().toString();
    }

    public static void main(String[] args) {
        int val = 175;
        System.out.println("Decimal " + val + " in Octal is: " + convertDecimalToOctal(val));
    }
}
</code></pre>
<h3>Octal to Decimal</h3>
<p>To convert from octal to decimal, sum each octal digit multiplied by \(8\) raised to its position power.</p>
<h4>Worked Example: Convert \(346_8\) to Decimal</h4>
<h4>Code Implementation</h4>
<pre><code class="language-java">public class OctalToDecimal {
    public static int convertOctalToDecimal(String octalStr) {
        int decimalSum = 0;
        int length = octalStr.length();
        
        for (int i = 0; i &lt; length; i++) {
            int digit = Character.getNumericValue(octalStr.charAt(i));
            int power = length - 1 - i;
            decimalSum += digit * Math.pow(8, power);
        }
        
        return decimalSum;
    }

    public static void main(String[] args) {
        String octal = "346";
        System.out.println("Octal " + octal + " in Decimal is: " + convertOctalToDecimal(octal));
    }
}
</code></pre>
<h3>Decimal to Hexadecimal</h3>
<p>To convert decimal numbers to hexadecimal, perform <strong>repeated division by 16</strong>. Remainders ranging from \(10\) to \(15\) must be translated to their corresponding letters (\(\text{A}\) through \(\text{F}\)).</p>
<h4>Worked Example: Convert \(942_{10}\) to Hexadecimal</h4>
<p>942÷16=58remainder 14⟹E(LSB)58÷16=3remainder 10⟹A3÷16=0remainder 3⟹3(MSB)</p>
<p>Reading from bottom to top:</p>
<p>$$942_{10} = 3\text{AE}_{16}$$</p>
<h4>Code Implementation</h4>
<pre><code class="language-java">public class DecimalToHexadecimal {
    private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();

    public static String convertDecimalToHex(int decimal) {
        if (decimal == 0) return "0";
        
        StringBuilder hexResult = new StringBuilder();
        int current = decimal;
        
        while (current &gt; 0) {
            int remainder = current % 16;
            // Lookup corresponding hex character for remainder
            hexResult.append(HEX_CHARS[remainder]);
            current /= 16;
        }
        
        return hexResult.reverse().toString();
    }

    public static void main(String[] args) {
        int number = 942;
        System.out.println("Decimal " + number + " in Hex is: " + convertDecimalToHex(number));
    }
}
</code></pre>
<h3>Hexadecimal to Decimal</h3>
<p>Convert each hexadecimal digit to its numerical decimal equivalent, multiply by \(16\) raised to its position power, and sum the terms.</p>
<h4>Worked Example: Convert \(2\text{F}8_{16}\) to Decimal</h4>
<p>Note that \(\text{F} = 15\).</p>
<p>$$\begin{aligned} 2\text{F}8_{16} &amp;= (2 \times 16^2) + (15 \times 16^1) + (8 \times 16^0) \ &amp;= (2 \times 256) + (15 \times 16) + (8 \times 1) \ &amp;= 512 + 240 + 8 \ &amp;= 760_{10} \end{aligned}$$</p>
<h4>Code Implementation</h4>
<pre><code class="language-java">public class HexadecimalToDecimal {
    public static int convertHexToDecimal(String hexStr) {
        int decimalSum = 0;
        String upperHex = hexStr.toUpperCase();
        int length = upperHex.length();
        
        for (int i = 0; i &lt; length; i++) {
            char ch = upperHex.charAt(i);
            // Convert character ('0'-'9' or 'A'-'F') to integer value
            int digitValue = "0123456789ABCDEF".indexOf(ch);
            int power = length - 1 - i;
            
            decimalSum += digitValue * Math.pow(16, power);
        }
        
        return decimalSum;
    }

    public static void main(String[] args) {
        String hex = "2F8";
        System.out.println("Hex " + hex + " in Decimal is: " + convertHexToDecimal(hex));
    }
}
</code></pre>
<h3>Binary to Octal</h3>
<p>Converting directly from binary to octal does not require arithmetic division. Because \(2^3 = 8\), you can perform conversion purely through <strong>visual bit-grouping</strong>.</p>
<h4>Algorithm Steps</h4>
<ol>
<li><p>Start from the <strong>rightmost bit</strong> (LSB) and split the binary number into groups of <strong>3 bits</strong>.</p>
</li>
<li><p>If the leftmost group has fewer than 3 bits, <strong>pad it with leading zeros</strong> on the left.</p>
</li>
<li><p>Convert each 3-bit group into its corresponding octal digit (\(0\) through \(7\)).</p>
</li>
</ol>
<h4>Worked Example: Convert \(1101011_2\) to Octal</h4>
<p>First, group into 3-bit sets starting from the right:</p>
<p>$$1 \quad \mid \quad 101 \quad \mid \quad 011$$</p>
<p>Pad the leftmost single bit with two leading zeros to complete the triplet:</p>
<p>$$001 \quad \mid \quad 101 \quad \mid \quad 011$$</p>
<p>Now translate each group:</p>
<ul>
<li><p>\(001_2 = 1_8\)</p>
</li>
<li><p>\(101_2 = 5_8\)</p>
</li>
<li><p>\(011_2 = 3_8\)</p>
</li>
</ul>
<p>Combine the results:</p>
<p>$$1101011_2 = 153_8$$</p>
<h3>Octal to Binary</h3>
<p>To convert octal to binary, perform the bit-grouping process in reverse. Replace <strong>every single octal digit</strong> with its exact <strong>3-bit binary representation</strong>.</p>
<h4>Worked Example: Convert \(624_8\) to Binary</h4>
<p>Convert each digit individually:</p>
<ul>
<li><p>\(6_8 = 110_2\)</p>
</li>
<li><p>\(2_8 = 010_2\) (Be sure to keep the leading zero to maintain 3 bits)</p>
</li>
<li><p>\(4_8 = 100_2\)</p>
</li>
</ul>
<p>Concatenate the binary groups:</p>
<p>$$624_8 = 110010100_2$$</p>
<h3>Binary to Hexadecimal</h3>
<p>Because \(2*4 = 16\), converting binary to hexadecimal is done by grouping bits into sets of <strong>4 bits</strong> (nibbles).</p>
<h4>Algorithm Steps</h4>
<ol>
<li><p>Start from the <strong>rightmost bit</strong> and partition the binary string into sets of 4 bits.</p>
</li>
<li><p>Pad the leftmost group with leading zeros if it contains fewer than 4 bits.</p>
</li>
<li><p>Replace each 4-bit block with its corresponding hexadecimal digit (\(0\) to \(\text{F}\)).</p>
</li>
</ol>
<h4>Worked Example: Convert \(11101011001_2\)​ to Hexadecimal</h4>
<p>Group from right to left in sets of four:</p>
<p>$$111 \quad \mid \quad 0101 \quad \mid \quad 1001$$</p>
<p>Pad the leftmost triplet with a single zero:</p>
<p>$$0111 \quad \mid \quad 0101 \quad \mid \quad 1001$$</p>
<p>Translate each nibble:</p>
<ul>
<li><p>\(0111_2 = 7_{16}\)</p>
</li>
<li><p>\(0101_2 = 5_{16}\)</p>
</li>
<li><p>\(1001_2 = 9_{16}\)</p>
</li>
</ul>
<p>Combine the hex digits:</p>
<p>$$11101011001_2 = 759_{16}$$</p>
<h3>Hexadecimal to Binary</h3>
<p>Convert each hexadecimal character into its exact <strong>4-bit binary block</strong>.</p>
<h4>Worked Example: Convert \(\text{B0E}_{16}\) to Binary</h4>
<p>Translate each character independently:</p>
<ul>
<li><p>\(\text{B}<em>{16} = 11</em>{10} = 1011_2\)</p>
</li>
<li><p>\(0_{16} = 0000_2\) (Always write out all four zeros)</p>
</li>
<li><p>\(\text{E}<em>{16} = 14</em>{10} = 1110_2\)</p>
</li>
</ul>
<p>Combine the binary blocks:</p>
<p>$$\text{B}0\text{E}_{16} = 101100001110_2$$</p>
<h3>Octal to Hexadecimal</h3>
<p>Direct conversion between octal (base 8) and hexadecimal (base 16) is awkward using pure arithmetic. The easiest and fastest way to convert between them is using <strong>Binary as an intermediary bridge</strong>.</p>
<h4>Worked Example: Convert \(735_8\) to Hexadecimal</h4>
<p><strong>Step 1</strong>: Convert Octal to Binary (3 bits per digit)</p>
<ul>
<li><p>\(7_8 = 111_2\)</p>
</li>
<li><p>\(3_8 = 011_2\)</p>
</li>
<li><p>\(5_8 = 101_2\)</p>
</li>
</ul>
<p>Intermediate Binary String: \(111011101_2\)</p>
<p><strong>Step 2</strong>: Group the Binary String into 4-bit sets (from right to left)</p>
<p>$$1 \quad \mid \quad 1101 \quad \mid \quad 1101$$</p>
<p>Pad leftmost group with zeros:</p>
<p>$$0001 \quad \mid \quad 1101 \quad \mid \quad 1101$$</p>
<p><strong>Step 3</strong>: Convert 4-bit blocks to Hexadecimal</p>
<ul>
<li><p>\(0001_2 = 1_{16}\)</p>
</li>
<li><p>\(1101_2 = \text{D}_{16}\)</p>
</li>
<li><p>\(1101_2 = \text{D}_{16}\)</p>
</li>
</ul>
<p>Result:</p>
<p>$$735_8 = 1\text{DD}_{16}$$</p>
<h3>Hexadecimal to Octal</h3>
<p>Converting from Hexadecimal to Octal uses the same binary bridge strategy.</p>
<h4>Worked Example: Convert \(4\text{AC}_{16}\) to Octal</h4>
<p><strong>Step 1</strong>: Expand Hex digits to 4-bit binary blocks</p>
<ul>
<li><p>\(4_{16} = 0100_2\)</p>
</li>
<li><p>\(\text{A}_{16} = 1010_2\)</p>
</li>
<li><p>\(\text{C}_{16} = 1100_2\)</p>
</li>
</ul>
<p>Intermediate Binary: \(010010101100_2\)</p>
<p><strong>Step 2</strong>: Re-group binary string into 3-bit triplets (from right to left)</p>
<p>$$010 \quad \mid \quad 010 \quad \mid \quad 101 \quad \mid \quad 100$$</p>
<p><strong>Step 3</strong>: Convert 3-bit groups to Octal digits</p>
<ul>
<li><p>\(010_2 = 2_8\)</p>
</li>
<li><p>\(010_2 = 2_8\)</p>
</li>
<li><p>\(101_2 = 5_8\)</p>
</li>
<li><p>\(100_2 = 4_8\)</p>
</li>
</ul>
<p>Result:</p>
<p>$$4\text{A}\text{C}_{16} = 2254_8$$</p>
<h2>Fractional Number Conversion</h2>
<p>How do computers handle fractional values (numbers with decimal points, like \(10.625_{10}\))?</p>
<p>A fractional number consists of two parts separated by a radix point: an integer portion and a fractional portion.</p>
<p>$$10.625_{10} \implies \text{Integer Part} = 10, \quad \text{Fractional Part} = 0.625$$</p>
<h3>Converting the Integer Part</h3>
<p>The integer part (10) is converted using standard division by 2:</p>
<p>$$10_{10} = 1010_2$$</p>
<h3>Converting the Fractional Part (Repeated Multiplication)</h3>
<p>To convert the fractional component (\(0.625\)), we use <strong>repeated multiplication by 2</strong>:</p>
<ol>
<li><p>Multiply the fraction by \(2\).</p>
</li>
<li><p>The integer portion of the result becomes the next binary fractional digit.</p>
</li>
<li><p>Take the remaining fractional part and multiply by \(2\) again.</p>
</li>
<li><p>Repeat until the fractional part becomes \(0\) (or until you reach your target precision level).</p>
</li>
</ol>
<p>Let us convert \(0.625_{10}\):</p>
<p>$$0.625 \times 2 = 1.25 \implies \text{Integer part: } 1, \quad \text{New fraction: } 0.25$$</p>
<p> $$ 0.25 \times 2 = 0.50 \implies \text{Integer part: } 0, \quad \text{New fraction: } 0.50$$</p>
<p> $$ 0.50 \times 2 = 1.00 \implies \text{Integer part: } 1, \quad \text{New fraction: } 0.00 \quad (\text{Stop})$$</p>
<p>Read the integer parts <strong>from top to bottom</strong>:</p>
<p>$$0.625_{10} = 0.101_2$$</p>
<p>Combine both integer and fractional results:</p>
<p>$$10.625_{10} = 1010.101_2$$</p>
<h2>Number Systems in Java</h2>
<p>Modern Java provides built-in syntax literals and utility functions within the <code>Integer</code> wrapper class to handle different number bases easily.</p>
<h3>Literal Syntax Prefix in Java</h3>
<ul>
<li><p>Binary Literals: Prefix with <code>0b</code> or <code>0B</code></p>
</li>
<li><p>Octal Literals: Prefix with <code>0</code></p>
</li>
<li><p>Hexadecimal Literals: Prefix with <code>0x</code> or <code>0X</code></p>
</li>
</ul>
<h3>Built-in Conversion Methods</h3>
<pre><code class="language-java">public class JavaNumberSystems {
    public static void main(String[] args) {
        // 1. Defining literals in source code
        int decimalValue = 42;
        int binaryValue = 0b101010; // 42 expressed in binary
        int octalValue = 052;       // 42 expressed in octal
        int hexValue = 0x2A;        // 42 expressed in hexadecimal

        System.out.println("Literal values evaluate identically in Java:");
        System.out.println("Binary 0b101010 = " + binaryValue);
        System.out.println("Hex 0x2A = " + hexValue);

        // 2. Converting Decimal Integers to String representations
        int number = 255;
        String binStr = Integer.toBinaryString(number); // "11111111"
        String octStr = Integer.toOctalString(number);  // "377"
        String hexStr = Integer.toHexString(number);    // "ff"

        System.out.println("\nFormatted string outputs for 255:");
        System.out.println("Binary string: " + binStr);
        System.out.println("Octal string: " + octStr);
        System.out.println("Hex string: " + hexStr.toUpperCase());

        // 3. Parsing Strings in arbitrary bases back to decimal integers
        int parsedBin = Integer.parseInt("110101", 2);  // Parse Base 2
        int parsedOct = Integer.parseInt("346", 8);     // Parse Base 8
        int parsedHex = Integer.parseInt("2F8", 16);    // Parse Base 16

        System.out.println("\nParsed Values:");
        System.out.println("Parsed binary 110101: " + parsedBin);
        System.out.println("Parsed hex 2F8: " + parsedHex);
    }
}
</code></pre>
<h2>Common Mistakes Beginners Make</h2>
<p>When working with number systems for the first time, beginners often encounter several predictable pitfalls. Keeping these in mind will save you hours of debugging time.</p>
<h3>1. Using Invalid Digits for a Given Base</h3>
<p>A common error is including a digit that is outside the range permitted by the base.</p>
<ul>
<li><p><em>Error</em>: Writing \(1021_2\) as a binary number (the digit \(2\) is invalid in base 2).</p>
</li>
<li><p><em>Error</em>: Writing \(781_8\) as an octal number (the digit \(8\) is invalid in base 8).</p>
</li>
</ul>
<h3>2. Grouping Bit Clusters from the Wrong Direction</h3>
<p>When grouping binary digits into 3-bit (octal) or 4-bit (hex) blocks, <strong>always group from right to left</strong> (starting at the LSB). Grouping from left to right alters the value completely.</p>
<p><em>Correct grouping of</em> \(11011_2\) <em>into hex (4 bits)</em>:</p>
<p>$$\text{Right to Left: } (0001)(1011) \implies 1\text{B}_{16} \quad \checkmark$$</p>
<p> $$ \text{Left to Right: } (1101)(1000) \implies \text{D}8_{16} \quad \mathbf{X}$$</p>
<h3>3. Forgetting Hexadecimal Characters A through F</h3>
<p>Remembering that hexadecimal digits extend past \(9\) to include letters (\(\text{A}=10, \text{B}=11, \text{C}=12, \text{D}=13, \text{E}=14, \text{F}=15\)) is critical.</p>
<ul>
<li><em>Mistake</em>: Writing \(10\) instead of \(\text{A}\) when doing remainder division by 16. The remainder sequence \(10, 11\) written side-by-side as <code>1011</code> will be misread as four separate digits instead of two hex digits <code>AB</code>.</li>
</ul>
<h3>4. Stripping Leading Zeros Prematurely</h3>
<p>While leading zeros on a standalone integer do not change its value (\(00010_2 = 10_2\)), stripping leading zeros during intermediate multi-step conversions causes major errors.</p>
<p>For instance, when converting the hex value <code>0x803</code> to binary, \(0_{16}\) must expand into four full zeros (<code>0000</code>). If you compress it to a single <code>0</code>, the whole binary alignment is ruined.</p>
<h3>5. Confusing String "10" with Value 10</h3>
<p>Always double check whether you are working with the decimal value \(10\) or the string <code>"10"</code> in a non-decimal base. The string <code>"10"</code> in binary means \(2_{10}\), in octal it means \(8_{10}\), and in hex it means \(16_{10}\).</p>
<h2>Quick Cheat Sheet</h2>
<p>Here is a quick summary table for fast reference during coding or exams.</p>
<table style="min-width:125px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Base Name</strong></p></td><td><p><strong>Base Number</strong></p></td><td><p><strong>Allowed Digits</strong></p></td><td><p><strong>Bit Grouping Size</strong></p></td><td><p><strong>Direct Shortcut</strong></p></td></tr><tr><td><p><strong>Binary</strong></p></td><td><p>2</p></td><td><p>0, 1</p></td><td><p>1 bit</p></td><td><p>Base system for logic circuits</p></td></tr><tr><td><p><strong>Octal</strong></p></td><td><p>8</p></td><td><p>0 to 7</p></td><td><p>3 bits (2^3 = 8)</p></td><td><p>Replace 1 octal digit with 3 bits</p></td></tr><tr><td><p><strong>Decimal</strong></p></td><td><p>10</p></td><td><p>0 to 9</p></td><td><p>N/A</p></td><td><p>Human standard</p></td></tr><tr><td><p><strong>Hexadecimal</strong></p></td><td><p>16</p></td><td><p>0-9, A-F</p></td><td><p>4 bits (2^4 = 16)</p></td><td><p>Replace 1 hex digit with 4 bits</p></td></tr></tbody></table>

<h3>Conversion Strategy Summary</h3>
<ul>
<li><p><strong>Decimal → Any Base</strong>: Repeatedly divide by the target base, track remainders, and read bottom-to-top.</p>
</li>
<li><p><strong>Any Base → Decimal</strong>: Multiply each digit by \(Base^{position}\) and sum the results.</p>
</li>
<li><p><strong>Binary ↔ Octal</strong>: Group/expand bits in sets of 3.</p>
</li>
<li><p><strong>Binary ↔ Hexadecimal</strong>: Group/expand bits in sets of 4.</p>
</li>
<li><p><strong>Octal ↔ Hexadecimal</strong>: Convert through Binary first.</p>
</li>
</ul>
<h2>Final Summary</h2>
<p>We have covered a lot of ground in this guide. Let us do a quick recap of the foundational concepts you have learned:</p>
<ol>
<li><p><strong>Number systems rely on positional notation</strong>. The place value of any digit is determined by its position multiplied by powers of the system's base.</p>
</li>
<li><p><strong>Computers run on Binary (Base 2)</strong> because electronic switches built out of silicon transistors operate most reliably in two discrete voltage states: ON (\(1\)) and OFF (\(0\)).</p>
</li>
<li><p><strong>Octal (Base 8) and Hexadecimal (Base 16) exist as human shorthand</strong>. Because \(8\) and \(16\) are powers of \(2\) (\(2^3\) and \(2^4\)), you can convert between binary bits and octal/hex digits visually without doing long division.</p>
</li>
<li><p><strong>Conversions rely on simple rules</strong>:</p>
<ul>
<li><p>To convert from Decimal to another base, use <strong>repeated division</strong>.</p>
</li>
<li><p>To convert from another base to Decimal, sum up the <strong>positional weights</strong>.</p>
</li>
<li><p>To convert between Octal and Hexadecimal, use <strong>Binary as a bridge</strong>.</p>
</li>
</ul>
</li>
</ol>
<p>Every high level language, framework, database, and operating system you will work with throughout your software development career rests on these simple base-level principles. When you feel comfortable reading, manipulating, and converting between different bases, low level computing stops feeling like mysterious magic and starts feeling like an approachable, logical system.</p>
<p>Keep practicing, build out the code exercises, and happy coding!</p>
]]></content:encoded></item><item><title><![CDATA[Introducing Invoice Now: A Free, Privacy-First Invoice Generator That Runs Entirely in Your Browser]]></title><description><![CDATA[Every time I needed to send an invoice, I found myself running into the same problems.
One tool wanted me to create an account before I could even see the editor. Another locked PDF exports or brandin]]></description><link>https://blog.ashutoshkrris.in/invoice-now-free-invoice-generator</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/invoice-now-free-invoice-generator</guid><category><![CDATA[Freelancing]]></category><category><![CDATA[React]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Invoice Generator]]></category><category><![CDATA[Open Source]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sun, 26 Jul 2026 04:22:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/8bf4b1f1-dab8-4054-a4e7-cd1a136a86d0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every time I needed to send an invoice, I found myself running into the same problems.</p>
<p>One tool wanted me to create an account before I could even see the editor. Another locked PDF exports or branding behind a subscription. Nearly all of them stored my clients' information on their servers, even though generating an invoice doesn't really require a backend.</p>
<p>I wanted something simpler.</p>
<p>So I built <a href="https://invoicenow.ashutoshkrris.in/"><strong>Invoice Now</strong></a>, a free and <a href="https://github.com/ashutoshkrris/invoice-now">open source</a> invoice generator that works entirely inside your browser.</p>
<p><strong>👉 Try it now:</strong> <a href="https://invoicenow.ashutoshkrris.in">https://invoicenow.ashutoshkrris.in</a></p>
<p>There are no accounts to create, no cloud sync, and no subscriptions. Your invoices, client details, logos, and settings stay on your device from start to finish.</p>
<p>Whether you're a freelancer, consultant, agency owner, or small business owner, you can create professional invoices in minutes without worrying about where your data is going.</p>
<h2>Why I Built Invoice Now</h2>
<p>Creating an invoice should be one of the easiest parts of running a business.</p>
<p>Instead, most online invoice generators introduce unnecessary friction.</p>
<p>They often require you to:</p>
<ul>
<li><p>Create an account before you can start</p>
</li>
<li><p>Upload client information to someone else's servers</p>
</li>
<li><p>Pay monthly just to remove limits</p>
</li>
<li><p>Re-enter the same business details every time</p>
</li>
<li><p>Struggle with mobile layouts when you're away from your desk</p>
</li>
</ul>
<p>For people who only need to send invoices occasionally, that's a lot of complexity for a simple task.</p>
<p>Invoice Now takes a different approach.</p>
<p>Everything happens locally in your browser. Once the page loads, your data never leaves your device unless you choose to export it.</p>
<h2>See Invoice Now in Action</h2>
<p>Before diving into the features, here's a quick walkthrough showing how to create an invoice from start to finish in under three minutes.</p>
<p><a class="embed-card" href="https://www.youtube.com/watch?v=QfH_IrGQEJw">https://www.youtube.com/watch?v=QfH_IrGQEJw</a></p>

<h2>What Makes Invoice Now Different</h2>
<h3>No accounts. No cloud. No tracking.</h3>
<p>This was the first design decision I made.</p>
<p>You shouldn't have to create an account just to generate an invoice.</p>
<p>With Invoice Now, you simply open the website, fill in the details, and export your invoice. That's it.</p>
<p>Your client information, payment details, invoices, and settings remain on your computer.</p>
<p>No backend database.</p>
<p>No telemetry.</p>
<p>No analytics collecting invoice data.</p>
<p>Just a browser doing what browsers are capable of today.</p>
<h3>Edit Everything in Real Time</h3>
<p>Instead of filling out a long form and hoping the PDF looks right, Invoice Now lets you edit directly on the invoice preview.</p>
<p>Click on any field and start typing.</p>
<p>As you make changes, you immediately see how the final invoice will look.</p>
<p>You can also switch between different templates, customize colors, add notes, include discounts, shipping charges, taxes, and payment instructions without leaving the editor.</p>
<h3>Generate Payment QR Codes</h3>
<p>One feature I wanted from the beginning was built-in payment QR codes.</p>
<p>If you accept UPI payments, Invoice Now can generate a QR code with your UPI ID, recipient name, and invoice amount already filled in.</p>
<p>Your client simply scans the QR code and pays.</p>
<p>If you use another payment provider, you can also generate QR codes for custom payment links such as Stripe, PayPal, Razorpay, Buy Me a Coffee, or any URL you choose.</p>
<p>Small feature.</p>
<p>Big convenience.</p>
<h3>Separate Workspaces for Different Businesses</h3>
<p>Many people don't operate under a single business.</p>
<p>You might freelance under your own name, run a small agency, and sell digital products on the side.</p>
<p>Instead of constantly replacing business information, Invoice Now lets you create separate workspaces.</p>
<p>Each workspace remembers its own:</p>
<ul>
<li><p>Business information</p>
</li>
<li><p>Logo</p>
</li>
<li><p>Currency</p>
</li>
<li><p>Tax settings</p>
</li>
<li><p>Invoice preferences</p>
</li>
</ul>
<p>Switching between businesses takes only a click.</p>
<h3>Backup Everything</h3>
<p>Because everything is stored locally, it's important that you can move your data whenever you want.</p>
<p>Invoice Now lets you export your entire workspace as a single JSON file.</p>
<p>That backup includes:</p>
<ul>
<li><p>Workspaces</p>
</li>
<li><p>Settings</p>
</li>
<li><p>Client information</p>
</li>
<li><p>Invoice defaults</p>
</li>
<li><p>Logos and images</p>
</li>
</ul>
<p>Import the file later and continue exactly where you left off, even on another computer.</p>
<p>Your data belongs to you. We don't want any of it.</p>
<h3>Built for International Invoicing</h3>
<p>Businesses around the world invoice differently.</p>
<p>Invoice Now supports:</p>
<ul>
<li><p>Multiple currencies</p>
</li>
<li><p>Custom currency symbols</p>
</li>
<li><p>Different tax labels like GST, VAT, HST, and Sales Tax</p>
</li>
<li><p>Regional number formatting</p>
</li>
</ul>
<p>Instead of forcing one format, you can configure the invoice to match your local requirements.</p>
<h3>Fast Local Storage</h3>
<p>Under the hood, Invoice Now stores lightweight settings separately from larger assets like logos and images.</p>
<p>That means switching templates, editing invoices, and generating exports stays responsive even when you're using high-resolution branding assets.</p>
<p>You don't need to know how it's implemented.</p>
<p>You just notice that it feels quick.</p>
<h3>Works Well on Mobile</h3>
<p>Sometimes you need to send an invoice immediately after finishing a meeting or visiting a client.</p>
<p>Invoice Now is fully responsive, making it comfortable to use on phones, tablets, and desktops.</p>
<p>No broken layouts.</p>
<p>No tiny buttons.</p>
<p>No features hidden behind hover menus.</p>
<h3>Export Professional PDFs and PNGs</h3>
<p>Once your invoice is ready, you can export it directly from your browser.</p>
<p>PDF exports preserve selectable text and clickable links, making them suitable for emailing clients or keeping for your own records.</p>
<p>If you need an image instead, you can also export a high-resolution PNG.</p>
<p>The layout is designed to avoid awkward page breaks, so multi-page invoices remain clean and readable.</p>
<h3>Undo When You Need It</h3>
<p>Everyone makes mistakes.</p>
<p>Invoice Now includes built-in undo and redo support, so accidental edits don't mean starting over.</p>
<p>Whether you remove an item by mistake or change the wrong field, you can easily step backward and continue working.</p>
<h3>Light and Dark Mode</h3>
<p>The interface automatically follows your system theme, and you can switch between light and dark mode whenever you prefer.</p>
<p>Only the editor changes.</p>
<p>Your exported invoices always retain their intended design.</p>
<h2>Feature Comparison</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Invoice Now</th>
<th>Typical Online Invoice Tools</th>
</tr>
</thead>
<tbody><tr>
<td>No account required</td>
<td>✅</td>
<td>Usually not</td>
</tr>
<tr>
<td>Stores data locally</td>
<td>✅</td>
<td>❌</td>
</tr>
<tr>
<td>Free to use</td>
<td>✅</td>
<td>Often limited</td>
</tr>
<tr>
<td>UPI &amp; custom payment QR codes</td>
<td>✅</td>
<td>Rare</td>
</tr>
<tr>
<td>Multiple workspaces</td>
<td>✅</td>
<td>Usually paid</td>
</tr>
<tr>
<td>JSON backup &amp; restore</td>
<td>✅</td>
<td>Rare</td>
</tr>
<tr>
<td>Offline exports</td>
<td>✅</td>
<td>Often server-generated</td>
</tr>
<tr>
<td>Undo &amp; redo</td>
<td>✅</td>
<td>Not common</td>
</tr>
</tbody></table>
<h2>Who Is It For?</h2>
<p>Invoice Now was built for anyone who needs to create professional invoices without unnecessary complexity.</p>
<p>It works especially well for:</p>
<ul>
<li><p>Freelancers</p>
</li>
<li><p>Consultants</p>
</li>
<li><p>Agencies</p>
</li>
<li><p>Small businesses</p>
</li>
<li><p>Independent creators</p>
</li>
<li><p>Developers who value privacy</p>
</li>
<li><p>Anyone who wants a simple invoice generator without another monthly subscription</p>
</li>
</ul>
<h2>Getting Started</h2>
<p>Using Invoice Now takes only a few minutes.</p>
<ol>
<li><p>Open the application.</p>
</li>
<li><p>Enter your business and client information.</p>
</li>
<li><p>Add your invoice items.</p>
</li>
<li><p>Include a payment QR code if needed.</p>
</li>
<li><p>Export your invoice as a PDF or PNG.</p>
</li>
<li><p>Send it to your client.</p>
</li>
</ol>
<p>No signup.</p>
<p>No waiting.</p>
<p>No hidden paywalls.</p>
<h2>Built in the Open</h2>
<p>Invoice Now is completely open source because I believe tools like this should be transparent.</p>
<p>If you're curious about how it works, want to report an issue, or would like to contribute, you're always welcome.</p>
<p><a class="embed-card" href="https://github.com/ashutoshkrris/invoice-now">https://github.com/ashutoshkrris/invoice-now</a></p>

<p>If you find the project useful, consider:</p>
<ul>
<li><p>⭐ Starring the project on GitHub</p>
</li>
<li><p>🚀 Supporting it on Product Hunt</p>
</li>
<li><p>💙 Sharing it with friends or colleagues</p>
</li>
<li><p>🐛 Reporting bugs or suggesting new features</p>
</li>
</ul>
<p>Every bit of feedback helps make the project better.</p>
<h2>Try Invoice Now</h2>
<p>Invoice Now started as a personal project because I wanted a faster and more private way to create invoices.</p>
<p>Today, I'm excited to share it with everyone.</p>
<p>If you've ever wished invoice software could be simpler, I hope you'll give it a try.</p>
<p>I'd love to hear what you think.</p>
<p>🌐 Website: <a href="https://invoicenow.ashutoshkrris.in">https://invoicenow.ashutoshkrris.in</a></p>
<p>⭐ GitHub: <a href="https://github.com/ashutoshkrris/invoice-now">https://github.com/ashutoshkrris/invoice-now</a></p>
<p>🚀 Product Hunt: <a href="https://www.producthunt.com/products/invoice-now">https://www.producthunt.com/products/invoice-now</a></p>
<p>If you have feedback, feature requests, or ideas for improvement, feel free to open an issue or reach out. I'd love to hear what you build with it.</p>
]]></content:encoded></item><item><title><![CDATA[Stop Misusing POST for Search: Welcome to the HTTP QUERY Method]]></title><description><![CDATA[Every developer building Web APIs eventually runs into the exact same architectural wall. You need to build a search feature, an analytics dashboard, or a complex reporting tool. The user selects a do]]></description><link>https://blog.ashutoshkrris.in/stop-misusing-post-for-search-welcome-to-the-http-query-method</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/stop-misusing-post-for-search-welcome-to-the-http-query-method</guid><category><![CDATA[Web Development]]></category><category><![CDATA[Query]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[tech ]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sat, 11 Jul 2026 06:31:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/f5e517cb-4268-4ecf-9ffb-b06d2aef4463.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every developer building Web APIs eventually runs into the exact same architectural wall. You need to build a search feature, an analytics dashboard, or a complex reporting tool. The user selects a dozen active filters, specifies nested conditions, chooses sorting rules, and hits "Search."</p>
<p>Suddenly, your clean backend design faces an unpleasant choice. If you choose a traditional <code>GET</code> request, your URL balloons into an unreadable string of encoded text that risks crashing into web browser or server character limits. If you choose a <code>POST</code> request, you easily bypass the size limits by placing the filter data inside the request body, but you strip away the fundamental caching, safety, and retry guarantees that make HTTP work so beautifully.</p>
<p>For decades, we treated this tension as just another normal quirk of web development. We built complex workarounds like persisted queries or query hashing, pretending that using an action verb like <code>POST</code> to perform a read-only search was fine.</p>
<p>That compromise is no longer necessary. The Internet Engineering Task Force (IETF) officially introduced a new standard HTTP method designed to break this deadlock: <code>QUERY</code> <strong>(</strong><a href="https://www.rfc-editor.org/info/rfc10008/"><strong>RFC 10008</strong></a><strong>)</strong>.</p>
<p>The <code>QUERY</code> method fills a massive gap in web architecture. It provides the heavy-lifting capability of a request body, while preserving the clean, read-only guarantees of a safe and idempotent fetch.</p>
<h2>Why GET Isn't Always Enough</h2>
<p>To understand why the <code>QUERY</code> method matters, we need to look at the practical limits of the options we have used for years.</p>
<p>When you learn REST API design, the rule is simple: if you are reading data, you use <code>GET</code>. This approach works flawlessly for simple lookups like <code>/api/v1/users/42</code> or light filtering like <code>/products?category=shoes&amp;size=10</code>. The parameters are right there in the URL string. They are easy to inspect, easy to bookmark, and perfectly suited for HTTP caching layers.</p>
<p>However, modern applications rarely stay that simple. Imagine you are building an advanced search engine or an enterprise reporting tool. Your user wants to filter products based on a highly complex query: they need items within a specific category, priced within a dynamic range, matching an array of tags, excluding clearance items, and sorted by a complex multi-column rule.</p>
<p>If you try to map that into a standard <code>GET</code> request, the URL starts looking like an encoded mess:</p>
<pre><code class="language-shell">GET /products/search?filter%5Bcategory%5D=laptops&amp;filter%5Bprice%5D%5Bmax%5D=1500&amp;filter%5Btags%5D%5B0%5D=ssd&amp;filter%5Btags%5D%5B1%5D=business&amp;sort=price&amp;order=desc HTTP/1.1
Host: query-demo-self.vercel.app
</code></pre>
<p>This approach presents four distinct architectural problems outlined in RFC 10008:</p>
<ul>
<li><p><strong>URL Length Limitations:</strong> While the HTTP specification doesn't enforce a hard limit on URL length, the real-world infrastructure handling your traffic does. Browsers, load balancers, corporate firewalls, and Content Delivery Networks (CDNs) often truncate or reject URLs that exceed a certain size—frequently capping out around 8,000 octets (bytes). If a user pastes a massive list of IDs into a search filter, a <code>GET</code> request will simply fail.</p>
</li>
<li><p><strong>Privacy and Data Leakage:</strong> URLs are designed to be visible. Because query strings live directly inside the request target, they are automatically logged in plain text by web servers, stored in browser history files, and passed along in <code>Referer</code> headers to third-party scripts. If your search query contains sensitive filters—like an account number, a medical symptom, or personal data—that information leaks across your infrastructure.</p>
</li>
<li><p><strong>Encoding Overhead:</strong> Expressing complex data structures inside a target URI is highly inefficient because of the overhead of percent-encoding brackets, spaces, and special characters, making network payloads harder to read and debug.</p>
</li>
<li><p><strong>Resource Dilution:</strong> Encoding every single query combination directly into the request URI effectively casts every unique combination of query inputs as entirely distinct resources on the web, cluttering resource organization.</p>
</li>
</ul>
<p>Faced with these limits, many developers ask a logical question: <em>Why not just send a request body inside a standard</em> <code>GET</code> <em>request?</em></p>
<p>The short answer is that the web infrastructure treats <code>GET</code> bodies as having <strong>no defined semantic meaning</strong>. Because of this ambiguity, the ecosystem handles it completely inconsistently. Some proxy servers silently strip the body before passing the request forward. Other API gateways reject the request entirely, while some frameworks ignore the body. Altering how <code>GET</code> processes bodies today would break millions of legacy network systems.</p>
<h2>Why POST Isn't the Ideal Replacement</h2>
<p>Because <code>GET</code> with a body is unusable in the wild, the industry settled on an alternative workaround: using <code>POST</code> for complex searches.</p>
<p>When you use <code>POST</code>, all your complex filters travel cleanly inside the request body. You can send a beautifully structured JSON payload of any size, avoiding URL length limits and keeping sensitive terms out of system access logs.</p>
<pre><code class="language-shell">POST /products/search HTTP/1.1
Host: query-demo-self.vercel.app
Content-Type: application/json

{
  "category": "Laptops",
  "price": { "max": 1500 },
  "tags": ["ssd", "business"],
  "sort": { "field": "price", "order": "desc" }
}
</code></pre>
<p>This works around the immediate structural limits, but it introduces a major flaw into your API's network behavior: <code>POST</code> <strong>is semantically unsafe and non-idempotent.</strong></p>
<p>In the language of HTTP, a method is considered <strong>safe</strong> if it does not change the state of the resource on the server. A method is <strong>idempotent</strong> if executing it multiple times produces the identical result and state as executing it exactly once.</p>
<p>Because <code>POST</code> is designed for state-altering actions, like creating a new database record or processing a credit card payment, network intermediaries must assume that every <code>POST</code> request changes something on your server. This structural assumption breaks two core performance optimizations:</p>
<ul>
<li><p><strong>Caches Are Bypassed:</strong> Because a <code>POST</code> request is assumed to modify state, edge networks, CDNs, and browser caches will not cache the response by default. If a thousand users execute the exact same complex dashboard query within a minute, your origin server must compute that identical database search a thousand times.</p>
</li>
<li><p><strong>Automatic Retries Are Blocked:</strong> If a network connection drops mid-request while a browser is sending a <code>POST</code> request, the browser cannot safely retry it automatically. Doing so might cause a double-charge or a duplicate record. The browser is forced to display a warning to the user, even if the backend endpoint was completely read-only.</p>
</li>
</ul>
<h2>How QUERY Solves the Problem</h2>
<p>The <code>QUERY</code> method defined in RFC 10008 directly resolves this tension. It serves as a semantic hybrid: it provides the robust request body capability of a <code>POST</code>, while strictly maintaining the safe, idempotent, and cacheable contracts of a <code>GET</code>.</p>
<p>When an endpoint uses <code>QUERY</code>, the protocol guarantees to every proxy, browser, and CDN along the route that the operation is entirely read-only. If a connection drops, your client library can seamlessly replay the request without risk. If an edge proxy sees identical query criteria come through a second time, it can serve a cached response immediately without waking up your origin database.</p>
<h2>Syntax and Request Examples</h2>
<p>To see how this works in practice, let's look at a raw HTTP representation of a <code>QUERY</code> request alongside its response.</p>
<h3>The Request</h3>
<pre><code class="language-shell">QUERY /products/search HTTP/1.1
Host: query-demo-self.vercel.app
Content-Type: application/json
Accept: application/json
Accept-Query: application/json

{
  "category": "Laptops",
  "brands": ["TechNova"],
  "price": { "min": 500, "max": 1500 }
}
</code></pre>
<p>Unlike a classic <code>GET</code>, the <code>QUERY</code> method requires a <code>Content-Type</code> header. The specification explicitly dictates that if a client sends a <code>QUERY</code> request without a <code>Content-Type</code>, or if the header doesn't match the format of the body, the server MUST fail the request.</p>
<p>Notice the <code>Accept-Query</code> header. This allows the server to advertise exactly which query formats it knows how to parse for that endpoint—whether that is JSON, SQL, or a custom format.</p>
<h3>The Response</h3>
<pre><code class="language-shell">HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: public, max-age=3600
Content-Location: /products/search/results/a1b2c3d4
Location: /products/search/stored-queries/42

{
  "count": 2,
  "query": {
    "brands": ["TechNova"],
    "category": "Laptops",
    "price": { "max": 1500, "min": 500 }
  },
  "results": [
    {
      "id": 1,
      "name": "UltraBook Pro 14",
      "category": "Laptops",
      "brand": "TechNova",
      "price": 1299,
      "rating": 4.8,
      "stock": 32,
      "discount": 15,
      "available": true,
      "tags": ["ssd", "lightweight", "business"],
      "specs": { "cpu": "Intel Core Ultra 7", "ram": 32, "storage": 1024, "color": "Silver" }
    },
    {
      "id": 3,
      "name": "OfficeBook Air",
      "category": "Laptops",
      "brand": "TechNova",
      "price": 799,
      "rating": 4.3,
      "stock": 50,
      "discount": 20,
      "available": true,
      "tags": ["office", "budget"],
      "specs": { "cpu": "Intel Core i5", "ram": 16, "storage": 512, "color": "Gray" }
    }
  ]
}
</code></pre>
<p>The server processes the request payload, runs the search logic, and returns a standard <code>200 OK</code> status with the data array.</p>
<p>The inclusion of the <code>Content-Location</code> and <code>Location</code> headers are incredibly powerful features of the specification:</p>
<ul>
<li><p><code>Content-Location</code><strong>:</strong> Provides a direct URL pointing to a resource representing these specific <em>results</em>. A client can perform a standard <code>GET</code> request directly on that URL later to fetch the same snapshot.</p>
</li>
<li><p><code>Location</code><strong>:</strong> Points to the <em>equivalent resource</em> representing the query itself. A client can send a <code>GET</code> request to this URI to repeat the same search operation later without resending the large query body.</p>
</li>
</ul>
<h2>Practical Code Examples</h2>
<p>Let's look at how to implement and use the <code>QUERY</code> method using modern development tools.</p>
<h3>1. Sending a QUERY Request using cURL</h3>
<p>You can test a <code>QUERY</code> endpoint directly from your terminal using standard <code>cURL</code>. We explicitly set the method to <code>QUERY</code>, provide the mandatory content headers, and pass our payload using the data flag.</p>
<pre><code class="language-shell">curl -X QUERY https://query-demo-self.vercel.app/products/search \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"category": "Laptops", "tags": ["gaming"]}'
</code></pre>
<p><strong>Why this approach is useful:</strong> Because <code>QUERY</code> is officially registered in the IANA HTTP methods registry, modern command-line utilities and network tools handle it natively without needing custom transport hacks.</p>
<h3>2. Fetch API Example (JavaScript)</h3>
<p>Modern web browsers allow you to pass arbitrary method names into the standard <code>Fetch API</code>. Here is how you can issue a <code>QUERY</code> request from client-side code:</p>
<pre><code class="language-javascript">async function searchProducts() {
  const queryPayload = {
    category: 'Laptops',
    price: { min: 1000 },
    sort: { field: 'price', order: 'desc' }
  };

  try {
    const response = await fetch('https://query-demo-self.vercel.app/products/search', {
      method: 'QUERY',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      },
      body: JSON.stringify(queryPayload)
    });

    if (!response.ok) {
      throw new Error(`HTTP error: ${response.status}`);
    }

    const data = await response.json();
    console.log(`Found ${data.count} items:`, data.results);
    return data;
  } catch (error) {
    console.error('Failed to execute search:', error);
  }
}
</code></pre>
<p>This script looks almost identical to a standard <code>POST</code> implementation. However, behind the scenes, the browser knows that this request is safe and idempotent. If the network drops while waiting for the response, the underlying network engine can automatically handle retrying the operation safely.</p>
<h2>QUERY vs GET vs POST</h2>
<p>Choosing the right tool for the job becomes much easier when we contrast the three methods side by side:</p>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Architectural Property</strong></p></td><td><p><strong>GET</strong></p></td><td><p><strong>POST</strong></p></td><td><p><strong>QUERY</strong></p></td></tr><tr><td><p><strong>Request Body Allowed</strong></p></td><td><p>No (Undefined Semantics)</p></td><td><p>Yes</p></td><td><p><strong>Yes</strong></p></td></tr><tr><td><p><strong>Safe (Read-Only)</strong></p></td><td><p>Yes</p></td><td><p>Potentially No</p></td><td><p><strong>Yes</strong></p></td></tr><tr><td><p><strong>Idempotent (Safe to Retry)</strong></p></td><td><p>Yes</p></td><td><p>Potentially No</p></td><td><p><strong>Yes</strong></p></td></tr><tr><td><p><strong>Default Cacheable</strong></p></td><td><p>Yes</p></td><td><p>No (Only future GET/HEAD)</p></td><td><p><strong>Yes (Requires Body-Aware Keying)</strong></p></td></tr><tr><td><p><strong>Data Payload Location</strong></p></td><td><p>URL Query String</p></td><td><p>Request Body</p></td><td><p><strong>Request Body</strong></p></td></tr><tr><td><p><strong>Primary Use Case</strong></p></td><td><p>Simple, short resource reads</p></td><td><p>Resource creation &amp; mutation</p></td><td><p><strong>Complex, large, or private reads</strong></p></td></tr></tbody></table>

<h2>Current Support and Considerations</h2>
<p>While RFC 10008 represents a massive leap forward for clean API design, deploying it in production requires an honest look at the current state of network infrastructure. Because it is a newer standard, adoption is an evolving process across the web ecosystem.</p>
<h3>The Caching Challenge</h3>
<p>Traditional caching proxies and CDNs use the request URL as the unique identifier—the "cache key"—to look up a stored response. For <code>QUERY</code>, this model breaks down completely. Two requests to <code>/products/search</code> could contain entirely different JSON filtering bodies, meaning they require completely different responses.</p>
<p>For <code>QUERY</code> caching to work safely, edge proxies must update their caching engines to fold the request body into the cache key calculation. While backend frameworks and language ecosystems have moved quickly to add native <code>QUERY</code> support, many edge networks and CDNs are still updating their systems to handle body-aware caching at scale.</p>
<h3>Security and Middleboxes</h3>
<p>Older Web Application Firewalls (WAFs) and load balancers operate on strict allowlists of classic HTTP verbs (<code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>DELETE</code>). When an unconfigured security gateway encounters a <code>QUERY</code> request, it might react unpredictably—either blocking the traffic outright as a potential exploit attempt, or failing to inspect the body because it treats it like a standard <code>GET</code>.</p>
<p>Additionally, a <code>QUERY</code> request from user agents implementing Cross-Origin Resource Sharing (CORS) will automatically require a "preflight" <code>OPTIONS</code> request, as <code>QUERY</code> does not belong to the basic set of CORS-safelisted methods.</p>
<h2>Best Practices for Adopting QUERY</h2>
<p>If you want to start integrating the <code>QUERY</code> method into your current systems, use these design strategies to ensure a smooth transition:</p>
<ul>
<li><p><strong>Don't Replace Simple GETs:</strong> If a request fits cleanly within a standard URL without hitting size limits or exposing sensitive data, leave it as a <code>GET</code>. <code>QUERY</code> is designed to solve the limits of complex parameters, not to deprecate standard endpoint paths.</p>
</li>
<li><p><strong>Leverage Discovery Methods:</strong> Use the <code>OPTIONS</code> method to return an <code>Allow: GET, QUERY, OPTIONS, HEAD</code> header, cleanly signaling to clients that the resource supports the new verb.</p>
</li>
<li><p><strong>Handle Content Negotiation Failures Gracefully:</strong> Follow the RFC guidelines for client errors. If a query syntax is correct but points to a non-existent field or table, return a <code>422 Unprocessable Content</code> status code. If the media type itself isn't supported, return a <code>415 Unsupported Media Type</code> along with the <code>Accept-Query</code> header.</p>
</li>
<li><p><strong>Validate the Content-Type Early:</strong> Always place a validation guard at the top of your route handlers. If an incoming <code>QUERY</code> request omits the <code>Content-Type</code> header, reject it immediately with a <code>400 Bad Request</code> or <code>415</code> status code to stay aligned with the official specification rules.</p>
</li>
</ul>
<h2>Key Takeaways</h2>
<p>The introduction of the <code>QUERY</code> method solves a structural compromise that engineers have accepted for decades. By merging the data payload flexibility of a request body with the strict safety and idempotency rules of a read operation, it removes the need to misuse <code>POST</code> for complex searches.</p>
<p>While full integration across every browser, WAF, and CDN proxy will take time, the establishment of RFC 10008 gives developers a standardized foundation to build cleaner, more predictable, and more efficient APIs.</p>
]]></content:encoded></item><item><title><![CDATA[The Ultimate Guide to the Java Singleton Pattern]]></title><description><![CDATA[Imagine a country. A country can have millions of citizens, thousands of politicians, and hundreds of cities, but it only ever has one President at a time. Whenever a citizen, a foreign diplomat, or a]]></description><link>https://blog.ashutoshkrris.in/the-ultimate-guide-to-the-java-singleton-pattern</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/the-ultimate-guide-to-the-java-singleton-pattern</guid><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Java]]></category><category><![CDATA[interview]]></category><category><![CDATA[design patterns]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Wed, 24 Jun 2026 07:34:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/b1b4f605-f8ad-47cb-9931-04fdda7f2283.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Imagine a country. A country can have millions of citizens, thousands of politicians, and hundreds of cities, but it only ever has <strong>one President</strong> at a time. Whenever a citizen, a foreign diplomat, or a journalist wants to address the head of state, they all route their communication to that exact same person.</p>
<p>In software engineering, there are certain objects in our systems that must operate exactly like this President. We need exactly <em>one</em> instance of them, and we need a global point of access to reach them.</p>
<p>This is the <strong>Singleton Design Pattern</strong>.</p>
<p>Singleton is one of the “Gang of Four” (GoF) creational design patterns. It is arguably the most famous design pattern in existence and simultaneously one of the most controversial. Whether you are building a configuration manager, a printer spooler, or a centralised logger, Singleton ensures that all parts of your application share the same state and resources.</p>
<blockquote>
<p><strong>Interview Tip:</strong> Interviewers love asking about Singletons because it is a “gateway pattern”. A simple question about Singleton quickly opens the door to complex discussions about multi-threading, the Java Memory Model, class loaders, and reflection.</p>
</blockquote>
<h2>What is a Singleton Class?</h2>
<p>By formal definition, the Singleton pattern ensures that a class has <strong>only one instance</strong> and provides a <strong>global point of access</strong> to that instance.</p>
<h3>Key Characteristics:</h3>
<ol>
<li><p><strong>One Instance:</strong> The JVM will only ever contain one object of this class per classloader.</p>
</li>
<li><p><strong>Self-Managed:</strong> The class itself is responsible for keeping track of its sole instance.</p>
</li>
<li><p><strong>Global Access:</strong> The class provides a public static method to allow clients to retrieve the instance.</p>
</li>
</ol>
<h4><strong>Benefits:</strong></h4>
<ul>
<li><p>Prevents other objects from instantiating their own copies.</p>
</li>
<li><p>Conserves memory by sharing a single object.</p>
</li>
<li><p>Centralises the state and management of a shared resource.</p>
</li>
</ul>
<h4><strong>Drawbacks:</strong></h4>
<ul>
<li><p>Introduces global state into an application.</p>
</li>
<li><p>Tightly couples code, making unit testing difficult.</p>
</li>
<li><p>Can cause hidden bottlenecks in heavily multi-threaded environments.</p>
</li>
</ul>
<h2>Why Do We Need Singleton?</h2>
<p>Why not just create new objects every time we need them using the <code>new</code> keyword?</p>
<p>Creating objects in Java has a cost: memory allocation, CPU cycles, and Garbage Collection overhead. But more importantly, some objects represent resources that are strictly singular by nature.</p>
<p>Practical use cases include:</p>
<ul>
<li><p><strong>Logger:</strong> If every class creates its own logger object, writing to a single log file concurrently can result in overwrites and corrupted data. A Singleton logger coordinates all file writes.</p>
</li>
<li><p><strong>Configuration Manager:</strong> You want to read an <code>application.properties</code> file once, parse it into memory, and share it across the app. You don't want to hit the disk every time a component needs a configuration value.</p>
</li>
<li><p><strong>Connection Pool Manager:</strong> Database connections are expensive. A Singleton pool manager creates a fixed number of connections and hands them out to threads, ensuring the database isn't overwhelmed.</p>
</li>
<li><p><strong>Cache Manager:</strong> An in-memory cache must be shared. If every service instantiates its own cache, they won't see each other's cached data!</p>
</li>
</ul>
<h2>Core Principles Behind Singleton</h2>
<p>To build a Singleton, we must actively prevent developers from using the <code>new</code> keyword. To do this, we rely on three core principles:</p>
<ol>
<li><p><strong>Private Constructor:</strong> If a constructor is <code>private</code>, no other class can call it. This absolutely prevents external instantiation.</p>
</li>
<li><p><strong>Static Instance Variable:</strong> We store the single created instance in a <code>private static</code> field. Making it <code>static</code> ties the variable to the <em>class</em> itself rather than to any specific object instance.</p>
</li>
<li><p><strong>Public Access Method:</strong> We expose a <code>public static</code> method (usually named <code>getInstance()</code>). This method acts as the gatekeeper. When called, it checks if the instance exists. If it does, it returns it. If it doesn't, it creates it, stores it, and <em>then</em> returns it.</p>
</li>
</ol>
<h2>Basic Singleton Implementation: Eager Initialization</h2>
<p>We now understand the theory, but how do we actually implement it? Let's start with the most straightforward approach: asking the Java Virtual Machine (JVM) to create the object the moment our application starts. This is known as Eager Initialization.</p>
<pre><code class="language-java">public class EagerSingleton {

    // Instance is created when the class is loaded by the JVM.
    // This guarantees that only one instance exists.
    private static final EagerSingleton instance = new EagerSingleton();

    // Private constructor prevents external instantiation.
    private EagerSingleton() {
        System.out.println("Eager Singleton initialized.");
    }

    // Global access point to the single instance.
    public static EagerSingleton getInstance() {
        return instance;
    }
}
</code></pre>
<p>When you write an Eager Singleton, the object is brought to life the exact moment the Java ClassLoader loads the class into memory, long before any user interacts with your application. Because the JVM internally guarantees that class loading is thread-safe, we do not have to worry about concurrency issues. The <code>final</code> keyword adds an extra layer of security, ensuring that once the instance is assigned, it can never be accidentally overwritten.</p>
<p>When a developer eventually calls <code>getInstance()</code>, the method simply acts as a courier, instantly returning the pre-created object.</p>
<h3>The Problem</h3>
<p>While eager initialization is elegantly simple and perfectly thread-safe, it introduces a glaring problem: <strong>Memory Leak Potential</strong>. Imagine this Singleton is a complex cache manager that pre-loads large data structures, or a connection pool holding open network sockets. With Eager Initialization, the JVM allocates these heavy resources immediately on startup, even if the user never accesses the feature that requires them. We are holding precious memory hostage.</p>
<p>To solve this problem, we need to delay the creation of the object until the precise moment it is requested.</p>
<h2>Lazy Initialization: Saving Memory</h2>
<p>If Eager Initialization wastes memory, the logical evolution is Lazy Initialization. Here, we defer the object creation until a developer actively calls our access method for the very first time.</p>
<pre><code class="language-java">public class LazySingleton {

    // Instance is not created until it is first requested.
    private static LazySingleton instance;

    // Private constructor prevents external instantiation.
    private LazySingleton() {
        System.out.println("Lazy Singleton initialized.");
    }

    // Creates the instance only when it is needed for the first time.
    public static LazySingleton getInstance() {

        // If no instance exists, create one.
        if (instance == null) {
            instance = new LazySingleton();
        }

        // Return the existing instance.
        return instance;
    }
}
</code></pre>
<p>In this implementation, we drop the <code>final</code> keyword and stop assigning the variable at the top. The intelligence of this pattern lives entirely within the <code>getInstance()</code> method.</p>
<p>When an application component requests the Singleton for the first time, our method evaluates the null check. Since the application just started, the instance variable is indeed null. The code gracefully steps inside the conditional block, invokes the private constructor to allocate the necessary memory, and assigns the newly minted object to our static variable. Finally, it returns the instance to the caller.</p>
<p>The beauty of this approach shines during the <em>second</em> request. When another component calls the method, the null check evaluates to false. The application completely skips the creation logic and instantly hands back the exact same object. We have successfully solved our memory problem. The object only exists if it is actually used.</p>
<p>However, we have unknowingly walked right into a catastrophic architectural bug. While this basic implementation works flawlessly in a simple, single-threaded script, modern Java applications operate in highly concurrent environments.</p>
<h3>The Problem</h3>
<p>To understand why our Lazy Singleton fails in the real world, we must take a brief detour into concurrency.</p>
<p>A <strong>thread</strong> is an independent path of execution within your application. <strong>Concurrency</strong> occurs when multiple threads execute tasks simultaneously, driven by a multi-core CPU. A <strong>race condition</strong> is a software bug that happens when the outcome of a program depends on the unpredictable timing of how the CPU schedules these threads.</p>
<p>Let's visualize a scenario where Thread A and Thread B try to access our <code>LazySingleton</code> at the exact same millisecond.</p>
<table>
<thead>
<tr>
<th>Time</th>
<th>Thread A</th>
<th>Thread B</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>calls <code>getInstance()</code></td>
<td>calls <code>getInstance()</code></td>
</tr>
<tr>
<td>2</td>
<td>evaluates: <code>if (instance == null)</code></td>
<td></td>
</tr>
<tr>
<td>3</td>
<td>(Result: TRUE)</td>
<td>evaluates: <code>if (instance == null)</code></td>
</tr>
<tr>
<td>4</td>
<td>-- CPU Context Switch --</td>
<td>(Result: TRUE)</td>
</tr>
<tr>
<td>5</td>
<td></td>
<td>enters if block</td>
</tr>
<tr>
<td>6</td>
<td>enters if block</td>
<td><code>instance = new LazySingleton()</code></td>
</tr>
<tr>
<td>7</td>
<td><code>instance = new LazySingleton()</code></td>
<td></td>
</tr>
<tr>
<td>8</td>
<td>returns Instance #1</td>
<td>returns Instance #2</td>
</tr>
</tbody></table>
<p>Because CPU context switching is unpredictable, Thread A evaluated the condition as true but was paused before it could actually create the object. Thread B then ran, also saw a null instance, and proceeded to create the object. When Thread A woke back up, it blindly continued into the <code>if</code> block and created a <em>second</em> instance.</p>
<p>Our Singleton pattern has been utterly shattered. We now have two separate objects floating in memory, violating the primary rule of the pattern. We need a way to control the traffic.</p>
<h2>Synchronized Method: The Traffic Jam</h2>
<p>The most intuitive way to prevent threads from colliding in Java is to force them to form an orderly line. We do this by applying the <code>synchronized</code> keyword to our method.</p>
<pre><code class="language-java">public class SyncMethodSingleton {

    // Instance is created only when it is first requested.
    private static SyncMethodSingleton instance;

    // Private constructor prevents external instantiation.
    private SyncMethodSingleton() {}

    // Synchronized method ensures that only one thread can execute the instance creation logic at a time.
    public static synchronized SyncMethodSingleton getInstance() {

        // Create the instance if it does not already exist.
        if (instance == null) {
            instance = new SyncMethodSingleton();
        }

        // Return the single shared instance.
        return instance;
    }
}
</code></pre>
<p>By adding <code>synchronized</code> to the method signature, we turn <code>getInstance()</code> into a locked room. Only one thread can possess the key to this room at any given time. If Thread A is inside evaluating the null check, Thread B is physically blocked from entering the method and must wait patiently outside. By the time Thread B is allowed in, Thread A has finished creating the instance. Thread B will correctly see that the instance is no longer null and will simply return it.</p>
<p>Our Singleton is finally thread-safe. But we have traded a correctness problem for a massive performance bottleneck.</p>
<h3>The Problem</h3>
<p>Think about the lifecycle of this Singleton. We only truly need synchronization for the very first thread, the one that actually executes the constructor. Once the object exists, every subsequent read operation is perfectly safe to happen concurrently. Yet, because we synchronized the entire method, every single time any part of our app wants to read from this Singleton, threads are forced to wait in line. In a high-traffic enterprise application, this single lock can choke your entire system's throughput.</p>
<h2>Double-Checked Locking</h2>
<p>We need a scalpel, not a sledgehammer. What if we only synchronize the exact block of code that creates the object, and only apply that lock if the object hasn't been created yet? This brings us to a highly performant idiom known as Double-Checked Locking (DCL).</p>
<pre><code class="language-java">public class DoubleCheckedSingleton {

    // Volatile ensures that changes made by one thread
    // are immediately visible to other threads.
    private static volatile DoubleCheckedSingleton instance;

    // Private constructor prevents external instantiation.
    private DoubleCheckedSingleton() {}

    public static DoubleCheckedSingleton getInstance() {

        // First check avoids synchronization after the instance has already been created.
        if (instance == null) {

            // Only one thread can enter this block at a time.
            synchronized (DoubleCheckedSingleton.class) {

                // Second check ensures another thread has not already created the instance while waiting.
                if (instance == null) {
                    instance = new DoubleCheckedSingleton();
                }
            }
        }

        // Return the single shared instance.
        return instance;
    }
}
</code></pre>
<p>The execution flow here is brilliant. When threads call <code>getInstance()</code>, they immediately hit the first <code>if</code> check. This check is completely lock-free. If the instance already exists, threads grab the object and go, operating at maximum speed without ever encountering a lock.</p>
<p>If the instance is null, threads proceed to the <code>synchronized</code> block. Suppose Thread A wins the lock while Thread B waits. Thread A enters the block and performs a <em>second</em> null check. Why? Because while Thread A was waiting to acquire the lock, another thread might have sneaked in and created the instance! The second check ensures we don't accidentally overwrite an instance that was just established. Thread A creates the object, assigns it, and releases the lock. When Thread B finally gets the lock, it hits the second check, sees the newly created object, and safely skips the creation logic.</p>
<blockquote>
<p><strong>Pro Tip:</strong> Historically, prior to Java 5, Double-Checked Locking was considered a broken anti-pattern. The Java Memory Model was not strict enough, allowing the JVM to wildly reorder instructions in ways that caused crashes. Today, thanks to the keyword we are about to discuss, DCL is a highly respected, production-ready solution.</p>
</blockquote>
<h2>Understanding the <code>volatile</code> Keyword</h2>
<p>You likely noticed the word <code>volatile</code> attached to the instance variable in our Double-Checked Locking example. If you forget this single word during an interview or in production code, your Singleton is fundamentally broken. To understand why, we must explore the physical architecture of modern hardware.</p>
<p>Modern multi-core CPUs are incredibly fast, much faster than the main system RAM. To bridge this speed gap, CPUs utilize ultra-fast local caches (L1, L2, L3) for each core. When a thread modifies a variable, it often writes that change to its local CPU cache to save time, rather than updating the main memory immediately.</p>
<p>This creates a severe <strong>Visibility Problem</strong>. If Thread A, running on Core 1, initializes the Singleton and saves it to its local cache, Thread B, running on Core 2, might look at the main memory, see that the variable is still null, and proceed to create a duplicate instance!</p>
<p>Furthermore, to optimize performance, the Java Compiler and the CPU are allowed to perform <strong>Instruction Reordering</strong>. The simple line <code>instance = new DoubleCheckedSingleton();</code> is actually three separate JVM instructions:</p>
<ol>
<li><p>Allocate blank memory for the object.</p>
</li>
<li><p>Initialize the object (run the constructor).</p>
</li>
<li><p>Assign the memory reference to the <code>instance</code> variable.</p>
</li>
</ol>
<p>The JVM is fully allowed to reorder these steps to 1 -&gt; 3 -&gt; 2. If it does, Thread A allocates memory and assigns the reference (Step 3). At this exact microsecond, the <code>instance</code> variable is no longer null, but the object is completely empty because the constructor hasn't run yet. Thread B comes along, hits the lock-free first check, sees a non-null instance, and tries to invoke a method on a half-baked object, triggering a catastrophic application crash.</p>
<p>The <code>volatile</code> keyword acts as an iron-clad disciplinarian. First, it solves the visibility problem by forcing all reads and writes of the variable to bypass the CPU cache and go straight to Main Memory. Second, it establishes a strict <em>happens-before</em> relationship, entirely forbidding the JVM from reordering the initialization instructions. The object <em>must</em> be fully constructed before the reference is published to the rest of the application.</p>
<h2>The Bill Pugh Singleton: A JVM Masterclass</h2>
<p>Double-Checked Locking is incredibly performant, but as we just saw, it requires a deep, uncomfortable understanding of memory visibility, instruction reordering, and the <code>volatile</code> keyword. It is verbose and notoriously easy to implement incorrectly.</p>
<p>William Pugh, a renowned computer scientist, proposed a much more elegant solution. He realized we could trick the JVM's internal class-loading mechanics into handling the synchronization for us, allowing us to achieve perfect lazy loading without using <code>synchronized</code> blocks or <code>volatile</code> variables.</p>
<pre><code class="language-java">public class BillPughSingleton {
    
    private BillPughSingleton() {}

    private static class SingletonHelper {
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }

    public static BillPughSingleton getInstance() {
        return SingletonHelper.INSTANCE;
    }
}
</code></pre>
<p>This approach utilizes a static inner helper class, and its brilliance lies in the JVM's lazy class-loading rules. When the application starts and the <code>BillPughSingleton</code> class is loaded into memory, the JVM explicitly ignores the inner <code>SingletonHelper</code> class. It does not load it, and therefore does not instantiate the Singleton object. We have achieved perfect lazy loading; zero memory is wasted.</p>
<p>The magic occurs only when a developer calls <code>getInstance()</code>. This method attempts to access <code>SingletonHelper.INSTANCE</code>. The moment that explicit reference is made, the JVM is forced to load the inner class and initialize its static fields.</p>
<p>Because the Java language specification strictly guarantees that the initialization of a class is thread-safe, the JVM natively locks the process behind the scenes. Multiple threads can call the method simultaneously, but the JVM will perfectly orchestrate the creation of a single object, returning it to all threads with blazing speed. For years, the Bill Pugh approach has been considered the gold standard of Java Singletons.</p>
<h2>The Reflection Problem</h2>
<p>Our Bill Pugh Singleton is lazy, fast, and thread-safe. But in the hands of a curious or malicious developer, it can easily be destroyed. Java provides a powerful API called Reflection, which allows developers to inspect and manipulate code at runtime, completely ignoring access modifiers.</p>
<pre><code class="language-java">public class ReflectionBreaker {
    public static void main(String[] args) {
        BillPughSingleton instanceOne = BillPughSingleton.getInstance();
        BillPughSingleton instanceTwo = null;

        try {
            Constructor[] constructors = BillPughSingleton.class.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                // We bypass the private constructor!
                constructor.setAccessible(true);
                instanceTwo = (BillPughSingleton) constructor.newInstance();
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println(instanceOne == instanceTwo); // Prints: false
    }
}
</code></pre>
<p>By retrieving the private constructor and explicitly calling <code>setAccessible(true)</code>, Reflection allows us to forcibly instantiate a second object, entirely breaking the Singleton contract.</p>
<p>To defend against this, we must add aggressive boilerplate logic inside our constructor. We must check if an instance already exists, and if it does, forcefully throw a <code>RuntimeException</code> to crash the rogue process before it can instantiate the duplicate.</p>
<h2>The Serialization Problem</h2>
<p>In distributed applications, you often need to convert an object into a byte stream (Serialization) to send it over a network or save it to a database, and later reconstruct it (Deserialization).</p>
<p>If your Singleton class implements the <code>Serializable</code> interface, you are in for a nasty surprise. During the deserialization process, the JVM reads the byte stream and automatically creates a <strong>brand-new instance</strong> of your Singleton, completely bypassing your private constructor.</p>
<p>To patch this vulnerability, you must provide a special, deeply hidden JVM hook method called <code>readResolve()</code>.</p>
<pre><code class="language-java">protected Object readResolve() {
    return getInstance();
}
</code></pre>
<p>When the JVM deserializes an object, it searches for the <code>readResolve()</code> method. If it finds it, the JVM immediately discards the freshly created duplicate object and instead returns whatever <code>readResolve()</code> dictates, in our case, the true Singleton instance.</p>
<h2>The Cloning Problem</h2>
<p>Similarly, if your Singleton accidentally implements the <code>Cloneable</code> interface (perhaps inherited from a parent class), a developer could invoke the <code>.clone()</code> method to create a shallow copy of your precious instance.</p>
<p>To prevent this, you must explicitly override the clone method and throw an exception to block the operation.</p>
<pre><code class="language-java">@Override
protected Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException("Cloning of a Singleton is strictly prohibited.");
}
</code></pre>
<h2>The Enum Singleton: The Indestructible Solution</h2>
<p>Protecting a Singleton from Reflection, Serialization, and Cloning requires writing a lot of defensive, ugly boilerplate code. Joshua Bloch, the legendary author of <em>Effective Java</em>, looked at this mess and proposed a radically simple alternative: just use a Java Enum.</p>
<pre><code class="language-java">public enum EnumSingleton {
    INSTANCE;

    public void doSomething() {
        System.out.println("Enum Singleton is working flawlessly.");
    }
}
</code></pre>
<p>That is the entire code. You access it anywhere in your application by calling <code>EnumSingleton.INSTANCE.doSomething()</code>.</p>
<p>Why is this considered the ultimate Singleton? Because the Java language specification treats enums like royalty. The JVM inherently guarantees that an enum value is instantiated exactly once in a given Java program. It naturally provides flawless thread-safety.</p>
<p>If a hacker tries to use Reflection to duplicate an enum, the internal <code>java.lang.reflect.Constructor</code> class explicitly detects it and throws an <code>IllegalArgumentException</code>. Furthermore, Java's serialization mechanism is custom-built to ensure enum values are never duplicated during deserialization, so no <code>readResolve()</code> hack required. While it does not support lazy loading, the Enum Singleton is the absolute safest, most robust way to implement the pattern in core Java.</p>
<h2>Singleton and Class Loaders: An Enterprise Reality</h2>
<p>There is a frequently overlooked enterprise concept that catches even senior engineers off guard. The standard rule of the GoF Singleton pattern states: "There is only one instance per JVM." <strong>This is technically false in Java.</strong></p>
<p>The accurate statement is: <strong>There is only one instance per ClassLoader.</strong></p>
<p>In Enterprise Java architectures (like Apache Tomcat, JBoss, or WebSphere), applications are packaged as WAR or EAR files. These heavy application servers use hierarchical, isolated class loaders. If your Singleton class is packaged into two separate WAR files deployed on the same Tomcat server, they will be loaded by two different class loaders. The JVM will treat them as entirely different classes. You will end up with multiple Singleton instances running in the exact same JVM memory space!</p>
<p>To resolve this in traditional enterprise environments, the Singleton class must be placed in a shared library folder (like Tomcat's <code>lib</code> directory) so it is loaded by a common parent class loader, ensuring true JVM-wide singularity.</p>
<h2>Comparing All Singleton Implementations</h2>
<p>To synthesize everything we have built, let's look at how the different approaches stack up against each other:</p>
<table style="min-width:150px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Implementation</strong></p></td><td><p><strong>Thread-Safe?</strong></p></td><td><p><strong>Lazy Loaded?</strong></p></td><td><p><strong>Performance</strong></p></td><td><p><strong>Reflection Safe?</strong></p></td><td><p><strong>Serialization Safe?</strong></p></td></tr><tr><td><p><strong>Eager</strong></p></td><td><p>Yes</p></td><td><p>No</p></td><td><p>High</p></td><td><p>Needs manual check</p></td><td><p>Needs <code>readResolve</code></p></td></tr><tr><td><p><strong>Basic Lazy</strong></p></td><td><p>No</p></td><td><p>Yes</p></td><td><p>High</p></td><td><p>Needs manual check</p></td><td><p>Needs <code>readResolve</code></p></td></tr><tr><td><p><strong>Synchronized</strong></p></td><td><p>Yes</p></td><td><p>Yes</p></td><td><p>Very Low</p></td><td><p>Needs manual check</p></td><td><p>Needs <code>readResolve</code></p></td></tr><tr><td><p><strong>Double-Checked</strong></p></td><td><p>Yes</p></td><td><p>Yes</p></td><td><p>High</p></td><td><p>Needs manual check</p></td><td><p>Needs <code>readResolve</code></p></td></tr><tr><td><p><strong>Bill Pugh</strong></p></td><td><p>Yes</p></td><td><p>Yes</p></td><td><p>High</p></td><td><p>Needs manual check</p></td><td><p>Needs <code>readResolve</code></p></td></tr><tr><td><p><strong>Enum</strong></p></td><td><p>Yes</p></td><td><p>No</p></td><td><p>High</p></td><td><p><strong>Yes (Native)</strong></p></td><td><p><strong>Yes (Native)</strong></p></td></tr></tbody></table>

<h2>Singleton vs Static Utility Class</h2>
<p>A common debate among developers is why we go through the trouble of creating Singletons when we could just create a class full of <code>static</code> methods and variables, much like the <code>java.lang.Math</code> class.</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Feature</strong></p></td><td><p><strong>Singleton Object</strong></p></td><td><p><strong>Static Utility Class</strong></p></td></tr><tr><td><p><strong>Object Orientation</strong></p></td><td><p>It is a real object on the heap.</p></td><td><p>It is not an object; just a collection of functions.</p></td></tr><tr><td><p><strong>Interfaces</strong></p></td><td><p>Can implement interfaces (e.g., <code>ILogger</code>).</p></td><td><p>Cannot implement interfaces.</p></td></tr><tr><td><p><strong>Inheritance</strong></p></td><td><p>Can extend base classes and utilize polymorphism.</p></td><td><p>Cannot participate in traditional OOP inheritance.</p></td></tr><tr><td><p><strong>State Management</strong></p></td><td><p>Excellent for holding and managing complex state.</p></td><td><p>Extremely poor. Static state is difficult to track and clear.</p></td></tr><tr><td><p><strong>Testing</strong></p></td><td><p>Can be mocked dynamically in testing frameworks.</p></td><td><p>Very difficult to mock; requires advanced static mockers.</p></td></tr></tbody></table>

<p><strong>The Verdict:</strong> If you are simply grouping stateless, utility helper methods together, use a Static Class. If your component needs to manage state, maintain active connections, or adhere to interface-driven design, you must use a Singleton.</p>
<h2>Singleton in the Spring Framework</h2>
<p>If you are a modern Java developer, you are almost certainly using the Spring Framework. In Spring, the framework manages the lifecycle of your objects for you using a concept called Inversion of Control (IoC).</p>
<p>When you annotate a class with <code>@Service</code> or <code>@Component</code>, Spring essentially registers it as a Singleton Bean.</p>
<p><strong>Interview Tip:</strong> It is crucial to understand the subtle difference between a GoF Java Singleton and a Spring Singleton. A classic Java Singleton guarantees one instance per <em>ClassLoader</em>. A Spring Singleton guarantees one instance per <em>ApplicationContext</em> (the Spring IoC container). If you instantiate two ApplicationContexts within the same JVM, Spring will happily create two instances of your globally intended <code>@Service</code>.</p>
<p>Because Spring handles the instantiation via Dependency Injection (DI), you completely abandon private constructors, static variables, and <code>getInstance()</code> boilerplates. You simply write standard, testable Java classes, and let Spring enforce the single-instance rule.</p>
<h2>Singleton in Modern Cloud Applications</h2>
<p>In the modern era of cloud-native development, applications are rarely deployed on a single massive server. They are broken down into microservices and deployed across dozens of identical Kubernetes pods.</p>
<p>This fundamentally shifts the concept of a Singleton. A Java Singleton only exists within the memory boundary of <em>one specific pod</em>. If you build an in-memory Singleton Cache Manager, Pod A and Pod B will have entirely disconnected, conflicting caches.</p>
<p>If you require a true "Cluster-wide Singleton", a resource that must be perfectly singular across a massive distributed network, a Java-level Singleton will fail you. You must step out of the JVM and rely on distributed systems tools like Redis for centralized caching, ZooKeeper for consensus, or database-level row locks for state management.</p>
<h2>When NOT to Use Singleton (The Anti-Pattern Debate)</h2>
<p>Despite its fame, many architects view the manual Singleton as an <strong>Anti-Pattern</strong> when misused.</p>
<p>The primary criticism is <strong>Hidden Dependencies</strong>. If an <code>OrderProcessor</code> class buries a call to <code>PaymentGateway.getInstance()</code> deep inside a method, the dependency is hidden. With modern Dependency Injection, dependencies are clearly declared in the constructor, making the code self-documenting.</p>
<p>Furthermore, Singletons introduce <strong>Global State</strong>. If Thread A mutates data inside a Singleton, and Thread B fails because of that mutation, tracking down who changed the state is a debugging nightmare.</p>
<p>Finally, they create a <strong>Testing Nightmare</strong>. Because Singletons persist for the entire life of the JVM, unit tests can pollute each other. Test 1 might alter the Singleton, causing Test 2 to fail simply because it expected a clean slate.</p>
<h2>Common Mistakes Developers Make</h2>
<ul>
<li><p><strong>Overusing the Pattern:</strong> Creating a Singleton just to pass arbitrary user data between two screens in a UI application. This creates severe memory leaks and fundamentally breaks architectural boundaries.</p>
</li>
<li><p><strong>Ignoring Thread Safety:</strong> Deploying a basic Lazy Singleton to a production web server, leading to silent, untraceable race conditions.</p>
</li>
<li><p><strong>Storing User Context:</strong> A Singleton is global. Never, under any circumstances, store user-specific context (like an Authentication Token or a Shopping Cart) in a Singleton, or User A will start seeing User B's private data!</p>
</li>
</ul>
<h2>Best Practices for Modern Development</h2>
<ol>
<li><p><strong>Prefer Dependency Injection:</strong> Lean heavily on frameworks like Spring, Guice, or CDI to manage singleton lifecycles. Let the framework do the heavy lifting of instantiation and sharing.</p>
</li>
<li><p><strong>Design for Interfaces:</strong> Even if you write a manual Singleton, have it implement an interface. This allows you to inject mock implementations during unit testing, preserving testability.</p>
</li>
<li><p><strong>Keep it Stateless:</strong> The safest Singletons are those that perform operations (like routing or logging) without holding onto mutable, changing data. A stateless Singleton cannot cause state-corruption bugs.</p>
</li>
</ol>
<h2>Common Interview Questions and Answers</h2>
<p>Interviewers use the Singleton pattern as a gateway to test your deeper understanding of Java mechanics. Here is how to navigate the most common questions:</p>
<p><strong>Q: What exactly is a Singleton Pattern?</strong><br /><strong>A:</strong> It is a creational design pattern ensuring a class has only one instance per class loader, and it provides a global point of access to that single instance.</p>
<p><strong>Q: How do you prevent the cloning of a Singleton?</strong><br /><strong>A:</strong> You must explicitly override the <code>clone()</code> method inherited from the <code>Object</code> class and throw a <code>CloneNotSupportedException</code>.</p>
<p><strong>Q: Why is Double-Checked Locking broken if you forget the</strong> <code>volatile</code> <strong>keyword?</strong><br /><strong>A:</strong> Because of instruction reordering and CPU caching visibility. Without <code>volatile</code>, the CPU might allocate memory for the object and assign the reference before the constructor actually runs. Another thread could see a non-null reference, try to use it, and crash because the object is only partially constructed.</p>
<p><strong>Q: What is the fundamental difference between a Spring Singleton and a Java GoF Singleton?</strong><br /><strong>A:</strong> A traditional GoF Java Singleton strictly guarantees one instance per JVM ClassLoader. A Spring Singleton guarantees one instance per ApplicationContext container. You can have multiple Spring containers in a single JVM.</p>
<p><strong>Q: Why does Joshua Bloch recommend the Enum Singleton?</strong><br /><strong>A:</strong> Because the JVM natively handles all the heavy lifting. Enums are thread-safe by default, the JVM prevents instantiation via reflection (<code>Constructor.newInstance</code> blocks enums), and it natively handles serialization without needing the <code>readResolve()</code> hack.</p>
<p><strong>Q: Is the Singleton pattern considered an anti-pattern?</strong><br /><strong>A:</strong> It can be. Manual Singletons introduce global state, hide class dependencies, and make isolated unit testing extremely difficult because state carries over between test cases. Modern practices heavily favor Dependency Injection over manual GoF Singletons.</p>
<h2>Conclusion</h2>
<p>The Singleton class in Java represents a fascinating journey through software architecture. What starts as a simple concept, a private constructor and a static variable, rapidly escalates into a deep dive into the Java Memory Model, multi-threading race conditions, CPU cache visibility, JVM class loading mechanics, and modern enterprise architecture.</p>
<p>While modern frameworks like Spring have largely abstracted away the need to manually write complex Bill Pugh or Double-Checked Singletons, understanding <em>how</em> to write them, <em>why</em> concurrency breaks them, and <em>how</em> the JVM interprets them is an absolute hallmark of a Senior Java Engineer.</p>
<p>Remember: A pattern is only as effective as its application. Use Singletons sparingly, prioritize statelessness, lean on Dependency Injection wherever possible, and always respect the dangers of global state.</p>
]]></content:encoded></item><item><title><![CDATA[The Complete Guide to Agile: How Modern Software is Actually Built]]></title><description><![CDATA[Imagine planning a massive cross country road trip. Three solid months are spent mapping out every single turn. Every hotel is pre booked. The exact amount of gas needed is calculated down to the gall]]></description><link>https://blog.ashutoshkrris.in/the-complete-guide-to-agile-how-modern-software-is-actually-built</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/the-complete-guide-to-agile-how-modern-software-is-actually-built</guid><category><![CDATA[software development]]></category><category><![CDATA[agile]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Mon, 15 Jun 2026 15:11:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/ba68351b-f140-41ba-ac04-929ef6ced4b4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Imagine planning a massive cross country road trip. Three solid months are spent mapping out every single turn. Every hotel is pre booked. The exact amount of gas needed is calculated down to the gallon. The car is packed, the engine starts, and the trip begins.</p>
<p>But on day two, a major highway is closed for a five year construction project. Then the car gets a flat tire. Later on, a beautiful national park appears on the horizon, but stopping is impossible because the rigid, pre planned schedule will not allow a two hour delay.</p>
<p>That perfect plan is suddenly completely useless.</p>
<p>Building software is incredibly similar to that road trip. For decades, software engineers tried to build applications by planning every single technical detail before writing a single line of code. They assumed the world would stand perfectly still while they worked. But in the real world, customers change their minds. Competitors release new products. Markets evolve. A pandemic hits. Entire business models shift overnight.</p>
<p>The absolute hardest part of building software is never the code itself. The real challenge is managing the constant, relentless changes to what the code is supposed to do.</p>
<p>Whether you're a bootcamp graduate preparing for interviews, a junior engineer stepping onto a new team, or a product manager trying to understand the engineering department, this guide will walk through exactly how modern software gets built. Grab a coffee. We are going to explore the history, the failures, and the modern solutions of software engineering.</p>
<h2>The Core Problem of Software Engineering</h2>
<p>If a family wants to build a house, they hire an architect. Blueprints are drawn up, load bearing walls are calculated, and the plans are handed to a construction crew. The crew builds exactly what is on the paper. Halfway through building the roof, the homeowner cannot suddenly walk up and ask the crew to move the concrete foundation ten feet to the left. The laws of physics prevent it.</p>
<p>But in the software industry, stakeholders ask for the digital equivalent of moving the foundation every single day.</p>
<p>Code is completely invisible. Because it is not made of bricks, steel, or wood, non technical people assume it is incredibly easy to change. A manager might think that changing a checkout page from a single step to a three step process is just a matter of changing a few colors. But behind the scenes, that change might require ripping apart the database, rewriting the security protocols, and changing how payment gateways communicate.</p>
<p>As an application grows, changing a core piece of logic late in the game can bring the whole system crashing down. The software industry desperately needed a way to handle these constant changes without burning out developers or throwing millions of dollars into the garbage.</p>
<h2>The Early Days and the Software Crisis</h2>
<p>In the 1960s and 1970s, writing code was basically the Wild West. Computers took up entire rooms, and code was written on physical punch cards. Developers would get a vague idea of what a business needed and just start typing.</p>
<p>This simple code and fix approach worked fine for tiny scripts. But computers were getting more powerful. Businesses wanted massive banking networks. Governments wanted global satellite tracking. The software required to run these systems was thousands of times more complex than anything humans had ever built before.</p>
<p>This led to a period historians actually call the Software Crisis. This guessing game of writing code without a structured plan led to absolutely massive failures. Projects were delivered years late. Budgets skyrocketed by millions of dollars. The tech industry realized it needed serious discipline.</p>
<p>To find a solution, engineers looked at the only other industries successfully building massive, complex things. They looked at manufacturing and construction. They decided to borrow the highly structured, step by step assembly line processes used to build skyscrapers and cars, and they pasted those exact rules right onto software engineering.</p>
<h2>Understanding the Waterfall Model</h2>
<p>The result of borrowing from the construction industry was the Waterfall Model. Born in the 1970s, it quickly became the absolute gold standard for managing software projects everywhere in the world.</p>
<p>Waterfall is a straight, unbending line. One phase must be completely finished, signed off, and stamped before work can flow down to the next phase. Just like a real waterfall in nature, water does not flow backward up the mountain. It is incredibly difficult and expensive to go back to a previous step once a phase is finished.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/1a400c9b-fbb8-448c-be1e-d2984b858637.jpg" alt="The 5 Stages of the Waterfall Method" style="display:block;margin:0 auto" />

<p>To really understand how heavy this process is, look at how a typical Waterfall project operates over a two year timeline.</p>
<p>First is the <strong>Requirements</strong> phase. Business analysts spend six months talking to executives. They write a 300 page manual detailing every single button, text field, error message, and database interaction the software will ever need. Developers do not write a single line of code during this time.</p>
<p>Next is the <strong>Design</strong> phase. Software architects take that massive manual and draw up technical blueprints. They decide on the servers, the programming languages, and the database structures.</p>
<p>Then comes <strong>Implementation</strong>. The developers are finally brought in. They take the blueprints, lock themselves in a room for a year, and translate those documents into actual code.</p>
<p>After the code is fully written, the <strong>Testing</strong> phase begins. A separate team of quality assurance testers takes the finished application and tries to break it. They document all the bugs and send them back to the developers.</p>
<p>Finally, the <strong>Deployment</strong> phase happens. The massive software package is burned onto a CD or pushed to a server, and the customer sees it for the very first time.</p>
<blockquote>
<p>In short, each process phase must be <strong>completed</strong> before the start of the next one and there is no overlapping.</p>
</blockquote>
<h2>Why Waterfall Worked Just Fine</h2>
<p>It is a very common trend for modern web developers to laugh at Waterfall and call it a complete failure. But that is not fair at all. Waterfall provides amazing predictability, deep and rigorous documentation, and crystal clear milestones. Managers love it because they know exactly what they are paying for upfront.</p>
<p>Think about building a simple promotional website for a blockbuster movie. The release date is locked. The cast list is finalized. The branding is already heavily trademarked. The requirements are absolutely never going to change midway through. A simple, linear Waterfall approach works perfectly there.</p>
<p>Waterfall is also still heavily used and required today in life or death industries. When a bug in a web application happens, a user has to refresh their browser. When a bug in an airplane engine happens, a disaster occurs. Aerospace engineers absolutely must use Waterfall. Medical device manufacturers creating pacemaker firmware use it. The process guarantees that massive documentation is created for legal and safety compliance.</p>
<h2>The Spectacular Failures of Waterfall</h2>
<p>Waterfall is great for airplanes, but it started to fail spectacularly when companies used it to build consumer software, banking apps, and government databases. The rigidity caused massive headaches.</p>
<p>The FBI Sentinel project is one of the most famous examples of this failure. Back in 2001, the FBI was still tracking criminals using paper files. They realized they needed a modern digital database. They called the project the Virtual Case File system. They used a strict textbook Waterfall approach. They spent months writing massive requirement documents. Contractors spent years writing code based on those documents.</p>
<p>By the time the software was finally tested and ready to look at years later, the world had changed. The technology was completely outdated. The system was so full of bugs and so hard to use that the FBI entirely scrapped it. They threw away over 170 million dollars and had zero working software to show for it.</p>
<p>Why did this happen? Waterfall has three massive flaws when dealing with complex, shifting projects.</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>The Problem</strong></p></td><td><p><strong>The Painful Reality</strong></p></td><td><p><strong>Real World Analogy</strong></p></td></tr><tr><td><p><strong>Delayed Feedback</strong></p></td><td><p>Customers do not see the product until the very end. If the requirements were wrong from the start, a year of work is completely wasted.</p></td><td><p>Baking a ten tier wedding cake without ever letting the couple taste the frosting first.</p></td></tr><tr><td><p><strong>Impossible Changes</strong></p></td><td><p>If a competitor launches a cool new feature, pivoting to add it requires rewriting hundreds of pages of documentation.</p></td><td><p>Trying to change the final destination of a massive freight train after the steel tracks are already bolted to the ground.</p></td></tr><tr><td><p><strong>Late Testing</strong></p></td><td><p>Testing only happens at the very end of the timeline. By then, architectural bugs are so deeply embedded in the code that fixing them requires tearing the whole system down.</p></td><td><p>Building an entire car, painting it, and installing leather seats before checking if the engine actually starts.</p></td></tr></tbody></table>

<p>In technical interviews, questions about traditional project management often pop up. The most critical things to remember about Waterfall are its extreme lack of flexibility, the danger of late feedback, and the high risk of finding massive bugs when the budget is already empty.</p>
<h2>The Industry Shift That Changed Everything</h2>
<p>By the late 1990s, the internet was exploding. The dot com boom meant companies could no longer wait two years to release a product. Back in the day, software was physically shipped in boxes to electronics stores. If a company released a new word processor, they had a year before the competitor could print and ship their own CDs.</p>
<p>The internet destroyed that safety net. Now, a startup in a garage could launch a competing product globally overnight. Customer expectations were moving at lightning speed. Businesses needed to release updates every month, not every two years.</p>
<p>Software developers were miserable. They were being forced to blindly follow giant, dusty requirement documents that were basically useless by the time they were printed. They knew the features they were coding were already outdated, but the Waterfall process forced them to build it anyway.</p>
<p>In February 2001, seventeen highly frustrated software engineers met at a ski resort in Snowbird, Utah. This group included developers who had been quietly experimenting with lighter, faster ways of writing code throughout the 1990s. They were tired of the heavy documentation and the endless management bureaucracy.</p>
<p>Over food, drinks, and intense debate, they realized they all shared the exact same core beliefs about how software should actually be built. They wanted a system focused on people, working code, and adaptability.</p>
<p>They wrote down those shared beliefs on a simple webpage. They called it the Agile Manifesto.</p>
<h2>Deep Dive into The Agile Manifesto</h2>
<p>The biggest trap new developers and even experienced managers fall into is thinking Agile is a strict set of rules. It is not a rulebook. It is not a process. It is a philosophy. It boils down to four simple, powerful values. Understanding these four sentences is the key to understanding modern software development.</p>
<h3><strong>Individuals and interactions over processes and tools</strong></h3>
<p>In the old Waterfall days, if a developer needed a database password from the security team, the process required them to submit a formal ticket, wait for a manager to approve it, and wait three days for an email reply. The tool was the ticketing system. The process was the approval chain. The result was a developer sitting idle for three days.</p>
<p>Agile says that simply walking over to the security team's desk, or sending a direct message on a chat app, is vastly superior. Human conversation solves problems faster than any rigid system. This does not mean throwing away tracking tools like Jira. It simply means human communication must always come before blind obedience to a process.</p>
<h3>Working software over comprehensive documentation</h3>
<p>Imagine a developer spending three full weeks writing a beautiful, perfectly formatted thirty page document describing exactly how a new shopping cart button will work. The business team signs off on the document. But a month later, user testing shows that customers actually want a swipe feature instead of a button. That thirty page document is instantly turned into trash.</p>
<p>The best way to show progress to a client is to put a working application in their hands. An ugly prototype with three working buttons provides far more value and feedback than a hundred page document describing an app that does not exist yet. Agile values building the thing over describing the thing.</p>
<h3>Customer collaboration over contract negotiation</h3>
<p>In traditional development, a company signs an ironclad contract with a software agency. Six months later, the company realizes they need the app to support mobile devices. The software agency waves the original contract in their face and demands an extra hundred thousand dollars to make the change. This creates a toxic, adversarial relationship.</p>
<p>Agile demands that the development team and the customer sit on the same side of the table. The team should show the customer their progress constantly. When the customer asks for a change, the team works with them to swap out features and adapt, rather than fighting over legal documents.</p>
<h3>Responding to change over following a plan</h3>
<p>A plan is a wonderful thing to have. But a plan is based on the information available at the time it was written. As a team builds software, they learn new things. They discover that a feature is harder to build than expected. They discover that users hate the color scheme.</p>
<p>When new information arrives, an Agile team changes the plan. If the market shifts, the team shifts with it. Sticking to a plan that is proven to be wrong is a recipe for building a useless product.</p>
<h2>The Twelve Agile Principles Explained</h2>
<p>Behind those four values are twelve guiding principles. Reading them as a plain list can feel very academic. To truly grasp them, it is best to see how they apply to a real world scenario.</p>
<p>Imagine a team of developers building a brand new mobile application for booking local concert tickets.</p>
<p><strong>Principle 1: Satisfy the customer through early and continuous delivery of valuable software.</strong><br />Instead of making music fans wait a full year for a massive app with social media integration, merchandise stores, and VIP programs, the team releases a very basic version in month one that just lets people buy a simple ticket. The customers get value immediately.</p>
<p><strong>Principle 2: Welcome changing requirements, even late in development.</strong><br />Three months before launch, a new digital wallet becomes wildly popular in the city. Instead of complaining that the new wallet integration was not in the original design document, the team embraces the change. They know that adding this feature will give their app a competitive edge.</p>
<p><strong>Principle 3: Deliver working software frequently.</strong><br />The team updates the app with small, safe improvements every two weeks. They never go months without pushing new code to the users.</p>
<p><strong>Principle 4: Business people and developers must work together daily.</strong><br />The marketing director does not just throw requirements over a brick wall to the coding team. The marketing team and the developers have a quick chat every single morning to ensure the technical work aligns with the business goals.</p>
<p><strong>Principle 5: Build projects around motivated individuals and trust them.</strong><br />Management gives the developers the goal, but they do not micromanage the code. If the team says they need to use a specific database technology to make the search faster, management trusts their technical expertise.</p>
<p><strong>Principle 6: Face to face conversation is the most efficient way to convey information.</strong><br />When a complex bug appears in the payment gateway, the frontend developer and the backend developer jump on a quick video call to debug it together. They do not waste time sending long, confusing email chains back and forth.</p>
<p><strong>Principle 7: Working software is the primary measure of progress.</strong><br />A manager asks for a status update. The team does not show the manager a slide presentation showing the project is forty percent complete. They pull out a phone and actually show the manager the working concert search bar.</p>
<p><strong>Principle 8: Maintain a sustainable working pace.</strong><br />This is one of the most important principles for developer mental health. The team plans their work carefully so they can leave the office at five o'clock. There are no heroic weekend coding sessions. There is no endless crunch time. A burned out developer writes terrible code.</p>
<p><strong>Principle 9: Continuous attention to technical excellence.</strong><br />The team does not rush to build sloppy features just to hit a deadline. They take the time to write clean, maintainable code because they know messy code will slow them down drastically in the future.</p>
<p><strong>Principle 10: Simplicity is essential.</strong><br />Simplicity is defined here as the art of maximizing the amount of work not done. The team avoids building a complex artificial intelligence recommendation engine because a simple chronological list of upcoming concerts works perfectly fine for early users.</p>
<p><strong>Principle 11: The best architectures emerge from self organizing teams.</strong><br />The database structure is not handed down by an executive who has not written code in ten years. The developers working on the ground floor collaborate and design the architecture together.</p>
<p><strong>Principle 12: Regularly reflect and adjust behavior.</strong><br />Every two weeks, the entire team grabs coffee and talks about what is slowing them down. If they realize their testing process takes too long, they brainstorm a way to automate it for the next cycle. They are constantly fine tuning their own workflow.</p>
<h2>Core Agile Concepts</h2>
<p>To fully master Agile thinking, it is vital to understand the difference between two specific concepts. Those concepts are Incremental delivery and Iterative delivery.</p>
<p><strong>Incremental</strong> means building a product piece by completely finished piece. Imagine building a castle out of Lego blocks. A solid wall is built first. Then a tall tower is built. Then a wooden drawbridge is added. Every individual piece is fully complete before moving on to the next.</p>
<p><strong>Iterative</strong> means refining a product over time. Imagine a master painter creating a portrait. They do not paint a photorealistic left eye and then move on to a photorealistic nose. They sketch a rough outline in pencil. Then they block in basic background colors. Then they add shading. Finally, they add fine details to the face. The whole painting improves in layers.</p>
<p>Agile development requires using both concepts together.</p>
<p>Consider someone opening a brand new restaurant.</p>
<p>If they use the old Waterfall method, they would spend two years designing a massive fifty item menu, hiring a huge staff, taking out loans, and opening the doors. They cross their fingers and pray the neighborhood likes the food.</p>
<p>If they use an Incremental and Iterative Agile approach, they start by renting a small food truck. They only sell tacos, burgers, and fries. That is the incremental part. They ask their first dozen customers how the food tastes. Customers say the salsa is not hot enough. The very next day, the chef adds jalapeños to the recipe based on that feedback. That is the iterative part. They learn, adapt, and grow safely.</p>
<h3>The Agile Lifecycle</h3>
<p>Unlike the straight, unbending line of Waterfall, Agile operates in a continuous loop. Teams build software in short, predictable cycles. These cycles are commonly called Sprints, and they typically last between one and four weeks.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/2be2e97f-bfe6-41f7-a49a-04d5e378d1d9.jpg" alt="The Agile Lifecycle emphasizes a continuous feedback loop." style="display:block;margin:0 auto" />

<p>A normal lifecycle flows logically.</p>
<p>First, a big master wish list of everything the app needs is created. This is the <strong>Backlog</strong>.<br />Then, the team holds <strong>Planning</strong>. They look at the big list and pick a small, realistic chunk of work to finish in the next two weeks.<br />Next comes <strong>Development and Testing</strong>. The team writes the code and checks for bugs continuously during the two weeks.<br />Finally, the cycle ends with a <strong>Review and Retrospective</strong>. The working feature is shown to the customer to secure immediate feedback, and the team discusses how to communicate better in the upcoming cycle.</p>
<h2>The Scrum Framework</h2>
<p>Agile is a mindset. It tells teams to be flexible, but it does not tell them exactly how to organize their Tuesday morning. That is where Scrum comes into play.</p>
<p>Scrum is the most popular framework used to actually execute Agile in the real world. If Agile is the broad concept of eating healthy and exercising, Scrum is the highly specific Monday through Friday gym routine followed to ensure the results actually happen.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/35157c72-e158-43cc-84fe-9719f2b760a0.jpg" alt="Visualizing the Scrum Development Methodology" style="display:block;margin:0 auto" />

<h3>Scrum Roles</h3>
<p>Think of a software development team like a professional movie crew.</p>
<ul>
<li><p><strong>The Product Owner:</strong> This person is the Film Director. They have the ultimate vision for the product. They spend their time talking to users and deciding what features will bring the most value to the business. They prioritize the backlog. They decide what needs to be built next.</p>
</li>
<li><p><strong>The Scrum Master:</strong> This person is the Film Producer. They ensure everyone understands and follows the Scrum rules. They protect the team from outside distractions. If a developer needs a software license approved, the Scrum Master handles the bureaucracy. They clear roadblocks so developers can simply focus on writing great code.</p>
</li>
<li><p><strong>The Development Team:</strong> These are the Actors and the Camera Crew. They do the actual heavy lifting. They write the code, design the databases, and create the user interfaces. They are highly skilled professionals, and they decide exactly how the technical work gets accomplished.</p>
</li>
</ul>
<h3>Scrum Artifacts</h3>
<p>Artifacts are simply the tangible lists and deliverables the team uses to keep track of reality.</p>
<ul>
<li><p><strong>Product Backlog:</strong> The giant master to do list containing every single feature, bug fix, and idea for the entire product.</p>
</li>
<li><p><strong>Sprint Backlog:</strong> The tiny, highly focused to do list pulled from the master list, meant to be completed in the current two week cycle.</p>
</li>
<li><p><strong>The Increment:</strong> The actual, working, fully tested piece of software produced at the very end of the cycle.</p>
</li>
</ul>
<h3>Scrum Events</h3>
<p>A Sprint is the heartbeat of the Scrum framework. Inside that two week Sprint, four specific meetings take place. The industry calls these meetings ceremonies.</p>
<ol>
<li><p><strong>Sprint Planning:</strong> On the very first day, the entire team gathers. The Product Owner presents the most important items from the backlog. The developers discuss the technical challenges and agree on what they can realistically finish before the cycle ends.</p>
</li>
<li><p><strong>Daily Scrum:</strong> Every single morning, the team stands together for a strict fifteen minute limit. Everyone answers three simple questions. What did I complete yesterday? What will I work on today? Is anything currently blocking my progress? This is a quick coordination meeting, not a deep technical discussion.</p>
</li>
<li><p><strong>Sprint Review:</strong> On the final day of the cycle, the team demonstrates the working software to executives, stakeholders, or customers. This is the moment to gather live feedback and celebrate finished work.</p>
</li>
<li><p><strong>Sprint Retrospective:</strong> After the review, the team sits down privately, without managers or stakeholders. They talk honestly about team dynamics. They discuss what went perfectly, what caused frustration, and concrete steps to make the next Sprint smoother.</p>
</li>
</ol>
<h2>Kanban and The Power of the Andon Cord</h2>
<p>Scrum is highly structured and widely used, but it is definitely not the only way to manage Agile work. Kanban is another hugely popular approach. The history of Kanban is fascinating because it does not come from the software world at all. It comes directly from Toyota car factories in Japan in the 1940s.</p>
<p>Instead of working in strict two week Sprints, Kanban focuses entirely on continuous, smooth flow. Teams use a visual board divided into columns.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/731c94b9-79b0-4b96-8e65-dd6159471c40.jpg" alt="A standard Kanban board visualizes the flow of work." style="display:block;margin:0 auto" />

<p>The absolute golden rule of Kanban is Work In Progress Limits. A team might establish a strict rule that only a maximum of three tasks are allowed in the In Progress column at any given time. A developer cannot pull a fourth task from the backlog until one of those three active tasks is completely moved to the Done column.</p>
<p>To understand why this is so powerful, look at a famous story from the automotive industry. In the early 1980s, General Motors operated a massive car plant in Fremont, California. The culture was toxic, and the process was driven by a relentless push for quantity over quality. The assembly line never stopped. Cars routinely rolled off the line with missing steering wheels or engines installed backward. It was a complete disaster.</p>
<p>Toyota formed a joint venture to take over that exact plant, renaming it NUMMI. Toyota brought in the Kanban philosophy and a physical tool called the Andon Cord. This was a rope hanging above the assembly line. Toyota told the factory workers that if they saw a single defect, a single loose screw, or a single misaligned door, they should pull the cord and stop the entire factory line immediately.</p>
<p>The American executives thought this was absolute madness. They assumed the line would constantly be stopped and they would never produce a single car.</p>
<p>But a profound thing happened. Because the workers stopped the line to fix problems immediately instead of letting defects pile up at the end of the day, quality skyrocketed. By forcing a strict limit on moving bad work forward, that exact same plant, with the exact same workers, quickly became one of the most productive and high quality car factories in America.</p>
<p>In software, Kanban boards and Work In Progress limits act like the Andon Cord. Limiting active tasks prevents developers from constantly switching context, keeps code quality incredibly high, and stops massive traffic jams of bugs from piling up right before release.</p>
<h2>Scrum vs Kanban</h2>
<p>Deciding between these two powerful frameworks usually comes down to the specific nature of the team's work.</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Feature</strong></p></td><td><p><strong>Scrum Approach</strong></p></td><td><p><strong>Kanban Approach</strong></p></td></tr><tr><td><p><strong>Timeline</strong></p></td><td><p>Strict cycles, usually two weeks.</p></td><td><p>Continuous flow. No set cycles.</p></td></tr><tr><td><p><strong>Roles</strong></p></td><td><p>Requires a Product Owner and Scrum Master.</p></td><td><p>No official or specific roles required.</p></td></tr><tr><td><p><strong>Changing Work</strong></p></td><td><p>New work cannot be added during a Sprint.</p></td><td><p>New work can be added anytime space opens up.</p></td></tr><tr><td><p><strong>Best Used For</strong></p></td><td><p>Building brand new products with a highly stable team.</p></td><td><p>Customer support teams, constant bug fixing, or highly unpredictable priorities.</p></td></tr></tbody></table>

<p>A large percentage of real world engineering teams actually blend these together. They value the daily standup communication of Scrum, but they prefer the continuous flow board of Kanban to visualize work. This popular hybrid approach is often referred to as <strong>Scrumban</strong>.</p>
<h2>The Psychology of Agile Estimation</h2>
<p>In the traditional Waterfall days, managers would walk up to a developer's desk and ask exactly how many hours a new database migration would take to build. The developer would sweat and guess forty hours. But then an unexpected server configuration error would appear, the task would drag out to eighty hours, and management would be furious.</p>
<p>Agile accepts a scientifically proven psychological truth. Human beings are terrible at guessing exact timeframes. People are overly optimistic (and really good at assuming things), they ignore risks, and they fail to account for interruptions.</p>
<p>However, humans are surprisingly brilliant at relative estimation.</p>
<p>If someone is asked exactly how many minutes it takes to hike to the top of a specific mountain, their guess will likely be completely wrong. But if someone points to a massive, jagged mountain and then points to a tiny, gentle hill, every person on earth instantly knows which one will require more effort.</p>
<p>Instead of guessing hours, Agile teams use Story Points to measure the overall effort, risk, and complexity of a task relative to other tasks. Teams almost universally use the Fibonacci sequence of numbers for this, primarily using 1, 2, 3, 5, 8, and 13. The gaps between the numbers get larger to reflect that bigger tasks carry vastly more uncertainty.</p>
<ul>
<li><p>A 1 Point task might be fixing a simple spelling error on the homepage.</p>
</li>
<li><p>A 5 Point task might be building a new secure login screen.</p>
</li>
<li><p>A 13 Point task might involve integrating a legacy, messy third party payment system.</p>
</li>
</ul>
<h3>Planning Poker</h3>
<p>Teams estimate these points together using an exercise called <strong>Planning Poker</strong>. The Product Owner explains a new feature. Every developer on the team looks at the task and secretly picks a point value card. Then, everyone reveals their numbers at the exact same time.</p>
<p>Hiding the cards until the reveal prevents an anchoring bias. If the loudest, most senior developer shouts out a tiny number before anyone else thinks, the junior developers will just agree out of fear. But with simultaneous revealing, if the senior developer holds up a 2 and a junior developer holds up an 8, a fascinating conversation happens. The team stops and discusses. Usually, the junior developer spotted a security risk the senior missed, or the senior knows a hidden shortcut in the code. They discuss the realities until the entire team agrees on a number.</p>
<h2>Writing Great User Stories</h2>
<p>Agile teams flatly refuse to write massive technical requirement documents. Instead, they write User Stories. A user story describes a piece of functionality strictly from the perspective of the actual human being interacting with the software.</p>
<p>The industry standard format for writing these is simple but powerful.</p>
<blockquote>
<p><strong>As a [type of user], I want [some goal], so that [some benefit].</strong></p>
</blockquote>
<p>Consider a team building a new ridesharing application. A terrible requirement looks like this: Build a GPS tracking toggle boolean in the Postgres database. A great user story looks like this: As a parent using the app late at night, I want to share my live ride status with a trusted friend, so that someone knows I am safe on my way home.</p>
<p>The first requirement dictates a technical solution. The second story explains the human problem, allowing the developers to invent the best technical solution.</p>
<p>A story is never allowed to be considered complete until it has clear Acceptance Criteria. This is a simple, bulleted checklist that proves the story is fully functioning. For the ridesharing story, the acceptance criteria checklist might look like this:</p>
<ul>
<li><p>A share button is visible on the active ride screen.</p>
</li>
<li><p>Clicking the button generates a unique, encrypted web link.</p>
</li>
<li><p>Sending the link allows a friend to open a web browser and see a moving car icon on a map without logging in.</p>
</li>
<li><p>The link automatically expires the moment the ride ends.</p>
</li>
</ul>
<h2>Metrics and The Danger of Goodhart's Law</h2>
<p>Charts and data help Agile teams understand if their processes are healthy. Velocity is the most common metric. Velocity is simply the total number of story points a team finishes in one single Sprint. If a team consistently finishes around 40 points every cycle, they should realistically plan to take on 40 points in the next cycle. It creates predictability.</p>
<p>Teams track this using a <strong>Burndown Chart</strong>. This is a line graph showing how much work is left in the Sprint. The line trends downward every day as tasks move to the Done column, ideally hitting zero on the final day.</p>
<p>But there is a massive, dangerous trap hidden inside these metrics.</p>
<p>There is an old adage in economics known as Goodhart's Law. It states that when a measure becomes a target, it ceases to be a good measure.</p>
<p>Velocity is intended purely as an internal planning tool to help developers protect their time. It is not a grade. It is not a performance review. If a manager walks into a room and demands that the team increase their velocity from 40 points to 60 points next week to prove they are working harder, the entire system collapses.</p>
<p>The developers will not magically type faster. Instead, they will engage in point inflation. They will simply look at a task that requires 2 points of effort and label it as a 5 point task. They will label 5 point tasks as 8 point tasks. Suddenly, the chart shows the team completing 70 points. Management is happy, the chart looks beautiful, but absolutely zero extra software was actually built. Weaponizing metrics destroys trust and invalidates the data completely.</p>
<h2>Agile Testing and the DevOps Revolution</h2>
<p>In the old Waterfall era, testing was a massive, isolated phase saved for the very end of the year. In Agile, testing happens constantly, every single day.</p>
<p>The industry calls this Shift Left testing. If someone looks at a standard project timeline moving from left to right, the testing process is literally moved way over to the left side so it happens much earlier. Developers write automated testing scripts right alongside their feature code.</p>
<p>This continuous testing mindset naturally led to the creation of DevOps. DevOps is essentially the automated technical engine that makes Agile delivery actually possible. In the early 2000s, Friday evenings were a nightmare for developers. Getting everyone's code merged together manually resulted in broken servers and hours of debugging known as merge hell.</p>
<p>Today, DevOps practices solve this.</p>
<ul>
<li><p><strong>Continuous Integration:</strong> Developers merge their new code into a central repository several times a single day. The moment the code is uploaded, automated server scripts compile the code and run hundreds of tests instantly to ensure nothing broke. It functions exactly like an auto save feature in a complex video game.</p>
</li>
<li><p><strong>Continuous Deployment:</strong> Once the code cleanly passes those automated checks, it gets pushed directly to the live production servers without a human ever having to manually click an upload button.</p>
</li>
</ul>
<p>Instead of an entire company holding its breath for a massive, terrifying software update every six months, modern engineering teams release tiny, safe updates ten to fifty times a day without the customer even noticing the transition.</p>
<h2>How Agile Looks in Real Organizations</h2>
<p>Reading a clean, academic textbook about Agile and then walking into a real tech company can be a highly confusing experience. Very few companies handle the process perfectly.</p>
<p><strong>Startups:</strong> Startups are incredibly fast and famously chaotic. They love Agile because pivoting rapidly is essential for their financial survival. However, they often completely skip the formal meetings. There might not be a dedicated Scrum Master. Developers simply collaborate rapidly across the room to get features out the door before funding runs dry.</p>
<p><strong>Product Companies:</strong> This is usually the sweet spot for a great developer experience. Mid sized tech companies producing software as a service typically have dedicated Product Owners, incredibly clean automated deployment pipelines, and very solid, predictable Scrum routines.</p>
<p><strong>Enterprises:</strong> Giant global banks, insurance companies, and massive legacy corporations often struggle deeply with Agile. They attempt to make ten thousand developers Agile all at exactly the same time. To do this, they adopt massive frameworks like the Scaled Agile Framework. For many developers on the ground floor, these heavy enterprise frameworks feel suspiciously like the old, rigid Waterfall model dressed up in modern Agile terminology.</p>
<h2>Genuine Challenges and Criticisms of Agile</h2>
<p>To provide a truly complete guide, it is necessary to be completely realistic. Agile is not a perfect utopia. Many modern developers voice serious, valid frustrations with how the philosophy is implemented today.</p>
<p>The most common problem plaguing the industry is Agile Theater. This happens when a company proudly claims they are completely Agile simply because they use tracking software like Jira and force developers to stand in a circle every morning. But behind the scenes, executives are still forcing rigid, inflexible, year long deadlines on the engineering team. The company performs the ceremonies of Agile, but they completely lack the actual mindset of adaptability.</p>
<p>Another massive pain point is meeting overload. A poorly implemented Scrum setup means developers spend fifteen hours a week trapped in backlog grooming meetings, planning sessions, and reviews instead of actually getting into a flow state and writing code. Agile was designed to increase speed and reduce bureaucracy, not trap creative people in endless conference room discussions.</p>
<p>Finally, the relentless two week cycle can sometimes cause teams to lose sight of the long term architectural vision. Because they are hyper focused on just getting the next small feature out the door, the overall codebase can sometimes become messy and fragmented over time.</p>
<h2>But, Do You Actually Need Agile?</h2>
<p>Agile is just a tool in a very large toolbox. A heavy iron hammer is a fantastic tool, but it is completely useless for turning a delicate screw. Automatically choosing Agile for every single project is a mark of inexperience.</p>
<h3>A Simple Decision Framework</h3>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>The Project Situation</strong></p></td><td><p><strong>The Best Approach</strong></p></td><td><p><strong>The Reasoning</strong></p></td></tr><tr><td><p>Building a consumer social media app</p></td><td><p>Agile</p></td><td><p>User trends change rapidly. Feedback is needed fast. A bug on a profile picture is annoying, but it hurts no one.</p></td></tr><tr><td><p>Building software for an orbital satellite</p></td><td><p>Waterfall</p></td><td><p>Pushing a hotfix update is physically impossible if the satellite explodes in the vacuum of space. Measure twice, cut once.</p></td></tr><tr><td><p>Strict government medical database</p></td><td><p>Waterfall</p></td><td><p>Massive architectural documentation is required by law for security compliance before a single line of code can be written.</p></td></tr></tbody></table>

<h3>The Hybrid Reality of Modern Business</h3>
<p>Out in the real world, massive Fortune 500 companies usually use a practical mix of both philosophies. This blended approach is often jokingly referred to in the industry as Water-Scrum-Fall.</p>
<p>At the very top, executives plan the yearly budget and major milestones using a traditional Waterfall approach. Down in the engineering department, developers write the actual code using highly iterative Scrum sprints. Finally, at the end of the line, the security and legal teams halt the final release for a month to perform a massive, heavy Waterfall style compliance audit. It can feel a bit messy and contradictory, but sometimes that exact structural blend is exactly what a highly regulated business needs to survive.</p>
<h2>Agile Expanding Beyond Software</h2>
<p>The most incredible validation of the Agile Manifesto is that the philosophy worked so incredibly well for software engineers that entirely different industries began actively adopting it.</p>
<p>Modern marketing teams now run their campaigns using sprints. Instead of spending two million dollars on a six month nationwide billboard campaign blindly, they run three different digital ads in a small city for a single week. They analyze the conversion data, drop the failing ads, and double down on the winner.</p>
<p>Classroom teachers are increasingly utilizing Kanban boards. Instead of forcing an entire classroom of thirty students to complete the exact same worksheet at the exact same pace, students pull assignments from a To Do column and move them to Done at their own individual speeds.</p>
<p>Even physical manufacturing teams designing hardware and robotics use iterative loops to 3D print prototypes, test them, and refine designs before committing to expensive steel molds.</p>
<h2>Final Thoughts</h2>
<p>This extensive journey has covered a vast amount of ground. It explored the chaotic, undocumented early days of coding. It analyzed the rigid safety and ultimate flaws of the Waterfall model. It unpacked the flexible, feedback driven world of the Agile Manifesto. The deep dives into Sprints, estimation psychology, and continuous deployment show exactly how modern professional teams operate daily.</p>
<p>Think back one last time to the cross country road trip analogy from the very beginning.</p>
<p>Following traditional Waterfall is like printing out paper directions, pre booking non refundable motels, and stubbornly refusing to change the route even if a massive blizzard covers the highway in snow.</p>
<p>Embracing Agile is like putting the final destination into a modern smartphone GPS. The final destination is perfectly clear. But if heavy traffic suddenly builds up ahead, the application recalculates and finds a faster route. If a fascinating landmark appears along the highway, the driver has the flexibility to take a quick detour and explore. The journey adjusts dynamically, intelligently, and safely to the reality of the road.</p>
<p>Agile is never really about daily standup meetings, tracking software, or colorful sticky notes on a wall. It is a fundamental shift in how humans approach complex work. It rests on the humble, honest realization that no human being can perfectly predict the future, but teams can be built with enough trust, communication, and flexibility to bravely adapt to absolutely whatever comes next.</p>
]]></content:encoded></item><item><title><![CDATA[RabbitMQ vs Kafka: Key Differences, Trade-offs, and When to Use Each]]></title><description><![CDATA[If you hang around software engineering circles, you will inevitably hear a heated debate: "Should we use RabbitMQ or Kafka?" It’s a question asked in architecture review boards, system design intervi]]></description><link>https://blog.ashutoshkrris.in/rabbitmq-vs-kafka-key-differences-trade-offs-and-when-to-use-each</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/rabbitmq-vs-kafka-key-differences-trade-offs-and-when-to-use-each</guid><category><![CDATA[System Design]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[interview]]></category><category><![CDATA[architecture]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Wed, 03 Jun 2026 18:04:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/49b2cc15-fab6-46f0-9284-fc65404c6ab7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you hang around software engineering circles, you will inevitably hear a heated debate: <em>"Should we use RabbitMQ or Kafka?"</em> It’s a question asked in architecture review boards, system design interviews, and Reddit threads. But it is fundamentally the wrong question.</p>
<p>Asking "RabbitMQ vs Kafka" is like asking "Should I buy a minivan or a dump truck?" Both are vehicles. Both have wheels. Both transport things. But they were engineered to solve entirely different problems.</p>
<p>Treating them as direct competitors leads to fragile architectures, frustrated developers, and costly production incidents. To truly master distributed systems, we must stop comparing their features in a vacuum and start understanding <em>why</em> they were created, the distinct architectural philosophies they embody, and the operational realities that dictate their use.</p>
<h2>Before RabbitMQ and Kafka: The Original Problem</h2>
<p>Before we look at the solutions, we must understand the problem. Think about a classic, monolithic application. When a user buys a product, the code to charge the credit card, update the inventory, and send a confirmation email all runs in the same process. It is a synchronous, tightly coupled flow.</p>
<p>As systems scale and break into microservices, this synchronous flow becomes a nightmare. If the <code>Checkout Service</code> calls the <code>Email Service</code> directly via HTTP:</p>
<ol>
<li><p><strong>Tight Coupling:</strong> The <code>Checkout Service</code> needs to know the exact address and API of the <code>Email Service</code>.</p>
</li>
<li><p><strong>Cascading Failures:</strong> If the <code>Email Service</code> goes down, the <code>Checkout Service</code> might time out, failing the entire user order just because an email couldn't be sent.</p>
</li>
<li><p><strong>Backpressure Issues:</strong> If the <code>Email Service</code> can handle 10 requests per second, but a Black Friday sale generates 100 orders per second, the <code>Email Service</code> crashes under the load.</p>
</li>
</ol>
<p>Engineers needed a way to decouple systems. They needed asynchronous communication. They needed an intermediary, a <strong>Message Broker</strong>, that could accept a message from a producer, hold onto it safely, and deliver it to a consumer at the consumer's own pace.</p>
<p>This is the genesis of message brokering. But <em>how</em> you broker those messages depends entirely on what you prioritize.</p>
<h2>Understanding RabbitMQ: The Smart Broker</h2>
<h3>The History and Philosophy</h3>
<p>In the mid-2000s, the financial industry had a problem. They needed to move millions of messages reliably between disparate, heterogeneous systems. Existing solutions were proprietary, expensive, and locked them into specific vendors.</p>
<p>Enter <strong>AMQP (Advanced Message Queuing Protocol)</strong>, an open standard designed to create a universal language for messaging. RabbitMQ, created in 2007 and written in Erlang (a language built for highly concurrent, fault-tolerant telecommunications), emerged as the premier implementation of AMQP.</p>
<p>RabbitMQ’s core philosophy is <strong>"Smart Broker, Dumb Consumer."</strong> The broker takes on the heavy lifting of routing messages, tracking who has consumed what, and ensuring reliable delivery. The consumers just connect, ask for work, and process it.</p>
<h3>Core Architecture</h3>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/a014bb77-54f8-422d-8199-376eb53f417a.png" alt="RabbitMQ Core Architecture" style="display:block;margin:0 auto" />

<p>RabbitMQ operates on a highly flexible routing model:</p>
<ol>
<li><p><strong>Producers</strong> never publish directly to a queue. They publish to an <strong>Exchange</strong>.</p>
</li>
<li><p><strong>Exchanges</strong> act like a post office sorting facility. Based on the rules (Bindings), the exchange routes copies of the message to one or more <strong>Queues</strong>.</p>
</li>
<li><p><strong>Queues</strong> store the messages until they are processed.</p>
</li>
<li><p><strong>Consumers</strong> receive messages from the queues, process them, and send an <strong>Acknowledgement (ACK)</strong>.</p>
</li>
</ol>
<h3>The "Why" Behind RabbitMQ's Design Choices</h3>
<ul>
<li><p><strong>Why Exchanges?</strong> Because routing logic shouldn't be hardcoded into producers or consumers. If you want a message to go to one service today and three services tomorrow, you just change the broker's binding rules. The producer code never changes.</p>
</li>
<li><p><strong>Why a "Push" Model?</strong> RabbitMQ <em>pushes</em> messages to consumers. To prevent overwhelming a consumer, it uses a <strong>Prefetch Limit</strong> (e.g., "only push 5 unacknowledged messages at a time"). This is how RabbitMQ elegantly handles backpressure.</p>
</li>
<li><p><strong>Why Acknowledgements?</strong> RabbitMQ deletes a message <em>only</em> after a consumer explicitly says, "I have successfully processed this." If a consumer crashes mid-processing, RabbitMQ detects the severed connection and re-queues the message for another worker. This guarantees work is never lost.</p>
</li>
<li><p><strong>Why does it excel at Task Distribution?</strong> RabbitMQ implements the <strong>Competing Consumers</strong> pattern perfectly. If you have a queue with 10,000 background jobs, you can attach 50 consumers to it, and RabbitMQ will safely deal them out round-robin style.</p>
</li>
<li><p><strong>Why does it avoid Head-of-Line Blocking?</strong> Imagine a single-lane drive-thru. If the first car orders 50 custom burgers, the 10 cars behind them waiting for a simple coffee are stuck. That is Head-of-Line blocking. Because RabbitMQ deals messages out to a pool of workers, a slow task doesn't block fast tasks from being processed by other consumers.</p>
</li>
</ul>
<blockquote>
<p>💡 <strong>System Design Interview Tip:</strong> When an interviewer asks you to design a system with long-running, isolated tasks (like generating a PDF or processing a video), immediately reach for a message queue like RabbitMQ. Mention the "Competing Consumers" pattern and message acknowledgements for fault tolerance.</p>
</blockquote>
<h2>Understanding Kafka: The Distributed Log</h2>
<h3>The History and Philosophy</h3>
<p>Around 2010, LinkedIn hit a wall. They were generating massive amounts of data - page views, clicks, profile updates, search queries. They needed to move this firehose of data from their frontend servers to their backend analytics systems, recommendation engines, and Hadoop clusters.</p>
<p>Traditional message brokers like RabbitMQ were choking. Why? Because RabbitMQ tracks the state of <em>every single message</em> for <em>every single consumer</em>. When you push millions of messages per second, the overhead of tracking individual ACKs and deleting individual messages becomes a massive bottleneck.</p>
<p>LinkedIn engineers realized they didn't need a traditional queue. They needed a high-throughput pipeline. So, they built <strong>Apache Kafka</strong>.</p>
<p>Kafka’s core philosophy is <strong>"Dumb Broker, Smart Consumer."</strong> Kafka doesn't track what you have read. It doesn't route messages dynamically. It just acts as a massive, highly optimized, distributed append-only log.</p>
<h3>Core Architecture</h3>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/e5d6d634-38e3-4f0f-be5b-5009c347033a.png" alt="Kafka Core Architecture" style="display:block;margin:0 auto" />

<ul>
<li><p><strong>Events</strong> are written to a <strong>Topic</strong>.</p>
</li>
<li><p>Topics are split into <strong>Partitions</strong>, which are distributed across multiple servers (Brokers) for massive horizontal scale.</p>
</li>
<li><p>Kafka writes messages sequentially to disk (an <strong>Append-only Log</strong>).</p>
</li>
<li><p><strong>Consumers</strong> explicitly request to read messages sequentially.</p>
</li>
<li><p>Instead of the broker deleting a message when read, the consumer remembers its position in the log, an <strong>Offset</strong>.</p>
</li>
</ul>
<h3>The "Why" Behind Kafka's Design Choices</h3>
<ul>
<li><p><strong>Why an Append-Only Log?</strong> Hard drives are incredibly fast at sequential writes, but slow at random reads/writes. By only appending to the end of a file and never modifying/deleting individual records, Kafka achieves RAM-like speed using cheap disk storage.</p>
</li>
<li><p><strong>What is "Zero-Copy I/O"?</strong> Kafka utilizes an OS-level optimization called Zero-Copy. Instead of loading data from the disk into the application's memory just to send it over the network, Kafka streams the data <em>directly</em> from the OS disk cache to the network socket. This is a massive reason for its million-message-per-second throughput.</p>
</li>
<li><p><strong>Why a "Pull" Model?</strong> Kafka consumers <em>poll</em> (pull) the broker for data. Why? Because in big data pipelines, batching is everything. By pulling, consumers can dictate their own consumption rate and grab hundreds of messages in a single network request, maximizing throughput.</p>
</li>
<li><p><strong>Why do Consumers track Offsets?</strong> By offloading the state-tracking to the consumers, the broker doesn't care if 1 consumer or 100,000 consumers are reading the log. The broker’s workload remains exactly the same. Decentralizing state is the secret to infinite scale.</p>
</li>
<li><p><strong>Why Partitions?</strong> A single log file can only be as big or fast as a single hard drive. By partitioning a topic, Kafka spreads the log across hundreds of machines, allowing parallel writes and reads.</p>
</li>
</ul>
<h2>The Deep Architectural Difference: Message vs. Event</h2>
<p>To truly master these systems, you must internalize this single, profound difference:</p>
<h3>RabbitMQ embodies the "Message Queue" mindset.</h3>
<p>A message is a command. It is transient. It is an envelope saying, "Hey, please do this work." Once the work is done, the message has fulfilled its destiny, and it is destroyed.</p>
<ul>
<li><em>Analogy:</em> RabbitMQ is a Post Office. The letter arrives, the mail carrier delivers it to your mailbox, you open it, and you throw the envelope away.</li>
</ul>
<h3>Kafka embodies the "Distributed Log" mindset.</h3>
<p>An event is a fact. It is persistent. It is a historical record saying, "This thing happened in the past." You cannot delete history.</p>
<ul>
<li><em>Analogy:</em> Kafka is a public ledger or a history book. Anyone can read chapter 1, at any time, as many times as they want. Reading the book doesn't make the pages disappear.</li>
</ul>
<h2>RabbitMQ vs Kafka: Feature Comparison Table</h2>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Feature</strong></p></td><td><p><strong>RabbitMQ (Message Queue)</strong></p></td><td><p><strong>Kafka (Event Log)</strong></p></td><td><p><strong>Why?</strong></p></td></tr><tr><td><p><strong>Data Retention</strong></p></td><td><p>Ephemeral</p></td><td><p>Persistent</p></td><td><p>Queues empty out when work is done. Logs store history.</p></td></tr><tr><td><p><strong>Consumer Model</strong></p></td><td><p>Push (with prefetch)</p></td><td><p>Pull (Polling)</p></td><td><p>RMQ distributes tasks immediately. Kafka lets big-data consumers optimize batches.</p></td></tr><tr><td><p><strong>Message State</strong></p></td><td><p>Tracked by Broker (ACKs)</p></td><td><p>Tracked by Consumer (Offsets)</p></td><td><p>Centralized state enables complex routing/retries. Decentralized state scales infinitely.</p></td></tr><tr><td><p><strong>Routing</strong></p></td><td><p>Highly complex (Exchanges)</p></td><td><p>Simple (Topic/Partition)</p></td><td><p>RMQ routes workflows dynamically. Kafka relies on producers putting events in the right topic.</p></td></tr><tr><td><p><strong>Delivery Semantics</strong></p></td><td><p>At-Least-Once</p></td><td><p>Exactly-Once (via Tx APIs)</p></td><td><p>Kafka's ecosystem allows transactional end-to-end processing. RMQ requires idempotent consumers.</p></td></tr><tr><td><p><strong>Replayability</strong></p></td><td><p>No</p></td><td><p>Yes (Time-travel via offsets)</p></td><td><p>You can't un-deliver mail. But you can re-read a history book.</p></td></tr></tbody></table>

<blockquote>
<p>Note: RabbitMQ recently introduced "Streams" which behave similarly to Kafka's append-only logs, showing that modern tools often borrow the best ideas from each other. However, RabbitMQ's primary identity remains a traditional message broker.</p>
</blockquote>
<h2>The Operational Reality Check: Failures and Idempotency</h2>
<p>Architectural theory is beautiful, but production is messy. If you are preparing for a senior engineering interview, you must understand the operational failure modes of these systems.</p>
<h3>1. At-Least-Once Delivery and the Need for Idempotency</h3>
<p>Whether you use RabbitMQ or Kafka, networks are unreliable. Imagine a RabbitMQ consumer processes an e-commerce order, charges the customer's credit card, but then the server's network cable is cut before it can send the <code>ACK</code> back to RabbitMQ.</p>
<p>RabbitMQ assumes the consumer died and requeues the message. Another consumer picks it up and charges the customer <em>again</em>.</p>
<p><strong>The Fix:</strong> You must design your consumers to be <strong>Idempotent</strong>. This means applying the same message multiple times has the same effect as applying it once. You achieve this by storing a unique <code>order_id</code> in your database and checking if you've already processed it before charging the card. Do not rely on the broker to save you from duplicate processing.</p>
<h3>2. Poison Messages and Dead Letter Queues (DLQ)</h3>
<p>What happens if a message payload is corrupted (a "poison message")?</p>
<ul>
<li><p><strong>In RabbitMQ:</strong> The consumer throws an error, rejects the message, and RabbitMQ gracefully routes it to a Dead Letter Queue for developers to inspect later. The next message in the queue processes normally.</p>
</li>
<li><p><strong>In Kafka:</strong> Because consumers read sequentially from a partition, a consumer crashing on Offset 5 means it will reboot, read Offset 5 again, and crash again. <strong>Forever.</strong> This blocks the entire partition. Implementing DLQs in Kafka requires you to manually catch the error, write the bad message to a separate "retry topic", and manually advance your offset. It is significantly more complex.</p>
</li>
</ul>
<h3>3. Scaling and Rebalancing Latency</h3>
<ul>
<li><p><strong>In RabbitMQ:</strong> If you have 50 workers and add a 51st, RabbitMQ simply starts dealing cards to the new worker. It is seamless and instant.</p>
</li>
<li><p><strong>In Kafka:</strong> A single partition can only be read by one consumer in a group to guarantee order. If you have 10 partitions, you can have a maximum of 10 consumers. If you add a new consumer, Kafka must perform a <strong>Consumer Group Rebalance</strong>. It pauses processing, recalculates who gets which partition, and starts back up. This can cause severe latency spikes in production.</p>
</li>
</ul>
<h2>System Design Interview Perspective</h2>
<p>In a system design interview, choosing the wrong message broker is a major red flag.</p>
<h3>When to choose RabbitMQ:</h3>
<ul>
<li><p><strong>"I need to run background tasks."</strong> (e.g., Image processing).</p>
</li>
<li><p><strong>"I need complex routing."</strong> (e.g., If user is VIP, send to Queue A; else Queue B).</p>
</li>
<li><p><strong>"Tasks have varying processing times."</strong> (Because RabbitMQ doesn't suffer from Head-of-Line blocking).</p>
</li>
<li><p><strong>"I need precise, individual message retries and Dead Letter tracking."</strong></p>
</li>
<li><p><strong>"I need strict ordering but with dynamic scaling."</strong> (Mention using RabbitMQ's Consistent Hash Exchange).</p>
</li>
</ul>
<h3>When to choose Kafka:</h3>
<ul>
<li><p><strong>"I have massive throughput requirements."</strong> (e.g., IoT telemetry, clickstreams).</p>
</li>
<li><p><strong>"I need strict chronological ordering of events."</strong> (e.g., Applying database updates/CDC in exact order).</p>
</li>
<li><p><strong>"Multiple independent services need to react to the same data."</strong> (e.g., A user signs up: Auth, Recommendations, and Analytics all need to know).</p>
</li>
<li><p><strong>"I need to replay history to rebuild state or train a new ML model."</strong></p>
</li>
</ul>
<blockquote>
<p>⚠️ <strong>Common Interview Trap:</strong> Candidates often say, "I'll use Kafka because it's faster and more modern." Interviewers will instantly ask how you plan to handle individual message retries or poison messages. If you don't know the complexity of Kafka error handling, stick to RabbitMQ for operational tasks.</p>
</blockquote>
<h2>Real Production Scenarios</h2>
<h3>Scenario 1: Background Job Processing</h3>
<ul>
<li><p><strong>The Job:</strong> You run a platform where users upload videos. You need to transcode these videos.</p>
</li>
<li><p><strong>The Choice:</strong> <strong>RabbitMQ</strong>.</p>
</li>
<li><p><strong>The Reasoning:</strong> Video transcoding takes time (minutes to hours). If you used Kafka, a 4-hour 4K video transcode would block all other videos in that partition. With RabbitMQ, you spin up a pool of worker nodes.</p>
</li>
</ul>
<h3>Scenario 2: E-Commerce Checkout System</h3>
<ul>
<li><p><strong>The Job:</strong> A user clicks "Buy." You must process payment, reserve inventory, and send a receipt.</p>
</li>
<li><p><strong>The Choice:</strong> <strong>RabbitMQ</strong> (for the operational workflow).</p>
</li>
<li><p><strong>The Reasoning:</strong> This is a transactional workflow. You need exact retries. If the payment gateway API times out, you want to retry <em>just that specific message</em> with exponential backoff. RabbitMQ's DLXs are perfect for this (paired with idempotent consumers!).</p>
</li>
</ul>
<h3>Scenario 3: Real-Time Analytics Pipeline</h3>
<ul>
<li><p><strong>The Job:</strong> You need to track every button click, mouse movement, and page transition from a million concurrent users.</p>
</li>
<li><p><strong>The Choice:</strong> <strong>Kafka</strong>.</p>
</li>
<li><p><strong>The Reasoning:</strong> Throughput. RabbitMQ would collapse under the sheer volume of ACKs required for millions of clicks per second. Kafka streams these events to disk sequentially, allowing your analytics engine to consume them in massive batches.</p>
</li>
</ul>
<h3>Scenario 4: Event Sourcing &amp; Audit Logs</h3>
<ul>
<li><p><strong>The Job:</strong> You are building a banking application. You must store every single transaction (Deposit \(10, Withdraw \)5) so you can independently verify the balance from scratch.</p>
</li>
<li><p><strong>The Choice:</strong> <strong>Kafka</strong>.</p>
</li>
<li><p><strong>The Reasoning:</strong> You need immutable history and replayability. If an auditor comes in, you point a new consumer at Offset 0 of the <code>transactions</code> topic, and it reads years of history to verify the ledger.</p>
</li>
</ul>
<h2>Why Companies Often Use Both</h2>
<p>One of the biggest misconceptions is that a company must standardize on <em>either</em> RabbitMQ <em>or</em> Kafka. In reality, almost all large-scale tech companies use both, playing to their respective strengths.</p>
<p>Consider a modern architecture for a food delivery platform:</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/e12b777f-9635-48db-b102-11922e381719.png" alt="RabbitMQ and Kafka Working Together" style="display:block;margin:0 auto" />

<ul>
<li><p><strong>The Operational Workflow:</strong> The immediate tasks (charging the card, pinging the restaurant's tablet) are handled by <strong>RabbitMQ</strong>. It acts as the nervous system, managing the state of the <em>work</em>.</p>
</li>
<li><p><strong>The Data Pipeline:</strong> As those workers complete their jobs, they emit "facts" (e.g., "Order #123 Paid") into <strong>Kafka</strong>. Kafka acts as the corporate memory, holding these events forever so the Data Science team can train machine learning models.</p>
</li>
</ul>
<p>They are entirely complementary. RabbitMQ coordinates the present. Kafka records the past.</p>
<h2>The Decision Framework</h2>
<p>If you find yourself paralyzed by choice in a project, use this simplified decision tree:</p>
<ul>
<li><p><strong>Do you need to replay messages from the past?</strong></p>
<ul>
<li>Yes → Kafka.</li>
</ul>
</li>
<li><p><strong>Are you routing messages based on complex rules (wildcards, headers)?</strong></p>
<ul>
<li>Yes → RabbitMQ.</li>
</ul>
</li>
<li><p><strong>Do you need massive throughput (100k+ events/sec) or stream processing?</strong></p>
<ul>
<li>Yes → Kafka.</li>
</ul>
</li>
<li><p><strong>Do tasks take varying amounts of time, requiring individual retries and Dead Letter tracking?</strong></p>
<ul>
<li>Yes → RabbitMQ.</li>
</ul>
</li>
<li><p><strong>Do I lack a dedicated platform engineering team to manage complex infrastructure?</strong></p>
<ul>
<li>Yes → RabbitMQ (Kafka's operational overhead with KRaft/Zookeeper is significant).</li>
</ul>
</li>
</ul>
<h2>Final Takeaway</h2>
<p>As an architect or senior engineer, your job is not to memorize feature matrices. Your job is to deeply understand the underlying paradigms of the tools at your disposal so you can align them with the contours of your specific business problem.</p>
<p>If you remember nothing else from this article, remember this fundamental principle:</p>
<p><strong>"RabbitMQ is primarily optimized for delivering work. Kafka is primarily optimized for preserving events."</strong></p>
<p>Design your systems accordingly.</p>
]]></content:encoded></item><item><title><![CDATA[Python Threading vs Multiprocessing vs Asyncio: When to Use Each]]></title><description><![CDATA[Imagine you are building a feature that needs to fetch data from 100 different API endpoints. You write a clean, simple loop in Python to call each endpoint one after the other. Each request takes exa]]></description><link>https://blog.ashutoshkrris.in/python-threading-multiprocessing-asyncio-concurrency-guide</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/python-threading-multiprocessing-asyncio-concurrency-guide</guid><category><![CDATA[Python]]></category><category><![CDATA[multithreading]]></category><category><![CDATA[backend]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sun, 31 May 2026 04:17:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/b4477114-c473-4d81-ac79-19436c6847d9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Imagine you are building a feature that needs to fetch data from 100 different API endpoints. You write a clean, simple loop in Python to call each endpoint one after the other. Each request takes exactly 1 second to respond.</p>
<p>You run the script, grab a cup of coffee, and wait. It takes over 100 seconds to finish.</p>
<p>Your code spends 99% of its time doing absolutely nothing. It is just sitting there, waiting for the remote servers to send back data over the network. This feels incredibly slow, and your users will definitely notice.</p>
<p>Many developers encounter this exact performance bottleneck early in their careers. To fix it, you need your program to handle multiple tasks at the same time. This is where Python concurrency comes into play.</p>
<p>Python gives us three distinct tools to solve this problem: <strong>threading</strong>, <strong>multiprocessing</strong>, and <strong>asyncio</strong>. However, choosing the wrong tool can actually make your code slower and significantly more complicated.</p>
<p>Most developers discover the Global Interpreter Lock (the GIL) shortly after wondering why their threaded code somehow became more complicated without becoming any faster.</p>
<p>In this article, we will break down how these three concurrency models work from first principles, look at real benchmarks, and learn exactly how to choose the right tool for your specific backend systems.</p>
<h2>What Is Concurrency?</h2>
<p>Before we look at code, we need to clear up a massive point of confusion. Developers often use the words <strong>concurrency</strong> and <strong>parallelism</strong> interchangeably, but they mean entirely different things.</p>
<ul>
<li><p><strong>Concurrency</strong> is about <strong>structure</strong>. It means organizing your program so it can handle multiple tasks at the same time. A concurrent program makes progress on multiple tasks, but it is not necessarily running them at the exact same millisecond.</p>
</li>
<li><p><strong>Parallelism</strong> is about <strong>execution</strong>. It means actually executing multiple tasks at the exact same physical millisecond. This requires a computer with multiple CPU cores.</p>
</li>
</ul>
<p>Let us use a simple analogy.</p>
<p>Imagine a single customer support agent handling three different live chats. The agent types a reply to Chat A, waits for the user to type back, switches to Chat B to answer a quick question, and then checks on Chat C. The agent is handling three chats concurrently. But at any single microsecond, the agent is only typing on one keyboard.</p>
<p>Now imagine three different customer support agents sitting at three different desks, each handling their own single chat. That is parallelism. The tasks are happening completely independently and simultaneously.</p>
<p>In Python, the way we achieve concurrency depends entirely on whether our code is waiting on external resources or maxing out our CPU.</p>
<h2>A Baseline Sequential Program</h2>
<p>To understand how concurrency helps, we first need a baseline. Let us write a simple, traditional program that runs sequentially (one task after another).</p>
<p>We will simulate a slow network request using <code>time.sleep()</code>.</p>
<pre><code class="language-python">import time

def fetch_data(task_id):
    print(f"Starting task {task_id}")
    # Simulating a 1-second network delay
    time.sleep(1)
    print(f"Finished task {task_id}")

def main():
    start_time = time.time()
    
    # Run 5 tasks sequentially
    for i in range(1, 6):
        fetch_data(i)
        
    end_time = time.time()
    print(f"Total execution time: {end_time - start_time:.2f} seconds")

if __name__ == "__main__":
    main()
</code></pre>
<p>Expected Output:</p>
<pre><code class="language-shell">Starting task 1
Finished task 1
Starting task 2
Finished task 2
Starting task 3
Finished task 3
Starting task 4
Finished task 4
Starting task 5
Finished task 5
Total execution time: 5.00 seconds
</code></pre>
<h3>Why This Program Is Slow</h3>
<p>Every time the loop calls <code>fetch_data()</code>, the entire execution of the program stops dead in its tracks at <code>time.sleep(1)</code>. The operating system halts the Python process for a full second. Your CPU sits idle, doing absolutely zero useful work while waiting for the timer to tick down.</p>
<p>Because we have 5 tasks, and each task must wait for the previous one to finish completely, the total time is simply the sum of all wait times (just over 5 seconds).</p>
<h2>Understanding Threading</h2>
<p>A <strong>thread</strong> is the smallest unit of execution that an operating system can schedule. Think of a thread as a single train of thought within your program.</p>
<p>When you run a standard Python script, it runs inside a single <strong>process</strong> and executes on a single <strong>main thread</strong>. However, your program can ask the operating system to spin up additional threads.</p>
<p>All threads inside a single process share the exact same memory space. This means they can easily access the same variables, objects, and data structures.</p>
<p>Because threads share memory, switching between them is incredibly fast for the operating system. This process of switching attention from one thread to another is called <strong>context switching</strong>.</p>
<p>Threading shines when your program is <strong>I/O-bound</strong> (Input/Output bound). An I/O-bound task is any task where the bottleneck is waiting for something outside your CPU, such as:</p>
<ul>
<li><p>Waiting for a response from a third-party API</p>
</li>
<li><p>Waiting for a database query to finish</p>
</li>
<li><p>Reading or writing a file to a hard drive</p>
</li>
</ul>
<p>Let us rewrite our sequential program using Python's modern <code>ThreadPoolExecutor</code> from the built-in <code>concurrent.futures</code> module.</p>
<pre><code class="language-python">import time
from concurrent.futures import ThreadPoolExecutor

def fetch_data(task_id):
    print(f"Starting task {task_id}\n", end="")
    time.sleep(1)
    print(f"Finished task {task_id}\n", end="")

def main():
    start_time = time.time()
    
    # Create a pool of up to 5 worker threads
    with ThreadPoolExecutor(max_workers=5) as executor:
        # Submit all 5 tasks to the pool
        executor.map(fetch_data, range(1, 6))
        
    end_time = time.time()
    print(f"Total execution time: {end_time - start_time:.2f} seconds")

if __name__ == "__main__":
    main()
</code></pre>
<p>Expected Output:</p>
<pre><code class="language-shell">Starting task 1
Starting task 2
Starting task 3
Starting task 4
Starting task 5
Finished task 3
Finished task 1
Finished task 2
Finished task 5
Finished task 4
Total execution time: 1.00 seconds
</code></pre>
<h3>What Just Happened?</h3>
<p>Our execution time dropped from 5 seconds to just 1 second.</p>
<p>When thread 1 hit <code>time.sleep(1)</code>, the operating system noticed that thread 1 was blocked and waiting. Instead of pausing the entire program, the operating system instantly performed a context switch over to thread 2.</p>
<p>Thread 2 started executing and also hit <code>time.sleep(1)</code>. The operating system immediately switched to thread 3, and so on.</p>
<p>All 5 threads ended up waiting at the exact same time. Their idle waiting periods overlapped perfectly, compressing our total runtime down to the duration of a single task.</p>
<h2>Understanding the GIL</h2>
<p>If threading is so fast and lightweight, why don't we just use it for absolutely everything?</p>
<p>The answer lies in Python's infamous <strong>Global Interpreter Lock</strong>, commonly known as the <strong>GIL</strong>.</p>
<p>The standard, most widely used implementation of Python is written in C and is called <strong>CPython</strong>. CPython manages memory using a system called reference counting. Every time you create an object, Python keeps track of how many variables are pointing to it. If that count hits zero, Python safely deletes the object from memory.</p>
<p>The problem is that if multiple threads try to increase or decrease this reference count at the exact same time, the count can become corrupted. This leads to leaked memory or, worse, your program crashing because it deleted an object that was still in use.</p>
<p>To protect your data, CPython introduces the GIL. The GIL is a master lock that ensures <strong>only one thread can execute Python bytecode at any given millisecond</strong>.</p>
<p>Your CPU can only drink from one Python straw at a time. Throwing more threads at a CPU-bound problem is often like hiring more people to use the same single-lane road.</p>
<p>Let us prove this with an experiment. We will write a <strong>CPU-bound</strong> task, which is a task that does heavy computational calculations and never pauses for network or disk I/O. We will count down from a large number.</p>
<pre><code class="language-python">import time
from concurrent.futures import ThreadPoolExecutor

COUNT = 20_000_000

def count_down(n):
    while n &gt; 0:
        n -= 1

def run_sequential():
    start = time.time()
    count_down(COUNT)
    count_down(COUNT)
    print(f"Sequential CPU-bound time: {time.time() - start:.2f} seconds")

def run_threaded():
    start = time.time()
    with ThreadPoolExecutor(max_workers=2) as executor:
        executor.submit(count_down, COUNT)
        executor.submit(count_down, COUNT)
    print(f"Threaded CPU-bound time: {time.time() - start:.2f} seconds")

if __name__ == "__main__":
    run_sequential()
    run_threaded()
</code></pre>
<p>Expected Output:</p>
<pre><code class="language-shell">Sequential CPU-bound time: 1.45 seconds
Threaded CPU-bound time: 1.51 seconds
</code></pre>
<h3>Analyzing the Results</h3>
<p>The threaded version actually took <em>longer</em> than the sequential version.</p>
<p>Because of the GIL, the two threads could not run in parallel on separate CPU cores. Instead, the operating system had to constantly pause one thread, save its state, swap in the second thread, let it count for a microsecond, and swap it back.</p>
<p>This constant swapping adds administrative overhead without providing any performance benefits. If you have heavy math, data processing, or image manipulation to do, standard Python threads will not help you.</p>
<h2>Understanding Multiprocessing</h2>
<p>To bypass the GIL entirely, we must use <strong>multiprocessing</strong>.</p>
<p>While threading creates multiple lines of execution inside a single process, multiprocessing spawns completely separate, independent processes.</p>
<p>Each individual process gets its own dedicated private memory space and, crucially, <strong>its own separate Python interpreter and GIL</strong>.</p>
<p>Because each process has its own interpreter, they can run truly in parallel across different physical cores of your computer's CPU.</p>
<p>Let us rewrite our heavy counting task using <code>ProcessPoolExecutor</code> from the <code>concurrent.futures</code> module.</p>
<pre><code class="language-python">import time
from concurrent.futures import ProcessPoolExecutor

COUNT = 20_000_000


def count_down(n):
    while n &gt; 0:
        n -= 1


def main():
    start_time = time.time()

    # Spin up 2 separate processes
    with ProcessPoolExecutor(max_workers=2) as executor:
        executor.submit(count_down, COUNT)
        executor.submit(count_down, COUNT)

    end_time = time.time()
    print(
        f"Multiprocessing CPU-bound time: {end_time - start_time:.2f} seconds")


if __name__ == "__main__":
    main()
</code></pre>
<p>Expected Output:</p>
<pre><code class="language-shell">Multiprocessing CPU-bound time: 0.86 seconds
</code></pre>
<p>The runtime dropped significantly. Because we used multiprocessing, Python sent one calculation task to Process A on CPU Core 0, and the second calculation task to Process B on CPU Core 1. Both cores worked at maximum capacity simultaneously.</p>
<p>However, this raw speed comes with a significant engineering trade-off: <strong>memory isolation</strong>.</p>
<p>Because processes do not share memory, you cannot easily modify a global variable in one process and see the change in another. If a process needs to send data back to the main program, Python must serialize the data (convert it into raw bytes), send it over a communication channel, and deserialize it back into a Python object. This operation adds noticeable memory and performance overhead.</p>
<h2>Understanding Asyncio</h2>
<p>Now let us look at the third option: <strong>asyncio</strong>.</p>
<p>Asyncio stands for Asynchronous Input/Output. It takes a radically different path to concurrency than threading or multiprocessing.</p>
<p>Instead of relying on the operating system to manage and swap tasks, asyncio handles concurrency entirely inside your application code using a single thread. It achieves this through a mechanism called the <strong>Event Loop</strong>.</p>
<p>Think of the event loop as a manager running a loop that monitors a list of registered tasks.</p>
<p>To use asyncio, you declare your functions using the <code>async</code> keyword, turning them into <strong>coroutines</strong>. Inside a coroutine, when you reach a slow operation (like a network request), you use the <code>await</code> keyword to hand control directly back to the event loop.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/3b18217f-610f-4e5a-944c-55ac4bd107ec.png" alt="" style="display:block;margin:0 auto" />

<p>Let us write a runnable example using Python's built-in <code>asyncio</code> library.</p>
<pre><code class="language-python">import asyncio
import time


# 'async def' tells Python this is a coroutine, not a regular function
async def fetch_data(task_id):
    print(f"Starting task {task_id}")
    # 'await' yields control back to the event loop
    await asyncio.sleep(1)
    print(f"Finished task {task_id}")


async def main():
    start_time = time.time()

    # Create a list of coroutine tasks
    tasks = [fetch_data(i) for i in range(1, 6)]

    # Run all tasks concurrently on the event loop
    await asyncio.gather(*tasks)

    end_time = time.time()
    print(f"Total execution time: {end_time - start_time:.2f} seconds")

if __name__ == "__main__":
    # Start the asyncio event loop
    asyncio.run(main())
</code></pre>
<p>Expected Output:</p>
<pre><code class="language-shell">Total execution time: 1.01 seconds
</code></pre>
<p>Our script processed all 5 tasks in 1 second, completely inside a single thread.</p>
<p>When <code>fetch_data(1)</code> executed <code>await asyncio.sleep(1)</code>, it explicitly paused itself and told the event loop: "I am going to be waiting for 1 second. Go ahead and run something else."</p>
<p>The event loop checked its list, saw <code>fetch_data(2)</code>, and started it immediately. No threads were created, meaning the operating system did not have to deal with heavy context switching overhead.</p>
<h2>Threading vs Asyncio for API Calls</h2>
<p>Backend engineers frequently debate whether to use threading or asyncio when building systems that make hundreds of external HTTP API calls. Both handle I/O-bound workloads efficiently, but they do it differently.</p>
<h3>The Technical Differences</h3>
<ul>
<li><p><strong>Threading</strong> uses cooperative or preemptive multitasking managed by the operating system. You can use standard, synchronous libraries like <code>requests</code>. However, each thread consumes roughly 8MB of memory by default. If you try to spin up 10,000 threads simultaneously, your server will likely run out of RAM and crash.</p>
</li>
<li><p><strong>Asyncio</strong> uses explicit cooperative multitasking managed entirely by your code. Because everything runs in a single thread, an individual coroutine task consumes less than 1KB of memory. You can easily run 10,000 or even 50,000 async tasks concurrently on a modest server.</p>
</li>
</ul>
<p>The catch? You cannot use <code>requests</code> inside asyncio because <code>requests</code> is a blocking library. It will lock up the entire single-threaded event loop, stopping every other task in its tracks. You must use asynchronous libraries like <code>httpx</code> or <code>aiohttp</code>.</p>
<h3>Which One Should You Choose?</h3>
<p>If you are modifying an existing codebase that relies heavily on synchronous libraries, or if you only need to run a few dozen tasks, <strong>threading</strong> is usually simpler and faster to implement.</p>
<p>If you are building a modern, high-throughput backend service from scratch (like a FastAPI application) that needs to maintain thousands of concurrent connections or scrapers, <strong>asyncio</strong> is the industry standard choice.</p>
<h2>The Concurrency Matrix</h2>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Feature</strong></p></td><td><p><strong>Threading</strong></p></td><td><p><strong>Multiprocessing</strong></p></td><td><p><strong>Asyncio</strong></p></td></tr><tr><td><p><strong>Best Use Case</strong></p></td><td><p>Web scraping, low-volume I/O</p></td><td><p>Heavy calculations, data processing</p></td><td><p>High-scale APIs, WebSockets</p></td></tr><tr><td><p><strong>Workload Type</strong></p></td><td><p>I/O-bound</p></td><td><p>CPU-bound</p></td><td><p>I/O-bound</p></td></tr><tr><td><p><strong>Memory Usage</strong></p></td><td><p>Moderate (Megabytes per thread)</p></td><td><p>High (Each process copies memory)</p></td><td><p>Low (Kilobytes per coroutine)</p></td></tr><tr><td><p><strong>Code Complexity</strong></p></td><td><p>Low to medium</p></td><td><p>Medium</p></td><td><p>High (Requires async/await everywhere)</p></td></tr><tr><td><p><strong>Scalability</strong></p></td><td><p>Hundreds of concurrent tasks</p></td><td><p>Limited by available CPU cores</p></td><td><p>Tens of thousands of concurrent tasks</p></td></tr><tr><td><p><strong>GIL Impact</strong></p></td><td><p>Kept in place (Limits execution)</p></td><td><p>Bypassed entirely</p></td><td><p>Kept in place (Unimpacted by single thread)</p></td></tr><tr><td><p><strong>Ease of Debugging</strong></p></td><td><p>Hard (Race conditions can happen)</p></td><td><p>Medium (Isolated state)</p></td><td><p>Hard (Stack traces can be cryptic)</p></td></tr></tbody></table>

<h3>Explaining the Rows</h3>
<h4>Workload Type &amp; Best Use Cases</h4>
<p>Threading and asyncio are tailored specifically for I/O tasks where your code spends time waiting on external networks or disks. Multiprocessing is reserved for intensive computations where your CPU cores are working at 100% capacity.</p>
<h4>Memory Usage &amp; Scalability</h4>
<p>Because processes run entirely separate interpreters, they have the heaviest memory footprint. Threads require a fixed chunk of memory from the operating system, limiting them to hundreds or thousands of instances. Asyncio coroutines are simple objects in memory, allowing you to scale up to tens of thousands of tasks without breaking a sweat.</p>
<h4>Code Complexity &amp; Debugging</h4>
<p>Threading allows you to use normal Python code, but sharing data between threads introduces subtle bugs called race conditions. Multiprocessing avoids this via isolated memory, but it makes passing data between tasks more complex. Asyncio requires you to change your entire coding style to use <code>async/await</code>, meaning a single synchronous function call can unexpectedly stall your system.</p>
<h2>Real-World Backend Engineering Examples</h2>
<p>Let us look at how backend teams map these tools to specific production infrastructure workloads.</p>
<h3>1. When to Use Threading</h3>
<ul>
<li><p><strong>Legacy Data Migrations:</strong> A background cron job that reads a batch of 50 customer profiles from a relational database and writes them to a third-party CRM system.</p>
</li>
<li><p><strong>File Downloader Utilities:</strong> A script that reads a list of 100 image URLs and downloads them onto a local drive.</p>
</li>
</ul>
<h3>2. When to Use Multiprocessing</h3>
<ul>
<li><p><strong>Machine Learning &amp; Analytics Pipelines:</strong> Tokenizing text datasets or calculating massive matrix transformations before feeding data into a model.</p>
</li>
<li><p><strong>Image Optimization Workers:</strong> An upload system that receives high-resolution user photos and resizes them into thumbnails for an e-commerce platform.</p>
</li>
</ul>
<h3>3. When to Use Asyncio</h3>
<ul>
<li><p><strong>Real-Time Chat Operations:</strong> Managing thousands of active, long-lived WebSocket connections for a chat application.</p>
</li>
<li><p><strong>High-Performance API Gateways:</strong> A service built with FastAPI that acts as a proxy, hitting five microservices concurrently to assemble a single response payload for a frontend application.</p>
</li>
</ul>
<h2>How to Choose the Right Tool</h2>
<p>When faced with a performance problem, do not guess. Follow this practical engineering decision flow to pick the correct concurrency model:</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/39c6eea7-0b4d-4974-97bd-8675f78f3850.png" alt="" style="display:block;margin:0 auto" />

<h2>Common Mistakes to Avoid</h2>
<h3>1. Blocking the Asyncio Event Loop</h3>
<p>The most frequent production failure in asyncio applications happens when developers use blocking functions inside an asynchronous code path.</p>
<pre><code class="language-python"># ANTI-PATTERN
async def handle_request():
    # This completely freezes the entire backend server for 2 seconds!
    time.sleep(2) 
    return {"status": "done"}
</code></pre>
<p><strong>The Fix:</strong> Always use the non-blocking equivalent (<code>await asyncio.sleep(2)</code>) or delegate the blocking call to a thread pool using <code>asyncio.to_thread()</code>.</p>
<h3>2. Using Threads for Heavy Calculations</h3>
<p>Developers often wrap heavy math operations in threads, assuming it will make them run faster. As we proved in our GIL section, the administrative cost of context switching will actually slow your program down. Always use multiprocessing for computational heavy lifting.</p>
<h3>3. Optimizing Code Before Measuring Performance</h3>
<p>Never implement a complex concurrency architecture based on assumptions. Always use a tool like Python's built-in <code>time</code> module or a profiler to measure your code first. Identify where the actual bottleneck is before writing a single line of concurrent code.</p>
<h2>Key Takeaways</h2>
<ul>
<li><p><strong>Concurrency vs Parallelism:</strong> Concurrency is about structuring your code to handle multiple tasks efficiently. Parallelism is about physically executing tasks at the exact same millisecond across multiple CPU cores.</p>
</li>
<li><p><strong>The Python GIL:</strong> The Global Interpreter Lock ensures that only one thread executes Python bytecode at a time inside a standard CPython process.</p>
</li>
<li><p><strong>Threading</strong> lets you handle multiple I/O-bound tasks by overlapping their idle wait states. It shares memory by default but is limited by the GIL.</p>
</li>
<li><p><strong>Multiprocessing</strong> completely bypasses the GIL by spawning isolated Python processes across different CPU cores, making it the perfect choice for computational work.</p>
</li>
<li><p><strong>Asyncio</strong> offers high-performance, single-threaded concurrency for I/O-bound tasks using an event loop, making it highly scalable but requiring a specific async library ecosystem.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Build AI Apps with Gradio: Turn Your Python Scripts into Web Apps]]></title><description><![CDATA[You build a machine learning model or a chatbot in Python. It works perfectly. The logic is solid, the API calls are fast, and the responses are exactly what you want.
But there is a problem. The enti]]></description><link>https://blog.ashutoshkrris.in/build-ai-apps-with-gradio-turn-your-python-scripts-into-web-apps</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/build-ai-apps-with-gradio-turn-your-python-scripts-into-web-apps</guid><category><![CDATA[AI]]></category><category><![CDATA[Python]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Artificial Intelligence]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sun, 24 May 2026 05:06:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/a94787c9-7026-45ba-942f-4ccfcd905060.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You build a machine learning model or a chatbot in Python. It works perfectly. The logic is solid, the API calls are fast, and the responses are exactly what you want.</p>
<p>But there is a problem. The entire experience is stuck inside a terminal.</p>
<p>Terminal interfaces are great for learning and debugging. However, nobody wants to impress users, stakeholders, or teammates with a blinking terminal cursor forever. Real users expect web interfaces with buttons, text boxes, and clean layouts.</p>
<p>Building a modern frontend app from scratch takes time. You have to set up React, configure a backend framework like FastAPI, manage CORS issues, and write API endpoints just to show a simple text generation result. This frontend work drastically slows down experimentation. AI engineers need to build fast prototypes, test ideas, and share them immediately.</p>
<p>This is where Gradio comes in.</p>
<p>Gradio basically lets Python developers cosplay as frontend developers for a day. It allows you to turn raw Python functions into interactive, shareable web applications in minutes (without writing a single line of HTML, CSS, or JavaScript).</p>
<p>In this article, we will take a simple terminal-based Gemini chatbot and convert it into a clean, modern web application.</p>
<h2>What is Gradio?</h2>
<p><a href="https://www.gradio.app/">Gradio</a> is an open-source Python library designed specifically for building interactive web apps around machine learning models and AI scripts.</p>
<p>You can think of Gradio as a translation layer between your Python code and a web browser. You define the inputs your function expects (like text or images) and the outputs it returns. Gradio automatically generates a user interface that matches those parameters.</p>
<p>It has become massive in the AI community. If you visit Hugging Face Spaces (a popular platform for hosting AI demos), almost everything is built with Gradio. Developers love it because it requires minimal setup, enables fast iteration, and handles all the messy frontend logic under the hood.</p>
<p>Here is a high-level look at how it works:</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/36f64eea-8321-4218-8552-951e3b0f3f38.png" alt="" style="display:block;margin:0 auto" />

<ol>
<li><p>The user types a message in the browser.</p>
</li>
<li><p>The Gradio UI sends that text to your Python backend.</p>
</li>
<li><p>Your Python function processes the text (calling the Google Gemini API).</p>
</li>
<li><p>The API returns the response to your function.</p>
</li>
<li><p>Gradio automatically updates the web UI with the new data.</p>
</li>
</ol>
<h2>Installing and Setting Up Gradio</h2>
<p>Before we write code, we need a clean environment. Creating a virtual environment keeps your project dependencies isolated from the rest of your system.</p>
<p>Open your terminal and run these commands:</p>
<pre><code class="language-shell"># Create a virtual environment
python -m venv ai_app_env

# Activate the environment (Mac/Linux)
source ai_app_env/bin/activate

# Activate the environment (Windows)
ai_app_env\Scripts\activate

# Install dependencies
pip install gradio google-genai python-dotenv
</code></pre>
<p>We are installing <code>gradio</code> for our UI framework, <code>google-genai</code> to access the free tier of Gemini models, and <code>python-dotenv</code> to securely manage our API keys.</p>
<p>Instead of exposing your API key in the terminal or hardcoding it into your script, we will use a <code>.env</code> file. This is a standard engineering practice to keep secrets safe.</p>
<p>Create a file named <code>.env</code> in your project folder. Go to Google AI Studio, grab your free API key, and add it to the file like this:</p>
<pre><code class="language-plaintext">GEMINI_API_KEY=your_actual_api_key_here
</code></pre>
<blockquote>
<p>Important: If you are using Git, make sure to add <code>.env</code> to your <code>.gitignore</code> file so you do not accidentally publish your key to the internet.</p>
</blockquote>
<h2>Build Your First Gradio App</h2>
<p>Let us start with the simplest possible example to see how Gradio wires things together. We will build an app that takes a user's name and returns a greeting.</p>
<p>Open <code>01_greeting_app.py</code> and add this code:</p>
<pre><code class="language-python">import gradio as gr


# 1. Define the core Python logic
def greet_user(name):
    return f"Hello, {name}! Welcome to your first AI app."


# 2. Create the Interface
demo = gr.Interface(
    fn=greet_user,
    inputs="text",
    outputs="text",
    title="Greeting Generator",
    description="Enter your name to get a custom greeting."
)

# 3. Launch the web server
if __name__ == "__main__":
    demo.launch()
</code></pre>
<p>This script introduces the most important class in the library: <code>gr.Interface</code>.</p>
<ul>
<li><p><code>fn=greet_user</code>: We tell Gradio exactly which Python function to run when a user interacts with the app.</p>
</li>
<li><p><code>inputs="text"</code>: We tell Gradio what kind of data the function expects. Because we said "text", Gradio automatically renders an HTML text box on the screen.</p>
</li>
<li><p><code>outputs="text"</code>: We tell Gradio what kind of data the function returns. Gradio renders another text box to display the result.</p>
</li>
<li><p><code>demo.launch()</code>: This kicks off a local web server (powered by FastAPI under the hood) and opens the connection to your browser.</p>
</li>
</ul>
<p>Run the script in your terminal:</p>
<pre><code class="language-shell">python 01_greeting_app.py
</code></pre>
<p>You will see an output like <code>Running on local URL: http://127.0.0.1:7860</code>. Open that link in your browser.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/7d1e9f4d-41dd-4bf4-94f6-b124e9c08b68.png" alt="" style="display:block;margin:0 auto" />

<p>Congratulations, you just built your first Gradio app. Go ahead and play around with it. Enter your name, your pet's name, or a random string of characters. It is a small step, but it is time to <em>greet</em> your new life as an AI UI developer.</p>
<p>The <code>gr.Interface</code> class does the heavy lifting here. It takes three crucial arguments:</p>
<ul>
<li><p><code>fn</code>: The Python function to run.</p>
</li>
<li><p><code>inputs</code>: The UI component for the function's arguments.</p>
</li>
<li><p><code>outputs</code>: The UI component for the function's return value.</p>
</li>
</ul>
<p>Gradio inspects this configuration and generates the HTML, wires up the API endpoints, and handles the button clicks for you.</p>
<h2>Convert Terminal Logic into a Web App</h2>
<p>If you have ever built a Python chatbot before, you likely used a <code>while True:</code> loop to capture user input from the terminal continuously. That works, but it scales poorly.</p>
<p>We are going to replace the terminal loop with a Gradio chat interface. To do this, we need to handle conversation state. The Gemini API expects to see the full history of the conversation to answer context-aware questions. Gradio's <code>ChatInterface</code> automatically tracks history, so we just need to map Gradio's history format into the format Gemini expects.</p>
<p>Create a new file named <code>02_basic_chatbot.py</code> for this step:</p>
<pre><code class="language-python">import gradio as gr
from dotenv import load_dotenv
from google import genai
from google.genai import types

# Load environment variables from the .env file
load_dotenv()

# Initialize the Gemini client (it automatically picks up the GEMINI_API_KEY env variable)
client = genai.Client()


def chat_with_ai(user_message, history):
    # Convert Gradio history format to Gemini's expected types.Content format
    contents = []
    for human_text, ai_text in history:
        contents.append(types.Content(role="user", parts=[
                        types.Part.from_text(text=human_text)]))
        contents.append(types.Content(role="model", parts=[
                        types.Part.from_text(text=ai_text)]))

    # Append the current user message
    contents.append(types.Content(role="user", parts=[
                    types.Part.from_text(text=user_message)]))

    # Configure system instructions
    config = types.GenerateContentConfig(
        system_instruction="You are a helpful engineering assistant."
    )

    # Call the free-tier Gemini model
    response = client.models.generate_content(
        model="gemini-2.5-flash",
        contents=contents,
        config=config
    )

    return response.text


# Create the Chat Interface
demo = gr.ChatInterface(
    fn=chat_with_ai,
    title="Gemini Engineering Assistant",
    description="Ask me anything about Python or system design."
)

if __name__ == "__main__":
    demo.launch()
</code></pre>
<p>This file introduces <code>gr.ChatInterface</code>, which is a specialized shortcut for building chatbots. It expects your function to accept exactly two arguments: the new <code>user_message</code> and the <code>history</code>.</p>
<p>The trickiest part here is translating data formats. Gradio 6 formats chat history using OpenAI's standard structure (a list of dictionaries). However, the Gemini API uses its own specific object structure.</p>
<p>Let us break down the <code>for msg in history:</code> loop:</p>
<ol>
<li><p><strong>Role Mapping:</strong> Gradio calls the AI an <code>"assistant"</code>. Gemini calls it a <code>"model"</code>. We use a simple inline <code>if</code> statement to translate this.</p>
</li>
<li><p><strong>Text Extraction:</strong> Gradio supports multimodal chat (images and text together). Because of this, it stores message content as a list of blocks. We use a list comprehension (<code>"".join([...])</code>) to sift through the blocks, find the text ones, and combine them into a single string.</p>
</li>
<li><p><strong>Building Gemini Objects:</strong> We wrap our extracted text and role inside <code>types.Content</code> and <code>types.Part.from_text</code>. This is strictly required by the <code>google-genai</code> library.</p>
</li>
</ol>
<p>Once the history is formatted, we append the brand-new user message, pass it to <code>gemini-3.5-flash</code>, and return the text response. Gradio handles rendering the chat bubbles automatically.</p>
<p>Run it using <code>python 02_basic_chatbot.py</code>.</p>
<p>Play around with the chat. Ask it to explain a Python concept, write a haiku, or help you debug a script. The bottom line here is that you just built a functional web interface for a powerful LLM in under 50 lines of code.</p>
<h2>Understanding Gradio Components</h2>
<p><code>gr.Interface</code> and <code>gr.ChatInterface</code> are great shortcuts, but building custom apps requires knowing the individual puzzle pieces. Gradio provides dozens of UI components.</p>
<p>Here are the most common ones you will use in AI development:</p>
<ul>
<li><p><code>gr.Textbox</code>: Used for standard text entry or displaying plain text outputs. You can configure it to have multiple lines or placeholder text.</p>
</li>
<li><p><code>gr.Chatbot</code>: A specialized display component that renders conversation histories in a familiar text-message bubble format.</p>
</li>
<li><p><code>gr.Button</code>: Triggers Python functions when clicked.</p>
</li>
<li><p><code>gr.Image</code>: Handles image uploads via drag-and-drop or webcam, and can display images generated by computer vision models.</p>
</li>
<li><p><code>gr.File</code>: Allows users to upload documents (PDFs, CSVs, TXT files) and passes the file path directly to your Python script.</p>
</li>
<li><p><code>gr.Markdown</code>: Renders formatted text, tables, and links to make your UI look professional.</p>
</li>
<li><p><code>gr.State</code>: A hidden component that stores variables (like user session data or complex history) across page refreshes without displaying anything on the screen.</p>
</li>
</ul>
<p>These components communicate with your backend automatically. When a user uploads a file, Gradio saves it to a temporary directory and hands your function the file path.</p>
<h2>Understanding Blocks</h2>
<p>The <code>Interface</code> class is rigid. It always puts inputs on the left and outputs on the right. When you want to build a real application, you need control over the layout.</p>
<p>This is why <code>gr.Blocks</code> exists.</p>
<p>Blocks give you a blank canvas. You can arrange components in rows and columns, add tabs, and assign specific click events to specific buttons.</p>
<p>Let us rebuild our chatbot using Blocks to add a custom layout and a "Clear History" button. Create a new file named <code>03_custom_layout.py</code>:</p>
<pre><code class="language-python">import gradio as gr


def respond(message, history):
    # Dummy logic for demonstration
    return f"I received your message: {message}"


with gr.Blocks() as demo:
    gr.Markdown("# Custom Chatbot Layout")

    with gr.Row():
        with gr.Column(scale=4):
            chatbot = gr.Chatbot(height=400)
            msg = gr.Textbox(placeholder="Type a message and press Enter...")

        with gr.Column(scale=1):
            clear_btn = gr.Button("Clear Chat")
            settings = gr.Markdown("### Settings\n(Add dropdowns here later)")

    # Hidden state to store history (Gradio 6 uses list of dicts natively)
    state = gr.State([])

    # Event wiring
    def user_turn(user_message, history):
        # Format the user message exactly how Gradio 6 expects it
        new_msg = {"role": "user", "content": [
            {"type": "text", "text": user_message}]}
        history.append(new_msg)
        return "", history, history  # Returns: clear textbox, update state, update chatbot

    def ai_turn(history):
        # Extract the user's actual text string from the deeply nested history block
        user_message = history[-1]["content"][0]["text"]
        bot_response = respond(user_message, history)

        new_msg = {"role": "assistant", "content": [
            {"type": "text", "text": bot_response}]}
        history.append(new_msg)
        return history, history  # Returns: update state, update chatbot

    # When the user presses Enter in the text box
    msg.submit(user_turn, [msg, state], [msg, state, chatbot], queue=False).then(
        ai_turn, state, [state, chatbot]
    )

    # Clear both the hidden state and the visible UI chatbot
    clear_btn.click(lambda: ([], []), None, [state, chatbot], queue=False)

if __name__ == "__main__":
    demo.launch()
</code></pre>
<p>This file introduces several advanced UI concepts.</p>
<ul>
<li><p><strong>Layout with</strong> <code>with</code> <strong>statements:</strong> <code>gr.Blocks()</code> uses Python's context managers. Everything indented under <code>with gr.Row():</code> will be placed side-by-side horizontally. Everything indented under <code>with gr.Column():</code> will be stacked vertically. The <code>scale</code> argument dictates how wide the columns are relative to each other.</p>
</li>
<li><p><code>gr.State([])</code>: In standard Python, variables inside functions disappear when the function finishes. <code>gr.State</code> creates a persistent, hidden variable attached to the user's browser session. We use it to store our list of message dictionaries.</p>
</li>
<li><p><strong>Event Chaining (</strong><code>.then</code><strong>)</strong>: Look at <code>msg.submit(...)</code>. When a user hits Enter, we first run the <code>user_turn</code> function. This grabs the text, updates the state, and immediately clears the input box so it feels snappy. We use <code>.then(...)</code> to immediately trigger the <code>ai_turn</code> function right after.</p>
</li>
<li><p><strong>Input and Output Arrays</strong>: Notice how <code>user_turn</code> returns three things: <code>"", history, history</code>. These map directly to the output array <code>[msg, state, chatbot]</code>. We are telling Gradio: "Set the textbox to an empty string, set the hidden state to the updated history, and set the visual chatbot to the updated history."</p>
</li>
</ul>
<p>Run the code with <code>python 03_custom_layout.py</code>.</p>
<p>Test this out in your browser. Type a few messages, then hit the "Clear Chat" button to watch the state reset perfectly. Welcome to the Gradio <em>block party</em>.</p>
<h2>Add Streaming Responses</h2>
<p>Have you noticed how modern chat engines print words on the screen one by one? That is called streaming. It prevents the user from staring at a loading spinner for ten seconds while the model generates a long paragraph.</p>
<p>Streaming improves user experience drastically. Gradio supports this natively using Python generators.</p>
<p>Instead of using <code>return</code> to send the final string all at once, we use <code>yield</code> to send incremental updates. Create <code>04_streaming_chatbot.py</code>:</p>
<pre><code class="language-python">import gradio as gr
from dotenv import load_dotenv
from google import genai
from google.genai import types

load_dotenv()
client = genai.Client()


def stream_chat(message, history):
    contents = []
    # History parsing logic remains identical to step 2
    for msg in history:
        role = "model" if msg["role"] == "assistant" else "user"
        text_content = "".join(
            [block["text"] for block in msg["content"] if block["type"] == "text"])
        contents.append(types.Content(role=role, parts=[
                        types.Part.from_text(text=text_content)]))

    contents.append(types.Content(role="user", parts=[
                    types.Part.from_text(text=message)]))

    # Enable streaming in the API call
    response_stream = client.models.generate_content_stream(
        model="gemini-3.5-flash",
        contents=contents
    )

    partial_message = ""
    for chunk in response_stream:
        if chunk.text is not None:
            partial_message += chunk.text
            # Yielding updates the UI immediately
            yield partial_message


demo = gr.ChatInterface(
    fn=stream_chat,
    title="Streaming Gemini Chatbot"
)

if __name__ == "__main__":
    demo.launch()
</code></pre>
<p>The structural logic here is almost identical to our basic chatbot, but the execution is totally different.</p>
<ul>
<li><p><code>generate_content_stream</code>: Instead of calling <code>generate_content</code> (which waits for the whole answer to be ready), we call the streaming version. This returns an iterable stream of small text chunks directly from Google's servers.</p>
</li>
<li><p><strong>The</strong> <code>for</code> <strong>loop</strong>: We iterate over every <code>chunk</code> that arrives from the stream. We take the new text, append it to our <code>partial_message</code> variable, and then call <code>yield partial_message</code>.</p>
</li>
<li><p><code>yield</code> <strong>vs</strong> <code>return</code>: A <code>return</code> statement ends a function immediately. A <code>yield</code> statement pauses the function, sends the current value to Gradio, updates the frontend UI, and then resumes exactly where it left off. This is the magic that creates the typing effect.</p>
</li>
</ul>
<p>Run the file with <code>python 04_streaming_chatbot.py</code>.</p>
<p>Ask the AI a complex question. Watch the text flow in word by word. Play around with it and enjoy that smooth <em>stream of consciousness</em> directly from Gemini.</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/a27b1c10-6c59-4f11-86d2-31c2981bc2a2.gif" alt="" style="display:block;margin:0 auto" />

<h2>Upload Files and Build a Simple AI Document Chat</h2>
<p>One of the most common AI app ideas is "chat with my document." We can build a basic version of this quickly by combining <code>gr.File</code> with our LLM logic.</p>
<p>We will read the contents of an uploaded text file and inject it into Gemini's system instructions. Create <code>05_document_qa.py</code>:</p>
<pre><code class="language-python">import gradio as gr
from dotenv import load_dotenv
from google import genai
from google.genai import types

load_dotenv()
client = genai.Client()


def analyze_document(file_obj, user_question):
    # Prevent crashing if the user clicks Ask without a file
    if file_obj is None:
        return "Please upload a text file first."

    # Read the file text
    with open(file_obj.name, "r", encoding="utf-8") as f:
        file_content = f.read()

    # Inject the file contents directly into the system prompt
    config = types.GenerateContentConfig(
        system_instruction=f"Use this document context to answer questions:\n\n{file_content}"
    )

    response = client.models.generate_content(
        model="gemini-3.5-flash",
        contents=user_question,
        config=config
    )

    return response.text


with gr.Blocks() as demo:
    gr.Markdown("# Document Q&amp;A App")

    with gr.Row():
        file_input = gr.File(label="Upload a .txt file")
        question_input = gr.Textbox(label="Ask a question about the file")

    submit_btn = gr.Button("Ask")

    gr.Markdown("### AI Answer")
    # Using gr.Markdown allows Gemini's bold text, lists, and code blocks to render beautifully
    output_markdown = gr.Markdown(value="Your answer will appear here...")

    submit_btn.click(
        fn=analyze_document,
        inputs=[file_input, question_input],
        outputs=output_markdown  # Send the result straight to the Markdown component
    )

if __name__ == "__main__":
    demo.launch()
</code></pre>
<p>This script bridges file management and prompt engineering, and steps up our UI game.</p>
<ul>
<li><p><code>if file_obj is None:</code>: This is a guard clause. If the user hits the "Ask" button before uploading a file, Gradio passes <code>None</code> to our function. If we try to open <code>None</code>, Python will crash. This clause prevents the crash and returns a helpful warning to the user.</p>
</li>
<li><p><code>file_obj.name</code>: When a user drops a file into a Gradio interface, Gradio does not pass the raw binary data to your function. Instead, it securely saves the file to a temporary directory on your machine and passes you an object. Calling <code>.name</code> retrieves the absolute file path (e.g., <code>/tmp/gradio/some_file.txt</code>), which we can then open normally using standard Python.</p>
</li>
<li><p><strong>System Prompt Injection</strong>: We use an f-string to literally paste the entire text of the file into the <code>system_instruction</code>. We are essentially telling the AI: "Here is everything you need to know. Now, answer the user's question based only on this."</p>
</li>
<li><p><strong>Rendering with</strong> <code>gr.Markdown</code>: LLMs naturally respond with Markdown formatting (like <code>bold text</code> or bulleted lists). If we use a standard <code>gr.Textbox</code>, the user sees raw asterisks and hashes. By assigning <code>gr.Markdown</code> to our <code>outputs</code> array, Gradio parses the formatting automatically. <em>Mark</em> my words, formatted text is infinitely easier to read.</p>
</li>
</ul>
<p>Run the script with <code>python 05_document_qa.py</code>.</p>
<p>Upload a <code>.txt</code> file containing an article, a snippet of code, or some meeting notes, and start asking questions. Play around to see how well Gemini pulls facts from your custom context. You can officially <em>file this under</em> "cool things I built today."</p>
<img src="https://cdn.hashnode.com/uploads/covers/61c1acb4a90dea775da8262b/6e3f0e94-bdee-4910-82a4-b1e8474e1fd0.png" alt="" style="display:block;margin:0 auto" />

<h2>Deploying Gradio Apps</h2>
<p>Building locally is fun, but you eventually need to share your work.</p>
<p>The fastest way to share a prototype is changing your launch command in any of these scripts:</p>
<pre><code class="language-python">demo.launch(share=True)
</code></pre>
<p>This generates a public <code>gradio.live</code> link valid for 72 hours. It tunnels traffic from the public URL directly to the Python script running on your laptop. It is perfect for showing a quick demo to a coworker over Slack.</p>
<p>For permanent deployment, the standard route is <strong>Hugging Face Spaces</strong>. Spaces offers free hosting tailored specifically for Gradio apps. You just create a repository, upload your specific Python file (renamed to <code>app.py</code> for Hugging Face) and a <code>requirements.txt</code> file, and Hugging Face handles the server configuration automatically.</p>
<p>Remember, your <code>.env</code> file is only for local development. When deploying to Hugging Face Spaces, you must set your <code>GEMINI_API_KEY</code> inside the repository's settings as a hidden secret so your app continues working securely in the cloud.</p>
<p>Keep in mind that Gradio is optimized for prototyping and internal tools. A basic Gradio app is not designed to handle thousands of concurrent users or complex authentication systems out of the box. Be realistic about your deployment goals.</p>
<h2>How Gradio Works Internally</h2>
<p>You do not need to know the internals to use Gradio, but understanding them makes debugging much easier.</p>
<p>Under the hood, when you call <code>demo.launch()</code>, Gradio starts a local web server using FastAPI. This server exposes API endpoints based on the functions you defined.</p>
<p>On the frontend, Gradio serves a single-page application (built with Svelte). When a user clicks a button, the Svelte frontend sends an HTTP request to your FastAPI backend. Your Python code runs, processes the data, and returns a JSON response.</p>
<p>If you are using streaming or long-running tasks, Gradio switches from standard HTTP requests to WebSockets. This allows a persistent, two-way connection where your Python script can continuously push text chunks to the browser without waiting for the user to request them.</p>
<h2>Common Beginner Mistakes</h2>
<p>When developers first start building AI UIs, they usually run into the same handful of issues.</p>
<ol>
<li><p><strong>Blocking the UI:</strong> Python runs synchronously by default. If your API call takes 20 seconds, the Gradio UI will freeze for 20 seconds. Use asynchronous functions or generators (<code>yield</code>) to keep the interface responsive.</p>
</li>
<li><p><strong>Forgetting State:</strong> Python variables inside functions reset on every click. If you need to remember data between clicks (like chat history or user choices), you must pass it through a <code>gr.State</code> component or the specialized history arguments.</p>
</li>
<li><p><strong>Exposing API Keys:</strong> Never hardcode your API keys into your Python scripts. Always use the <code>.env</code> approach combined with the <code>python-dotenv</code> package. If you upload a hardcoded key to GitHub, bots will find it in seconds.</p>
</li>
<li><p><strong>Handling Large Files Badly:</strong> Reading massive datasets entirely into memory will crash your app. If a user uploads a 50MB text file, reading it straight into an LLM prompt will trigger context window boundaries or network timeouts.</p>
</li>
</ol>
<h2>When to Use Gradio vs Full Frameworks</h2>
<p>Gradio is a specific tool for a specific job.</p>
<p><strong>Use Gradio when:</strong></p>
<ul>
<li><p>You want to test an AI idea in an afternoon.</p>
</li>
<li><p>You need to share a prototype with non-technical stakeholders.</p>
</li>
<li><p>You are building an internal utility tool for your team.</p>
</li>
<li><p>You want to host a portfolio project on Hugging Face.</p>
</li>
</ul>
<p><strong>Use Streamlit when:</strong></p>
<ul>
<li>Your app is heavily focused on data science, charts, and dashboards rather than pure inputs and outputs. (Streamlit is another great Python UI tool, optimized slightly more for data visualization).</li>
</ul>
<p><strong>Use FastAPI + React (Full Framework) when:</strong></p>
<ul>
<li><p>You are building a production SaaS product.</p>
</li>
<li><p>You need strict user authentication, database management, and complex state routing.</p>
</li>
<li><p>You have thousands of users and need to scale microservices.</p>
</li>
</ul>
<p>Building UIs manually for every AI experiment gets old very quickly. Gradio shines during the discovery phase of software engineering.</p>
<h2>Final Thoughts</h2>
<p>The distance between an idea and a working web app has never been shorter. Gradio became popular in the AI landscape because it eliminated the frontend bottleneck for machine learning engineers.</p>
<p>Using a free-tier API like Gemini means you can experiment with intelligent text generation models endlessly without running up an infrastructure bill. Separating your code into specific scripts like we did makes it easy to push to GitHub, build a portfolio, and reference past work.</p>
<p>You can find all the separate Python scripts we wrote today neatly organized in this <a href="https://github.com/ashutoshkrris/gradio-tutorial">GitHub repository</a>. Feel free to fork it, clone it to your local machine, and use those files as a baseline for your own projects. Take the code examples from this article and experiment. Change the system prompts, tweak the UI blocks, or try uploading different file types.</p>
<p>The fastest way to learn AI engineering is to build things and put them out into the world. Once you turn your Python logic into a working Gradio app, share a screenshot or a screen recording of your project on Twitter/X/LinkedIn. Make sure to tag me at <a href="http://x.com/ashutoshkrris">@ashutoshkrris</a> so I can see what you built and help showcase your work.</p>
<p>You have the tools. Now go build some AI apps.</p>
]]></content:encoded></item><item><title><![CDATA[Spring Boot @Value Property Order Explained]]></title><description><![CDATA[If you’ve ever been in a Spring Boot interview, you’ve probably come across this question:

“Where does Spring Boot look for @Value("${my.property:DEFAULT_VALUE}"), and in what order?”

At first, it might sound straightforward, but it actually tests ...]]></description><link>https://blog.ashutoshkrris.in/spring-boot-value-property-order-explained</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/spring-boot-value-property-order-explained</guid><category><![CDATA[Java]]></category><category><![CDATA[interview questions]]></category><category><![CDATA[interview]]></category><category><![CDATA[Springboot]]></category><category><![CDATA[backend]]></category><category><![CDATA[Backend Development]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Wed, 29 Oct 2025 11:48:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761738465610/ca4a7f84-eba1-4059-b827-39dcc962c77a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you’ve ever been in a Spring Boot interview, you’ve probably come across this question:</p>
<blockquote>
<p>“Where does Spring Boot look for <code>@Value("${my.property:DEFAULT_VALUE}")</code>, and in what order?”</p>
</blockquote>
<p>At first, it might sound straightforward, but it actually tests a developer’s understanding of <strong>how Spring Boot resolves configuration properties</strong> — a concept that directly impacts how applications behave across environments.</p>
<p>Understanding the configuration hierarchy in Spring Boot is essential because it helps you:</p>
<ul>
<li><p>Debug issues when the wrong value is picked up.</p>
</li>
<li><p>Control how environment variables and external configurations override defaults.</p>
</li>
<li><p>Manage different environments such as development, staging, and production in CI/CD pipelines.</p>
</li>
</ul>
<p>In this article, we’ll look at how <code>@Value</code> works, the exact order in which Spring Boot looks for property values, and why this knowledge is crucial for building predictable and maintainable applications.</p>
<h2 id="heading-understanding-the-value-annotation">Understanding the <code>@Value</code> Annotation</h2>
<p>The <code>@Value</code> annotation in Spring Boot is used to <strong>inject values</strong> into fields directly from property sources such as <code>application.properties</code>, <code>application.yml</code>, environment variables, or command-line arguments. It allows you to bind configuration values to variables in your code without hardcoding them.</p>
<p>Here’s a simple example:</p>
<pre><code class="lang-java"><span class="hljs-meta">@Value("${my.property:DEFAULT_VALUE}")</span>
<span class="hljs-keyword">private</span> String myProperty;
</code></pre>
<p>In this example:</p>
<ul>
<li><p><code>my.property</code> is the <strong>key</strong> whose value Spring Boot will try to resolve.</p>
</li>
<li><p><code>DEFAULT_VALUE</code> is the <strong>fallback value</strong> that will be used <strong>if the property is not found</strong> in any configuration source.</p>
</li>
</ul>
<p>This default value mechanism is very useful. It ensures your application does not fail to start even if a configuration is missing. Instead, Spring Boot will inject the specified default, keeping your application stable and predictable.</p>
<p>Using <code>@Value</code> is a simple way to access configuration properties for small or single-value injections. For more complex or grouped configurations, developers often use <code>@ConfigurationProperties</code>, which we’ll discuss later.</p>
<h2 id="heading-where-does-spring-boot-look-for-properties-order-of-resolution">Where Does Spring Boot Look for Properties (Order of Resolution)</h2>
<p>When you use <code>@Value</code> or any other property injection mechanism, Spring Boot doesn’t just look in one place for configuration values. It searches across <strong>multiple sources</strong> in a specific <strong>priority order</strong>.</p>
<p>This order determines which value is finally injected when the same property key appears in different places. The <strong>higher the source is in the list</strong>, the <strong>greater its priority</strong>.</p>
<p>Here’s the general order in which Spring Boot resolves properties (based on the <code>SpringApplication</code> configuration sources):</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Priority</td><td>Source</td><td>Example / Notes</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td><strong>Command-line arguments</strong></td><td>e.g. <code>--my.property=value</code> when running the application</td></tr>
<tr>
<td>2</td><td><strong>Java System properties</strong></td><td>e.g. <code>-Dmy.property=value</code></td></tr>
<tr>
<td>3</td><td><strong>OS environment variables</strong></td><td>e.g. <code>export MY_PROPERTY=value</code></td></tr>
<tr>
<td>4</td><td><strong>Application properties or YAML files</strong></td><td>Located in <code>src/main/resources/application.properties</code> or <code>.yml</code></td></tr>
<tr>
<td>5</td><td><strong>Profile-specific configuration files</strong></td><td>e.g. <code>application-dev.properties</code> when <code>spring.profiles.active=dev</code></td></tr>
<tr>
<td>6</td><td><strong>External configuration files</strong></td><td>Files located in a <code>/config</code> directory outside the packaged JAR</td></tr>
<tr>
<td>7</td><td><strong>JNDI attributes</strong></td><td>Used in servlet containers or enterprise environments</td></tr>
<tr>
<td>8</td><td><strong>Random values</strong></td><td>e.g. <code>${random.uuid}</code>, <code>${random.int}</code> generated by Spring Boot</td></tr>
<tr>
<td>9</td><td><strong>Default value in code</strong></td><td>The fallback provided in <code>@Value("${my.property:default}")</code></td></tr>
</tbody>
</table>
</div><p>Spring Boot checks these sources <strong>in order</strong> — from top to bottom — and uses the <strong>first value it finds</strong> for a given property key.</p>
<p>This hierarchy allows you to easily <strong>override configurations</strong> at runtime without changing your code. For example, values from command-line arguments or environment variables can override those in your application files, which is especially useful for deploying the same codebase to multiple environments like development, testing, and production.</p>
<h2 id="heading-example-demonstration">Example Demonstration</h2>
<p>Let’s look at a simple example to understand how Spring Boot decides which property value to use when multiple sources define the same key.</p>
<p>Imagine the following project structure:</p>
<pre><code class="lang-plaintext">src/
 └─ main/resources/
     ├─ application.properties
     ├─ application-dev.properties
</code></pre>
<h3 id="heading-step-1-define-properties-in-both-files">Step 1: Define properties in both files</h3>
<p><strong>application.properties</strong></p>
<pre><code class="lang-java">my.property=HelloFromApplication
</code></pre>
<p><strong>application-dev.properties</strong></p>
<pre><code class="lang-java">my.property=HelloFromDevProfile
</code></pre>
<h3 id="heading-step-2-use-value-in-your-code">Step 2: Use <code>@Value</code> in your code</h3>
<pre><code class="lang-java"><span class="hljs-meta">@Value("${my.property:DefaultHello}")</span>
<span class="hljs-keyword">private</span> String message;
</code></pre>
<h3 id="heading-step-3-run-the-application-with-different-configurations">Step 3: Run the application with different configurations</h3>
<h4 id="heading-case-1-default-profile-no-active-profile">Case 1: Default profile (no active profile)</h4>
<p>If you run your Spring Boot app normally:</p>
<pre><code class="lang-bash">java -jar myapp.jar
</code></pre>
<p>Spring Boot will load <code>application.properties</code> and inject the value:</p>
<pre><code class="lang-bash">HelloFromApplication
</code></pre>
<h4 id="heading-case-2-active-profile-set-to-dev">Case 2: Active profile set to “dev”</h4>
<p>If you run:</p>
<pre><code class="lang-bash">java -jar myapp.jar --spring.profiles.active=dev
</code></pre>
<p>Spring Boot will load both <code>application.properties</code> and <code>application-dev.properties</code>, but <strong>the profile-specific file has higher priority</strong>.<br />So the value becomes:</p>
<pre><code class="lang-bash">HelloFromDevProfile
</code></pre>
<h4 id="heading-case-3-override-from-the-command-line">Case 3: Override from the command line</h4>
<p>Now, if you run:</p>
<pre><code class="lang-bash">java -jar myapp.jar --my.property=HelloFromCLI
</code></pre>
<p>Command-line arguments take the <strong>highest priority</strong>, so this overrides everything else:</p>
<pre><code class="lang-bash">HelloFromCLI
</code></pre>
<h4 id="heading-case-4-no-property-found-anywhere">Case 4: No property found anywhere</h4>
<p>If you remove the property from all configuration files and don’t pass it as an argument, Spring Boot uses the default value given in the code:</p>
<pre><code class="lang-bash">DefaultHello
</code></pre>
<p>This example shows how Spring Boot’s property resolution order allows flexible configuration management. You can define defaults in your code, keep environment-specific values in property files, and still override them at runtime when needed.</p>
<h2 id="heading-common-pitfalls">Common Pitfalls</h2>
<p>Even though Spring Boot’s configuration system is powerful, it’s easy to run into small mistakes that cause unexpected behavior. Here are some common pitfalls developers face when working with <code>@Value</code> and property resolution.</p>
<h3 id="heading-1-forgetting-to-set-the-active-profile">1. Forgetting to Set the Active Profile</h3>
<p>Spring Boot supports profile-specific configuration files, such as <code>application-dev.properties</code> or <code>application-prod.properties</code>.<br />However, these files are only used when the corresponding profile is active. If you forget to set the profile, Spring Boot will ignore those files and fall back to the default <code>application.properties</code>.</p>
<p>For example:</p>
<pre><code class="lang-bash">java -jar myapp.jar --spring.profiles.active=dev
</code></pre>
<p>Without this argument, your <code>application-dev.properties</code> file won’t be loaded at all.</p>
<h3 id="heading-2-unintentional-property-overrides">2. Unintentional Property Overrides</h3>
<p>Because Spring Boot merges multiple property sources, it’s possible to <strong>accidentally override</strong> values from one source with another.<br />A common case is when an environment variable or command-line argument unintentionally replaces a property defined in your configuration file.</p>
<p>For instance, if your system has an environment variable named <code>MY_PROPERTY</code>, it might override the <code>my.property</code> key from your <code>.properties</code> file. Always check the effective configuration when debugging unexpected values.</p>
<h3 id="heading-3-confusing-value-and-configurationproperties">3. Confusing <code>@Value</code> and <code>@ConfigurationProperties</code></h3>
<p>Both <code>@Value</code> and <code>@ConfigurationProperties</code> are used to inject configuration values, but they serve different purposes.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td><code>@Value</code></td><td><code>@ConfigurationProperties</code></td></tr>
</thead>
<tbody>
<tr>
<td>Best for</td><td>Single values</td><td>Grouped or structured properties</td></tr>
<tr>
<td>Type safety</td><td>Limited</td><td>Strong (binds directly to fields)</td></tr>
<tr>
<td>Supports validation</td><td>No</td><td>Yes</td></tr>
<tr>
<td>Preferred for large configs</td><td>❌</td><td>✅</td></tr>
</tbody>
</table>
</div><ul>
<li><p>Use <code>@Value</code> when you only need a few properties.</p>
</li>
<li><p>Use <code>@ConfigurationProperties</code> when dealing with a group of related configurations (for example, database settings or API credentials).</p>
</li>
</ul>
<p>Choosing the right one helps keep your configuration clean, organized, and easy to maintain.</p>
<h2 id="heading-interview-tip-summary">Interview Tip / Summary</h2>
<p>When asked about property resolution in Spring Boot interviews, it’s not just about recalling the list — it’s about showing that you understand how and why it works that way.</p>
<p>Here are the key points to keep in mind:</p>
<ol>
<li><p><strong>Spring Boot merges multiple property sources</strong> — it doesn’t rely on a single file.</p>
</li>
<li><p><strong>Higher-priority sources override lower-priority ones</strong> — values from the command line or environment variables can replace those in your application files.</p>
</li>
<li><p><code>@Value("${my.property:DEFAULT}")</code> provides a safety net — the default value ensures your application runs even when the property is missing.</p>
</li>
</ol>
<h3 id="heading-quick-mnemonic-to-remember-the-order">Quick Mnemonic to Remember the Order</h3>
<p>You can remember the lookup order with this simple phrase:</p>
<blockquote>
<p><strong>“CLI → System → Env → App → Default”</strong></p>
</blockquote>
<p>Or think of it as:</p>
<pre><code class="lang-plaintext">Command-line arguments
↓
System properties (-D)
↓
Environment variables
↓
Application files (.properties / .yml)
↓
Default value in code
</code></pre>
<p>If you end your interview answer with a short, clear explanation like this:</p>
<blockquote>
<p>“Spring Boot checks multiple property sources in a specific order — starting from command-line arguments, system properties, environment variables, and application files, before finally using the default value provided in code.”</p>
</blockquote>
<p>—you’ll leave a confident and lasting impression.</p>
<h2 id="heading-frequently-asked-questions-faq">Frequently Asked Questions (FAQ)</h2>
<h3 id="heading-1-what-happens-if-a-property-is-missing-and-no-default-value-is-given">1. What happens if a property is missing and no default value is given?</h3>
<p>If a property key cannot be found in any configuration source <strong>and</strong> you haven’t provided a default value in your <code>@Value</code> expression, Spring Boot will throw an exception during startup.<br />For example:</p>
<pre><code class="lang-java"><span class="hljs-meta">@Value("${my.property}")</span>
<span class="hljs-keyword">private</span> String value;
</code></pre>
<p>If <code>my.property</code> is not defined anywhere, you’ll see an error like:</p>
<pre><code class="lang-bash">Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder <span class="hljs-string">'my.property'</span> <span class="hljs-keyword">in</span> value <span class="hljs-string">"<span class="hljs-variable">${my.property}</span>"</span>
</code></pre>
<p>To prevent this, always provide a fallback value:</p>
<pre><code class="lang-java"><span class="hljs-meta">@Value("${my.property:DefaultValue}")</span>
<span class="hljs-keyword">private</span> String value;
</code></pre>
<p>This ensures your application starts smoothly, even when the property is missing.</p>
<h3 id="heading-2-how-does-configurationproperties-differ-from-value">2. How does <code>@ConfigurationProperties</code> differ from <code>@Value</code>?</h3>
<p>While both are used to inject configuration values, they are suited to different use cases:</p>
<ul>
<li><p><code>@Value</code> is ideal for <strong>single values</strong> or small configurations.<br />  Example:</p>
<pre><code class="lang-java">  <span class="hljs-meta">@Value("${server.port:8080}")</span>
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> port;
</code></pre>
</li>
<li><p><code>@ConfigurationProperties</code> is better for <strong>structured or grouped configurations</strong>, such as database or API settings. It binds multiple related properties into a single Java object and supports validation.</p>
<p>  Example:</p>
<pre><code class="lang-java">  <span class="hljs-meta">@ConfigurationProperties(prefix = "app")</span>
  <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppConfig</span> </span>{
      <span class="hljs-keyword">private</span> String name;
      <span class="hljs-keyword">private</span> String version;
  }
</code></pre>
</li>
</ul>
<p>In short, use <code>@Value</code> for simple injections and <code>@ConfigurationProperties</code> for larger, type-safe configurations.</p>
<h3 id="heading-3-can-we-override-properties-at-runtime">3. Can we override properties at runtime?</h3>
<p>Yes, you can override properties <strong>at runtime</strong> without changing your code.<br />Spring Boot allows this through various property sources, such as:</p>
<ul>
<li><p>Command-line arguments</p>
<pre><code class="lang-bash">  java -jar myapp.jar --server.port=9090
</code></pre>
</li>
<li><p>Environment variables</p>
<pre><code class="lang-bash">  <span class="hljs-built_in">export</span> SERVER_PORT=9090
</code></pre>
</li>
<li><p>System properties</p>
<pre><code class="lang-bash">  java -Dserver.port=9090 -jar myapp.jar
</code></pre>
</li>
</ul>
<p>These dynamic overrides are particularly useful in <strong>CI/CD pipelines</strong> or <strong>cloud environments</strong>, where configurations may differ between development, staging, and production.</p>
]]></content:encoded></item><item><title><![CDATA[Core Java Interview Questions: Complete Guide with Answers and Examples]]></title><description><![CDATA[Mastering Core Java is essential for cracking technical interviews at top tech companies. Whether you’re preparing for coding rounds, design discussions, or scenario-based questions, having a solid grasp of Java fundamentals, memory management, multi...]]></description><link>https://blog.ashutoshkrris.in/core-java-interview-questions-complete-guide-with-answers-and-examples</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/core-java-interview-questions-complete-guide-with-answers-and-examples</guid><category><![CDATA[Java]]></category><category><![CDATA[interview]]></category><category><![CDATA[interview questions]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Wed, 15 Oct 2025 10:52:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761403045450/70cdbaf6-8417-4727-a9b8-0cada8bfe8a4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Mastering Core Java is essential for cracking technical interviews at top tech companies. Whether you’re preparing for <strong>coding rounds, design discussions, or scenario-based questions</strong>, having a solid grasp of <strong>Java fundamentals, memory management, multithreading, collections, and design patterns</strong> can set you apart.</p>
<p>This <strong>comprehensive guide covers all the essential Core Java interview questions in 2025</strong>, with clear explanations, comparisons, and <strong>code examples</strong>. From <strong>OOP principles to Java 8 features, JVM internals, and practical real-world scenarios</strong>, you’ll get a complete overview of the concepts that interviewers frequently test.</p>
<p>Use this guide to <strong>boost your Java knowledge, strengthen problem-solving skills, and confidently tackle interviews</strong>, making sure you’re well-prepared for both theoretical and hands-on coding rounds.</p>
<h2 id="heading-object-oriented-programming-concepts">Object Oriented Programming Concepts</h2>
<h3 id="heading-1-what-are-the-principles-of-oop"><strong>1. What are the principles of OOP?</strong></h3>
<p>OOP (Object-Oriented Programming) is based on four main principles:</p>
<ol>
<li><p><strong>Encapsulation</strong> – Bundling data and methods that operate on that data into a single unit (class).<br /> <em>Example:</em> Private fields with public getters/setters.</p>
</li>
<li><p><strong>Abstraction</strong> – Hiding internal implementation details and exposing only essential features.<br /> <em>Example:</em> Abstract classes and interfaces.</p>
</li>
<li><p><strong>Inheritance</strong> – Reusing properties and methods from an existing class into a new class.<br /> <em>Example:</em> <code>class Dog extends Animal</code></p>
</li>
<li><p><strong>Polymorphism</strong> – The ability of objects to take multiple forms.<br /> <em>Example:</em> Method overriding where the same method behaves differently in different subclasses.</p>
</li>
</ol>
<p>These principles together make code <strong>modular, extensible, and maintainable</strong>.</p>
<h3 id="heading-2-difference-between-abstraction-and-encapsulation"><strong>2. Difference between abstraction and encapsulation</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>Abstraction</strong></td><td><strong>Encapsulation</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Purpose</strong></td><td>Focuses on hiding implementation details</td><td>Focuses on bundling data and behavior</td></tr>
<tr>
<td><strong>Achieved By</strong></td><td>Abstract classes and interfaces</td><td>Access modifiers (private, public, etc.)</td></tr>
<tr>
<td><strong>Concerned With</strong></td><td>Design level</td><td>Implementation level</td></tr>
<tr>
<td><strong>Example</strong></td><td>Hiding database connection details behind an interface</td><td>Making class variables private and exposing getters/setters</td></tr>
</tbody>
</table>
</div><p><strong>In short:</strong><br />Abstraction hides <em>what</em> is done, Encapsulation hides <em>how</em> it’s done.</p>
<h3 id="heading-3-what-is-inheritance-how-is-it-implemented-in-java"><strong>3. What is inheritance? How is it implemented in Java?</strong></h3>
<p><strong>Inheritance</strong> allows one class to inherit properties and behaviors from another, promoting code reuse.</p>
<p>In Java:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Parent</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">greet</span><span class="hljs-params">()</span> </span>{ System.out.println(<span class="hljs-string">"Hello!"</span>); }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Child</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Parent</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">greetChild</span><span class="hljs-params">()</span> </span>{ System.out.println(<span class="hljs-string">"Hi from Child!"</span>); }
}
</code></pre>
<p>Here, <code>Child</code> inherits the <code>greet()</code> method from <code>Parent</code>.</p>
<p><strong>Types of inheritance in Java:</strong></p>
<ul>
<li><p>Single</p>
</li>
<li><p>Multilevel</p>
</li>
<li><p>Hierarchical</p>
</li>
</ul>
<blockquote>
<p>Note: Java does <strong>not support multiple inheritance with classes</strong> to avoid ambiguity, but supports it with interfaces.</p>
</blockquote>
<h3 id="heading-4-what-is-polymorphism-types"><strong>4. What is polymorphism? Types?</strong></h3>
<p>Polymorphism allows an object to behave differently based on context.</p>
<p><strong>Types:</strong></p>
<ol>
<li><p><strong>Compile-time polymorphism (Method Overloading):</strong></p>
<ul>
<li><p>Same method name, different parameter lists.</p>
</li>
<li><p>Resolved at compile-time.</p>
</li>
</ul>
</li>
</ol>
<pre><code class="lang-java">    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">show</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a)</span> </span>{}
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">show</span><span class="hljs-params">(String b)</span> </span>{}
</code></pre>
<ol start="2">
<li><p><strong>Runtime polymorphism (Method Overriding):</strong></p>
<ul>
<li><p>Subclass provides a new implementation of a parent method.</p>
</li>
<li><p>Resolved at runtime using <strong>dynamic method dispatch</strong>.</p>
</li>
</ul>
</li>
</ol>
<p>Polymorphism improves flexibility and scalability in OOP systems.</p>
<h3 id="heading-5-what-is-method-overloading-vs-overriding"><strong>5. What is method overloading vs overriding?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>Method Overloading</strong></td><td><strong>Method Overriding</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>When</strong></td><td>Compile-time</td><td>Runtime</td></tr>
<tr>
<td><strong>Class Relationship</strong></td><td>Same class</td><td>Parent-child classes</td></tr>
<tr>
<td><strong>Parameters</strong></td><td>Must differ in type/number/order</td><td>Must be same</td></tr>
<tr>
<td><strong>Return Type</strong></td><td>Can differ</td><td>Must be same or covariant</td></tr>
<tr>
<td><strong>Static Binding</strong></td><td>Yes</td><td>No (uses dynamic binding)</td></tr>
</tbody>
</table>
</div><p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-comment">// Overloading</span>
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">add</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span> </span>{}
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">add</span><span class="hljs-params">(<span class="hljs-keyword">double</span> a, <span class="hljs-keyword">double</span> b)</span> </span>{}

<span class="hljs-comment">// Overriding</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">A</span> </span>{ 
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">show</span><span class="hljs-params">()</span> </span>{} 
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">B</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">A</span> </span>{ 
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">show</span><span class="hljs-params">()</span> </span>{} 
}
</code></pre>
<h3 id="heading-6-can-we-override-static-methods"><strong>6. Can we override static methods?</strong></h3>
<p>No.<br />Static methods are <strong>bound at compile-time</strong> (using class reference), not runtime (using object).</p>
<p>If a subclass defines a static method with the same name as the parent class’s static method, it <strong>hides</strong> the parent method — it’s not overriding.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Parent</span> </span>{ 
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">greet</span><span class="hljs-params">()</span> </span>{} 
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Child</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Parent</span> </span>{ 
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">greet</span><span class="hljs-params">()</span> </span>{} 
} <span class="hljs-comment">// Method hiding</span>
</code></pre>
<h3 id="heading-7-can-a-constructor-be-overridden"><strong>7. Can a constructor be overridden?</strong></h3>
<p>No.<br />Constructors are <strong>not inherited</strong>, so overriding doesn’t apply.</p>
<p>However, constructors can be <strong>overloaded</strong> — a class can have multiple constructors with different parameter lists.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
    Person() {}
    Person(String name) {}
}
</code></pre>
<h3 id="heading-8-why-use-interfaces-instead-of-abstract-classes"><strong>8. Why use interfaces instead of abstract classes?</strong></h3>
<p>Interfaces are preferred when you want to <strong>define a contract</strong> that multiple unrelated classes can implement.</p>
<p><strong>Key reasons:</strong></p>
<ul>
<li><p>Java supports <strong>multiple interface inheritance</strong>, but not multiple class inheritance.</p>
</li>
<li><p>Promotes <strong>loose coupling</strong> — implementation can vary independently.</p>
</li>
<li><p>Ideal for defining <strong>APIs, services, or capabilities</strong> (e.g., <code>Comparable</code>, <code>Runnable</code>).</p>
</li>
</ul>
<p><strong>Example:</strong><br />A class can <code>implements Serializable, Comparable</code> but can only <code>extends</code> one abstract class.</p>
<h3 id="heading-9-interface-vs-abstract-class"><strong>9. Interface vs Abstract Class</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>Interface</strong></td><td><strong>Abstract Class</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Inheritance</strong></td><td>Multiple allowed</td><td>Single allowed</td></tr>
<tr>
<td><strong>Contains</strong></td><td>Abstract methods + constants (Java 8+: default &amp; static methods too)</td><td>Can have abstract &amp; concrete methods</td></tr>
<tr>
<td><strong>Variables</strong></td><td><code>public static final</code> by default</td><td>Can be instance variables</td></tr>
<tr>
<td><strong>Constructor</strong></td><td>Not allowed</td><td>Allowed</td></tr>
<tr>
<td><strong>Use Case</strong></td><td>When defining behavior/contract</td><td>When defining base class with partial implementation</td></tr>
</tbody>
</table>
</div><p>In modern Java, interfaces are often used to define <strong>capabilities</strong>, while abstract classes define <strong>common base logic</strong>.</p>
<h3 id="heading-10-can-we-create-an-object-of-abstract-class-or-interface"><strong>10. Can we create an object of abstract class or interface?</strong></h3>
<p>No, both <strong>cannot be instantiated</strong> directly.<br />They serve as blueprints for subclasses or implementing classes.</p>
<p>However, you can create:</p>
<ul>
<li><strong>Anonymous inner classes</strong> or <strong>lambda expressions</strong> that provide concrete implementations.</li>
</ul>
<pre><code class="lang-java">Runnable r = <span class="hljs-keyword">new</span> Runnable() {
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{ System.out.println(<span class="hljs-string">"Running..."</span>); }
};
</code></pre>
<p>Here, an <strong>anonymous implementation</strong> of the interface is created.</p>
<h2 id="heading-java-basics">Java Basics</h2>
<h3 id="heading-1-what-is-the-java-virtual-machine-jvm"><strong>1. What is the Java Virtual Machine (JVM)?</strong></h3>
<p>The <strong>JVM (Java Virtual Machine)</strong> is an abstract machine that executes Java bytecode.<br />It provides a <strong>runtime environment</strong> for Java applications and is platform-dependent.</p>
<p><strong>Key responsibilities:</strong></p>
<ul>
<li><p><strong>Loading</strong>: Uses the ClassLoader to load class files.</p>
</li>
<li><p><strong>Verifying</strong>: Ensures bytecode security.</p>
</li>
<li><p><strong>Executing</strong>: Uses the Just-In-Time (JIT) compiler to convert bytecode to native code.</p>
</li>
<li><p><strong>Memory Management</strong>: Allocates and manages heap, stack, and garbage collection.</p>
</li>
</ul>
<p>In short:<br />👉 <strong>Java code → compiled to bytecode → executed by JVM → runs on any OS (platform independence).</strong></p>
<h3 id="heading-2-explain-jre-vs-jdk-vs-jvm"><strong>2. Explain JRE vs JDK vs JVM.</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Component</strong></td><td><strong>Full Form</strong></td><td><strong>Purpose</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>JVM</strong></td><td>Java Virtual Machine</td><td>Executes Java bytecode</td></tr>
<tr>
<td><strong>JRE</strong></td><td>Java Runtime Environment</td><td>Contains JVM + libraries required to run Java apps</td></tr>
<tr>
<td><strong>JDK</strong></td><td>Java Development Kit</td><td>Contains JRE + development tools (compiler, debugger, etc.)</td></tr>
</tbody>
</table>
</div><p><strong>Relationship:</strong><br />👉 <strong>JDK = JRE + development tools</strong><br />👉 <strong>JRE = JVM + libraries</strong></p>
<h3 id="heading-3-what-is-the-role-of-main-method-in-java"><strong>3. What is the role of main() method in Java?</strong></h3>
<p><code>main()</code> is the <strong>entry point</strong> of any standalone Java application.<br />Signature:</p>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span></span>
</code></pre>
<p><strong>Breakdown:</strong></p>
<ul>
<li><p><code>public</code>: Accessible by JVM.</p>
</li>
<li><p><code>static</code>: JVM can call it without creating an object.</p>
</li>
<li><p><code>void</code>: Doesn’t return any value.</p>
</li>
<li><p><code>String[] args</code>: Accepts command-line arguments.</p>
</li>
</ul>
<p>Without <code>main()</code>, the program doesn’t have a starting point.</p>
<h3 id="heading-4-what-happens-if-the-main-method-is-not-static"><strong>4. What happens if the main() method is not static?</strong></h3>
<p>If <code>main()</code> is <strong>not static</strong>, the JVM cannot invoke it directly because no object of the class exists yet.<br />This leads to a <strong>runtime error</strong> like:</p>
<pre><code class="lang-java">Error: Main method is not <span class="hljs-keyword">static</span> in <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainClass</span></span>
</code></pre>
<p>JVM needs <code>main()</code> to be static so that it can call it <strong>without object instantiation</strong>.</p>
<h3 id="heading-5-can-java-run-without-main"><strong>5. Can Java run without main()?</strong></h3>
<p>In modern Java (Java 7+), <strong>no</strong> — every standalone program needs a <code>main()</code> method.</p>
<p>Earlier (in applets or servlet containers), Java classes could be run without <code>main()</code> because:</p>
<ul>
<li><p>Applets start with the <code>init()</code> method.</p>
</li>
<li><p>Servlets are loaded and managed by a container (<code>init()</code>, <code>service()</code>, <code>destroy()</code>).</p>
</li>
</ul>
<p>For normal console applications → <strong>main() is mandatory</strong>.</p>
<h2 id="heading-memory-management">Memory Management</h2>
<h3 id="heading-1-explain-java-memory-model"><strong>1. Explain Java memory model.</strong></h3>
<p>The <strong>Java Memory Model (JMM)</strong> defines how Java threads interact through memory — how variables are read/written, and how visibility is ensured in concurrent execution.</p>
<p>It divides memory into:</p>
<ul>
<li><p><strong>Heap:</strong> Stores objects and their instance variables (shared across threads).</p>
</li>
<li><p><strong>Stack:</strong> Each thread has its own stack storing method calls and local variables.</p>
</li>
<li><p><strong>Method Area (Metaspace in Java 8+):</strong> Stores class-level metadata like method definitions and constant pool.</p>
</li>
<li><p><strong>PC Register:</strong> Holds address of current executing instruction.</p>
</li>
<li><p><strong>Native Method Stack:</strong> Used for native (non-Java) code execution.</p>
</li>
</ul>
<p>The JMM ensures <strong>visibility</strong>, <strong>ordering</strong>, and <strong>atomicity</strong> across threads using keywords like <code>volatile</code>, <code>synchronized</code>, and <code>final</code>.</p>
<h3 id="heading-2-what-is-heap-vs-stack"><strong>2. What is heap vs stack?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Aspect</strong></td><td><strong>Heap</strong></td><td><strong>Stack</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Stores</strong></td><td>Objects, instance variables</td><td>Local variables, method calls</td></tr>
<tr>
<td><strong>Shared?</strong></td><td>Shared among all threads</td><td>Each thread has its own stack</td></tr>
<tr>
<td><strong>Lifetime</strong></td><td>Exists until object is garbage collected</td><td>Exists until method completes</td></tr>
<tr>
<td><strong>Managed By</strong></td><td>Garbage Collector</td><td>JVM automatically manages</td></tr>
<tr>
<td><strong>Access Speed</strong></td><td>Slower</td><td>Faster</td></tr>
</tbody>
</table>
</div><p>Example:</p>
<pre><code class="lang-java"><span class="hljs-keyword">int</span> x = <span class="hljs-number">10</span>;            <span class="hljs-comment">// stored in stack</span>
Person p = <span class="hljs-keyword">new</span> Person(); <span class="hljs-comment">// object p in heap, reference in stack</span>
</code></pre>
<h3 id="heading-3-what-is-permgen-and-metaspace"><strong>3. What is PermGen and Metaspace?</strong></h3>
<ul>
<li><p><strong>PermGen (Permanent Generation):</strong><br />  Used before Java 8 to store class metadata, static variables, and interned strings.<br />  Had a <strong>fixed size</strong>, which could cause <code>OutOfMemoryError: PermGen space</code>.</p>
</li>
<li><p><strong>Metaspace (Java 8+):</strong><br />  Replaced PermGen. It stores <strong>class metadata</strong> in <strong>native memory</strong> (not heap).<br />  Grows dynamically as needed, reducing memory errors.</p>
</li>
</ul>
<p>✅ <strong>In short:</strong> Metaspace is a more flexible, dynamic replacement for PermGen.</p>
<h3 id="heading-4-what-is-garbage-collection-how-does-it-work"><strong>4. What is garbage collection? How does it work?</strong></h3>
<p><strong>Garbage Collection (GC)</strong> is an automatic memory management process that reclaims memory from objects no longer reachable by any reference.</p>
<p><strong>How it works:</strong></p>
<ol>
<li><p>JVM identifies <strong>unreachable objects</strong> (not referenced anywhere).</p>
</li>
<li><p>GC frees that memory space.</p>
</li>
<li><p>Memory is reused for new objects.</p>
</li>
</ol>
<p><strong>GC Algorithms:</strong></p>
<ul>
<li><p><strong>Serial GC</strong> (single-threaded, small apps)</p>
</li>
<li><p><strong>Parallel GC</strong> (multi-threaded)</p>
</li>
<li><p><strong>G1 GC (Garbage First)</strong> – default in Java 9+, low pause time collector.</p>
</li>
</ul>
<p><strong>Phases:</strong></p>
<ul>
<li><p><strong>Mark:</strong> Identify live objects.</p>
</li>
<li><p><strong>Sweep/Compact:</strong> Remove dead objects and defragment memory.</p>
</li>
</ul>
<p>Developers can trigger GC via <code>System.gc()</code>, but JVM decides the actual execution time.</p>
<h3 id="heading-5-finalize-method-how-and-when-is-it-called"><strong>5. Finalize method – how and when is it called?</strong></h3>
<p><code>finalize()</code> is a method defined in the <code>Object</code> class:</p>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">finalize</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Throwable</span>
</code></pre>
<p>It’s called by the <strong>Garbage Collector</strong> before reclaiming an object’s memory — a last chance to release resources.</p>
<p><strong>However:</strong></p>
<ul>
<li><p>Execution is <strong>not guaranteed</strong> or <strong>timely</strong>.</p>
</li>
<li><p>It might <strong>never be called</strong> if the program exits before GC runs.</p>
</li>
</ul>
<p>✅ Since Java 9, <code>finalize()</code> is <strong>deprecated</strong>.<br />Modern alternatives:</p>
<ul>
<li><p>Use <code>try-with-resources</code> for closing streams.</p>
</li>
<li><p>Implement <code>AutoCloseable</code> for cleanup logic.</p>
</li>
</ul>
<h2 id="heading-access-modifiers">Access Modifiers</h2>
<h3 id="heading-1-difference-between-private-protected-public-and-default"><strong>1. Difference between private, protected, public, and default</strong></h3>
<p>Java provides four access levels to control visibility of classes, methods, and variables.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Modifier</strong></td><td><strong>Within Class</strong></td><td><strong>Within Package</strong></td><td><strong>Subclass (Other Package)</strong></td><td><strong>Outside Package</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>private</strong></td><td>✅</td><td>❌</td><td>❌</td><td>❌</td></tr>
<tr>
<td><strong>default</strong> <em>(no modifier)</em></td><td>✅</td><td>✅</td><td>❌</td><td>❌</td></tr>
<tr>
<td><strong>protected</strong></td><td>✅</td><td>✅</td><td>✅</td><td>❌</td></tr>
<tr>
<td><strong>public</strong></td><td>✅</td><td>✅</td><td>✅</td><td>✅</td></tr>
</tbody>
</table>
</div><p><strong>Summary:</strong></p>
<ul>
<li><p><strong>private</strong> → Most restrictive; used for encapsulation.</p>
</li>
<li><p><strong>default</strong> → Accessible within the same package.</p>
</li>
<li><p><strong>protected</strong> → Visible to subclasses even if they’re in different packages.</p>
</li>
<li><p><strong>public</strong> → Accessible from anywhere.</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> age;
    <span class="hljs-keyword">protected</span> String name;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">greet</span><span class="hljs-params">()</span> </span>{}
}
</code></pre>
<h3 id="heading-2-can-a-class-be-private-in-java"><strong>2. Can a class be private in Java?</strong></h3>
<p>Top-level (outer) classes <strong>cannot be private</strong> — they must be either <strong>public</strong> or <strong>default</strong>.</p>
<p>However, <strong>inner classes</strong> can be private.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Outer</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Inner</span> </span>{   <span class="hljs-comment">// ✅ allowed</span>
        <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">show</span><span class="hljs-params">()</span> </span>{ System.out.println(<span class="hljs-string">"Inner"</span>); }
    }
}
</code></pre>
<p>If a top-level class were private, <strong>no other class</strong> (even in the same package) could access it — defeating the purpose of reusability.</p>
<h3 id="heading-3-what-are-static-blocks"><strong>3. What are static blocks?</strong></h3>
<p>A <strong>static block</strong> in Java is used for <strong>class-level initialization</strong>.<br />It runs <strong>once</strong>, when the class is <strong>first loaded</strong> into memory (before any constructor or object creation).</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DatabaseConnection</span> </span>{
    <span class="hljs-keyword">static</span> {
        System.out.println(<span class="hljs-string">"Initializing DB connection..."</span>);
    }
}
</code></pre>
<p><strong>Use cases:</strong></p>
<ul>
<li><p>Initialize static variables.</p>
</li>
<li><p>Load configurations.</p>
</li>
<li><p>Perform one-time setup (e.g., registering JDBC drivers).</p>
</li>
</ul>
<p><strong>Order of execution:</strong></p>
<ol>
<li><p>Static variables.</p>
</li>
<li><p>Static blocks (in order of appearance).</p>
</li>
<li><p>Constructors (when object is created).</p>
</li>
</ol>
<h2 id="heading-exception-handling">Exception Handling</h2>
<h3 id="heading-1-checked-vs-unchecked-exceptions"><strong>1. Checked vs Unchecked Exceptions?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Type</strong></td><td><strong>Checked Exception</strong></td><td><strong>Unchecked Exception</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Inheritance</strong></td><td>Subclass of <code>Exception</code> (excluding <code>RuntimeException</code>)</td><td>Subclass of <code>RuntimeException</code></td></tr>
<tr>
<td><strong>Checked at</strong></td><td>Compile-time</td><td>Runtime</td></tr>
<tr>
<td><strong>Handling Required?</strong></td><td>Must be handled or declared using <code>throws</code></td><td>Optional</td></tr>
<tr>
<td><strong>Examples</strong></td><td><code>IOException</code>, <code>SQLException</code>, <code>FileNotFoundException</code></td><td><code>NullPointerException</code>, <code>ArithmeticException</code>, <code>ArrayIndexOutOfBoundsException</code></td></tr>
</tbody>
</table>
</div><p><strong>Key point:</strong><br />Checked exceptions represent <strong>recoverable errors</strong>, while unchecked ones indicate <strong>programming bugs</strong> (e.g., null access).</p>
<h3 id="heading-2-difference-between-throw-and-throws"><strong>2. Difference between throw and throws?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Keyword</strong></td><td><code>throw</code></td><td><code>throws</code></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Purpose</strong></td><td>Used to actually throw an exception</td><td>Declares that a method may throw exceptions</td></tr>
<tr>
<td><strong>Usage Place</strong></td><td>Inside method body</td><td>In method signature</td></tr>
<tr>
<td><strong>Follows</strong></td><td>Single exception instance</td><td>One or more exception classes</td></tr>
<tr>
<td><strong>Example</strong></td><td><code>throw new IOException("File not found");</code></td><td><code>void readFile() throws IOException {}</code></td></tr>
</tbody>
</table>
</div><p>Example:</p>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">readFile</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> IOException </span>{
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IOException(<span class="hljs-string">"Error reading file"</span>);
}
</code></pre>
<h3 id="heading-3-can-we-have-try-block-without-catchfinally"><strong>3. Can we have try block without catch/finally?</strong></h3>
<p>No ❌<br />A <code>try</code> block must be followed by at least <strong>one</strong> of the following:</p>
<ul>
<li><p>A <code>catch</code> block</p>
</li>
<li><p>A <code>finally</code> block</p>
</li>
</ul>
<p>However, <code>try-finally</code> without <code>catch</code> is valid:</p>
<pre><code class="lang-java"><span class="hljs-keyword">try</span> {
    System.out.println(<span class="hljs-string">"Try block"</span>);
} <span class="hljs-keyword">finally</span> {
    System.out.println(<span class="hljs-string">"Cleanup code"</span>);
}
</code></pre>
<p>This ensures cleanup executes even if no exception occurs.</p>
<h3 id="heading-4-what-is-the-use-of-finally-block"><strong>4. What is the use of finally block?</strong></h3>
<p>The <code>finally</code> block is used for <strong>resource cleanup</strong> — it executes <strong>always</strong>, regardless of whether an exception occurs or not.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-keyword">try</span> {
    FileInputStream fis = <span class="hljs-keyword">new</span> FileInputStream(<span class="hljs-string">"data.txt"</span>);
} <span class="hljs-keyword">catch</span> (IOException e) {
    e.printStackTrace();
} <span class="hljs-keyword">finally</span> {
    System.out.println(<span class="hljs-string">"Closing resources..."</span>);
}
</code></pre>
<p>✅ Executed:</p>
<ul>
<li><p>After try or catch block</p>
</li>
<li><p>Even if <code>return</code> is used inside try or catch<br />  ❌ Not executed if JVM exits via <code>System.exit(0)</code> or power failure.</p>
</li>
</ul>
<p><strong>Modern alternative:</strong><br />Use <strong>try-with-resources (Java 7+)</strong> to auto-close resources.</p>
<h3 id="heading-5-custom-exception-in-java"><strong>5. Custom exception in Java?</strong></h3>
<p>A <strong>custom exception</strong> allows developers to define domain-specific error types.</p>
<p><strong>Steps to create:</strong></p>
<ol>
<li><p>Extend <code>Exception</code> (for checked) or <code>RuntimeException</code> (for unchecked).</p>
</li>
<li><p>Add constructors for custom messages.</p>
</li>
</ol>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InvalidAgeException</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Exception</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">InvalidAgeException</span><span class="hljs-params">(String msg)</span> </span>{
        <span class="hljs-keyword">super</span>(msg);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Validator</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">validate</span><span class="hljs-params">(<span class="hljs-keyword">int</span> age)</span> <span class="hljs-keyword">throws</span> InvalidAgeException </span>{
        <span class="hljs-keyword">if</span> (age &lt; <span class="hljs-number">18</span>)
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> InvalidAgeException(<span class="hljs-string">"Age must be &gt;= 18"</span>);
    }
}
</code></pre>
<p><strong>Use cases:</strong></p>
<ul>
<li><p>Validation (e.g., invalid user input)</p>
</li>
<li><p>Business logic constraints</p>
</li>
<li><p>Domain-specific error reporting (e.g., <code>InsufficientBalanceException</code>)</p>
</li>
</ul>
<h2 id="heading-collections-framework">Collections Framework</h2>
<h3 id="heading-1-list-vs-set-vs-map"><strong>1. List vs Set vs Map?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>List</strong></td><td><strong>Set</strong></td><td><strong>Map</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Stores</strong></td><td>Ordered collection of elements</td><td>Unique elements (no duplicates)</td><td>Key-value pairs</td></tr>
<tr>
<td><strong>Duplicates</strong></td><td>Allowed</td><td>Not allowed</td><td>Keys: not allowed, Values: allowed</td></tr>
<tr>
<td><strong>Order</strong></td><td>Maintains insertion order</td><td>Depends on implementation</td><td>Depends on implementation</td></tr>
<tr>
<td><strong>Implementations</strong></td><td><code>ArrayList</code>, <code>LinkedList</code>, <code>Vector</code></td><td><code>HashSet</code>, <code>LinkedHashSet</code>, <code>TreeSet</code></td><td><code>HashMap</code>, <code>TreeMap</code>, <code>LinkedHashMap</code></td></tr>
</tbody>
</table>
</div><p><strong>Example:</strong></p>
<pre><code class="lang-java">List&lt;String&gt; list = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();
Set&lt;String&gt; set = <span class="hljs-keyword">new</span> HashSet&lt;&gt;();
Map&lt;Integer, String&gt; map = <span class="hljs-keyword">new</span> HashMap&lt;&gt;();
</code></pre>
<h3 id="heading-2-arraylist-vs-linkedlist"><strong>2. ArrayList vs LinkedList?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>ArrayList</td><td>LinkedList</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Data Structure</strong></td><td>Dynamic array</td><td>Doubly linked list</td></tr>
<tr>
<td><strong>Access Time</strong></td><td>O(1) for index-based access</td><td>O(n) traversal required</td></tr>
<tr>
<td><strong>Insertion/Deletion (middle)</strong></td><td>O(n)</td><td>O(1) if node reference known</td></tr>
<tr>
<td><strong>Memory Usage</strong></td><td>Less (compact)</td><td>More (extra node references)</td></tr>
<tr>
<td><strong>Use Case</strong></td><td>Random access</td><td>Frequent insertions/deletions</td></tr>
</tbody>
</table>
</div><p><strong>Example:</strong></p>
<ul>
<li><p>Use <code>ArrayList</code> when reads are frequent.</p>
</li>
<li><p>Use <code>LinkedList</code> when insertions/removals are frequent.</p>
</li>
</ul>
<h3 id="heading-3-hashmap-vs-hashtable"><strong>3. HashMap vs Hashtable?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>HashMap</strong></td><td><strong>Hashtable</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Thread-Safety</strong></td><td>Not synchronized</td><td>Synchronized</td></tr>
<tr>
<td><strong>Null Keys/Values</strong></td><td>Allows one null key, multiple null values</td><td>Doesn’t allow nulls</td></tr>
<tr>
<td><strong>Performance</strong></td><td>Faster (no locking)</td><td>Slower (locks entire table)</td></tr>
<tr>
<td><strong>Introduced In</strong></td><td>Java 1.2</td><td>Java 1.0</td></tr>
<tr>
<td><strong>Preferred?</strong></td><td>Yes, in modern Java</td><td>Legacy class</td></tr>
</tbody>
</table>
</div><p>✅ For thread-safe alternatives, use <code>ConcurrentHashMap</code> instead of <code>Hashtable</code>.</p>
<h3 id="heading-4-how-does-hashmap-work-internally"><strong>4. How does HashMap work internally?</strong></h3>
<p>HashMap stores data in <strong>buckets</strong> using a <strong>hashing mechanism</strong>.</p>
<p><strong>Process:</strong></p>
<ol>
<li><p>Key’s <code>hashCode()</code> is computed.</p>
</li>
<li><p>The hash is mapped to an index in the bucket array (<code>(n - 1) &amp; hash</code>).</p>
</li>
<li><p>Each bucket holds a linked list or tree (Java 8+).</p>
</li>
<li><p>On <code>put()</code>:</p>
<ul>
<li><p>If key exists → value replaced.</p>
</li>
<li><p>If not → new node added.</p>
</li>
</ul>
</li>
<li><p>On <code>get()</code>:</p>
<ul>
<li>Hash computed → bucket located → key compared using <code>equals()</code>.</li>
</ul>
</li>
</ol>
<p><strong>Optimization (Java 8+):</strong></p>
<ul>
<li>If bucket size &gt; 8, converts linked list → <strong>balanced tree</strong> (Red-Black Tree) for O(log n) lookup.</li>
</ul>
<h3 id="heading-5-what-is-the-load-factor-and-threshold-in-hashmap"><strong>5. What is the load factor and threshold in HashMap?</strong></h3>
<ul>
<li><p><strong>Load Factor:</strong> Defines how full the HashMap can get before resizing (default = 0.75).</p>
</li>
<li><p><strong>Threshold:</strong> <code>capacity × loadFactor</code>.<br />  When the number of entries exceeds this threshold, HashMap <strong>resizes</strong> (doubles its capacity).</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-java">HashMap&lt;String, Integer&gt; map = <span class="hljs-keyword">new</span> HashMap&lt;&gt;(<span class="hljs-number">16</span>, <span class="hljs-number">0.75f</span>);
</code></pre>
<p>✅ Resizing improves performance but comes with a cost — it’s best to initialize maps with an estimated size to minimize rehashing.</p>
<h3 id="heading-6-what-are-fail-fast-and-fail-safe-iterators"><strong>6. What are fail-fast and fail-safe iterators?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Type</strong></td><td><strong>Behavior</strong></td><td><strong>Example Collections</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Fail-Fast</strong></td><td>Throws <code>ConcurrentModificationException</code> if the collection is modified while iterating</td><td><code>ArrayList</code>, <code>HashMap</code></td></tr>
<tr>
<td><strong>Fail-Safe</strong></td><td>Works on a clone or snapshot of the collection</td><td><code>ConcurrentHashMap</code>, <code>CopyOnWriteArrayList</code></td></tr>
</tbody>
</table>
</div><p>Example:</p>
<pre><code class="lang-java"><span class="hljs-keyword">for</span> (Integer i : list) {
    list.add(<span class="hljs-number">10</span>); <span class="hljs-comment">// ❌ throws ConcurrentModificationException</span>
}
</code></pre>
<p>✅ Use <strong>fail-safe</strong> collections in concurrent environments.</p>
<h3 id="heading-7-what-is-concurrenthashmap-and-how-is-it-different"><strong>7. What is ConcurrentHashMap and how is it different?</strong></h3>
<p><code>ConcurrentHashMap</code> is a thread-safe alternative to <code>HashMap</code> that provides <strong>high concurrency</strong> with minimal locking.</p>
<p><strong>How it differs:</strong></p>
<ul>
<li><p>No full-table lock (uses <strong>segment-level locking</strong> or <strong>CAS</strong> in Java 8+).</p>
</li>
<li><p>Null keys/values are <strong>not allowed</strong>.</p>
</li>
<li><p>Iterators are <strong>fail-safe</strong> (operate on snapshot).</p>
</li>
<li><p>Performs better than <code>Hashtable</code> under multithreading.</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">ConcurrentHashMap&lt;String, Integer&gt; map = <span class="hljs-keyword">new</span> ConcurrentHashMap&lt;&gt;();
map.put(<span class="hljs-string">"A"</span>, <span class="hljs-number">1</span>);
</code></pre>
<h3 id="heading-8-treemap-vs-hashmap"><strong>8. TreeMap vs HashMap?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>HashMap</td><td>TreeMap</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Order</strong></td><td>No ordering</td><td>Sorted (natural/comparator)</td></tr>
<tr>
<td><strong>Implementation</strong></td><td>Hash table</td><td>Red-Black tree</td></tr>
<tr>
<td><strong>Null Keys</strong></td><td>Allows one</td><td>Doesn’t allow null key</td></tr>
<tr>
<td><strong>Performance</strong></td><td>O(1) average</td><td>O(log n)</td></tr>
<tr>
<td><strong>Use Case</strong></td><td>Fast lookups</td><td>Sorted data retrieval</td></tr>
</tbody>
</table>
</div><p><strong>Example:</strong></p>
<pre><code class="lang-java">Map&lt;Integer, String&gt; map = <span class="hljs-keyword">new</span> TreeMap&lt;&gt;();
map.put(<span class="hljs-number">2</span>, <span class="hljs-string">"B"</span>);
map.put(<span class="hljs-number">1</span>, <span class="hljs-string">"A"</span>); <span class="hljs-comment">// Automatically sorted by key</span>
</code></pre>
<h3 id="heading-9-what-is-linkedhashmap"><strong>9. What is LinkedHashMap?</strong></h3>
<p><code>LinkedHashMap</code> maintains <strong>insertion order</strong> or <strong>access order</strong> of entries.</p>
<p><strong>Internally:</strong><br />It extends <code>HashMap</code> and adds a <strong>doubly-linked list</strong> to preserve order.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">Map&lt;Integer, String&gt; map = <span class="hljs-keyword">new</span> LinkedHashMap&lt;&gt;();
map.put(<span class="hljs-number">1</span>, <span class="hljs-string">"A"</span>);
map.put(<span class="hljs-number">2</span>, <span class="hljs-string">"B"</span>);
</code></pre>
<p>✅ Useful when you need predictable iteration order or LRU caching (using <code>removeEldestEntry</code>).</p>
<h3 id="heading-10-when-to-use-arraylist-vs-vector"><strong>10. When to use ArrayList vs Vector?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>ArrayList</strong></td><td><strong>Vector</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Synchronization</strong></td><td>Not synchronized</td><td>Synchronized</td></tr>
<tr>
<td><strong>Performance</strong></td><td>Faster</td><td>Slower (locks every method)</td></tr>
<tr>
<td><strong>Introduced In</strong></td><td>Java 1.2</td><td>Java 1.0 (legacy)</td></tr>
<tr>
<td><strong>Growth</strong></td><td>Grows by 50%</td><td>Grows by 100% (doubles)</td></tr>
</tbody>
</table>
</div><p>✅ Modern Java avoids <code>Vector</code>.<br />Use <code>ArrayList</code> for single-threaded cases, or <code>Collections.synchronizedList()</code> if synchronization is needed.</p>
<h2 id="heading-multithreading-and-concurrency">Multithreading and Concurrency</h2>
<h3 id="heading-1-difference-between-process-and-thread"><strong>1. Difference between process and thread?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>Process</strong></td><td><strong>Thread</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Definition</strong></td><td>Independent program in execution</td><td>Smallest unit of a process</td></tr>
<tr>
<td><strong>Memory</strong></td><td>Has its own memory space</td><td>Shares memory with other threads of same process</td></tr>
<tr>
<td><strong>Communication</strong></td><td>Inter-process communication is complex</td><td>Easier via shared objects</td></tr>
<tr>
<td><strong>Failure Impact</strong></td><td>One process crash doesn’t affect others</td><td>Thread crash may affect whole process</td></tr>
<tr>
<td><strong>Example</strong></td><td>Running two Java programs</td><td>Two threads in same Java program</td></tr>
</tbody>
</table>
</div><p><strong>In short:</strong> Threads share the same heap, enabling lightweight multitasking within a single process.</p>
<h3 id="heading-2-ways-to-create-a-thread-in-java"><strong>2. Ways to create a thread in Java?</strong></h3>
<p>There are <strong>three main ways</strong>:</p>
<ol>
<li><p><strong>Extend</strong> <code>Thread</code> class</p>
<pre><code class="lang-java"> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyThread</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Thread</span> </span>{
     <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
         System.out.println(<span class="hljs-string">"Thread running..."</span>);
     }
 }
 <span class="hljs-keyword">new</span> MyThread().start();
</code></pre>
</li>
<li><p><strong>Implement</strong> <code>Runnable</code> interface</p>
<pre><code class="lang-java"> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyTask</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Runnable</span> </span>{
     <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
         System.out.println(<span class="hljs-string">"Running via Runnable"</span>);
     }
 }
 <span class="hljs-keyword">new</span> Thread(<span class="hljs-keyword">new</span> MyTask()).start();
</code></pre>
</li>
<li><p><strong>Use</strong> <code>ExecutorService</code> or <code>Callable</code> (preferred in modern Java)</p>
<pre><code class="lang-java"> ExecutorService service = Executors.newFixedThreadPool(<span class="hljs-number">2</span>);
 service.submit(() -&gt; System.out.println(<span class="hljs-string">"Running in pool"</span>));
</code></pre>
</li>
</ol>
<p>✅ Best practice: Use <code>ExecutorService</code> to manage threads efficiently.</p>
<h3 id="heading-3-thread-vs-runnable"><strong>3. Thread vs Runnable?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>Thread</strong></td><td><strong>Runnable</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Inheritance</strong></td><td>Requires extending Thread</td><td>Can be implemented along with other interfaces</td></tr>
<tr>
<td><strong>Code Reuse</strong></td><td>Less flexible</td><td>More flexible (no multiple inheritance issue)</td></tr>
<tr>
<td><strong>Preferred</strong></td><td>For small/simple use</td><td>Runnable preferred for real-world apps</td></tr>
</tbody>
</table>
</div><p><strong>Example:</strong><br />If your class already extends another class, use <code>Runnable</code> since Java doesn’t support multiple inheritance.</p>
<h3 id="heading-4-what-is-thread-lifecycle"><strong>4. What is thread lifecycle?</strong></h3>
<p>A thread in Java passes through these <strong>five states</strong>:</p>
<ol>
<li><p><strong>New</strong> – Created but not started (<code>new Thread()</code>).</p>
</li>
<li><p><strong>Runnable</strong> – Ready to run, waiting for CPU (<code>start()</code> called).</p>
</li>
<li><p><strong>Running</strong> – Currently executing.</p>
</li>
<li><p><strong>Blocked/Waiting</strong> – Waiting for a resource or another thread.</p>
</li>
<li><p><strong>Terminated</strong> – Execution completed or stopped.</p>
</li>
</ol>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">Thread t = <span class="hljs-keyword">new</span> Thread(() -&gt; {});
t.start();  <span class="hljs-comment">// Runnable</span>
</code></pre>
<h3 id="heading-5-difference-between-wait-sleep-join"><strong>5. Difference between wait, sleep, join?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Method</strong></td><td><strong>Defined In</strong></td><td><strong>Releases Lock?</strong></td><td><strong>Purpose</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>wait()</strong></td><td>Object class</td><td>✅ Yes</td><td>Waits until notified (<code>notify()</code> / <code>notifyAll()</code>)</td></tr>
<tr>
<td><strong>sleep()</strong></td><td>Thread class</td><td>❌ No</td><td>Pauses execution for given time</td></tr>
<tr>
<td><strong>join()</strong></td><td>Thread class</td><td>❌ No</td><td>Waits for another thread to finish</td></tr>
</tbody>
</table>
</div><p>Example:</p>
<pre><code class="lang-java">Thread t = <span class="hljs-keyword">new</span> Thread(() -&gt; System.out.println(<span class="hljs-string">"Task"</span>));
t.start();
t.join(); <span class="hljs-comment">// waits for t to finish</span>
</code></pre>
<h3 id="heading-6-what-is-synchronized-blockmethod"><strong>6. What is synchronized block/method?</strong></h3>
<p>The <code>synchronized</code> keyword ensures <strong>mutual exclusion</strong> — only one thread can access a block/method at a time for a given object.</p>
<p><strong>Types:</strong></p>
<ul>
<li><p><strong>Synchronized method</strong></p>
<pre><code class="lang-java">  <span class="hljs-function"><span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">void</span> <span class="hljs-title">increment</span><span class="hljs-params">()</span> </span>{ 
      count++; 
  }
</code></pre>
</li>
<li><p><strong>Synchronized block</strong></p>
<pre><code class="lang-java">  <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">increment</span><span class="hljs-params">()</span> </span>{
      <span class="hljs-keyword">synchronized</span>(<span class="hljs-keyword">this</span>) {
          count++;
      }
  }
</code></pre>
</li>
</ul>
<p><strong>Benefits:</strong> Prevents race conditions.<br /><strong>Downside:</strong> Can reduce performance due to locking.</p>
<h3 id="heading-7-what-is-a-deadlock-how-to-prevent-it"><strong>7. What is a deadlock? How to prevent it?</strong></h3>
<p>A <strong>deadlock</strong> occurs when two or more threads are waiting for each other’s locks indefinitely.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-keyword">synchronized</span> (obj1) {
    <span class="hljs-keyword">synchronized</span> (obj2) { ... }
}
</code></pre>
<p>Another thread might lock <code>obj2</code> first, then wait for <code>obj1</code>.</p>
<p><strong>Prevention:</strong></p>
<ul>
<li><p>Acquire locks in a consistent order.</p>
</li>
<li><p>Use <code>tryLock()</code> with timeout (<code>ReentrantLock</code>).</p>
</li>
<li><p>Avoid nested locks where possible.</p>
</li>
</ul>
<h3 id="heading-8-what-is-volatile-keyword"><strong>8. What is volatile keyword?</strong></h3>
<p>The <code>volatile</code> keyword ensures that a variable’s value is <strong>always read from main memory</strong>, not from a thread’s local cache.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-keyword">volatile</span> <span class="hljs-keyword">boolean</span> flag = <span class="hljs-keyword">true</span>;
</code></pre>
<p>If one thread changes <code>flag</code>, other threads immediately see the updated value.</p>
<p><strong>Important:</strong></p>
<ul>
<li><p>Ensures <strong>visibility</strong>, not <strong>atomicity</strong>.</p>
</li>
<li><p>For compound operations (e.g., <code>count++</code>), use synchronization or <code>AtomicInteger</code>.</p>
</li>
</ul>
<h3 id="heading-9-difference-between-executorservice-and-thread"><strong>9. Difference between ExecutorService and Thread?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Aspect</strong></td><td><strong>Thread</strong></td><td><strong>ExecutorService</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Creation</strong></td><td>Manually create and start threads</td><td>Manages thread pool automatically</td></tr>
<tr>
<td><strong>Reusability</strong></td><td>One-time use</td><td>Threads are reused</td></tr>
<tr>
<td><strong>Performance</strong></td><td>Higher overhead</td><td>More efficient for multiple tasks</td></tr>
<tr>
<td><strong>Introduced</strong></td><td>Java 1.0</td><td>Java 5 (<code>java.util.concurrent</code>)</td></tr>
</tbody>
</table>
</div><p>Example:</p>
<pre><code class="lang-java">ExecutorService executor = Executors.newFixedThreadPool(<span class="hljs-number">3</span>);
executor.submit(() -&gt; System.out.println(<span class="hljs-string">"Task executed"</span>));
executor.shutdown();
</code></pre>
<p>✅ <strong>Best practice:</strong> Always use <code>ExecutorService</code> for managing multiple threads efficiently.</p>
<h3 id="heading-10-what-is-thread-safety"><strong>10. What is thread safety?</strong></h3>
<p><strong>Thread safety</strong> means an object or code segment behaves correctly when accessed by multiple threads simultaneously.</p>
<p><strong>Ways to achieve:</strong></p>
<ul>
<li><p>Use <strong>immutable objects</strong></p>
</li>
<li><p>Use <strong>synchronized blocks</strong></p>
</li>
<li><p>Use <strong>atomic classes</strong> (<code>AtomicInteger</code>, <code>AtomicReference</code>)</p>
</li>
<li><p>Use <strong>concurrent collections</strong> (<code>ConcurrentHashMap</code>, <code>CopyOnWriteArrayList</code>)</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">AtomicInteger counter = <span class="hljs-keyword">new</span> AtomicInteger();
counter.incrementAndGet();
</code></pre>
<p>✅ Thread-safe code avoids <strong>race conditions</strong> and <strong>data inconsistency</strong>.</p>
<h2 id="heading-java-8-features">Java 8 Features</h2>
<h3 id="heading-1-what-are-the-major-features-introduced-in-java-8"><strong>1. What are the major features introduced in Java 8?</strong></h3>
<p>Java 8 introduced <strong>functional programming</strong> concepts and several performance improvements.</p>
<p><strong>Key Features:</strong></p>
<ul>
<li><p>Lambda Expressions</p>
</li>
<li><p>Functional Interfaces</p>
</li>
<li><p>Stream API</p>
</li>
<li><p>Optional class</p>
</li>
<li><p>Method References</p>
</li>
<li><p>Default and Static methods in Interfaces</p>
</li>
<li><p>Date and Time API (<code>java.time</code>)</p>
</li>
<li><p>Parallel Streams</p>
</li>
</ul>
<h3 id="heading-2-what-are-lambda-expressions"><strong>2. What are lambda expressions?</strong></h3>
<p>A <strong>lambda expression</strong> provides a concise way to represent anonymous functions.</p>
<p><strong>Syntax:</strong></p>
<pre><code class="lang-java">(parameter) -&gt; expression
</code></pre>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">List&lt;String&gt; names = Arrays.asList(<span class="hljs-string">"John"</span>, <span class="hljs-string">"Jane"</span>, <span class="hljs-string">"Max"</span>);
names.forEach(name -&gt; System.out.println(name));
</code></pre>
<p><strong>Before Java 8:</strong></p>
<pre><code class="lang-java"><span class="hljs-keyword">for</span> (String name : names)
    System.out.println(name);
</code></pre>
<p>✅ <strong>Advantages:</strong></p>
<ul>
<li><p>Reduces boilerplate code</p>
</li>
<li><p>Enables functional programming</p>
</li>
<li><p>Works well with Streams and Collections</p>
</li>
</ul>
<h3 id="heading-3-what-is-a-functional-interface"><strong>3. What is a functional interface?</strong></h3>
<p>A <strong>functional interface</strong> is an interface that contains exactly <strong>one abstract method</strong>.<br />It can have <strong>default or static methods</strong> as well.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-meta">@FunctionalInterface</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Calculator</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">add</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span></span>;
}
</code></pre>
<p><strong>Built-in Functional Interfaces (in</strong> <code>java.util.function</code>):</p>
<ul>
<li><p><code>Predicate&lt;T&gt;</code> → returns boolean</p>
</li>
<li><p><code>Function&lt;T, R&gt;</code> → transforms T to R</p>
</li>
<li><p><code>Consumer&lt;T&gt;</code> → accepts and performs action</p>
</li>
<li><p><code>Supplier&lt;T&gt;</code> → returns value without input</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">Predicate&lt;Integer&gt; isEven = x -&gt; x % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>;
System.out.println(isEven.test(<span class="hljs-number">4</span>)); <span class="hljs-comment">// true</span>
</code></pre>
<h3 id="heading-4-what-is-the-stream-api"><strong>4. What is the Stream API?</strong></h3>
<p>The <strong>Stream API</strong> is used to process collections of data in a <strong>declarative and functional style</strong>.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">List&lt;Integer&gt; nums = Arrays.asList(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>);
List&lt;Integer&gt; squares = nums.stream()
                            .map(n -&gt; n * n)
                            .collect(Collectors.toList());
System.out.println(squares);
</code></pre>
<p><strong>Key Operations:</strong></p>
<ul>
<li><p>Intermediate → <code>filter()</code>, <code>map()</code>, <code>sorted()</code></p>
</li>
<li><p>Terminal → <code>collect()</code>, <code>forEach()</code>, <code>count()</code>, <code>reduce()</code></p>
</li>
</ul>
<p>✅ <strong>Streams don’t modify the original collection.</strong></p>
<h3 id="heading-5-what-is-the-difference-between-map-and-flatmap"><strong>5. What is the difference between map() and flatMap()?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Method</strong></td><td><strong>Purpose</strong></td><td><strong>Example</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>map()</strong></td><td>Transforms each element</td><td><code>[1,2,3] → [1,4,9]</code></td></tr>
<tr>
<td><strong>flatMap()</strong></td><td>Flattens nested streams</td><td><code>[[1,2],[3,4]] → [1,2,3,4]</code></td></tr>
</tbody>
</table>
</div><p><strong>Example:</strong></p>
<pre><code class="lang-java">List&lt;List&lt;Integer&gt;&gt; list = Arrays.asList(Arrays.asList(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>), Arrays.asList(<span class="hljs-number">3</span>,<span class="hljs-number">4</span>));
list.stream().flatMap(Collection::stream).forEach(System.out::println);
</code></pre>
<h3 id="heading-6-what-is-the-optional-class"><strong>6. What is the Optional class?</strong></h3>
<p><code>Optional&lt;T&gt;</code> is a container that may or may not hold a non-null value.<br />It helps <strong>avoid NullPointerException</strong>.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">Optional&lt;String&gt; name = Optional.ofNullable(getName());
System.out.println(name.orElse(<span class="hljs-string">"Unknown"</span>));
</code></pre>
<p><strong>Common methods:</strong></p>
<ul>
<li><p><code>isPresent()</code></p>
</li>
<li><p><code>orElse()</code></p>
</li>
<li><p><code>orElseGet()</code></p>
</li>
<li><p><code>orElseThrow()</code></p>
</li>
<li><p><code>map()</code> and <code>flatMap()</code></p>
</li>
</ul>
<p>✅ Always use <code>Optional</code> for return types, not fields.</p>
<h3 id="heading-7-what-are-method-references"><strong>7. What are method references?</strong></h3>
<p>Method references provide a shorthand for calling existing methods using <code>::</code>.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">list.forEach(System.out::println);
</code></pre>
<p><strong>Types:</strong></p>
<ul>
<li><p>Static method → <code>ClassName::staticMethod</code></p>
</li>
<li><p>Instance method → <code>object::instanceMethod</code></p>
</li>
<li><p>Constructor → <code>ClassName::new</code></p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">Supplier&lt;List&lt;String&gt;&gt; supplier = ArrayList::<span class="hljs-keyword">new</span>;
</code></pre>
<h3 id="heading-8-what-are-default-and-static-methods-in-interfaces"><strong>8. What are default and static methods in interfaces?</strong></h3>
<p><strong>Default methods</strong>: Provide a method body inside an interface.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Vehicle</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">default</span> <span class="hljs-keyword">void</span> <span class="hljs-title">start</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Vehicle started"</span>);
    }
}
</code></pre>
<p><strong>Static methods</strong> in interfaces belong to the interface itself:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Utils</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">show</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Static method in interface"</span>);
    }
}
</code></pre>
<p>✅ These features were introduced to maintain backward compatibility when new methods were added to interfaces like <code>List</code> and <code>Map</code>.</p>
<h3 id="heading-9-what-is-the-new-date-and-time-api-javatime"><strong>9. What is the new Date and Time API (java.time)?</strong></h3>
<p>Java 8 introduced a <strong>modern, immutable, thread-safe</strong> Date-Time API.</p>
<p><strong>Key Classes:</strong></p>
<ul>
<li><p><code>LocalDate</code>, <code>LocalTime</code>, <code>LocalDateTime</code></p>
</li>
<li><p><code>ZonedDateTime</code></p>
</li>
<li><p><code>Period</code>, <code>Duration</code></p>
</li>
<li><p><code>DateTimeFormatter</code></p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(<span class="hljs-number">1</span>);
System.out.println(tomorrow);
</code></pre>
<p>✅ No more <code>java.util.Date</code> and <code>SimpleDateFormat</code> pain!</p>
<h3 id="heading-10-what-are-parallel-streams"><strong>10. What are parallel streams?</strong></h3>
<p>Parallel streams allow data to be processed <strong>in multiple threads automatically</strong>.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">list.parallelStream()
    .filter(x -&gt; x &gt; <span class="hljs-number">10</span>)
    .forEach(System.out::println);
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li><p>Use parallel streams <strong>for CPU-intensive</strong> operations.</p>
</li>
<li><p>Avoid for <strong>IO-bound</strong> or small datasets (due to overhead).</p>
</li>
</ul>
<h2 id="heading-strings">Strings</h2>
<h3 id="heading-1-string-vs-stringbuilder-vs-stringbuffer"><strong>1. String vs StringBuilder vs StringBuffer?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><code>String</code></td><td><code>StringBuilder</code></td><td><code>StringBuffer</code></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Mutability</strong></td><td>Immutable</td><td>Mutable</td><td>Mutable</td></tr>
<tr>
<td><strong>Thread-safety</strong></td><td>Not thread-safe</td><td>Not thread-safe</td><td>Thread-safe (synchronized)</td></tr>
<tr>
<td><strong>Performance</strong></td><td>Slower (creates new objects)</td><td>Faster (no synchronization)</td><td>Slightly slower (synchronization overhead)</td></tr>
<tr>
<td><strong>Use Case</strong></td><td>When data doesn’t change</td><td>Single-threaded string manipulations</td><td>Multi-threaded string manipulations</td></tr>
</tbody>
</table>
</div><p><strong>Example:</strong></p>
<pre><code class="lang-java">String s = <span class="hljs-string">"Hello"</span>;
s.concat(<span class="hljs-string">" World"</span>); <span class="hljs-comment">// New object created</span>

StringBuilder sb = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-string">"Hello"</span>);
sb.append(<span class="hljs-string">" World"</span>); <span class="hljs-comment">// Modified in place</span>
</code></pre>
<p>✅ For most use cases → prefer <strong>StringBuilder</strong> (fast, flexible).</p>
<h3 id="heading-2-how-are-strings-stored-in-memory"><strong>2. How are strings stored in memory?</strong></h3>
<ul>
<li><p>Strings are stored in a special area of heap memory called the <strong>String Constant Pool (SCP)</strong>.</p>
</li>
<li><p>When you create a string literal, e.g., <code>"Java"</code>, it’s <strong>interned</strong> — meaning:</p>
<ul>
<li><p>If <code>"Java"</code> already exists in the pool, the same reference is reused.</p>
</li>
<li><p>If not, it’s added to the pool.</p>
</li>
</ul>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">String s1 = <span class="hljs-string">"Java"</span>;
String s2 = <span class="hljs-string">"Java"</span>;
System.out.println(s1 == s2); <span class="hljs-comment">// true (same reference)</span>
</code></pre>
<p>✅ <strong>String literals</strong> are interned;<br /><code>new String("Java")</code> creates a <strong>new object</strong> on the heap (not in SCP).</p>
<h3 id="heading-3-what-is-the-string-constant-pool"><strong>3. What is the String Constant Pool?</strong></h3>
<p>The <strong>String Constant Pool</strong> (SCP) is part of the <strong>heap memory</strong> (since Java 7+).<br />It’s a cache that stores <strong>unique string literals</strong> to improve performance and save memory.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">String a = <span class="hljs-string">"Test"</span>;
String b = <span class="hljs-string">"Test"</span>;
System.out.println(a == b); <span class="hljs-comment">// true (both refer to same object)</span>
</code></pre>
<p>If created using <code>new</code>:</p>
<pre><code class="lang-java">String c = <span class="hljs-keyword">new</span> String(<span class="hljs-string">"Test"</span>);
System.out.println(a == c); <span class="hljs-comment">// false (different objects)</span>
</code></pre>
<p>✅ You can manually add strings to the pool using <code>intern()</code>:</p>
<pre><code class="lang-java">String d = c.intern();
System.out.println(a == d); <span class="hljs-comment">// true</span>
</code></pre>
<h3 id="heading-4-why-are-strings-immutable-in-java"><strong>4. Why are Strings immutable in Java?</strong></h3>
<p><strong>Reasons:</strong></p>
<ol>
<li><p><strong>Security:</strong> Used in sensitive contexts (ClassLoader, File paths, URLs).</p>
</li>
<li><p><strong>Thread-safety:</strong> Immutable objects can be shared safely between threads.</p>
</li>
<li><p><strong>Caching:</strong> Hash code of a string is cached; immutability ensures it’s consistent.</p>
</li>
<li><p><strong>String Pool Optimization:</strong> Same string literals can be reused safely.</p>
</li>
</ol>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">String s = <span class="hljs-string">"Java"</span>;
s.concat(<span class="hljs-string">" Rocks"</span>); <span class="hljs-comment">// creates a new string</span>
</code></pre>
<p>✅ Once created, the value of a String object <strong>cannot be changed</strong>.</p>
<h3 id="heading-5-how-does-equals-work-in-string"><strong>5. How does equals() work in String?</strong></h3>
<p>The <code>equals()</code> method compares <strong>the contents (values)</strong> of two strings,<br />while the <code>==</code> operator compares <strong>references</strong>.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">String s1 = <span class="hljs-keyword">new</span> String(<span class="hljs-string">"Hello"</span>);
String s2 = <span class="hljs-keyword">new</span> String(<span class="hljs-string">"Hello"</span>);

System.out.println(s1 == s2);       <span class="hljs-comment">// false (different objects)</span>
System.out.println(s1.equals(s2));  <span class="hljs-comment">// true (same content)</span>
</code></pre>
<p>✅ <code>String</code> overrides <code>equals()</code> and <code>hashCode()</code> from <code>Object</code> class to compare actual text.</p>
<h3 id="heading-6-how-does-hashcode-work-in-strings"><strong>6. How does</strong> <code>hashCode()</code> work in Strings?</h3>
<ul>
<li><p>The hash code for a string is computed based on its characters:</p>
<pre><code class="lang-java">  s[<span class="hljs-number">0</span>]*<span class="hljs-number">31</span>^(n-<span class="hljs-number">1</span>) + s[<span class="hljs-number">1</span>]*<span class="hljs-number">31</span>^(n-<span class="hljs-number">2</span>) + ... + s[n-<span class="hljs-number">1</span>]
</code></pre>
</li>
<li><p>Because strings are immutable, their hash code is <strong>cached</strong> for performance.</p>
</li>
</ul>
<p>✅ Used extensively in collections like <code>HashMap</code> and <code>HashSet</code>.</p>
<h3 id="heading-7-how-do-substring-split-and-join-work"><strong>7. How do</strong> <code>substring()</code>, <code>split()</code>, and <code>join()</code> work?</h3>
<p><code>substring(begin, end)</code></p>
<ul>
<li><p>Returns part of the string.</p>
</li>
<li><p>Creates a new String (does not modify original).</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">String s = <span class="hljs-string">"developer"</span>;
System.out.println(s.substring(<span class="hljs-number">0</span>, <span class="hljs-number">3</span>)); <span class="hljs-comment">// "dev"</span>
</code></pre>
<p><code>split(regex)</code></p>
<ul>
<li>Splits a string into an array based on a delimiter.</li>
</ul>
<pre><code class="lang-java">String s = <span class="hljs-string">"a,b,c"</span>;
String[] arr = s.split(<span class="hljs-string">","</span>);
</code></pre>
<p><code>String.join(delimiter, elements...)</code></p>
<pre><code class="lang-java">String result = String.join(<span class="hljs-string">"-"</span>, <span class="hljs-string">"Java"</span>, <span class="hljs-string">"Python"</span>, <span class="hljs-string">"C++"</span>);
System.out.println(result); <span class="hljs-comment">// "Java-Python-C++"</span>
</code></pre>
<h3 id="heading-8-what-is-string-interning"><strong>8. What is String interning?</strong></h3>
<p>Interning ensures that identical strings share the same reference in the <strong>String Pool</strong>.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">String s1 = <span class="hljs-keyword">new</span> String(<span class="hljs-string">"Java"</span>);
String s2 = s1.intern();
String s3 = <span class="hljs-string">"Java"</span>;

System.out.println(s2 == s3); <span class="hljs-comment">// true</span>
</code></pre>
<p>✅ Improves memory efficiency, especially when there are many repeated strings.</p>
<h3 id="heading-9-what-are-common-stringbuilder-methods"><strong>9. What are common StringBuilder methods?</strong></h3>
<ul>
<li><p><code>append()</code> – concatenates data</p>
</li>
<li><p><code>insert()</code> – inserts at position</p>
</li>
<li><p><code>delete()</code> – removes substring</p>
</li>
<li><p><code>reverse()</code> – reverses content</p>
</li>
<li><p><code>capacity()</code> – returns current buffer capacity</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">StringBuilder sb = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-string">"Hello"</span>);
sb.append(<span class="hljs-string">" World"</span>).reverse();
System.out.println(sb); <span class="hljs-comment">// "dlroW olleH"</span>
</code></pre>
<h3 id="heading-10-can-we-make-string-mutable-in-java"><strong>10. Can we make String mutable in Java?</strong></h3>
<p>Not directly.<br />However, you can <strong>simulate mutability</strong> using:</p>
<ul>
<li><p><code>StringBuilder</code> or <code>StringBuffer</code></p>
</li>
<li><p>Reflection (not recommended)</p>
</li>
<li><p>Creating a wrapper class with a mutable reference internally</p>
</li>
</ul>
<h2 id="heading-java-keywords-and-modifiers">Java Keywords and Modifiers</h2>
<h3 id="heading-1-difference-between-final-finally-and-finalize"><strong>1. Difference between final, finally, and finalize?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Keyword</strong></td><td><strong>Purpose</strong></td><td><strong>Example</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>final</strong></td><td>Restricts modification</td><td><code>final int x = 10;</code> or <code>final class MyClass</code></td></tr>
<tr>
<td><strong>finally</strong></td><td>Block to execute after try/catch</td><td><code>try {…} finally {…}</code></td></tr>
<tr>
<td><strong>finalize()</strong></td><td>Called by GC before object is destroyed</td><td><code>protected void finalize() {…}</code></td></tr>
</tbody>
</table>
</div><p><strong>Summary:</strong></p>
<ul>
<li><p><code>final</code> → compile-time constant, prevents inheritance/overriding</p>
</li>
<li><p><code>finally</code> → runtime block for cleanup</p>
</li>
<li><p><code>finalize()</code> → deprecated method, used for cleanup before garbage collection</p>
</li>
</ul>
<h3 id="heading-2-what-does-static-mean"><strong>2. What does static mean?</strong></h3>
<ul>
<li><p><strong>Static</strong> members belong to the <strong>class</strong>, not instances.</p>
</li>
<li><p><strong>Static variable:</strong> Shared across all objects</p>
</li>
<li><p><strong>Static method:</strong> Can be called without an object</p>
</li>
<li><p><strong>Static block:</strong> Executes once at class loading</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Demo</span> </span>{
    <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> count;
    <span class="hljs-keyword">static</span> { System.out.println(<span class="hljs-string">"Class loaded"</span>); }
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">show</span><span class="hljs-params">()</span> </span>{ System.out.println(<span class="hljs-string">"Static method"</span>); }
}
Demo.show();
System.out.println(Demo.count);
</code></pre>
<p>✅ Use static for memory efficiency and shared state.</p>
<h3 id="heading-3-what-is-transient"><strong>3. What is transient?</strong></h3>
<ul>
<li><p><strong>Transient</strong> is a keyword used in <strong>serialization</strong>.</p>
</li>
<li><p>Fields marked as transient are <strong>not serialized</strong>.</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Serializable</span> </span>{
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">transient</span> String password; <span class="hljs-comment">// won’t be saved</span>
}
</code></pre>
<p>✅ Useful for sensitive data like passwords or temporary fields.</p>
<h3 id="heading-4-what-is-volatile"><strong>4. What is volatile?</strong></h3>
<ul>
<li><p>Ensures <strong>visibility</strong> of changes across threads.</p>
</li>
<li><p>Guarantees that <strong>reads/writes go directly to main memory</strong>.</p>
</li>
<li><p>Does <strong>not</strong> guarantee atomicity.</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-keyword">volatile</span> <span class="hljs-keyword">boolean</span> running = <span class="hljs-keyword">true</span>;

<span class="hljs-keyword">while</span> (running) { 
    <span class="hljs-comment">/* do work */</span> 
}
</code></pre>
<p>Without <code>volatile</code>, one thread may never see the updated value.</p>
<h3 id="heading-5-difference-between-this-and-super"><strong>5. Difference between this and super?</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Keyword</strong></td><td><strong>Purpose</strong></td><td><strong>Example</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>this</strong></td><td>Refers to current object</td><td><code>this.name = name;</code></td></tr>
<tr>
<td><strong>super</strong></td><td>Refers to parent class</td><td><code>super.toString();</code></td></tr>
</tbody>
</table>
</div><ul>
<li><p><code>this()</code> → calls current class constructor</p>
</li>
<li><p><code>super()</code> → calls parent class constructor</p>
</li>
<li><p>Both must be the <strong>first statement</strong> in constructor when used</p>
</li>
</ul>
<h3 id="heading-6-additional-notes-on-keywordsmodifiers"><strong>6. Additional Notes on Keywords/Modifiers</strong></h3>
<ul>
<li><p><strong>abstract:</strong> Cannot instantiate class, may contain abstract methods</p>
</li>
<li><p><strong>synchronized:</strong> Ensures mutual exclusion for threads</p>
</li>
<li><p><strong>native:</strong> Method implemented in platform-specific code (C/C++)</p>
</li>
<li><p><strong>strictfp:</strong> Ensures floating-point calculations are platform-independent</p>
</li>
<li><p><strong>default (in interfaces):</strong> Provides default method implementation</p>
</li>
<li><p><strong>var (Java 10+):</strong> Type inference for local variables</p>
</li>
</ul>
<h2 id="heading-java-inner-classes">Java Inner Classes</h2>
<h3 id="heading-1-what-are-inner-classes"><strong>1. What are inner classes?</strong></h3>
<p>An <strong>inner class</strong> is a class defined <strong>within another class</strong>.<br />They allow logical grouping of classes and access to <strong>private members</strong> of the outer class.</p>
<p><strong>Types of inner classes:</strong></p>
<ol>
<li><p><strong>Member (non-static) inner class</strong></p>
</li>
<li><p><strong>Static nested class</strong></p>
</li>
<li><p><strong>Local inner class</strong></p>
</li>
<li><p><strong>Anonymous inner class</strong></p>
</li>
</ol>
<h3 id="heading-2-what-are-static-nested-classes"><strong>2. What are static nested classes?</strong></h3>
<ul>
<li><p>A <strong>static nested class</strong> is declared with the <code>static</code> keyword.</p>
</li>
<li><p>Unlike member inner classes, it <strong>does not have access to instance variables</strong> of the outer class.</p>
</li>
<li><p>Can be instantiated without an object of the outer class.</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Outer</span> </span>{
    <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Nested</span> </span>{
        <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">show</span><span class="hljs-params">()</span> </span>{ System.out.println(<span class="hljs-string">"Static nested class"</span>); }
    }
}
Outer.Nested nested = <span class="hljs-keyword">new</span> Outer.Nested();
nested.show();
</code></pre>
<p>✅ Useful for <strong>grouping classes</strong> logically and reducing namespace pollution.</p>
<h3 id="heading-3-difference-between-local-anonymous-and-member-classes"><strong>3. Difference between local, anonymous, and member classes</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Type</strong></td><td><strong>Definition</strong></td><td><strong>Scope</strong></td><td><strong>Example</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Member inner class</strong></td><td>Defined at class level (non-static)</td><td>Can access outer class members</td><td><code>class Outer { class Inner {} }</code></td></tr>
<tr>
<td><strong>Static nested class</strong></td><td>Defined with <code>static</code> keyword</td><td>Only static members of outer class</td><td><code>Outer.Nested nested = new Outer.Nested();</code></td></tr>
<tr>
<td><strong>Local inner class</strong></td><td>Defined inside a method</td><td>Only visible within method</td><td><code>void method() { class Local {} }</code></td></tr>
<tr>
<td><strong>Anonymous inner class</strong></td><td>No class name, used for instant implementation</td><td>Usually for implementing interfaces or extending classes</td><td><code>Runnable r = new Runnable() { public void run() {} };</code></td></tr>
</tbody>
</table>
</div><p><strong>Key points:</strong></p>
<ul>
<li><p>Member inner classes hold a <strong>reference to outer class</strong>.</p>
</li>
<li><p>Static nested classes <strong>don’t hold outer class reference</strong>, so memory footprint is smaller.</p>
</li>
<li><p>Anonymous classes are great for <strong>event handlers and callbacks</strong>.</p>
</li>
</ul>
<p><strong>Example of anonymous inner class:</strong></p>
<pre><code class="lang-java">Runnable r = <span class="hljs-keyword">new</span> Runnable() {
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Anonymous Runnable"</span>);
    }
};
<span class="hljs-keyword">new</span> Thread(r).start();
</code></pre>
<h3 id="heading-4-when-to-use-inner-classes"><strong>4. When to use inner classes?</strong></h3>
<ul>
<li><p>When a class is <strong>only relevant to its outer class</strong>.</p>
</li>
<li><p>For <strong>callbacks, listeners, or adapters</strong>.</p>
</li>
<li><p>To <strong>encapsulate helper classes</strong> without exposing them publicly.</p>
</li>
<li><p>To <strong>access outer class private members</strong> without getters/setters.</p>
</li>
</ul>
<p>✅ Correct use of inner classes improves <strong>code readability, encapsulation, and design</strong>.</p>
<h2 id="heading-design-principles-patterns">Design Principles / Patterns</h2>
<h3 id="heading-1-what-is-solid"><strong>1. What is SOLID?</strong></h3>
<p><a target="_blank" href="https://blog.ashutoshkrris.in/solid-principles-for-better-software-design"><strong>SOLID</strong></a> is an acronym for five design principles that make code <strong>more maintainable, scalable, and testable</strong>:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Principle</strong></td><td><strong>Description</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>S – Single Responsibility Principle (SRP)</strong></td><td>A class should have <strong>only one reason to change</strong>. Each class should focus on a single functionality.</td></tr>
<tr>
<td><strong>O – Open/Closed Principle (OCP)</strong></td><td>Classes should be <strong>open for extension, closed for modification</strong>.</td></tr>
<tr>
<td><strong>L – Liskov Substitution Principle (LSP)</strong></td><td>Subclasses should be <strong>substitutable</strong> for their parent classes without affecting program correctness.</td></tr>
<tr>
<td><strong>I – Interface Segregation Principle (ISP)</strong></td><td>Clients should <strong>not be forced to depend on methods they don’t use</strong>. Prefer multiple small interfaces over one large interface.</td></tr>
<tr>
<td><strong>D – Dependency Inversion Principle (DIP)</strong></td><td>High-level modules should <strong>not depend on low-level modules</strong>. Both should depend on <strong>abstractions</strong>.</td></tr>
</tbody>
</table>
</div><p>✅ These principles are key to <strong>writing clean and scalable Java applications</strong>.</p>
<h3 id="heading-2-what-is-the-singleton-pattern"><strong>2. What is the Singleton pattern?</strong></h3>
<p>The <strong>Singleton pattern</strong> ensures a class has <strong>only one instance</strong> and provides a global access point.</p>
<p><strong>Implementation (Thread-safe, lazy initialization):</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Singleton</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">volatile</span> Singleton instance;

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">Singleton</span><span class="hljs-params">()</span> </span>{} <span class="hljs-comment">// private constructor</span>

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Singleton <span class="hljs-title">getInstance</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">if</span> (instance == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">synchronized</span>(Singleton.class) {
                <span class="hljs-keyword">if</span> (instance == <span class="hljs-keyword">null</span>) {
                    instance = <span class="hljs-keyword">new</span> Singleton();
                }
            }
        }
        <span class="hljs-keyword">return</span> instance;
    }
}
</code></pre>
<p>✅ Use cases:</p>
<ul>
<li><p>Logger</p>
</li>
<li><p>Configuration manager</p>
</li>
<li><p>Thread pool manager</p>
</li>
</ul>
<h3 id="heading-3-how-to-implement-an-immutable-class"><strong>3. How to implement an immutable class?</strong></h3>
<p><strong>Steps to make a class immutable:</strong></p>
<ol>
<li><p>Declare class as <code>final</code>.</p>
</li>
<li><p>Make all fields <code>private</code> and <code>final</code>.</p>
</li>
<li><p>No setters.</p>
</li>
<li><p>Return <strong>deep copies</strong> of mutable objects.</p>
</li>
</ol>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Employee</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> String name;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> age;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Employee</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.age = age;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{ <span class="hljs-keyword">return</span> name; }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getAge</span><span class="hljs-params">()</span> </span>{ <span class="hljs-keyword">return</span> age; }
}
</code></pre>
<p>✅ Immutable objects are <strong>thread-safe</strong> and prevent unintended state changes.</p>
<h3 id="heading-4-what-is-the-factory-pattern"><strong>4. What is the Factory pattern?</strong></h3>
<p>The <strong>Factory pattern</strong> provides a <strong>way to create objects without exposing instantiation logic</strong>.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Shape</span> </span>{ <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">draw</span><span class="hljs-params">()</span></span>; }

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Circle</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Shape</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">draw</span><span class="hljs-params">()</span> </span>{ System.out.println(<span class="hljs-string">"Circle"</span>); }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Shape</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">draw</span><span class="hljs-params">()</span> </span>{ System.out.println(<span class="hljs-string">"Square"</span>); }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ShapeFactory</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Shape <span class="hljs-title">getShape</span><span class="hljs-params">(String type)</span> </span>{
        <span class="hljs-keyword">if</span> (type.equalsIgnoreCase(<span class="hljs-string">"circle"</span>)) <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Circle();
        <span class="hljs-keyword">if</span> (type.equalsIgnoreCase(<span class="hljs-string">"square"</span>)) <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Square();
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"Unknown shape"</span>);
    }
}

<span class="hljs-comment">// Usage</span>
Shape s = ShapeFactory.getShape(<span class="hljs-string">"circle"</span>);
s.draw();
</code></pre>
<p>✅ Use when object creation <strong>logic is complex</strong> or depends on conditions.</p>
<h3 id="heading-5-what-is-dependency-injection-di"><strong>5. What is Dependency Injection (DI)?</strong></h3>
<p><strong>Dependency Injection</strong> is a <strong>design pattern</strong> where an object receives its dependencies from <strong>external sources</strong> rather than creating them internally.</p>
<p><strong>Types of DI:</strong></p>
<ul>
<li><p><strong>Constructor injection</strong> – dependencies passed via constructor</p>
</li>
<li><p><strong>Setter injection</strong> – dependencies set via setters</p>
</li>
<li><p><strong>Interface injection</strong> – using an interface to inject dependencies (less common)</p>
</li>
</ul>
<p><strong>Example (Constructor DI):</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Service</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Repository repo;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Service</span><span class="hljs-params">(Repository repo)</span> </span>{ <span class="hljs-keyword">this</span>.repo = repo; }
}
Repository repo = <span class="hljs-keyword">new</span> Repository();
Service service = <span class="hljs-keyword">new</span> Service(repo);
</code></pre>
<p>✅ Benefits:</p>
<ul>
<li><p>Promotes <strong>loose coupling</strong></p>
</li>
<li><p>Easier <strong>unit testing</strong></p>
</li>
<li><p>Improves <strong>maintainability</strong></p>
</li>
</ul>
<h2 id="heading-jvm-internals-and-performance">JVM Internals and Performance</h2>
<h3 id="heading-1-what-happens-when-you-run-a-java-program"><strong>1. What happens when you run a Java program?</strong></h3>
<p><strong>Steps in Java program execution:</strong></p>
<ol>
<li><p><strong>Compilation:</strong> <code>.java</code> source code is compiled into <code>.class</code> bytecode using <code>javac</code>.</p>
</li>
<li><p><strong>Class loading:</strong> JVM loads the <code>.class</code> files into memory using ClassLoaders.</p>
</li>
<li><p><strong>Bytecode verification:</strong> Ensures code is valid and doesn’t violate JVM constraints.</p>
</li>
<li><p><strong>Execution:</strong> Just-In-Time (JIT) compiler converts bytecode into native machine code for performance.</p>
</li>
<li><p><strong>Memory allocation:</strong> Objects are created in the heap; references stored in stack.</p>
</li>
<li><p><strong>Garbage Collection:</strong> Unreferenced objects are cleaned automatically.</p>
</li>
</ol>
<p>✅ Key point: JVM allows <strong>platform independence</strong> by abstracting underlying OS and hardware.</p>
<h3 id="heading-2-explain-class-loading-process"><strong>2. Explain class loading process</strong></h3>
<p>Class loading is handled by the JVM in <strong>three phases</strong>:</p>
<ol>
<li><p><strong>Loading:</strong> Loads <code>.class</code> file into memory using ClassLoader.</p>
</li>
<li><p><strong>Linking:</strong></p>
<ul>
<li><p><strong>Verification:</strong> Ensures bytecode integrity</p>
</li>
<li><p><strong>Preparation:</strong> Allocates memory for static variables</p>
</li>
<li><p><strong>Resolution:</strong> Resolves symbolic references</p>
</li>
</ul>
</li>
<li><p><strong>Initialization:</strong> Executes static blocks and initializes static fields.</p>
</li>
</ol>
<h3 id="heading-3-what-is-the-role-of-classloader"><strong>3. What is the role of ClassLoader?</strong></h3>
<p><strong>ClassLoader</strong> loads Java classes into JVM <strong>at runtime</strong>.</p>
<p><strong>Types of ClassLoaders:</strong></p>
<ol>
<li><p><strong>Bootstrap ClassLoader:</strong> Loads core Java classes (rt.jar)</p>
</li>
<li><p><strong>Extension ClassLoader:</strong> Loads JDK extension libraries (<code>lib/ext</code>)</p>
</li>
<li><p><strong>Application ClassLoader:</strong> Loads classes from classpath (your code)</p>
</li>
<li><p><strong>Custom ClassLoader:</strong> Can be created for dynamic class loading</p>
</li>
</ol>
<p>✅ ClassLoader ensures <strong>lazy loading</strong> — classes are loaded only when needed.</p>
<h3 id="heading-4-how-does-java-achieve-platform-independence"><strong>4. How does Java achieve platform independence?</strong></h3>
<ul>
<li><p>Java code is compiled into <strong>bytecode</strong> (<code>.class</code> file), not native machine code.</p>
</li>
<li><p>JVM <strong>interprets bytecode</strong> or uses JIT to convert to <strong>native code</strong>.</p>
</li>
<li><p>Same bytecode can run on any platform with a compatible JVM.</p>
</li>
</ul>
<p><strong>Key principle:</strong> Write Once, Run Anywhere (WORA).</p>
<h3 id="heading-5-how-to-improve-java-performance"><strong>5. How to improve Java performance?</strong></h3>
<ul>
<li><p><strong>Memory management:</strong></p>
<ul>
<li><p>Use proper <strong>data structures</strong> (ArrayList vs LinkedList)</p>
</li>
<li><p>Minimize object creation, reuse objects</p>
</li>
</ul>
</li>
<li><p><strong>Multithreading:</strong> Use <strong>ExecutorService</strong>, parallel streams wisely</p>
</li>
<li><p><strong>Collections:</strong> Use <strong>Concurrent collections</strong> for thread safety</p>
</li>
<li><p><strong>Garbage Collection tuning:</strong> Adjust <strong>heap size</strong> and <strong>GC algorithm</strong></p>
</li>
<li><p><strong>String handling:</strong> Use <strong>StringBuilder</strong> instead of String concatenation in loops</p>
</li>
<li><p><strong>Profiling:</strong> Use tools like <strong>VisualVM, JConsole</strong> to detect bottlenecks</p>
</li>
</ul>
<h3 id="heading-6-garbage-collection-overview"><strong>6. Garbage Collection overview</strong></h3>
<ul>
<li><p><strong>Automatic memory management</strong> by JVM</p>
</li>
<li><p>Removes <strong>unreachable objects</strong> from heap</p>
</li>
<li><p>Common collectors: Serial, Parallel, CMS, G1</p>
</li>
<li><p>GC events: Minor GC (young generation), Major GC (old generation)</p>
</li>
<li><p><strong>Finalize()</strong> is called before GC (deprecated in Java 9+)</p>
</li>
</ul>
<p>✅ Modern JVM uses <strong>generational GC</strong> for efficiency.</p>
<h3 id="heading-7-heap-vs-stack"><strong>7. Heap vs Stack</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Memory Area</strong></td><td><strong>Purpose</strong></td><td><strong>Example</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Heap</strong></td><td>Stores objects and arrays</td><td><code>new Employee()</code></td></tr>
<tr>
<td><strong>Stack</strong></td><td>Stores method call frames, local variables</td><td><code>int x = 10;</code></td></tr>
</tbody>
</table>
</div><ul>
<li><p>Stack memory is <strong>LIFO</strong>, automatically cleaned.</p>
</li>
<li><p>Heap memory is <strong>shared</strong>, cleaned by GC.</p>
</li>
</ul>
<h3 id="heading-8-permgen-vs-metaspace"><strong>8. PermGen vs Metaspace</strong></h3>
<ul>
<li><p><strong>PermGen (Java 7 and below):</strong> Stores class metadata; fixed size → risk of <code>OutOfMemoryError</code>.</p>
</li>
<li><p><strong>Metaspace (Java 8+):</strong> Dynamically resizable; stored in native memory → reduces class loading errors.</p>
</li>
</ul>
<h2 id="heading-miscellaneous-java-concepts">Miscellaneous Java Concepts</h2>
<h3 id="heading-1-serialization-vs-deserialization"><strong>1. Serialization vs Deserialization</strong></h3>
<ul>
<li><p><strong>Serialization:</strong> Converts a Java object into a byte stream to save to disk or send over a network.</p>
</li>
<li><p><strong>Deserialization:</strong> Converts the byte stream back into a Java object.</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-comment">// Serialization</span>
ObjectOutputStream oos = <span class="hljs-keyword">new</span> ObjectOutputStream(<span class="hljs-keyword">new</span> FileOutputStream(<span class="hljs-string">"data.obj"</span>));
oos.writeObject(employee);

<span class="hljs-comment">// Deserialization</span>
ObjectInputStream ois = <span class="hljs-keyword">new</span> ObjectInputStream(<span class="hljs-keyword">new</span> FileInputStream(<span class="hljs-string">"data.obj"</span>));
Employee e = (Employee) ois.readObject();
</code></pre>
<p><strong>Notes:</strong></p>
<ul>
<li><p>Use <code>transient</code> keyword for fields that shouldn’t be serialized.</p>
</li>
<li><p>Serializable classes must implement <code>Serializable</code>.</p>
</li>
</ul>
<h3 id="heading-2-what-is-a-marker-interface"><strong>2. What is a marker interface?</strong></h3>
<ul>
<li><p>An interface <strong>without methods</strong> used to mark a class with special behavior.</p>
</li>
<li><p>Examples: <code>Serializable</code>, <code>Cloneable</code>, <code>Remote</code>.</p>
</li>
</ul>
<p><strong>Purpose:</strong> Provides <strong>metadata</strong> to JVM or frameworks.</p>
<h3 id="heading-3-what-is-instanceof-keyword"><strong>3. What is instanceof keyword?</strong></h3>
<ul>
<li>Checks if an object is an instance of a specific class or implements an interface.</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">String s = <span class="hljs-string">"Java"</span>;
<span class="hljs-keyword">if</span> (s <span class="hljs-keyword">instanceof</span> String) {
    System.out.println(<span class="hljs-string">"s is a String"</span>);
}
</code></pre>
<p>✅ Always returns <code>true</code> for null checks: <code>null instanceof String</code> → <code>false</code>.</p>
<h3 id="heading-4-what-is-reflection-api"><strong>4. What is reflection API?</strong></h3>
<ul>
<li><p><strong>Reflection</strong> allows inspecting and manipulating classes, methods, and fields <strong>at runtime</strong>.</p>
</li>
<li><p>Can be used to:</p>
<ul>
<li><p>Get class info (<code>Class&lt;?&gt; clazz = obj.getClass();</code>)</p>
</li>
<li><p>Access private fields/methods</p>
</li>
<li><p>Dynamically create instances</p>
</li>
</ul>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">Class&lt;?&gt; clazz = Class.forName(<span class="hljs-string">"java.util.ArrayList"</span>);
Object obj = clazz.getDeclaredConstructor().newInstance();
</code></pre>
<p>✅ Useful for frameworks like Spring, Hibernate, and testing tools.</p>
<h3 id="heading-5-what-is-autoboxing-and-unboxing"><strong>5. What is autoboxing and unboxing?</strong></h3>
<ul>
<li><p><strong>Autoboxing:</strong> Automatic conversion from primitive to wrapper class</p>
<pre><code class="lang-java">  <span class="hljs-keyword">int</span> x = <span class="hljs-number">10</span>;
  Integer y = x; <span class="hljs-comment">// autoboxing</span>
</code></pre>
</li>
<li><p><strong>Unboxing:</strong> Wrapper class → primitive</p>
<pre><code class="lang-java">  Integer a = <span class="hljs-number">20</span>;
  <span class="hljs-keyword">int</span> b = a; <span class="hljs-comment">// unboxing</span>
</code></pre>
</li>
</ul>
<h3 id="heading-6-what-is-enum-in-java"><strong>6. What is enum in Java?</strong></h3>
<ul>
<li><p><code>enum</code> is a <strong>special class representing a fixed set of constants</strong>.</p>
</li>
<li><p>Can have <strong>fields, methods, and constructors</strong>.</p>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Day</span> </span>{ MONDAY, TUESDAY, WEDNESDAY }
Day today = Day.MONDAY;
</code></pre>
<p>✅ Useful for <strong>type safety</strong> instead of string constants.</p>
<h3 id="heading-7-can-we-override-private-methods"><strong>7. Can we override private methods?</strong></h3>
<ul>
<li><p><strong>No</strong>, private methods are not visible to subclasses.</p>
</li>
<li><p>They are <strong>class-specific</strong> and <strong>cannot be overridden</strong>, but they can be <strong>redeclared</strong> in a subclass.</p>
</li>
</ul>
<h3 id="heading-8-can-we-overload-main-method"><strong>8. Can we overload main method?</strong></h3>
<ul>
<li><strong>Yes</strong>, you can overload <code>main</code>:</li>
</ul>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{ }
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(<span class="hljs-keyword">int</span>[] args)</span> </span>{ }
</code></pre>
<ul>
<li>JVM always calls the <strong>String[] main method</strong>.</li>
</ul>
<h3 id="heading-9-can-constructor-be-private"><strong>9. Can constructor be private?</strong></h3>
<ul>
<li><p><strong>Yes</strong>, used in <strong>Singleton pattern</strong> or factory methods.</p>
</li>
<li><p>Prevents direct instantiation from outside the class.</p>
</li>
</ul>
<h3 id="heading-10-what-are-annotations-in-java"><strong>10. What are annotations in Java?</strong></h3>
<ul>
<li><p>Metadata for <strong>classes, methods, fields</strong>.</p>
</li>
<li><p>Examples: <code>@Override</code>, <code>@Deprecated</code>, <code>@FunctionalInterface</code></p>
</li>
<li><p>Custom annotation example:</p>
</li>
</ul>
<pre><code class="lang-java"><span class="hljs-meta">@Retention(RetentionPolicy.RUNTIME)</span>
<span class="hljs-meta">@Target(ElementType.METHOD)</span>
<span class="hljs-meta">@interface</span> Test { 
}
</code></pre>
<h3 id="heading-11-what-is-javabeans"><strong>11. What is JavaBeans?</strong></h3>
<ul>
<li><p><strong>JavaBean:</strong> A reusable class following:</p>
<ul>
<li><p>Private fields</p>
</li>
<li><p>Public getters and setters</p>
</li>
<li><p>No-arg constructor</p>
</li>
<li><p>Serializable</p>
</li>
</ul>
</li>
</ul>
<p>✅ Used for <strong>encapsulation</strong> and frameworks like JSP, JSF, and Spring.</p>
<h3 id="heading-12-what-is-var-keyword-in-java"><strong>12. What is var keyword in Java?</strong></h3>
<ul>
<li>Introduced in <strong>Java 10</strong> for <strong>local variable type inference</strong>.</li>
</ul>
<pre><code class="lang-java"><span class="hljs-keyword">var</span> name = <span class="hljs-string">"Ashutosh"</span>; <span class="hljs-comment">// inferred as String</span>
</code></pre>
<ul>
<li>Cannot be used for method parameters, fields, or return type.</li>
</ul>
<h3 id="heading-13-what-are-records-in-java"><strong>13. What are records in Java?</strong></h3>
<ul>
<li><p>Introduced in <strong>Java 14</strong> as <strong>immutable data carriers</strong>.</p>
</li>
<li><p>Automatically generate <strong>constructor, getters, equals, hashCode, toString</strong>.</p>
</li>
</ul>
<pre><code class="lang-java"><span class="hljs-function">record <span class="hljs-title">Employee</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{ }
Employee e = <span class="hljs-keyword">new</span> Employee(<span class="hljs-string">"John"</span>, <span class="hljs-number">25</span>);
</code></pre>
<p>✅ Great for <strong>DTOs and value objects</strong>.</p>
<blockquote>
<p>Learn more about records <a target="_blank" href="https://blog.ashutoshkrris.in/dto-vs-record-in-java-which-should-you-use">here</a>.</p>
</blockquote>
<h3 id="heading-14-difference-between-compile-time-and-runtime-errors"><strong>14. Difference between compile-time and runtime errors</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Type</td><td>When occurs</td><td>Example</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Compile-time error</strong></td><td>During compilation</td><td>Syntax error, missing semicolon</td></tr>
<tr>
<td><strong>Runtime error</strong></td><td>During program execution</td><td>NullPointerException, ArrayIndexOutOfBounds</td></tr>
</tbody>
</table>
</div><h2 id="heading-real-world-scenario-based-questions">Real-World Scenario-Based Questions</h2>
<h3 id="heading-1-how-would-you-optimize-a-large-collection-for-search"><strong>1. How would you optimize a large collection for search?</strong></h3>
<p><strong>Scenario:</strong> You have a large dataset and need frequent lookups.</p>
<p><strong>Approach:</strong></p>
<ol>
<li><p><strong>Choose the right data structure:</strong></p>
<ul>
<li><p><code>HashMap</code> for O(1) key-value lookup.</p>
</li>
<li><p><code>TreeMap</code> if sorted order is required (O(log n) lookup).</p>
</li>
<li><p><code>HashSet</code> for unique element search.</p>
</li>
</ul>
</li>
<li><p><strong>Indexing:</strong> Precompute indices for frequent queries.</p>
</li>
<li><p><strong>Use streams with parallel processing</strong> if data is very large.</p>
</li>
<li><p><strong>Avoid unnecessary object creation:</strong> Use primitives or immutable objects.</p>
</li>
<li><p><strong>Memory considerations:</strong> If memory is tight, consider using compressed data structures or disk-based solutions.</p>
</li>
</ol>
<p><strong>Example:</strong></p>
<pre><code class="lang-java">Map&lt;String, Employee&gt; employeeMap = <span class="hljs-keyword">new</span> HashMap&lt;&gt;();
<span class="hljs-keyword">for</span>(Employee e: employees) {
    employeeMap.put(e.getId(), e);
}
<span class="hljs-comment">// Lookup by ID is now O(1)</span>
</code></pre>
<h3 id="heading-2-how-to-handle-concurrency-in-a-shared-resource"><strong>2. How to handle concurrency in a shared resource?</strong></h3>
<p><strong>Scenario:</strong> Multiple threads need to access/update shared data.</p>
<p><strong>Approach:</strong></p>
<ol>
<li><p><strong>Synchronized blocks/methods:</strong></p>
<pre><code class="lang-java"> <span class="hljs-keyword">synchronized</span>(<span class="hljs-keyword">this</span>) {
     <span class="hljs-comment">// critical section</span>
 }
</code></pre>
</li>
<li><p><strong>Concurrent Collections:</strong> Use <code>ConcurrentHashMap</code>, <code>CopyOnWriteArrayList</code>.</p>
</li>
<li><p><strong>Locks:</strong> Use <code>ReentrantLock</code> for fine-grained control.</p>
</li>
<li><p><strong>Atomic Variables:</strong> Use <code>AtomicInteger</code>, <code>AtomicReference</code> for atomic operations.</p>
</li>
<li><p><strong>Avoid deadlocks:</strong> Always acquire locks in consistent order.</p>
</li>
</ol>
<p>✅ Modern Java encourages <strong>lock-free structures</strong> and <strong>immutability</strong> where possible.</p>
<h3 id="heading-3-whats-your-approach-for-debugging-memory-leaks"><strong>3. What’s your approach for debugging memory leaks?</strong></h3>
<p><strong>Steps:</strong></p>
<ol>
<li><p><strong>Identify symptoms:</strong> High heap usage, <code>OutOfMemoryError</code>, slow performance.</p>
</li>
<li><p><strong>Analyze heap dumps:</strong> Use tools like <strong>VisualVM, Eclipse MAT, JProfiler</strong>.</p>
</li>
<li><p><strong>Check references:</strong> Look for <strong>unreleased objects</strong>, static collections, caches.</p>
</li>
<li><p><strong>Fix common causes:</strong></p>
<ul>
<li><p>Remove unused listeners or callbacks</p>
</li>
<li><p>Use <code>WeakReference</code> where needed</p>
</li>
<li><p>Clear collections properly</p>
</li>
</ul>
</li>
<li><p><strong>Test thoroughly:</strong> Run under load to confirm memory usage stabilizes.</p>
</li>
</ol>
<h3 id="heading-4-how-to-ensure-thread-safety-without-performance-issues"><strong>4. How to ensure thread safety without performance issues?</strong></h3>
<p><strong>Scenario:</strong> High-concurrency application.</p>
<p><strong>Approach:</strong></p>
<ol>
<li><p>Prefer <strong>immutable objects</strong> to avoid synchronization overhead.</p>
</li>
<li><p>Use <strong>concurrent collections</strong> (<code>ConcurrentHashMap</code>, <code>ConcurrentLinkedQueue</code>) instead of synchronized versions.</p>
</li>
<li><p>Minimize <strong>synchronized blocks</strong> to only critical sections.</p>
</li>
<li><p>Use <strong>atomic variables</strong> for counters or flags.</p>
</li>
<li><p>Consider <strong>ReadWriteLock</strong> if reads dominate writes.</p>
</li>
</ol>
<p>✅ Key: Balance <strong>thread safety vs performance</strong>.</p>
<h3 id="heading-5-explain-a-situation-where-you-used-java-8-features-to-simplify-code"><strong>5. Explain a situation where you used Java 8 features to simplify code</strong></h3>
<p><strong>Example Answer:</strong></p>
<blockquote>
<p>“In a recent project, we had a list of employees and needed to filter those in a specific department, sort by salary, and collect names. Using Java 8 Streams and lambdas, I could do it in one readable statement instead of nested loops:</p>
<pre><code class="lang-java">List&lt;String&gt; names = employees.stream()
    .filter(e -&gt; e.getDepartment().equals(<span class="hljs-string">"Engineering"</span>))
    .sorted(Comparator.comparing(Employee::getSalary).reversed())
    .map(Employee::getName)
    .collect(Collectors.toList());
</code></pre>
<p>This approach reduced boilerplate code, improved readability, and was easy to maintain.”</p>
</blockquote>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>This guide covers <strong>all essential Core Java concepts, coding patterns, and real-world scenarios</strong> needed to excel in Java interviews in 2025. Use it to <strong>strengthen fundamentals, improve problem-solving, and confidently tackle interviews</strong>.</p>
]]></content:encoded></item><item><title><![CDATA[DTO vs Record in Java: Which Should You Use?]]></title><description><![CDATA[In Java applications, we often need to transfer data between different layers of the application, or between services. For this purpose, we use Data Transfer Objects (DTOs). A DTO is a simple object designed to hold data, without any complex behavior...]]></description><link>https://blog.ashutoshkrris.in/dto-vs-record-in-java-which-should-you-use</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/dto-vs-record-in-java-which-should-you-use</guid><category><![CDATA[Java]]></category><category><![CDATA[Records]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sun, 29 Sep 2024 19:13:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727637193632/82341f89-6db7-4b75-9f37-dcf56814cdce.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Java applications, we often need to transfer data between different layers of the application, or between services. For this purpose, we use <strong>Data Transfer Objects (DTOs)</strong>. A DTO is a simple object designed to hold data, without any complex behavior or logic. Its job is to bundle data and pass it along where needed.</p>
<p>Now, Java introduced a new feature in <strong>Java 14</strong>, called <strong>Records</strong>. These are special types of classes that focus on holding data, just like DTOs. The big difference is that Records do a lot of the repetitive work for us. For example, they automatically create methods to get the data (like getters), and they handle equality checks, <code>toString()</code>, and more. This feature became fully available in <strong>Java 16</strong>, making Records a modern, clean way to work with data in Java.</p>
<p>So, why are we comparing DTOs and Records? Because they both serve a similar purpose — carrying data. However, understanding when to use one over the other is important as Java continues to evolve. In this article, we’ll explore the differences and help you decide which one fits your needs better, especially if you’re working on modern Java applications.</p>
<h2 id="heading-what-is-a-dto">What is a DTO?</h2>
<p>A <strong>Data Transfer Object (DTO)</strong> is a simple Java object that is used to move data between different parts of an application. Think of it as a container for carrying data between layers of your application. For example, in a web application, a DTO might be used to transfer data from the service layer to the controller, or from the controller to the view layer.</p>
<p>DTOs help keep the different parts of an application separated, making the code more organized and easier to maintain. They typically don’t have any business logic or complex behavior. Instead, they just hold data.</p>
<h3 id="heading-how-are-dtos-implemented">How are DTOs implemented?</h3>
<p>DTOs are usually implemented as regular Java classes. A typical DTO includes:</p>
<ul>
<li><p><strong>Private fields</strong> for the data it holds.</p>
</li>
<li><p><strong>Getters and Setters</strong> to access and modify the data.</p>
</li>
<li><p>A <strong>Constructor</strong> to create the object.</p>
</li>
<li><p><strong>Override methods</strong> like <code>toString()</code>, <code>hashCode()</code>, and <code>equals()</code> for comparing and printing the object in a meaningful way.</p>
</li>
</ul>
<p>Here’s an example of a <strong>UserDTO</strong> class :</p>
<pre><code class="lang-java"><span class="hljs-keyword">import</span> java.util.Objects;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserDTO</span> </span>{
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> age;
    <span class="hljs-keyword">private</span> String email;

    <span class="hljs-comment">// Constructor</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">UserDTO</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age, String email)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.age = age;
        <span class="hljs-keyword">this</span>.email = email;
    }

    <span class="hljs-comment">// Getters and Setters</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> name;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setName</span><span class="hljs-params">(String name)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getAge</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> age;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAge</span><span class="hljs-params">(<span class="hljs-keyword">int</span> age)</span> </span>{
        <span class="hljs-keyword">this</span>.age = age;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getEmail</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> email;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setEmail</span><span class="hljs-params">(String email)</span> </span>{
        <span class="hljs-keyword">this</span>.email = email;
    }

    <span class="hljs-comment">// Overriding toString method for meaningful output</span>
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"UserDTO{"</span> +
                <span class="hljs-string">"name='"</span> + name + <span class="hljs-string">'\''</span> +
                <span class="hljs-string">", age="</span> + age +
                <span class="hljs-string">", email='"</span> + email + <span class="hljs-string">'\''</span> +
                <span class="hljs-string">'}'</span>;
    }

    <span class="hljs-comment">// Overriding equals method for object comparison</span>
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">equals</span><span class="hljs-params">(Object o)</span> </span>{
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span> == o) <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
        <span class="hljs-keyword">if</span> (o == <span class="hljs-keyword">null</span> || getClass() != o.getClass()) <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
        UserDTO userDTO = (UserDTO) o;
        <span class="hljs-keyword">return</span> age == userDTO.age &amp;&amp; Objects.equals(name, userDTO.name) &amp;&amp; Objects.equals(email, userDTO.email);
    }

    <span class="hljs-comment">// Overriding hashCode method</span>
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">hashCode</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> Objects.hash(name, age, email);
    }
}
</code></pre>
<p>This <strong>UserDTO</strong> class holds information about a user: their name, age, and email. It also provides basic functionality like comparing two <code>UserDTO</code> objects (using <code>equals()</code>), generating a unique hash code (using <code>hashCode()</code>), and a <code>toString()</code> method for readable output.</p>
<blockquote>
<p>With tools like Lombok, you can avoid manually writing boilerplate code while still having a fully functional DTO. However, with <strong>Records</strong>, as we’ll explore later, Java offers an alternative that also eliminates much of the boilerplate but with a different design philosophy (immutability by default).</p>
</blockquote>
<p>Here’s how you can use the <code>UserDTO</code>:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserDTOUsageExample</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        UserDTO user = <span class="hljs-keyword">new</span> UserDTO(<span class="hljs-string">"Ashutosh"</span>, <span class="hljs-number">25</span>, <span class="hljs-string">"ashutosh@example.com"</span>);

        <span class="hljs-comment">// Access data</span>
        System.out.println(user.getName());
        System.out.println(user.getAge());
        System.out.println(user.getEmail());

        <span class="hljs-comment">// Using the toString() method</span>
        System.out.println(user);

        <span class="hljs-comment">// Comparing records</span>
        UserDTO anotherUser = <span class="hljs-keyword">new</span> UserDTO(<span class="hljs-string">"Vishakha"</span>, <span class="hljs-number">22</span>, <span class="hljs-string">"vishakha@example.com"</span>);
        System.out.println(user.equals(anotherUser));
    }
}
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Ashutosh
25
ashutosh@example.com
UserDTO{name=<span class="hljs-string">'Ashutosh'</span>, age=25, email=<span class="hljs-string">'ashutosh@example.com'</span>}
<span class="hljs-literal">false</span>
</code></pre>
<h2 id="heading-what-is-a-java-record">What is a Java Record?</h2>
<p><strong>Java Records</strong> are a special type of class introduced in <strong>Java 14</strong> (as a preview feature) and fully released in <strong>Java 16</strong>. They simplify the creation of immutable data carriers. Records are designed to hold data in a concise and readable way, and they eliminate much of the boilerplate code that traditional classes, like DTOs, require.</p>
<p>In a traditional DTO, you manually write constructors, getters, <code>equals()</code>, <code>hashCode()</code>, and <code>toString()</code> methods (as we did earlier). With Records, Java generates all of these for you automatically. This makes them ideal for simple, immutable objects whose main job is to carry data.</p>
<h3 id="heading-key-features-of-java-records">Key Features of Java Records</h3>
<ul>
<li><p><strong>Immutable by default</strong>: Once you create a record, you can't change its data (unlike DTOs, which are typically mutable).</p>
</li>
<li><p><strong>Compact syntax</strong>: You declare the fields and Java generates the constructor, getters, <code>equals()</code>, <code>hashCode()</code>, and <code>toString()</code> automatically.</p>
</li>
<li><p><strong>No setters</strong>: Since records are immutable, they don’t provide setters.</p>
</li>
</ul>
<p>Let’s create a <strong>UserRecord</strong> that represents the same user data as our earlier <strong>UserDTO</strong>, but using a record:</p>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">public</span> record <span class="hljs-title">UserRecord</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age, String email)</span> </span>{
}
</code></pre>
<p>That's it! With just one line, Java generates:</p>
<ul>
<li><p>A <strong>constructor</strong>: <code>new UserRecord(String name, int age, String email)</code></p>
</li>
<li><p><strong>Getters</strong> for each field: <code>name()</code>, <code>age()</code>, and <code>email()</code></p>
</li>
<li><p>An <code>equals()</code> method for comparing two <code>UserRecord</code> objects.</p>
</li>
<li><p>A <code>hashCode()</code> method to generate a unique hash code.</p>
</li>
<li><p>A <code>toString()</code> method that returns a string representation like this: <code>UserRecord[name=Ashutosh, age=25, email=ashutosh@example.com]</code>.</p>
</li>
</ul>
<p>Here’s how you can use the <code>UserRecord</code>:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserRecordUsageExample</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        UserRecord user = <span class="hljs-keyword">new</span> UserRecord(<span class="hljs-string">"Ashutosh"</span>, <span class="hljs-number">25</span>, <span class="hljs-string">"ashutosh@example.com"</span>);

        <span class="hljs-comment">// Access data</span>
        System.out.println(user.name());
        System.out.println(user.age());
        System.out.println(user.email());

        <span class="hljs-comment">// Using the toString() method</span>
        System.out.println(user);

        <span class="hljs-comment">// Comparing records</span>
        UserRecord anotherUser = <span class="hljs-keyword">new</span> UserRecord(<span class="hljs-string">"Vishakha"</span>, <span class="hljs-number">22</span>, <span class="hljs-string">"vishakha@example.com"</span>);
        System.out.println(user.equals(anotherUser));
    }
}
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Ashutosh
25
ashutosh@example.com
UserRecord[name=Ashutosh, age=25, email=ashutosh@example.com]
<span class="hljs-literal">false</span>
</code></pre>
<p>With <strong>UserRecord</strong>, we avoided writing getters, constructors, <code>equals()</code>, <code>hashCode()</code>, and <code>toString()</code> manually. Java Records offer a clean, concise way to create immutable objects that only carry data.</p>
<h3 id="heading-why-use-records">Why Use Records?</h3>
<ul>
<li><p><strong>Less Boilerplate</strong>: You don’t have to write repetitive code like getters or <code>equals()</code> methods.</p>
</li>
<li><p><strong>Immutable by Design</strong>: Ensures the data can't be changed after the object is created, making it <strong>safer to use in multi-threaded environments</strong>.</p>
</li>
<li><p><strong>Clear Intent</strong>: Using a Record clearly communicates that the object is just for carrying data, without additional behavior or logic.</p>
</li>
</ul>
<h2 id="heading-comparing-dto-and-record">Comparing DTO and Record</h2>
<p>Now that we know about DTO and Records, let’s compare them in this section.</p>
<h3 id="heading-immutability">Immutability</h3>
<p><strong>Records</strong> are <strong>immutable by design</strong>, meaning once you create a record instance, you can’t change its data. This immutability ensures that the data remains <strong>consistent and thread-safe</strong> without needing any extra code. For example, in a <code>UserRecord</code>, the fields <code>name</code>, <code>age</code>, and <code>email</code> can be set only when the record is created, and they can't be modified afterward.</p>
<p>On the other hand, <strong>DTOs</strong> are typically <strong>mutable</strong>, meaning their fields can be changed after the object is created. To make DTOs immutable, you would have to explicitly avoid setters or design them carefully (e.g., using final fields). Here’s how immutability looks with a record versus a traditional DTO:</p>
<ul>
<li><p><strong>Record</strong>: Immutable by default.</p>
</li>
<li><p><strong>DTO</strong>: Requires manual enforcement for immutability, which can lead to more complex code and potential bugs.</p>
</li>
</ul>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ImmutabilityExample</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        UserDTO userDTO = <span class="hljs-keyword">new</span> UserDTO(<span class="hljs-string">"Ashutosh"</span>, <span class="hljs-number">25</span>, <span class="hljs-string">"ashutosh@example.com"</span>);
        userDTO.setAge(<span class="hljs-number">26</span>);  <span class="hljs-comment">// DTO allows this by default.</span>

        UserRecord userRecord = <span class="hljs-keyword">new</span> UserRecord(<span class="hljs-string">"Ashutosh"</span>, <span class="hljs-number">25</span>, <span class="hljs-string">"ashutosh@example.com"</span>);
        userRecord.name = <span class="hljs-string">"Jane"</span>; <span class="hljs-comment">// This would result in a compile-time error.</span>
    }
}
</code></pre>
<h3 id="heading-boilerplate-code">Boilerplate Code</h3>
<p>One of the biggest advantages of <strong>Records</strong> is that they significantly <strong>reduce boilerplate code</strong>. When using a DTO, you often have to manually write getters, setters, constructors, <code>equals()</code>, <code>hashCode()</code>, and <code>toString()</code> methods. With Records, all of this is generated for you automatically.</p>
<p>In contrast, traditional <strong>DTOs</strong> require more manual coding. Although tools like <strong>Lombok</strong> can help reduce the amount of boilerplate, they still don’t provide the same level of simplicity as Records. Here’s a comparison:</p>
<ul>
<li><p><strong>Record</strong>: Automatically generates constructor, getters, <code>equals()</code>, <code>hashCode()</code>, and <code>toString()</code>.</p>
</li>
<li><p><strong>DTO</strong>: Requires manual implementation or the use of tools like Lombok.</p>
</li>
</ul>
<h3 id="heading-data-representation">Data Representation</h3>
<p><strong>Records</strong> provide a <strong>compact and concise</strong> way of representing data. Since the declaration of a Record contains only the fields, the code is cleaner and easier to read. This makes it easier to maintain, especially in projects with a lot of data models.</p>
<p>For example:</p>
<pre><code class="lang-java"><span class="hljs-comment">// Record: Clean and simple</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> record <span class="hljs-title">UserRecord</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age, String email)</span> </span>{}
</code></pre>
<p>Compare this to a DTO, which typically has a lot more code:</p>
<pre><code class="lang-java"><span class="hljs-comment">// DTO: More verbose</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserDTO</span> </span>{
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> age;
    <span class="hljs-keyword">private</span> String email;

    <span class="hljs-comment">// Constructor, Getters, Setters, toString, equals, hashCode...</span>
}
</code></pre>
<p>With Records, the intent is clearer: it’s just a data carrier with no extra behavior, whereas DTOs can easily become cluttered with boilerplate or additional logic.</p>
<h3 id="heading-customization">Customization</h3>
<p>One area where <strong>DTOs</strong> have an advantage is in <strong>customization</strong>. DTOs allow you to add custom logic, such as data validation, transformation methods, or even business logic if needed (although this is generally discouraged in pure DTOs). For example, you could add a validation method to ensure the email field follows a valid format.</p>
<p>With <strong>Records</strong>, customization is more limited. Since they are designed to be lightweight and immutable, you can’t easily add custom methods that modify internal state or perform complex logic. If your use case requires custom behavior or logic in your data objects, DTOs offer more flexibility.</p>
<p>Here’s a quick example of adding custom validation to a DTO:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserDTO</span> </span>{
    <span class="hljs-keyword">private</span> String email;

    <span class="hljs-comment">// Method to validate email format</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isValidEmail</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> email != <span class="hljs-keyword">null</span> &amp;&amp; email.contains(<span class="hljs-string">"@"</span>);
    }
}
</code></pre>
<p>With a <strong>Record</strong>, this level of customization would typically be handled outside the Record itself. Records focus strictly on carrying data, while logic like validation is expected to be handled elsewhere.</p>
<h3 id="heading-alignment-with-functional-programming">Alignment with Functional Programming</h3>
<p>One of the key principles of <strong>functional programming</strong> is immutability — the idea that data objects should not be changed after they are created. <strong>Records</strong> align more closely with functional programming principles because they are <strong>immutable by default</strong>. This makes them an ideal choice in systems that favor or adopt a functional programming style.</p>
<ul>
<li><p><strong>Records</strong>:</p>
<ul>
<li><p>Designed to be immutable, which aligns with functional programming's emphasis on creating data structures that cannot change state.</p>
</li>
<li><p>They promote a more declarative style, where you can pass around immutable data objects without side effects, making them predictable and easier to reason about.</p>
</li>
</ul>
</li>
</ul>
<p>In contrast, <strong>DTOs</strong> are traditionally <strong>mutable</strong> by nature. While it’s possible to make DTOs immutable (by avoiding setters and using final fields), it requires manual enforcement. DTOs often follow the <strong>object-oriented</strong> paradigm, where state changes are more common.</p>
<ul>
<li><p><strong>DTOs</strong>:</p>
<ul>
<li><p>More flexible in terms of mutability, which makes them better suited to imperative or object-oriented programming styles.</p>
</li>
<li><p>When used in their mutable form, DTOs can lead to side effects, which is generally discouraged in functional programming.</p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-when-to-use-dto-vs-record">When to Use DTO vs Record</h2>
<p>When deciding between using a <strong>DTO</strong> or a <strong>Record</strong>, the choice depends largely on your specific use case, project requirements, and the version of Java you're using. Below is a breakdown of when to use each:</p>
<h3 id="heading-when-to-use-dtos">When to Use DTOs</h3>
<ol>
<li><p><strong>When mutability is required</strong>:<br /> If your object’s data needs to be modified after creation, <strong>DTOs</strong> are the better choice. DTOs are typically mutable, allowing you to change the values of fields as needed. This is useful in scenarios where data is updated throughout the lifecycle of an object.</p>
<p> Example: In a web application, a form submission may initially create a <code>UserDTO</code> with some fields left blank. As the user updates their profile, the <code>UserDTO</code> may need to change accordingly.</p>
</li>
<li><p><strong>When additional behavior or validation logic is needed</strong>:<br /> DTOs are more flexible when it comes to adding custom behavior like validation, transformations, or additional methods. If your data object needs logic beyond simply carrying data (e.g., verifying an email format or sanitizing input), then a DTO is more suitable.</p>
<p> Example: Adding a method in <code>UserDTO</code> to validate the format of an email before passing it between layers of your application.</p>
</li>
<li><p><strong>Compatibility with older versions of Java (pre-Java 16)</strong>:<br /> If your project is running on a version of Java earlier than Java 16, you won’t be able to use Records. In these cases, you’ll need to use traditional DTOs or alternatives like Lombok to simplify the code.</p>
<p> Example: If your application must support Java 11 or Java 8, then Records are not an option, and you’ll stick with DTOs.</p>
</li>
</ol>
<h3 id="heading-when-to-use-records">When to Use Records</h3>
<ol>
<li><p><strong>When you need a concise, immutable data carrier</strong>:<br /> <strong>Records</strong> are ideal when you need a lightweight, immutable object to carry data. Since they automatically generate essential methods (constructor, getters, <code>equals()</code>, <code>hashCode()</code>, and <code>toString()</code>), they offer a clean and efficient way to represent data.</p>
<p> Example: If you’re transferring data between services in a microservice architecture and don't need to modify the data, a <code>UserRecord</code> would be a perfect fit.</p>
</li>
<li><p><strong>For read-only data transfer between layers or services</strong>:<br /> If your application involves passing data around without the need to modify it, using a Record is a great choice. The immutability of Records ensures that the data remains consistent, making it suitable for cases like sending data from the database to a service layer or from one service to another.</p>
<p> Example: A Record might be used to send user data from a database layer to a REST controller in a web application.</p>
</li>
<li><p><strong>In modern Java applications (Java 16+)</strong>:<br /> If your project uses Java 16 or later, you can take full advantage of Records. They are designed to simplify data representation in modern Java applications and help reduce the boilerplate that comes with traditional DTOs.</p>
<p> Example: In a Java 17 web service, you might use Records for all your data transfer needs between different layers of your application to keep the codebase concise and maintainable.</p>
</li>
</ol>
<h2 id="heading-performance-considerations">Performance Considerations</h2>
<p>When comparing <strong>DTOs</strong> and <strong>Records</strong> in terms of performance, the differences are typically minimal, but there are a few important factors to consider:</p>
<h3 id="heading-memory-efficiency">Memory Efficiency</h3>
<p>Since <strong>Records</strong> are compact by design, they may consume slightly less memory than traditional <strong>DTOs</strong>. The key reason is that Records do not require the additional overhead of manually implementing getters, setters, <code>equals()</code>, <code>hashCode()</code>, and <code>toString()</code> methods. All of this is generated automatically by the Java compiler in a more optimized way, resulting in a smaller memory footprint.</p>
<p>For example:</p>
<ul>
<li><p>A <strong>DTO</strong> would need separate fields and methods for each operation (<code>getName()</code>, <code>setName()</code>, etc.).</p>
</li>
<li><p>A <strong>Record</strong> internally holds just the fields and automatically generates the necessary methods, potentially using fewer resources.</p>
</li>
</ul>
<h3 id="heading-immutability-and-thread-safety">Immutability and Thread-Safety</h3>
<p>The immutable nature of <strong>Records</strong> provides some inherent performance benefits, particularly in <strong>multi-threaded environments</strong>. Since Records are immutable, they don’t require synchronization or locking mechanisms when shared between threads. This can lead to better performance in scenarios where thread contention would normally degrade performance.</p>
<p>In contrast, if you use <strong>mutable DTOs</strong> in multi-threaded environments, you need to ensure thread safety, either by synchronizing access or using other mechanisms, which can introduce overhead and slow down the application.</p>
<h3 id="heading-garbage-collection">Garbage Collection</h3>
<p>Both DTOs and Records are plain Java objects (POJOs), so they are subject to the same garbage collection process. However, the <strong>concise nature of Records</strong> could lead to slightly faster garbage collection, as fewer objects are created or held in memory. This can contribute to improved performance in long-running applications or those handling large volumes of data objects.</p>
<h3 id="heading-cpu-overhead">CPU Overhead</h3>
<p>Since Records are auto-generated by the compiler and are optimized for performance, there may be slight <strong>CPU performance improvements</strong> in operations such as object creation, method invocation, and comparison (<code>equals()</code>, <code>hashCode()</code>). This is particularly true when comparing complex DTOs where developers might introduce inefficiencies in manually implemented methods. The uniformity and optimization of Records ensure that these operations are handled consistently and efficiently.</p>
<h3 id="heading-real-world-performance-impact">Real-World Performance Impact</h3>
<p>In practice, the <strong>performance differences</strong> between DTOs and Records will likely be <strong>small</strong> and often <strong>negligible</strong> for most applications. The compact nature of Records might lead to slight performance gains in some scenarios, but the actual impact would only be noticeable in applications with heavy data processing, high throughput, or those running in resource-constrained environments (e.g., mobile or IoT devices).</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>In this tutorial, we've explored the key differences between <strong>DTOs</strong> and <strong>Records</strong>, their respective use cases, and how they align with different programming paradigms like functional programming. While <strong>DTOs</strong> offer flexibility, mutability, and custom behavior, <strong>Records</strong> provide a concise and immutable way to model data, making them ideal for modern Java applications.</p>
<p>The decision to use a <strong>DTO</strong> or a <strong>Record</strong> ultimately depends on your specific requirements:</p>
<ul>
<li><p>If you need <strong>mutability</strong> or want to add custom logic, DTOs are a better fit.</p>
</li>
<li><p>If you prefer a <strong>compact, immutable structure</strong> and are working in Java 16 or later, <strong>Records</strong> offer a cleaner and more efficient option.</p>
</li>
</ul>
<p>Both approaches have their strengths, and understanding when to use each will help you write more efficient and maintainable Java code.</p>
]]></content:encoded></item><item><title><![CDATA[Simplify Your Writing Workflow with Table of Contents Generator]]></title><description><![CDATA[Organizing content for clarity and ease of navigation is essential in the digital age. Whether you're writing a comprehensive article, a well-structured table of contents (TOC) can significantly enhance the readability of your content. TOC Generator ...]]></description><link>https://blog.ashutoshkrris.in/simplify-your-writing-workflow-with-table-of-contents-generator</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/simplify-your-writing-workflow-with-table-of-contents-generator</guid><category><![CDATA[toc-generator]]></category><category><![CDATA[Table of Contents]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sat, 03 Aug 2024 10:55:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722768424987/6b88ff26-d188-4990-a5ec-12f45f30b024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Organizing content for clarity and ease of navigation is essential in the digital age. Whether you're writing a comprehensive article, a well-structured table of contents (TOC) can significantly enhance the readability of your content. <a target="_blank" href="https://toc-generator.ashutoshkrris.in/">TOC Generator</a> makes generating TOCs effortless, helping you focus on content creation rather than formatting. This article will explain how this tool can assist you and guide you through the process.</p>
<h2 id="heading-why-use-a-table-of-contents"><strong>Why Use a Table of Contents?</strong></h2>
<ul>
<li><p><strong>Enhanced Navigation:</strong> TOCs allow readers to quickly jump to sections of interest.</p>
</li>
<li><p><strong>Improved Readability:</strong> A clear structure helps understand the document's flow.</p>
</li>
<li><p><strong>Better SEO:</strong> Well-organized content is more likely to rank higher in search engines.</p>
</li>
</ul>
<h2 id="heading-key-features-of-the-application"><strong>Key Features of the Application</strong></h2>
<ul>
<li><p><strong>Supports freeCodeCamp Draft Posts:</strong> Easily generate TOCs for your drafts using the platform's unique URL.</p>
</li>
<li><p><strong>Markdown Support:</strong> Quickly convert your Markdown headers into a clickable TOC.</p>
</li>
<li><p><strong>User-Friendly Interface:</strong> Simple and intuitive design for a seamless experience.</p>
</li>
</ul>
<p>Here's a demo of the application:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/P5_nhLBcgEk">https://youtu.be/P5_nhLBcgEk</a></div>
<p> </p>
<h2 id="heading-how-to-use-the-toc-generator-for-freecodecamp"><strong>How to Use the TOC Generator for freeCodeCamp</strong></h2>
<ol>
<li><p><strong>Access the Application</strong></p>
<ul>
<li>Visit the <a target="_blank" href="https://toc-generator.ashutoshkrris.in/">TOC Generator</a> website.</li>
</ul>
</li>
<li><p><strong>Select the Level</strong></p>
<ul>
<li>Choose the "Single Level" or "Multi-Level" as per your choice.</li>
</ul>
</li>
<li><p><strong>Enter the Preview URL</strong></p>
<ul>
<li><p>Input your Hashnode Preview URL. The placeholder will show an example URL format for guidance: <a target="_blank" href="https://preview.freecodecamp.org/66bf202fb513336e7843a932"><code>https://preview.freecodecamp.org/66bf202fb513336e7843a932</code></a>.<br />  Here's how you can get the preview URL:</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723871746006/f1e83701-752a-47d3-a652-3207491c414c.gif" alt="Hashnode Preview URL" class="image--center mx-auto" /></p>
</li>
</ul>
</li>
<li><p><strong>Generate TOC</strong></p>
<ul>
<li>Click the "Generate TOC" button to create a structured TOC.</li>
</ul>
</li>
</ol>
<p>You can copy the generated TOC and paste it into your article wherever you want. Hashnode will automatically convert the Markdown to proper links.</p>
<p>Sample TOC with Single Level Headings:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1723871529484/696684fb-63df-4fca-9f37-61a1cb656271.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-how-to-use-the-toc-generator-for-markdown"><strong>How to Use the TOC Generator for Markdown</strong></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1722768509639/38ca5b0e-dde3-42ca-9b1d-527a897504f6.png" alt class="image--center mx-auto" /></p>
<ol>
<li><p><strong>Access the Markdown TOC Generator</strong></p>
<ul>
<li>Visit our <a target="_blank" href="https://toc-generator.ashutoshkrris.in/markdown">Markdown TOC Generator</a> page.</li>
</ul>
</li>
<li><p><strong>Enter Your Markdown Content</strong></p>
<ul>
<li>Paste or type your Markdown content into the provided textbox.</li>
</ul>
</li>
<li><p><strong>Generate TOC</strong></p>
<ul>
<li>Click "Generate TOC" to automatically generate the TOC based on your headers.</li>
</ul>
</li>
<li><p><strong>Copy the TOC</strong></p>
<ul>
<li>Use the "Copy" button to copy the TOC to your clipboard.</li>
</ul>
</li>
</ol>
<h2 id="heading-benefits-of-using-our-application"><strong>Benefits of Using Our Application</strong></h2>
<ul>
<li><p><strong>Time-Saving:</strong> Quickly generate TOCs without manual formatting.</p>
</li>
<li><p><strong>Consistency:</strong> Ensure your TOC is always formatted correctly.</p>
</li>
<li><p><strong>Versatility:</strong> Suitable for various platforms and content types.</p>
</li>
</ul>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>My Table of Contents Generator is designed to streamline the process of organizing your content, making it easier for your readers to navigate and understand. Whether you're a freeCodeCamp contributor or a Markdown enthusiast, this tool can enhance your workflow and improve the presentation of your work. Try it out today and see how it can simplify your content creation process!</p>
]]></content:encoded></item><item><title><![CDATA[Comparable vs Comparator Explained in Java]]></title><description><![CDATA[Sorting is a fundamental operation in programming, essential for organizing data in a specific order. In Java, built-in sorting methods provide efficient ways to sort primitive data types and arrays, making it easy to manage and manipulate collection...]]></description><link>https://blog.ashutoshkrris.in/comparable-vs-comparator-explained-in-java</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/comparable-vs-comparator-explained-in-java</guid><category><![CDATA[Java]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[coding]]></category><category><![CDATA[interview]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sat, 20 Jul 2024 20:01:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1721505697717/cf92ee5b-1fd8-4a01-aff1-780ce13dbc23.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Sorting is a fundamental operation in programming, essential for organizing data in a specific order. In Java, built-in sorting methods provide efficient ways to sort primitive data types and arrays, making it easy to manage and manipulate collections of data. For instance, you can quickly sort an array of integers or a list of strings using methods like <code>Arrays.sort()</code> and <code>Collections.sort()</code>.</p>
<p>However, when it comes to sorting custom objects, such as instances of user-defined classes, the built-in sorting methods fall short. These methods don't know how to order objects based on custom criteria. This is where Java's <code>Comparable</code> and <code>Comparator</code> interfaces come into play, allowing developers to define and implement custom sorting logic tailored to specific requirements.</p>
<p>In this blog post, we'll explore how to use the <code>Comparable</code> and <code>Comparator</code> interfaces to sort custom objects in Java. I'll provide examples to illustrate the differences and use cases for each approach, helping you master custom sorting in your Java applications.</p>
<h2 id="heading-sorting-methods-for-primitive-types">Sorting Methods for Primitive Types</h2>
<p>Java provides a variety of built-in sorting methods that make it easy to sort primitive data types. These methods are highly optimized and efficient, allowing you to sort arrays and collections with minimal code. For primitive types, such as integers, floating-point numbers, and characters, the <code>Arrays.sort()</code> method is commonly used.</p>
<h3 id="heading-arrayssort">Arrays.sort()</h3>
<p>The <code>Arrays.sort()</code> method sorts the specified array into ascending numerical order. This method uses a Dual-Pivot Quicksort algorithm, which is faster and more efficient for most data sets.</p>
<p>Let's look at an example of sorting an array of integers and characters using <code>Arrays.sort()</code>:</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial;

<span class="hljs-keyword">import</span> java.util.Arrays;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PrimitiveSorting</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        <span class="hljs-keyword">int</span>[] numbers = { <span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">8</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span> };
        System.out.println(<span class="hljs-string">"Original array: "</span> + Arrays.toString(numbers));

        Arrays.sort(numbers);
        System.out.println(<span class="hljs-string">"Sorted array: "</span> + Arrays.toString(numbers));

        <span class="hljs-keyword">char</span>[] characters = { <span class="hljs-string">'o'</span>, <span class="hljs-string">'i'</span>, <span class="hljs-string">'e'</span>, <span class="hljs-string">'u'</span>, <span class="hljs-string">'a'</span> };
        System.out.println(<span class="hljs-string">"Original array: "</span> + Arrays.toString(characters));

        Arrays.sort(characters);
        System.out.println(<span class="hljs-string">"Sorted array: "</span> + Arrays.toString(characters));
    }
}
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Original array: [5, 3, 8, 2, 1]
Sorted array: [1, 2, 3, 5, 8]
Original array: [o, i, e, u, a]
Sorted array: [a, e, i, o, u]
</code></pre>
<h3 id="heading-collectionssort">Collections.sort()</h3>
<p>The <code>Collections.sort()</code> method is used to sort collections such as <code>ArrayList</code>. This method is also based on the natural ordering of the elements or a custom comparator.</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial;

<span class="hljs-keyword">import</span> java.util.ArrayList;
<span class="hljs-keyword">import</span> java.util.Collections;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CollectionsSorting</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        ArrayList&lt;String&gt; wordsList = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();
        wordsList.add(<span class="hljs-string">"banana"</span>);
        wordsList.add(<span class="hljs-string">"apple"</span>);
        wordsList.add(<span class="hljs-string">"cherry"</span>);
        wordsList.add(<span class="hljs-string">"date"</span>);
        System.out.println(<span class="hljs-string">"Original list: "</span> + wordsList);

        Collections.sort(wordsList);
        System.out.println(<span class="hljs-string">"Sorted list: "</span> + wordsList);
    }
}
</code></pre>
<p>Output:</p>
<pre><code class="lang-plaintext">Original list: [banana, apple, cherry, date]
Sorted list: [apple, banana, cherry, date]
</code></pre>
<h3 id="heading-limitations-with-custom-classes">Limitations with Custom Classes</h3>
<p>While Java's built-in sorting methods, such as <code>Arrays.sort()</code> and <code>Collections.sort()</code>, are powerful and efficient for sorting primitive types and objects with natural ordering (like <code>String</code>), they fall short when it comes to sorting custom objects. These methods do not inherently know how to order user-defined objects because there is no natural way for them to compare these objects.</p>
<p>For example, consider a simple <code>Person</code> class that has <code>name</code>, <code>age</code>, and <code>weight</code> attributes:</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
    String name;
    <span class="hljs-keyword">int</span> age;
    <span class="hljs-keyword">double</span> weight;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age, <span class="hljs-keyword">double</span> weight)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.age = age;
        <span class="hljs-keyword">this</span>.weight = weight;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Person [name="</span> + name + <span class="hljs-string">", age="</span> + age + <span class="hljs-string">", weight="</span> + weight + <span class="hljs-string">" kgs]"</span>;
    }
}
</code></pre>
<p>If we try to sort a list of <code>Person</code> objects using <code>Arrays.sort()</code> or <code>Collections.sort()</code>, we will encounter a compilation error because these methods do not know how to compare <code>Person</code> objects:</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial;

<span class="hljs-keyword">import</span> java.util.ArrayList;
<span class="hljs-keyword">import</span> java.util.Arrays;
<span class="hljs-keyword">import</span> java.util.Collections;
<span class="hljs-keyword">import</span> java.util.List;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CustomClassSorting</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        List&lt;Person&gt; people = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;(Arrays.asList(
                <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Alice"</span>, <span class="hljs-number">30</span>, <span class="hljs-number">65.5</span>),
                <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Bob"</span>, <span class="hljs-number">25</span>, <span class="hljs-number">75.0</span>),
                <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Charlie"</span>, <span class="hljs-number">35</span>, <span class="hljs-number">80.0</span>)
        ));
        System.out.println(<span class="hljs-string">"Original people list: "</span> + people);

        Collections.sort(people);
        System.out.println(<span class="hljs-string">"Sorted people list: "</span> + people);
    }
}
</code></pre>
<p>Compilation Error:</p>
<pre><code class="lang-bash">java: no suitable method found <span class="hljs-keyword">for</span> sort(java.util.List&lt;tutorial.Person&gt;)
    method java.util.Collections.&lt;T&gt;sort(java.util.List&lt;T&gt;) is not applicable
      (inference variable T has incompatible bounds
        equality constraints: tutorial.Person
        lower bounds: java.lang.Comparable&lt;? super T&gt;)
    method java.util.Collections.&lt;T&gt;sort(java.util.List&lt;T&gt;,java.util.Comparator&lt;? super T&gt;) is not applicable
      (cannot infer type-variable(s) T
        (actual and formal argument lists differ <span class="hljs-keyword">in</span> length))
</code></pre>
<p>The error occurs because the <code>Person</code> class does not implement the <code>Comparable</code> interface, and there is no way for the sorting method to know how to compare two <code>Person</code> objects.</p>
<p>To sort custom objects like <code>Person</code>, we need to provide a way to compare these objects. Java offers two main approaches to achieve this:</p>
<ol>
<li><p>Implementing the <code>Comparable</code> Interface: This allows a class to define its natural ordering by implementing the <code>compareTo</code> method.</p>
</li>
<li><p>Using the <code>Comparator</code> Interface: This allows us to create separate classes or lambda expressions to define multiple ways of comparing objects.</p>
</li>
</ol>
<p>We will explore both approaches in the upcoming sections, starting with the <code>Comparable</code> interface.</p>
<h2 id="heading-comparable-interface">Comparable Interface</h2>
<p>Java provides a <code>Comparable</code> interface to define a natural ordering for objects of a user-defined class. By implementing the <code>Comparable</code> interface, a class can provide a single natural ordering that can be used to sort its instances. This is particularly useful when you need a default way to compare and sort objects.</p>
<h3 id="heading-overview">Overview</h3>
<p>The <code>Comparable</code> interface contains a single method, <code>compareTo()</code>, which compares the current object with the specified object for order. The method returns:</p>
<ul>
<li><p>A negative integer if the current object is less than the specified object.</p>
</li>
<li><p>Zero if the current object is equal to the specified object.</p>
</li>
<li><p>A positive integer if the current object is greater than the specified object.</p>
</li>
</ul>
<h3 id="heading-how-comparable-allows-for-a-single-natural-ordering-of-objects">How Comparable Allows for a Single Natural Ordering of Objects</h3>
<p>By implementing the <code>Comparable</code> interface, a class can ensure that its objects have a natural ordering. This allows the objects to be sorted using methods like <code>Arrays.sort()</code> or <code>Collections.sort()</code> without the need for a separate comparator.</p>
<p>Let's implement the <code>Comparable</code> interface in a new <code>PersonV2</code> class, comparing by age.</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PersonV2</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Comparable</span>&lt;<span class="hljs-title">PersonV2</span>&gt; </span>{
    String name;
    <span class="hljs-keyword">int</span> age;
    <span class="hljs-keyword">double</span> weight;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">PersonV2</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age, <span class="hljs-keyword">double</span> weight)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.age = age;
        <span class="hljs-keyword">this</span>.weight = weight;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"PersonV2 [name="</span> + name + <span class="hljs-string">", age="</span> + age + <span class="hljs-string">", weight="</span> + weight + <span class="hljs-string">" kgs]"</span>;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">compareTo</span><span class="hljs-params">(PersonV2 other)</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.age - other.age;
    }
}
</code></pre>
<p>In this implementation, the <code>compareTo()</code> method compares the <code>age</code> attribute of the current <code>PersonV2</code> object with the <code>age</code> attribute of the specified <code>PersonV2</code> object by subtracting one age from the other. By using the expression <code>this.age - other.age</code>, we’re effectively implementing this logic as follows:</p>
<ul>
<li><p>If <code>this.age</code> is less than <code>other.age</code>, the result will be negative.</p>
</li>
<li><p>If <code>this.age</code> is equal to <code>other.age</code>, the result will be zero.</p>
</li>
<li><p>If <code>this.age</code> is greater than <code>other.age</code>, the result will be positive.</p>
</li>
</ul>
<blockquote>
<p>Note: We can also use <code>Integer.compare(this.age, other.age)</code> instead of performing the arithmetic operation manually.</p>
</blockquote>
<p>Now that the <code>PersonV2</code> class implements the <code>Comparable</code> interface, we can sort a list of <code>PersonV2</code> objects using <code>Collections.sort()</code>:</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial;

<span class="hljs-keyword">import</span> java.util.ArrayList;
<span class="hljs-keyword">import</span> java.util.Arrays;
<span class="hljs-keyword">import</span> java.util.Collections;
<span class="hljs-keyword">import</span> java.util.List;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CustomClassSortingV2</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        List&lt;PersonV2&gt; people = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;(Arrays.asList(
                <span class="hljs-keyword">new</span> PersonV2(<span class="hljs-string">"Alice"</span>, <span class="hljs-number">30</span>, <span class="hljs-number">65.5</span>),
                <span class="hljs-keyword">new</span> PersonV2(<span class="hljs-string">"Bob"</span>, <span class="hljs-number">25</span>, <span class="hljs-number">75.0</span>),
                <span class="hljs-keyword">new</span> PersonV2(<span class="hljs-string">"Charlie"</span>, <span class="hljs-number">35</span>, <span class="hljs-number">80.0</span>)
        ));
        System.out.println(<span class="hljs-string">"Original people list: "</span> + people);

        Collections.sort(people);
        System.out.println(<span class="hljs-string">"Sorted people list: "</span> + people);
    }
}
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Original people list: [PersonV2 [name=Alice, age=30, weight=65.5 kgs], PersonV2 [name=Bob, age=25, weight=75.0 kgs], PersonV2 [name=Charlie, age=35, weight=80.0 kgs]]
Sorted people list: [PersonV2 [name=Bob, age=25, weight=75.0 kgs], PersonV2 [name=Alice, age=30, weight=65.5 kgs], PersonV2 [name=Charlie, age=35, weight=80.0 kgs]]
</code></pre>
<p>In this example, the <code>PersonV2</code> objects are sorted in ascending order of age using the <code>Collections.sort()</code> method, which relies on the natural ordering defined by the <code>compareTo()</code> method in the <code>PersonV2</code> class.</p>
<h3 id="heading-limitations-of-comparable">Limitations of Comparable</h3>
<p>While the <code>Comparable</code> interface provides a way to define a natural ordering for objects, it has several limitations that can restrict its use in practical applications. Understanding these limitations can help us determine when to use other mechanisms, such as the <code>Comparator</code> interface, to achieve more flexible sorting.</p>
<ul>
<li><p><strong>Single Natural Ordering</strong>: The primary limitation of <code>Comparable</code> is that it allows only one natural ordering for the objects of a class. When you implement <code>Comparable</code>, you define a single way to compare objects, which is used whenever the objects are sorted or compared. This can be restrictive if you need to sort objects in multiple ways.</p>
</li>
<li><p><strong>Inflexibility</strong>: If you need to sort objects by different attributes or in different orders, you will have to modify the class or create new implementations of <code>Comparable</code>. This inflexibility can lead to a proliferation of comparison methods and can make the code harder to maintain.</p>
</li>
<li><p><strong>Non-Adaptable</strong>: Once a class implements <code>Comparable</code>, the natural ordering is fixed and cannot be easily changed. For instance, if your <code>PersonV2</code> class initially sorts by age but later you need to sort by weight or name, you have to either change the <code>compareTo()</code> method or create a new version of the class.</p>
</li>
</ul>
<p>This is where the <code>Comparator</code> interface comes into play. To define multiple ways of comparing objects, we can use the <code>Comparator</code> interface, which we will explore in the next section.</p>
<h2 id="heading-comparator-interface">Comparator Interface</h2>
<p>The <code>Comparator</code> interface in Java provides a way to define multiple ways to compare and sort objects. Unlike the <code>Comparable</code> interface, which allows only a single natural ordering, <code>Comparator</code> is designed to offer flexibility by allowing multiple sorting strategies. This makes it particularly useful for scenarios where objects need to be sorted in different ways.</p>
<h3 id="heading-overview-1">Overview</h3>
<p>The <code>Comparator</code> interface defines a single method, <code>compare()</code>, which compares two objects and returns:</p>
<ul>
<li><p>A negative integer if the first object is less than the second object.</p>
</li>
<li><p>Zero if the first object is equal to the second object.</p>
</li>
<li><p>A positive integer if the first object is greater than the second object.</p>
</li>
</ul>
<p>This method provides a way to define custom ordering for objects without modifying the class itself.</p>
<h3 id="heading-how-comparator-allows-for-multiple-ways-of-ordering-objects">How Comparator Allows for Multiple Ways of Ordering Objects</h3>
<p>The <code>Comparator</code> interface allows you to create multiple <code>Comparator</code> instances, each defining a different ordering for objects. This flexibility means you can sort objects by various attributes or in different orders without altering the object's class.</p>
<p>Let's implement multiple <code>Comparator</code> instances for the <code>Person</code> class. We'll define comparators for sorting by name, by age, and by weight. First, we need to update the <code>Person</code> class to include getters and ensure that attributes are accessible.</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
    String name;
    <span class="hljs-keyword">int</span> age;
    <span class="hljs-keyword">double</span> weight;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age, <span class="hljs-keyword">double</span> weight)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.age = age;
        <span class="hljs-keyword">this</span>.weight = weight;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> name;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getAge</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> age;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">getWeight</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> weight;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Person [name="</span> + name + <span class="hljs-string">", age="</span> + age + <span class="hljs-string">", weight="</span> + weight + <span class="hljs-string">" kgs]"</span>;
    }
}
</code></pre>
<h4 id="heading-comparator-by-name"><strong>Comparator by Name</strong></h4>
<p>This comparator sorts <code>Person</code> objects alphabetically by their <code>name</code>.</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial.comparator;

<span class="hljs-keyword">import</span> tutorial.Person;

<span class="hljs-keyword">import</span> java.util.Comparator;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PersonNameComparator</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Comparator</span>&lt;<span class="hljs-title">Person</span>&gt; </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">compare</span><span class="hljs-params">(Person p1, Person p2)</span> </span>{
        <span class="hljs-keyword">return</span> p1.getName().compareTo(p2.getName());
    }
}
</code></pre>
<h4 id="heading-comparator-by-age">Comparator by Age</h4>
<p>This comparator sorts <code>Person</code> objects by their <code>age</code>, in ascending order.</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial.comparator;

<span class="hljs-keyword">import</span> tutorial.Person;

<span class="hljs-keyword">import</span> java.util.Comparator;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PersonAgeComparator</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Comparator</span>&lt;<span class="hljs-title">Person</span>&gt; </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">compare</span><span class="hljs-params">(Person p1, Person p2)</span> </span>{
        <span class="hljs-keyword">return</span> p1.getAge() - p2.getAge();
    }
}
</code></pre>
<h4 id="heading-comparator-by-weight">Comparator by Weight</h4>
<p>This comparator sorts <code>Person</code> objects by their <code>weight</code>, in ascending order.</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial.comparator;

<span class="hljs-keyword">import</span> tutorial.Person;

<span class="hljs-keyword">import</span> java.util.Comparator;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PersonWeightComparator</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Comparator</span>&lt;<span class="hljs-title">Person</span>&gt; </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">compare</span><span class="hljs-params">(Person p1, Person p2)</span> </span>{
        <span class="hljs-keyword">return</span> (<span class="hljs-keyword">int</span>) (p1.getWeight() - p2.getWeight());
    }
}
</code></pre>
<p>Now, here’s how you can use these <code>Comparator</code> instances to sort a list of <code>Person</code> objects:</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> tutorial;

<span class="hljs-keyword">import</span> tutorial.comparator.PersonAgeComparator;
<span class="hljs-keyword">import</span> tutorial.comparator.PersonNameComparator;
<span class="hljs-keyword">import</span> tutorial.comparator.PersonWeightComparator;

<span class="hljs-keyword">import</span> java.util.ArrayList;
<span class="hljs-keyword">import</span> java.util.Arrays;
<span class="hljs-keyword">import</span> java.util.Collections;
<span class="hljs-keyword">import</span> java.util.List;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CustomClassSortingV3</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        List&lt;Person&gt; people = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;(Arrays.asList(
                <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Alice"</span>, <span class="hljs-number">30</span>, <span class="hljs-number">65.5</span>),
                <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Bob"</span>, <span class="hljs-number">25</span>, <span class="hljs-number">75.0</span>),
                <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Charlie"</span>, <span class="hljs-number">35</span>, <span class="hljs-number">80.0</span>)
        ));
        System.out.println(<span class="hljs-string">"Original people list: "</span> + people);

        Collections.sort(people, <span class="hljs-keyword">new</span> PersonNameComparator());
        System.out.println(<span class="hljs-string">"Sorted people list by name: "</span> + people);

        Collections.sort(people, <span class="hljs-keyword">new</span> PersonAgeComparator());
        System.out.println(<span class="hljs-string">"Sorted people list by age: "</span> + people);

        Collections.sort(people, <span class="hljs-keyword">new</span> PersonWeightComparator());
        System.out.println(<span class="hljs-string">"Sorted people list by weight: "</span> + people);
    }
}
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Original people list: [Person [name=Alice, age=30, weight=65.5 kgs], Person [name=Bob, age=25, weight=75.0 kgs], Person [name=Charlie, age=35, weight=80.0 kgs]]
Sorted people list by name: [Person [name=Alice, age=30, weight=65.5 kgs], Person [name=Bob, age=25, weight=75.0 kgs], Person [name=Charlie, age=35, weight=80.0 kgs]]
Sorted people list by age: [Person [name=Bob, age=25, weight=75.0 kgs], Person [name=Alice, age=30, weight=65.5 kgs], Person [name=Charlie, age=35, weight=80.0 kgs]]
Sorted people list by weight: [Person [name=Alice, age=30, weight=65.5 kgs], Person [name=Bob, age=25, weight=75.0 kgs], Person [name=Charlie, age=35, weight=80.0 kgs]]
</code></pre>
<p>In this example, the <code>Comparator</code> instances allow sorting the <code>Person</code> objects by different attributes: name, age, and weight. This demonstrates how the <code>Comparator</code> interface enables flexible and versatile sorting strategies for a class.</p>
<h2 id="heading-comparable-vs-comparator">Comparable vs Comparator</h2>
<p>When sorting objects in Java, you have two primary options: the <code>Comparable</code> and <code>Comparator</code> interfaces. Understanding the differences between these two interfaces can help you choose the right approach for your needs. Please note that this is also a <strong>very important interview question</strong>.</p>
<h3 id="heading-comparison">Comparison</h3>
<p>Here’s a table comparing and contrasting the <code>Comparable</code> and <code>Comparator</code> interfaces in Java:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>Comparable</td><td>Comparator</td></tr>
</thead>
<tbody>
<tr>
<td>Definition</td><td>Provides a single, natural ordering for objects</td><td>Provides multiple ways to compare objects</td></tr>
<tr>
<td>Method</td><td>compareTo(T o)</td><td>compare(T o1, T o2)</td></tr>
<tr>
<td>Implementation</td><td>Implemented within the class itself</td><td>Implemented outside the class</td></tr>
<tr>
<td>Sorting Criteria</td><td>One default natural ordering</td><td>Multiple sorting criteria</td></tr>
<tr>
<td>Flexibility</td><td>Limited to one way of comparing objects</td><td>Flexible; multiple comparators can be defined</td></tr>
<tr>
<td>Class Modification</td><td>Requires modifying the class to implement <code>Comparable</code></td><td>Does not require modifying the class</td></tr>
<tr>
<td>Use Case</td><td>Use when there is a clear, natural ordering (e.g., sorting employees by ID)</td><td>Use when different sorting orders are needed or when you cannot modify the class</td></tr>
</tbody>
</table>
</div><h3 id="heading-benefits-and-drawbacks-of-each-approach">Benefits and Drawbacks of Each Approach</h3>
<h4 id="heading-comparable"><strong>Comparable</strong></h4>
<ul>
<li><p><strong>Benefits</strong>:</p>
<ul>
<li><p><strong>Simplicity</strong>: Provides a default sorting order that is easy to implement and use.</p>
</li>
<li><p><strong>Built-in</strong>: The natural ordering is part of the class itself, so it is always available and used by default in sorting methods.</p>
</li>
</ul>
</li>
<li><p><strong>Drawbacks</strong>:</p>
<ul>
<li><p><strong>Single Ordering</strong>: Can only define one way to compare objects. If different sorting orders are needed, the class must be modified or additional <code>Comparator</code> instances must be used.</p>
</li>
<li><p><strong>Class Modification</strong>: Requires altering the class to implement <code>Comparable</code>, which might not be feasible if the class is part of a library or if its natural ordering is not clear.</p>
</li>
</ul>
</li>
</ul>
<h4 id="heading-comparator"><strong>Comparator</strong></h4>
<ul>
<li><p><strong>Benefits</strong>:</p>
<ul>
<li><p><strong>Flexibility</strong>: Allows for multiple sorting orders and criteria, which can be defined externally and used as needed.</p>
</li>
<li><p><strong>Non-invasive</strong>: Does not require modification of the class itself, making it suitable for classes you do not control or when you need different sorting options.</p>
</li>
</ul>
</li>
<li><p><strong>Drawbacks</strong>:</p>
<ul>
<li><p><strong>Complexity</strong>: Requires creating and managing multiple <code>Comparator</code> instances, which can add complexity to the code.</p>
</li>
<li><p><strong>Overhead</strong>: Might introduce additional overhead if many comparators are used, especially if they are created on the fly.</p>
</li>
</ul>
</li>
</ul>
<p>In summary, <code>Comparable</code> is best used when a class has a natural ordering that makes sense for most use cases. <code>Comparator</code>, on the other hand, provides flexibility for sorting by multiple criteria and is useful when the class does not have a natural ordering or when different sorting orders are needed. Choosing between <code>Comparable</code> and <code>Comparator</code> depends on your specific sorting needs and whether you need a single default order or multiple flexible sorting options.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Understanding and utilizing both <code>Comparable</code> and <code>Comparator</code> can significantly enhance your ability to manage and manipulate object collections in Java. By applying these concepts, you can create more flexible and powerful sorting mechanisms.</p>
<p>To solidify your understanding, try implementing both <code>Comparable</code> and <code>Comparator</code> in real-world scenarios. Experiment with different classes and sorting criteria to see how each approach works in practice.</p>
<p><strong>Links to Official Java Documentation</strong>:</p>
<ul>
<li><p><a target="_blank" href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html">Java Comparable Interface</a></p>
</li>
<li><p><a target="_blank" href="https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html">Java Comparator Interface</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Implementing Instant Search with Flask and HTMX]]></title><description><![CDATA[Introduction
Instant search is a feature that shows search results as users type their query. Instead of waiting for a full page to reload or submitting a form, results appear instantly, allowing users to find what they are looking for more quickly. ...]]></description><link>https://blog.ashutoshkrris.in/implementing-instant-search-with-flask-and-htmx</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/implementing-instant-search-with-flask-and-htmx</guid><category><![CDATA[Python]]></category><category><![CDATA[Flask Framework]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[htmx]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[beginner]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[projects]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Thu, 18 Jul 2024 17:38:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1721324236154/48518f00-c61e-4723-bcc9-e81533e14e9c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Instant search is a feature that shows search results as users type their query. Instead of waiting for a full page to reload or submitting a form, results appear instantly, allowing users to find what they are looking for more quickly. For example, when you start typing in a search box, suggestions or matching items will appear immediately, making the process smoother and more efficient.</p>
<p>In this tutorial, we will learn how to create a simple instant search feature using Flask and HTMX. This will help you build interactive web applications with a better user experience.</p>
<h3 id="heading-why-use-instant-search"><strong>Why Use Instant Search?</strong></h3>
<ul>
<li><p><strong>Speed</strong>: Users get immediate feedback, which helps them refine their search.</p>
</li>
<li><p><strong>Convenience</strong>: It reduces the number of clicks and page loads, leading to a more seamless experience.</p>
</li>
<li><p><strong>Engagement</strong>: Users are more likely to stay on your site if they can find what they need easily.</p>
</li>
</ul>
<h3 id="heading-technologies-used"><strong>Technologies Used</strong></h3>
<p>To implement this instant search feature, we will use two main technologies:</p>
<ul>
<li><p><strong>Flask</strong>: <a target="_blank" href="https://blog.ashutoshkrris.in/getting-started-with-flask">Flask</a> is a popular web framework for Python. It is simple and lightweight, making it easy to set up and start building web applications quickly. Flask allows us to create routes, handle requests, and serve HTML templates with minimal setup.</p>
</li>
<li><p><strong>HTMX</strong>: This is a powerful JavaScript library that allows us to create dynamic web pages without having to write a lot of JavaScript code. With HTMX, we can update parts of a page based on user actions, like typing in a search box. It makes it easy to load data from the server and display it on the page without a full reload.</p>
</li>
</ul>
<h2 id="heading-setting-up-the-environment">Setting Up the Environment</h2>
<p>In this section, we will set up the environment for our Flask project, including installing the necessary packages and organizing the project structure.</p>
<h4 id="heading-1-installing-flask-and-htmx">1. Installing Flask and HTMX</h4>
<p>First, you need to install Flask, Flask-SQLAlchemy, and Flask-Migrate. You can do this using pip. Open your terminal and run:</p>
<pre><code class="lang-bash">pip install Flask Flask-SQLAlchemy Flask-Migrate
</code></pre>
<p>For HTMX, we will include it in our HTML template directly from a CDN.</p>
<h4 id="heading-2-creating-a-virtual-environment">2. Creating a Virtual Environment</h4>
<p>It's a good practice to create a virtual environment for your projects to manage dependencies. Here's how to create one:</p>
<pre><code class="lang-bash">python -m venv venv
</code></pre>
<p>Next, activate the environment:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># On Windows</span>
venv\Scripts\activate

<span class="hljs-comment"># On macOS/Linux</span>
<span class="hljs-built_in">source</span> venv/bin/activate
</code></pre>
<h4 id="heading-3-setting-up-the-project-structure">3. Setting Up the Project Structure</h4>
<p>Now, set up your project structure as follows:</p>
<pre><code class="lang-bash">my_flask_app/
├── core/
│   ├── __init__.py
│   ├── models.py
│   └── routes.py
├── config.py
└── main.py
</code></pre>
<p>Let us start with creating the first file - <code>core/__init__.py</code>. This file is the initialization script for the core module of our Flask application. It sets up the Flask app instance and configures it using the settings from the <code>DevelopmentConfig</code> class, and initialize the database and migration system.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask
<span class="hljs-keyword">from</span> flask_sqlalchemy <span class="hljs-keyword">import</span> SQLAlchemy
<span class="hljs-keyword">from</span> flask_migrate <span class="hljs-keyword">import</span> Migrate
<span class="hljs-keyword">from</span> config <span class="hljs-keyword">import</span> DevelopmentConfig

<span class="hljs-comment"># Create the Flask app instance</span>
app = Flask(__name__)

<span class="hljs-comment"># Load configuration from DevelopmentConfig</span>
app.config.from_object(DevelopmentConfig)

<span class="hljs-comment"># Initialize SQLAlchemy with the app instance</span>
db = SQLAlchemy(app)

<span class="hljs-comment"># Initialize Flask-Migrate with the app instance and database</span>
migrate = Migrate(app, db)

<span class="hljs-comment"># Import routes to register them with the app</span>
<span class="hljs-keyword">from</span> core <span class="hljs-keyword">import</span> routes
</code></pre>
<p>Next, we will create the <code>config.py</code> file from where we imported the <code>DevelopmentConfig</code> class. This file contains configuration settings for different environments (development, testing, production). These settings help manage different behaviors and configurations based on where your app is running.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Config</span>(<span class="hljs-params">object</span>):</span>
    DEBUG = <span class="hljs-literal">False</span>
    TESTING = <span class="hljs-literal">False</span>
    CSRF_ENABLED = <span class="hljs-literal">True</span>
    SECRET_KEY = <span class="hljs-string">"guess-me"</span>
    SQLALCHEMY_DATABASE_URI = <span class="hljs-string">"sqlite:///db.sqlite"</span>
    SQLALCHEMY_TRACK_MODIFICATIONS = <span class="hljs-literal">False</span>
    BCRYPT_LOG_ROUNDS = <span class="hljs-number">13</span>
    WTF_CSRF_ENABLED = <span class="hljs-literal">True</span>
    DEBUG_TB_ENABLED = <span class="hljs-literal">False</span>
    DEBUG_TB_INTERCEPT_REDIRECTS = <span class="hljs-literal">False</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DevelopmentConfig</span>(<span class="hljs-params">Config</span>):</span>
    DEVELOPMENT = <span class="hljs-literal">True</span>
    DEBUG = <span class="hljs-literal">True</span>
    WTF_CSRF_ENABLED = <span class="hljs-literal">False</span>
    DEBUG_TB_ENABLED = <span class="hljs-literal">True</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TestingConfig</span>(<span class="hljs-params">Config</span>):</span>
    TESTING = <span class="hljs-literal">True</span>
    DEBUG = <span class="hljs-literal">True</span>
    SQLALCHEMY_DATABASE_URI = <span class="hljs-string">"sqlite:///testdb.sqlite"</span>
    BCRYPT_LOG_ROUNDS = <span class="hljs-number">1</span>
    WTF_CSRF_ENABLED = <span class="hljs-literal">False</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProductionConfig</span>(<span class="hljs-params">Config</span>):</span>
    DEBUG = <span class="hljs-literal">False</span>
    DEBUG_TB_ENABLED = <span class="hljs-literal">False</span>
</code></pre>
<ul>
<li><p><code>Config</code>: The base configuration class with default settings.</p>
</li>
<li><p><code>DevelopmentConfig</code>: Inherits from <code>Config</code> and overrides development settings.</p>
</li>
<li><p><code>TestingConfig</code>: Inherits from <code>Config</code> and overrides settings for testing.</p>
</li>
<li><p><code>ProductionConfig</code>: Inherits from <code>Config</code> and overrides production settings.</p>
</li>
</ul>
<p>Finally, we will create the <code>main.py</code> file. This is the entry point of our application. When we run this file, it starts the Flask web server.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> core <span class="hljs-keyword">import</span> app

<span class="hljs-comment"># Start the Flask app</span>
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    app.run(debug=<span class="hljs-literal">True</span>)
</code></pre>
<ul>
<li><p><code>if __name__ == '__main__'</code>: This ensures the Flask app runs only if the script is executed directly (not imported as a module).</p>
</li>
<li><p><code>app.run(debug=True)</code>: Starts the Flask development server with debug mode enabled, which provides detailed error messages and auto-reloading.</p>
</li>
</ul>
<p>Now that you understand the project files, we can proceed with implementing the instant search functionality. This will involve creating the models and search route, setting up the HTMX-powered front-end, and connecting everything to fetch and display search results dynamically.</p>
<h2 id="heading-setting-up-the-database">Setting up the Database</h2>
<p>In this section, we will set up the database for our Flask application. We will use SQLite for simplicity. We will create a model for the data we want to search and seed the database with sample data.</p>
<p>SQLite is a lightweight, disk-based database that doesn’t require a separate server process. It's an excellent choice for development and small projects because it is easy to set up and use.</p>
<h3 id="heading-creating-model-for-the-data-to-be-searched">Creating Model for the Data to Be Searched</h3>
<p>We will create a <code>Book</code> model to represent the data in our database. This model will include fields like the book title and author.</p>
<p>Let's create the <code>core/models.py</code> file and add the model there:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> core <span class="hljs-keyword">import</span> db

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Book</span>(<span class="hljs-params">db.Model</span>):</span>
    id = db.Column(db.Integer, primary_key=<span class="hljs-literal">True</span>)
    title = db.Column(db.String(<span class="hljs-number">100</span>), nullable=<span class="hljs-literal">False</span>)
    author = db.Column(db.String(<span class="hljs-number">100</span>), nullable=<span class="hljs-literal">False</span>)
</code></pre>
<h3 id="heading-applying-migrations-using-flask-migrate">Applying Migrations Using Flask-Migrate</h3>
<p>Before we can seed our database, we need to set up database migrations using Flask-Migrate. This tool helps us manage database changes, such as creating tables and altering schemas, systematically.</p>
<p>Initialize the migrations folder by running the following command in your project directory:</p>
<pre><code class="lang-bash">flask db init
</code></pre>
<p>This command creates a <code>migrations</code> directory in our project, which will store migration scripts.</p>
<p>Generate a migration script that creates the necessary database tables based on your models:</p>
<pre><code class="lang-bash">flask db migrate -m <span class="hljs-string">"Initial migration"</span>
</code></pre>
<p>This command scans your models and generates a new migration script in the <code>migrations</code> folder.</p>
<p>Apply the migration to create the tables in your database:</p>
<pre><code class="lang-bash">flask db upgrade
</code></pre>
<p>This command executes the migration script, creating the tables defined by your models in the database. Post this step, you will see an <code>instance/db.sqlite</code> file created.</p>
<h3 id="heading-seeding-data-into-our-database">Seeding Data Into Our Database</h3>
<p>Now that we have set up the database and applied the migration, we can proceed with seeding the database. Create a file named <code>seeder.py</code> with the following content:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> csv
<span class="hljs-keyword">from</span> sqlalchemy.exc <span class="hljs-keyword">import</span> IntegrityError

<span class="hljs-keyword">from</span> core <span class="hljs-keyword">import</span> db, app
<span class="hljs-keyword">from</span> core.models <span class="hljs-keyword">import</span> Book


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">seed_data</span>():</span>
    <span class="hljs-keyword">with</span> app.app_context():
        <span class="hljs-comment"># Open the CSV file</span>
        <span class="hljs-keyword">with</span> open(<span class="hljs-string">"data.csv"</span>, newline=<span class="hljs-string">''</span>, encoding=<span class="hljs-string">'utf-8'</span>) <span class="hljs-keyword">as</span> csvfile:
            reader = csv.DictReader(csvfile)

            <span class="hljs-comment"># Iterate over the rows in the CSV file</span>
            <span class="hljs-keyword">for</span> row <span class="hljs-keyword">in</span> reader:
                <span class="hljs-comment"># Create a new Book instance</span>
                book = Book(
                    title=row[<span class="hljs-string">'Book Name'</span>],
                    author=row[<span class="hljs-string">'Author Name'</span>]
                )

                <span class="hljs-comment"># Add the book to the session</span>
                db.session.add(book)

            <span class="hljs-keyword">try</span>:
                <span class="hljs-comment"># Commit the session to write the books to the database</span>
                db.session.commit()
                print(<span class="hljs-string">"Books added successfully."</span>)
            <span class="hljs-keyword">except</span> IntegrityError <span class="hljs-keyword">as</span> e:
                db.session.rollback()
                print(<span class="hljs-string">f"Error occurred: <span class="hljs-subst">{e}</span>"</span>)


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    seed_data()
</code></pre>
<p>The seeder script is responsible for populating the database with initial data. This is useful for testing and development purposes, allowing you to work with a set of sample data. This script reads data from <code>data.csv</code>, and processes it to insert it into the database.</p>
<blockquote>
<p>Note: You can download the <a target="_blank" href="https://github.com/ashutoshkrris/instant-search-with-flask-htmx/blob/main/data.csv">data.csv</a> file from here.</p>
</blockquote>
<p>To use this script, ensure your <code>data.csv</code> file exists in the same directory as <a target="_blank" href="http://seeder.py"><code>seeder.py</code></a>. Run the script using Python:</p>
<pre><code class="lang-bash">python seeder.py
</code></pre>
<h2 id="heading-setting-up-basic-routing-and-html">Setting Up Basic Routing and HTML</h2>
<p>In this section, we'll set up a basic route in Flask to serve an index page (<code>index.html</code>) where users can search and display books.</p>
<h3 id="heading-setting-up-flask-route">Setting Up Flask Route</h3>
<p>Let's set up a Flask route (<code>/</code>) to render an <code>index.html</code> template and display books. For that, create a <code>core/routes.py</code> file and add the following route:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> render_template
<span class="hljs-keyword">from</span> core <span class="hljs-keyword">import</span> app
<span class="hljs-keyword">from</span> core.models <span class="hljs-keyword">import</span> Book

<span class="hljs-meta">@app.route('/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">index</span>():</span>
    <span class="hljs-comment"># Fetch the first 20 books to display by default</span>
    books = Book.query.limit(<span class="hljs-number">20</span>).all()
    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"index.html"</span>, books=books)
</code></pre>
<p>The Flask application handles routing through the <code>@app.route('/')</code> decorator, which directs requests to the root URL (<code>/</code>). When a user visits the homepage, the <code>index()</code> function is invoked. Inside this function, we query the <code>Book</code> model using SQLAlchemy to fetch the first 20 books from the database. These books are then passed as a parameter (<code>books</code>) to the <code>render_template</code> function, which renders the <code>index.html</code> template.</p>
<h3 id="heading-creating-the-indexhtml-template">Creating the <code>index.html</code> Template</h3>
<p>Create a file named <code>index.html</code> inside a <code>templates</code> directory in your project. The <code>templates</code> directory will lie in the <code>core</code> package. This file will contain the HTML structure for our book search page.</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Book Search<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"section"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"columns"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"column is-one-third is-offset-one-third"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"input"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Search"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"query"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"table is-fullwidth"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">thead</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>ID<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>Book Title<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>Book Author<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">thead</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"results"</span>&gt;</span>
        {% for book in books %}
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{{ book.id }}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{{ book.title }}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{{ book.author }}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
        {% endfor %}
      <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>This HTML file uses the Bulma CSS framework for styling and includes elements such as an input field for user searches and a table to display book details fetched from the database.</p>
<p>The <code>index.html</code> template utilizes Jinja2 templating to dynamically populate the table rows (<code>&lt;tr&gt;</code>) with book data retrieved from the Flask backend. Each book's ID, title, and author are displayed in the table rows using <code>{{</code><a target="_blank" href="http://book.id"><code>book.id</code></a><code>}}</code>, <code>{{ book.title }}</code>, and <code>{{</code><a target="_blank" href="http://book.author"><code>book.author</code></a><code>}}</code> respectively.</p>
<h3 id="heading-running-the-application">Running the application</h3>
<p>Let's run the application using the following command:</p>
<pre><code class="lang-bash">flask run
</code></pre>
<p>Once your application is up and running, this is how it will look like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1721316465728/d5037fd3-f49b-4c59-993c-4ff7c23cabef.png" alt="Book Search Application Home Page" class="image--center mx-auto" /></p>
<h2 id="heading-adding-htmx-for-instant-search">Adding HTMX for Instant Search</h2>
<p>Finally, we will add HTMX to enhance our Flask application with dynamic search capabilities. For this, we'll introduce a new route and modify existing HTML templates.</p>
<h3 id="heading-creating-the-search-route">Creating the Search Route</h3>
<p>First, create a new route <code>/search</code> in your Flask application to handle book searches based on user input:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> render_template, request
<span class="hljs-keyword">from</span> core <span class="hljs-keyword">import</span> app
<span class="hljs-keyword">from</span> core.models <span class="hljs-keyword">import</span> Book

<span class="hljs-meta">@app.route('/search')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">search</span>():</span>
    query = request.args.get(<span class="hljs-string">"query"</span>)
    <span class="hljs-keyword">if</span> query:
        results = Book.query.filter(Book.title.ilike(<span class="hljs-string">f"%<span class="hljs-subst">{query}</span>%"</span>) | Book.author.ilike(<span class="hljs-string">f"%<span class="hljs-subst">{query}</span>%"</span>)).limit(<span class="hljs-number">10</span>).all()
    <span class="hljs-keyword">else</span>:
        results = Book.query.limit(<span class="hljs-number">20</span>).all()
    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"search_results.html"</span>, results=results)
</code></pre>
<p>This route listens for GET requests to <code>/search</code>. It retrieves the search query from the URL parameter using <code>request.args.get("query")</code>. If a <code>query</code> parameter is present, it uses SQLAlchemy's <code>ilike</code> method to perform a case-insensitive search across the <code>title</code> and <code>author</code> columns of the <code>Book</code> table, fetching up to 10 results. If no query parameter is provided, it defaults to fetching the first 20 books from the database. The results are passed to a new <code>search_results.html</code> template for rendering.</p>
<h3 id="heading-modifying-indexhtml-to-add-htmx">Modifying <code>index.html</code> to add HTMX</h3>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Book Search<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css"</span> /&gt;</span>
  <span class="hljs-comment">&lt;!-- Include HTMX library --&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/htmx.org/dist/htmx.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"section"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"columns"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"column is-one-third is-offset-one-third"</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- HTMX-enabled search input --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
            <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>
            <span class="hljs-attr">class</span>=<span class="hljs-string">"input"</span>
            <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Search"</span>
            <span class="hljs-attr">name</span>=<span class="hljs-string">"query"</span>
            <span class="hljs-attr">hx-get</span>=<span class="hljs-string">"/search"</span>
            <span class="hljs-attr">hx-trigger</span>=<span class="hljs-string">"keyup changed delay:500ms"</span>
            <span class="hljs-attr">hx-target</span>=<span class="hljs-string">"#results"</span>
          /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"table is-fullwidth"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">thead</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>ID<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>Book Title<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">th</span>&gt;</span>Book Author<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">thead</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"results"</span>&gt;</span>
        {% for book in books %}
          <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{{ book.id }}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{{ book.title }}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{{ book.author }}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
        {% endfor %}
      <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The <code>&lt;script&gt;</code> tag imports the HTMX library from a CDN, enabling client-side interactions without requiring complex JavaScript. In addition to that, we enhance the <code>&lt;input&gt;</code> element with HTMX attributes:</p>
<ul>
<li><p><code>hx-get="/search"</code>: Specifies the endpoint (<code>/search</code>) to send GET requests when the user types in the input field.</p>
</li>
<li><p><code>hx-trigger="keyup changed delay:500ms"</code>: Triggers the search action after a 500ms delay when the user types (<code>keyup</code>) or changes the input (<code>changed</code>).</p>
</li>
<li><p><code>hx-target="#results"</code>: Updates the content of the element with <code>id="results"</code> with the response from the <code>/search</code> endpoint.</p>
</li>
</ul>
<h3 id="heading-creating-searchresultshtml-template">Creating <code>search_results.html</code> Template</h3>
<p>Next, we will create a new template <code>search_results.html</code> to display search results:</p>
<pre><code class="lang-xml">{% for result in results %}
<span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{{ result.id }}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{{ result.title }}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>{{ result.author }}<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
{% endfor %}
</code></pre>
<p>This template iterates over <code>results</code>, which are passed from the <code>/search</code> route. For each book in <code>results</code>, it generates a table row (<code>&lt;tr&gt;</code>) displaying the book's ID, title, and author.</p>
<h2 id="heading-demo">Demo</h2>
<p>Finally, we have implemented instant search with HTMX in our Flask application. Here's what our final application should look like:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/llCmZXaopX0">https://youtu.be/llCmZXaopX0</a></div>
<p> </p>
<p>Did you notice the delay in the search results? It is called debouncing. It is a programming and web development technique to limit the rate at which a function or event handler is executed. It ensures that a function is only executed after a certain amount of time has passed since the last invocation of the function. In our case, we had set the delay of 500 ms before it hit the <code>/search</code> API. It ensures we do not hit the API for every character the user types.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, we learned how to implement instant search using Flask and HTMX, focusing on enhancing user interaction and performance. By integrating HTMX for AJAX interactions, we enabled dynamic updates to search results without refreshing the entire page. This approach improves user experience by providing real-time feedback and optimizes server load by debouncing search queries.</p>
<p>By mastering these techniques, you're equipped to build responsive web applications that deliver seamless search experiences, combining the flexibility of Flask with the interactivity of HTMX to meet diverse user needs efficiently and effectively.</p>
<p>You can find the code for this tutorial in this repository:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/ashutoshkrris/instant-search-with-flask-htmx">https://github.com/ashutoshkrris/instant-search-with-flask-htmx</a></div>
]]></content:encoded></item><item><title><![CDATA[How to Set Up Magic Link Authentication with React, Flask, and Authsignal]]></title><description><![CDATA[Authentication is the process of verifying the identity of a user or system. It ensures that only authorized individuals or systems can access certain resources or perform specific actions.
Magic Link Authentication offers a simple yet secure way for...]]></description><link>https://blog.ashutoshkrris.in/how-to-set-up-magic-link-authentication-with-react-flask-and-authsignal</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/how-to-set-up-magic-link-authentication-with-react-flask-and-authsignal</guid><category><![CDATA[Python]]></category><category><![CDATA[React]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[authentication]]></category><category><![CDATA[authsignal]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sat, 13 Jan 2024 07:24:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1705130246382/1a51cb94-4991-476d-937c-ce44c4e2d37c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Authentication is the process of verifying the identity of a user or system. It ensures that only authorized individuals or systems can access certain resources or perform specific actions.</p>
<p>Magic Link Authentication offers a simple yet secure way for users to log in without passwords. This tutorial will walk you through the implementation of Magic Link Authentication using React for the front end, Flask for the back end, and the authentication service provided by <a target="_blank" href="https://www.authsignal.com/">Authsignal</a>.</p>
<h2 id="heading-understanding-magic-link-authentication"><strong>Understanding Magic Link Authentication</strong></h2>
<p>Magic link authentication is a convenient and secure authentication method that simplifies users' login process. Instead of entering a username and password, users receive a unique link via email. This link, known as a magic link, grants them access to their account without traditional credentials.</p>
<p>One key difference between magic link authentication and authentication with email verification is the user experience. With magic link authentication, users can authenticate with just a single click. They don't need to remember or enter a password, which can be especially beneficial for users who struggle with password management or find it inconvenient to type in their credentials repeatedly.</p>
<p>While email verification adds an extra layer of security, it may require the user to remember additional credentials or go through multiple steps before accessing their account. If you're interested in learning more about email verification, you can check out my article <a target="_blank" href="https://blog.ashutoshkrris.in/how-to-set-up-email-verification-in-a-flask-app">here</a> to dive deeper into the topic.</p>
<h2 id="heading-how-to-configure-authsignal"><strong>How to Configure Authsignal</strong></h2>
<p><a target="_blank" href="https://www.authsignal.com/">Authsignal</a> is a service that makes implementing modern authentication methods (like Magic Links and Passkeys) easier. It provides simple tools to integrate secure login methods into your web apps without hassle.</p>
<p>Before proceeding with the tutorial, you need to create an Authsignal account. To do that, you can follow these steps:</p>
<p>First, go to <a target="_blank" href="https://www.freecodecamp.org/news">authsignal.com</a> and click on "Create Free Account".</p>
<p>In the next step, create your first tenant. Choose any name for your tenant and select the data storage region.</p>
<p><img src="https://lh7-us.googleusercontent.com/PoQ1Jl8b1fNXmzruv750erSeyi4jxnVlI_QAvoHDH6-O6GVHmDQ07yd2U7WxHrYTUMCyKowll7W-Bs0dBuet9KqiF-mZuV_w8IbFO5tpYziI5M5kaO1ipWEaJPJ7dkPWTNtXyib-BE-8S5VcVtanNNc" alt="Creating Tenant on Authsignal" /></p>
<p>Next, you need to configure the authenticators you want to use for your application. For example, I have enabled Email Magic Link and Authenticator App (TOTP).</p>
<p><img src="https://lh7-us.googleusercontent.com/AagTYGVbXToDeHqe4S-lFUx2qgIerUbzlUnGTv3sxZ2EyPBzfDeXNcvT-_oeQksckyhGFHX2YY6g8heKHdIz18qf2N_ejed9fJDFA_pSMzfKX3d5Tid4eDnrn7PUbEX_zVh10urhFa49Ek-eSYZJdAA" alt="Configuring Authenticators" /></p>
<p>Once you have configured the authenticator, navigate to the API Keys option. Here, you will find your Secret Key, which will be necessary for implementing the authentication.</p>
<p><img src="https://lh7-us.googleusercontent.com/UJgdqGLl6IRK8sr3NOsf1BXVp7EJpSFMkxTzdRw0QNhz7DqL5fyGMn7KBotMvrp3ivZnYtw8M-fdVX-aJgNrdszRyAziVCxIAXAxb-g8r42F9ZgQFlpm9D1FYicnhuS4DcS5V7hZ430FM5ruEUioiSw" alt="Finding your secret key" /></p>
<h2 id="heading-application-flow"><strong>Application Flow</strong></h2>
<p>Let's understand the flow of the application:</p>
<h3 id="heading-initial-visit"><strong>Initial Visit</strong></h3>
<ul>
<li>The user visits the application's user interface. On the user interface, they see a login input box and a signup option. Since the user is new, they opt to sign up.</li>
</ul>
<h3 id="heading-signup-flow"><strong>Signup Flow</strong></h3>
<ul>
<li><p>Upon clicking the signup link, the user is directed to a page to enter their chosen username.</p>
</li>
<li><p>After entering the username and clicking the signup button, the front end triggers a POST API call to /api/signup, sending the username in the request body.</p>
</li>
<li><p>The backend receives the request and communicates with the Authsignal server for user authentication.</p>
</li>
<li><p>Authsignal prompts the user to set up Magic Link authentication by entering their email address.</p>
</li>
<li><p>Authsignal sends a magic link to the provided email address.</p>
</li>
<li><p>After clicking the magic link, the user is authenticated and redirected to the home page, where they receive a welcome message displaying their email address. The page also includes a logout button.</p>
</li>
</ul>
<h3 id="heading-login-flow"><strong>Login Flow</strong></h3>
<ul>
<li><p>The user logs out and returns to the login page.</p>
</li>
<li><p>Here, the user enters their registered username and clicks the Login button.</p>
</li>
<li><p>Upon clicking Login, the front end triggers a POST API call to /api/login, passing the username in the request body.</p>
</li>
<li><p>The backend again communicates with Authsignal for user authentication, prompting the setup of Magic Link authentication.</p>
</li>
<li><p>The user is directed to a page to enter their email address.</p>
</li>
<li><p>Authsignal sends a magic link to the provided email address.</p>
</li>
<li><p>After clicking the magic link, the user is authenticated and redirected to the home page, greeted with a welcome message displaying their email address.</p>
</li>
</ul>
<p>This flow ensures users can sign up using a chosen username, and set up Magic Link authentication via email for both signup and login. Here is a video tutorial to visually aid you in understanding the flow:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/kr8frW5Wwcg">https://youtu.be/kr8frW5Wwcg</a></div>
<p> </p>
<h2 id="heading-how-to-set-up-your-backend-server"><strong>How to Set Up Your Backend Server</strong></h2>
<p>In this section, I will guide you through how to set up your Flask server for implementing Magic Link Authentication. Before we begin, it's recommended to set up a virtual environment to isolate your project's dependencies. Here's how you can do it:</p>
<ol>
<li><p>Open your terminal or command prompt.</p>
</li>
<li><p>Navigate to your project's directory.</p>
</li>
<li><p>Run the following command to create a new virtual environment:</p>
</li>
</ol>
<pre><code class="lang-bash">python -m venv myenv
</code></pre>
<p>Note: Replace <code>myenv</code> with the desired name for your virtual environment.</p>
<p>4.  Activate the virtual environment using the appropriate command for your operating system:</p>
<ul>
<li>For Windows:</li>
</ul>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> myenv/Scripts/activate
</code></pre>
<ul>
<li>For macOS/Linux:</li>
</ul>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> myenv/bin/activate
</code></pre>
<p>Now that you have your virtual environment set up, let's install the necessary dependencies.</p>
<p>To begin, make sure you have Flask installed, which is a micro web framework for Python. You can install it using the following one-liner:</p>
<pre><code class="lang-bash">pip install Flask
</code></pre>
<p>Next, we need <code>python-decouple</code>, a library that helps manage configuration settings in separate files. Install it with the following command:</p>
<pre><code class="lang-bash">pip install python-decouple
</code></pre>
<p>The <code>flask-cors</code> library is a Flask extension that allows for Cross-Origin Resource Sharing (CORS) support in your Flask application.</p>
<pre><code class="lang-bash">pip install flask-cors
</code></pre>
<p>Finally, we need to install the Python SDK for Authsignal. You can install it with the following command:</p>
<pre><code class="lang-bash">pip install authsignal
</code></pre>
<p>Now that we have all the necessary dependencies installed, let's create a sample Flask server to get started with Magic Link Authentication. Here's a basic setup to help you get started:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask
<span class="hljs-keyword">from</span> flask_cors <span class="hljs-keyword">import</span> CORS

app = Flask(__name__)
CORS(app, supports_credentials=<span class="hljs-literal">True</span>)

<span class="hljs-meta">@app.route("/")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hello</span>():</span>
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello, world!"</span>

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    app.run(debug=<span class="hljs-literal">True</span>)
</code></pre>
<p>In the next steps, we will integrate AuthSignal and implement the Magic Link Authentication functionality into this server.</p>
<h2 id="heading-how-to-set-up-environment-variables"><strong>How to Set Up Environment Variables</strong></h2>
<p>To successfully configure and integrate AuthSignal into your Flask server, you need to set up the following environment variables:</p>
<ul>
<li><p><code>AUTHSIGNAL_BASE_URL</code>: This variable contains the base URL of the Authsignal server. It allows your server to communicate with Authsignal's authentication service.</p>
</li>
<li><p><code>AUTHSIGNAL_SECRET_KEY</code>: This variable contains the secret key associated with your Authsignal project. It is used for secure communication between your server and AuthSignal.</p>
</li>
<li><p><code>SECRET_KEY</code>: This variable is a random key used to encrypt the cookies and send them to the browser.</p>
</li>
</ul>
<p>Setting environment variables instead of hardcoding in the code provides improved security by keeping sensitive information, such as API keys and secret keys, separate from the codebase. This reduces the risk of accidental exposure or unauthorized access to these credentials.</p>
<p>To set up these environment variables, you can follow these steps:</p>
<ol>
<li><p>Open a terminal or command prompt.</p>
</li>
<li><p>Navigate to the directory where your Flask server is located.</p>
</li>
<li><p>Create a <code>.env</code> file and export the environment variables using the following commands:</p>
</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> AUTHSIGNAL_BASE_URL=&lt;base_url&gt;
<span class="hljs-built_in">export</span> AUTHSIGNAL_SECRET_KEY=&lt;secret_key&gt;
<span class="hljs-built_in">export</span> SECRET_KEY=&lt;random-secret-key&gt;
</code></pre>
<p>Make sure to replace <code>&lt;base_url&gt;</code>, <code>&lt;secret_key&gt;</code>, and <code>&lt;random-secret-key&gt;</code> with the appropriate values for your Authsignal project. You can find the values for these environment variables in the API Keys section of the Authsignal dashboard as explained earlier.</p>
<blockquote>
<p>Note: The method for setting environment variables can vary depending on your operating system. The above commands are applicable for Unix-based systems. For Windows, you can use the <code>set</code> command instead of <code>export</code>.</p>
</blockquote>
<p>To export the variables added in the .env file, you can use the following command in the terminal:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> .env
</code></pre>
<p>By properly setting these environment variables, your Flask server can securely communicate with Authsignal and implement the Magic Link Authentication functionality.</p>
<h2 id="heading-how-to-initialize-the-authsignal-client"><strong>How to Initialize the Authsignal Client</strong></h2>
<p>To integrate Authsignal into your Flask server and implement Magic Link Authentication, you need to initialize the Authsignal client. Here's an example of how you can do this:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask
<span class="hljs-keyword">from</span> flask_cors <span class="hljs-keyword">import</span> CORS
<span class="hljs-keyword">import</span> authsignal.client
<span class="hljs-keyword">from</span> decouple <span class="hljs-keyword">import</span> config

app = Flask(__name__)
CORS(app)

AUTHSIGNAL_BASE_URL = config(<span class="hljs-string">"AUTHSIGNAL_BASE_URL"</span>)
AUTHSIGNAL_SECRET_KEY = config(<span class="hljs-string">"AUTHSIGNAL_SECRET_KEY"</span>)
SECRET_KEY = config(<span class="hljs-string">"SECRET_KEY"</span>)

authsignal_client = authsignal.Client(
    api_key=AUTHSIGNAL_SECRET_KEY,
    api_url=AUTHSIGNAL_BASE_URL
)
</code></pre>
<p>In this code snippet, we first import the <code>authsignal.client</code>, the Python SDK for Authsignal. We also import config from python-decouple to retrieve the environment variables.</p>
<p>We retrieve the environment variables <code>AUTHSIGNAL_BASE_URL</code>, <code>AUTHSIGNAL_SECRET_KEY</code> and <code>SECRET_KEY</code> using config from python-decouple.</p>
<p>Finally, we initialize the <code>authsignal.Client</code> by passing in the API key <code>AUTHSIGNAL_SECRET_KEY</code> and the base URL of the Authsignal server <code>AUTHSIGNAL_BASE_URL</code>.</p>
<p>By initializing the Authsignal client, we are ready to implement the Magic Link Authentication functionality in our Flask server.</p>
<h2 id="heading-authsignal-actions"><strong>Authsignal Actions</strong></h2>
<p>Authsignal allows you to create actions to track and manage user interactions in your application. Actions are events that can be triggered by users, such as signing up or logging in. By creating custom actions, you can have more control over the authentication process and implement specific authentication methods like Magic Link Authentication.</p>
<p>To create an action on your Authsignal dashboard, follow these steps:</p>
<ol>
<li><p>Click on "<strong>Actions</strong>" in your Authsignal dashboard.</p>
</li>
<li><p>Click on "<strong>Configure a new action</strong>" to create a new action.</p>
</li>
<li><p>Enter a name for the action that describes its purpose or the user interaction it represents.</p>
</li>
<li><p>Next, you can configure the rule for the action. In our case, since we want to implement Magic Link Authentication, we will add a rule to challenge users with Email Magic Link. This will send a magic link to the user's email for authentication.</p>
</li>
<li><p>Save the action to apply the rule and make it active.</p>
</li>
</ol>
<p>Here is a video demonstrating the process of creating an Authsignal action and configuring it for Magic Link Authentication:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/action.gif" alt="Creating action on Authsignal" /></p>
<p>You can create two actions – "<strong>signUp</strong>" and "<strong>signIn</strong>". In the next steps, we will make use of these actions.</p>
<h2 id="heading-how-to-create-the-required-routes"><strong>How to Create the Required Routes</strong></h2>
<p>Finally, to implement the Magic Link Authentication, we need to create three routes: <code>/api/signup</code>, <code>/api/login</code>, <code>/api/callback</code>, and <code>/api/user</code>.</p>
<h3 id="heading-apisignup-route"><code>/api/signup</code> Route</h3>
<p>The <code>/api/signup</code> route is responsible for allowing the users to register in our application. Here's how we implement it:</p>
<pre><code class="lang-python"><span class="hljs-meta">@app.route('/api/signup', methods=['POST'])</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">signup</span>():</span>
    username = request.json.get(<span class="hljs-string">'username'</span>)
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> username:
        <span class="hljs-keyword">return</span> jsonify({<span class="hljs-string">'error'</span>: <span class="hljs-string">'Missing username parameter'</span>}), <span class="hljs-number">400</span>

    response = authsignal_client.track(
        user_id=username,
        action=<span class="hljs-string">"signUp"</span>,
        payload={
            <span class="hljs-string">"user_id"</span>: username,
            <span class="hljs-string">"redirectUrl"</span>: <span class="hljs-string">"http://localhost:5000/api/callback"</span>
        }
    )
    <span class="hljs-keyword">return</span> jsonify(response), <span class="hljs-number">200</span>
</code></pre>
<p>In this implementation, the route expects a JSON payload containing the <code>username</code> parameter. It then uses the <code>authsignal_client</code> to track the user's <strong>signUp</strong> action and generate a Magic Link. The <code>track</code> method lets you record actions performed by users and initiate challenges. The <code>redirectUrl</code> specifies the URL where the user will be redirected after they have been authenticated. We will create this API next.</p>
<h3 id="heading-apicallback-route"><code>/api/callback</code> Route</h3>
<p>The <code>/api/callback</code> route handles the callback URL where the user is redirected after verifying themselves. Here's the implementation for this route:</p>
<pre><code class="lang-python"><span class="hljs-meta">@app.route('/api/callback', methods=['GET'])</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">callback</span>():</span>
    token = request.args.get(<span class="hljs-string">'token'</span>)
    challenge_response = authsignal_client.validate_challenge(token)

    <span class="hljs-keyword">if</span> challenge_response[<span class="hljs-string">"state"</span>] == <span class="hljs-string">'CHALLENGE_SUCCEEDED'</span>:
        encoded_token = jwt.encode(
            payload={<span class="hljs-string">"username"</span>: challenge_response[<span class="hljs-string">"user_id"</span>]},
            key=SECRET_KEY,
            algorithm=<span class="hljs-string">"HS256"</span>
        )
        response = redirect(<span class="hljs-string">'http://localhost:3000/'</span>)
        response.set_cookie(
            key=<span class="hljs-string">'auth-session'</span>,
            value=encoded_token,
            secure=<span class="hljs-literal">False</span>,
            path=<span class="hljs-string">'/'</span>
        )
        <span class="hljs-keyword">return</span> response

    <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">"/"</span>)
</code></pre>
<p>When the users are redirected, Authsignal adds the JWT token in the URL as a token query parameter.</p>
<p>In this implementation, the route retrieves the token parameter from the query string. It then uses the <code>authsignal_client</code> to validate the challenge and check if the authentication was successful.</p>
<p>If the authentication succeeds, we encode a JSON Web Token (JWT). The token payload includes the <code>username</code> obtained from the challenge response. It uses the <code>SECRET_KEY</code> and the <em>HS256 algorithm</em> for encryption.</p>
<p>Next, the user is redirected to the home page (<a target="_blank" href="https://www.freecodecamp.org/news">http://localhost:3000/</a>), and a <code>auth-session</code> cookie is set with the encoded token for further user identification.</p>
<p>Note that the token returned from Authsignal in the redirect is not intended to be used as a session token. It just contains information about the challenge so that we can determine if the challenge was successful.</p>
<h3 id="heading-apilogin-route"><code>/api/login</code> Route</h3>
<p>The <code>/api/login</code> route is responsible for allowing the users to log into the application. Here’s the implementation for the route:</p>
<pre><code class="lang-python"><span class="hljs-meta">@app.route('/api/login', methods=['POST'])</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">login</span>():</span>
    username = request.json.get(<span class="hljs-string">'username'</span>)
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> username:
        <span class="hljs-keyword">return</span> jsonify({<span class="hljs-string">'error'</span>: <span class="hljs-string">'Missing username parameter'</span>}), <span class="hljs-number">400</span>

    response = authsignal_client.track(
        user_id=username,
        action=<span class="hljs-string">"signIn"</span>,
        payload={
            <span class="hljs-string">"user_id"</span>: username,
            <span class="hljs-string">"redirectUrl"</span>: <span class="hljs-string">"http://localhost:5000/api/callback"</span>
        }
    )
    <span class="hljs-keyword">return</span> jsonify(response), <span class="hljs-number">200</span>
</code></pre>
<p>The route is configured to handle POST requests on the <code>/api/login</code> endpoint. Upon receiving a POST request, the route first extracts the provided <code>username</code> from the JSON payload sent with the request. It ensures that the username is present. If not, it promptly returns a 400 error response indicating a missing username parameter.</p>
<p>Similar to the signup flow, it then uses the <code>authsignal_client</code> to track the user's <strong>signIn</strong> action and generate a Magic Link. The redirectUrl specifies the URL where the user will be redirected after they have been authenticated.</p>
<h3 id="heading-apiuser-route"><code>/api/user</code> Route</h3>
<p>The <code>/api/user</code> route is responsible for retrieving user information. Here's the implementation for this route:</p>
<pre><code class="lang-python"><span class="hljs-meta">@app.route("/api/user", methods=['GET'])</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">user</span>():</span>
    token = request.cookies.get(<span class="hljs-string">'auth-session'</span>)
    decoded_token = jwt.decode(token, SECRET_KEY, algorithms=[<span class="hljs-string">"HS256"</span>])
    username = decoded_token.get(<span class="hljs-string">'username'</span>)
    response = authsignal_client.get_user(user_id=username)
    <span class="hljs-keyword">return</span> jsonify({<span class="hljs-string">"username"</span>: username, <span class="hljs-string">"email"</span>: response[<span class="hljs-string">"email"</span>]}), <span class="hljs-number">200</span>
</code></pre>
<p>In this implementation, the GET endpoint starts by extracting the auth-session cookie from the incoming request. Then it decodes the JWT using the jwt.decode method, utilizing the <code>SECRET_KEY</code> as the secret key for decoding.</p>
<p>The decoded token provides the username of the user. It then uses the <code>authsignal_client</code> to retrieve user information based on the provided <code>userId</code>. It then returns a JSON response with the username and email information.</p>
<p>By implementing these routes, we will be able to handle the basic authentication process and retrieve user information in our Flask server.</p>
<h2 id="heading-how-to-set-up-a-new-frontend-react-project"><strong>How to Set Up a New Frontend React Project</strong></h2>
<p>Let's set up our front-end project in this section. This will also include setting up routing in the application.</p>
<p>Start by initializing a new React project using <code>create-react-app</code> or any preferred method (<a target="_blank" href="https://www.freecodecamp.org/news/complete-vite-course-for-beginners/">like Vite</a>, for example, which is a more modern way to set up a React app). This command sets up the basic structure for your React application.</p>
<pre><code class="lang-bash">npx create-react-app magic-link-auth
<span class="hljs-built_in">cd</span> magic-link-auth
</code></pre>
<p>Once the project is created and you're inside the project directory, install the required dependencies. Here, we need <code>react-router-dom</code> for handling routing and <code>bootstrap</code> for easy styling.</p>
<pre><code class="lang-bash">npm install react-router-dom bootstrap
</code></pre>
<h3 id="heading-import-bootstrap-css"><strong>Import Bootstrap CSS</strong></h3>
<p>Bootstrap provides pre-styled components and utilities for easier and faster styling of your application.</p>
<p>In the <code>index.js</code> file, import Bootstrap:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom/client'</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App'</span>;
<span class="hljs-keyword">import</span> reportWebVitals <span class="hljs-keyword">from</span> <span class="hljs-string">'./reportWebVitals'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"bootstrap/dist/css/bootstrap.min.css"</span>; <span class="hljs-comment">// Import Bootstrap CSS</span>

<span class="hljs-keyword">const</span> root = ReactDOM.createRoot(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>));
root.render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>
);

<span class="hljs-comment">// If you want to start measuring performance in your app, pass a function</span>
<span class="hljs-comment">// to log results (for example: reportWebVitals(console.log))</span>
<span class="hljs-comment">// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals</span>
reportWebVitals();
</code></pre>
<p>Additionally, we will write some custom CSS. Replace the code in the <code>index.css</code> file with the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">html</span>,
<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">font-family</span>: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}

* {
  <span class="hljs-attribute">box-sizing</span>: border-box;
}

<span class="hljs-selector-tag">main</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">5rem</span> <span class="hljs-number">0</span>;
  <span class="hljs-attribute">flex</span>: <span class="hljs-number">1</span>;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-direction</span>: column;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">align-items</span>: center;
}

<span class="hljs-selector-tag">code</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#fafafa</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.75rem</span>;
  <span class="hljs-attribute">font-family</span>: Menlo, Monaco, Lucida Console, Courier New, monospace;
}

<span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=<span class="hljs-string">"button"</span>]</span> {
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">background</span>: cornflowerblue;
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">12px</span> <span class="hljs-number">24px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">18px</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">cursor</span>: pointer;
}
</code></pre>
<p>Similarly, replace the code in the <code>App.css</code> with the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.mainContainer</span> {
  <span class="hljs-attribute">flex-direction</span>: column;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
}

<span class="hljs-selector-class">.titleContainer</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-direction</span>: column;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">48px</span>;
  <span class="hljs-attribute">font-weight</span>: bolder;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">justify-content</span>: center;
}

<span class="hljs-selector-class">.resultContainer</span>,
<span class="hljs-selector-class">.historyItem</span> {
  <span class="hljs-attribute">flex-direction</span>: row;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">400px</span>;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">justify-content</span>: space-between;
}

<span class="hljs-selector-class">.historyContainer</span> {
  <span class="hljs-attribute">flex-direction</span>: column;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">200px</span>;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">flex-grow</span>: <span class="hljs-number">5</span>;
  <span class="hljs-attribute">justify-content</span>: flex-start;
}

<span class="hljs-selector-class">.buttonContainer</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-direction</span>: column;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">260px</span>;
}

<span class="hljs-selector-class">.inputContainer</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-direction</span>: column;
  <span class="hljs-attribute">align-items</span>: flex-start;
  <span class="hljs-attribute">justify-content</span>: center;
}

<span class="hljs-selector-class">.inputContainer</span>&gt;<span class="hljs-selector-class">.errorLabel</span> {
  <span class="hljs-attribute">color</span>: red;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">16px</span>;
  <span class="hljs-attribute">text-align</span>: center;
}

<span class="hljs-selector-class">.inputBox</span> {
  <span class="hljs-attribute">height</span>: <span class="hljs-number">48px</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">400px</span>;
  <span class="hljs-attribute">font-size</span>: medium;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">8px</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid grey;
  <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">8px</span>;
}

<span class="hljs-selector-class">.inputButton</span> {
  <span class="hljs-attribute">height</span>: <span class="hljs-number">48px</span>;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">400px</span>;
}
</code></pre>
<h3 id="heading-set-up-routing"><strong>Set Up Routing</strong></h3>
<p>Routing in React applications helps navigate between different views or pages. <code>react-router-dom</code> simplifies this process.</p>
<p>In your <code>App.js</code> file, configure the routing:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { BrowserRouter, Routes, Route } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-router-dom"</span>;
<span class="hljs-keyword">import</span> Dashboard <span class="hljs-keyword">from</span> <span class="hljs-string">"./pages/Dashboard"</span>;
<span class="hljs-keyword">import</span> Register <span class="hljs-keyword">from</span> <span class="hljs-string">"./pages/Register"</span>;
<span class="hljs-keyword">import</span> Login <span class="hljs-keyword">from</span> <span class="hljs-string">"./pages/Login"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./App.css"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./index.css"</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">BrowserRouter</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Dashboard</span> /&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/login"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Login</span> /&gt;</span>} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/signup"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Register</span> /&gt;</span>} /&gt;
      <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">BrowserRouter</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>It defines an App component that encapsulates the entire application structure within a <code>&lt;BrowserRouter&gt;</code> component. Inside <code>&lt;Routes&gt;</code>, we define three &lt;Route&gt; components: one for the root path <code>/</code> rendering the <code>Dashboard</code> component, and two for the <code>/login</code> and <code>/signup</code>  paths, rendering the <code>Login</code> and <code>Register</code> components respectively.</p>
<p>This setup enables navigation between different views based on URL paths, allowing users to access specific components when they visit corresponding routes within the application.</p>
<p>In the upcoming sections, we will set up the above-mentioned three components.</p>
<h2 id="heading-how-to-set-up-the-components"><strong>How to Set Up the Components</strong></h2>
<p>In the previous section, we imported two components from the <code>src/pages</code> folder. Let's create a <code>pages</code> folder inside the <code>src</code> folder, and then we can start creating the components.</p>
<h3 id="heading-register-component"><strong>Register Component</strong></h3>
<p>Let’s create a <code>Register.jsx</code> file inside the pages folder. The <strong>Register</strong> component allows users to register within our application.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useNavigate, Link } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-router-dom"</span>;

<span class="hljs-keyword">const</span> Register = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [username, setUsername] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [usernameError, setUsernameError] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-keyword">const</span> navigate = useNavigate();

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> isAuthenticated = checkCookies();
    <span class="hljs-keyword">if</span> (isAuthenticated) {
      navigate(<span class="hljs-string">"/"</span>);
    }
  }, [navigate]);

  <span class="hljs-keyword">const</span> checkCookies = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> authSessionCookie = <span class="hljs-built_in">document</span>.cookie.match(<span class="hljs-string">"auth-session=([^;]+)"</span>);

    <span class="hljs-keyword">return</span> !!authSessionCookie;
  };

  <span class="hljs-keyword">const</span> onButtonClick = <span class="hljs-function">() =&gt;</span> {
    setUsernameError(<span class="hljs-string">""</span>);

    <span class="hljs-keyword">if</span> (<span class="hljs-string">""</span> === username) {
      setUsernameError(<span class="hljs-string">"Username is mandatory!"</span>);
      <span class="hljs-keyword">return</span>;
    }

    signup();
  };

  <span class="hljs-keyword">const</span> signup = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"http://localhost:5000/api/login"</span>, {
      <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
      <span class="hljs-attr">headers</span>: {
        <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
      },
      <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
        username,
      }),
      <span class="hljs-attr">credentials</span>: <span class="hljs-string">"include"</span>,
    });

    <span class="hljs-keyword">const</span> { url } = <span class="hljs-keyword">await</span> response.json();

    <span class="hljs-comment">// Redirect to verification URL</span>
    <span class="hljs-built_in">window</span>.location.href = url;
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">mainContainer</span>"}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">titleContainer</span>"}&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Sign Up<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">inputContainer</span>"}&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">value</span>=<span class="hljs-string">{username}</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your username"</span>
          <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setUsername(e.target.value)}
          className={"inputBox"}
        /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"errorLabel text-center"</span>&gt;</span>{usernameError}<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">inputContainer</span>"}&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">inputButton</span>"}
          <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span>
          <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onButtonClick}</span>
          <span class="hljs-attr">value</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">Sign</span> <span class="hljs-attr">Up</span>"}
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        Existing User? <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/login"</span>&gt;</span>Login here<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Register;
</code></pre>
<p>The component initializes state variables using <code>useState</code> to manage the visibility of the <code>usernameError</code> and store the username input in <code>userName</code>. It also initializes the <code>navigate</code> function from <code>useNavigate</code> to handle navigation within the application.</p>
<p>We use the <code>useEffect</code> hook to check for authentication cookies when the component mounts. It calls the <code>checkCookies</code> function, which checks for the existence of cookies that we had set from the backend server. If <code>auth-session</code> cookie is found, the user is automatically redirected to the root URL using navigate("/").</p>
<p>Clicking the “Sign Up” button triggers the <code>onButtonClick</code> function. It first checks whether the user has entered the username. If not, it shows an error message using the <code>usernameError</code>. If the user has entered the username, it calls the <code>signup</code> function.</p>
<p>The <code>signup</code> performs an asynchronous POST request to the <code>/api/signup</code> endpoint with the provided username. Upon successful response, it redirects the user to the received verification URL by changing window.location.href.</p>
<p>The JSX returned by the component defines the UI layout that looks like the below:</p>
<p><img src="https://lh7-us.googleusercontent.com/gncsDRe9QVK20DWMkiWwdGOt_ZymbSVXTv-8UGvyKIpp5-TZ64-DwLGLbMtDM0B-wgXh8jNOCdkA0kia3-gJftMxFaH-za_4O0cqCSvK9GLMHSbO_nH_UfgGIf5QhHaOZg559_N0c4P9Oof4O5JmkPE" alt="Register UI Component" /></p>
<p>It includes an input field for the users to enter their username and a "Sign Up" button. Below the button, we have a link to the Login page for the existing users to log in.</p>
<h3 id="heading-login-component"><strong>Login Component</strong></h3>
<p>We have kept the login page similar to the signup page for simplicity. Hence, the Login component is pretty much the same as the Register component.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useNavigate, Link } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-router-dom"</span>;

<span class="hljs-keyword">const</span> Login = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [username, setUsername] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [usernameError, setUsernameError] = useState(<span class="hljs-string">""</span>);

  <span class="hljs-keyword">const</span> navigate = useNavigate();

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> isAuthenticated = checkCookies();
    <span class="hljs-keyword">if</span> (isAuthenticated) {
      navigate(<span class="hljs-string">"/"</span>);
    }
  }, [navigate]);

  <span class="hljs-keyword">const</span> checkCookies = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> authSessionCookie = <span class="hljs-built_in">document</span>.cookie.match(<span class="hljs-string">"auth-session=([^;]+)"</span>);

    <span class="hljs-keyword">return</span> !!authSessionCookie;
  };

  <span class="hljs-keyword">const</span> onButtonClick = <span class="hljs-function">() =&gt;</span> {
    setUsernameError(<span class="hljs-string">""</span>);

    <span class="hljs-keyword">if</span> (<span class="hljs-string">""</span> === username) {
      setUsernameError(<span class="hljs-string">"Username is mandatory!"</span>);
      <span class="hljs-keyword">return</span>;
    }

    login();
  };

  <span class="hljs-keyword">const</span> login = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"http://localhost:5000/api/login"</span>, {
      <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
      <span class="hljs-attr">headers</span>: {
        <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
      },
      <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
        username,
      }),
      <span class="hljs-attr">credentials</span>: <span class="hljs-string">"include"</span>,
    });

    <span class="hljs-keyword">const</span> { url } = <span class="hljs-keyword">await</span> response.json();

    <span class="hljs-comment">// Redirect to verification URL</span>
    <span class="hljs-built_in">window</span>.location.href = url;
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">mainContainer</span>"}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">titleContainer</span>"}&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">inputContainer</span>"}&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">value</span>=<span class="hljs-string">{username}</span>
          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter your username"</span>
          <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(ev)</span> =&gt;</span> setUsername(ev.target.value)}
          className={"inputBox"}
        /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"errorLabel text-center"</span>&gt;</span>{usernameError}<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">inputContainer</span>"}&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
          <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">inputButton</span>"}
          <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span>
          <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onButtonClick}</span>
          <span class="hljs-attr">value</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">Log</span> <span class="hljs-attr">in</span>"}
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        New User? <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/signup"</span>&gt;</span>Sign up here<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Login;
</code></pre>
<p>The only significant difference other than the text and button in the UI here is that we will be making the API call to the <code>/api/login</code> route when the users hit the Login button.</p>
<p>The UI looks like below:</p>
<p><img src="https://lh7-us.googleusercontent.com/F4EDOhuMbTRtXt3UxhpLYdZPT8XtCuYWjEX3H95bEXEZatLDsuRxaut3KZ3ZtyHSWIQ1WkuA5WWUxZcXrCBHyCMfMG-LQTKjnQHXyY8Y2Ha93YstE0Kycd9ji9lj33wMc1D8Km7pFNu5EGyQh14D9m8" alt="Login UI Component" /></p>
<h3 id="heading-dashboard-component"><strong>Dashboard Component</strong></h3>
<p>The Dashboard component in our application serves as the interface for authenticated users, displaying a welcome message with the user’s email and enabling user logout functionality.</p>
<p>Let’s create a <code>Dashboard.jsx</code> file inside the <code>pages</code> folder.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useNavigate } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-router-dom"</span>;

<span class="hljs-keyword">const</span> Dashboard = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [userEmail, setUserEmail] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> navigate = useNavigate();

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> checkCookies = <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">const</span> authSessionCookie = <span class="hljs-built_in">document</span>.cookie.match(<span class="hljs-string">"auth-session=([^;]+)"</span>);

      <span class="hljs-keyword">if</span> (!authSessionCookie) {
        navigate(<span class="hljs-string">"/auth"</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
      }

      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    };

    <span class="hljs-keyword">const</span> fetchData = <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">const</span> cookiesValid = <span class="hljs-keyword">await</span> checkCookies();
      <span class="hljs-keyword">if</span> (!cookiesValid) <span class="hljs-keyword">return</span>;

      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"http://localhost:5000/api/user"</span>, {
          <span class="hljs-attr">method</span>: <span class="hljs-string">"GET"</span>,
          <span class="hljs-attr">headers</span>: {
            <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
          },
          <span class="hljs-attr">credentials</span>: <span class="hljs-string">"include"</span>
        });

        <span class="hljs-keyword">if</span> (!response.ok) {
          <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to fetch user data"</span>);
        }

        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
        setUserEmail(data.email);
      } <span class="hljs-keyword">catch</span> (error) {
        navigate(<span class="hljs-string">"/auth"</span>);
      }
    };

    fetchData();
  }, [navigate]);

  <span class="hljs-keyword">const</span> handleLogout = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">document</span>.cookie = <span class="hljs-string">`auth-session=; max-age=0`</span>;
    navigate(<span class="hljs-string">"/auth"</span>);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"d-flex justify-content-center align-items-center vh-100"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"px-3 text-center"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Welcome Home!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"lead"</span>&gt;</span>You're logged in as {userEmail}!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"d-flex justify-content-center"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
            <span class="hljs-attr">className</span>=<span class="hljs-string">"btn btn-lg btn-dark fw-bold border-white bg-dark"</span>
            <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleLogout}</span>
          &gt;</span>
            Log Out
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Dashboard;
</code></pre>
<p>Upon component mounting or when <code>navigate</code> changes (a dependency of <code>useEffect</code>), the effect runs. It begins by defining two asynchronous functions. The first, <code>checkCookies</code>, verifies the presence of <code>auth-session</code> cookies. If it is missing, it redirects the user to the authentication route.</p>
<p>The second function, <code>fetchData</code>, is responsible for fetching user data. It checks the validity of cookies using <code>checkCookies</code>. Upon verification, it sends a GET request to our back-end API endpoint. Upon successful response, it updates the <code>userEmail</code> state with the user's email fetched from the API data.</p>
<p>If any error occurs during this process, such as failing to fetch user data, it redirects the user back to the authentication route.</p>
<p>The JSX returned by the component renders a simple dashboard layout.</p>
<p><img src="https://lh7-us.googleusercontent.com/ca-epjkteyLzE_dVbbWN6bC5fMVogCJLRvR8Milfjl7UzoHRK7462_YJZhkJvhoTpBtD0sNFwpGbNaLTKNEuBg6wKSxv6j5-ApmjpOtPgx-UkeM8i39A0KwAuU3L2TeRc8R_3aXugnAMcH4iGrlBP0M" alt="Dashboard UI Component" /></p>
<p>The displayed content includes a welcoming message and the currently logged-in user's email. There's also a "Log Out" button which, upon clicking, initiates the logout process by triggering the <code>handleLogout</code> function. It removes the <code>auth-session</code> cookies by setting their <code>max-age</code> to 0, effectively expiring them. Afterward, it redirects the user to the authentication route.</p>
<h2 id="heading-how-to-run-the-application"><strong>How to Run the Application</strong></h2>
<p>You can find the code of the final application in this <a target="_blank" href="https://github.com/ashutoshkrris/authsignal-magic-link-demo">GitHub repository</a>.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/ashutoshkrris/authsignal-magic-link-demo">https://github.com/ashutoshkrris/authsignal-magic-link-demo</a></div>
<p> </p>
<p>To run your backend application, run <code>python</code> <a target="_blank" href="https://www.freecodecamp.org/news"><code>app.py</code></a> from your back-end folder in your terminal. This will start your back-end server on port 5000. Next, run the frontend application using the <code>npm start</code> command. This will start your frontend application on the port 3000.</p>
<h2 id="heading-wrapping-up"><strong>Wrapping Up</strong></h2>
<p>In this tutorial, you learned how to use Authsignal to implement basic user authentication with email verification through magic links.</p>
<p>Authsignal makes handling users and keeping things safe easier, letting developers focus on improving apps. It also removes the overhead of remembering another password for the users of the application.</p>
<p>To learn more about Authsignal, <a target="_blank" href="https://docs.authsignal.com/">visit the Authsignal documentation</a>.</p>
<blockquote>
<p>Should you have any issues or questions related to the tutorial, then feel free to reach out to me on <a target="_blank" href="https://twitter.com/ashutoshkrris">Twitter</a>.</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[How to Implement Two-Factor Authentication with PyOTP and Google Authenticator in Your Flask App]]></title><description><![CDATA[Two-factor authentication, or 2FA, is like having an extra lock on the door to your online accounts. Instead of just using a password, 2FA adds another layer of security. It's a bit like needing both a key and a special code to open a vault.
Think of...]]></description><link>https://blog.ashutoshkrris.in/how-to-implement-two-factor-authentication-with-pyotp-and-google-authenticator-in-your-flask-app</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/how-to-implement-two-factor-authentication-with-pyotp-and-google-authenticator-in-your-flask-app</guid><category><![CDATA[Python]]></category><category><![CDATA[Flask Framework]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[authentication]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Thu, 30 Nov 2023 02:25:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1701310653950/695ba990-3bbf-439b-8fd7-ba73fa8d3fb0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Two-factor authentication, or 2FA, is like having an extra lock on the door to your online accounts. Instead of just using a password, 2FA adds another layer of security. It's a bit like needing both a key and a special code to open a vault.</p>
<p>Think of it as a shield for your accounts. Passwords can sometimes be guessed or stolen, but with 2FA, even if someone gets your password, they'd still need that extra code or device to get in. It's an extra step that makes your accounts much harder for hackers to break into.</p>
<p>So, let's explore how to set up this extra layer of protection using PyOTP and Google Authenticator in your Flask app.</p>
<h2 id="heading-overview-of-pyotp-and-google-authenticator"><strong>Overview of PyOTP and Google Authenticator</strong></h2>
<p>PyOTP is a Python library that's incredibly handy for generating Time-based One-Time Passwords (TOTP) and HMAC-based One-Time Passwords (HOTP). Its primary role revolves around creating these unique, time-sensitive codes that add an extra layer of security to user accounts.</p>
<p>By integrating PyOTP into your Flask application, you can easily implement Two-Factor Authentication (2FA) by generating and verifying these OTPs.</p>
<blockquote>
<p>If you're new to PyOTP or would like a refresher on its functionalities, I recommend reviewing my previous <a target="_blank" href="https://blog.ashutoshkrris.in/how-to-generate-otps-using-pyotp-in-python">guide on PyOTP</a>. This understanding will be beneficial as we get into the integration of PyOTP within your Flask application for Two-Factor Authentication (2FA).</p>
</blockquote>
<p>Google Authenticator, on the other hand, stands out as one of the most widely used OTP generator apps available. It functions as a secure platform for generating time-based OTPs, compatible with various services and applications supporting 2FA. Users can easily set up Google Authenticator on their devices to generate these time-sensitive codes, adding an extra level of security to their accounts.</p>
<h2 id="heading-two-factor-authentication-workflow-in-our-application"><strong>Two-Factor Authentication Workflow in Our Application</strong></h2>
<p>Here's a breakdown of the flow of two-factor authentication in our application:</p>
<ol>
<li><p><strong>Registration with 2FA Setup</strong>: When users sign up on our website, they're prompted to set up an extra layer of security—2FA. This involves scanning a QR code using an authenticator app, such as Google Authenticator, to link their account securely.</p>
</li>
<li><p><strong>Login Initiation</strong>: When users return to log in, they start by entering their usual email/username and password combo to access their account.</p>
</li>
<li><p><strong>Extra Security Check</strong>: Before granting access, our website throws in an additional hurdle: users need to provide an OTP (One-Time Password) displayed on their authenticator app. This ensures they're not just entering the password but also confirming their identity with a unique, time-sensitive code.</p>
</li>
<li><p><strong>Validation and Authorization</strong>: The user inputs the received OTP into our platform. The system then double-checks this OTP against the expected code, validating the information. If the OTP matches, it's like handing over the secret handshake, granting the user access to their account.</p>
</li>
</ol>
<p>This seamless back-and-forth between passwords, authenticator apps, and unique codes ensures that only the rightful account owner can access the precious content behind the digital doors of your website.</p>
<p>If you also enjoy visual learning, here's a fancy video showing how the app does its thing.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/qzLcbq5-UNA">https://youtu.be/qzLcbq5-UNA</a></div>
<p> </p>
<p>Now, let's get to some coding!</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>Before you get started with the tutorial, make sure you have the following requirements satisfied:</p>
<ul>
<li><p>Working knowledge of Python</p>
</li>
<li><p>Python 3.8+ installed on your system</p>
</li>
<li><p>Basic knowledge of <a target="_blank" href="https://ashutoshkrris.hashnode.dev/getting-started-with-flask">Flask</a> and <a target="_blank" href="https://ashutoshkrris.hashnode.dev/how-to-use-blueprints-to-organize-your-flask-apps">Flask Blueprints</a></p>
</li>
<li><p>Knowledge of <a target="_blank" href="https://blog.ashutoshkrris.in/how-to-set-up-basic-user-authentication-in-a-flask-app">basic authentication in Flask</a> (optional)</p>
</li>
</ul>
<h2 id="heading-get-your-tools-ready"><strong>Get Your Tools Ready</strong></h2>
<p>You'll need a few external libraries for this project. Let's learn more about them and install them one by one.</p>
<p>But before we install them, let's create a virtual environment and activate it.</p>
<p>First, start with creating the project directory and navigating to it like this:</p>
<pre><code class="lang-bash">mkdir flask-two-factor-auth
<span class="hljs-built_in">cd</span> flask-two-factor-auth
</code></pre>
<p>We are going to create a virtual environment using <code>venv</code>. Python now ships with a pre-installed <code>venv</code> library. So, to create a virtual environment, you can use the below command:</p>
<pre><code class="lang-bash">python -m venv env
</code></pre>
<p>The above command will create a virtual environment named env. Now, we need to activate the environment using this command:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> env/Scripts/activate
</code></pre>
<p>To verify if the environment has been activated or not, you can see <code>(env)</code> in your terminal. Now, we can install the libraries.</p>
<ul>
<li><p><a target="_blank" href="https://flask.palletsprojects.com/en/2.2.x/">Flask</a> is a simple, easy-to-use microframework for Python that helps you build scalable and secure web applications.</p>
</li>
<li><p><a target="_blank" href="https://flask-login.readthedocs.io/en/latest/">Flask-Login</a> provides user session management for Flask. It handles the common tasks of logging in, logging out, and remembering your users’ sessions over extended periods.</p>
</li>
<li><p><a target="_blank" href="https://flask-bcrypt.readthedocs.io/en/1.0.1/">Flask-Bcrypt</a> is a Flask extension that provides bcrypt hashing utilities for your application.</p>
</li>
<li><p><a target="_blank" href="https://flask-wtf.readthedocs.io/en/1.0.x/">Flask-WTF</a> is a simple integration of Flask and WTForms that helps you create forms in Flask.</p>
</li>
<li><p><a target="_blank" href="https://flask-migrate.readthedocs.io/en/latest/">Flask-Migrate</a> is an extension that handles SQLAlchemy database migrations for Flask applications using Alembic. The database operations are made available through the Flask command-line interface.</p>
</li>
<li><p><a target="_blank" href="https://flask-sqlalchemy.palletsprojects.com/en/2.x/">Flask-SQLAlchemy</a> is an extension for Flask that adds support for SQLAlchemy to your application. It helps you simplify things using SQLAlchemy with Flask by giving you useful defaults and extra helpers that make it easier to perform common tasks.</p>
</li>
<li><p><a target="_blank" href="https://blog.ashutoshkrris.in/how-to-generate-otps-using-pyotp-in-python">PyOTP</a> helps you generate OTPs using Time-based OTP (TOTP) and HMAC-based OTP (HOTP) algorithms effortlessly.</p>
</li>
<li><p><a target="_blank" href="https://pypi.org/project/qrcode/">QRCode</a> helps you generate QR Codes in Python</p>
</li>
<li><p><a target="_blank" href="https://pypi.org/project/python-decouple/">Python Decouple</a> helps you use environment variables in your Python project.</p>
</li>
</ul>
<p>To install the above-mentioned libraries all in one go, run the following command:</p>
<pre><code class="lang-bash">pip install Flask Flask-Login Flask-Bcrypt Flask-WTF FLask-Migrate Flask-SQLAlchemy pyotp qrcode python-decouple
</code></pre>
<h2 id="heading-how-to-set-up-the-project"><strong>How to Set Up the Project</strong></h2>
<p>Let’s start by creating a <code>src</code> directory:</p>
<pre><code class="lang-bash">mkdir src
</code></pre>
<p>The first file will be the <code>__init__.py</code> file for the project:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> decouple <span class="hljs-keyword">import</span> config
<span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask
<span class="hljs-keyword">from</span> flask_bcrypt <span class="hljs-keyword">import</span> Bcrypt
<span class="hljs-keyword">from</span> flask_migrate <span class="hljs-keyword">import</span> Migrate
<span class="hljs-keyword">from</span> flask_sqlalchemy <span class="hljs-keyword">import</span> SQLAlchemy

app = Flask(__name__)
app.config.from_object(config(<span class="hljs-string">"APP_SETTINGS"</span>))

bcrypt = Bcrypt(app)
db = SQLAlchemy(app)
migrate = Migrate(app, db)

<span class="hljs-comment"># Registering blueprints</span>
<span class="hljs-keyword">from</span> src.accounts.views <span class="hljs-keyword">import</span> accounts_bp
<span class="hljs-keyword">from</span> src.core.views <span class="hljs-keyword">import</span> core_bp

app.register_blueprint(accounts_bp)
app.register_blueprint(core_bp)
</code></pre>
<p>In the above script, we created a Flask app called <code>app</code> . We use the <code>__name__</code> argument to indicate the app's module or package so that Flask knows where to find other files such as templates. We also set the configuration of the app using an environment variable called <code>APP_SETTINGS</code>. We'll export it later.</p>
<p>To use Flask-Bcrypt, Flask-SQLAlchemy, and Flask-Migrate in our application, we just need to create objects of the <code>Bcrypt</code>, <code>SQLAlchemy</code> and <code>Migrate</code> classes from the <code>flask_bcrypt</code>, <code>flask_sqlalchemy</code> and, <code>flask_migrate</code> libraries, respectively.</p>
<p>We've also registered blueprints called <code>accounts_bp</code> and <code>core_bp</code> in the application. We'll define them later in the tutorial.</p>
<p>In the root directory of the project (that is, outside the <code>src</code> directory), create a file called <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>config.py</code></a>. We'll store the configurations for the project in this file. Within the file, add the following content:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> decouple <span class="hljs-keyword">import</span> config

DATABASE_URI = config(<span class="hljs-string">"DATABASE_URL"</span>)
<span class="hljs-keyword">if</span> DATABASE_URI.startswith(<span class="hljs-string">"postgres://"</span>):
    DATABASE_URI = DATABASE_URI.replace(<span class="hljs-string">"postgres://"</span>, <span class="hljs-string">"postgresql://"</span>, <span class="hljs-number">1</span>)


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Config</span>(<span class="hljs-params">object</span>):</span>
    DEBUG = <span class="hljs-literal">False</span>
    TESTING = <span class="hljs-literal">False</span>
    CSRF_ENABLED = <span class="hljs-literal">True</span>
    SECRET_KEY = config(<span class="hljs-string">"SECRET_KEY"</span>, default=<span class="hljs-string">"guess-me"</span>)
    SQLALCHEMY_DATABASE_URI = DATABASE_URI
    SQLALCHEMY_TRACK_MODIFICATIONS = <span class="hljs-literal">False</span>
    BCRYPT_LOG_ROUNDS = <span class="hljs-number">13</span>
    WTF_CSRF_ENABLED = <span class="hljs-literal">True</span>
    DEBUG_TB_ENABLED = <span class="hljs-literal">False</span>
    DEBUG_TB_INTERCEPT_REDIRECTS = <span class="hljs-literal">False</span>
    APP_NAME = config(<span class="hljs-string">"APP_NAME"</span>)


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DevelopmentConfig</span>(<span class="hljs-params">Config</span>):</span>
    DEVELOPMENT = <span class="hljs-literal">True</span>
    DEBUG = <span class="hljs-literal">True</span>
    WTF_CSRF_ENABLED = <span class="hljs-literal">False</span>
    DEBUG_TB_ENABLED = <span class="hljs-literal">True</span>


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TestingConfig</span>(<span class="hljs-params">Config</span>):</span>
    TESTING = <span class="hljs-literal">True</span>
    DEBUG = <span class="hljs-literal">True</span>
    SQLALCHEMY_DATABASE_URI = <span class="hljs-string">"sqlite:///testdb.sqlite"</span>
    BCRYPT_LOG_ROUNDS = <span class="hljs-number">1</span>
    WTF_CSRF_ENABLED = <span class="hljs-literal">False</span>


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProductionConfig</span>(<span class="hljs-params">Config</span>):</span>
    DEBUG = <span class="hljs-literal">False</span>
    DEBUG_TB_ENABLED = <span class="hljs-literal">False</span>
</code></pre>
<p>In the above script, we have created a <code>Config</code> class and defined various attributes inside that. Also, we have created different child classes (as per different stages of development) that inherit the <code>Config</code> class.</p>
<p>Notice that we're using a few environment variables like <code>SECRET_KEY</code>, <code>DATABASE_URL</code>, and <code>APP_NAME</code>. Create a file named <code>.env</code> in the root directory and add the following content there:</p>
<pre><code class="lang-python">export SECRET_KEY=fdkjshfhjsdfdskfdsfdcbsjdkfdsdf
export DEBUG=<span class="hljs-literal">True</span>
export APP_SETTINGS=config.DevelopmentConfig
export DATABASE_URL=sqlite:///db.sqlite
export FLASK_APP=src
export FLASK_DEBUG=<span class="hljs-number">1</span>
export APP_NAME=<span class="hljs-string">"Flask User Authentication App"</span>
</code></pre>
<p>Apart from the <code>SECRET_KEY</code> , <code>DATABASE_URL</code> and <code>APP_NAME</code>, we've also exported <code>APP_SETTINGS</code>, <code>DEBUG</code>, <code>FLASK_APP</code>, and <code>FLASK_DEBUG</code>.</p>
<p>The <code>APP_SETTINGS</code> refers to one of the classes we created in the <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>config.py</code></a> file. We set it to the current stage of the project.</p>
<p>The value of <code>FLASK_APP</code> is the name of the package we have created. Since the app is in the development stage, you can set the values of <code>DEBUG</code> and <code>FLASK_DEBUG</code> to <code>True</code> and <code>1</code>, respectively.</p>
<p>Run the following command to export all the environment variables from the <code>.env</code> file:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> .env
</code></pre>
<p>Next, we'll create a CLI application of the app so that we can later add custom commands if required.</p>
<p>Create a <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>manage.py</code></a> file in the root directory of the application and add the following code:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask.cli <span class="hljs-keyword">import</span> FlaskGroup

<span class="hljs-keyword">from</span> src <span class="hljs-keyword">import</span> app

cli = FlaskGroup(app)


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    cli()
</code></pre>
<p>Now, your basic application is ready. You can run it using the following command:</p>
<pre><code class="lang-bash">python manage.py run
</code></pre>
<p>Your file structure should look like below as of now:</p>
<pre><code class="lang-bash">flask-two-factor-auth/
├── src/
│   └── __init__.py
├── .env
├── config.py
└── manage.py
</code></pre>
<h2 id="heading-how-to-create-blueprints-for-accounts-and-core"><strong>How to Create Blueprints for Accounts and Core</strong></h2>
<p>As mentioned earlier, you'll use the concepts of blueprints in the project. Let's create two blueprints – <code>accounts_bp</code> and <code>core_bp</code> – in this section.</p>
<p>First, create a directory called <code>accounts</code> like this:</p>
<pre><code class="lang-bash">mkdir accounts
<span class="hljs-built_in">cd</span> accounts
</code></pre>
<p>Next, add an empty <code>__init__.py</code> file to convert it into a Python package. Now, create a <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>views.py</code></a> file inside the package where you'll store all your routes related to user authentication.</p>
<pre><code class="lang-bash">touch __init__.py views.py
</code></pre>
<p>Add the following code to the <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>views.py</code></a> file:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Blueprint

accounts_bp = Blueprint(<span class="hljs-string">"accounts"</span>, __name__)
</code></pre>
<p>In the above script, you have created a blueprint called <code>accounts_bp</code> for the <code>accounts</code> package.</p>
<p>Similarly, you can create a <code>core</code> package in the root directory, and add a <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>views.py</code></a> file.</p>
<pre><code class="lang-bash">mkdir core
<span class="hljs-built_in">cd</span> core
touch __init__.py views.py
</code></pre>
<p>Now, add the following code to the <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>views.py</code></a> file:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Blueprint

core_bp = Blueprint(<span class="hljs-string">"core"</span>, __name__)
</code></pre>
<blockquote>
<p>Note: If you're new to Flask Blueprints, make sure you go through <a target="_blank" href="https://ashutoshkrris.hashnode.dev/how-to-use-blueprints-to-organize-your-flask-apps">this tutorial</a> to learn more about how it works.</p>
</blockquote>
<p>Now, your file structure should look like what you see below:</p>
<pre><code class="lang-bash">flask-two-factor-auth/
├── src/
│   ├── accounts/
│   │   ├── __init__.py
│   │   └── views.py
│   ├── core/
│   │   ├── __init__.py
│   │   └── views.py
│   └── __init__.py
├── .env
├── config.py
└── manage.py
</code></pre>
<h2 id="heading-how-to-create-a-user-model"><strong>How to Create a User Model</strong></h2>
<p>Let's create a <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>models.py</code></a> file inside the <code>accounts</code> package.</p>
<pre><code class="lang-bash">touch src/accounts/models.py
</code></pre>
<p>Inside the <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>models.py</code></a> file, add the following code:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime

<span class="hljs-keyword">import</span> pyotp
<span class="hljs-keyword">from</span> flask_login <span class="hljs-keyword">import</span> UserMixin

<span class="hljs-keyword">from</span> src <span class="hljs-keyword">import</span> bcrypt, db
<span class="hljs-keyword">from</span> config <span class="hljs-keyword">import</span> Config


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span>(<span class="hljs-params">db.Model</span>):</span>

    __tablename__ = <span class="hljs-string">"users"</span>

    id = db.Column(db.Integer, primary_key=<span class="hljs-literal">True</span>)
    username = db.Column(db.String, unique=<span class="hljs-literal">True</span>, nullable=<span class="hljs-literal">False</span>)
    password = db.Column(db.String, nullable=<span class="hljs-literal">False</span>)
    created_at = db.Column(db.DateTime, nullable=<span class="hljs-literal">False</span>)
    is_two_factor_authentication_enabled = db.Column(
        db.Boolean, nullable=<span class="hljs-literal">False</span>, default=<span class="hljs-literal">False</span>)
    secret_token = db.Column(db.String, unique=<span class="hljs-literal">True</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, username, password</span>):</span>
        self.username = username
        self.password = bcrypt.generate_password_hash(password)
        self.created_at = datetime.now()
        self.secret_token = pyotp.random_base32()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_authentication_setup_uri</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> pyotp.totp.TOTP(self.secret_token).provisioning_uri(
            name=self.username, issuer_name=Config.APP_NAME)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_otp_valid</span>(<span class="hljs-params">self, user_otp</span>):</span>
        totp = pyotp.parse_uri(self.get_authentication_setup_uri())
        <span class="hljs-keyword">return</span> totp.verify(user_otp)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__repr__</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">f"&lt;user <span class="hljs-subst">{self.username}</span>&gt;"</span>
</code></pre>
<p>In the above code, you created a <code>User</code> model by inheriting the <code>db.Model</code> class. The <code>User</code> model consists of the following fields:</p>
<ul>
<li><p><code>id</code>: stores the primary key for the <code>users</code> table</p>
</li>
<li><p><code>username</code>: stores the username of the user</p>
</li>
<li><p><code>password</code>: stores the hashed password of the user</p>
</li>
<li><p><code>created_at</code>: stores the timestamp when the user was created</p>
</li>
<li><p><code>is_two_factor_authentication_enabled</code>: boolean flag that stores whether the user has activated two-factor authentication. Default value is <code>False</code>.</p>
</li>
<li><p><code>secret_token</code>: stores a unique token generated for each user, essential for implementing two-factor authentication.</p>
</li>
</ul>
<p>The constructor initializes the <code>User</code> object upon instantiation by accepting <code>username</code> and <code>password</code> parameters. It hashes the provided password using <code>bcrypt.generate_password_hash(password)</code>, records the current timestamp as the <code>created_at</code> value, and generates a unique <code>secret_token</code> using <code>pyotp.random_base32()</code> for 2FA setup.</p>
<p>The <code>get_authentication_setup_uri()</code> method generates a setup URI used by authenticator apps like Google Authenticator. It constructs a URI containing the user's username and the application's name (<a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>Config.APP</code></a><code>_NAME</code>) necessary for setting up two-factor authentication. The basic format of the URI is:</p>
<pre><code class="lang-bash">otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&amp;issuer=Example
</code></pre>
<p>where <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator">alice@google.com</a> is the username of the user and Example is the application's name.</p>
<p>Next up, the <code>is_otp_valid()</code> method verifies the one-time password (OTP) entered by the user during login. It parses the setup URI generated earlier, checks the validity of the provided OTP (<code>user_otp</code>), and returns <code>True</code> if the OTP matches, ensuring secure authentication.</p>
<p>Finally, the <code>__repr__</code> method provides a string representation of the <code>User</code> object, displaying the associated username when an instance of the class is printed or represented as a string.</p>
<h2 id="heading-how-to-add-flask-login"><strong>How to Add Flask-Login</strong></h2>
<p>The most important part of Flask-Login is the <code>LoginManager</code> class that lets your application and Flask-Login work together.</p>
<p>In the <code>src/__init__.py</code> file, add the following code:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> decouple <span class="hljs-keyword">import</span> config
<span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask
<span class="hljs-keyword">from</span> flask_login <span class="hljs-keyword">import</span> LoginManager <span class="hljs-comment"># Add this line</span>
<span class="hljs-keyword">from</span> flask_migrate <span class="hljs-keyword">import</span> Migrate
<span class="hljs-keyword">from</span> flask_sqlalchemy <span class="hljs-keyword">import</span> SQLAlchemy

app = Flask(__name__)
app.config.from_object(config(<span class="hljs-string">"APP_SETTINGS"</span>))

login_manager = LoginManager() <span class="hljs-comment"># Add this line</span>
login_manager.init_app(app) <span class="hljs-comment"># Add this line</span>
db = SQLAlchemy(app)
migrate = Migrate(app, db)

<span class="hljs-comment"># Registering blueprints</span>
<span class="hljs-keyword">from</span> src.accounts.views <span class="hljs-keyword">import</span> accounts_bp
<span class="hljs-keyword">from</span> src.core.views <span class="hljs-keyword">import</span> core_bp

app.register_blueprint(accounts_bp)
app.register_blueprint(core_bp)
</code></pre>
<p>In the above script, we created and initialized the login manager in our app.</p>
<p>Next, we need to provide a <code>user_loader</code> callback. This callback is used to reload the user object from the user ID stored in the session. It should take the ID of a user, and return the corresponding user object.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> src.accounts.models <span class="hljs-keyword">import</span> User

<span class="hljs-meta">@login_manager.user_loader</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">load_user</span>(<span class="hljs-params">user_id</span>):</span>
    <span class="hljs-keyword">return</span> User.query.filter(User.id == int(user_id)).first()
</code></pre>
<p>The <code>User</code> model should implement the following properties and methods:</p>
<ul>
<li><p><code>is_authenticated</code>: This property returns True if the user is authenticated.</p>
</li>
<li><p><code>is_active</code>: This property returns True if this is an active user (the account is activated)</p>
</li>
<li><p><code>is_anonymous</code>: This property returns True if this is an anonymous user (actual users return False).</p>
</li>
<li><p><code>get_id()</code>: This method returns a string that uniquely identifies this user, and can be used to load the user from the <code>user_loader</code> callback.</p>
</li>
</ul>
<p>Now, we don't need to implement these explicitly. Instead, the Flask-Login provides a <code>UserMixin</code> class that contains the default implementations for all of these properties and methods. We just need to inherit it in the following way:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime

<span class="hljs-keyword">from</span> flask_login <span class="hljs-keyword">import</span> UserMixin <span class="hljs-comment"># Add this line</span>

<span class="hljs-keyword">from</span> src <span class="hljs-keyword">import</span> bcrypt, db


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span>(<span class="hljs-params">UserMixin, db.Model</span>):</span> <span class="hljs-comment"># Change this line</span>
    ....
</code></pre>
<p>We can also customize the default login process in the <code>src/__init__.py</code> file.</p>
<p>The name of the login view can be set as <code>LoginManager.login_view</code>. The value refers to the function name that will handle the login process.</p>
<pre><code class="lang-python">login_manager.login_view = <span class="hljs-string">"accounts.login"</span>
</code></pre>
<p>To customize the message category, set <code>LoginManager.login_message_category</code>:</p>
<pre><code class="lang-python">login_manager.login_message_category = <span class="hljs-string">"danger"</span>
</code></pre>
<h2 id="heading-how-to-add-templates-and-static-files"><strong>How to Add Templates and Static Files</strong></h2>
<p>Let's create a CSS file called <code>styles.css</code> inside the <code>src/static</code> folder:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.error</span> {
  <span class="hljs-attribute">color</span>: red;
  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">5px</span>;
  <span class="hljs-attribute">text-align</span>: center;
}

<span class="hljs-selector-tag">a</span> {
  <span class="hljs-attribute">text-decoration</span>: none;
}
</code></pre>
<p>Let's also create the basic templates inside the <code>src/templates</code> folder. Create a <code>_base.html</code> file and add the following code:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Two Factor Authentication<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- meta --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">""</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"author"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">""</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width,initial-scale=1"</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- styles --&gt;</span>
    <span class="hljs-comment">&lt;!-- CSS only --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"</span> <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{url_for('static', filename="</span><span class="hljs-attr">styles.css</span>")}}"&gt;</span>
    {% block css %}{% endblock %}
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>

    {% include "navigation.html" %}

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>

      <span class="hljs-comment">&lt;!-- messages --&gt;</span>
      {% with messages = get_flashed_messages(with_categories=true) %}
      {% if messages %}
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span>
          {% for category, message in messages %}
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"alert alert-{{ category }} alert-dismissible fade show"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"alert"</span>&gt;</span>
           {{message}}
           <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn-close"</span> <span class="hljs-attr">data-bs-dismiss</span>=<span class="hljs-string">"alert"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Close"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
          {% endfor %}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      {% endif %}
      {% endwith %}

      <span class="hljs-comment">&lt;!-- child template --&gt;</span>
      {% block content %}{% endblock %}

    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-comment">&lt;!-- scripts --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://code.jquery.com/jquery-3.7.1.min.js"</span> <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="</span> <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- JavaScript Bundle with Popper --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"</span> <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r"</span> <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js"</span> <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+"</span> <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    {% block js %}{% endblock %}
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The <code>_base.html</code> is the parent HTML file that will be inherited by the other templates. We have added Bootstrap 5 support in the above file. We are also making use of Flask Flashes to show Bootstrap alerts in the app.</p>
<p>Let's also create a <code>navigation.html</code> file that contains the navbar of the app:</p>
<pre><code class="lang-html"><span class="hljs-comment">&lt;!-- Navigation --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">nav</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"navbar bg-dark navbar-expand-lg bg-body-tertiary p-3"</span> <span class="hljs-attr">data-bs-theme</span>=<span class="hljs-string">"dark"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container-fluid"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"navbar-brand"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ url_for('core.home') }}"</span>&gt;</span>Two-Factor Authentication App<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"navbar-toggler"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">data-bs-toggle</span>=<span class="hljs-string">"collapse"</span> <span class="hljs-attr">data-bs-target</span>=<span class="hljs-string">"#navbarSupportedContent"</span> <span class="hljs-attr">aria-controls</span>=<span class="hljs-string">"navbarSupportedContent"</span> <span class="hljs-attr">aria-expanded</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Toggle navigation"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"navbar-toggler-icon"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"collapse navbar-collapse"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"navbarSupportedContent"</span>&gt;</span>
      {% if current_user.is_authenticated %}
      <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ url_for('accounts.logout') }}"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-danger me-2"</span>&gt;</span>Logout<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
      {% endif %}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
</code></pre>
<p>Note that we have not yet created the views used above.</p>
<h2 id="heading-how-to-create-the-homepage"><strong>How to Create the Homepage</strong></h2>
<p>In this section, we'll first create a view function for the homepage inside the <code>core/</code><a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>views.py</code></a> file. Add the following code there:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Blueprint, render_template
<span class="hljs-keyword">from</span> flask_login <span class="hljs-keyword">import</span> login_required

core_bp = Blueprint(<span class="hljs-string">"core"</span>, __name__)


<span class="hljs-meta">@core_bp.route("/")</span>
<span class="hljs-meta">@login_required</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">home</span>():</span>
    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"core/index.html"</span>)
</code></pre>
<p>Notice that we have used the blueprint to add the route. We also added a <code>@login_required</code> middleware to prevent access for unauthenticated users.</p>
<p>Next, let's create an <code>index.html</code> file inside the <code>templates/core</code> folder, and add the following code:</p>
<pre><code class="lang-html">{% extends "_base.html" %}
{% block content %}

<span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-center"</span>&gt;</span>Welcome {{current_user.username}}!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

{% endblock %}
</code></pre>
<p>The HTML page will just have a welcome message for authenticated users.</p>
<p>Your file structure as of now should look like below:</p>
<pre><code class="lang-bash">flask-two-factor-auth/
├── src/
│   ├── accounts/
│   │   ├── __init__.py
│   │   └── views.py
│   ├── core/
│   │   ├── __init__.py
│   │   └── views.py
│   ├── static/
│   │   └── styles.css
│   ├── templates/
│   │   ├── core/
│   │   │   └── index.html
│   │   ├── _base.html
│   │   └── navigation.html
│   └── __init__.py
├── .env
├── config.py
└── manage.py
</code></pre>
<h2 id="heading-how-to-implement-user-registration"><strong>How to Implement User Registration</strong></h2>
<p>First of all, we'll create a registration form using Flask-WTF. Create a <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>forms.py</code></a> file inside the <code>accounts</code> package and add the following code:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask_wtf <span class="hljs-keyword">import</span> FlaskForm
<span class="hljs-keyword">from</span> wtforms <span class="hljs-keyword">import</span> EmailField, PasswordField
<span class="hljs-keyword">from</span> wtforms.validators <span class="hljs-keyword">import</span> DataRequired, Email, EqualTo, Length

<span class="hljs-keyword">from</span> src.accounts.models <span class="hljs-keyword">import</span> User


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RegisterForm</span>(<span class="hljs-params">FlaskForm</span>):</span>
    username = StringField(
        <span class="hljs-string">"Username"</span>, validators=[DataRequired(), Length(min=<span class="hljs-number">6</span>, max=<span class="hljs-number">40</span>)]
    )
    password = PasswordField(
        <span class="hljs-string">"Password"</span>, validators=[DataRequired(), Length(min=<span class="hljs-number">6</span>, max=<span class="hljs-number">25</span>)]
    )
    confirm = PasswordField(
        <span class="hljs-string">"Repeat password"</span>,
        validators=[
            DataRequired(),
            EqualTo(<span class="hljs-string">"password"</span>, message=<span class="hljs-string">"Passwords must match."</span>),
        ],
    )

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">validate</span>(<span class="hljs-params">self, extra_validators</span>):</span>
        initial_validation = super(RegisterForm, self).validate(extra_validators)
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> initial_validation:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
        user = User.query.filter_by(username=self.username.data).first()
        <span class="hljs-keyword">if</span> user:
            self.username.errors.append(<span class="hljs-string">"Username already registered"</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
        <span class="hljs-keyword">if</span> self.password.data != self.confirm.data:
            self.password.errors.append(<span class="hljs-string">"Passwords must match"</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
        <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre>
<p>The <code>RegisterForm</code> extends the <code>FlaskForm</code> class and contains three fields – <code>username</code>, <code>password</code>, and <code>confirm</code>. We have added different validators such as <code>DataRequired</code>, <code>Length</code>, <code>Email</code>, and <code>EqualTo</code> to the respective fields.</p>
<p>We also defined a <code>validate()</code> method that is automatically called when the form is submitted.</p>
<p>Inside the method, we first perform the initial validation provided by FlaskForm. If that is successful, we perform our custom validation such as checking whether user is already registered and matching the password with the confirmed password. If there are any errors, we append the error message in the respective fields.</p>
<p>Now, let's use this form inside the HTML file. Create an <code>accounts</code> directory inside the <code>templates</code> folder and add a new file called <code>register.html</code> inside it. Add the following code:</p>
<pre><code class="lang-html">{% extends "_base.html" %}

{% block content %}

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-signin w-100 m-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"form"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span>&gt;</span>
        {{ form.csrf_token }}
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"h3 mb-3 fw-normal text-center"</span>&gt;</span>Please register<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-floating"</span>&gt;</span>
          {{ form.username(placeholder="username", class="form-control mb-2") }}
          {{ form.username.label }}
            {% if form.username.errors %}
              {% for error in form.username.errors %}
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"alert alert-danger"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"alert"</span>&gt;</span>
                  {{ error }}
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
              {% endfor %}
            {% endif %}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-floating"</span>&gt;</span>
          {{ form.password(placeholder="password", class="form-control mb-2") }}
          {{ form.password.label }}
            {% if form.password.errors %}
              {% for error in form.password.errors %}
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"alert alert-danger"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"alert"</span>&gt;</span>
                  {{ error }}
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
              {% endfor %}
            {% endif %}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-floating"</span>&gt;</span>
          {{ form.confirm(placeholder="Confirm Password", class="form-control mb-2") }}
          {{ form.confirm.label }}
            {% if form.confirm.errors %}
              {% for error in form.confirm.errors %}
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"alert alert-danger"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"alert"</span>&gt;</span>
                  {{ error }}
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
              {% endfor %}
            {% endif %}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-100 btn btn-lg btn-primary"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Sign up<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-center mt-3"</span>&gt;</span>Already registered? <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ url_for('accounts.login') }}"</span>&gt;</span>Login now<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

{% endblock %}
</code></pre>
<p>In the above Jinja template, we make use of the form that we created and add relevant error-handling logic checks for validation errors in each field. Users can submit the form by clicking the "Sign up" button, and a link below the form allows already registered users to navigate to the login page for authentication.</p>
<p>Next, let's use this form in the <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>views.py</code></a> to create a function to handle the registration process.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> .forms <span class="hljs-keyword">import</span> RegisterForm
<span class="hljs-keyword">from</span> src.accounts.models <span class="hljs-keyword">import</span> User
<span class="hljs-keyword">from</span> src <span class="hljs-keyword">import</span> db, bcrypt
<span class="hljs-keyword">from</span> flask_login <span class="hljs-keyword">import</span> current_user
<span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Blueprint, flash, redirect, render_template, request, url_for

accounts_bp = Blueprint(<span class="hljs-string">"accounts"</span>, __name__)

HOME_URL = <span class="hljs-string">"core.home"</span>
SETUP_2FA_URL = <span class="hljs-string">"accounts.setup_two_factor_auth"</span>
VERIFY_2FA_URL = <span class="hljs-string">"accounts.verify_two_factor_auth"</span>

<span class="hljs-meta">@accounts_bp.route("/register", methods=["GET", "POST"])</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">register</span>():</span>
    <span class="hljs-keyword">if</span> current_user.is_authenticated:
        <span class="hljs-keyword">if</span> current_user.is_two_factor_authentication_enabled:
            flash(<span class="hljs-string">"You are already registered."</span>, <span class="hljs-string">"info"</span>)
            <span class="hljs-keyword">return</span> redirect(url_for(HOME_URL))
        <span class="hljs-keyword">else</span>:
            flash(<span class="hljs-string">"You have not enabled 2-Factor Authentication. Please enable first to login."</span>, <span class="hljs-string">"info"</span>)
            <span class="hljs-keyword">return</span> redirect(url_for(SETUP_2FA_URL))
    form = RegisterForm(request.form)
    <span class="hljs-keyword">if</span> form.validate_on_submit():
        <span class="hljs-keyword">try</span>:
            user = User(username=form.username.data, password=form.password.data)
            db.session.add(user)
            db.session.commit()

            login_user(user)
            flash(<span class="hljs-string">"You are registered. You have to enable 2-Factor Authentication first to login."</span>, <span class="hljs-string">"success"</span>)

            <span class="hljs-keyword">return</span> redirect(url_for(SETUP_2FA_URL))
        <span class="hljs-keyword">except</span> Exception:
            db.session.rollback()
            flash(<span class="hljs-string">"Registration failed. Please try again."</span>, <span class="hljs-string">"danger"</span>)

    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"accounts/register.html"</span>, form=form)
</code></pre>
<p>The route begins by checking if the current user is already authenticated. If so, it verifies whether 2FA is enabled for the user. If 2FA is already enabled, a message informs the user that they're already registered, redirecting them to the home URL. However, if the user is authenticated but 2FA is not enabled, a flash message prompts the user to enable 2FA first before logging in, redirecting them to the 2FA setup URL.</p>
<p>If the user is not authenticated or has not yet registered 2FA, the code initializes a registration form and proceeds to validate the form data on submission. Upon successful form validation, we create a new <code>User</code> object with the provided username and password and save it to the database.</p>
<p>Upon successful user registration, the newly registered user is logged in. A success message flashes, notifying the user of successful registration and prompting them to enable 2FA before logging in. Subsequently, the user is redirected to the 2FA setup URL to enable 2FA.</p>
<h2 id="heading-how-to-implement-user-login"><strong>How to Implement User Login</strong></h2>
<p>First, let's create a login form in the <code>accounts/</code><a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>forms.py</code></a> file:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LoginForm</span>(<span class="hljs-params">FlaskForm</span>):</span>
    username = StringField(<span class="hljs-string">"Username"</span>, validators=[DataRequired()])
    password = PasswordField(<span class="hljs-string">"Password"</span>, validators=[DataRequired()])
</code></pre>
<p>The form is similar to the registration form but it has only two fields – <code>username</code> and <code>password</code>.</p>
<p>Now, let's use this form inside a new HTML file called <code>login.html</code> created inside the <code>templates/accounts</code> directory. Add the following code:</p>
<pre><code class="lang-html">{% extends "_base.html" %}

{% block content %}

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-signin w-100 m-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"form"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span>&gt;</span>
        {{ form.csrf_token }}
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"h3 mb-3 fw-normal text-center"</span>&gt;</span>Please sign in<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-floating"</span>&gt;</span>
          {{ form.username(placeholder="username", class="form-control mb-2") }}
          {{ form.username.label }}
            {% if form.username.errors %}
              {% for error in form.username.errors %}
              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"alert alert-danger"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"alert"</span>&gt;</span>
                {{ error }}
              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
              {% endfor %}
            {% endif %}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-floating"</span>&gt;</span>
          {{ form.password(placeholder="password", class="form-control mb-2") }}
          {{ form.password.label }}
            {% if form.password.errors %}
              {% for error in form.password.errors %}
                <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"alert alert-danger"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"alert"</span>&gt;</span>
                  {{ error }}
                <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
              {% endfor %}
            {% endif %}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-100 btn btn-lg btn-primary"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Sign in<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-center mt-3"</span>&gt;</span>New User? <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ url_for('accounts.register') }}"</span>&gt;</span>Register now<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

{% endblock %}
</code></pre>
<p>The above HTML file is also similar to the <code>register.html</code> file but with just two fields for the username and password.</p>
<p>Next, let's create a view function to handle the login process inside the <code>accounts/</code><a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>views.py</code></a> file:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> .forms <span class="hljs-keyword">import</span> LoginForm, RegisterForm

<span class="hljs-meta">@accounts_bp.route("/login", methods=["GET", "POST"])</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">login</span>():</span>
    <span class="hljs-keyword">if</span> current_user.is_authenticated:
        <span class="hljs-keyword">if</span> current_user.is_two_factor_authentication_enabled:
            flash(<span class="hljs-string">"You are already logged in."</span>, <span class="hljs-string">"info"</span>)
            <span class="hljs-keyword">return</span> redirect(url_for(HOME_URL))
        <span class="hljs-keyword">else</span>:
            flash(<span class="hljs-string">"You have not enabled 2-Factor Authentication. Please enable first to login."</span>, <span class="hljs-string">"info"</span>)
            <span class="hljs-keyword">return</span> redirect(url_for(SETUP_2FA_URL))

    form = LoginForm(request.form)
    <span class="hljs-keyword">if</span> form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        <span class="hljs-keyword">if</span> user <span class="hljs-keyword">and</span> bcrypt.check_password_hash(user.password, request.form[<span class="hljs-string">"password"</span>]):
            login_user(user)
            <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> current_user.is_two_factor_authentication_enabled:
                flash(
                    <span class="hljs-string">"You have not enabled 2-Factor Authentication. Please enable first to login."</span>, <span class="hljs-string">"info"</span>)
                <span class="hljs-keyword">return</span> redirect(url_for(SETUP_2FA_URL))
            <span class="hljs-keyword">return</span> redirect(url_for(VERIFY_2FA_URL))
        <span class="hljs-keyword">elif</span> <span class="hljs-keyword">not</span> user:
            flash(<span class="hljs-string">"You are not registered. Please register."</span>, <span class="hljs-string">"danger"</span>)
        <span class="hljs-keyword">else</span>:
            flash(<span class="hljs-string">"Invalid username and/or password."</span>, <span class="hljs-string">"danger"</span>)
    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"accounts/login.html"</span>, form=form)
</code></pre>
<p>The route starts by checking if the current user is already authenticated. If the user is authenticated and 2FA is enabled, a message informs the user they're already logged in, redirecting them to the home URL. If the user is authenticated but 2FA isn't enabled, a flash message prompts the user to enable 2FA before logging in, redirecting them to the 2FA setup URL.</p>
<p>If the user isn't authenticated, the code initializes a login form and validates the form data upon submission. Upon successful validation, it queries the database to find a user matching the provided username. If the user exists and the password matches the hashed password stored in the database, the user is logged in.</p>
<p>Additionally, if 2FA isn't enabled for the current user after successful login, a flash message prompts the user to enable 2FA before proceeding, redirecting them to the 2FA setup URL. If the login is successful and 2FA is enabled, the user is redirected to the 2FA verification URL.</p>
<p>If the user isn't registered, a flash message informs them to register. If there's a mismatch in the provided username or password, another flash message notifies the user of invalid credentials.</p>
<h2 id="heading-how-to-log-out-the-users"><strong>How to Log Out the Users</strong></h2>
<p>Logging out the user is a very simple process. You just need to create a view function for it inside the <code>accounts/</code><a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>views.py</code></a> file:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask_login <span class="hljs-keyword">import</span> login_required, login_user, logout_user


<span class="hljs-meta">@accounts_bp.route("/logout")</span>
<span class="hljs-meta">@login_required</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logout</span>():</span>
    logout_user()
    flash(<span class="hljs-string">"You were logged out."</span>, <span class="hljs-string">"success"</span>)
    <span class="hljs-keyword">return</span> redirect(url_for(<span class="hljs-string">"accounts.login"</span>))
</code></pre>
<p>The <code>Flask-Login</code> library contains a <code>logout_user</code> method that removes the user from the session. We used the <code>@login_required</code> decorator so that only authenticated users could logout.</p>
<h2 id="heading-how-to-add-the-setup-2fa-page"><strong>How to Add the Setup 2FA Page</strong></h2>
<p>Up until now, we have been redirecting the users to the setup 2FA page whenever the 2FA is not enabled in their accounts, but we haven't implemented it yet. Let's do that in this section.</p>
<p>Let's start with the route for the page:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> src.utils <span class="hljs-keyword">import</span> get_b64encoded_qr_image

<span class="hljs-meta">@accounts_bp.route("/setup-2fa")</span>
<span class="hljs-meta">@login_required</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">setup_two_factor_auth</span>():</span>
    secret = current_user.secret_token
    uri = current_user.get_authentication_setup_uri()
    base64_qr_image = get_b64encoded_qr_image(uri)
    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"accounts/setup-2fa.html"</span>, secret=secret, qr_image=base64_qr_image)
</code></pre>
<p>The route, created inside <code>accounts/</code><a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>views.py</code></a>, ensures that only authenticated users can access it using the <code>@login_required</code> decorator.</p>
<p>Upon accessing this route, the function retrieves the current user's <code>secret_token</code> for 2FA setup and generates a URI through <code>current_user.get_authentication_setup_uri()</code> to configure an authenticator app like Google Authenticator.</p>
<p>It also uses <code>get_b64encoded_qr_image(uri)</code> to obtain a Base64-encoded QR code image representing this setup URI. We will define it below.</p>
<p>Finally, it renders the <code>setup-2fa.html</code> template, passing the user's <code>secret_token</code> and the Base64-encoded QR image to the template for users to scan it.</p>
<p>Next, create a <a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>utils.py</code></a> file in the <code>src</code> directory and add the following code to <a target="_blank" href="https://blog.ashutoshkrris.in/5-quick-python-projects#heading-qr-codes-in-python">generate the QR</a>:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> io <span class="hljs-keyword">import</span> BytesIO
<span class="hljs-keyword">import</span> qrcode
<span class="hljs-keyword">from</span> base64 <span class="hljs-keyword">import</span> b64encode


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_b64encoded_qr_image</span>(<span class="hljs-params">data</span>):</span>
    print(data)
    qr = qrcode.QRCode(version=<span class="hljs-number">1</span>, box_size=<span class="hljs-number">10</span>, border=<span class="hljs-number">5</span>)
    qr.add_data(data)
    qr.make(fit=<span class="hljs-literal">True</span>)
    img = qr.make_image(fill_color=<span class="hljs-string">'black'</span>, back_color=<span class="hljs-string">'white'</span>)
    buffered = BytesIO()
    img.save(buffered)
    <span class="hljs-keyword">return</span> b64encode(buffered.getvalue()).decode(<span class="hljs-string">"utf-8"</span>)
</code></pre>
<p>Remember the <code>qrcode</code> library we installed at the beginning of the tutorial? This is where we're going to use it.</p>
<p>Upon receiving <code>data</code> as input, representing the content to be embedded within the QR code, the function initializes a QRCode object using the <code>qrcode</code> library. It adds the provided data to this QR code instance and generates the QR code. The code then converts this QR code into an image representation.</p>
<p>Using a BytesIO object, it stores this image in memory. The function proceeds to encode the content of this in-memory buffer, representing the QR code image, into Base64 format. Finally, it returns this Base64-encoded string, encapsulating the QR code image, ready for transmission or display in various applications.</p>
<p>Next, let's create the <code>setup-2fa.html</code> page inside the <code>templates/accounts</code> folder, and add the following content:</p>
<pre><code class="lang-html">{% extends "_base.html" %}

{% block content %}

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-signin w-100 m-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"form"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h5</span>&gt;</span>Instructions!<span class="hljs-tag">&lt;/<span class="hljs-name">h5</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Download <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&amp;hl=en&amp;gl=US"</span> <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span>&gt;</span>Google Authenticator<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> on your mobile.<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Set up a new authenticator.<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Once you have scanned the QR, please click <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ url_for('accounts.verify_two_factor_auth') }}"</span>&gt;</span>here.<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-center"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"data:image/png;base64, {{ qr_image }}"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Secret Token"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width:200px;height:200px"</span>/&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"secret"</span>&gt;</span>Secret Token<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-control"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"secret"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"{{ secret }}"</span> <span class="hljs-attr">readonly</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-center mt-2"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-primary"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"copySecret()"</span>&gt;</span>
            Copy Secret
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mt-4 text-center"</span>&gt;</span>
          Once you have scanned the QR, please click <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"{{ url_for('accounts.verify_two_factor_auth') }}"</span>&gt;</span>here<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>.
        <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

{% endblock %}

{% block js %}
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">copySecret</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> copyText = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"secret"</span>);
    copyText.select();
    copyText.setSelectionRange(<span class="hljs-number">0</span>, <span class="hljs-number">99999</span>); <span class="hljs-comment">/*For mobile devices*/</span>
    <span class="hljs-built_in">document</span>.execCommand(<span class="hljs-string">"copy"</span>);
    alert(<span class="hljs-string">"Successfully copied TOTP secret token!"</span>);
  }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
{% endblock %}
</code></pre>
<p>We added some instructions on the page for the users to follow. These instructions provide clear steps for users to enable 2FA: directing them to download the Google Authenticator app via a link, guiding the setup process within the app, and prompting users to proceed by clicking a link after scanning the displayed QR code.</p>
<p>Displaying the QR code is central to the setup process. The template embeds the QR code image using an <code>&lt;img&gt;</code> tag with its source set to a Base64-encoded string (<code>{{ qr_image }}</code>). This image represents the secret key essential for the 2FA setup.</p>
<p>We also show the secret key in read-only mode, allowing users to view the key without being able to modify it. We have added a copy button to make it easier for the users to copy the key.</p>
<p>Moreover, we have added a link to the 2FA verification page guiding users to proceed with the setup process after scanning the QR code. We will implement this functionality in the next section.</p>
<p>Here's how your page looks right now:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-26-010925.png" alt="2FA Setup Page" /></p>
<h2 id="heading-how-to-add-a-2fa-verification-page"><strong>How to Add a 2FA Verification Page</strong></h2>
<p>In this section, let's implement the 2FA verification. To start with, we will require an OTP form where users can enter their OTP. Add the following content to the <code>accounts/</code><a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>forms.py</code></a> file:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TwoFactorForm</span>(<span class="hljs-params">FlaskForm</span>):</span>
    otp = StringField(<span class="hljs-string">'Enter OTP'</span>, validators=[
                      InputRequired(), Length(min=<span class="hljs-number">6</span>, max=<span class="hljs-number">6</span>)])
</code></pre>
<p>The <code>TwoFactorForm</code> contains just one field (<code>otp</code>) to get the OTP from the users.</p>
<p>Now, let's use this form in the <code>verify-2fa.html</code> file inside the <code>templates/accounts</code> folder:</p>
<pre><code class="lang-html">{% extends "_base.html" %}

{% block content %}

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-signin w-100 m-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"form"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-attr">action</span>=<span class="hljs-string">""</span>&gt;</span>
        {{ form.csrf_token }}
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"h3 mb-3 fw-normal text-center"</span>&gt;</span>Enter OTP<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-floating"</span>&gt;</span>
          {{ form.otp(placeholder="OTP", class="form-control mb-2") }}
          {{ form.otp.label }}
            {% if form.otp.errors %}
              {% for error in form.otp.errors %}
              <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"alert alert-danger"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"alert"</span>&gt;</span>
                {{ error }}
              <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
              {% endfor %}
            {% endif %}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-100 btn btn-lg btn-primary"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Verify<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-md-4"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

{% endblock %}
</code></pre>
<p>The Jinja template essentially contains a form with one field for OTP and a verify button.</p>
<p>Let's create the route that handles the submission of this form inside the <code>accounts/</code><a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>views.py</code></a> file:</p>
<pre><code class="lang-python"><span class="hljs-meta">@accounts_bp.route("/verify-2fa", methods=["GET", "POST"])</span>
<span class="hljs-meta">@login_required</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">verify_two_factor_auth</span>():</span>
    form = TwoFactorForm(request.form)
    <span class="hljs-keyword">if</span> form.validate_on_submit():
        <span class="hljs-keyword">if</span> current_user.is_otp_valid(form.otp.data):
            <span class="hljs-keyword">if</span> current_user.is_two_factor_authentication_enabled:
                flash(<span class="hljs-string">"2FA verification successful. You are logged in!"</span>, <span class="hljs-string">"success"</span>)
                <span class="hljs-keyword">return</span> redirect(url_for(HOME_URL))
            <span class="hljs-keyword">else</span>:
                <span class="hljs-keyword">try</span>:
                    current_user.is_two_factor_authentication_enabled = <span class="hljs-literal">True</span>
                    db.session.commit()
                    flash(<span class="hljs-string">"2FA setup successful. You are logged in!"</span>, <span class="hljs-string">"success"</span>)
                    <span class="hljs-keyword">return</span> redirect(url_for(HOME_URL))
                <span class="hljs-keyword">except</span> Exception:
                    db.session.rollback()
                    flash(<span class="hljs-string">"2FA setup failed. Please try again."</span>, <span class="hljs-string">"danger"</span>)
                    <span class="hljs-keyword">return</span> redirect(url_for(VERIFY_2FA_URL))
        <span class="hljs-keyword">else</span>:
            flash(<span class="hljs-string">"Invalid OTP. Please try again."</span>, <span class="hljs-string">"danger"</span>)
            <span class="hljs-keyword">return</span> redirect(url_for(VERIFY_2FA_URL))
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> current_user.is_two_factor_authentication_enabled:
            flash(
                <span class="hljs-string">"You have not enabled 2-Factor Authentication. Please enable it first."</span>, <span class="hljs-string">"info"</span>)
        <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"accounts/verify-2fa.html"</span>, form=form)
</code></pre>
<p>The route starts by initializing a form (<code>TwoFactorForm</code>) meant for 2FA verification using the data obtained from the request. Upon form submission, the code proceeds with several conditional checks to validate the OTP entered by the user.</p>
<p>Once the form has been successfully submitted and validated, the code verifies the authenticity of the OTP using <code>current_</code><a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>user.is</code></a><code>_otp_valid(</code><a target="_blank" href="https://www.freecodecamp.org/news/how-to-implement-two-factor-authentication-in-your-flask-app/#overview-of-pyotp-and-google-authenticator"><code>form.otp.data</code></a><code>)</code>, which checks if the entered OTP is valid for the current user. If the OTP is valid, the code executes the following logic:</p>
<ul>
<li><p>If the provided OTP is valid and 2FA is already enabled for the user, a success message is flashed indicating successful 2FA verification, and the user is redirected to the home URL.</p>
</li>
<li><p>If the OTP is valid but 2FA isn't enabled for the user, it attempts to enable 2FA for that user. Upon successful activation, a success message flashes, and the user is redirected to the home URL.</p>
</li>
</ul>
<p>Furthermore, if the OTP entered by the user is invalid, the code flashes an error message indicating an invalid OTP and redirects the user back to the 2FA verification URL to retry the verification process.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-26-011107.png" alt="2FA Verification Page" /></p>
<p>With this, we have completed the implementation of all the features! 🎉</p>
<h2 id="heading-how-to-run-the-completed-app-for-the-first-time"><strong>How to Run the Completed App for the First Time</strong></h2>
<p>Now that our application is ready, you can first migrate the database, and then run the app.</p>
<p>To initialize the database (create a migration repository), use the command:</p>
<pre><code class="lang-bash">flask db init
</code></pre>
<p>To migrate the database changes, use the command:</p>
<pre><code class="lang-bash">flask db migrate
</code></pre>
<p>To apply the migrations, use the command:</p>
<pre><code class="lang-bash">flask db upgrade
</code></pre>
<p>Since this is the first time we're running our app, you'll need to run all the above commands. Later, whenever you make changes to the database, you'll just need to run the last two commands.</p>
<p>After that, you can run your application using the command:</p>
<pre><code class="lang-python">python manage.py run
</code></pre>
<p>Since we have completed the development, here's how your file structure should look like:</p>
<pre><code class="lang-bash">flask-two-factor-auth/
├── migrations/
├── src/
│   ├── accounts/
│   │   ├── __init__.py
│   │   ├── forms.py
│   │   ├── models.py
│   │   └── views.py
│   ├── core/
│   │   ├── __init__.py
│   │   └── views.py
│   ├── static/
│   │   └── styles.css
│   ├── templates/
│   │   ├── accounts/
│   │   │   ├── login.html
│   │   │   ├── register.html
│   │   │   ├── setup-2fa.html
│   │   │   └── verify-2fa.html
│   │   ├── core/
│   │   │   └── index.html
│   │   ├── _base.html
│   │   └── navigation.html
│   ├── __init__.py
│   └── utils.py
├── .env
├── config.py
└── manage.py
</code></pre>
<h2 id="heading-wrapping-up"><strong>Wrapping up</strong></h2>
<p>In this tutorial, you learned how to set up two-factor authentication in your Flask app using PyOTP.</p>
<p>Here's the link to the <a target="_blank" href="https://github.com/ashutoshkrris/Flask-Two-Factor-Authentication">GitHub repository</a>. Feel free to check it out whenever you're stuck.</p>
<p>Here are some other tutorials I wrote about authentication, email verification, and OTPs that you might enjoy:</p>
<ul>
<li><p><a target="_blank" href="https://blog.ashutoshkrris.in/how-to-set-up-basic-user-authentication-in-a-flask-app">How to Set Up Basic User Authentication in a Flask App</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/news/how-to-setup-user-authentication-in-flask/">How to Set Up Email Verification in a Flask App</a></p>
</li>
<li><p><a target="_blank" href="https://blog.ashutoshkrris.in/how-to-generate-otps-using-pyotp-in-python">How To Generate OTPs Using PyOTP in Python</a></p>
</li>
</ul>
<p>Thank you for reading. I hope you found this article useful. You can follow me on <a target="_blank" href="https://twitter.com/ashutoshkrris">Twitter</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Python One-Liners - Code Hacks You Should Know]]></title><description><![CDATA[Python's beauty lies in its simplicity and readability. And mastering the art of writing concise yet powerful code can significantly enhance your productivity as a developer. I'm talking about really short lines of code that do big things.
In this ar...]]></description><link>https://blog.ashutoshkrris.in/python-one-liners-code-hacks-you-should-know</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/python-one-liners-code-hacks-you-should-know</guid><category><![CDATA[Python]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Programming Tips]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Thu, 30 Nov 2023 02:16:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1701310388682/e7385d7a-ffe1-463b-a839-7210269ed822.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Python's beauty lies in its simplicity and readability. And mastering the art of writing concise yet powerful code can significantly enhance your productivity as a developer. I'm talking about really short lines of code that do big things.</p>
<p>In this article, we'll explore 8 essential Python one-liners that every Pythonista should have in their toolkit. From list comprehensions to lambda functions and beyond, these techniques offer elegant solutions to common programming challenges, helping you write cleaner, more efficient code.</p>
<h2 id="heading-list-comprehension"><strong>List Comprehension</strong></h2>
<p>List comprehension is a Pythonic way to create lists with a single line of code. It offers a concise alternative to traditional loops, enabling you to generate lists quickly and efficiently.</p>
<p>Let's say you want to create a list containing squares of numbers from 0 to 9. Using a traditional loop, you'd do it like this:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Using a traditional loop</span>
squared_numbers = []
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>):
    squared_numbers.append(i ** <span class="hljs-number">2</span>)
print(squared_numbers)
</code></pre>
<p>The traditional loop method requires more lines of code and explicitly defines the iteration process, appending each squared number to the list step by step.</p>
<p>On the other hand, list comprehension can achieve the same result in a single line, making the code more concise and readable. It condenses the loop into a clear, compact structure, generating the squared numbers directly into a list.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Using list comprehension</span>
squared_numbers = [i ** <span class="hljs-number">2</span> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)]
print(squared_numbers)
</code></pre>
<p>You can use list comprehensions when you need to apply a simple operation to every element in a sequence, such as transforming a list of numbers or strings.</p>
<p>You can learn how you can pack and destructure lists in Python <a target="_blank" href="https://blog.ashutoshkrris.in/mastering-list-destructuring-and-packing-in-python-a-comprehensive-guide">here</a>.</p>
<h2 id="heading-lambda-functions"><strong>Lambda Functions</strong></h2>
<p><a target="_blank" href="https://blog.ashutoshkrris.in/mastering-lambdas-a-guide-to-anonymous-functions-in-python">Lambda functions</a>, also known as anonymous functions, allow you to create small, throwaway functions without explicitly defining them with <code>def</code>. They are particularly useful in scenarios where a function is needed for a short operation.</p>
<p>First, let's look at an example using <code>def</code>:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Using def</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_numbers</span>(<span class="hljs-params">x, y</span>):</span>
    <span class="hljs-keyword">return</span> x + y

print(add_numbers(<span class="hljs-number">2</span>, <span class="hljs-number">3</span>))
</code></pre>
<p>In this code, the <code>def</code> keyword is used to define a named function <code>add_numbers</code> explicitly. It takes an argument <code>x</code> and <code>y</code> and returns the sum of them. This traditional approach provides a named function that can be called multiple times.</p>
<p>But when you need a function just for one-time usage, you can just define an anonymous function using the <code>lambda</code> keyword like this:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Using Lambda</span>
add = <span class="hljs-keyword">lambda</span> x, y: x + y
print(add(<span class="hljs-number">2</span>, <span class="hljs-number">3</span>))
</code></pre>
<p>It achieves the same result as <code>add_numbers</code> but in a single line without assigning a name explicitly. Lambda functions are useful for short, throwaway functions that are used infrequently or as part of other expressions.</p>
<h2 id="heading-map-and-filter"><strong>Map and Filter</strong></h2>
<p>The <code>map</code> and <code>filter</code> functions are powerful tools for working with iterables, allowing concise manipulation and filtering of data.</p>
<p>Let's say you have a list of strings and you want to convert each item of the list into uppercase.</p>
<pre><code class="lang-python">fruits = [<span class="hljs-string">'apple'</span>, <span class="hljs-string">'banana'</span>, <span class="hljs-string">'cherry'</span>]
upper_case_loop = []
<span class="hljs-keyword">for</span> fruit <span class="hljs-keyword">in</span> fruits:
    upper_case_loop.append(fruit.upper())
print(upper_case_loop)
</code></pre>
<p>Now, you can achieve the same using the <code>map</code> function:</p>
<pre><code class="lang-python">upper_case = list(map(<span class="hljs-keyword">lambda</span> x: x.upper(), [<span class="hljs-string">'apple'</span>, <span class="hljs-string">'banana'</span>, <span class="hljs-string">'cherry'</span>]))
</code></pre>
<p>You can utilize <code>map</code> when you need to perform an operation on every element of an iterable. <code>filter</code> is handy for selectively choosing elements based on a condition.</p>
<p>You can learn more about the <code>map</code>, <code>filter</code> and <code>reduce</code> functions <a target="_blank" href="https://blog.ashutoshkrris.in/mastering-lambdas-a-guide-to-anonymous-functions-in-python#heading-using-lambda-functions-as-arguments-in-higher-order-functions-map-filter-reduce">here</a>.</p>
<h2 id="heading-ternary-operator"><strong>Ternary Operator</strong></h2>
<p>The ternary operator provides a condensed way to write conditional statements in a single line, enhancing code readability.</p>
<p>Let's say, you have a number and you want to check if it's even or odd. You can do it using the traditional if condition as below:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Traditional if</span>
result = <span class="hljs-literal">None</span>
num = <span class="hljs-number">5</span>
<span class="hljs-keyword">if</span> num % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>:
    result = <span class="hljs-string">"Even"</span>
<span class="hljs-keyword">else</span>:
    result = <span class="hljs-string">"Odd"</span>
</code></pre>
<p>But you can achieve the same results in a single line using the ternary operator:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Ternary Operator</span>
num = <span class="hljs-number">7</span>
result = <span class="hljs-string">"Even"</span> <span class="hljs-keyword">if</span> num % <span class="hljs-number">2</span> == <span class="hljs-number">0</span> <span class="hljs-keyword">else</span> <span class="hljs-string">"Odd"</span>
</code></pre>
<p>When you need to assign values based on conditions, especially in situations requiring simple if-else checks, the ternary operator shines.</p>
<h2 id="heading-zip-function"><strong>Zip Function</strong></h2>
<p>The <code>zip</code> function enables you to combine multiple iterables element-wise, forming tuples of corresponding elements.</p>
<p>Let's assume you have two lists: one containing the names of students and the other containing their respective grades for a specific assignment.</p>
<pre><code class="lang-python">students = [<span class="hljs-string">'Dilli'</span>, <span class="hljs-string">'Vikram'</span>, <span class="hljs-string">'Rolex'</span>, <span class="hljs-string">'Leo'</span>]
grades = [<span class="hljs-number">85</span>, <span class="hljs-number">92</span>, <span class="hljs-number">78</span>, <span class="hljs-number">88</span>]
</code></pre>
<p>Now, you want to create a report that pairs each student's name with their grade for easy comprehension or further analysis. You can do it by iterating over the list and appending them to a new list as below:</p>
<pre><code class="lang-python">students = [<span class="hljs-string">'Dilli'</span>, <span class="hljs-string">'Vikram'</span>, <span class="hljs-string">'Rolex'</span>, <span class="hljs-string">'Leo'</span>]
grades = [<span class="hljs-number">85</span>, <span class="hljs-number">92</span>, <span class="hljs-number">78</span>, <span class="hljs-number">88</span>]

student_grade_pairs = []
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(len(students)):
    student_grade_pairs.append((students[i], grades[i]))

print(student_grade_pairs)
</code></pre>
<p>The above loop method manually pairs elements from two lists by iterating through their indices, accessing elements at the same positions, and appending tuples of those elements into a new list <code>student_grade_pairs</code>.</p>
<p>But, what if I tell you that we can achieve the same pairing effect in one line using the <code>zip</code> function as below:</p>
<pre><code class="lang-python">students = [<span class="hljs-string">'Dilli'</span>, <span class="hljs-string">'Vikram'</span>, <span class="hljs-string">'Rolex'</span>, <span class="hljs-string">'Leo'</span>]
grades = [<span class="hljs-number">85</span>, <span class="hljs-number">92</span>, <span class="hljs-number">78</span>, <span class="hljs-number">88</span>]

student_grade_pairs = list(zip(students, grades))
print(student_grade_pairs)
</code></pre>
<p>The <code>zip</code> function elegantly combines elements from both lists, creating pairs of corresponding elements as tuples. The result <code>student_grade_pairs</code> is a list of tuples, where each tuple contains an element from the grades list paired with the corresponding element from the <code>students</code> list.</p>
<p>You can learn more about the <code>zip</code>  function <a target="_blank" href="https://blog.ashutoshkrris.in/zipping-through-python-a-comprehensive-guide-to-the-zip-function">here</a>.</p>
<h2 id="heading-enumerate-function"><strong>Enumerate Function</strong></h2>
<p>The <code>enumerate</code> function offers a concise way to iterate over a sequence while keeping track of the index.</p>
<p>Let's say you're developing a feature where users can add items to their shopping list, and you want to display the items along with their position or index in the list for easy reference.</p>
<p>You can do it using a traditional for-loop as below:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Simulating a grocery list</span>
grocery_list = [<span class="hljs-string">'Apples'</span>, <span class="hljs-string">'Milk'</span>, <span class="hljs-string">'Bread'</span>, <span class="hljs-string">'Eggs'</span>, <span class="hljs-string">'Cheese'</span>]

<span class="hljs-comment"># Displaying the grocery list with indices</span>
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(len(grocery_list)):
    print(<span class="hljs-string">f"<span class="hljs-subst">{i}</span>. <span class="hljs-subst">{grocery_list[i]}</span>"</span>)
</code></pre>
<p>The traditional loop with manual indexing involves using <code>range</code> along with <code>len</code> to generate indices that are then used to access elements in the <code>grocery_list</code> list. This method requires more code and is less readable due to the explicit handling of indices.</p>
<p>The <code>enumerate</code> function simplifies the process by directly providing both indices and elements from the <code>grocery_list</code> list.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Simulating a grocery list</span>
grocery_list = [<span class="hljs-string">'Apples'</span>, <span class="hljs-string">'Milk'</span>, <span class="hljs-string">'Bread'</span>, <span class="hljs-string">'Eggs'</span>, <span class="hljs-string">'Cheese'</span>]

<span class="hljs-comment"># Displaying the grocery list with indices</span>
<span class="hljs-keyword">for</span> index, item <span class="hljs-keyword">in</span> enumerate(grocery_list):
    print(<span class="hljs-string">f"<span class="hljs-subst">{index}</span>. <span class="hljs-subst">{item}</span>"</span>)
</code></pre>
<p>It's concise, readable, and more Pythonic, eliminating the need for manual index handling and making the code cleaner. This approach is generally preferred for its simplicity and clarity in obtaining indices and elements from an iterable.</p>
<h2 id="heading-string-join"><strong>String Join</strong></h2>
<p>The <code>join</code> method is a clean way to concatenate strings from an iterable into a single string.</p>
<p>Suppose you have a list of words and want to create a sentence by joining these words using traditional concatenation. You'd do it as below:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Using traditional concatenation</span>
words = [<span class="hljs-string">'Python'</span>, <span class="hljs-string">'is'</span>, <span class="hljs-string">'awesome'</span>, <span class="hljs-string">'and'</span>, <span class="hljs-string">'powerful'</span>]

sentence = <span class="hljs-string">''</span>
<span class="hljs-keyword">for</span> word <span class="hljs-keyword">in</span> words:
    sentence += word + <span class="hljs-string">' '</span>

print(sentence.strip())  <span class="hljs-comment"># Strip to remove the trailing space</span>
</code></pre>
<p>In the traditional concatenation method, a loop iterates through the list of words, and each word is concatenated with a space. However, this approach requires creating a new string for each concatenation operation, which might not be efficient for larger strings due to string immutability.</p>
<p>The <code>join</code> method, on the other hand, is more efficient and concise. It joins the elements of the list using the specified separator (in this case, a space), creating the sentence in a single operation.</p>
<pre><code class="lang-python">.<span class="hljs-comment"># Using join method</span>
words = [<span class="hljs-string">'Python'</span>, <span class="hljs-string">'is'</span>, <span class="hljs-string">'awesome'</span>, <span class="hljs-string">'and'</span>, <span class="hljs-string">'powerful'</span>]

sentence = <span class="hljs-string">' '</span>.join(words)
print(sentence)
</code></pre>
<p>This method is generally the preferred way to join strings in Python due to its efficiency and readability.</p>
<h2 id="heading-unpacking-lists"><strong>Unpacking Lists</strong></h2>
<p>Python's unpacking feature allows for efficient assignment of elements from iterables to variables.</p>
<p>Suppose you have a list of numbers, and you want to assign each number to separate variables using traditional indexing.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Using traditional unpacking</span>
numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]

a = numbers[<span class="hljs-number">0</span>]
b = numbers[<span class="hljs-number">1</span>]
c = numbers[<span class="hljs-number">2</span>]

print(a, b, c)
</code></pre>
<p>In the traditional unpacking method, individual elements from the list are accessed and assigned to separate variables by explicitly indexing each element. This method is more verbose and requires knowing the number of elements in advance.</p>
<p>Now, let's accomplish the same using the <code>*</code> operator for unpacking the list into variables.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Using * operator for unpacking</span>
numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]

a, b, c = numbers

print(a, b, c)
</code></pre>
<p>You can learn more about the <code>*</code> operator and list unpacking in <a target="_blank" href="https://blog.ashutoshkrris.in/mastering-list-destructuring-and-packing-in-python-a-comprehensive-guide#heading-destructuring-assignment">this tutorial</a>.</p>
<h2 id="heading-should-you-always-use-one-liners"><strong>Should You Always Use One-Liners?</strong></h2>
<p>While Python one-liners offer conciseness and elegance, there are considerations to keep in mind before applying them universally:</p>
<ol>
<li><p><strong>Readability</strong>: One-liners might sacrifice readability for crispness. Complex one-liners can be hard to understand, especially for newcomers or when revisiting code after some time.</p>
</li>
<li><p><strong>Maintainability</strong>: Overusing one-liners, especially complex ones, can make code maintenance challenging. Debugging and modifying concise code might be more difficult.</p>
</li>
<li><p><strong>Performance</strong>: In certain scenarios, one-liners might not be the most performant solution. These concise expressions may consume more resources, such as memory or CPU, and their underlying operations might have higher time complexity, affecting efficiency, especially with large datasets or intensive computations.</p>
</li>
<li><p><strong>Debugging</strong>: Debugging a one-liner can be more challenging due to its compactness. Identifying issues or errors might take longer compared to well-structured, multiple-line code.</p>
</li>
<li><p><strong>Context</strong>: Not all situations warrant one-liners. Sometimes, a straightforward, explicit approach might be more suitable for code clarity, especially when working in teams.</p>
</li>
</ol>
<p>Ultimately, the decision to use one-liners should consider the trade-offs between conciseness and readability. Strive for a balance that enhances code clarity without compromising maintainability and understanding, especially when collaborating or working on larger projects.</p>
<h2 id="heading-wrapping-up"><strong>Wrapping Up</strong></h2>
<p>Mastering Python's concise techniques like list comprehensions, lambda functions, <code>enumerate</code>, <code>join</code>, <code>zip</code>, and unpacking with the <code>*</code> operator can significantly enhance code readability, efficiency, and simplicity. These methods offer elegant solutions to common programming challenges, reducing verbosity and improving code maintainability.</p>
<p>Understanding when and how to use these Pythonic constructs empowers developers to write cleaner, more expressive code and enhance overall productivity in various programming scenarios.</p>
]]></content:encoded></item><item><title><![CDATA[How To Send Emails Using Python?]]></title><description><![CDATA[Sending emails manually is time-consuming and error-prone, but it’s easy to automate with Python. Imagine a scenario where you can effortlessly send hundreds of customized emails to your customers, automate routine follow-ups, or send birthday wishes...]]></description><link>https://blog.ashutoshkrris.in/how-to-send-emails-using-python</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/how-to-send-emails-using-python</guid><category><![CDATA[Python]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Wed, 18 Oct 2023 12:50:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697633374557/1cfd4c37-7d77-4096-bb33-4daeadc5fcee.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Sending emails manually is time-consuming and error-prone, but it’s easy to automate with Python. Imagine a scenario where you can effortlessly send hundreds of customized emails to your customers, automate routine follow-ups, or send birthday wishes automatically, all with the simplicity and elegance of Python code.</p>
<p>In this article, we're going to explore how Python can make your email life more effortless. I'll show you step-by-step how to get started and send plain-text and fancy emails (with attachments too!). All you need is Python installed on your system.</p>
<h2 id="heading-getting-started">Getting Started</h2>
<p>Python comes with a built-in module called <code>smtplib</code> to send emails. It works by following a set of rules called the Simple Mail Transfer Protocol, or SMTP for short. Think of it like a recipe for sending emails. The <code>smtplib</code> module uses the <a target="_blank" href="https://tools.ietf.org/html/rfc821">RFC 821</a> protocol for SMTP.</p>
<p>For our examples, we will use Gmail's SMTP server for sending emails. In the next section, we will set up our Gmail account for sending out emails programmatically.</p>
<h3 id="heading-setting-up-gmail-for-sending-emails">Setting up Gmail for Sending Emails</h3>
<p>Though you can use your personal account to send emails, it's recommended to use a throw-away account for the tutorial. If you're ready with the Gmail account, follow the below steps to get started:</p>
<ol>
<li><p>Go to your Google Account Settings.</p>
</li>
<li><p>Choose "Security" and click on "2-Step Verification."</p>
</li>
<li><p>Scroll down to find "App passwords" and select it.</p>
</li>
<li><p>Give the password a name for reference. and click "Generate."</p>
</li>
<li><p>Follow the on-screen instructions and get the 16-character app password.</p>
</li>
<li><p>Click "Done."</p>
</li>
</ol>
<p>Make sure you copy and store the password somewhere safely as you won't be able to see it later.</p>
<h2 id="heading-how-to-secure-your-email-connections">How To Secure Your Email Connections?</h2>
<p>When you're sending emails with Python, it's crucial to keep your messages and login details safe from prying eyes. To do this, you can use encryption to protect your communication. Two common methods for encrypting your email connection are <strong>SSL (Secure Sockets Layer)</strong> and <strong>TLS (Transport Layer Security)</strong>.</p>
<p>To establish a secure connection with your email server, you have two options:</p>
<h3 id="heading-using-smtpssl">Using <code>SMTP_SSL()</code></h3>
<p>This method creates a secure connection right from the start, ensuring your communication is encrypted. The default port for this is 465. Thus, if <code>port</code> is zero, or not specified, <code>.SMTP_SSL()</code> will use this standard port for SMTP over SSL.</p>
<p>The following Python code example demonstrates this approach:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> smtplib
<span class="hljs-keyword">import</span> ssl
<span class="hljs-keyword">import</span> os

EMAIL = os.environ.get(<span class="hljs-string">"EMAIL"</span>)
PASSWORD = os.environ.get(<span class="hljs-string">"PASSWORD"</span>)
PORT = <span class="hljs-number">465</span>

context = ssl.create_default_context()

<span class="hljs-keyword">with</span> smtplib.SMTP_SSL(<span class="hljs-string">"smtp.gmail.com"</span>, PORT, context=context) <span class="hljs-keyword">as</span> server:
    server.login(EMAIL, PASSWORD)
    <span class="hljs-comment"># <span class="hljs-doctag">TODO:</span> Send email here</span>
</code></pre>
<p>In the above code, we retrieve the email and password from environment variables, which is a recommended practice for security. It then creates a secure SSL context using <code>ssl.create_default_context()</code>. The <code>with</code> statement sets up the secure connection to the Gmail SMTP server, using the provided server address and port, along with the SSL context to ensure a safe and encrypted connection. Once connected, the script logs in to the email server using the retrieved credentials. Using the <a target="_blank" href="https://earthly.dev/blog/use-with-keyword-in-py/"><code>with</code> context manager</a> ensures that the connection is closed properly when you're done.</p>
<h3 id="heading-using-starttls">Using <code>.starttls()</code></h3>
<p>This method first establishes an unsecured SMTP connection, and later encrypts using <code>.starttls()</code>.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> smtplib
<span class="hljs-keyword">import</span> ssl

SMTP_SERVER = <span class="hljs-string">"smtp.gmail.com"</span>
PORT = <span class="hljs-number">587</span>
EMAIL = os.environ.get(<span class="hljs-string">"EMAIL"</span>)
PASSWORD = os.environ.get(<span class="hljs-string">"PASSWORD"</span>)

context = ssl.create_default_context()

<span class="hljs-keyword">with</span> smtplib.SMTP(SMTP_SERVER, PORT) <span class="hljs-keyword">as</span> server:
    server.ehlo()
    server.starttls(context=context)  <span class="hljs-comment"># Secure the connection</span>
    server.ehlo()
    server.login(EMAIL, PASSWORD)
    <span class="hljs-comment"># <span class="hljs-doctag">TODO:</span> Send an email here</span>
</code></pre>
<p>Within the <code>with</code> statement, the script initializes the connection to the SMTP server, introduces itself with <code>server.ehlo()</code>, secures the connection with <code>server.starttls(context=context)</code> for encryption, and logs in using the provided email and password.</p>
<p>You don't need to use <code>.helo()</code>(for SMTP) or <code>.ehlo()</code>(for ESMTP) explicitly because they are automatically called by <code>.starttls()</code> and <code>.sendmail()</code> if required. These functions handle the SMTP service extensions of the server, so you can generally omit using <code>.helo()</code> or <code>.ehlo()</code> unless you specifically need to check those extensions.</p>
<blockquote>
<p>Note: The above snippets use environment variables to store the email and password securely. You can create a <code>.env</code> file and set the values of <code>EMAIL</code> and <code>PASSWORD</code>. Then, you need to run <code>source .env</code> on your terminal to load these values. You can read more about them <a target="_blank" href="https://medium.com/p/201f4abd46b8">here</a>.</p>
</blockquote>
<h2 id="heading-how-to-send-plain-text-emails">How To Send Plain-Text Emails?</h2>
<p>Now that you've learned how to secure your SMTP connection, you're all set to send your first email using Python. Please note that we'll use <code>.starttls()</code> to encrypt the connection in the examples that follow.</p>
<p>To send an email, Python provides the <code>sendmail()</code> function, which does exactly what its name suggests: it sends an email. Here's the syntax of the <code>sendmail()</code> function:</p>
<pre><code class="lang-python">sendmail(sender_email, receiver_email, message)
</code></pre>
<ul>
<li><p><code>sender_email</code>: The email address of the sender.</p>
</li>
<li><p><code>receiver_email</code>: The email address of the recipient.</p>
</li>
<li><p><code>message</code>: The email content you want to send.</p>
</li>
</ul>
<p>Now, let's send our very first email:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> smtplib
<span class="hljs-keyword">import</span> ssl

SMTP_SERVER = <span class="hljs-string">"smtp.gmail.com"</span>
PORT = <span class="hljs-number">587</span>
EMAIL = os.environ.get(<span class="hljs-string">"EMAIL"</span>)
PASSWORD = os.environ.get(<span class="hljs-string">"PASSWORD"</span>)

context = ssl.create_default_context()

<span class="hljs-keyword">with</span> smtplib.SMTP(SMTP_SERVER, PORT) <span class="hljs-keyword">as</span> server:
    server.starttls(context=context)
    server.login(EMAIL, PASSWORD)
    message = <span class="hljs-string">"""\
    Subject: My First Email

    Hello there, this is my first email sent using Python.
    """</span>
    server.sendmail(EMAIL, <span class="hljs-string">"sogiho2398@weirby.com"</span>, message)
</code></pre>
<p>The <code>message</code> variable holds the content of the email, including the subject and the body of the message. The message starts with "Subject: My First Email" followed by two newlines(<code>\n</code>). This ensures <code>My First Email</code> shows up as the subject of the email, and the text following the newlines will be treated as the message body.</p>
<p>Then the <code>server.sendmail()</code> function is used to send the email from the sender's address to the recipient's address ("<a target="_blank" href="mailto:sogiho2398@weirby.com">sogiho2398@weirby.com</a>" in this case), along with the message content.</p>
<h2 id="heading-how-to-send-fancy-emails">How To Send Fancy Emails?</h2>
<p>In the previous section, you learned how you can send plain-text emails using Python. But, you won't always want to send those boring emails, right? Using Python, you can send emails with attachments as well as HTML content(yes, those fancy emails that have filled your inbox).</p>
<p>The built-in <code>email</code> package in Python enables you to create more fancy emails, which can be subsequently sent using the <code>smtplib</code> module, as you've already seen. In the following sections, you'll learn how to utilize the <code>email</code> package to send emails with HTML content and attachments, adding an extra layer of versatility to your email-sending capabilities.</p>
<h3 id="heading-multipurpose-internet-mail-extensions-mime">Multipurpose Internet Mail Extensions (MIME)</h3>
<p>The most common type of email we use today is called MIME (Multipurpose Internet Mail Extensions) Multipart email. It's like an email that can have different parts, like both regular text and fancy HTML. Python has a special module called <code>email.mime</code> that helps us create these kinds of emails. With it, we can make emails that look nice, have plain text, and even attach things like pictures or documents. This is how we send cool newsletters, attachments, or emails with both simple text and pretty pictures. It's a crucial tool for making emails more interesting and useful. If you need more information on how to use it, you can find detailed instructions in <a target="_blank" href="https://docs.python.org/3/library/email.mime.html">the official documentation</a>.</p>
<h3 id="heading-including-attachments">Including Attachments</h3>
<p>In this section, we'll explore how to send emails with attachments using Python. Sending emails with attachments can be incredibly useful, especially when you need to share files or documents. We'll use the <code>email</code> and <code>smtplib</code> modules to accomplish this.</p>
<p>The following code shows how you can send an email with an image attachment:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> smtplib
<span class="hljs-keyword">import</span> ssl

<span class="hljs-keyword">from</span> email <span class="hljs-keyword">import</span> encoders
<span class="hljs-keyword">from</span> email.mime.base <span class="hljs-keyword">import</span> MIMEBase
<span class="hljs-keyword">from</span> email.mime.multipart <span class="hljs-keyword">import</span> MIMEMultipart
<span class="hljs-keyword">from</span> email.mime.text <span class="hljs-keyword">import</span> MIMEText

SMTP_SERVER = <span class="hljs-string">"smtp.gmail.com"</span>
PORT = <span class="hljs-number">587</span>
EMAIL = os.environ.get(<span class="hljs-string">"EMAIL"</span>)
PASSWORD = os.environ.get(<span class="hljs-string">"PASSWORD"</span>)

subject = <span class="hljs-string">"My Second Email"</span>
body = <span class="hljs-string">"Hello there, I hope you are able to see my attached image."</span>
receiver_email = <span class="hljs-string">"sogiho2398@weirby.com"</span>

message = MIMEMultipart()
message[<span class="hljs-string">"From"</span>] = EMAIL
message[<span class="hljs-string">"To"</span>] = receiver_email
message[<span class="hljs-string">"Subject"</span>] = subject

message.attach(MIMEText(body, <span class="hljs-string">"plain"</span>))

filename = <span class="hljs-string">"image.png"</span>

<span class="hljs-keyword">with</span> open(filename, <span class="hljs-string">"rb"</span>) <span class="hljs-keyword">as</span> attachment:
    part = MIMEBase(<span class="hljs-string">"application"</span>, <span class="hljs-string">"octet-stream"</span>)
    part.set_payload(attachment.read())

encoders.encode_base64(part)

part.add_header(
    <span class="hljs-string">"Content-Disposition"</span>,
    <span class="hljs-string">f"attachment; filename= <span class="hljs-subst">{filename}</span>"</span>,
)

message.attach(part)
text = message.as_string()

context = ssl.create_default_context()
<span class="hljs-keyword">with</span> smtplib.SMTP_SSL(SMTP_SERVER, PORT, context=context) <span class="hljs-keyword">as</span> server:
    server.login(EMAIL, PASSWORD)
    server.sendmail(EMAIL, receiver_email, text)
</code></pre>
<p>The above code uses the <code>MIMEMultipart</code> class to structure the email, providing fields for sender, recipient, and subject. The email's body is added using MIMEText. To attach a file, it selects the file ("image.png" in this case), encodes it using base64 encoding, and attaches it to the email. This step allows you to include files like images, documents, or any binary data. The email message is then converted to a string for transmission.</p>
<p>Here's how you email should look:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697630883172/34ce4317-a8d7-47e0-9aec-f75326dc874e.png" alt="Email with Attachment" class="image--center mx-auto" /></p>
<h3 id="heading-including-html-content">Including HTML Content</h3>
<p>HTML emails are a powerful way to create visually appealing messages with various formatting and styling options. You can define the HTML content in the same Python file or in a different HTML file itself. But it would be ideal to separate it from your Python code, else the code will grow longer.</p>
<p>Here's the code that demonstrates how to send HTML emails:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> smtplib
<span class="hljs-keyword">import</span> ssl

<span class="hljs-keyword">from</span> email.mime.multipart <span class="hljs-keyword">import</span> MIMEMultipart
<span class="hljs-keyword">from</span> email.mime.text <span class="hljs-keyword">import</span> MIMEText

SMTP_SERVER = <span class="hljs-string">"smtp.gmail.com"</span>
PORT = <span class="hljs-number">587</span>
EMAIL = os.environ.get(<span class="hljs-string">"EMAIL"</span>)
PASSWORD = os.environ.get(<span class="hljs-string">"PASSWORD"</span>)

subject = <span class="hljs-string">"My Third Email"</span>
receiver_email = <span class="hljs-string">"sogiho2398@weirby.com"</span>

message = MIMEMultipart(<span class="hljs-string">"alternative"</span>)
message[<span class="hljs-string">"From"</span>] = EMAIL
message[<span class="hljs-string">"To"</span>] = receiver_email
message[<span class="hljs-string">"Subject"</span>] = subject

filename = <span class="hljs-string">"email.html"</span>

text = <span class="hljs-string">"""\
Hi there,

Sometimes you just want to send a simple HTML email with a simple design and clear call to action. This is it.

This is a really simple email template. Its sole purpose is to get the recipient to click the button with no distractions.

Good luck! Hope it works.
"""</span>

<span class="hljs-keyword">with</span> open(filename, <span class="hljs-string">"r"</span>) <span class="hljs-keyword">as</span> file:
    html = file.read()

part1 = MIMEText(text, <span class="hljs-string">"plain"</span>)
part2 = MIMEText(html, <span class="hljs-string">"html"</span>)

message.attach(part1)
message.attach(part2)

text = message.as_string()

context = ssl.create_default_context()
<span class="hljs-keyword">with</span> smtplib.SMTP(SMTP_SERVER, PORT) <span class="hljs-keyword">as</span> server:
    server.starttls(context=context)
    server.login(EMAIL, PASSWORD)
    server.sendmail(EMAIL, receiver_email, text)
</code></pre>
<p>To structure the email, we use <code>MIMEMultipart("alternative")</code>, enabling the inclusion of both plain text and HTML content. We read the HTML content from a file "email.html". You can get the contents of this HTML file from <a target="_blank" href="https://github.com/leemunroe/responsive-html-email-template/blob/master/email.html">here</a>. We also create two parts - one for plaintext and one for HTML. This is required as not all email clients display HTML content by default. The message is finally converted into text and the email is sent.</p>
<p>Here's how your HTML email looks like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1697631404514/4ea7bea2-8161-4f31-a40c-9e67d9ff9e86.png" alt="HTML Email" class="image--center mx-auto" /></p>
<h2 id="heading-how-to-send-bulk-emails">How To Send Bulk Emails?</h2>
<p>In many real-world scenarios, sending a single email is not sufficient. Whether you're managing a mailing list, delivering regular updates to subscribers, or sending notifications to a large number of recipients, there comes a time when you need to send multiple emails efficiently. In this section, we will learn how to read a CSV file and send them personalized emails.</p>
<p>Let's start with creating a CSV file called "receivers.csv" and add the following content:</p>
<pre><code class="lang-plaintext">name,email,designation,salary
Person 1,sogiho2398@weirby.com,Application Developer I,20000 USD
Person 2,sogiho2398@weirby.com,Application Developer II,30000 USD 
Person 3,sogiho2398@weirby.com,Application Developer III,50000 USD
Person 4,sogiho2398@weirby.com,Application Developer IV,80000 USD
</code></pre>
<p>Make sure you separate the values with commas(,).</p>
<p>Next, let's read this file and iterate over the values:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> csv


<span class="hljs-keyword">with</span> open(<span class="hljs-string">"receivers.csv"</span>, <span class="hljs-string">"r"</span>) <span class="hljs-keyword">as</span> file:
    reader = csv.reader(file)
    next(reader)
    <span class="hljs-keyword">for</span> name, email, designation, salary <span class="hljs-keyword">in</span> reader:
        print(<span class="hljs-string">f"Sending email to <span class="hljs-subst">{name}</span> on email: <span class="hljs-subst">{email}</span>"</span>)
        <span class="hljs-comment"># <span class="hljs-doctag">TODO:</span> Send email</span>
</code></pre>
<p>The above code reads the "receivers.csv" file and iterates over the CSV data. It skips the header row using <code>next(reader)</code>. For each subsequent row, it extracts the name, email, designation, and salary.</p>
<p>Let us now send the emails to the users:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> csv
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> smtplib
<span class="hljs-keyword">import</span> ssl

SMTP_SERVER = <span class="hljs-string">"smtp.gmail.com"</span>
PORT = <span class="hljs-number">587</span>
EMAIL = os.environ.get(<span class="hljs-string">"EMAIL"</span>)
PASSWORD = os.environ.get(<span class="hljs-string">"PASSWORD"</span>)

context = ssl.create_default_context()

<span class="hljs-keyword">with</span> smtplib.SMTP(SMTP_SERVER, PORT) <span class="hljs-keyword">as</span> server:
    server.starttls(context=context)
    server.login(EMAIL, PASSWORD)

    <span class="hljs-keyword">with</span> open(<span class="hljs-string">"receivers.csv"</span>, <span class="hljs-string">"r"</span>) <span class="hljs-keyword">as</span> file:
        reader = csv.reader(file)
        next(reader)
        <span class="hljs-keyword">for</span> name, email, designation, salary <span class="hljs-keyword">in</span> reader:
            message = <span class="hljs-string">f"""\
            Subject: <span class="hljs-subst">{name}</span>, you're hired!

            Hi <span class="hljs-subst">{name}</span>

            Congratulations, you're hired for the role of <span class="hljs-subst">{designation}</span>. Your salary will be <span class="hljs-subst">{salary}</span>.

            Thanks
            HR    
            """</span>
            server.sendmail(EMAIL, email, message)
</code></pre>
<p>In each iteration, we construct the personalized message using <code>f-strings</code> and send the message to the respective users.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we've explored how Python can be used to send emails in different ways. We've learned how to make email connections secure, send emails with fancy designs or attachments, and even send emails to many people at once.</p>
<p>Python's tools make it easy to send various types of emails, whether for personal use or in a professional setting. This can save time and make your messages more engaging. In a world where email is a crucial part of our daily lives, Python offers you the ability to send emails efficiently and effectively, no matter your background or needs.</p>
]]></content:encoded></item><item><title><![CDATA[How To Generate OTPs Using PyOTP in Python]]></title><description><![CDATA[In a digital age filled with hackers and cybersecurity threats where "password123" just doesn't cut it anymore, Two-Factor Authentication (2FA) emerges as the superhero of online security. OTPs are an important part of 2FA. In this article, we'll lea...]]></description><link>https://blog.ashutoshkrris.in/how-to-generate-otps-using-pyotp-in-python</link><guid isPermaLink="true">https://blog.ashutoshkrris.in/how-to-generate-otps-using-pyotp-in-python</guid><category><![CDATA[Python]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Security]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Ashutosh Krishna]]></dc:creator><pubDate>Sun, 01 Oct 2023 07:19:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1696144698813/b5dc7bf6-825b-46f6-aa2a-f1cda218bfe2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In a digital age filled with hackers and cybersecurity threats where "password123" just doesn't cut it anymore, Two-Factor Authentication (2FA) emerges as the superhero of online security. OTPs are an important part of 2FA. In this article, we'll learn how to create OTPs using Python and the PyOTP library. So, grab your Python wizard hat, and let's dive in!</p>
<h2 id="heading-what-are-otps">What are OTPs?</h2>
<p>You're no stranger to the scenario: you're online, making that critical purchase, and then it happens - the dreaded login screen. Before you use your trusty "password123," you should know it's not as strong as you think. But don't worry, we've got a superhero in the digital world - OTPs!</p>
<p><a target="_blank" href="https://www.freepik.com/free-vector/enter-otp-concept-illustration_20602807.htm#query=otp&amp;position=0&amp;from_view=keyword&amp;track=sph"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696164298514/31ce8e39-1ee7-47e4-8924-c7011fd8cfa2.jpeg" alt="Image by storyset on Freepik" class="image--center mx-auto" /></a></p>
<p>An OTP, or One-Time Password, is a temporary code that changes each time you use it. It's like having a new secret handshake every time you want to access your online accounts. This dynamic nature makes OTPs incredibly secure, as they're almost impossible for malicious actors to predict or crack.</p>
<p>Before we dive into the code, let's understand the two main types of OTPs:</p>
<p><strong>1. Time-based OTP (TOTP):</strong> These OTPs change at regular time intervals (usually 30 or 60 seconds). Think of it as a constantly evolving secret code that only you and your device know.</p>
<p><strong>2. HMAC-based OTP (HOTP):</strong> In contrast, HOTPs are event-based OTPs. They change each time you authenticate, providing an extra layer of security.</p>
<h2 id="heading-how-to-generate-otps-using-python">How To Generate OTPs Using Python?</h2>
<p>In Python, you can generate OTPs using the <code>random</code> library as below:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> random <span class="hljs-keyword">import</span> choice
<span class="hljs-keyword">import</span> string


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">generate_otp</span>(<span class="hljs-params">number_of_digits</span>):</span>
    otp = <span class="hljs-string">''</span>.join(choice(string.digits) <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(number_of_digits))
    <span class="hljs-keyword">return</span> otp


print(generate_otp(<span class="hljs-number">6</span>))
</code></pre>
<p>The above <code>generate_otp</code> method uses list comprehension to generate an OTP of the required number of digits. However, there are a few limitations to generating OTPs this way. The generated OTPs are predictable and attackers can easily predict the values. These OTPs do not have a built-in expiration time. For security reasons, OTPs should have a limited validity period to prevent replay attacks. The <code>random</code> module is not intended for cryptographic purposes. For high-security applications, it's better to use a cryptographic library like <code>secrets</code> or dedicated OTP generation libraries that provide cryptographically secure randomness.</p>
<p>This is where libraries such as <code>PytOTP</code> come into the picture. <a target="_blank" href="https://pyauth.github.io/pyotp/#">PyOTP</a> is a fantastic Python library that simplifies the creation and verification of OTPs. With PyOTP, you can generate OTPs using Time-based OTP (TOTP) and HMAC-based OTP (HOTP) algorithms effortlessly. So, let's get started!</p>
<h2 id="heading-how-to-generate-otps-using-pyotp">How to Generate OTPs using PyOTP?</h2>
<p>Before you can start generating OTPs, you need to install PyOTP. If you don't have Python installed, go ahead and do that first. Then, open your terminal and run the following command:</p>
<pre><code class="lang-bash">pip install pyotp
</code></pre>
<p>This command installs PyOTP and prepares you for the exciting journey ahead. Please note that you can also create a virtual environment before installing PyOTP. But for the sake of this simple tutorial, we won't be doing that here.</p>
<h3 id="heading-time-based-otps-totps">Time-Based OTPs (TOTPs)</h3>
<p>The <strong>moving factor in a TOTP is time-based</strong>. The amount of time duration for which the OTP is valid is called <strong>timestep</strong>. If you haven’t used your password within the timestep window, it will no longer be valid, and you’ll need to request a new one.</p>
<p>Let's start by importing the PyOTP library. We'll also create a secret key using the PyOTP library. Remember, this key should be kept as secret as your mother's secret recipe for your favorite food!</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pyotp

<span class="hljs-comment"># Create a secret key (keep it secret!)</span>
secret_key = pyotp.random_base32()
</code></pre>
<p>PyOTP provides a <code>random_base32()</code> function that helps you generate a random secret key in Base32 encoding. It generates a random sequence of bytes, which is essentially a random collection of numbers and letters. It then encodes this random sequence of bytes into Base32 format.</p>
<p>Now, let's generate an OTP using our secret key. We'll use the TOTP algorithm:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Generate an OTP using TOTP</span>
otp = pyotp.TOTP(secret_key)
otp_code = otp.now()

print(<span class="hljs-string">"Your Time-based OTP:"</span>, otp_code)
</code></pre>
<p>That's it! You've just created a Time-based OTP. This code will generate a new OTP every 30 seconds, making it an excellent choice for securing your online accounts.</p>
<pre><code class="lang-bash">Your Time-based OTP: 641079
</code></pre>
<p>Do you want to verify that the OTP changes after 30 seconds? Let's use the <code>sleep</code> function:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> time
<span class="hljs-keyword">import</span> pyotp

<span class="hljs-comment"># Create a secret key (keep it secret!)̥</span>
secret_key = pyotp.random_base32()

otp = pyotp.TOTP(secret_key)
<span class="hljs-comment"># Generate an OTP using TOTP after every 30 seconds</span>
<span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
    print(<span class="hljs-string">f"Your Time-based OTP at <span class="hljs-subst">{time.ctime()}</span>:"</span>, otp.now())

    time.sleep(<span class="hljs-number">30</span>)
</code></pre>
<p>In the above code, you enter an infinite loop (<code>while True</code>) to continuously generate OTPs. Inside the loop, you generate a TOTP and then let the code sleep for 30 seconds. Then after 30 seconds, it again generates the OTP. You will see an output as below:</p>
<pre><code class="lang-bash">Your Time-based OTP at Sun Oct  1 11:42:06 2023: 127722
Your Time-based OTP at Sun Oct  1 11:42:36 2023: 582057
Your Time-based OTP at Sun Oct  1 11:43:06 2023: 744459
Your Time-based OTP at Sun Oct  1 11:43:36 2023: 508890
</code></pre>
<h3 id="heading-hmac-based-otps-hotps"><strong>HMAC-based OTPs (HOTPs)</strong></h3>
<p>HOTPs are <strong>event-based OTPs where the moving factor in each code is based on a counter</strong>. Each time the HOTP is requested and validated, the moving factor is incremented based on a counter.</p>
<p>While Time-based OTPs are fantastic, HMAC-based OTPs offer another layer of security. Let's take a look at generating HOTPs.</p>
<p>Start by importing the library and generating the secret key.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pyotp

<span class="hljs-comment"># Create a secret key (keep it secret!)̥</span>
secret_key = pyotp.random_base32()
</code></pre>
<p>Next, you can generate the OTP as below:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pyotp

<span class="hljs-comment"># Create a secret key (keep it secret!)̥</span>
secret_key = pyotp.random_base32()

<span class="hljs-comment"># Generate an OTP using HOTP</span>
hotp = pyotp.HOTP(secret_key)
otp_code = hotp.at(<span class="hljs-number">0</span>)  <span class="hljs-comment"># You can use different counter values for different OTPs</span>

print(<span class="hljs-string">"Your HMAC-based OTP:"</span>, otp_code)
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Your HMAC-based OTP: 469785
</code></pre>
<p>With this code, you'll have a new HMAC-based OTP each time you increment the counter value.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pyotp

<span class="hljs-comment"># Create a secret key (keep it secret!)̥</span>
secret_key = pyotp.random_base32()

<span class="hljs-comment"># Generate an OTP using HOTP</span>
hotp = pyotp.HOTP(secret_key)

print(<span class="hljs-string">"Your HMAC-based OTP at counter 0:"</span>, hotp.at(<span class="hljs-number">0</span>))
print(<span class="hljs-string">"Your HMAC-based OTP at counter 1:"</span>, hotp.at(<span class="hljs-number">1</span>))
print(<span class="hljs-string">"Your HMAC-based OTP at counter 2:"</span>, hotp.at(<span class="hljs-number">2</span>))
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Your HMAC-based OTP at counter 0: 230227
Your HMAC-based OTP at counter 1: 437103
Your HMAC-based OTP at counter 2: 290927
</code></pre>
<h2 id="heading-how-to-customize-the-otp-generation"><strong>How to Customize the OTP Generation?</strong></h2>
<p>Just as you order pizza with customizations like extra cheese and toppings, you can customize the OTPs when generating using PyOTP. You can adjust the length, choose different algorithms, and set expiration periods to suit your needs. These customizations are possible for both the <code>TOTP</code> and <code>HOTP</code> classes.</p>
<p>Let's explore some customization options:</p>
<h3 id="heading-adjusting-otp-length">Adjusting OTP Length</h3>
<p>By default, PyOTP generates OTPs with 6 digits. However, you can easily customize the length of your OTPs. For example, if you want to generate OTPs with 4 digits, you can do so as follows:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pyotp

<span class="hljs-comment"># Create a secret key (keep it secret!)</span>
secret_key = pyotp.random_base32()

<span class="hljs-comment"># Create a TOTP object with a custom OTP length (e.g., 4 digits)</span>
otp = pyotp.TOTP(secret_key, digits=<span class="hljs-number">4</span>)

<span class="hljs-comment"># Generate and print the OTP</span>
print(<span class="hljs-string">"You 4-Digit OTP:"</span>, otp.now())
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">You 4-Digit OTP: 9854
</code></pre>
<p>By setting the <code>digits</code> parameter to 4, you've changed the OTP length for this TOTP object to 4 digits instead of the default 6 digits.</p>
<h3 id="heading-handling-otp-expiration"><strong>Handling OTP Expiration</strong></h3>
<p>Sometimes, you might want to set an expiration period for your OTPs. You can do this by specifying the <code>interval</code> parameter when creating a TOTP object. For example, if you want OTPs to expire every 60 seconds, you can configure it like this:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pyotp

<span class="hljs-comment"># Create a secret key (keep it secret!)</span>
secret_key = pyotp.random_base32()

<span class="hljs-comment"># Create a TOTP object with a custom expiration interval (60 seconds)</span>
otp = pyotp.TOTP(secret_key, interval=<span class="hljs-number">60</span>)

<span class="hljs-comment"># Generate and print the OTP</span>
print(<span class="hljs-string">"OTP with 60-second expiration:"</span>, otp.now())
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">OTP with 60-second expiration: 144980
</code></pre>
<p>To verify this, you can set your code to sleep for 30 seconds, and see that the same OTP is printed twice in a minute:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> time
<span class="hljs-keyword">import</span> pyotp

<span class="hljs-comment"># Create a secret key (keep it secret!)̥</span>
secret_key = pyotp.random_base32()


otp = pyotp.TOTP(secret_key, interval=<span class="hljs-number">60</span>)
<span class="hljs-comment"># Generate an OTP using TOTP after every 60 seconds</span>
<span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
    print(<span class="hljs-string">f"Your Time-based OTP at <span class="hljs-subst">{time.ctime()}</span>:"</span>, otp.now())

    time.sleep(<span class="hljs-number">30</span>)
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Your Time-based OTP at Sun Oct  1 12:22:11 2023: 043977
Your Time-based OTP at Sun Oct  1 12:22:41 2023: 043977
Your Time-based OTP at Sun Oct  1 12:23:11 2023: 491773
Your Time-based OTP at Sun Oct  1 12:23:41 2023: 491773
Your Time-based OTP at Sun Oct  1 12:24:11 2023: 468957
</code></pre>
<p>There are more customizations available but they are out of scope for this tutorial. By customizing OTP generation in these ways, you can tailor your OTPs to fit your application's security requirements and user experience.</p>
<h2 id="heading-how-to-verify-the-otps">How to Verify the OTPs?</h2>
<p>Creating OTPs is just one side of the coin; verifying them is equally important. PyOTP simplifies OTP verification through its <code>verify</code> method. Let's explore how to verify OTPs using PyOTP.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pyotp

<span class="hljs-comment"># Create a secret key (keep it secret!)̥</span>
secret_key = pyotp.random_base32()

otp = pyotp.TOTP(secret_key, interval=<span class="hljs-number">60</span>)
<span class="hljs-comment"># Generate an OTP using TOTP after every 30 seconds</span>
print(<span class="hljs-string">"Your TOTP is: "</span>, otp.now())

user_otp = input(<span class="hljs-string">"Enter the OTP: "</span>)
<span class="hljs-keyword">if</span> (otp.verify(user_otp)):
    print(<span class="hljs-string">"Access granted!"</span>)
<span class="hljs-keyword">else</span>:
    print(<span class="hljs-string">"Incorrect OTP"</span>)
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Your TOTP is:  747559
Enter the OTP: 747559
Access granted!
</code></pre>
<pre><code class="lang-bash">Your TOTP is:  676707
Enter the OTP: 123456
Incorrect OTP
</code></pre>
<p>By using the <code>verify</code> method, you can easily determine whether the user-provided OTP matches the expected OTP generated from the secret key. If they match, access is granted; otherwise, access is denied.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Now that you've got your OTP-generating skills down, you can integrate OTPs into your Python applications. In a world where "password123" just won't cut it anymore, OTPs are your digital knights in shining armor. PyOTP, with its Pythonic charm, makes implementing OTPs a breeze. So, go ahead, give it a try, and keep those cyber villains at bay.</p>
]]></content:encoded></item></channel></rss>