Author: fire_horse

  • 🕵️‍♂️ Wireshark: Seeing the Internet Beneath the Surface

    Most people use the internet every day without ever seeing what’s actually happening under the hood. We click links, send messages, stream videos—and everything just works.

    But beneath that simplicity lies a constant flow of packets: tiny chunks of data moving across networks at incredible speed.

    If you’ve ever wanted to see that invisible layer, Wireshark is where things get interesting.


    What is Wireshark?

    Wireshark is a network protocol analyzer—a tool that lets you capture and inspect the data traveling across a network in real time.

    Think of it as:

    • A microscope for network traffic
    • A debugger for connectivity issues
    • A truth-teller when systems behave strangely

    It shows you exactly what data is being sent, where it’s going, and how it’s structured.


    Why Wireshark Matters

    At first glance, Wireshark can feel overwhelming. Thousands of packets, cryptic protocols, endless columns.

    But once you understand it, it becomes incredibly powerful.

    🔍 Troubleshooting Network Issues

    When something breaks, logs don’t always tell the full story. Wireshark shows:

    • Failed connections
    • Retransmissions
    • DNS issues
    • Latency bottlenecks

    Instead of guessing, you see the problem.


    🔐 Security Analysis

    Wireshark is widely used in cybersecurity to:

    • Detect suspicious traffic
    • Identify data leaks
    • Analyze malware communication
    • Inspect unencrypted credentials

    It’s not a hacking tool—but it’s often used to understand how attacks work.


    📡 Learning How the Internet Works

    If you want to truly understand networking, there’s no better teacher.

    You can observe:

    • TCP handshakes
    • HTTP requests and responses
    • TLS encryption flows
    • DNS lookups

    It turns abstract concepts into something tangible.


    A Simple Example

    Let’s say you open a website.

    Behind the scenes, Wireshark will show something like:

    1. Your computer sends a DNS request to resolve the domain
    2. A TCP handshake is established (SYN → SYN-ACK → ACK)
    3. An HTTP or HTTPS request is sent
    4. The server responds with data packets
    5. Your browser reconstructs everything into a webpage

    What feels instant is actually a series of precise, structured steps.


    Key Features That Make Wireshark Powerful

    📊 Deep Packet Inspection

    Wireshark doesn’t just capture packets—it decodes them into human-readable formats.


    🔎 Powerful Filtering

    Instead of drowning in data, you can filter traffic like:

    http
    dns
    ip.addr == 192.168.1.1
    tcp.port == 443
    

    This turns chaos into clarity.


    ⏱️ Real-Time Capture

    You can watch traffic as it happens, which is incredibly useful for debugging live systems.


    The Learning Curve (and Why It’s Worth It)

    Let’s be honest—Wireshark is not beginner-friendly.

    The interface can feel intimidating:

    • Thousands of packets scrolling
    • Protocols you’ve never heard of
    • Hex data everywhere

    But once you learn:

    • Basic networking (TCP/IP, DNS, HTTP)
    • How to filter traffic
    • How to follow streams

    …it becomes one of the most valuable tools in your toolkit.


    Who Should Learn Wireshark?

    • Site Reliability Engineers (SREs)
    • Backend engineers
    • Security analysts
    • DevOps engineers
    • Curious developers

    If you work with systems, networks, or APIs—this tool will give you an edge.


    Final Thoughts

    Wireshark changes how you see the internet.

    It takes something invisible and makes it observable.
    It turns guesswork into evidence.
    It forces you to understand how things actually work.

    And once you’ve used it, you’ll never look at a “simple” web request the same way again.


  • Binary Gap

    A binary gap within a positive integer N is any maximal sequence of consecutive zeros that is surrounded by ones at both ends in the binary representation of N. For example, number 9 has binary representation 1001 content_copy and contains a binary gap of length 2. The number 529 has binary representation 1000010001 content_copy and contains two binary gaps: one of length 4 and one of length 3. The number 20 has binary representation 10100 content_copy and contains one binary gap of length 1. The number 15 has binary representation 1111 content_copy and has no binary gaps. The number 32 has binary representation 100000 content_copy and has no binary gaps. Write a function: function solution(N); content_copy that, given a positive integer N, returns the length of its longest binary gap. The function should return 0 if N doesn’t contain a binary gap. For example, given N = 1041 the function should return 5, because N has binary representation 10000010001 content_copy and so its longest binary gap is of length 5. Given N = 32 the function should return 0, because N has binary representation ‘100000’ and thus no binary gaps. Write an efficient algorithm for the following assumptions: N is an integer within the range [1..2,147,483,647].

    // you can write to stdout for debugging purposes, e.g.
    // console.log('this is a debug message');
    
    function solution(N) {
      const binary = N.toString(2);
      let maxGap = 0;
      let currentGap = 0;
      let counting = false;
    
      for (let char of binary) {
        if (char === "1") {
          if (counting) {
            maxGap = Math.max(maxGap, currentGap);
          }
          counting = true;
          currentGap = 0;
        } else if (counting) {
          currentGap++;
        }
      }
    
      return maxGap;
    }
    

  • Why This Fibonacci Code Is Smarter Than It Looks

    At first glance, a Fibonacci function seems like a simple coding exercise. You take a number n, and return the nth number in the Fibonacci sequence:

    0, 1, 1, 2, 3, 5, 8, 13, 21…

    Each number is the sum of the two before it.

    Many beginners write Fibonacci using recursion because it feels natural. But while recursive code looks elegant, it can hide a major performance problem.

    The Classic Recursive Version

    var yourself = {
        fibonacci : function(n) {
            if (n === 0) {
                return 0;
            } else if (n === 1) {
                return 1;
            } else {
                return this.fibonacci(n - 1) +
                    this.fibonacci(n - 2);
            }
        }
    };
    

    This works correctly, but it becomes painfully slow as n grows.

    Why?

    Because the function keeps solving the same subproblems repeatedly.

    For example, to calculate fibonacci(6), it must calculate:

    • fibonacci(5)
    • fibonacci(4)

    But inside fibonacci(5), it calculates fibonacci(4) again.

    Then deeper down, it recalculates fibonacci(3), fibonacci(2), and so on many times.

    The result is a lot of wasted work.

    A Better Approach: Memoization

    Memoization is a technique where you store previously calculated results so they can be reused instantly.

    Instead of recalculating fibonacci(4) ten times, compute it once and save it.

    Here’s the improved version:

    var yourself = {
        cache: {},
    
        fibonacci: function(n) {
            if (n === 0) return 0;
            if (n === 1) return 1;
    
            if (this.cache[n] !== undefined) {
                return this.cache[n];
            }
    
            this.cache[n] =
                this.fibonacci(n - 1) +
                this.fibonacci(n - 2);
    
            return this.cache[n];
        }
    };

    What This Code Is Doing

    The object contains two parts:

    1. A cache

    cache: {}

    This stores answers that were already computed.

    Example after running:

    {
    2: 1,
    3: 2,
    4: 3,
    5: 5
    }

    2. A Fibonacci function

    When asked for a value:

    • If it’s 0 or 1, return immediately.
    • If it already exists in the cache, use the saved answer.
    • Otherwise, calculate it, store it, and return it.

    Why It’s Faster

    The recursive version can explode into thousands or millions of repeated calls.

    The memoized version calculates each Fibonacci number once.

    That turns a slow problem into a fast one.

    Real Lesson Behind This Example

    This is not really about Fibonacci.

    It teaches an important programming principle:

    If a problem repeats the same work, store results and reuse them.

    This idea appears everywhere:

    • Dynamic programming
    • Web caching
    • Database query optimization
    • API response caching
    • Machine learning pipelines

    Final Thought

    Sometimes the smartest code is not code that does more work. It is code that avoids doing the same work twice.

    That small cache: {} line transforms a beginner exercise into a lesson in efficient thinking.

  • Senior Java Full Stack Developer (+Javascript/Typescript)

    Senior software developers collaborate with business and quality analysts, designers, project managers and more to design software solutions that will create meaningful change for our clients. They listen thoughtfully to understand the context of a business problem and write clean and iterative code to deliver a powerful end result whilst consistently advocating for better engineering practices. By balancing strong opinions with a willingness to find the right answer, senior software developers bring integrity to technology, ensuring all voices are heard. 

    For a team to thrive, it needs collaboration and room for healthy, respectful debate. Senior developers are the technologists who cultivate this environment while driving teams toward delivering on an aspirational tech vision and acting as mentors for more junior-level consultants. You will leverage deep technical knowledge to solve complex business problems and proactively assess your team’s health, code quality and nonfunctional requirements.

    • You will learn and adopt best practices like writing clean and reusable code using TDD, pair programming and design patterns.
    • You will use and advocate for continuous delivery practices to deliver high-quality software as well as value to end customers as early as possible.
    • You will drive the AI-first software delivery strategy by strategically integrating and utilizing AI tools throughout the development lifecycle to enhance productivity, ensure high-quality code and create capacity for more complex and creative problem-solving.
    • You will work in collaborative, value-driven teams to build innovative customer experiences for our clients.
    • You will create large-scale distributed systems out of microservices.
    • You will collaborate with a variety of teammates to build features, design concepts and interactive prototypes and ensure best practices and UX specifications are embedded along the way.
    • You will efficiently utilize DevSecOps tools and practices to build and deploy software, advocating devops culture and shifting security left in development.
    • You will oversee or take part in the entire cycle of software consulting and delivery from ideation to deployment and everything in between.
    • You will act as a mentor for less-experienced peers through both your technical knowledge and leadership skills. 

    This means more than just years of experience. It usually implies the person can:

    • Own features or projects end-to-end
    • Make technical decisions independently
    • Mentor junior developers
    • Review code and improve team standards
    • Debug complex production issues
    • Balance speed, quality, and scalability
    • Communicate with product managers, designers, and stakeholders

    Java

    This refers mainly to backend development using Java. Typical responsibilities include:

    • Building APIs and microservices
    • Business logic implementation
    • Integrating databases
    • Security and authentication
    • Performance tuning
    • Working with frameworks like Spring / Spring Boot

    Full Stack

    This means they work on both:

    Backend

    Server-side systems, databases, APIs, cloud infrastructure

    Frontend

    User-facing interfaces in the browser

    + JavaScript / TypeScript

    This means they are also strong in frontend technologies like:

    • JavaScript for interactive web apps
    • TypeScript for safer, scalable codebases
    • Modern frameworks such as React, Angular, Vue

    What they usually do day-to-day

    A Senior Java Full Stack Developer may:

    • Build new product features from database to UI
    • Design REST or GraphQL APIs
    • Write frontend components and dashboards
    • Review pull requests
    • Improve architecture and code quality
    • Fix production bugs quickly
    • Help plan sprints and estimate work
    • Mentor teammates

    Common Tech Stack

    Examples often include:

    • Backend: Java, Spring Boot, Hibernate
    • Frontend: JavaScript, TypeScript, React, Angular
    • Database: PostgreSQL, MySQL, MongoDB
    • DevOps: Docker, Kubernetes, CI/CD
    • Cloud: AWS, Azure, GCP

    What companies usually expect

    When hiring for this role, employers often want someone who can:

    • Work independently with minimal supervision
    • Ship production-ready code
    • Understand system design
    • Handle both frontend and backend tasks
    • Lead technical discussions
    • Improve team productivity

  • 10 Terminal Tricks Most Developers Don’t Know


    • Tab Autocompletion
      Let the terminal complete commands, file names, and paths as you type—super fast navigation. (codemag.com)
    • touch [filename] to quickly create empty files
      Great for bootstrapping config or placeholder files. (codeburst, Medium)
    • grep to search within files
      Find specific patterns quickly across files or entire directories; essential for logs or large codebases. (trevorlasn.com, Medium)
    • rm, mv, cp, and common file ops
      Rename (mv), copy (cp), or delete (rm) files/directories—fundamental for filesystem management. (Medium)
    • cd, ls, pwd, mkdir, ps, sudo
      Basic navigational and process commands that every dev uses daily. (Medium)
    • Use && to chain commands
      E.g. npm install && npm test, so the next command only runs if the previous succeeded. (codeburst)
    • pbcopy < file (macOS)
      Copies file contents directly into your clipboard—super handy for SSH keys or code snippets. (codeburst)
    • Split panes in iTerm2 (cmd + d, cmd + shift + d)
      Work across multiple sessions without opening new windows—perfect for multitasking. (codeburst)
    • imgcat to preview images inline in iTerm2
      Handy when working with visual assets directly in terminal. (codeburst)
    • open . (macOS)
      Opens the current directory in Finder, bridging CLI and GUI. (codeburst)

    Summary Table

    TrickWhat It Does
    Ctrl + RReverse search command history
    Tab autocompletionAuto-completes commands/paths
    touch [file]Creates a new empty file
    grep [pattern] [file]Searches text within files
    && operatorChains commands conditionally
    pbcopy < fileCopies file content to clipboard (macOS)
    iTerm2 splits (cmd + d, etc.)Opens multiple panes in one terminal
    imgcatDisplays images inline in terminal (iTerm2)
    open .Opens current folder in GUI (macOS)

    Advanced Terminal & Shell Tricks

    1. Use fzf for interactive fuzzy finding

    Integrate fzf, a fuzzy-finder tool, into your custom scripts—for example, to select Git branches or AWS EC2 instance options interactively. This turns typing long commands into quick, user-friendly selections.bitsand.cloud

    2. Replace heredocs with /dev/stdin

    Instead of traditional heredoc syntax, piping input through /dev/stdin offers a simpler and shell-agnostic way to feed multi-line input—especially useful if you’re not using Bash.bitsand.cloud

    3. SSH multiplexing for faster connections

    Optimize SSH workflows by enabling multiplexing in your ~/.ssh/config. Reusing existing connections avoids repetitive authentication—great if you’re jumping between servers frequently.bitsand.cloud

    4. Quick-access shortcuts in Bash/fish

    • git checkout - to toggle between branches, just like cd - for directories.
    • Retrieve the last argument of a previous command with !$, $_, or Alt + ..
    • Prefix a space before a command to omit it from history.
    • Use pushd and popd to manage directory stacks (or nextd/prevd in fish).
    • Redirect output to protected files using pipes with sudo tee, e.g., command | sudo tee file.bitsand.cloud

    5. Master find, grep, awk, and sed workflows

    • find — locate files by type, size, or modification date:
      find /project -type f -name "*.js" -size +1M -mtime -7Medium
    • grep -E — powerful regex search:
      grep -E "function\s+\w+\s*\(.*\)" file.jsMedium
    • awk — quick analysis:
      awk '/ERROR/ {count++} END {print count}' application.logMedium
    • sed — stream-editing scripts; great for automated transformations.Medium

    6. Leverage Bash parameter expansion & arrays

    Avoid external tools for string manipulation—use built-in expansions instead:

    filename="/path/to/document.pdf"
    name="${filename##*/}"           # document.pdf
    base="${name%.*}"              # document
    extension="${name##*.}"        # pdf
    clean_line="${log_line//[ERROR]/[WARN]}"
    config="${CONFIG_FILE:-/etc/myapp/config.conf}"
    database="${DATABASE_URL:?DATABASE_URL must be set}"
    

    Arrays in Bash (declare -a or declare -A) unlock powerful data handling and cleaner scripts.Medium

    7. Implement AI-powered and modern UI enhancements

    • Use machine learning–enhanced autocompletion via plugins like ml-autocompleter in Oh My Zsh for smarter suggestions.DEV Community
    • Enable multi-cursor editing in Vim to streamline simultaneous edits.DEV Community
    • Try out GPU-accelerated terminals for faster rendering, especially useful for large outputs or visual-heavy workflows.DEV Community

    8. Explore subshells, expansions, and job controls in Bash

    Deepen your shell expertise with:

    • Subshells: use ( … ) to run commands in a separate shell environment.Wikipedia
    • Brace expansion: echo file{1..4}.txt generates file1.txt file2.txt …Wikipedia
    • Process substitution: connect commands with <(...) or >(...)
    • Job control: use &, jobs, fg, bg, and kill to manage parallel tasks.Wikipedia

    Quick Summary Table

    Tip CategoryUse Case
    fzfInteractive selection in scripts and workflows
    /dev/stdinCleaner alternative to heredocs across shells
    SSH multiplexingReusing secure connections without re-authentication
    Bash/fish shortcutsBoost navigation and efficiency with shorthand bindings
    find, grep, awk, sedAdvanced file searching, parsing, and editing
    Parameter expansion & arraysEfficient string handling and data structures in scripts
    ML autocompletion & UISmarter typing assistance and terminal usability
    Shell internals & job controlAdvanced scripting patterns and process management

  • Demystifying DNS: Your Guide to Understanding the Backbone of the Internet

    Introduction

    In a world dominated by the internet, we often take for granted the complex processes that enable us to access websites, send emails, or stream our favorite shows seamlessly. One such critical component of this digital ecosystem is the Domain Name System (DNS). DNS is the unsung hero that translates human-friendly domain names into IP addresses, making it possible for us to access websites and services with ease. In this blog post, we’ll delve into the world of DNS, demystifying its importance and functionality.

    What is DNS?

    DNS, or the Domain Name System, is essentially the internet’s phonebook. Instead of remembering the numerical IP addresses (e.g., 192.168.1.1) that computers use to identify each other, we use domain names (e.g., www.example.com) that are easier for humans to recall. DNS acts as the intermediary that translates these user-friendly domain names into IP addresses, allowing your device to connect to the right server on the internet.

    How Does DNS Work?

    The DNS system works like a hierarchical and distributed database. It involves several key components:

    1. DNS Resolver: When you type a URL (Uniform Resource Locator) into your web browser, a DNS resolver on your device is responsible for converting the domain name (e.g., www.example.com) into an IP address. If it doesn’t have the IP address in its cache, it contacts a DNS server to fetch the information.
    2. DNS Server: DNS servers are distributed worldwide and store massive databases of domain names and their corresponding IP addresses. There are various types of DNS servers, including:
    • Root Servers: These servers are the top level of the DNS hierarchy and provide information about the authoritative DNS servers for top-level domains like .com, .org, and .net.
    • Top-Level Domain (TLD) Servers: These servers maintain information about specific top-level domains (e.g., .com, .org) and direct queries to authoritative name servers for those domains.
    • Authoritative Name Servers: These servers hold the authoritative records for individual domains. When a DNS resolver queries an authoritative name server for a specific domain, it returns the IP address associated with that domain.
    1. Caching: To reduce the load on DNS servers and speed up the process, DNS resolvers often cache DNS records. Cached records can be used for subsequent queries, saving time and bandwidth.

    DNS Resolvers and Public DNS Services

    Most internet service providers (ISPs) provide DNS resolvers for their customers. However, there are also public DNS services like Google DNS (8.8.8.8 and 8.8.4.4) and Cloudflare DNS (1.1.1.1) that you can use for faster and more reliable DNS resolution.

    DNSSEC: Enhancing DNS Security

    The DNS is a fundamental part of the internet’s infrastructure, and it’s essential to ensure its security. DNSSEC (Domain Name System Security Extensions) is a set of extensions to DNS that adds an extra layer of security by digitally signing DNS data. This prevents DNS spoofing and ensures that the DNS records you receive are authentic and haven’t been tampered with.

    Conclusion

    DNS is the unsung hero of the internet, silently working behind the scenes to ensure that you can access websites and services by simply typing in a domain name. Understanding how DNS works can help you appreciate the complexity of the internet’s infrastructure and make informed choices about the DNS resolver you use. So, the next time you browse the web, remember that DNS is the backbone that makes it all possible.