<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nishanthan</title>
    <description>The latest articles on DEV Community by Nishanthan (@nishanthan-k).</description>
    <link>https://dev.to/nishanthan-k</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2117032%2F840671b3-0012-4e95-8c3a-fce7ced0a21c.png</url>
      <title>DEV Community: Nishanthan</title>
      <link>https://dev.to/nishanthan-k</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nishanthan-k"/>
    <language>en</language>
    <item>
      <title>Core Elements of Large Language Models (LLMs): Tokens, Context Windows, Temperature, and Sampling</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Mon, 26 Oct 2026 11:30:00 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/core-elements-of-large-language-models-llms-tokens-context-windows-temperature-and-sampling-2m45</link>
      <guid>https://dev.to/nishanthan-k/core-elements-of-large-language-models-llms-tokens-context-windows-temperature-and-sampling-2m45</guid>
      <description>&lt;p&gt;Large Language Models (LLMs) have become a fundamental part of modern AI applications, powering everything from conversational chatbots to code generation and intelligent assistants. While their capabilities may seem complex, understanding the core elements behind how they process and generate text provides a clearer picture of how they work.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore some of the fundamental concepts behind LLMs, including tokens, context windows, temperature, Top-K sampling, Top-P sampling, and repetition penalties. Understanding these elements will help you build a stronger foundation in LLMs and understand how different parameters influence their outputs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Tokens?
&lt;/h2&gt;

&lt;p&gt;Tokens are individual units of data that are fed into a model during training. They can be words, phrases, or even entire sentences depending on the type of model being trained.&lt;/p&gt;

&lt;p&gt;For example, in NLP, tokens are commonly used to represent words in a text. Consider the sentence "Hello, world!" - it might be tokenized into &lt;code&gt;["Hello", ",", "world", "!"]&lt;/code&gt;. These tokens are then used as inputs for the model to learn patterns and relationships between them.&lt;/p&gt;

&lt;p&gt;Tokens can also represent other types of data such as numerical values or images. For instance, in image recognition tasks, each pixel in an image is a token that the model uses to identify and classify objects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Tokens
&lt;/h3&gt;

&lt;p&gt;Tokens can take many forms depending on the type of data and the task at hand. Let’s look at a brief overview of the common types of tokens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Word Tokens:&lt;/strong&gt; Each word is treated as a separate token.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subword Tokens:&lt;/strong&gt; Words are broken down into smaller meaningful units to handle out-of-vocabulary words better. E.g. "cats" can be broken down into "cat" and "s".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phrase Tokens:&lt;/strong&gt; These consist of multiple words that are grouped together, such as "New York City" or "machine learning".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Character Tokens:&lt;/strong&gt; These represent individual characters within a word.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image Tokens:&lt;/strong&gt; These can include pixels, image segments, or other visual features used in computer vision tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Byte-Pair Encoding (BPE):&lt;/strong&gt; This is a type of tokenization that uses an algorithm to merge the most frequently occurring character pairs in a given text corpus. BPE is commonly used in speech recognition and natural language processing tasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Context Window
&lt;/h2&gt;

&lt;p&gt;The context window (or “context length”) of a large language model (LLM) is the amount of text, in tokens, that the model can consider or “remember” at any one time. A larger context window enables an AI model to process longer inputs and incorporate a greater amount of information into each output.&lt;/p&gt;

&lt;p&gt;An LLM’s context window can be thought of as the equivalent of its working memory. It determines how long of a conversation it can carry out without forgetting details from earlier in the exchange. It also determines the maximum size of documents or code samples that it can process at once. When a prompt, conversation, document or code base exceeds an artificial intelligence model’s context window, it must be truncated or summarized for the model to proceed.&lt;/p&gt;

&lt;p&gt;Generally speaking, increasing an LLM’s context window size translates to increased accuracy, fewer hallucinations, more coherent model responses, longer conversations and an improved ability to analyze longer sequences of data. However, increasing context length is not without tradeoffs: it often entails increased computational power requirements and therefore increased costs.&lt;/p&gt;

&lt;p&gt;Equipping a model with a large context window comes at a cost, both figuratively and literally. Compute requirements scale quadratically with the length of a sequence: for instance, if the number of input tokens doubles, the model needs 4 times as much processing power to handle it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Temperature
&lt;/h2&gt;

&lt;p&gt;Temperature is a crucial feature for controlling randomness in model performance. It allows users to adjust the LLM output to better suit different real-world applications of text generation. More specifically, this LLM setting allows users to balance coherence and creativity when generating output for a specific use case. For instance, a low temperature might be preferable for tasks requiring precision and factual accuracy, such as technical documentation or conversational replies with chatbots. The lower temperature value helps the LLM to produce more coherent and consistent text and avoid irrelevant responses. By contrast, a high temperature is preferable for creative outputs or creative tasks such as creative writing or concept brainstorming. The temperature setting effectively allows users to fine-tune LLMs and adjust a model's output to their own desired outcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top-K Sampling
&lt;/h2&gt;

&lt;p&gt;Top-K sampling limits the model to choosing from the K most likely tokens at each step. For instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If top-K = 20, the model only considers the 20 most probable tokens, ignoring less likely ones. This makes responses more focused and factual.&lt;/li&gt;
&lt;li&gt;If top-K = 40, the model has more options, which adds variety but can introduce less predictable results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of top-K as narrowing the model’s “vocabulary” to a shortlist of top contenders. A smaller K value keeps things tight and controlled, while a larger K allows for more creativity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top-P (Nucleus Sampling)
&lt;/h2&gt;

&lt;p&gt;Top-P sampling, also called nucleus sampling, selects a group of tokens whose cumulative probability is at least P. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If top-P = 0.9, the model picks the smallest set of tokens whose combined probability reaches 90%. This filters out low-probability tokens, balancing accuracy and creativity.&lt;/li&gt;
&lt;li&gt;A lower top-P (e.g., 0.8) makes the output more conservative, while a higher top-P (e.g., 0.99) allows more diversity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike top-K, which fixes the number of tokens, top-P dynamically adjusts based on probability, making it more flexible for tasks requiring varied outputs.&lt;/p&gt;

&lt;h3&gt;
  
  
  How They Work Together
&lt;/h3&gt;

&lt;p&gt;Top-K and top-P are often used alongside temperature, which controls the randomness of the model’s choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low temperature (e.g., 0.1) makes the model stick closely to high-probability tokens, ideal for precise tasks.&lt;/li&gt;
&lt;li&gt;High temperature (e.g., 0.9) increases randomness, boosting creativity but risking incoherent outputs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Repetition Penalty
&lt;/h2&gt;

&lt;p&gt;A repetition penalty is an inference-time decoding parameter in Large Language Models (LLMs) that reduces the probability of generating tokens that have already appeared in the text. It helps prevent repetitive phrases and endless loops during text generation.&lt;/p&gt;

&lt;p&gt;The penalty is applied to previously encountered tokens by modifying their logits before the next token is selected.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1.0:&lt;/strong&gt; No penalty is applied.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Greater than 1.0:&lt;/strong&gt; Repeated tokens are discouraged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Too high:&lt;/strong&gt; Can make the output unnatural or reduce clarity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repetition penalty is useful in chatbots, content generation, and long-form text generation. However, excessive penalties can discourage necessary word repetition and affect the quality of responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding the core elements of LLMs is an important step toward understanding how modern language models work. From breaking text into tokens and processing information within a context window to controlling output generation through temperature, sampling strategies, and repetition penalties, each element plays a role in shaping the model's behavior.&lt;/p&gt;

&lt;p&gt;These concepts provide a foundation for exploring more advanced topics, such as Transformer architecture, attention mechanisms, model inference, and LLM optimization. As you continue learning about LLMs, understanding these fundamentals will help you move beyond simply using AI models to understanding how to configure, optimize, and build applications around them.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>ai</category>
      <category>genai</category>
    </item>
    <item>
      <title>How Query, Key, and Value (QKV) Work in Transformers</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Thu, 22 Oct 2026 08:17:29 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/how-query-key-and-value-qkv-work-in-transformers-199a</link>
      <guid>https://dev.to/nishanthan-k/how-query-key-and-value-qkv-work-in-transformers-199a</guid>
      <description>&lt;p&gt;Every Transformer-based language model, from BERT to GPT, relies on a mechanism called &lt;em&gt;attention&lt;/em&gt; to determine how different tokens in a sequence relate to one another. At the heart of this mechanism are three representations: &lt;strong&gt;Query (Q), Key (K), and Value (V).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's understand what they are, why we need them, and how they work together to help Transformers process language.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What Are Query, Key, and Value (QKV)?
&lt;/h2&gt;

&lt;p&gt;To understand QKV, imagine searching for information in a large collection of documents. You have a question you want answered, each document has information that helps you decide whether it is relevant, and each document contains the actual content you might retrieve.&lt;/p&gt;

&lt;p&gt;The attention mechanism follows a conceptually similar process: it determines what information a token should gather from other tokens in the sequence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query (Q) — What information am I looking for?
&lt;/h3&gt;

&lt;p&gt;A Query represents what a token is looking for in other tokens. It helps determine which tokens contain information relevant to the current token.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key (K) — What information do I match on?
&lt;/h3&gt;

&lt;p&gt;A Key represents the features used to match a token against a Query. It helps determine how relevant that token is to another token's Query.&lt;/p&gt;

&lt;h3&gt;
  
  
  Value (V) — What information do I contribute?
&lt;/h3&gt;

&lt;p&gt;A Value represents the information a token contributes when other tokens attend to it. The attention mechanism combines Values according to the attention weights.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Query&lt;/strong&gt; determines what a token is looking for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key&lt;/strong&gt; helps determine how relevant another token is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value&lt;/strong&gt; supplies the information that gets incorporated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not three different tokens. They are three different representations of tokens, each serving a distinct purpose in the attention mechanism.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Why Do We Need Q, K, and V?
&lt;/h2&gt;

&lt;p&gt;Words get their meaning from context. Consider the word &lt;em&gt;bank&lt;/em&gt; in these two sentences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I deposited money in the bank."&lt;/li&gt;
&lt;li&gt;"We sat on the bank of the river."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The word is the same, but its meaning changes depending on the surrounding words. A Transformer needs a way to understand these relationships.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;self-attention&lt;/strong&gt; comes in. It allows each token to gather relevant information from other tokens in the sequence.&lt;/p&gt;

&lt;p&gt;But how does a token decide which other tokens are relevant and what information to gather from them?&lt;/p&gt;

&lt;p&gt;That's why we need Query, Key, and Value.&lt;/p&gt;

&lt;p&gt;For example, in &lt;em&gt;"The animal was tired because it had been running,"&lt;/em&gt; the token &lt;code&gt;it&lt;/code&gt; can attend to &lt;code&gt;animal&lt;/code&gt; and other relevant words to build a context-aware representation.&lt;/p&gt;

&lt;p&gt;Without this mechanism, the model would have a much harder time connecting information across a sequence. QKV gives self-attention a flexible, learnable way to determine which tokens should influence one another and how their information should be combined.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; Queries and Keys help determine where attention goes, while Values determine what information is gathered.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How Are Q, K, and V Generated?
&lt;/h2&gt;

&lt;p&gt;Now that we understand why Q, K, and V are needed, let's look at how a Transformer actually generates them.&lt;/p&gt;

&lt;p&gt;It starts with the input representations of the tokens. These are arranged into a matrix called (X), where each row represents a token.&lt;/p&gt;

&lt;p&gt;The Transformer then uses three learnable weight matrices to create Query, Key, and Value:&lt;/p&gt;

&lt;p&gt;Q = X × W_Q&lt;/p&gt;

&lt;p&gt;K = X × W_K&lt;/p&gt;

&lt;p&gt;V = X × W_V&lt;/p&gt;

&lt;p&gt;Here, (W_Q), (W_K), and (W_V) are &lt;strong&gt;learnable weight matrices&lt;/strong&gt;. Each transforms the input representations into a different representation for its specific role.&lt;/p&gt;

&lt;p&gt;Why three matrices? Because the model needs to learn what information is useful for calculating attention scores and what information should be passed along through the Values.&lt;/p&gt;

&lt;p&gt;These matrices are learned during training through backpropagation and gradient-based optimization.&lt;/p&gt;

&lt;p&gt;The important point is that &lt;strong&gt;Q, K, and V are not manually defined. The model learns how to generate them from the input representations.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. How Do Queries and Keys Calculate Attention?
&lt;/h2&gt;

&lt;p&gt;Once the Transformer generates Q, K, and V, it needs to determine how relevant each token is to the others. This is where Queries and Keys come into play.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Calculate Attention Scores
&lt;/h3&gt;

&lt;p&gt;The model multiplies the Query matrix (Q) by the transpose of the Key matrix (K):&lt;/p&gt;

&lt;p&gt;S = Q × Kᵀ&lt;/p&gt;

&lt;p&gt;Each score represents how strongly a token's Query matches another token's Key. Higher scores generally lead to higher attention weights, although these scores are learned representations rather than direct measures of semantic similarity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Scale the Scores
&lt;/h3&gt;

&lt;p&gt;Before applying softmax, the model divides the scores by the square root of the Key dimension, (d_k):&lt;/p&gt;

&lt;p&gt;S_scaled = (Q × Kᵀ) / √dₖ&lt;/p&gt;

&lt;p&gt;This scaling helps prevent the dot products from becoming excessively large, which can cause softmax to produce very peaked distributions and make optimization less effective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Apply Softmax
&lt;/h3&gt;

&lt;p&gt;Finally, softmax converts the scaled scores into normalized attention weights:&lt;/p&gt;

&lt;p&gt;A = softmax((Q × Kᵀ) / √dₖ)&lt;/p&gt;

&lt;p&gt;Each row of (A) contains the attention weights for one token, indicating how its attention is distributed across the available tokens. In causal language models, an attention mask prevents tokens from attending to future positions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; Queries and Keys calculate relevance scores, scaling helps stabilize them, and softmax converts them into attention weights.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. How Do Values Produce Contextual Information?
&lt;/h2&gt;

&lt;p&gt;After calculating the attention weights, the Transformer uses them to determine how much information to gather from each token. This is where &lt;strong&gt;Values (V)&lt;/strong&gt; come into play.&lt;/p&gt;

&lt;p&gt;The attention weights are multiplied by the Value matrix to produce the attention output:&lt;/p&gt;

&lt;p&gt;O = A × V&lt;/p&gt;

&lt;p&gt;Substituting the attention formula gives us the complete scaled dot-product attention equation:&lt;/p&gt;

&lt;p&gt;Attention(Q, K, V) = softmax((Q × Kᵀ) / √dₖ) × V&lt;/p&gt;

&lt;p&gt;Here, each token's output is a weighted combination of the Value vectors from the tokens it is allowed to attend to.&lt;/p&gt;

&lt;p&gt;For example, when processing &lt;em&gt;"The animal was tired because it had been running,"&lt;/em&gt; the representation of &lt;code&gt;it&lt;/code&gt; can incorporate information from &lt;code&gt;animal&lt;/code&gt; and other relevant tokens, helping the model build a context-aware representation.&lt;/p&gt;

&lt;p&gt;The model does not simply select the token with the highest attention score. Instead, it generally combines information from multiple tokens according to their attention weights.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; Queries and Keys determine how attention is distributed, while Values carry the information that gets combined to produce the attention output.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. QKV in Multi-Head Attention
&lt;/h2&gt;

&lt;p&gt;So far, we've explored how a single attention mechanism uses Query, Key, and Value to determine relationships between tokens and combine information. But what if a Transformer needs to capture different types of relationships at the same time?&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Multi-Head Attention&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;Instead of using a single attention mechanism, the Transformer uses multiple attention heads, each with its own learned Query, Key, and Value projections. Different heads can learn to focus on different patterns, such as grammatical relationships or connections between entities.&lt;/p&gt;

&lt;p&gt;Each head calculates attention independently:&lt;/p&gt;

&lt;p&gt;headᵢ = Attention(X × WᵢQ, X × WᵢK, X × WᵢV)&lt;/p&gt;

&lt;p&gt;The outputs from all heads are then concatenated and passed through a final learnable projection matrix:&lt;/p&gt;

&lt;p&gt;MultiHead(Q, K, V) = Concat(head₁, ..., headₕ) × Wᴼ&lt;/p&gt;

&lt;p&gt;Here, (h) is the number of attention heads, and (W^O) is the output projection matrix.&lt;/p&gt;

&lt;p&gt;By allowing multiple attention heads to operate in parallel, Transformers can learn different patterns of relationships within the same sequence and combine them into a single representation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; Each attention head learns its own way of gathering information, and the output projection combines the results into a unified representation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Query, Key, and Value form the foundation of the attention mechanism in Transformers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Query&lt;/strong&gt; determines what information a token is looking for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key&lt;/strong&gt; helps determine which tokens are relevant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value&lt;/strong&gt; carries the information that gets incorporated into the output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, they enable self-attention to calculate relationships between tokens and build context-aware representations. Multi-Head Attention extends this idea by allowing multiple attention mechanisms to learn different patterns in parallel.&lt;/p&gt;

&lt;p&gt;Understanding QKV is an important step toward understanding how Transformers process language and how modern large language models work under the hood.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>deeplearning</category>
      <category>nlp</category>
      <category>llm</category>
    </item>
    <item>
      <title>Understanding Transformer: The Architecture Behind Modern AI</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Thu, 15 Oct 2026 03:30:00 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/understanding-transformer-the-architecture-behind-modern-ai-55o8</link>
      <guid>https://dev.to/nishanthan-k/understanding-transformer-the-architecture-behind-modern-ai-55o8</guid>
      <description>&lt;h3&gt;
  
  
  What Is a Transformer?
&lt;/h3&gt;

&lt;p&gt;A Transformer is a neural network architecture introduced by Google researchers in 2017 in the paper &lt;em&gt;Attention Is All You Need&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It uses attention mechanisms to help the model learn relationships between tokens. Unlike recurrent neural networks (RNNs) and long short-term memory networks (LSTMs), which process sequences through recurrent steps, Transformers can process input token representations in parallel during training.&lt;/p&gt;

&lt;p&gt;The Transformer architecture combines attention with other components, including &lt;strong&gt;feed-forward neural networks&lt;/strong&gt;, &lt;strong&gt;positional information&lt;/strong&gt;, &lt;strong&gt;residual connections&lt;/strong&gt;, and &lt;strong&gt;normalization&lt;/strong&gt;, to build &lt;strong&gt;contextual representations&lt;/strong&gt; of input tokens.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4mobgwpainkboglup1ep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4mobgwpainkboglup1ep.png" alt="Transformer" width="407" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Were Transformers Introduced?
&lt;/h3&gt;

&lt;p&gt;Transformers addressed important limitations of recurrent neural networks (RNNs) in sequence processing.&lt;/p&gt;

&lt;p&gt;Two key motivations were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Learning relationships between tokens:&lt;/strong&gt; RNNs and LSTMs can struggle to capture dependencies between tokens that are far apart. Transformers use attention mechanisms to let tokens incorporate information from other relevant tokens directly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Parallel processing:&lt;/strong&gt; RNNs process tokens sequentially because each hidden state depends on the previous one. Transformers enable parallel computation across input tokens during training, improving computational efficiency.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Although LSTMs improved the ability of recurrent networks to retain information over long sequences, they did not remove the sequential-processing limitation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Problem Were Transformers Designed to Solve?
&lt;/h3&gt;

&lt;p&gt;Before Transformers, RNNs and LSTMs were widely used to process sequential data, including natural language. They processed tokens sequentially while maintaining a hidden state that carried information from earlier tokens.&lt;/p&gt;

&lt;p&gt;However, these architectures had two important limitations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Difficulty learning long-range dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In recurrent networks, information from earlier tokens must pass through multiple recurrent steps to influence later tokens. During training, gradients can vanish as they propagate through long sequences, making it difficult to learn some long-range relationships. LSTMs mitigate this issue through their cell state and gating mechanisms, but they do not eliminate every difficulty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Limited parallelism&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because each recurrent hidden state depends on the previous state, RNNs and LSTMs cannot compute all hidden states of an input sequence simultaneously. This limits parallel computation during training.&lt;/p&gt;

&lt;p&gt;Transformers introduced an attention-based architecture without recurrence. Self-attention enables tokens to incorporate information from other relevant tokens directly, while the absence of recurrent dependencies allows input token representations to be processed in parallel during training.&lt;/p&gt;

&lt;h3&gt;
  
  
  How RNNs and LSTMs Process Sequences
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;RNN:&lt;/strong&gt; A recurrent neural network processes a sequence one token at a time. At each step, it combines the current token representation with the previous hidden state to produce a new hidden state. This state carries a learned representation of information from the sequence processed so far.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitation:&lt;/strong&gt; As sequences become longer, an RNN can struggle to preserve useful information from earlier tokens. During training, vanishing gradients can also make long-range dependencies difficult to learn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LSTM:&lt;/strong&gt; Long Short-Term Memory networks extend RNNs with a cell state and three gates: forget, input, and output. These mechanisms regulate which information is retained, added, or exposed. They help preserve relevant information over longer sequences and improve gradient flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remaining limitation:&lt;/strong&gt; LSTMs still process tokens sequentially because each recurrent step depends on the previous step. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdpcx8i52draoe60c99yl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdpcx8i52draoe60c99yl.png" alt="RNN &amp;amp; LSTM" width="422" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Was Sequential Processing a Limitation?
&lt;/h3&gt;

&lt;p&gt;RNNs and LSTMs process sequences through recurrent steps, where each hidden state depends on the previous state. This dependency prevents the model from computing all recurrent hidden states simultaneously.&lt;/p&gt;

&lt;p&gt;As a result, these architectures limit parallel computation across sequence positions during training, particularly for long sequences.&lt;/p&gt;

&lt;p&gt;Transformers remove recurrence from the core architecture and use self-attention to process input token representations in parallel during training. This enables more efficient use of modern parallel hardware, although Transformer attention also introduces computational and memory costs as sequence length increases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmptzg7swwdgs8uv0ir85.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmptzg7swwdgs8uv0ir85.png" alt="Sequential Processing" width="353" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Did the 2017 Paper &lt;em&gt;Attention Is All You Need&lt;/em&gt; Introduce?
&lt;/h3&gt;

&lt;p&gt;In 2017, Vaswani and colleagues introduced the Transformer architecture in their paper &lt;em&gt;Attention Is All You Need&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The paper proposed an encoder-decoder architecture that relied on attention mechanisms instead of recurrent or convolutional layers for sequence processing.&lt;/p&gt;

&lt;p&gt;Its key contributions included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Self-attention:&lt;/strong&gt; Allowed tokens to incorporate information from other positions in a sequence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-head attention:&lt;/strong&gt; Enabled the model to learn different relationships through multiple attention heads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallelizable computation:&lt;/strong&gt; Removing recurrence allowed input sequence representations to be processed in parallel during training.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The original Transformer was designed for sequence transduction tasks, particularly machine translation. Its architecture later became the foundation for many language models, including encoder-only, decoder-only, and encoder-decoder models.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7q3n4rnv4xk6oy287i5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7q3n4rnv4xk6oy287i5k.png" alt="Attention Is All You Need" width="354" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do Transformers Process Relationships Between Tokens?
&lt;/h3&gt;

&lt;p&gt;Transformers use a mechanism called &lt;strong&gt;self-attention&lt;/strong&gt; to model relationships between tokens in a sequence.&lt;/p&gt;

&lt;p&gt;Unlike recurrent networks, which pass information through successive hidden states, self-attention allows each token to incorporate information from other relevant tokens directly.&lt;/p&gt;

&lt;p&gt;For each token, the model computes attention scores that determine how much information to gather from other token positions. These scores are converted into weights, which are used to combine information from those tokens and produce updated representations.&lt;/p&gt;

&lt;p&gt;As a result, each token can develop a contextual representation that incorporates information from across the sequence. These representations are then processed by other Transformer components, including feed-forward neural networks.&lt;/p&gt;

&lt;p&gt;This mechanism helps Transformers learn relationships between distant tokens and provides a flexible way to represent context.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fybnhohe3i5ct6065vg8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fybnhohe3i5ct6065vg8d.png" alt="Token semantics" width="514" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Where Are Transformers Used Today?
&lt;/h3&gt;

&lt;p&gt;Transformers have become a foundational architecture in modern AI, with applications across several domains.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Natural language processing:&lt;/strong&gt; Large language models use Transformers for text generation, question answering, coding, summarization, and conversational AI. Transformer-based encoder models are also used for classification and information extraction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine translation:&lt;/strong&gt; Encoder-decoder Transformers learn relationships between source and target sequences to translate between languages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Computer vision:&lt;/strong&gt; Vision Transformers process image patches to perform tasks such as image classification and image understanding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech and audio:&lt;/strong&gt; Transformer-based architectures support speech recognition, transcription, translation, and audio generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multimodal AI:&lt;/strong&gt; These models combine information from modalities such as text, images, audio, and video to support tasks that require understanding multiple forms of input.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Across these applications, the central idea is to learn useful representations and relationships among elements of the input. The specific architecture and training objective depend on the task.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbtkwir5bw6x8o1o1aqfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbtkwir5bw6x8o1o1aqfb.png" alt="Transformer use-cases" width="546" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Transformers marked a significant shift in how neural networks process sequential data. By replacing recurrent processing with attention-based mechanisms, they enabled models to learn relationships between tokens more directly while supporting greater parallelism during training.&lt;/p&gt;

&lt;p&gt;The idea introduced in &lt;em&gt;Attention Is All You Need&lt;/em&gt; in 2017 has since become foundational to modern AI, powering advances in language processing, computer vision, speech, and multimodal systems.&lt;/p&gt;

&lt;p&gt;Understanding Transformers is more than learning a particular neural network architecture. It is understanding how a different approach to representing context and relationships can unlock new capabilities in AI.&lt;/p&gt;

&lt;p&gt;And this is only the beginning. To understand how modern language models work under the hood, the next step is to explore self-attention in detail: how Query, Key, and Value representations are created, how attention scores are calculated, and how those scores determine the information each token receives.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>deeplearning</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Backpropagation in Deep Learning: A Complete, Intuitive, and Practical Guide</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Wed, 17 Dec 2025 03:30:00 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/backpropagation-in-deep-learning-a-complete-intuitive-and-practical-guide-3dm4</link>
      <guid>https://dev.to/nishanthan-k/backpropagation-in-deep-learning-a-complete-intuitive-and-practical-guide-3dm4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: Why Backpropagation Matters
&lt;/h2&gt;

&lt;p&gt;Backpropagation is the &lt;strong&gt;learning engine&lt;/strong&gt; behind modern deep learning.&lt;br&gt;
Every time a neural network improves its predictions — from recognizing faces to generating text — the improvement comes from one mechanism: &lt;strong&gt;adjusting weights using gradients&lt;/strong&gt;, and those gradients are computed through backpropagation.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why this matters:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A neural network is essentially a giant parametric function with millions or billions of weights.&lt;/li&gt;
&lt;li&gt;Backpropagation provides an efficient way to compute how much each weight contributed to the final error.&lt;/li&gt;
&lt;li&gt;Without backpropagation, training a deep model would be computationally impossible — you’d need to recompute partial derivatives for every weight independently, which would scale exponentially.&lt;/li&gt;
&lt;li&gt;Backprop makes learning &lt;strong&gt;practical&lt;/strong&gt; and &lt;strong&gt;efficient&lt;/strong&gt;, even for very large models.&lt;/li&gt;
&lt;li&gt;It also forms the foundation for:

&lt;ul&gt;
&lt;li&gt;Convolutional networks&lt;/li&gt;
&lt;li&gt;Transformers
-Diffusion models&lt;/li&gt;
&lt;li&gt;Reinforcement learning&lt;/li&gt;
&lt;li&gt;Large language models&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;In short, backpropagation is the backbone of modern AI.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What a Neural Network Really Computes (Forward Pass Overview)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Before understanding backpropagation, we need a clear picture of what the network does in the &lt;em&gt;&lt;code&gt;forward pass&lt;/code&gt;&lt;/em&gt; because backprop is simply the &lt;strong&gt;reverse of this computation&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;At its core, a neural network performs three steps repeatedly across layers:

&lt;ol&gt;
&lt;li&gt;Take inputs from the previous layer&lt;/li&gt;
&lt;li&gt;Apply a linear transformation using weights and biases&lt;/li&gt;
&lt;li&gt;Pass the result through a non-linear activation function
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mathematically, for a single layer:

z = Wx + b
a = f(z)

Where:
- x = input vector
- W = weight matrix
- b = bias vector
- z = linear combination (pre-activation)
- f(⋅) = activation function (ReLU, Sigmoid, etc.)
- a = output (activation)

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;A deep network simply &lt;strong&gt;repeats this process&lt;/strong&gt; layer after layer.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Each layer transforms the input into a representation that makes the final task easier — whether that’s classification, detection, language modeling, or something else.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why this matters for backprop:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The forward pass creates a computational graph — &lt;strong&gt;a chain of operations where each output depends on previous ones&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Backprop will move in the opposite direction through this graph, calculating &lt;strong&gt;how changes in each weight affect the final loss&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Knowing the exact operations in the forward pass helps us understand how the gradients flow backward.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Core Idea Behind Backpropagation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  How should each weight in the network change to reduce the final error?”
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A neural network may have millions of parameters, and each parameter influences the output in a slightly different way. Backpropagation provides a systematic method to compute these influences efficiently&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Here’s the core idea in simple terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Calculate the loss&lt;/strong&gt;:  After the forward pass, we compare the model’s prediction with the true label and compute how “wrong” the prediction was.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Determine how the loss changes with respect to the output of the last layer&lt;/strong&gt;. This tells us the immediate direction in which the model should adjust.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Move backward layer by layer&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Using the chain rule, we figure out how the loss depends on:

&lt;ol&gt;
&lt;li&gt; each layer’s activations&lt;/li&gt;
&lt;li&gt;each layer’s weights&lt;/li&gt;
&lt;li&gt;each layer’s inputs&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accumulate gradients&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Every weight gets a gradient value that tells us:

&lt;ul&gt;
&lt;li&gt;direction (positive or negative)&lt;/li&gt;
&lt;li&gt;magnitude (how strong the update should be)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update the weights&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Optimizers like &lt;strong&gt;SGD&lt;/strong&gt; or &lt;strong&gt;Adam&lt;/strong&gt; use these gradients to move the weights to slightly better values.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key insight:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Backprop does not compute gradients from scratch for each weight.&lt;br&gt;
It reuses intermediate results from the forward pass, which makes the entire process efficient.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Understanding the Computational Graph
&lt;/h2&gt;

&lt;p&gt;A neural network can be viewed as a computational graph — a sequence of operations where each node represents a mathematical function, and each edge represents the flow of data.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why this graph matters:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Every value produced during the forward pass (like z, a, activations, etc.) becomes part of the graph.&lt;/li&gt;
&lt;li&gt;Backpropagation relies on this graph to know how outputs depend on earlier computations.&lt;/li&gt;
&lt;li&gt;Deep learning frameworks like PyTorch and TensorFlow automatically build this graph behind the scenes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Chain Rule: The Mathematical Engine of Backpropagation
&lt;/h2&gt;

&lt;p&gt;Backpropagation is built entirely on one mathematical principle: the chain rule of calculus.&lt;br&gt;
If you understand the chain rule, you understand the heart of backprop.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why the chain rule is needed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In a neural network, the loss doesn’t depend on any weight directly.&lt;/li&gt;
&lt;li&gt;Instead, it depends on:

&lt;ul&gt;
&lt;li&gt;the activations of the last layer&lt;/li&gt;
&lt;li&gt;which depend on the previous layer&lt;/li&gt;
&lt;li&gt;which depend on the one before it&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This creates a long chain of dependencies.&lt;/li&gt;
&lt;li&gt;The chain rule tells us how a change in any early variable (like a weight) affects the final loss.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Applying the chain rule to layers
&lt;/h3&gt;

&lt;p&gt;Consider one layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    z = Wx + b
    a = f(z)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the loss:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    L = Loss(a)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the chain rule, the gradient of the loss with respect to the weights is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ∂L/∂W = (∂L/∂a) · (∂a/∂z) · (∂z/∂W)

    where
        ∂L/∂a: how the loss changes with the layer’s output
        ∂a/∂z: how the activation reacts to its input
        ∂z/∂W: how the output of this layer depends on its weights
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step-by-Step Backpropagation Through a Single Neuron
&lt;/h2&gt;

&lt;p&gt;Now that the chain rule and computational graph ideas are clear, let’s walk through backpropagaion &lt;strong&gt;inside one neuron&lt;/strong&gt;.&lt;br&gt;
This is the smallest unit of a neural network, and understanding it removes most of the confusion around deeper models.&lt;/p&gt;
&lt;h3&gt;
  
  
  Forward Pass (Single Neuron)
&lt;/h3&gt;

&lt;p&gt;A neuron computes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    z = Wx + b
    a = f(z)

    where
        x -&amp;gt; input
        W -&amp;gt; weight
        b -&amp;gt; bias
        f -&amp;gt; activation function
        a -&amp;gt; output of the neuron

    L(a): Loss function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Backward Pass (Goal: compute gradients)
&lt;/h3&gt;

&lt;p&gt;We want&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gradient with respect to the activation output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ∂L/∂a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Gradient through the activation function
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ∂L/∂z = (∂L/∂a) · f′(z)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Gradient with respect to the weights
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ∂L/∂W = (∂L/∂z) · x

Since   z = Wx + b

        ∂z/∂W = x

So,
        ∂L/∂W = ∂L/∂z * x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Gradient with respect to the bias
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        ∂z/∂b = 1
So,
        ∂L/∂b = ∂L/∂z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Gradient with respect to the input
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        ∂L/∂x = (∂L/∂z) · W
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Backpropagation is more than a mathematical procedure — it’s the core mechanism that allows neural networks to learn.&lt;br&gt;
Once you understand how gradients flow through a network, you gain the ability to reason about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why certain architectures train well?&lt;/li&gt;
&lt;li&gt;Why others fail?&lt;/li&gt;
&lt;li&gt;How initialization, activations, normalization, and residual connections shape gradient behavior?&lt;/li&gt;
&lt;li&gt;What makes transformers, CNNs, and deep RNNs stable?&lt;/li&gt;
&lt;li&gt;How to debug training issues with confidence?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The deeper your intuition for backpropagation, the more effective you become at designing and improving models.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>deeplearning</category>
    </item>
    <item>
      <title>Neural Network — A Simple, Beginner-Friendly Overview</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Mon, 01 Dec 2025 03:30:00 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/neural-network-a-simple-beginner-friendly-overview-16p8</link>
      <guid>https://dev.to/nishanthan-k/neural-network-a-simple-beginner-friendly-overview-16p8</guid>
      <description>&lt;p&gt;Neural networks are at the heart of modern AI. Whether it’s image recognition, chatbots, or recommendation systems, they all rely on these interconnected structures to learn patterns from data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Neural Network?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A neural network is made up of many &lt;strong&gt;interconnected nodes (neurons)&lt;/strong&gt;, each acting like a tiny decision-making unit.
&lt;/li&gt;
&lt;li&gt;Every connection between neurons carries a &lt;strong&gt;weight&lt;/strong&gt;, which is a parameter the model learns during training.
&lt;/li&gt;
&lt;li&gt;These weights determine how strongly one neuron influences another, and they are gradually adjusted so the network can make better predictions over time.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How Are the Values Estimated?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When training begins, each neuron starts with &lt;strong&gt;random weights&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;These weights are updated through &lt;strong&gt;backpropagation&lt;/strong&gt;, a feedback process that adjusts them based on how wrong the model’s prediction was.
&lt;/li&gt;
&lt;li&gt;The update depends on:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Loss value:&lt;/strong&gt; how far the prediction was from correct
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradient:&lt;/strong&gt; the direction the weight should move
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning rate:&lt;/strong&gt; how big each step of adjustment should be
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The goal is to &lt;strong&gt;reduce the loss&lt;/strong&gt; and push the &lt;strong&gt;gradient closer to zero&lt;/strong&gt; over time.
&lt;/li&gt;
&lt;li&gt;Interpreting the gradient:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Positive gradient → decrease the weight&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Negative gradient → increase the weight&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Neural Networks?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Traditional machine learning works well when data patterns are &lt;strong&gt;linear&lt;/strong&gt;, meaning they follow straight-line relationships.
&lt;/li&gt;
&lt;li&gt;Neural networks shine because they use &lt;strong&gt;activation functions&lt;/strong&gt; to introduce &lt;strong&gt;non-linearity&lt;/strong&gt;, enabling them to learn complex patterns — shapes, edges, behaviors, and any relationship that isn’t simple or straight.
&lt;/li&gt;
&lt;li&gt;Popular activation functions include &lt;strong&gt;ReLU&lt;/strong&gt;, &lt;strong&gt;Sigmoid&lt;/strong&gt;, and &lt;strong&gt;Softplus&lt;/strong&gt;, each influencing how a neuron activates.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Layers in a Neural Network
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Input Layer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The network begins with an input layer containing multiple nodes.
&lt;/li&gt;
&lt;li&gt;These nodes don’t learn anything — they simply &lt;strong&gt;pass the raw input into the network&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;They are often mistaken for neurons, but their job is mainly to feed data forward.

&lt;ul&gt;
&lt;li&gt;They take the raw data.&lt;/li&gt;
&lt;li&gt;They pass those numbers into the network.&lt;/li&gt;
&lt;li&gt;They do not apply weights, biases, or activations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Because of this, these nodes are often mistaken for “neurons” but they’re better understood as data carriers — a doorway into the network rather than processors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hidden Layers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A network may have one or several hidden layers, each filled with neurons.
&lt;/li&gt;
&lt;li&gt;These are the &lt;strong&gt;actual learning units&lt;/strong&gt;, transforming the input step by step to capture patterns in the data.

&lt;ul&gt;
&lt;li&gt;It receives input from the previous layer&lt;/li&gt;
&lt;li&gt;Applies &lt;strong&gt;weights&lt;/strong&gt; and &lt;strong&gt;biases&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Passes the result through an &lt;strong&gt;activation function&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;And sends the output deeper into the network&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This repeated transformation allows the model to gradually extract patterns — edges in images, sentiment in text, or trends in numerical data.&lt;/li&gt;
&lt;li&gt;Layer by layer, the network builds up a more meaningful internal representation of the input.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Output Layer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The final layer, responsible for producing the network’s output — a prediction, probability, class label, etc.&lt;/li&gt;
&lt;li&gt;Depending on the problem, this layer may output:

&lt;ul&gt;
&lt;li&gt; A single number&lt;/li&gt;
&lt;li&gt; A vector of probabilities&lt;/li&gt;
&lt;li&gt; A class label&lt;/li&gt;
&lt;li&gt; A multi-dimensional prediction&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Like hidden neurons, output neurons also use weights, biases, and sometimes an activation function (e.g., sigmoid or softmax).&lt;/li&gt;
&lt;li&gt;The only difference is that this layer’s output is directly interpreted as the model’s answer.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The 5-Step Life Cycle of a Neuron (Applies to Every Layer Except Input)
&lt;/h2&gt;

&lt;p&gt;Every neuron inside a neural network — whether in a hidden layer or the output layer — follows the exact same processing routine. Understanding this cycle is key to building intuition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. It receives inputs (activations).&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;These activations come from either the input layer or the previous hidden layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. It multiplies each input by its corresponding weight.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Weights determine how strongly the neuron should pay attention to each incoming value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. It adds a bias.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The bias shifts the weighted sum, giving the neuron flexibility to activate even when inputs are small or zero.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. It applies an activation function.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The weighted sum plus bias (called the pre-activation, or z) goes through a function like ReLU, sigmoid, or tanh.&lt;/li&gt;
&lt;li&gt;This step introduces non-linearity — essential for learning complex patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. It outputs a new activation.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This final value (a) becomes the input to the next layer, allowing the network to stack transformations and build rich representations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;A neural network is essentially a repeated cycle of: &lt;strong&gt;input → weighted sum → bias → activation → output&lt;/strong&gt; layer after layer, until the final prediction is produced.&lt;/p&gt;

&lt;p&gt;This is a gentle introduction to neural networks — enough to understand what they are made of and how they learn. From here, you can explore topics like &lt;strong&gt;activation functions, optimizers, loss functions, and different neural architectures&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>deeplearning</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>How Neural Networks Learn – A Simple Guide to Machine Learning &amp; Deep Learning</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Fri, 28 Nov 2025 04:30:00 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/how-a-model-really-learns-from-loss-to-learning-in-machine-learning-deep-learning-26b0</link>
      <guid>https://dev.to/nishanthan-k/how-a-model-really-learns-from-loss-to-learning-in-machine-learning-deep-learning-26b0</guid>
      <description>&lt;p&gt;Machine Learning and Deep Learning are often treated as black boxes filled with complex math and jargon. But at their core, they are built on a few simple ideas: measuring error, understanding direction, and making small improvements over time.&lt;/p&gt;

&lt;p&gt;In this article, I break down how a model &lt;em&gt;actually learns&lt;/em&gt; — from the moment it makes a mistake, to how that mistake travels backward through the network to update weights and improve future predictions. Starting from a simple equation, we’ll build up to neural networks and the complete training loop, step by step.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Intelligence, Patterns, and Models
&lt;/h2&gt;

&lt;p&gt;Human intelligence works by building &lt;strong&gt;mental models&lt;/strong&gt; of the world.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Black clouds + strong wind → We expect rain
&lt;/li&gt;
&lt;li&gt;Sometimes this is wrong (it could be a cloud shadow)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Over time, the brain refines these models.&lt;/p&gt;

&lt;p&gt;Machine Learning works the same way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Input → Pattern → Output&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The system learns relationships from data, not rules written manually.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;em&gt;model&lt;/em&gt; is simply a mathematical way of representing this pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Core Idea: Model as an Equation
&lt;/h2&gt;

&lt;p&gt;The simplest model looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = mX + b

Where:
X = input
y = output
m and b = parameters (values to be learned)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Machine Learning, this is often written as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = wX + b

Here:
w = weight (importance of input)
b = bias (base value added to the output)

The entire goal of training is to find the best values of w and b so the prediction matches reality.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Loss Function — Measuring Mistakes
&lt;/h2&gt;

&lt;p&gt;Once the model makes a prediction, it needs to know: “How wrong am I?” That’s the job of the loss function.&lt;/p&gt;

&lt;h3&gt;
  
  
  A loss function:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Compares actual output and predicted output&lt;/li&gt;
&lt;li&gt;Returns a number that shows how bad the prediction was&lt;/li&gt;
&lt;li&gt;High loss → very wrong&lt;/li&gt;
&lt;li&gt;Low loss → close to correct&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This number becomes the main guiding signal for learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Gradient — Finding the Direction of Improvement
&lt;/h2&gt;

&lt;p&gt;After loss is calculated, the model asks: “In which direction should I change my parameters to reduce this error?” The gradient is that direction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intuitively:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A positive gradient means: if we increase this parameter, loss will go up&lt;/li&gt;
&lt;li&gt;A negative gradient means: if we increase this parameter, loss will go down&lt;/li&gt;
&lt;li&gt;A zero gradient means: we are at a flat point (often a minimum)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Learning Rate — Controlling the Speed of Learning
&lt;/h2&gt;

&lt;p&gt;The learning rate controls how much the parameter is allowed to change in each step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Conceptually, the update rule is:

new_weight = old_weight - (learning_rate × gradient)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If the learning rate is too large → the model jumps wildly, overshoots, and becomes unstable&lt;/li&gt;
&lt;li&gt;If the learning rate is too small → the model moves very slowly and takes forever to learn&lt;/li&gt;
&lt;li&gt;If the learning rate is reasonable → learning is smooth and stable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the learning rate is simply the step size of learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Epoch — Repeating the Learning Process
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One epoch means the model has seen the entire training dataset once.&lt;/li&gt;
&lt;li&gt;During an epoch, the model would makes predictions on all training data

&lt;ul&gt;
&lt;li&gt;Calculates the loss&lt;/li&gt;
&lt;li&gt;Updates the parameters&lt;/li&gt;
&lt;li&gt;Repeats this process for the next epoch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;More epochs → more opportunities to learn&lt;/li&gt;
&lt;li&gt;Too many epochs → the model may start memorizing instead of generalizing (this is called overfitting)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Batch — Dividing the Dataset
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Instead of feeding the entire dataset to the model at once, we split it into batches.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example:

Dataset size: 1000 samples
Batch size: 100
Then per epoch, we have: 1000 / 100 = 10 batches

So the model updates its parameters 10 times in one epoch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Benefits of batching:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reduces memory usage&lt;/li&gt;
&lt;li&gt;Gives more frequent parameter updates&lt;/li&gt;
&lt;li&gt;Often leads to better and more stable learning&lt;/li&gt;
&lt;li&gt;There is no single “perfect” batch size. It depends on:

&lt;ul&gt;
&lt;li&gt;Dataset size&lt;/li&gt;
&lt;li&gt;Available hardware (CPU/GPU, RAM/VRAM)&lt;/li&gt;
&lt;li&gt;Model size and complexity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Weights and Bias — Making Real-World Sense
&lt;/h2&gt;

&lt;p&gt;Earlier, we saw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = mX + b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In ML terms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = wX + b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;w (weight) represents how important an input is&lt;/li&gt;
&lt;li&gt;b (bias) is a base value added regardless of the input&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: Courier Charges
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;₹100 per kg → weight&lt;/li&gt;
&lt;li&gt;₹50 base charge → bias&lt;/li&gt;
&lt;li&gt;Even if the parcel weighs 0 kg, you still pay ₹50.&lt;/li&gt;
&lt;li&gt;Without the bias term, the model would be forced to predict ₹0 when the input is 0. Bias lets us shift the line up or down and represent real “base” behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;So bias is needed so that:&lt;/p&gt;

&lt;p&gt;The model is not forced to pass through (0, 0), and can better fit real-world data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  9. Neural Network — From One Equation to Many
&lt;/h2&gt;

&lt;p&gt;A single neuron performs a calculation like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = w1·x1 + w2·x2 + ... + wn·xn + b

- It takes many inputs
- Multiplies each by its own weight
- Adds them up and adds a bias
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;A layer is a group of neurons working in parallel on the same input.&lt;/li&gt;
&lt;li&gt;A neural network is a stack of such layers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why use neural networks?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A single linear equation is limited to straight-line relationships&lt;/li&gt;
&lt;li&gt;Neural networks, combined with activation functions, can model complex, non-linear patterns&lt;/li&gt;
&lt;li&gt;This is what enables them to handle images, text, audio, and other complex data&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. Activation Function — The Source of Non-Linearity
&lt;/h2&gt;

&lt;p&gt;After a neuron computes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;z = w·x + b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We apply an activation function to get the final output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a = activation(z)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Activation functions:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Introduce non-linearity&lt;/li&gt;
&lt;li&gt;Allow the network to learn complex patterns and decision boundaries&lt;/li&gt;
&lt;li&gt;Enable tasks such as:

&lt;ul&gt;
&lt;li&gt;Image classification&lt;/li&gt;
&lt;li&gt;Object detection&lt;/li&gt;
&lt;li&gt;Natural language processing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Without activation functions:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Every neuron is just a linear transformation&lt;/li&gt;
&lt;li&gt;Stacking multiple linear layers still gives a linear function&lt;/li&gt;
&lt;li&gt;The network would be no more powerful than a single linear model&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;In short:&lt;/p&gt;

&lt;p&gt;Activation functions are what make neural networks more powerful than simple linear models.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  11. Forward Propagation — Data Moving Through the Network
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Forward propagation is the process of passing data through the network to produce an output.&lt;/li&gt;
&lt;li&gt;Steps:

&lt;ul&gt;
&lt;li&gt;Input data is fed into the input layer&lt;/li&gt;
&lt;li&gt;Each neuron in the next layer:&lt;/li&gt;
&lt;li&gt;Multiplies inputs by weights&lt;/li&gt;
&lt;li&gt;Adds bias&lt;/li&gt;
&lt;li&gt;Applies activation function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The output of one layer becomes the input to the next layer&lt;/li&gt;
&lt;li&gt;This continues until the final output layer produces the prediction&lt;/li&gt;
&lt;li&gt;Flow: &lt;code&gt;Input → Hidden layer 1 → Hidden layer 2 → ... → Output layer&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Important:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Forward propagation only computes the outputs.&lt;/li&gt;
&lt;li&gt;No learning or weight updates happen in this step.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  12. Backward Propagation — Learning From Mistakes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;After forward propagation, we:

&lt;ul&gt;
&lt;li&gt;Compare the prediction with the actual target&lt;/li&gt;
&lt;li&gt;Compute the loss (error)&lt;/li&gt;
&lt;li&gt;Now the model needs to adjust its weights to reduce this loss.&lt;/li&gt;
&lt;li&gt;This is where backward propagation (backprop) comes in.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Backpropagation:

&lt;ul&gt;
&lt;li&gt;Sends the error signal backward from the output layer toward the input layer&lt;/li&gt;
&lt;li&gt;Computes, for each weight and bias, how much it contributed to the error (its gradient)&lt;/li&gt;
&lt;li&gt;Once gradients are known, we update parameters using gradient descent:

&lt;ul&gt;
&lt;li&gt;new_weight = old_weight - (learning_rate × gradient)&lt;/li&gt;
&lt;li&gt;new_bias   = old_bias   - (learning_rate × gradient)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;So:

&lt;ul&gt;
&lt;li&gt;Backpropagation calculates gradients;&lt;/li&gt;
&lt;li&gt;Gradient descent + learning rate perform the actual update.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Backpropagation is the core of how the network learns.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  13. The Complete Training Cycle
&lt;/h2&gt;

&lt;p&gt;Putting everything together, a full training loop for a neural network looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Input data is passed into the network&lt;/li&gt;
&lt;li&gt;Forward propagation computes the prediction&lt;/li&gt;
&lt;li&gt;Loss function measures how wrong the prediction&lt;/li&gt;
&lt;li&gt;Backward propagation computes gradients for all weights and biases&lt;/li&gt;
&lt;li&gt;Gradient descent updates the parameters using the learning rate&lt;/li&gt;
&lt;li&gt;This is repeated for:

&lt;ul&gt;
&lt;li&gt;Every batch&lt;/li&gt;
&lt;li&gt;Across multiple epochs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;In one line:&lt;/p&gt;

&lt;p&gt;Input → Forward Propagation → Loss → Backpropagation → Update Weights → Repeat&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;With each cycle:

&lt;ul&gt;
&lt;li&gt;The model becomes a bit less wrong&lt;/li&gt;
&lt;li&gt;The loss usually goes down&lt;/li&gt;
&lt;li&gt;The predictions improve&lt;/li&gt;
&lt;li&gt;This is the entire training process in a nutshell.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  14. Inference — Using the Trained Model
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Once the model is trained:

&lt;ul&gt;
&lt;li&gt;We freeze the learned weights and biases&lt;/li&gt;
&lt;li&gt;We give it new input data it has never seen&lt;/li&gt;
&lt;li&gt;It runs only forward propagation to produce predictions&lt;/li&gt;
&lt;li&gt;No backpropagation or weight updates happen during inference.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This is the phase where the model is actually used in production:

&lt;ul&gt;
&lt;li&gt;Recommending products&lt;/li&gt;
&lt;li&gt;Classifying images&lt;/li&gt;
&lt;li&gt;Translating text&lt;/li&gt;
&lt;li&gt;Detecting fraud, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;From a simple line like y = wX + b to deep neural networks, everything in Machine Learning and Deep Learning is built on a few core ideas:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Representing patterns with models
- Measuring error with a loss function
- Using gradients to find a better direction
- Controlling change with learning rate
- Repeating the process over batches and epochs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The concepts are simple.&lt;br&gt;
The power comes from scale, data, and iteration.&lt;/p&gt;

</description>
      <category>deeplearning</category>
      <category>machinelearning</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Understanding Java Constructors: Types, Execution, and Differences from Methods</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Sun, 05 Oct 2025 18:30:00 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/understanding-java-constructors-types-execution-and-differences-from-methods-35cm</link>
      <guid>https://dev.to/nishanthan-k/understanding-java-constructors-types-execution-and-differences-from-methods-35cm</guid>
      <description>&lt;h2&gt;
  
  
  Understanding Constructors in Java
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;constructor&lt;/strong&gt; in Java is similar to a method but serves a specific purpose: initializing objects. This article provides a deep dive into constructors, their execution, types, and how they differ from regular methods.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a Constructor?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Same name as the class&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No return type&lt;/strong&gt; (not even &lt;code&gt;void&lt;/code&gt;)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Primary role&lt;/strong&gt;: Assign or initialize values to class variables
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic invocation&lt;/strong&gt;: Called automatically when an object is created; cannot be called like a regular method
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Execution of Constructors
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Compile Time
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The Java compiler converts a constructor into a special method called &lt;code&gt;&amp;lt;init&amp;gt;&lt;/code&gt; in the &lt;code&gt;.class&lt;/code&gt; file.
&lt;/li&gt;
&lt;li&gt;JVM maintains two special methods for initialization:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;init&amp;gt;&lt;/code&gt;&lt;/strong&gt; → Contains instance constructors; not callable directly by user code
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;clinit&amp;gt;&lt;/code&gt;&lt;/strong&gt; → Contains static field initializations and static blocks; executed once when the class is loaded
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If no constructor is defined by the developer, Java automatically creates a &lt;strong&gt;default constructor&lt;/strong&gt; and stores it in &lt;code&gt;&amp;lt;init&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Runtime
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In the JVM, a constructor is represented as a special method (&lt;code&gt;&amp;lt;init&amp;gt;&lt;/code&gt;) and stored &lt;strong&gt;once&lt;/strong&gt; in the &lt;strong&gt;Method Area&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Every time an object is created, the JVM executes this stored constructor; no new constructor code is created per object.
&lt;/li&gt;
&lt;li&gt;Constructors are primarily for initializing object state; heavy business logic should generally be avoided.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Types of Constructors
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Default Constructor&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added automatically by Java when no constructor is defined.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No-Argument Constructor&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explicitly written by the developer without parameters.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Parameterized Constructor&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Written with parameters to initialize object fields flexibly.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Copy Constructor&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not built into Java by default, but can be created by the developer to copy values from another object.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Default constructor (auto-generated by Java)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;

&lt;span class="c1"&gt;// No-arg constructor&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;B&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"B created"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Parameterized constructor&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Copy constructor&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;D&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="no"&gt;D&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;D&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Constructor vs Method in Java
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Constructor&lt;/th&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Must be same as the class&lt;/td&gt;
&lt;td&gt;Can have any legal identifier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Return Type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None (not even &lt;code&gt;void&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Must declare a return type (or &lt;code&gt;void&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Invocation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Called automatically with &lt;code&gt;new&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Must be explicitly invoked (&lt;code&gt;obj.method()&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Initialize object state (fresh object setup)&lt;/td&gt;
&lt;td&gt;Define behavior of an already created object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bytecode Representation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stored as &lt;code&gt;&amp;lt;init&amp;gt;&lt;/code&gt; in &lt;code&gt;.class&lt;/code&gt; file&lt;/td&gt;
&lt;td&gt;Stored with its given name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Inheritance Behavior&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not inherited, but calls parent constructor (&lt;code&gt;super()&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Inherited and can be overridden&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Overloading&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Can be overloaded&lt;/td&gt;
&lt;td&gt;Can be overloaded and overridden&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Special Rules&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Can call another constructor (&lt;code&gt;this(...)&lt;/code&gt; or &lt;code&gt;super(...)&lt;/code&gt;) as first statement&lt;/td&gt;
&lt;td&gt;No such restriction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Constructor&lt;/strong&gt; → Object birth + initialization, JVM-reserved mechanism (&lt;code&gt;&amp;lt;init&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Method&lt;/strong&gt; → Object behavior, regular callable unit of code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Constructors are foundational to object-oriented programming in Java, ensuring objects are properly initialized while maintaining a clean separation of initialization logic from business logic.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>java</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Brushing Up on React Hooks</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Mon, 28 Jul 2025 03:33:01 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/brushing-up-on-react-hooks-30la</link>
      <guid>https://dev.to/nishanthan-k/brushing-up-on-react-hooks-30la</guid>
      <description>&lt;h2&gt;
  
  
  React Hooks Summary
&lt;/h2&gt;

&lt;h2&gt;
  
  
  1. &lt;code&gt;useState&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;memoizedState&lt;/code&gt; holds the current state value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;baseState&lt;/code&gt; is the initial state value.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dispatch&lt;/code&gt; is the setter function to update state.&lt;/li&gt;
&lt;li&gt;Triggers re-render &lt;strong&gt;after&lt;/strong&gt; the current call stack is empty.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. &lt;code&gt;useEffect&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Allows you to perform side effects (API calls, subscriptions).&lt;/li&gt;
&lt;li&gt;Cleanup is handled by returning a function inside the effect.&lt;/li&gt;
&lt;li&gt;Cleanup runs:

&lt;ul&gt;
&lt;li&gt;Before the component unmounts.&lt;/li&gt;
&lt;li&gt;Before the effect runs again (if dependencies change).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. &lt;code&gt;useMemo&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Caches the &lt;strong&gt;result&lt;/strong&gt; of a computation.&lt;/li&gt;
&lt;li&gt;Prevents recalculating expensive operations unless dependencies change.&lt;/li&gt;
&lt;li&gt;Useful for:

&lt;ul&gt;
&lt;li&gt;Filtering, sorting, parsing large data.&lt;/li&gt;
&lt;li&gt;Memoizing derived data for performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Can also be used to wrap child components to prevent unnecessary re-renders (in conjunction with &lt;code&gt;React.memo&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. &lt;code&gt;React.memo&lt;/code&gt; vs &lt;code&gt;useMemo&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;React.memo&lt;/code&gt;: Prevents re-rendering a &lt;strong&gt;component&lt;/strong&gt; unless props change.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useMemo&lt;/code&gt;: Prevents re-running a &lt;strong&gt;function&lt;/strong&gt; unless dependencies change.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. &lt;code&gt;useCallback&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Memoizes the &lt;strong&gt;function definition&lt;/strong&gt; itself.&lt;/li&gt;
&lt;li&gt;Useful when passing callbacks to memoized child components.&lt;/li&gt;
&lt;li&gt;Prevents unnecessary re-renders due to new function references on each render.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. &lt;code&gt;useRef&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Mutable ref object that persists for the full lifetime of the component.&lt;/li&gt;
&lt;li&gt;Doesn't trigger re-renders.&lt;/li&gt;
&lt;li&gt;Can be used to access DOM nodes or hold mutable variables.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. &lt;code&gt;useReducer&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Alternative to &lt;code&gt;useState&lt;/code&gt; for complex state logic.&lt;/li&gt;
&lt;li&gt;Accepts a reducer function and an initial state.&lt;/li&gt;
&lt;li&gt;Returns &lt;code&gt;[state, dispatch]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Best for managing state transitions or multiple sub-values.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. &lt;code&gt;useLayoutEffect&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Like &lt;code&gt;useEffect&lt;/code&gt;, but runs &lt;strong&gt;after DOM mutation&lt;/strong&gt;, &lt;strong&gt;before paint&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use for DOM measurements, layout adjustments.&lt;/li&gt;
&lt;li&gt;Main use case: e.g., sidebar collapse before layout shift.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9. &lt;code&gt;useImperativeHandle&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Customizes the instance value exposed by &lt;code&gt;ref&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Used with &lt;code&gt;forwardRef&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Allows parent to trigger child functions imperatively.&lt;/li&gt;
&lt;li&gt;Use case: trigger child API call on parent submit button click.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. &lt;code&gt;useDebugValue&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Used for debugging custom hooks in React DevTools.&lt;/li&gt;
&lt;li&gt;Display custom hook values to help debugging.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>How Java Stores Data in Memory: Writing Efficient Code with Primitives and Non-Primitives</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Fri, 16 May 2025 03:30:00 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/how-java-stores-data-in-memory-writing-efficient-code-with-primitives-and-non-primitives-42kg</link>
      <guid>https://dev.to/nishanthan-k/how-java-stores-data-in-memory-writing-efficient-code-with-primitives-and-non-primitives-42kg</guid>
      <description>&lt;h2&gt;
  
  
  How Java Stores Data in Memory — Primitives vs Non-Primitives
&lt;/h2&gt;

&lt;p&gt;Java is a &lt;strong&gt;statically typed language&lt;/strong&gt;, which means every variable’s type must be known at compile time. This allows the JVM (Java Virtual Machine) to allocate memory efficiently and enforce type safety during execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Primitive Types in Java
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Primitive types&lt;/strong&gt; are the building blocks of data in Java. They have &lt;strong&gt;fixed memory sizes&lt;/strong&gt; and are stored in the &lt;strong&gt;stack&lt;/strong&gt;. The value of a primitive can change, but its size does not.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;byte&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 byte&lt;/td&gt;
&lt;td&gt;Smallest integer (–128 to 127)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;short&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2 bytes&lt;/td&gt;
&lt;td&gt;Short integer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;int&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4 bytes&lt;/td&gt;
&lt;td&gt;Default integer type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;long&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8 bytes&lt;/td&gt;
&lt;td&gt;Large-range integer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;float&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4 bytes&lt;/td&gt;
&lt;td&gt;Single-precision float&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;double&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8 bytes&lt;/td&gt;
&lt;td&gt;Double-precision float&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;char&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2 bytes&lt;/td&gt;
&lt;td&gt;Unicode character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;boolean&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 bit*&lt;/td&gt;
&lt;td&gt;True or False (handled as 1 byte internally)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note: Although &lt;code&gt;boolean&lt;/code&gt; is conceptually 1 bit, it is usually stored as **1 byte&lt;/em&gt;* in memory due to alignment and practical implementation constraints.*&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Non-Primitive (Reference) Types
&lt;/h3&gt;

&lt;p&gt;Non-primitives, also called &lt;strong&gt;reference types&lt;/strong&gt;, are more complex and stored in the &lt;strong&gt;heap&lt;/strong&gt;, while their references (pointers) are kept in the &lt;strong&gt;stack&lt;/strong&gt;. These types include:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;String&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sequence of characters (immutable)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Arrays&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ordered collection of elements (of any type, including primitives)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Class&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Custom-defined objects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Interface&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Abstract types that other classes implement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Enum&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A fixed set of constants (internally class-like)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Wrapper&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Object representations of primitive types (e.g., &lt;code&gt;Integer&lt;/code&gt;, &lt;code&gt;Double&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Collections&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Data structures like &lt;code&gt;List&lt;/code&gt;, &lt;code&gt;Set&lt;/code&gt;, &lt;code&gt;Map&lt;/code&gt;, etc. (part of Java Collections Framework)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  How Java Stores Data in Memory
&lt;/h3&gt;

&lt;p&gt;Java abstracts memory management with &lt;strong&gt;automatic garbage collection&lt;/strong&gt;, but here’s how it works under the hood:&lt;/p&gt;

&lt;h4&gt;
  
  
  Stack Memory
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Stores &lt;strong&gt;method calls&lt;/strong&gt;, &lt;strong&gt;local variables&lt;/strong&gt;, and &lt;strong&gt;primitive types&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast access&lt;/strong&gt; due to LIFO structure.&lt;/li&gt;
&lt;li&gt;Memory is freed automatically once a method exits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Heap Memory
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Stores &lt;strong&gt;objects&lt;/strong&gt; and &lt;strong&gt;non-primitive values&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Accessed via references stored in the stack.&lt;/li&gt;
&lt;li&gt;Managed by &lt;strong&gt;Garbage Collector&lt;/strong&gt; (GC).&lt;/li&gt;
&lt;li&gt;Larger and &lt;strong&gt;slower&lt;/strong&gt; than stack but can store dynamic and complex structures.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Primitive Types Are Accessed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stored &lt;strong&gt;directly&lt;/strong&gt; in the stack.&lt;/li&gt;
&lt;li&gt;Access and modification are &lt;strong&gt;fast and straightforward&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Since they are fixed-size, the JVM knows exactly how much memory to allocate and retrieve.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Non-Primitives Are Accessed
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;When a non-primitive is created, the &lt;strong&gt;reference (memory address)&lt;/strong&gt; is stored in the stack.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;actual object&lt;/strong&gt; is stored in the heap.&lt;/li&gt;
&lt;li&gt;Accessing the object involves &lt;strong&gt;following the reference&lt;/strong&gt; from stack to heap.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Example:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; (stack) → points to → &lt;code&gt;"John"&lt;/code&gt; (heap)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we change &lt;code&gt;name = "Jack";&lt;/code&gt;, now &lt;code&gt;name&lt;/code&gt; points to a new &lt;code&gt;"Jack"&lt;/code&gt; in heap (because &lt;code&gt;String&lt;/code&gt; is immutable).&lt;/p&gt;

&lt;h3&gt;
  
  
  Memory Alignment and JVM Optimization
&lt;/h3&gt;

&lt;p&gt;Java is designed with the principle: &lt;strong&gt;“Write once, run anywhere”&lt;/strong&gt;, which means JVM must work on both &lt;strong&gt;32-bit and 64-bit CPUs&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  JVM Alignment Strategy:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Regardless of declared type, JVM aligns memory into &lt;strong&gt;4-byte or 8-byte chunks&lt;/strong&gt; depending on CPU.&lt;/li&gt;
&lt;li&gt;Operations on smaller types (&lt;code&gt;byte&lt;/code&gt;, &lt;code&gt;short&lt;/code&gt;) are &lt;strong&gt;converted to &lt;code&gt;int&lt;/code&gt;&lt;/strong&gt; internally.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Why is that?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;byte&lt;/code&gt; takes 25% of a 4-byte block; &lt;code&gt;short&lt;/code&gt; takes 50%.&lt;/li&gt;
&lt;li&gt;CPU needs &lt;strong&gt;extra steps&lt;/strong&gt; to calculate offsets and align the memory block.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;int&lt;/code&gt; consumes the entire 4-byte block, making &lt;strong&gt;storage and retrieval faster&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;blockquote&gt;
&lt;p&gt;JVM promotes &lt;code&gt;byte&lt;/code&gt; and &lt;code&gt;short&lt;/code&gt; to &lt;code&gt;int&lt;/code&gt; during calculations and requires &lt;strong&gt;explicit casting&lt;/strong&gt; to store results back.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Misconception: Using &lt;code&gt;byte&lt;/code&gt;/&lt;code&gt;short&lt;/code&gt; Saves Memory?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Why &lt;code&gt;byte&lt;/code&gt; and &lt;code&gt;short&lt;/code&gt; are &lt;em&gt;less efficient&lt;/em&gt;:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;JVM treats them as &lt;code&gt;int&lt;/code&gt; internally.&lt;/li&gt;
&lt;li&gt;Adds &lt;strong&gt;extra overhead&lt;/strong&gt; during arithmetic and access.&lt;/li&gt;
&lt;li&gt;Introduces &lt;strong&gt;hidden conversions&lt;/strong&gt; (widening and narrowing).&lt;/li&gt;
&lt;li&gt;Slower due to memory misalignment and CPU inefficiency.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;For performance and alignment, &lt;strong&gt;use &lt;code&gt;int&lt;/code&gt; as default&lt;/strong&gt; for integers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What About Wrapper Classes?
&lt;/h3&gt;

&lt;p&gt;Wrapper classes (&lt;code&gt;Integer&lt;/code&gt;, &lt;code&gt;Double&lt;/code&gt;, etc.) are &lt;strong&gt;object versions&lt;/strong&gt; of primitive types.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stored in heap like any object.&lt;/li&gt;
&lt;li&gt;Used in Collections (e.g., &lt;code&gt;List&amp;lt;Integer&amp;gt;&lt;/code&gt;, not &lt;code&gt;List&amp;lt;int&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Include utility methods like &lt;code&gt;parseInt&lt;/code&gt;, &lt;code&gt;compareTo&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Auto-boxing and unboxing happen automatically:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// auto-boxing&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// unboxing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boxing adds &lt;strong&gt;memory and performance overhead&lt;/strong&gt;, so avoid unnecessary boxing in critical code paths.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Primitive types&lt;/strong&gt; are fixed-size and fast, stored in stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-primitives&lt;/strong&gt; are stored in heap with reference in stack.&lt;/li&gt;
&lt;li&gt;JVM uses &lt;strong&gt;int as the baseline&lt;/strong&gt; for all smaller integral operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid using &lt;code&gt;byte&lt;/code&gt; and &lt;code&gt;short&lt;/code&gt; for optimization&lt;/strong&gt;, it backfires due to hidden processing.&lt;/li&gt;
&lt;li&gt;Wrapper classes add object overhead; &lt;strong&gt;prefer primitives&lt;/strong&gt; for performance-critical paths.&lt;/li&gt;
&lt;li&gt;Java abstracts memory handling, but &lt;strong&gt;understanding this helps you write more efficient code&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>data</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understanding Angular Rendering, Re-rendering, and Change Detection for Optimal Performance</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Mon, 07 Apr 2025 04:30:00 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/understanding-angular-rendering-re-rendering-and-change-detection-for-optimal-performance-2dle</link>
      <guid>https://dev.to/nishanthan-k/understanding-angular-rendering-re-rendering-and-change-detection-for-optimal-performance-2dle</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you’re transitioning from React to Angular or starting with Angular as first step, understanding Angular’s rendering process, change detection mechanism, and re-rendering strategy is crucial for writing efficient and high-performance applications. Unlike React, where the virtual DOM helps optimize the re-render process, Angular’s change detection mechanism checks every component to ensure the UI reflects the latest data. This article will break down the concepts of rendering, change detection, and performance optimization in Angular, answering the questions you might have along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Angular Rendering and Re-rendering
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How Does Angular Render and Re-render Components?
&lt;/h3&gt;

&lt;p&gt;Angular, unlike React, uses a real DOM and checks for changes during change detection. Let's break down the process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Initial Rendering:&lt;/strong&gt; When a component is created for the first time, Angular processes the component’s template and binds the data from the component to the template.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Change Detection:&lt;/strong&gt; Once the component is initialized, Angular listens for changes in the data. When any data-bound property changes, Angular triggers the change detection process, checking the whole component tree from the root.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Re-rendering:&lt;/strong&gt; When data in a component changes, Angular goes through the change detection cycle again. Unlike React, which uses a virtual DOM, Angular re-renders the DOM directly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This brings up an interesting question: &lt;strong&gt;If change detection checks the whole component tree, does Angular re-render everything even if only a small part of the data changes?&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Do Angular Re-renders Everything or Just the Changed Part?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Angular does indeed go through all bindings in the component, even if only a single property changes. This is less efficient compared to React’s virtual DOM diffing mechanism, where only the changed elements are re-rendered.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;However, Angular uses optimizations such as OnPush change detection strategy and TrackBy in *ngFor to reduce unnecessary checks. Let's dive deeper into these strategies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Exploring Angular's Change Detection Mechanism
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How Does Change Detection Work in Angular?
&lt;/h3&gt;

&lt;p&gt;Change detection in Angular follows a process where Angular traverses the component tree and checks each binding to see if it has changed. If any change is detected, Angular updates the DOM.&lt;/p&gt;

&lt;p&gt;The default strategy is CheckAlways, which checks all components in the component tree. But Angular allows you to optimize this using OnPush.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is OnPush?
&lt;/h3&gt;

&lt;p&gt;When using OnPush change detection, Angular only checks a component for changes when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One of its Input properties changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An event is triggered (e.g., button click).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An observable emits a new value.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can significantly improve performance in large applications by avoiding unnecessary checks on components that haven’t changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component({
  selector: 'app-my-component',
  changeDetection: ChangeDetectionStrategy.OnPush,
  templateUrl: './my-component.component.html',
})
export class MyComponent {
  @Input() data: any;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using OnPush, you restrict the component to be checked only when a relevant change occurs, rather than checking it on every cycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Does Angular Check All Components for Changes?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You might wonder, &lt;strong&gt;Why does Angular check the entire component tree? Can it just check the component where the change happened?&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Angular’s default change detection works by traversing the whole component tree to check for any data changes. This design ensures that all bindings are up to date, but can become inefficient, especially in large applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unlike React’s virtual DOM, Angular doesn’t maintain a previous DOM snapshot, and so it doesn't have an efficient diffing mechanism that would allow it to detect changes at a granular level.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Challenge with Functions in Templates
&lt;/h3&gt;

&lt;p&gt;Angular has a two-way binding mechanism, which helps with reactivity. But one performance pitfall is calling functions directly in templates. Functions in templates are re-evaluated on every change detection cycle, which can hurt performance if not used properly.&lt;/p&gt;

&lt;p&gt;For example, calling a function in a template like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{ computeValue() }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Could cause the function to run repeatedly, making it inefficient. To avoid this, use getters or Signals (in Angular 16.2+) to track state more efficiently.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get computedValue(): number {
  return this.data * 10;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, the value is calculated once, and Angular can optimize re-renders.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimizing Angular for Better Performance
&lt;/h2&gt;

&lt;p&gt;To address performance concerns, let’s talk about strategies to optimize rendering and change detection in Angular.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;strong&gt;OnPush&lt;/strong&gt; Change Detection&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As mentioned earlier, the OnPush strategy significantly reduces unnecessary re-renders. It tells Angular to check the component only when its inputs or observables change, or when an event is triggered.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;strong&gt;trackBy&lt;/strong&gt; with *ngFor&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When using *ngFor, Angular creates new DOM elements for every item in the list. If the list is large, this can become inefficient. You can optimize the rendering of lists by using trackBy to track which items have changed, rather than recreating the entire DOM for the list every time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div *ngFor="let item of items; trackBy: trackById"&amp;gt;
  {{ item.name }}
&amp;lt;/div&amp;gt;

trackById(index: number, item: any): number {
  return item.id;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Avoid Functions in Templates&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of calling functions directly in the template, use getters or Signals (in Angular 16.2+) to keep state changes efficient and avoid recomputing values on every change detection cycle.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Signals (Angular 16.2+):&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Signals in Angular provide a more efficient way to manage state and trigger updates. With signals, Angular tracks the state and updates the DOM only when the value of the signal changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;isA = signal(true);
isB = signal(false);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Use &lt;strong&gt;ngOnChanges and Input Setters&lt;/strong&gt;
For efficient handling of input changes, Angular provides Input Setters and ngOnChanges. Instead of checking changes manually, use these lifecycle hooks to optimize reactivity.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Input() set data(value: any) {
  this._data = value;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use this instead of ngOnChanges to efficiently handle changes in input properties.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding Angular’s rendering, re-rendering, and change detection mechanisms is key to building efficient applications. By using techniques like OnPush change detection, trackBy in *ngFor, avoiding functions in templates, and leveraging Signals (in Angular 16.2+), you can optimize your Angular applications for better performance.&lt;/p&gt;

&lt;p&gt;Remember, while Angular doesn’t use a virtual DOM like React, it offers a powerful change detection system that you can fine-tune for optimal performance. Implement these strategies and take control of your app’s reactivity—leading to faster, smoother, and more efficient user experiences.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How MongoDB’s ObjectID and B-Tree Search Make Your Queries Super Fast</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Wed, 19 Feb 2025 03:30:00 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/how-mongodbs-objectid-and-b-tree-search-make-your-queries-super-fast-3hhn</link>
      <guid>https://dev.to/nishanthan-k/how-mongodbs-objectid-and-b-tree-search-make-your-queries-super-fast-3hhn</guid>
      <description>&lt;p&gt;MongoDB uses a unique identifier, called &lt;strong&gt;ObjectId&lt;/strong&gt;, for each document stored in its database. An ObjectId is a 12-byte identifier that is generated in a specific format to ensure it’s unique across distributed systems. &lt;/p&gt;

&lt;p&gt;In this article, we will break down the structure of MongoDB's ObjectId, how it is generated, and how MongoDB uses a binary tree-like structure for indexing and searching. We will also discuss how this structure helps MongoDB perform searches efficiently, even with millions of entries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure of MongoDB's ObjectId
&lt;/h2&gt;

&lt;p&gt;MongoDB’s &lt;strong&gt;ObjectId&lt;/strong&gt; is a &lt;strong&gt;12-byte&lt;/strong&gt; identifier, and its structure is designed to ensure uniqueness while keeping it compact. The 12 bytes are divided into four main parts:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Timestamp (4 bytes)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The first 4 bytes represent the timestamp when the ObjectId was generated. &lt;/li&gt;
&lt;li&gt;This timestamp is recorded in &lt;strong&gt;seconds&lt;/strong&gt; since the Unix epoch (January 1, 1970).&lt;/li&gt;
&lt;li&gt;This ensures that ObjectIds are roughly ordered by creation time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Machine Id (3 bytes)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The next 3 bytes represent a unique identifier for the machine where the ObjectId was generated.&lt;/li&gt;
&lt;li&gt;Typically, it’s derived from the machine's IP address or a hash of the machine's network interfaces.&lt;/li&gt;
&lt;li&gt;This will be &lt;strong&gt;constant for its lifetime&lt;/strong&gt; untill the &lt;strong&gt;hostname and other system details&lt;/strong&gt; got changed&lt;/li&gt;
&lt;li&gt;This ensures that even if two MongoDB instances are running on different machines, they can generate unique ObjectIds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Process Id (2 bytes)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The following 2 bytes represent the process ID of the MongoDB server process. &lt;/li&gt;
&lt;li&gt;This helps to distinguish ObjectIds generated by different processes running on the same machine.&lt;/li&gt;
&lt;li&gt;This is only constant for that run and it will change when the server was restarted / on re-run.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Counter (3 bytes)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The last 3 bytes represent an &lt;strong&gt;incrementing counter&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;The counter starts at a random value. If &lt;strong&gt;multiple documents / objectIds&lt;/strong&gt; are generated at the same timestamp (same second), the counter ensures each generated &lt;strong&gt;ObjectId is unique by incrementing&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If only one &lt;strong&gt;Document / ObjectId&lt;/strong&gt; is generated per second, the counter will reset to another random value for the next second.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key point:&lt;/strong&gt; This counter ensures uniqueness when multiple ObjectId values are generated in the same second by the same machine and process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example of an ObjectId:
&lt;/h3&gt;

&lt;p&gt;507f191e810c19729de860ea&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first 4 bytes: &lt;code&gt;507f191e&lt;/code&gt; represent the timestamp.&lt;/li&gt;
&lt;li&gt;The next 3 bytes: &lt;code&gt;81&lt;/code&gt; represent the machine ID.&lt;/li&gt;
&lt;li&gt;The next 2 bytes: &lt;code&gt;0c&lt;/code&gt; represent the process ID.&lt;/li&gt;
&lt;li&gt;The last 3 bytes: &lt;code&gt;19729de&lt;/code&gt; represent the incrementing counter.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  MongoDB Index Structure and Page Layout:
&lt;/h3&gt;

&lt;p&gt;MongoDB uses a &lt;strong&gt;B-tree-like&lt;/strong&gt; index structure, not an real tree we are using in data structures but with certain modifications for optimization. Here's a breakdown:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Root Node:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;root node&lt;/strong&gt; of the index tree stores &lt;strong&gt;keys&lt;/strong&gt; (usually indexed fields like &lt;code&gt;ObjectId&lt;/code&gt;, or other indexed fields).&lt;/li&gt;
&lt;li&gt;This root node acts as the starting point for the search process, &lt;strong&gt;guiding MongoDB towards the right child node.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Features:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Contains &lt;strong&gt;sorted keys&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Points to &lt;strong&gt;child nodes&lt;/strong&gt; which continue the search deeper into the tree.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Child Pages:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Child nodes (or child pages) store &lt;strong&gt;sorted keys&lt;/strong&gt; and pointers to their &lt;strong&gt;leaf nodes&lt;/strong&gt; or further child nodes.&lt;/li&gt;
&lt;li&gt;These nodes are like intermediates, helping narrow down the range of values that need to be searched.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Features:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Contains &lt;strong&gt;sorted key-value pairs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Contains pointers to the next level (further child pages or leaf pages).&lt;/li&gt;
&lt;li&gt;May be created or split as the index grows.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Leaf Pages:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;leaf pages&lt;/strong&gt; are the actual locations where &lt;strong&gt;document references&lt;/strong&gt; (pointers to documents) are stored.&lt;/li&gt;
&lt;li&gt;Each entry in the leaf page contains a &lt;strong&gt;key&lt;/strong&gt; (indexed field value) and a &lt;strong&gt;pointer&lt;/strong&gt; to the actual document (i.e., location in the data store).&lt;/li&gt;
&lt;li&gt;These pages are where the final results are stored, which MongoDB returns in a query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Features:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Contains the &lt;strong&gt;actual document references&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Sorted by the indexed field for fast lookups.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Page Structure:
&lt;/h3&gt;

&lt;p&gt;In MongoDB, &lt;strong&gt;index pages&lt;/strong&gt; are typically designed to be &lt;strong&gt;4 KB&lt;/strong&gt; in size. If the page contains entries like &lt;code&gt;ObjectId&lt;/code&gt; (a 12-byte identifier), each page can store around &lt;strong&gt;317 entries&lt;/strong&gt;. This size may vary slightly based on the size of indexed fields.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pages&lt;/strong&gt; are fetched from the disk into memory during searches, ensuring that queries are handled efficiently.&lt;/li&gt;
&lt;li&gt;MongoDB uses a &lt;strong&gt;binary search&lt;/strong&gt; within a page to locate the exact entry, which ensures faster retrieval of documents.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  How MongoDB Manages Page Growth:
&lt;/h3&gt;

&lt;p&gt;As MongoDB adds more entries to an index, it needs to &lt;strong&gt;split nodes&lt;/strong&gt; to ensure that the index remains balanced.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a &lt;strong&gt;page&lt;/strong&gt; reaches its capacity, MongoDB &lt;strong&gt;splits&lt;/strong&gt; the page into two and &lt;strong&gt;promotes the middle key&lt;/strong&gt; to the parent node.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;middle key&lt;/strong&gt; is the key that divides the entries in half and is used to maintain a balanced index.&lt;/li&gt;
&lt;li&gt;As the index continues to grow, this process of splitting and promoting ensures the &lt;strong&gt;B-tree remains balanced&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Balancing the tree&lt;/strong&gt; through splits and promotions ensures that &lt;strong&gt;search operations remain efficient&lt;/strong&gt; and that the index is optimal for query performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example of How the Index Tree Works:
&lt;/h3&gt;

&lt;p&gt;Consider an index on the &lt;code&gt;ObjectId&lt;/code&gt; field in MongoDB:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Root Node&lt;/strong&gt;: Contains keys pointing to child nodes. For example, if you have a collection of documents with &lt;code&gt;ObjectId&lt;/code&gt;, the root node will store keys like &lt;code&gt;ObjectId:123&lt;/code&gt;, &lt;code&gt;ObjectId:124&lt;/code&gt;, etc., with pointers to child nodes that contain more detailed keys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Child Pages&lt;/strong&gt;: These child nodes will store ranges of &lt;code&gt;ObjectId&lt;/code&gt;s and pointers to further nodes or leaf nodes, helping narrow down the search.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Leaf Pages&lt;/strong&gt;: Finally, the leaf pages contain the &lt;strong&gt;actual document pointers&lt;/strong&gt; for specific &lt;code&gt;ObjectId&lt;/code&gt;s. For example, a leaf page might contain a key like &lt;code&gt;ObjectId:123&lt;/code&gt; and a pointer to the exact location of the document in the storage.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When a query is executed, MongoDB will traverse this tree structure by following the &lt;strong&gt;key pointers&lt;/strong&gt; from the root node, through child nodes, and ultimately to the leaf nodes where it finds the &lt;strong&gt;document references&lt;/strong&gt;. This ensures efficient searching, even with large datasets.&lt;/p&gt;




&lt;h3&gt;
  
  
  Key Takeaways:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;MongoDB uses a &lt;strong&gt;modified B-tree&lt;/strong&gt; index structure for fast lookups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pages&lt;/strong&gt; are crucial for holding index entries and documents. Pages are typically 4 KB in size and contain &lt;strong&gt;sorted entries&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leaf pages&lt;/strong&gt; contain the actual document references and are where the search ultimately lands.&lt;/li&gt;
&lt;li&gt;As the tree grows, &lt;strong&gt;node splits&lt;/strong&gt; and &lt;strong&gt;middle key promotions&lt;/strong&gt; ensure that the index remains balanced and efficient for query processing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example: From Scratch to 17 Entries
&lt;/h2&gt;

&lt;p&gt;Let’s consider the process of adding entries to a MongoDB index and how the keys move up in the tree.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-by-Step Tree Construction:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Insert 1, 2, 3&lt;/strong&gt;:
Initially, we add three entries, and they all fit in the root node.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;[1, 2, 3]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Insert 4&lt;/strong&gt;:
Adding the fourth entry causes the root to split. The middle key (&lt;code&gt;2&lt;/code&gt;) gets promoted to a new root.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Root: [2]&lt;br&gt;
Left Child: [1]&lt;br&gt;
Right Child: [3, 4]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Insert 5, 6, 7&lt;/strong&gt;:
The right child now overflows, so the middle key (&lt;code&gt;6&lt;/code&gt;) moves up.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Root: [2, 6]&lt;br&gt;
Left Child: [1]&lt;br&gt;
Middle Child: [3, 4, 5]&lt;br&gt;
Right Child: [7]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Insert 8, 9, 10&lt;/strong&gt;:
The right child overflows again, so the middle key (&lt;code&gt;9&lt;/code&gt;) moves up.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Root: [2, 6, 9]&lt;br&gt;
Left Child: [1]&lt;br&gt;
Middle Left Child: [3, 4, 5]&lt;br&gt;
Middle Right Child: [7, 8]&lt;br&gt;
Right Child: [10]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Insert 11, 12, 13, 14, 15, 16, 17&lt;/strong&gt;:
We continue inserting entries, and they cause further splits, with the middle keys getting promoted up.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Root: [2, 6, 9, 13]&lt;br&gt;&lt;br&gt;
Left Child: [1]&lt;br&gt;&lt;br&gt;
Middle Left Child: [3, 4, 5]&lt;br&gt;&lt;br&gt;
Middle Child: [7, 8]&lt;br&gt;&lt;br&gt;
Right Child: [10, 11]&lt;br&gt;&lt;br&gt;
Final Child: [12, 14, 15, 16, 17]  &lt;/p&gt;

&lt;h3&gt;
  
  
  Final tree strucutre
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         [6, 9, 13]
                      /    |    |    \
         [1, 2, 3, 4, 5]   [7, 8]  [10, 11]  [12, 14, 15, 16, 17]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Simplified MongoDB Search Process
&lt;/h2&gt;

&lt;p&gt;Here’s a simplified summary of how MongoDB searches for documents using the index:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Start with the Index&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MongoDB first looks at the &lt;strong&gt;index&lt;/strong&gt; (similar to a table of contents in a book) to figure out where to find documents.&lt;/li&gt;
&lt;li&gt;The index is stored in a &lt;strong&gt;B-tree&lt;/strong&gt; structure, which helps MongoDB quickly find the right spot.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Navigate the Tree&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;root node&lt;/strong&gt; of the tree holds pointers to the next pages (child nodes).&lt;/li&gt;
&lt;li&gt;The tree is &lt;strong&gt;split into pages&lt;/strong&gt;, each containing &lt;strong&gt;key-value pairs&lt;/strong&gt;. These keys are the indexed fields (like ObjectId, or any other field you're indexing).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Find the Relevant Range&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a query is made, MongoDB starts at the &lt;strong&gt;root node&lt;/strong&gt; and uses &lt;strong&gt;binary search&lt;/strong&gt; to find the right range of keys.&lt;/li&gt;
&lt;li&gt;It keeps following the pointers to the next pages until it narrows down to the correct range of keys for the search.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Determine the Page to Search&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As MongoDB navigates the tree, it looks for the &lt;strong&gt;page number&lt;/strong&gt; (stored in the index) that contains the matching &lt;strong&gt;_id&lt;/strong&gt; or document key range.&lt;/li&gt;
&lt;li&gt;Once it finds the correct page, it jumps to that page.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Search on the Page&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;page&lt;/strong&gt; contains a &lt;strong&gt;binary search&lt;/strong&gt; of documents stored in it. MongoDB uses the pointers in the page to go straight to the document's &lt;strong&gt;storage location&lt;/strong&gt; (like the exact spot where the document is stored on disk).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fetch the Document&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finally, MongoDB uses the &lt;strong&gt;storage location&lt;/strong&gt; found in the index (the &lt;strong&gt;position pointer&lt;/strong&gt;) to go directly to the document on the disk and fetch it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  In short:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MongoDB first uses the &lt;strong&gt;index&lt;/strong&gt; (a tree structure) to find the right range of documents.&lt;/li&gt;
&lt;li&gt;It uses &lt;strong&gt;binary search&lt;/strong&gt; to find the correct page.&lt;/li&gt;
&lt;li&gt;Then, it jumps to that page and finds the document by looking up the position pointer, directly fetching it from the disk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This process ensures that MongoDB can &lt;strong&gt;quickly&lt;/strong&gt; locate and fetch documents even if the database grows large.&lt;/p&gt;


&lt;h2&gt;
  
  
  Real strucuture with 64 level split
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                           ┌────────────────── Root Node ───────────────────┐
                           │ Keys: [512, 1024, 1536]                         │
                           │ Child Pointers: [P1, P2, P3, P4]                │
                           └────────────────────────────────────────────────┘
                                         ↓ Choose correct child based on _id

 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
 │                         Internal Nodes (Level 2)                                                              │
 └───────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
 │ P1 → Keys: [128, 256, 384]  │ P2 → Keys: [640, 768, 896]  │ P3 → Keys: [1152, 1280, 1408]  │ P4 → Keys: [1664, 1792, 1920] │
 │ Child Pointers: [P5-P8]     │ Child Pointers: [P9-P12]    │ Child Pointers: [P13-P16]     │ Child Pointers: [P17-P20]    │

                                         ↓ Choose correct child based on _id

 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
 │                         Internal Nodes (Level 3)                                                              │
 └───────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
 │ P5 → Keys: [32, 64, 96]  │ P6 → Keys: [160, 192, 224]  │ P7 → Keys: [288, 320, 352]  │ P8 → Keys: [416, 448, 480]  │
 │ P9 → Keys: [544, 576, 608]  │ P10 → Keys: [672, 704, 736]  │ P11 → Keys: [800, 832, 864]  │ P12 → Keys: [928, 960, 992]  │
 │ P13 → Keys: [1056, 1088, 1120]  │ P14 → Keys: [1184, 1216, 1248]  │ P15 → Keys: [1312, 1344, 1376]  │ P16 → Keys: [1440, 1472, 1504]  │
 │ P17 → Keys: [1568, 1600, 1632]  │ P18 → Keys: [1728, 1760, 1792]  │ P19 → Keys: [1856, 1888, 1920]  │ P20 → Keys: [1984, 2000]  │

                                         ↓ Choose correct child based on _id

 ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
 │                         Leaf Nodes (Level 4) - Actual Document Pointers                                       │
 └───────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
 │ P21 → Keys: [1-64] (D1-D64)  │ P22 → Keys: [65-128] (D65-D128)  │ P23 → Keys: [129-192] (D129-D192)  │ P24 → Keys: [193-256] (D193-D256)  │
 │ P25 → Keys: [257-320] (D257-D320)  │ P26 → Keys: [321-384] (D321-D384)  │ P27 → Keys: [385-448] (D385-D448)  │ P28 → Keys: [449-512] (D449-D512)  │
 │ P29 → Keys: [513-576] (D513-D576)  │ P30 → Keys: [577-640] (D577-D640)  │ P31 → Keys: [641-704] (D641-D704)  │ P32 → Keys: [705-768] (D705-D768)  │
 │ P33 → Keys: [769-832] (D769-D832)  │ P34 → Keys: [833-896] (D833-D896)  │ P35 → Keys: [897-960] (D897-D960)  │ P36 → Keys: [961-1024] (D961-D1024)  │
 │ P37 → Keys: [1025-1088] (D1025-D1088)  │ P38 → Keys: [1089-1152] (D1089-D1152)  │ P39 → Keys: [1153-1216] (D1153-D1216)  │ P40 → Keys: [1217-1280] (D1217-D1280)  │
 │ P41 → Keys: [1281-1344] (D1281-D1344)  │ P42 → Keys: [1345-1408] (D1345-D1408)  │ P43 → Keys: [1409-1472] (D1409-D1472)  │ P44 → Keys: [1473-1536] (D1473-D1536)  │
 │ P45 → Keys: [1537-1600] (D1537-D1600)  │ P46 → Keys: [1601-1664] (D1601-D1664)  │ P47 → Keys: [1665-1728] (D1665-D1728)  │ P48 → Keys: [1729-1792] (D1729-D1792)  │
 │ P49 → Keys: [1793-1856] (D1793-D1856)  │ P50 → Keys: [1857-1920] (D1857-D1920)  │ P51 → Keys: [1921-1984] (D1921-D1984)  │ P52 → Keys: [1985-2000] (D1985-D2000)  │


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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Search flow for _id 1754
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Root Node: &lt;code&gt;_id = 1754&lt;/code&gt; falls in range [1536, 2000], follow &lt;code&gt;P4&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Internal Node (L2): &lt;code&gt;_id = 1754&lt;/code&gt; falls in range [1664, 1920], follow &lt;code&gt;P18&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Internal Node (L3): &lt;code&gt;_id = 1754&lt;/code&gt; falls in range [1728, 1792], follow &lt;code&gt;P48&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Leaf Node (L4): &lt;code&gt;_id = 1754&lt;/code&gt; is found, get &lt;code&gt;Document Pointer D1754&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Retrieve document from storage&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Searching for an ID in MongoDB (Example with 3.6 Million Entries)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Let’s say we have a collection of &lt;strong&gt;3.6 million entries&lt;/strong&gt; and you need to find an entry with a specific &lt;strong&gt;ObjectId&lt;/strong&gt;. Here’s how MongoDB would perform the search.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;At each level, you have 64 choices (64 child pointers).&lt;br&gt;
So for large values (like the 3.7 millionth record), this structure is efficient.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import math

total_entries = 3600000

branching_factor = 64

num_searches = math.ceil(math.log(total_entries, branching_factor))
print(num_searches)

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;For searching the 3.6 millionth entry, it would take approximately &lt;strong&gt;4 searches (or 4 levels of traversal in the tree)&lt;/strong&gt;. This is because the B-tree structure narrows down the search space significantly at each level. &lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;MongoDB’s &lt;strong&gt;ObjectId&lt;/strong&gt; provides a compact, efficient way to uniquely identify documents, and its indexing system uses a &lt;strong&gt;B-tree-like structure&lt;/strong&gt; to allow for fast searches. As documents are inserted, keys are promoted to parent nodes, ensuring that MongoDB maintains a balanced and efficient index structure. When searching for a specific &lt;strong&gt;ObjectId&lt;/strong&gt;, MongoDB can quickly narrow down the search space using &lt;strong&gt;binary search&lt;/strong&gt; on the root and child pages, resulting in fast lookups even for large collections.&lt;/p&gt;

&lt;p&gt;By combining &lt;strong&gt;timestamp-based generation&lt;/strong&gt; for ObjectIds and a &lt;strong&gt;binary search-based indexing&lt;/strong&gt; structure, MongoDB is able to offer high performance for both data storage and retrieval.&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>database</category>
      <category>optimization</category>
      <category>performance</category>
    </item>
    <item>
      <title>Understanding the Java Execution Process: From Code to Execution</title>
      <dc:creator>Nishanthan</dc:creator>
      <pubDate>Thu, 30 Jan 2025 04:00:00 +0000</pubDate>
      <link>https://dev.to/nishanthan-k/understanding-the-java-execution-process-from-code-to-execution-1n89</link>
      <guid>https://dev.to/nishanthan-k/understanding-the-java-execution-process-from-code-to-execution-1n89</guid>
      <description>&lt;p&gt;Java is widely known for its platform independence and efficient execution. This article will walk you through the entire Java execution process, from writing human-readable code to running it across different platforms. We’ll cover the roles of JDK, JVM, and JRE, as well as the steps involved in compiling and executing Java programs.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Key Java Components
&lt;/h2&gt;

&lt;p&gt;Before diving into the execution process, it’s essential to understand the three core components in Java:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JDK (Java Development Kit)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The JDK is a full-fledged software development kit that allows you to write, compile, and execute Java programs.&lt;/li&gt;
&lt;li&gt;It includes the JVM (Java Virtual Machine) and JRE (Java Runtime Environment), as well as essential tools for development, such as the compiler (&lt;code&gt;javac&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;JDK is used by developers to write and compile code, which is later executed by the JVM.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JVM (Java Virtual Machine)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The JVM is the engine that runs Java bytecode. It makes Java platform-independent by abstracting the underlying hardware and operating system.&lt;/li&gt;
&lt;li&gt;Java programs are compiled into bytecode, which the JVM interprets and executes, allowing the same Java program to run on any machine with a JVM.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JRE (Java Runtime Environment)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The JRE provides the necessary libraries and resources to run Java programs, including the JVM.&lt;/li&gt;
&lt;li&gt;It contains the core classes like String and Array, which your Java program may depend on.&lt;/li&gt;
&lt;li&gt;The JRE doesn’t include development tools like the compiler, making it suitable for running Java applications but not for development.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. The Java Execution Process
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Write the Code&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You start by writing Java code, which is typically saved in &lt;code&gt;.java&lt;/code&gt; files. This code is human-readable and follows Java syntax.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Compile the Code&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the code is ready, the &lt;code&gt;javac&lt;/code&gt; compiler is used to convert the human-readable &lt;code&gt;.java&lt;/code&gt; code into bytecode (stored in &lt;code&gt;.class&lt;/code&gt; files).&lt;/li&gt;
&lt;li&gt;Bytecode is a binary format, which is the same for all operating systems. This bytecode can then be executed on any platform that has a JVM, ensuring platform independence.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Execute the Bytecode with JVM&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;3.1 Loading the Bytecode&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;When you attempt to execute the Java program, the JVM loads the bytecode (i.e., the &lt;code&gt;.class&lt;/code&gt; file) into memory.&lt;/li&gt;
&lt;li&gt;The ClassLoader is responsible for finding and loading the class based on the class name provided by the user.&lt;/li&gt;
&lt;li&gt;If the class cannot be found, a &lt;code&gt;ClassNotFoundException&lt;/code&gt; is thrown.&lt;/li&gt;
&lt;li&gt;If the class is found, the JVM loads it into memory. Static methods, variables, and data from the class are stored in the Method Area, a special part of the JVM memory.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3.2 Executing the Bytecode&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Once the class is loaded, the JVM looks for the &lt;code&gt;main()&lt;/code&gt; method (the entry point of the program) to begin execution.&lt;/li&gt;
&lt;li&gt;If the &lt;code&gt;main()&lt;/code&gt; method is found, the execution process starts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Execution Mechanism
&lt;/h2&gt;

&lt;p&gt;There are two main approaches the JVM uses to execute bytecode: Interpreter and Just-In-Time (JIT) Compiler.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Interpreter (Slower)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the interpreter approach, the JVM reads and executes the bytecode line by line.&lt;/li&gt;
&lt;li&gt;Every time a method is invoked, the JVM re-interprets the bytecode, which can be slow since the same method may be re-executed multiple times.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JIT (Just-In-Time) Compiler (Faster)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The JIT Compiler compiles bytecode into native machine code, which is specific to the platform and machine on which the program is running.&lt;/li&gt;
&lt;li&gt;It optimizes performance by using a technique called Hot Spots.&lt;/li&gt;
&lt;li&gt;Hot Spots are frequently used parts of the code (like methods). These are identified by the JIT compiler, and instead of interpreting them each time, the JIT compiles them into native machine code.&lt;/li&gt;
&lt;li&gt;The compiled machine code is cached, so when the same method is needed again, the JVM can use the cached machine code, resulting in faster execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Hot Spots&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Hot Spot technique ensures that the JVM only compiles the frequently used methods, not the entire class. This results in significant performance improvements for long-running applications.&lt;/li&gt;
&lt;li&gt;The JVM uses machine code for execution of these hot spots instead of interpreting the bytecode every time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. JVM Memory Areas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The JVM allocates memory for different parts of the program during execution. Some key areas include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Method Area:&lt;/strong&gt; Holds information about classes, methods, and static variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heap Area:&lt;/strong&gt; Stores objects created during runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stack Area:&lt;/strong&gt; Stores local variables and method calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Program Counter (PC):&lt;/strong&gt; A register that points to the current instruction being executed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Summary of the Execution Flow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write Code:&lt;/strong&gt; Java code is written in .java files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compile:&lt;/strong&gt; The code is compiled into bytecode (.class files) by the javac compiler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Bytecode:&lt;/strong&gt; The JVM, using the ClassLoader, loads the bytecode into memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find Entry Point:&lt;/strong&gt; The JVM looks for the main() method to start execution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution via Interpreter or JIT:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interpreter:&lt;/strong&gt; Executes bytecode line by line (slower).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JIT Compiler:&lt;/strong&gt; Compiles hot spots into native machine code for faster execution (faster).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The combination of bytecode, JVM, and the JIT compiler ensures that Java is both platform-independent and efficient. The execution flow uses the Interpreter for simplicity and the JIT Compiler for performance optimization, allowing Java programs to run efficiently across various platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The JVM plays a key role in ensuring that Java code is portable and efficient. It first loads the bytecode, then executes it through either an interpreter (slower) or a JIT compiler (faster).&lt;/li&gt;
&lt;li&gt;By using JIT and hot spots, the JVM optimizes performance while maintaining the ability to run the same bytecode on different platforms.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>jvm</category>
      <category>jre</category>
      <category>jdk</category>
    </item>
  </channel>
</rss>
