<?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: CLIFF OYOH OMOLLO</title>
    <description>The latest articles on DEV Community by CLIFF OYOH OMOLLO (@cliffdoyle).</description>
    <link>https://dev.to/cliffdoyle</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1721709%2F9e3ccc65-146e-4f36-b59f-5409dfc19e3a.png</url>
      <title>DEV Community: CLIFF OYOH OMOLLO</title>
      <link>https://dev.to/cliffdoyle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cliffdoyle"/>
    <language>en</language>
    <item>
      <title>Go Beyond Globals: A Practical Guide to Dependency Injection</title>
      <dc:creator>CLIFF OYOH OMOLLO</dc:creator>
      <pubDate>Thu, 07 Aug 2025 12:19:54 +0000</pubDate>
      <link>https://dev.to/cliffdoyle/go-beyond-globals-a-practical-guide-to-dependency-injection-3i67</link>
      <guid>https://dev.to/cliffdoyle/go-beyond-globals-a-practical-guide-to-dependency-injection-3i67</guid>
      <description>&lt;p&gt;When building an application in Go, it's tempting to reach for global variables to share resources like configuration or a logger. It feels easy, but it's a path laden with technical debt.&lt;br&gt;
In this article we will try and investigate the best approach to make our dependencies available to all our handlers, its an approach that i have fallen in love with and use now in almost all my projects.&lt;br&gt;
First let's look at this common but problematic approach which entails assigning our dependencies as global variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//using global variables
var logger *slog.Logger
var appConfig config

func main() {
    // initialize logger and config...
    // register handlers...
}

func HealthcheckHandler(w http.ResponseWriter, r *http.Request) {
    // This handler secretly depends on global state.
    // It's not clear from its signature what it needs to run.
    data := map[string]string{
        "status": "available",
        "environment": appConfig.env, // using global config
    }
    // ... write response ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code works, but it hides a time bomb. It creates implicit, "magical" dependencies that makes our application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hard to Test&lt;/strong&gt;: How do you test a handler that relies on global state? You have to manipulate those globals, which can lead to flaky tests that interfere with each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard to Reason About&lt;/strong&gt;: Looking at HealthcheckHandler's signature, you have no idea it needs appConfig. The function isn't honest about its requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less Reusable&lt;/strong&gt;: The handler is now tightly coupled to the main package and cannot be easily used elsewhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A Cleaner Architecture: Dependency Injection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's build a simple API to see it in action, focusing on three common dependencies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A config struct for application settings.&lt;/li&gt;
&lt;li&gt;A structured slog logger for consistent logging.&lt;/li&gt;
&lt;li&gt;A set of helper methods for centralized JSON error handling.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Dependency #1: Application Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Almost every application needs configuration (port, environment, version, etc.). We'll define a struct to hold this data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// In main.go
type config struct {
    port int
    env  string
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dependency #2: The application Struct&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This struct is our central dependency container. We'll start by adding fields for our config and a structured logger.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// In main.go
import (
    "log/slog"
)

type application struct {
    config config
    logger *slog.Logger
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dependency #3: Centralized Helper Methods&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dependency injection isn't just for data; it's also for behavior. We can define helper methods directly on our application struct. This is perfect for tasks like sending consistent JSON error responses.&lt;br&gt;
These helpers will have access to the other dependencies, like our logger!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// In helpers.go
package main

import (
    "encoding/json"
    "net/http"
)

// The errorResponse method sends a JSON-formatted error message to the client
// with a given status code. It uses our application logger!
func (app *application) errorResponse(w http.ResponseWriter, r *http.Request, status int, message any) {
    env := map[string]any{"error": message}

    js, err := json.Marshal(env)
    if err != nil {
        app.logger.Error("failed to marshal error response", "error", err)
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    w.Header().Set("Content-Type", "application/json; charset=utf-8")
    w.WriteHeader(status)
    w.Write(js)
}

// A specific helper for server errors (500).
func (app *application) serverErrorResponse(w http.ResponseWriter, r *http.Request, err error) {
    app.logger.Error("server error", "request_method", r.Method, "request_url", r.URL.String(), "error", err)
    message := "the server encountered a problem and could not process your request"
    app.errorResponse(w, r, http.StatusInternalServerError, message)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By centralizing this, we ensure all our error responses look the same and are properly logged. Our handlers stay clean and DRY (Don't Repeat Yourself).&lt;br&gt;
&lt;strong&gt;Bringing it Together: Writing Handlers as Methods&lt;/strong&gt;&lt;br&gt;
Now, our handlers become methods on *application, giving them access to everything we've set up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// In handlers.go
package main

import (
    "encoding/json"
    "net/http"
)

// This healthcheck handler can now access the config and logger from app.
func (app *application) healthcheckHandler(w http.ResponseWriter, r *http.Request) {
    data := map[string]string{
        "status":      "available",
        "environment": app.config.env,
        "port":        fmt.Sprintf("%d", app.config.port),
    }

    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(data)
}

func (app *application) createUserHandler(w http.ResponseWriter, r *http.Request) {
    var input struct {
        Name  string `json:"name"`
        Email string `json:"email"`
    }

    err := json.NewDecoder(r.Body).Decode(&amp;amp;input)
    if err != nil {
        // Here we use our new helper!
        app.errorResponse(w, r, http.StatusBadRequest, "invalid request body")
        return
    }

    // ... validation logic for name and email ...

    app.logger.Info("Creating new user", "name", input.Name, "email", input.Email)

    // In a real application, we would pass this data to a `service` layer
    // to handle database interactions.

    w.WriteHeader(http.StatusCreated)
    // ... send success response ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Final main.go&lt;/strong&gt;&lt;br&gt;
Finally, we initialize our dependencies, "inject" them into an application instance, and register our methods with the router.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// In main.go
package main

import (
    "flag"
    "fmt"
    "log/slog"
    "net/http"
    "os"
)

// ... config struct definition ...
// ... application struct definition ...

func main() {
    var cfg config

    // 1. Initialize Dependencies
    flag.IntVar(&amp;amp;cfg.port, "port", 4000, "API server port")
    flag.StringVar(&amp;amp;cfg.env, "env", "development", "Environment (development|staging|production)")
    flag.Parse()

    logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))

    // 2. Create and Inject into the application struct
    app := &amp;amp;application{
        config: cfg,
        logger: logger,
    }

    // 3. Register Method Handlers
    mux := http.NewServeMux()
    mux.HandleFunc("GET /v1/healthcheck", app.healthcheckHandler)
    mux.HandleFunc("POST /v1/users", app.createUserHandler)

    logger.Info("starting server", "addr", fmt.Sprintf(":%d", cfg.port), "env", cfg.env)

    err := http.ListenAndServe(fmt.Sprintf(":%d", cfg.port), mux)
    logger.Error("server failed", "error", err)
    os.Exit(1)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Payoff&lt;/strong&gt;&lt;br&gt;
This dependency injection pattern is foundational for professional Go development. It gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explicit Code&lt;/strong&gt;: Your function signatures are honest. It's clear that your handlers require an *application context to work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Superior Testability&lt;/strong&gt;: You can easily create a mock application instance in your tests with a mock logger and fixed config, allowing you to test handler logic in perfect isolation.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Maintainable Scale&lt;/strong&gt;: Adding a new shared dependency (like a rate limiter or mail client) is as simple as adding a field to the application struct. No messy refactoring required.&lt;br&gt;
By moving away from global variables and embracing the application struct pattern for dependency injection, we are doing more than just cleaning up our code—we are laying a robust foundation for the future of our application.&lt;br&gt;
The beauty of this pattern lies in its extensibility. While we focused on configuration, logging, and helpers, you can see how easily this could expand to include other common dependencies:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A *sql.DB database connection pool.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A pre-compiled *template.Template cache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A client for an external service (like Stripe or an email provider).&lt;br&gt;
This approach provides a fantastic starting point for small to medium-sized applications. &lt;br&gt;
Give this pattern a try in your next Go project. It will lead to code that is cleaner, more professional, and a pleasure to maintain as it grows.&lt;br&gt;
THANK YOU AND HAPPY CODING &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>architecture</category>
      <category>logging</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Rate Limiting</title>
      <dc:creator>CLIFF OYOH OMOLLO</dc:creator>
      <pubDate>Sat, 02 Aug 2025 19:56:31 +0000</pubDate>
      <link>https://dev.to/cliffdoyle/rate-limiting-2m3d</link>
      <guid>https://dev.to/cliffdoyle/rate-limiting-2m3d</guid>
      <description>&lt;p&gt;If you’ve ever built an API for public use, then it’s quite likely that you'll want to implement some form of rate limiting to prevent clients from making too many requests too quickly, and putting excessive strain on your server.&lt;br&gt;
In this guide I am going to demonstrate how to implement this by creating a middleware that will intercept requests coming into the server.&lt;br&gt;
Essentially, we want this middleware to check how many requests have been received in the last ‘N’ seconds and — if there have been too many — then it should send the client a &lt;code&gt;429 Too Many Requests response&lt;/code&gt;. We’ll position this middleware before our main application handlers, so that it carries out this check before we do any expensive processing like decoding a JSON request body or querying our database.&lt;br&gt;
What will become clear by the end of this guide is that you will understand with clarity the principles behind &lt;code&gt;token-bucketrate-limiter algorithms&lt;/code&gt; and how we can apply them in the context of an API or web application.&lt;br&gt;
You will also learn how to create middleware to rate-limit requests to your API endpoints, first by making a single &lt;code&gt;rate global limiter&lt;/code&gt;, then extending it to support &lt;code&gt;per-client limiting based on IP address&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Global Rate Limiting&lt;/strong&gt;&lt;br&gt;
This simply means creating one single token bucket for the entire application. Every single request from every single user spends a token from this shared bucket.&lt;br&gt;
It’s incredibly easy to implement and provides a hard cap on your server's total load, protecting it from a massive, distributed spike in traffic.&lt;br&gt;
However that also means that one misbehaving client can exhaust all the tokens in the global bucket, effectively locking out every other legitimate user. This is often not the desired behavior.&lt;br&gt;
We are not going to implement the rate limiting logic by ourselves from scratch but will instead leverage the &lt;code&gt;x/time/rate package&lt;/code&gt; from golang external library.This package provides a tried-and-tested implementation of a &lt;code&gt;token bucket&lt;/code&gt; rate limiter and we can therefore trust it to do its job perfectly well.&lt;/p&gt;

&lt;p&gt;first we'll need to download the latest version of this package into our code by running this on our terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go get golang.org/x/time/rate@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How token-bucket logic works&lt;/strong&gt;&lt;br&gt;
According to its description from the official &lt;code&gt;x/time/rate&lt;/code&gt; documentation:&lt;br&gt;
&lt;em&gt;A Limiter controls how frequently events are allowed to happen. It implements a “token&lt;br&gt;
bucket” of size &lt;strong&gt;b&lt;/strong&gt; , initially full and refilled at rate r tokens per second.&lt;/em&gt;&lt;br&gt;
Putting that into the context of what we are trying to build translates to this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We will have a bucket that starts with b tokens in it.&lt;/li&gt;
&lt;li&gt;Each time we receive a HTTP request, we will remove one token from the bucket.&lt;/li&gt;
&lt;li&gt;Every 1/r seconds, a token is added back to the bucket — up to a maximum of b total tokens.&lt;/li&gt;
&lt;li&gt;If we receive a HTTP request and the bucket is empty, then we should return a 429 Too Many Requests response.
In practice this means that our application would allow a maximum ‘burst’ of b HTTP requests in quick succession, but over time it would allow an average of r requests per second.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The function we use to create a token bucket rate limiter from x/time/rate is known as NewLimiter() function and has this signature:&lt;code&gt;func NewLimiter(r Limit, b int) *Limiter&lt;/code&gt;&lt;br&gt;
So if we want to create a rate limiter which allows an average of 2 requests per second, with&lt;br&gt;
a maximum of 5 requests in a single ‘burst’, we could do so with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Allow 2 requests per second, with a maximum of 4 requests in a burst.
limiter := rate.NewLimiter(2, 5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Enforcing a global rate limit&lt;/strong&gt;&lt;br&gt;
We that high level description of how a potential rate limiter algorithm works, lets now dive into the code to see how it works practically.&lt;br&gt;
One of the great things about the middleware pattern we’re using is that it allows us to define initialization logic that runs only once, at the moment we wrap a handler with the middleware — not on every request. This is possible because the middleware returns a closure that retains access to the variables in its surrounding scope, such as the rate limiter instance.&lt;/p&gt;

&lt;p&gt;Here’s a simplified example of such middleware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (app *application) exampleMiddleware(next http.Handler) http.Handler {
// Any code here will run only once, when we wrap something with the middleware.
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Any code here will run for every request that the middleware handles.
next.ServeHTTP(w, r)
})
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our case, we’ll create a new &lt;code&gt;rateLimit()&lt;/code&gt;middleware function that initializes a rate limiter once during setup and then reuses it to control the rate of every incoming request that the middleware handles.&lt;br&gt;
inside the function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initialize a new rate limiter which allows an average of 2 requests per second,with a maximum of 4 requests in a single ‘burst’.&lt;/li&gt;
&lt;li&gt;The function we are returning is a closure, which 'closes over' the limiter variable.&lt;/li&gt;
&lt;li&gt;We call the Allow() method to see if the request is permitted, if its not we return a 429 Too many Requests response.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
func rateLimit(next http.Handler) http.Handler {

    limiter := rate.NewLimiter(2, 4)


    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if !limiter.Allow() {

            http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests)
            return
        }
        next.ServeHTTP(w, r)
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this code, whenever we call the &lt;code&gt;Allow()&lt;/code&gt; method on the rate limiter exactly one token will&lt;br&gt;
be consumed from the bucket. If there are no tokens left in the bucket, then Allow() will&lt;br&gt;
return false and that acts as the trigger for us to send the client a 429 Too Many Requests&lt;br&gt;
response.&lt;br&gt;
&lt;strong&gt;Made for Concurrency&lt;/strong&gt;&lt;br&gt;
Internally, the limiter uses a &lt;code&gt;mutex (mutual exclusion lock)&lt;/code&gt;.&lt;br&gt;
A mutex ensures that only one &lt;code&gt;goroutine (thread)&lt;/code&gt; can access or modify the limiter’s internal data at a time.&lt;/p&gt;

&lt;p&gt;This prevents race conditions, where multiple requests could otherwise access and modify the shared token bucket at the same time, leading to unpredictable behavior.&lt;/p&gt;

&lt;p&gt;This makes the rate limiter thread-safe and reliable even when our server is handling thousands of simultaneous requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IP-based Rate Limiting&lt;/strong&gt;&lt;br&gt;
Using a global rate limiter can be useful when you want to enforce a strict limit on the total&lt;br&gt;
rate of requests coming to your API, and you don’t care where the requests are coming from. But it’s generally more common to want an individual rate limiter for each client, so that one bad client making too many requests doesn’t affect all the others.&lt;br&gt;
A conceptually straightforward way to implement this logic is to create an &lt;code&gt;in-memory map of rate limiters&lt;/code&gt;, using the &lt;code&gt;IP address&lt;/code&gt; for each client as the map key.&lt;br&gt;
Each time a new client makes a request to our API, we will initialize a new rate limiter and add it to the map. For any subsequent requests, we will retrieve the client’s rate limiter from the map and check whether the request is permitted by calling its Allow() method, just like we did earlier on.&lt;br&gt;
However, it's important to note that maps are not safe for concurrent use. This is a big issue for our case because our &lt;code&gt;rateLimit()&lt;/code&gt; middleware might be executed in multiple goroutines at a go- by default &lt;code&gt;Go's http.Server&lt;/code&gt; handles each HTTP request in its own goroutine.&lt;br&gt;
From Go blog:&lt;br&gt;
&lt;em&gt;Maps are not safe for concurrent use: it’s not defined what happens when you read and write to them simultaneously. If you need to read from and write to a map from concurrently executing goroutines, the accesses must be mediated by some kind of synchronization mechanism.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;IP addresses&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
In a production environment, it's common for requests to pass through proxy servers before reaching your application. Because of this, the IP address you get from &lt;code&gt;r.RemoteAddr&lt;/code&gt; may not belong to the actual client — instead, it might be the address of the last proxy.&lt;/p&gt;

&lt;p&gt;Fortunately, most proxies add headers like &lt;code&gt;X-Forwarded-For&lt;/code&gt; or &lt;code&gt;X-Real-IP&lt;/code&gt; to the request, which include the &lt;code&gt;original client’s IP address&lt;/code&gt;. By checking these headers first, you can more accurately determine where the request came from.&lt;/p&gt;

&lt;p&gt;Rather than manually writing logic to handle this, you can use a small Go package called &lt;code&gt;realip&lt;/code&gt;. It automatically checks for those headers and, if they’re missing, falls back to &lt;code&gt;r.RemoteAddr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To install the package, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go get github.com/tomasen/realip@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets move on and update our rateLimit() middleware to implement this changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func rateLimitMiddleware(limit rate.Limit, burst int, exceededHandler http.HandlerFunc) func(http.Handler) http.Handler {
    // Shared state: mutex and a map to track rate limiters by //client IP.
    var (
        mu      sync.Mutex
        clients = make(map[string]*rate.Limiter)
    )

    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // Retrieve the real client IP from headers //or fallback to RemoteAddr.
            ip := realip.FromRequest(r)

            // Safely access or create a rate limiter //for the IP address.
            mu.Lock()
            limiter, exists := clients[ip]
            if !exists {
                limiter = rate.NewLimiter(limit, burst)
                clients[ip] = limiter
            }
            // If not allowed, unlock and handle rate //limit exceeded.
            if !limiter.Allow() {
                mu.Unlock()
                http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests)
                return
            }
            mu.Unlock()

            // Proceed to the next handler in the chain.
            next.ServeHTTP(w, r)
        })
    }
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Deleting old limiters&lt;/strong&gt;&lt;br&gt;
The code we wrote earlier works perfectly for rate limiting users based on their IP addresses. However, there’s a small issue we need to fix.&lt;/p&gt;

&lt;p&gt;Right now, we’re using a map[string]*rate.Limiter to store each user’s rate limiter, based on their IP. But the problem is:&lt;/p&gt;

&lt;p&gt;This map will grow endlessly as more and more users visit the site.&lt;/p&gt;

&lt;p&gt;Every new user adds a new key to the clients map, and we never delete them. That means over time — especially on a high-traffic server — this could consume a lot of memory and eventually cause performance issues.&lt;/p&gt;

&lt;p&gt;To make this work, we’ll need to create a custom client struct which holds both the rate limiter and last seen time for each client, and launch the background cleanup goroutine when initializing the middleware.&lt;/p&gt;

&lt;p&gt;Let's go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func rateLimit(next http.Handler) http.Handler {
    // Define a struct to store information for each client, including
    // their rate limiter and the last time we saw a request from them.
    type client struct {
        limiter  *rate.Limiter
        lastSeen time.Time
    }

    var (
        // Mutex to safely access the clients map across goroutines.
        mu sync.Mutex

        // Map to store client IP addresses and their associated rate limiter data.
        clients = make(map[string]*client)
    )

    // Start a background goroutine to clean up clients we haven’t seen recently.
    go func() {
        for {
            // Wait for 1 minute between cleanup runs.
            time.Sleep(time.Minute)

            mu.Lock() // Lock while cleaning to avoid race conditions.

            for ip, c := range clients {
                // Remove clients not seen in the last 3 minutes.
                if time.Since(c.lastSeen) &amp;gt; 3*time.Minute {
                    delete(clients, ip)
                }
            }

            mu.Unlock() // Unlock after cleanup.
        }
    }()

    // Middleware handler function.
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Extract the real IP address of the client.
        ip := realip.FromRequest(r)

        mu.Lock()

        // If the client doesn't exist in our map, create a new rate limiter for them.
        if _, found := clients[ip]; !found {
            clients[ip] = &amp;amp;client{
                limiter: rate.NewLimiter(2, 4), // Allow 2 requests/sec with a burst of 4.
            }
        }

        // Update the lastSeen time to now.
        clients[ip].lastSeen = time.Now()

        // Check if the client is allowed to proceed.
        if !clients[ip].limiter.Allow() {
            mu.Unlock()
            // Respond with a 429 Too Many Requests error.
            http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests)
            return
        }

        mu.Unlock()

        // Call the next handler in the chain if allowed.
        next.ServeHTTP(w, r)
    })
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Distributed Applications&lt;/strong&gt;&lt;br&gt;
In conclusion I would like to reiterate that this in-memory rate-limiting approach works well only if our API is running on a single machine. In a distributed setup — where your application runs on multiple servers behind a load balancer — this pattern can not be effective.&lt;/p&gt;

&lt;p&gt;If you’re using HAProxy or Nginx as your load balancer or reverse proxy, consider using their built-in rate-limiting features. These are often the most straightforward solution.&lt;/p&gt;

&lt;p&gt;Alternatively, for more complex setups, you can use a centralized, fast data store like Redis to track request counts. This allows all your application servers to coordinate rate-limiting through a shared backend.&lt;br&gt;
THANK YOU AND HAPPY CODING!&lt;/p&gt;

</description>
      <category>backenddevelopment</category>
      <category>webdev</category>
      <category>go</category>
      <category>api</category>
    </item>
    <item>
      <title>A Guide to Graceful Shutdowns</title>
      <dc:creator>CLIFF OYOH OMOLLO</dc:creator>
      <pubDate>Thu, 31 Jul 2025 21:12:59 +0000</pubDate>
      <link>https://dev.to/cliffdoyle/a-guide-to-graceful-shutdowns-40mi</link>
      <guid>https://dev.to/cliffdoyle/a-guide-to-graceful-shutdowns-40mi</guid>
      <description>&lt;p&gt;If you've built a web server in Go, you probably started it with a simple &lt;code&gt;http.ListenAndServe()&lt;/code&gt;. It works great until you need to stop it. What do you do? You hit &lt;code&gt;Ctrl+C&lt;/code&gt;, and the process dies instantly.&lt;/p&gt;

&lt;p&gt;When we stop our API application (usually by pressing Ctrl+C ) it is terminated immediately with no opportunity for in-flight HTTP requests to complete. This isn’t ideal for two reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It means that clients won’t receive responses to their in-flight requests — all they will experience is a hard closure of the HTTP connection.&lt;/li&gt;
&lt;li&gt;Any work being carried out by our handlers may be left in an incomplete state.
I am going to demonstrate to you how to mitigate these problems by adding &lt;code&gt;graceful shutdown&lt;/code&gt; functionality inside your application in a very simple way, so that in-flight HTTP requests have the opportunity to finish being processed
before the application is terminated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is a Graceful Shutdown?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A graceful shutdown is a process where a server:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stops accepting new incoming connections the moment the shutdown signal is received. &lt;/li&gt;
&lt;li&gt;Continues to handle any requests already in progress. &lt;/li&gt;
&lt;li&gt;Waits for all active requests to finish before shutting down completely.&lt;/li&gt;
&lt;li&gt;Has a timeout, so it doesn't wait forever for a stuck request.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The Starting Point: Normal Server&lt;/strong&gt;&lt;br&gt;
Here’s a standard, basic Go web server. It has the problem we described—hitting Ctrl+C kills it instantly leaving no room for the background operations running in other goroutines to actually finish there tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello, World!")
    })

    fmt.Println("Starting server on :4000")
    err := http.ListenAndServe(":4000", mux)
    if err != nil {
        fmt.Println("Error starting server:", err)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 1: Listening for OS Signals&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When our application is running, we can terminate it at any time by sending it a specific&lt;br&gt;
signal. A common way to do this, which you’ve probably been using, is by pressing Ctrl+C&lt;br&gt;
on your keyboard to send an interrupt signal — also known as a &lt;code&gt;SIGINT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It’s important to explain upfront that some signals are catchable and others are not. Catchable signals can be intercepted by our application and either ignored, or used to trigger a certain action (such as a graceful shutdown).Other signals, like &lt;code&gt;SIGKILL&lt;/code&gt; , are not catchable and cannot be intercepted.&lt;/p&gt;

&lt;p&gt;We'll use a &lt;code&gt;buffered channel&lt;/code&gt; to receive these signals.&lt;/p&gt;

&lt;p&gt;Why a buffered channel? The &lt;code&gt;signal.Notify()&lt;/code&gt; function that sends signals doesn't wait for a receiver to be ready. If we used a regular (&lt;code&gt;unbuffered&lt;/code&gt;) channel, a signal could be sent at the exact moment our channel isn't ready to receive, and the signal would be missed. A buffer of size 1 ensures that a signal can be "dropped off" in the channel and picked up a moment later, guaranteeing we never miss it.&lt;/p&gt;

&lt;p&gt;The next thing that we want to do is update the server so that it ‘catches’ any &lt;code&gt;SIGINT&lt;/code&gt; and &lt;code&gt;SIGTERM&lt;/code&gt; signals. As I mentioned above, &lt;code&gt;SIGKILL&lt;/code&gt; signals are not &lt;code&gt;catchable&lt;/code&gt; (and will always cause the application to terminate immediately), and we’ll leave &lt;code&gt;SIGQUIT&lt;/code&gt; with its default behavior (as it’s handy if you want to execute a non-graceful shutdown via a keyboard shortcut).&lt;br&gt;
To catch the signals, we’ll need to spin up a background goroutine which runs for the lifetime of the application we are writing. In this background goroutine, we can use the &lt;code&gt;signal.Notify()&lt;/code&gt;function to listen for specific signals and relay them to a channel for further processing.&lt;br&gt;
I’ll demonstrate how to set up the listener goroutine in the background:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go func() {
    quit := make(chan os.Signal, 1)

    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

    s := &amp;lt;-quit

    fmt.Println("Caught signal:", s.String())
}()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above isn’t doing much —But the important thing is that it demonstrates&lt;br&gt;
the pattern of how to catch specific signals and handle them inside your code. With that in place I'll now proceed to the actual implementation of graceful shutdown that's our main topic in step two below.&lt;br&gt;
&lt;strong&gt;Step 2: Orchestrating the Shutdown&lt;/strong&gt;&lt;br&gt;
After catching a specific signal using our useful goroutine above, we now need a way to inform our server to begin the process of graceful shutdown process. Luckily enough our &lt;code&gt;http.Server&lt;/code&gt; struct has a very powerful method known as &lt;code&gt;Shutdown()&lt;/code&gt;that we can call to do just that.The official documentation describes this as follows:&lt;br&gt;
&lt;em&gt;Shutdown gracefully shuts down the server without interrupting any active connections.&lt;br&gt;
Shutdown works by first closing all open listeners, then closing all idle connections, and&lt;br&gt;
then waiting indefinitely for connections to return to idle and then shut down.&lt;/em&gt;&lt;br&gt;
Before writing the code let me explain step by step how this works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Shutdown() method on HTTP server takes context.Context as an argument, this allows one to set a timeout. The timeout simply acts as a safety net as it tells the shutdown process to not wait longer than time set i.e 37 seconds.&lt;/li&gt;
&lt;li&gt;Calling &lt;code&gt;server.Shutdown()&lt;/code&gt; causes &lt;code&gt;server.ListenAndServe()&lt;/code&gt; to immediately stop blocking and return an http.ErrServerClosed error. This is a "good" error—it allows us to know the graceful shutdown has begun.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;server.Shutdown()&lt;/code&gt; itself then blocks and waits for all active requests to finish (or for its context to time out).&lt;/li&gt;
&lt;li&gt;Once it's done, server.Shutdown() returns its own result: nil if successful, or an error if it timed out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now lets head to code and show how all this fits in together to implement graceful shutdwon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "context"
    "errors"
    "fmt"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    if err := serve(); err != nil {
        fmt.Println("Server error:", err)
        os.Exit(1)
    }
    fmt.Println("Server stopped successfully.")
}

func serve() error {
    mux := http.NewServeMux()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello, World!")
    })

    server := &amp;amp;http.Server{
        Addr:    ":4000",
        Handler: mux,
    }

    shutdownError := make(chan error)

    go func() {
        quit := make(chan os.Signal, 1)
        signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
        s := &amp;lt;-quit

        fmt.Println("Caught signal:", s.String())

        ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
        defer cancel()

        shutdownError &amp;lt;- server.Shutdown(ctx)
    }()

    fmt.Println("Starting server on", server.Addr)

    err := server.ListenAndServe()
    if !errors.Is(err, http.ErrServerClosed) {
        return err
    }

    err = &amp;lt;-shutdownError
    if err != nil {
        return err
    }

    return nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Seeing it in Action&lt;/strong&gt;&lt;br&gt;
For now, when you try to run this and press Ctr+C, it still looks like it shuts down almost instantly and that is very true because at the moment we have no slow request coming into our server. So to demonstrate our graceful shutdown implementation can handle slow request and thus the issues we highlighted above, we'll create a slow endpoint and see how it's handled, lets go into the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func slowHandler(w http.ResponseWriter, r *http.Request){
    fmt.Println("Starting slow request...")

    time.Sleep(10 * time.Second) 

    fmt.Println("...finished slow request.")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order for this to work you'll need to create an endpoint for this handler, just below the line where we create the serve mux, 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;mux.HandleFunc("/slow", slowHandler)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run the Test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You'll need two terminals so as to see everything happening real time.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Terminal 1:&lt;/code&gt; for running your Go server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go run .
# Output: Starting server on :4000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Terminal 2:&lt;/code&gt; we make a request to the slow endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://localhost:4000/slow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Terminal 1 (Immediately):&lt;/code&gt; As soon as curl is running, switch back to your server's terminal and press Ctrl+C.&lt;br&gt;
&lt;strong&gt;&lt;code&gt;logs in terminal 1:&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Starting server on :4000
Starting slow request...        &amp;lt;-- curl started the request
# You press Ctrl+C now
Caught signal: interrupt       &amp;lt;-- The shutdown process begins!
# The server is now waiting patiently... (for about 9 seconds)
...finished slow request.       &amp;lt;-- The handler was allowed to finish
Server stopped successfully.    &amp;lt;-- Clean exit!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In terminal 2, curl completes successfully after 10 seconds. We just implemented a graceful handling of an in-flight request!&lt;/p&gt;

&lt;p&gt;That's it! Any time that we want to gracefully shutdown our application, we can do so by sending a &lt;code&gt;SIGINT ( Ctrl+C )&lt;/code&gt; or &lt;code&gt;SIGTERM signal&lt;/code&gt;. So long as no in-flight requests take more than 30 seconds to complete, our handlers will have time to complete their work and our clients will receive a proper HTTP response.And if we ever want to exit immediately, without a graceful shutdown, we can still do so by sending a&lt;code&gt;SIGQUIT ( Ctrl+\ )&lt;/code&gt; or &lt;code&gt;SIGKILL signal&lt;/code&gt; instead. &lt;/p&gt;

&lt;p&gt;THANK YOU AND HAPPY CODING!&lt;/p&gt;

</description>
      <category>backend</category>
      <category>webdev</category>
      <category>go</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understanding Base numbering System and Bitwise Operations</title>
      <dc:creator>CLIFF OYOH OMOLLO</dc:creator>
      <pubDate>Wed, 24 Jul 2024 07:02:05 +0000</pubDate>
      <link>https://dev.to/cliffdoyle/understanding-base-numbering-system-and-bitwise-operations-ioc</link>
      <guid>https://dev.to/cliffdoyle/understanding-base-numbering-system-and-bitwise-operations-ioc</guid>
      <description>&lt;p&gt;Throughout human history, our quest to represent numbers has sparked countless innovations. From the early days of counting on fingers and toes to the intricate hieroglyphs etched in clay, each civilization crafted unique systems. The Greeks introduced the Ionic system, while the Romans famously gave us numerals like I, V, X. Yet, as societies advanced, these methods proved cumbersome to work with. The decimal place system, which has roots in Hindu-Arabic and Chinese traditions,has become the standard we use today.&lt;/p&gt;

&lt;p&gt;With the advent of computers, new number systems emerged. Binary, octal, and hexadecimal systems emerged as vital tools in processing data, revolutionizing how we compute and communicate. The binary system (base-2) became fundamental to digital technology, while octal (base-8) and hexadecimal (base-16) systems provided more efficient ways to represent and process large amounts of data. These modern systems replace the familiar base-10 of our everyday arithmetic, marking a significant shift in how we understand and utilize numbers in the digital age.&lt;/p&gt;

&lt;p&gt;In this article, we delve into the intricacies of these different numbering systems and explore their practical applications in modern computing. Additionally, we'll unravel the mysteries of bitwise operations, showcasing how they empower programmers to manipulate data at the most fundamental level.&lt;/p&gt;

&lt;h3&gt;
  
  
  Algebra behind the decimal system
&lt;/h3&gt;

&lt;p&gt;Each position in a decimal number represents a power of 10. Each place value to the left of the decimal point increases by a power of 10.&lt;/p&gt;

&lt;p&gt;The expression;&lt;/p&gt;

&lt;p&gt;m × 10&lt;sup&gt;3&lt;/sup&gt; + n × 10&lt;sup&gt;2&lt;/sup&gt; + o × 10&lt;sup&gt;1&lt;/sup&gt; + p × 10&lt;sup&gt;0&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;where m, n, o, p take on any value between 0 and 9, describes any whole number between 0 and 9999. By including&lt;/p&gt;

&lt;p&gt;q × 10&lt;sup&gt;-1&lt;/sup&gt; + r × 10&lt;sup&gt;-2&lt;/sup&gt; + s × 10&lt;sup&gt;-3&lt;/sup&gt; + t × 10&lt;sup&gt;-4&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;where q, r, s, t take on any value between 0 and 9, any decimal number between 0 and 9999.9999 can be represented.&lt;/p&gt;

&lt;p&gt;Indices bring the notation alive and reveal the true underlying pattern:&lt;/p&gt;

&lt;p&gt;. . . m10&lt;sup&gt;3&lt;/sup&gt; + n10&lt;sup&gt;2&lt;/sup&gt; + o10&lt;sup&gt;1&lt;/sup&gt; + p10&lt;sup&gt;0&lt;/sup&gt; + q10&lt;sup&gt;-1&lt;/sup&gt; + r 10&lt;sup&gt;-2&lt;/sup&gt; + s10&lt;sup&gt;-3&lt;/sup&gt; + t10&lt;sup&gt;-4&lt;/sup&gt; . . . .&lt;/p&gt;

&lt;p&gt;Remember that any number raised to the power 0 equals 1. By adding extra terms both left and right, any number can be accommodated.&lt;/p&gt;

&lt;p&gt;In this example, 10 is the base, which means that the values of m to t range between 0 and 9, 1 less than the base. Therefore, by substituting B for the base we have&lt;/p&gt;

&lt;p&gt;. . . mB&lt;sup&gt;3&lt;/sup&gt; + nB&lt;sup&gt;2&lt;/sup&gt; + oB&lt;sup&gt;1&lt;/sup&gt; + pB&lt;sup&gt;0&lt;/sup&gt; + qB&lt;sup&gt;-1&lt;/sup&gt; + rB&lt;sup&gt;-2&lt;/sup&gt; + sB&lt;sup&gt;-3&lt;/sup&gt; + tB&lt;sup&gt;-4&lt;/sup&gt; . . .&lt;/p&gt;

&lt;p&gt;where the values of m to t range between 0 and B − 1.&lt;/p&gt;

&lt;h3&gt;
  
  
  Octal Numbers
&lt;/h3&gt;

&lt;p&gt;The Octal number system has B = 8 and m to t range between 0 and 7.&lt;/p&gt;

&lt;p&gt;. . . m8&lt;sup&gt;3&lt;/sup&gt; + n8&lt;sup&gt;2&lt;/sup&gt; + o8&lt;sup&gt;1&lt;/sup&gt; + p8&lt;sup&gt;0&lt;/sup&gt; + q8&lt;sup&gt;-1&lt;/sup&gt; + r 8&lt;sup&gt;-2&lt;/sup&gt; + s8&lt;sup&gt;-3&lt;/sup&gt; + t8&lt;sup&gt;-4&lt;/sup&gt; . . .&lt;/p&gt;

&lt;p&gt;and the first 1 octal numbers are&lt;/p&gt;

&lt;p&gt;18, 28, 38, 48, 58, 68, 78, 108, 118, 128, 138, 148, 158, 168, 178.&lt;/p&gt;

&lt;p&gt;Octal numbering (base-8), has no digits ‘8’ or ‘9’ in Octal representation, as the highest single-digit number in octal ‘7’. So decimal ‘8’ in Octal will be 10. To understand how decimal ‘8’ converts to octal 10 we can use this steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Divide the decimal number by 8.&lt;/li&gt;
&lt;li&gt;Record the remainder.&lt;/li&gt;
&lt;li&gt;Divide the quotient by 8 again, recording the remainder each time until the quotient is zero.&lt;/li&gt;
&lt;li&gt;The octal number is the remainders read in reverse order.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example 1: converting decimal ‘8’ to Octal will be;
&lt;/h3&gt;

&lt;p&gt;Divide 8 by 8:&lt;/p&gt;

&lt;p&gt;Quotient = 1&lt;/p&gt;

&lt;p&gt;Remainder = 0&lt;/p&gt;

&lt;p&gt;Since the quotient is now 1, we continue:&lt;/p&gt;

&lt;p&gt;Divide 1 by 8:&lt;/p&gt;

&lt;p&gt;Quotient = 0 (since 1 divided by 8 is less than 1, so the quotient is 0)&lt;/p&gt;

&lt;p&gt;Remainder = 1&lt;/p&gt;

&lt;p&gt;Reading the remainders in reverse order, we get 10.&lt;/p&gt;

&lt;p&gt;The subscript 8, reminds us that although we may continue to use the words “fifteen”, it is an octal number, and not a decimal. But what is 138 in decimal? Well, it stands for&lt;/p&gt;

&lt;p&gt;1 × 8&lt;sup&gt;1&lt;/sup&gt; + 3 × 8&lt;sup&gt;0&lt;/sup&gt; = 11&lt;/p&gt;

&lt;p&gt;Thus 268.38 in decimal equals;&lt;/p&gt;

&lt;p&gt;(2 x 8&lt;sup&gt;2&lt;/sup&gt;) + (6 x 8&lt;sup&gt;1&lt;/sup&gt;) + (8 x 8&lt;sup&gt;0&lt;/sup&gt;) + (3 x 8&lt;sup&gt;-1&lt;/sup&gt;)&lt;/p&gt;

&lt;p&gt;(2 x 64) + (6 x 8) + (8 x 1) + (3 x 0.125)&lt;/p&gt;

&lt;p&gt;(128 + 48 + 8 + 0.375)&lt;/p&gt;

&lt;p&gt;=184.375&lt;/p&gt;

&lt;p&gt;Counting in octal seems challenging at first only because we're not familiar with it, unlike the decimal system. If humans had developed with 8 fingers instead of 10, we would naturally be counting in octal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hexadecimal Numbers
&lt;/h3&gt;

&lt;p&gt;The hexadecimal number system has B = 16, and m to t can be 0 to 15, which presents a slight problem, as we don’t have 15 different numerical characters. Consequently, we use 0 to 9, and the letters A, B, C, D, E, F to represent 10, 11, 12, 13, 14, 15 respectively&lt;/p&gt;

&lt;p&gt;. . . m16&lt;sup&gt;3&lt;/sup&gt; + n16&lt;sup&gt;2&lt;/sup&gt; + o16&lt;sup&gt;1&lt;/sup&gt; + p16&lt;sup&gt;0&lt;/sup&gt; + q16&lt;sup&gt;-1&lt;/sup&gt; + r16&lt;sup&gt;-2&lt;/sup&gt; + s16&lt;sup&gt;-3&lt;/sup&gt; + 16&lt;sup&gt;-4&lt;/sup&gt; . . .&lt;/p&gt;

&lt;p&gt;and the first 15 hexadecimal numbers are:&lt;/p&gt;

&lt;p&gt;116, 216, 316, 416, 516, 616, 716, 816, 916, A16, B16, C16, D16, E16, F16.&lt;/p&gt;

&lt;p&gt;Thus 1E.816 in decimal, equals&lt;/p&gt;

&lt;p&gt;(1 × 16) + (E × 1) + (8 × 16&lt;sup&gt;-1&lt;/sup&gt;)&lt;/p&gt;

&lt;p&gt;(16 + 14) + (8/16)&lt;/p&gt;

&lt;p&gt;=30.5&lt;/p&gt;

&lt;h3&gt;
  
  
  Binary Numbers
&lt;/h3&gt;

&lt;p&gt;The binary number system has B=2, and m to t are 0 or 1.&lt;/p&gt;

&lt;p&gt;.. m2&lt;sup&gt;3&lt;/sup&gt; + n2&lt;sup&gt;2&lt;/sup&gt; + o2&lt;sup&gt;1&lt;/sup&gt; + p2&lt;sup&gt;0&lt;/sup&gt; + q2&lt;sup&gt;-1&lt;/sup&gt; + r 2&lt;sup&gt;-2&lt;/sup&gt; + s2&lt;sup&gt;-3&lt;/sup&gt; + t2&lt;sup&gt;-4&lt;/sup&gt; . . .&lt;/p&gt;

&lt;p&gt;And the first 5 binary numbers are;&lt;/p&gt;

&lt;p&gt;12, 102, 112, 1002, 1012.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step-by-Step Process of Converting Decimal to Binary;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Divide the number by 2.&lt;/li&gt;
&lt;li&gt;Record the remainder.&lt;/li&gt;
&lt;li&gt;Update the number to be the quotient of the division by 2.&lt;/li&gt;
&lt;li&gt;Repeat steps 1-3 until the number is 0.&lt;/li&gt;
&lt;li&gt;The binary representation is the sequence of remainders read from bottom to top (last to first).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example: Convert 29 to Binary
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;29 ÷ 2 = 14, remainder = 1&lt;/li&gt;
&lt;li&gt;14 ÷ 2 = 7, remainder = 0&lt;/li&gt;
&lt;li&gt;7 ÷ 2 = 3, remainder = 1&lt;/li&gt;
&lt;li&gt;3 ÷ 2 = 1, remainder = 1&lt;/li&gt;
&lt;li&gt;1 ÷ 2 = 0, remainder = 1&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Reading the remainders from bottom to top, the binary representation of 29 is 11101.&lt;/p&gt;

&lt;p&gt;Thus, 11011.112 in decimal equals:&lt;/p&gt;

&lt;p&gt;(1 × 2&lt;sup&gt;4&lt;/sup&gt;) + (1 × 2&lt;sup&gt;3&lt;/sup&gt;) + (0 × 2&lt;sup&gt;2&lt;/sup&gt;) + (1 × 2&lt;sup&gt;1&lt;/sup&gt;) + (1 × 2&lt;sup&gt;0&lt;/sup&gt;) + (1 × 2&lt;sup&gt;-1&lt;/sup&gt;) + (1 × 2&lt;sup&gt;-2&lt;/sup&gt;)&lt;/p&gt;

&lt;p&gt;(1 × 16) + (1 × 8) + (0 × 4) + (1 × 2) + (1 × 1) + (1 × 0.5) + (1 × 0.25)&lt;/p&gt;

&lt;p&gt;(16 + 8 + 2) + (1 + 0.5 + 0.25)&lt;/p&gt;

&lt;p&gt;= 26.75&lt;/p&gt;

&lt;h3&gt;
  
  
  Logic and Bit Operations
&lt;/h3&gt;

&lt;p&gt;Computers represent information using Bits. A bit is a symbol with two possible values, namely 0 and 1. The meaning of the word bit comes from binary digit. A bit can be used to represent a truth value because there are two truth values, namely, true and false, with 1 bit representing True and 0 bit representing False.&lt;/p&gt;

&lt;p&gt;At the lowest level, computers have to represent information using simple switches, which can be either on or off. If one switch were used to represent a number, you could only represent the values 0 (switch “off”) or 1 (switch “on”). If you combine multiple bits, you can represent larger numbers. In everyday life, we have the most experience with decimal notation, which uses the digits 0 through 9. But binary notation uses only the digits 0 and 1 to represent numbers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Bitwise AND (&amp;amp;)
&lt;/h4&gt;

&lt;p&gt;The bitwise AND operation compares each bit of two numbers. If both bits are 1, the result is 1. Otherwise, it's 0. To illustrate this, we’ll look at the following example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: 5 &amp;amp; 3&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert to binary:

&lt;ul&gt;
&lt;li&gt;5 in binary: 0101&lt;/li&gt;
&lt;li&gt;3 in binary: 0011&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Perform AND operation:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;0101&lt;br&gt;
&amp;amp;0011&lt;br&gt;
0001&lt;/p&gt;

&lt;p&gt;3.Result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0001 in binary is 1 in decimal.&lt;/li&gt;
&lt;li&gt;So, 5 &amp;amp; 3 is 1.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Bitwise OR (|)
&lt;/h4&gt;

&lt;p&gt;The bitwise OR operation compares each bit of two numbers. If at least one of the bits is 1, the result is 1. Otherwise, it's 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: 5 | 3&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert to binary:

&lt;ul&gt;
&lt;li&gt;5 in binary: 0101&lt;/li&gt;
&lt;li&gt;3 in binary: 0011&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Perform OR operation:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;0101&lt;br&gt;
|0011&lt;br&gt;
0111&lt;/p&gt;

&lt;p&gt;3.Result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0111 in binary is 7 in decimal.&lt;/li&gt;
&lt;li&gt;So, 5 | 3 is 7.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Bitwise XOR (^)
&lt;/h4&gt;

&lt;p&gt;The bitwise XOR operation compares each bit of two numbers. If the bits are different, the result is 1. If they are the same, the result is 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: 5 ^ 3&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert to binary:

&lt;ul&gt;
&lt;li&gt;5 in binary: 0101&lt;/li&gt;
&lt;li&gt;3 in binary: 0011&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Perform XOR operation:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;0101&lt;br&gt;
^0011&lt;br&gt;
0110&lt;/p&gt;

&lt;p&gt;3.Result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0110 in binary is 6 in decimal.&lt;/li&gt;
&lt;li&gt;So, 5 ^ 3 is 6.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Bitwise NOT (~)
&lt;/h4&gt;

&lt;p&gt;The bitwise NOT operation flips each bit of the number (0 becomes 1 and 1 becomes 0). This operation works on a single number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: ~5&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert to binary:

&lt;ul&gt;
&lt;li&gt;5 in binary: 0101&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Perform NOT operation:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;~ 0101&lt;br&gt;
1010&lt;/p&gt;

&lt;p&gt;3.Result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In many systems, this operation is performed on 32-bit integers.&lt;/li&gt;
&lt;li&gt;So, 0101 would be represented as 00000000000000000000000000000101.&lt;/li&gt;
&lt;li&gt;The result of ~5 would be 11111111111111111111111111111010.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Left Shift (&amp;lt;&amp;lt;)
&lt;/h4&gt;

&lt;p&gt;The left shift operation shifts all bits of a number to the left by a certain number of positions. The bits that are shifted out on the left are discarded, and zeros are shifted in from the right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: 5 &amp;lt;&amp;lt; 1&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Convert to binary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;5 in binary: 0101&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Perform Left Shift by 1 Position:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you left shift by 1, each bit moves one position to the left.&lt;/li&gt;
&lt;li&gt;The leftmost bit (most significant bit) is discarded.&lt;/li&gt;
&lt;li&gt;A zero is added to the rightmost bit (least significant bit).
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Original:  0101  (binary for 5)
Shifted:   1010  (binary for 10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Visual Representation of Left Shift&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Illustration of the left shift step-by-step:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Original Bits&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Position: 3 2 1 0&lt;br&gt;
Bits: 0 1 0 1 (5 in binary)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shift All Bits to the Left by 1 Position:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Position: 4 3 2 1&lt;br&gt;
New Bits: 1 0 1 0 (after left shift by 1)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The bit in position 3 moves to position 4.&lt;/li&gt;
&lt;li&gt;The bit in position 2 moves to position 3.&lt;/li&gt;
&lt;li&gt;The bit in position 1 moves to position 2.&lt;/li&gt;
&lt;li&gt;The bit in position 0 moves to position 1.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A zero is added to the new rightmost position (position 0).&lt;br&gt;
3.Resulting Binary Number:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New binary number after the shift: 1010&lt;/li&gt;
&lt;li&gt;1010 in binary is 10 in decimal.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  Right Shift (&amp;gt;&amp;gt;)
&lt;/h4&gt;

&lt;p&gt;The right shift operation shifts all bits of a binary number to the right by a specified number of positions. The bits that are shifted out on the right are discarded, and zeros are shifted in from the left.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: 5 &amp;gt;&amp;gt; 1&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Convert to Binary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;5 in binary: 0101&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Perform Right Shift by 1 Position:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you right shift by 1, each bit moves one position to the right.&lt;/li&gt;
&lt;li&gt;The rightmost bit (least significant bit) is discarded.&lt;/li&gt;
&lt;li&gt;A zero is added to the leftmost bit (most significant bit).
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Original:  0101  (binary for 5)
Shifted:   0010  (binary for 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Visual Representation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Illustration of the right shift step-by-step:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Original Bits&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Position: 3 2 1 0&lt;br&gt;
Bits: 0 1 0 1 (5 in binary)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shift All Bits to the Right by 1 Position:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Position: - 3 2 1&lt;br&gt;
New Bits: 0 0 1 0 (after right shift by 1)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The bit in position 3 moves to position 2.&lt;/li&gt;
&lt;li&gt;The bit in position 2 moves to position 1.&lt;/li&gt;
&lt;li&gt;The bit in position 1 moves to position 0.&lt;/li&gt;
&lt;li&gt;The bit in position 0 is discarded.&lt;/li&gt;
&lt;li&gt;A zero is added to the new leftmost position (position 3).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.Resulting Binary Number:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; New binary number after the shift: 0010
- 0010 in binary is 2 in decimal.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Understanding these operations and conversions is fundamental in computer science and digital electronics, as they form the basis for more complex algorithms and data manipulation techniques.&lt;/p&gt;

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