<?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: Naman Vashistha</title>
    <description>The latest articles on DEV Community by Naman Vashistha (@namanvashistha).</description>
    <link>https://dev.to/namanvashistha</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%2F525517%2F7635be3e-aef0-4603-a260-93486fe7f908.jpg</url>
      <title>DEV Community: Naman Vashistha</title>
      <link>https://dev.to/namanvashistha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/namanvashistha"/>
    <language>en</language>
    <item>
      <title>Gardening and the Pace of Things as an Engineer</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 17 Feb 2026 08:00:40 +0000</pubDate>
      <link>https://dev.to/namanvashistha/gardening-and-the-pace-of-things-2faf</link>
      <guid>https://dev.to/namanvashistha/gardening-and-the-pace-of-things-2faf</guid>
      <description>&lt;p&gt;I am a software engineer, so most of my day is in front of a screen. Things respond quickly there. Code compiles or it doesn’t, a message gets a reply, something either works or it breaks. I got used to that without really noticing I had.&lt;/p&gt;

&lt;p&gt;I had always liked the idea of gardening, just never done it. At some point the time and situation felt right and I started. Also wanted to do something that had nothing to do with screens or electronics. Soil, water, sunlight. That was the appeal.&lt;/p&gt;

&lt;p&gt;I water a plant and walk away not knowing if it did anything. The soil looks the same the next morning, the leaves don’t visibly change, and if something is happening it’s somewhere I can’t see. Weeks went by where I couldn’t really tell if I was helping or just showing up.&lt;/p&gt;

&lt;p&gt;Then one morning a leaf had an odd color, slightly yellow at the edges and curling inward. I took a photo and sent it to ChatGPT out of curiosity. It gave me a confident answer. I read it, tried to understand what the plant might need, and moved on. Somewhere along the way I realized I had started paying more attention to the plant itself rather than looking for someone to tell me what was wrong with it.&lt;/p&gt;

&lt;p&gt;The basics turned out to be most of it. Good soil, mostly. Something to hold moisture, something to let it drain, something to feed the roots. Soil, cocopeat &amp;amp; compost. The balance matters more than the ingredients. And water only when the soil asks for it, not before.&lt;/p&gt;

&lt;p&gt;One plant died and I still don’t know why. By the time something was clearly wrong it was already too late. There was no obvious moment I could point to.&lt;/p&gt;

&lt;p&gt;The others came up slowly. Quietly, in their own order, at their own pace. It was nice to watch.&lt;/p&gt;

&lt;p&gt;Some plants have looked exactly the same for weeks now. Same height, same leaves, no visible change. I notice it, but it doesn’t pull at me the way it used to. I water, I check the soil, I watch. Most mornings that’s enough.&lt;/p&gt;

</description>
      <category>gardening</category>
      <category>reflection</category>
      <category>patience</category>
      <category>software</category>
    </item>
    <item>
      <title>Automating LimeDB LXC Container Deployment on Proxmox</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Fri, 21 Nov 2025 17:08:29 +0000</pubDate>
      <link>https://dev.to/namanvashistha/automating-limedb-lxc-container-deployment-on-proxmox-905</link>
      <guid>https://dev.to/namanvashistha/automating-limedb-lxc-container-deployment-on-proxmox-905</guid>
      <description>&lt;p&gt;Github: &lt;a href="https://github.com/namanvashistha/limedb/commit/8fe072ece279b6678243716f1f659e159da48c0c" rel="noopener noreferrer"&gt;namanvashistha/limedb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This commit introduces a new bash script, &lt;code&gt;proxmox/limedb_lxc.sh&lt;/code&gt;, designed to automate the provisioning and setup of a LimeDB instance within an LXC container on a Proxmox VE host.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Changed
&lt;/h3&gt;

&lt;p&gt;A new executable bash script (&lt;code&gt;limedb_lxc.sh&lt;/code&gt;) has been added to the repository's &lt;code&gt;proxmox/&lt;/code&gt; directory. This script provides a single-command solution for deploying a fully functional LimeDB server in a containerized environment on Proxmox.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the Change Was Needed
&lt;/h3&gt;

&lt;p&gt;Deploying a distributed key-value store like LimeDB often involves repetitive setup steps, especially when provisioning multiple instances for a cluster or for development/testing environments. Manually creating LXC containers, configuring their resources, installing dependencies, downloading and setting up LimeDB, and configuring its systemd service can be time-consuming and prone to human error. This script aims to reduce operational overhead, ensure consistency across deployments, and lower the barrier for users to quickly get LimeDB running on Proxmox.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design Choices Made
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Proxmox &lt;code&gt;pct&lt;/code&gt; Utility:&lt;/strong&gt; The script heavily relies on the &lt;code&gt;pct&lt;/code&gt; command-line interface provided by Proxmox for all container management operations, including creation, starting, and executing commands within the container.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Unprivileged LXC:&lt;/strong&gt; It creates an unprivileged container by default (&lt;code&gt;--unprivileged 1&lt;/code&gt;), which is a security best practice as it isolates the container processes more effectively from the host kernel.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Debian 12 Base:&lt;/strong&gt; A Debian 12 standard template (&lt;code&gt;debian-12-standard_12.2-1_amd64.tar.zst&lt;/code&gt;) is chosen as the default operating system for the container, offering a stable and widely-used base.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Resource Configuration:&lt;/strong&gt; Default parameters for CPU cores (&lt;code&gt;1&lt;/code&gt;), RAM (&lt;code&gt;512MB&lt;/code&gt;), swap (&lt;code&gt;512MB&lt;/code&gt;), and disk size (&lt;code&gt;2GB&lt;/code&gt;) are set, providing a lightweight yet functional setup suitable for initial deployments or development.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;DHCP Networking:&lt;/strong&gt; The container's network is configured to use DHCP on &lt;code&gt;vmbr0&lt;/code&gt;, simplifying network setup in most standard Proxmox environments.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Nesting Support:&lt;/strong&gt; The &lt;code&gt;--features nesting=1&lt;/code&gt; flag is included, which can be beneficial for running certain nested virtualization or containerization technologies within the LXC, though not strictly required for LimeDB itself.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Binary Installation:&lt;/strong&gt; LimeDB is installed by directly downloading a pre-compiled binary from its GitHub releases (&lt;code&gt;v0.0.2&lt;/code&gt;) into &lt;code&gt;/usr/local/bin&lt;/code&gt; inside the container. This avoids the need for a full build environment within the LXC.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Systemd Service Management:&lt;/strong&gt; A &lt;code&gt;systemd&lt;/code&gt; unit file (&lt;code&gt;limedb.service&lt;/code&gt;) is dynamically created and enabled within the container. This ensures LimeDB starts automatically on boot and is managed robustly by the system's init system.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Basic Error Handling and Feedback:&lt;/strong&gt; The script includes functions for informative messages, success indicators, and error reporting, with checks for root execution and successful container creation.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Trade-offs and Constraints
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Proxmox-Specific:&lt;/strong&gt; The script is tightly coupled to the Proxmox VE environment and cannot be used for deploying LimeDB on other virtualization platforms without significant modifications.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Default Parameters:&lt;/strong&gt; It uses hardcoded default values for container ID (&lt;code&gt;105&lt;/code&gt;), password, storage pool (&lt;code&gt;local-lvm&lt;/code&gt;), and OS template. Users need to ensure these defaults are appropriate for their specific Proxmox setup or modify the script variables directly.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Root Privileges:&lt;/strong&gt; The script itself must be run as root on the Proxmox host. Commands executed within the container (e.g., &lt;code&gt;apt-get&lt;/code&gt;, &lt;code&gt;wget&lt;/code&gt;, &lt;code&gt;systemctl&lt;/code&gt;) are also run as the root user.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Network Assumptions:&lt;/strong&gt; It assumes the presence of a network bridge named &lt;code&gt;vmbr0&lt;/code&gt; and a DHCP server on that network. Static IP configuration is not an option within the current script implementation.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;External Dependency:&lt;/strong&gt; The LimeDB binary is fetched directly from GitHub releases. This implies a dependency on GitHub's availability and the persistence of the specific release version.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Limited Customization:&lt;/strong&gt; While essential parameters are configured, more advanced LXC settings (e.g., CPU limits, IOPS limits, specific static IP addresses, custom bind mounts) are not exposed for easy modification.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Security Post-Setup:&lt;/strong&gt; The use of a default container password and root installation inside the container means that for production deployments, additional security hardening (e.g., changing passwords, creating dedicated unprivileged users for LimeDB) would be necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Future Implications
&lt;/h3&gt;

&lt;p&gt;This script serves as a foundational automation tool for LimeDB on Proxmox. It significantly simplifies the initial deployment phase, making it easier for users to experiment with, test, and potentially scale LimeDB instances. Future enhancements could include making more parameters configurable via command-line arguments, supporting different OS templates, enabling static IP configuration, or integrating with configuration management systems for more advanced fleet management.&lt;/p&gt;

</description>
      <category>limedb</category>
      <category>proxmox</category>
      <category>lxc</category>
      <category>automation</category>
    </item>
    <item>
      <title>LimeDB: Architectural Shift to a Go-based Distributed Key-Value Store with Consistent Hashing</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Fri, 21 Nov 2025 15:18:21 +0000</pubDate>
      <link>https://dev.to/namanvashistha/limedb-architectural-shift-to-a-go-based-distributed-key-value-store-with-consistent-hashing-367i</link>
      <guid>https://dev.to/namanvashistha/limedb-architectural-shift-to-a-go-based-distributed-key-value-store-with-consistent-hashing-367i</guid>
      <description>&lt;p&gt;Github: &lt;a href="https://github.com/namanvashistha/limedb/commit/4dbdf30cc35b8884f47987ea15d8fa98d8360a4f" rel="noopener noreferrer"&gt;namanvashistha/limedb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This commit marks a pivotal architectural change for LimeDB, transitioning its core distributed key-value store implementation from a Java/Spring Boot foundation managed by Docker Compose to a new Go-based system. This complete rewrite focuses on performance, efficiency, and a streamlined deployment model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed
&lt;/h2&gt;

&lt;p&gt;TheThe primary change is the introduction of a complete Go implementation of LimeDB's distributed key-value store. This necessitated the removal of all previous Java-related Docker infrastructure, including &lt;code&gt;.dockerignore&lt;/code&gt;, &lt;code&gt;DOCKER.md&lt;/code&gt;, &lt;code&gt;docker-compose.yml&lt;/code&gt;, and &lt;code&gt;docker-compose.prod.yml&lt;/code&gt;. A &lt;code&gt;.gitignore&lt;/code&gt; update also reflects a new development environment preference.&lt;/p&gt;

&lt;p&gt;The new Go codebase introduces several key components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;cmd/server/main.go&lt;/code&gt;&lt;/strong&gt;: The application's entry point, responsible for loading configuration, initializing services, starting the HTTP server, and managing graceful shutdown.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;internal/config&lt;/code&gt;&lt;/strong&gt;: A package for parsing command-line arguments to configure node-specific parameters such as &lt;code&gt;NodeID&lt;/code&gt;, &lt;code&gt;ServerPort&lt;/code&gt;, a list of &lt;code&gt;Peers&lt;/code&gt;, and the number of &lt;code&gt;VirtualNodes&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;internal/server&lt;/code&gt;&lt;/strong&gt;: Implements the HTTP server using &lt;code&gt;github.com/valyala/fasthttp&lt;/code&gt;. It defines API endpoints for &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;SET&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt; operations, as well as cluster and ring state monitoring (&lt;code&gt;/api/v1/cluster/state&lt;/code&gt;, &lt;code&gt;/api/v1/cluster/ring&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;internal/node&lt;/code&gt;&lt;/strong&gt;: Contains the &lt;code&gt;NodeService&lt;/code&gt; which orchestrates key-value operations. It manages an in-memory &lt;code&gt;Store&lt;/code&gt; (based on &lt;code&gt;sync.Map&lt;/code&gt;) for local data and routes requests to the appropriate node using consistent hashing, forwarding them via an &lt;code&gt;fasthttp.Client&lt;/code&gt; if the key belongs to a remote peer.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;internal/ring&lt;/code&gt;&lt;/strong&gt;: This package provides the &lt;code&gt;ConsistentHashRing&lt;/code&gt; implementation, which uses MD5 hashing to map keys to &lt;code&gt;int64&lt;/code&gt; values on the ring. It supports adding and removing physical nodes, each represented by a configurable number of virtual nodes, and efficiently determines the responsible node for a given key.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;go.mod&lt;/code&gt; and &lt;code&gt;go.sum&lt;/code&gt;&lt;/strong&gt;: These files define the Go module &lt;code&gt;limedb-go&lt;/code&gt; and its dependencies, primarily &lt;code&gt;fasthttp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;run_go_cluster.sh&lt;/code&gt;&lt;/strong&gt;: A shell script facilitating the local setup and execution of a multi-node Go LimeDB cluster, automatically generating the peer list.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;scripts/bulk_set.py&lt;/code&gt;&lt;/strong&gt;: The Python testing script was updated to support a higher number of nodes (up to 50) and increased concurrent key operations, reflecting the expected scalability improvements of the Go implementation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why the Change was Needed
&lt;/h2&gt;

&lt;p&gt;The transition from Java/Spring Boot to Go was driven by the pursuit of higher performance, reduced resource consumption, and improved concurrency characteristics. Go's design, with its lightweight goroutines and efficient memory management, offers significant advantages for building high-throughput distributed systems like LimeDB. The aim is to achieve lower latency and higher request per second (RPS) metrics compared to the previous Java-based setup, while also simplifying the deployment footprint by moving to a single-binary model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Choices Made
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Go Language Adoption&lt;/strong&gt;: The primary decision was to rewrite the system in Go. This choice aligns with the project's goal of being a &lt;em&gt;lightweight, fast, open-source distributed key-value store for high-performance systems&lt;/em&gt;. Go's built-in concurrency model and performance profile are well-suited for this.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;fasthttp&lt;/code&gt; for HTTP Communication&lt;/strong&gt;: &lt;code&gt;github.com/valyala/fasthttp&lt;/code&gt; was selected over Go's standard &lt;code&gt;net/http&lt;/code&gt; package for its optimized performance. In a key-value store where network I/O and request handling throughput are critical, &lt;code&gt;fasthttp&lt;/code&gt; provides a more performant foundation for inter-node communication and client APIs.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Consistent Hashing with Virtual Nodes&lt;/strong&gt;: The &lt;code&gt;ConsistentHashRing&lt;/code&gt; implementation is central to the distributed nature of LimeDB. By employing consistent hashing and distributing virtual nodes across physical nodes, the system achieves even data distribution, minimizes data movement during node additions/removals, and enhances fault tolerance. MD5 hashing to &lt;code&gt;int64&lt;/code&gt; provides a consistent mapping to the hash space.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;In-Memory &lt;code&gt;sync.Map&lt;/code&gt; Storage&lt;/strong&gt;: For the initial phase of this rewrite, an in-memory &lt;code&gt;sync.Map&lt;/code&gt; was chosen for local key-value storage. This provides a simple, thread-safe, and highly performant local store, allowing the development focus to remain on the distributed routing and consistent hashing logic.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Command-Line Configuration&lt;/strong&gt;: Node configuration is managed via command-line flags. This provides a transparent and explicit way to bootstrap and configure individual nodes, particularly useful in development and for static cluster deployments.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Direct Request Forwarding&lt;/strong&gt;: When a request targets a key not owned by the current node, the &lt;code&gt;NodeService&lt;/code&gt; directly forwards the HTTP request to the responsible peer. This keeps the routing logic within the application layer, leveraging the consistent hash ring.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Trade-offs and Constraints
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Persistence (Current Constraint)&lt;/strong&gt;: The current &lt;code&gt;internal/node/store&lt;/code&gt; is an in-memory implementation, meaning data is not durable across restarts. This is a deliberate simplification for the initial Go rewrite phase, prioritizing the core distributed logic. For production readiness, a persistent storage layer will be required (the previous Java version used PostgreSQL, highlighting this need).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Static Peer Configuration&lt;/strong&gt;: The &lt;code&gt;node.peers&lt;/code&gt; list is currently static and defined at startup. This approach lacks dynamic cluster membership capabilities, meaning manual intervention is required to update peer lists when nodes join or leave the cluster. This could be a scalability bottleneck in highly elastic environments.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;fasthttp&lt;/code&gt; Ecosystem&lt;/strong&gt;: While fast, &lt;code&gt;fasthttp&lt;/code&gt; has a smaller ecosystem of middleware and integrations compared to the standard &lt;code&gt;net/http&lt;/code&gt; package. This is an accepted trade-off for the performance gains it provides in a specialized service.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Basic API Routing&lt;/strong&gt;: The server's &lt;code&gt;router&lt;/code&gt; uses a basic &lt;code&gt;switch&lt;/code&gt; statement for URL matching. While functional, it could evolve into a more robust routing framework as the API surface grows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Future Implications
&lt;/h2&gt;

&lt;p&gt;This Go-based rewrite provides a strong, high-performance foundation for LimeDB. Future development efforts will likely focus on enhancing its capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Durable Storage&lt;/strong&gt;: Implementing a persistent storage layer (e.g., integrating with a local embedded key-value store like BadgerDB or RocksDB, or a custom log-structured approach) to ensure data durability.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Replication and Consistency&lt;/strong&gt;: Introducing robust data replication strategies (e.g., N-way replication, quorum reads/writes) to ensure high availability and strong consistency guarantees.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Dynamic Cluster Membership and Discovery&lt;/strong&gt;: Developing mechanisms for nodes to dynamically discover each other, join/leave the cluster, and handle failures gracefully (e.g., using a gossip protocol or integrating with a service discovery system like Consul or etcd).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Load Balancing and Client-Side Hashing&lt;/strong&gt;: Exploring options for smarter client-side load balancing or direct client integration with the consistent hashing ring to minimize request forwarding overhead.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Advanced Observability&lt;/strong&gt;: Expanding metrics, logging, and tracing capabilities for better monitoring and debugging in production environments.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>distributedsystems</category>
      <category>go</category>
      <category>database</category>
    </item>
    <item>
      <title>Why I'm Building My Own Distributed Database</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Sat, 11 Oct 2025 21:09:44 +0000</pubDate>
      <link>https://dev.to/namanvashistha/why-im-building-my-own-distributed-database-3lj</link>
      <guid>https://dev.to/namanvashistha/why-im-building-my-own-distributed-database-3lj</guid>
      <description>&lt;p&gt;As a backend developer, I've worked with Redis, PostgreSQL, MongoDB, and countless other databases. But I always felt like there was something missing – a deeper understanding of how these systems actually work under the hood. So I decided to embark on a journey to build my own distributed key-value database from scratch.&lt;/p&gt;

&lt;p&gt;Meet &lt;strong&gt;LimeDB&lt;/strong&gt; – a distributed key-value store I'm currently building with Java 21 and Spring Boot. My goal is to create a truly custom database system that starts with PostgreSQL as a foundation but evolves into something much more ambitious, all wrapped in a horizontally scalable coordinator-shard architecture.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/namanvashistha/limedb" rel="noopener noreferrer"&gt;namanvashistha/limedb&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Why Build Another Database?
&lt;/h2&gt;

&lt;p&gt;You might be thinking: "Why reinvent the wheel? Redis and PostgreSQL already exist!" And you're absolutely right. But here's the thing – as backend developers, we often treat databases as black boxes. We know &lt;em&gt;how&lt;/em&gt; to use them, but not &lt;em&gt;how&lt;/em&gt; they work.&lt;/p&gt;

&lt;p&gt;Building LimeDB is already teaching me more about distributed systems, consistency, partitioning, and database internals than years of just using existing solutions. It's like the difference between driving a car and understanding how the engine works.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 The Learning Goals
&lt;/h2&gt;

&lt;p&gt;When I started this project, I had several learning objectives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Understand Distributed System Patterns&lt;/strong&gt; - How do you route requests across multiple nodes?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grasp Database Internals&lt;/strong&gt; - What happens when you store and retrieve data?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learn About Horizontal Scaling&lt;/strong&gt; - How do systems like Redis Cluster actually work?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Master Modern Java&lt;/strong&gt; - Put Java 21 features and Spring Boot to real use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build Something Production-Adjacent&lt;/strong&gt; - Not just a toy, but something that could theoretically scale&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🏗️ Architecture Decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Coordinator-Shard Pattern
&lt;/h3&gt;

&lt;p&gt;Instead of a peer-to-peer system (like Cassandra) or a single-node system (like Redis), I chose a coordinator-shard architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client → Coordinator → Shard 1, 2, 3...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this pattern?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity&lt;/strong&gt;: Clients only need to know about one endpoint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing Logic&lt;/strong&gt;: Centralized decision-making about where data lives&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational Ease&lt;/strong&gt;: Easy to monitor and debug&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Familiar&lt;/strong&gt;: Similar to how many real systems work (think MongoDB's router)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hash-Based Routing (For Now)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simple but effective&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;shardIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;abs&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hashCode&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;numberOfShards&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is deliberately simple. I know consistent hashing is "better" for rebalancing, but I wanted to start with something I could fully understand and implement correctly. You can see this decision in the &lt;code&gt;ShardRegistryService&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getShardByKey&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;key&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;abs&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hashCode&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;shards&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;shards&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&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;p&gt;Perfect? No. Educational? Absolutely.&lt;/p&gt;

&lt;h3&gt;
  
  
  PostgreSQL as a Starting Point
&lt;/h3&gt;

&lt;p&gt;Each shard currently uses its own PostgreSQL database (&lt;code&gt;limedb_shard_1&lt;/code&gt;, &lt;code&gt;limedb_shard_2&lt;/code&gt;, etc.). But here's the key - PostgreSQL is just my &lt;strong&gt;Phase 1&lt;/strong&gt; storage engine, not the final destination.&lt;/p&gt;

&lt;p&gt;Why start with PostgreSQL?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quick Validation&lt;/strong&gt;: Get the distributed architecture working first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACID Guarantees&lt;/strong&gt;: Data survives restarts while I focus on routing logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Familiar Tooling&lt;/strong&gt;: Easy to inspect and debug during development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stepping Stone&lt;/strong&gt;: Proven foundation before building custom storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The plan is to eventually replace PostgreSQL with custom storage engines optimized for key-value workloads. Think LSM trees, custom file formats, and memory-mapped storage - but PostgreSQL lets me focus on the distributed systems challenges first.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 What I'm Learning Building This
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Distributed Systems Are Hard&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Even with this simple architecture, I'm already running into fascinating problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens when a shard goes down?&lt;/li&gt;
&lt;li&gt;How do you handle network timeouts?&lt;/li&gt;
&lt;li&gt;What about data consistency across shards?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't academic questions anymore – they're real problems I need to solve as I build this system.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;The Power of Good Abstractions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The Spring Boot framework is letting me focus on the distributed systems logic rather than HTTP parsing and dependency injection. My controllers are staying clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/get/{key}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;)&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;routingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;build&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;h3&gt;
  
  
  3. &lt;strong&gt;Testing Distributed Systems is Different&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can't just unit test individual methods. You need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start multiple services&lt;/li&gt;
&lt;li&gt;Test network failures&lt;/li&gt;
&lt;li&gt;Verify data consistency&lt;/li&gt;
&lt;li&gt;Check routing logic
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_values&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1_000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;key_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8080/api/v1/set&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. &lt;strong&gt;Configuration Management is Crucial&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With multiple nodes, configuration becomes complex. Each shard needs to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which database to connect to&lt;/li&gt;
&lt;li&gt;What port to run on&lt;/li&gt;
&lt;li&gt;Its shard ID
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew bootRun &lt;span class="nt"&gt;--args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'--node.type=shard --server.port=7001 --shard.id=1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 Current Progress
&lt;/h2&gt;

&lt;p&gt;LimeDB currently supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ GET/SET/DELETE operations (Redis-like API)&lt;/li&gt;
&lt;li&gt;✅ Hash-based routing across 3 shards&lt;/li&gt;
&lt;li&gt;✅ PostgreSQL persistence per shard&lt;/li&gt;
&lt;li&gt;✅ REST API with proper error handling&lt;/li&gt;
&lt;li&gt;✅ Health monitoring endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Performance? It's not going to beat Redis. But it's already handling operations smoothly and teaching me &lt;em&gt;why&lt;/em&gt; Redis is so fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 What's Next?
&lt;/h2&gt;

&lt;p&gt;The roadmap is ambitious and includes features I'm excited to tackle:&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: Better Distribution
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistent Hashing&lt;/strong&gt;: Replace modulo with a proper hash ring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health Checks&lt;/strong&gt;: Automatic failover when shards go down&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replication&lt;/strong&gt;: Primary-replica setup for high availability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics&lt;/strong&gt;: Monitoring and observability&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 3: Custom Storage Engine
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LSM Trees&lt;/strong&gt;: Replace PostgreSQL with custom key-value storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory-Mapped Files&lt;/strong&gt;: Direct file system control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Serialization&lt;/strong&gt;: Optimized data formats&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WAL Implementation&lt;/strong&gt;: Write-ahead logging from scratch&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 4: Advanced Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom Binary Protocol&lt;/strong&gt;: Move beyond HTTP/REST&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compression&lt;/strong&gt;: Custom compression algorithms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache Layers&lt;/strong&gt;: Multi-level caching strategies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction Support&lt;/strong&gt;: ACID across multiple shards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each phase represents deeper database internals knowledge - PostgreSQL is just the beginning!&lt;/p&gt;

&lt;h2&gt;
  
  
  💭 Why You Should Build One Too
&lt;/h2&gt;

&lt;p&gt;Building your own database isn't about competing with PostgreSQL or Redis. It's about:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deep Learning&lt;/strong&gt;: Understanding systems from the ground up&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interview Prep&lt;/strong&gt;: Nothing impresses like saying "I built a distributed database"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problem-Solving Skills&lt;/strong&gt;: Real distributed systems problems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technology Mastery&lt;/strong&gt;: Push your programming language skills&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio Project&lt;/strong&gt;: Something unique that stands out&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🛠️ Getting Started
&lt;/h2&gt;

&lt;p&gt;If this inspired you to build your own database, here's my advice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start Simple&lt;/strong&gt;: Don't try to build Redis on day one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pick Your Language&lt;/strong&gt;: Use something you're comfortable with&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose One Feature&lt;/strong&gt;: GET/SET is enough to start&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add Gradually&lt;/strong&gt;: Persistence, then distribution, then optimizations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document Everything&lt;/strong&gt;: Future you will thank you&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🔗 Follow the Journey
&lt;/h2&gt;

&lt;p&gt;Want to see the code as I build it? It's all open source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/namanvashistha/limedb" rel="noopener noreferrer"&gt;namanvashistha/limedb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tech Stack&lt;/strong&gt;: Java 21, Spring Boot, PostgreSQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Current Status&lt;/strong&gt;: Basic coordinator-shard architecture working&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The README has setup instructions, and I'm trying to make the code as readable as possible for learning purposes. Feel free to star the repo and follow along as I tackle more distributed systems challenges!&lt;/p&gt;

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

&lt;p&gt;Building LimeDB is turning out to be one of the most educational projects I've undertaken as a backend developer. It's not going to be the fastest database, or the most feature-complete, but it's &lt;em&gt;mine&lt;/em&gt;. I understand every line of code, every architectural decision, and every trade-off I'm making along the way.&lt;/p&gt;

&lt;p&gt;In a world of microservices and cloud abstractions, there's something deeply satisfying about building a system from first principles. I'm already looking at Redis, PostgreSQL, and MongoDB differently after just starting this journey.&lt;/p&gt;

&lt;p&gt;So grab your favourite programming language, pick a simple data structure, and start building. The distributed systems knowledge you'll gain is worth its weight in gold.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What do you think? Have you ever built your own database or distributed system? What did you learn? Drop a comment below!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>distributedsystems</category>
      <category>java</category>
      <category>springboot</category>
    </item>
    <item>
      <title>What No One Tells You About Being a Mid-Level Developer</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 22 Apr 2025 21:42:04 +0000</pubDate>
      <link>https://dev.to/namanvashistha/what-no-one-tells-you-about-being-a-mid-level-developer-28ji</link>
      <guid>https://dev.to/namanvashistha/what-no-one-tells-you-about-being-a-mid-level-developer-28ji</guid>
      <description>&lt;p&gt;Let’s talk about what it actually feels like to be a mid-level dev—the quiet confusion, the shifting expectations, and the slow realization that growth isn’t always about writing better code.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. You’re not a beginner anymore—but you still feel like one sometimes
&lt;/h3&gt;

&lt;p&gt;You know how to ship features. You’ve debugged scary bugs. You’ve even explained things to newer devs and realized, &lt;em&gt;“Wait, I do know this!”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But then, you’ll get thrown into something new—some legacy codebase, some architectural decision—and you’ll freeze. That little voice comes back: &lt;em&gt;“Shouldn’t I already know this by now?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You’re not alone. Mid-level is where imposter syndrome doesn’t vanish—it just mutates.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. People start expecting &lt;em&gt;more&lt;/em&gt;, but don’t always tell you what that is
&lt;/h3&gt;

&lt;p&gt;You’re suddenly in charge of things like “code quality,” “project ownership,” and sometimes even “mentoring.” But no one tells you what those things actually &lt;em&gt;look like&lt;/em&gt; day-to-day.&lt;/p&gt;

&lt;p&gt;You find yourself in meetings, nodding along, Googling acronyms under the table. Half the skill lies in confidently navigating new challenges as you figure things out on the fly.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. You have more influence than you think
&lt;/h3&gt;

&lt;p&gt;You might not be leading teams, but your suggestions matter. Your pull requests shape patterns. Your way of solving problems gets copied.&lt;/p&gt;

&lt;p&gt;And when a junior dev asks you for help, you suddenly see how much you've learned. That moment when you explain a concept and they go “Ohh!”—yeah, that’s a quiet promotion right there.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. You start realizing that growth isn’t just about code
&lt;/h3&gt;

&lt;p&gt;It’s about communication. It’s about trade-offs. It’s about choosing boring solutions when they’re the right ones.&lt;/p&gt;

&lt;p&gt;It’s learning when to speak up in a design review—and when to just listen. It’s understanding the business impact of your work, not just its technical elegance.&lt;/p&gt;

&lt;p&gt;The things that &lt;em&gt;don’t&lt;/em&gt; go in your resume? They matter a lot more now.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. It’s okay to not feel “ready” yet
&lt;/h3&gt;

&lt;p&gt;Here’s the truth: no one fully knows what they’re doing. The difference at this level is that you’re getting better at handling uncertainty. Better at asking for clarity. Better at shipping &lt;em&gt;anyway&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Being mid-level isn’t a stop on the way to senior. It’s a whole stage of its own—messy, confusing, but also really rewarding.&lt;/p&gt;

&lt;p&gt;And if you’re here? You’re doing just fine.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/namanvashistha" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2F2znn4km0i2jib7ru1sm9.png" alt="" width="170" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Imposter Syndrome in Software Engineering – You're Not Alone</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 22 Apr 2025 21:10:32 +0000</pubDate>
      <link>https://dev.to/namanvashistha/title-imposter-syndrome-in-software-engineering-youre-not-alone-3a4g</link>
      <guid>https://dev.to/namanvashistha/title-imposter-syndrome-in-software-engineering-youre-not-alone-3a4g</guid>
      <description>&lt;p&gt;I remember staring at my screen after deploying a bug fix, thinking, &lt;em&gt;"Someone’s going to find out I have no idea what I’m doing."&lt;/em&gt; It didn’t matter that I’d been writing production code for years. That little voice—the one that says you’re not good enough—never really goes away.&lt;/p&gt;

&lt;p&gt;Imposter syndrome is weird like that. It doesn’t care about your experience, your contributions, or your title. It creeps in when you're debugging a weird issue, sitting in a meeting with sharp teammates, or reading code that just seems way too elegant for you to have written.&lt;/p&gt;

&lt;h3&gt;
  
  
  What We'll Talk About:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;What imposter syndrome feels like in our field&lt;/li&gt;
&lt;li&gt;Why it's especially common among developers&lt;/li&gt;
&lt;li&gt;Some mindset shifts and coping strategies that actually helped&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why This Matters
&lt;/h3&gt;

&lt;p&gt;You’re not broken. You’re not alone. And most importantly, you don’t need to "fix" yourself to belong here.&lt;/p&gt;




&lt;p&gt;Let’s start with the obvious: this job is hard. Not just technically, but emotionally.&lt;/p&gt;

&lt;p&gt;You're expected to learn constantly, work with code that was written in a rush (also by you), and make decisions with incomplete information. And when things break—because they &lt;em&gt;will&lt;/em&gt; break—you feel like the world is watching. Even if it’s just you.&lt;/p&gt;

&lt;p&gt;And the weirdest part? Nobody talks about it enough.&lt;/p&gt;




&lt;h3&gt;
  
  
  What Imposter Syndrome Feels Like in Our Field
&lt;/h3&gt;

&lt;p&gt;Imposter syndrome for developers often isn’t loud. It’s quiet. It whispers things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“You don’t actually &lt;em&gt;understand&lt;/em&gt; this pattern, you just copied it from ChatGPT/StackOverflow.”&lt;/li&gt;
&lt;li&gt;“They think you’re good because you got lucky with that last project.”&lt;/li&gt;
&lt;li&gt;“You should know this by now. Why don’t you?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It can hit during a code review, or while pairing with someone who types faster than you think. And worst of all—it often hits &lt;em&gt;after&lt;/em&gt; success. After a promotion. After a session. As if your wins are just accidents.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why It's So Common Among Developers
&lt;/h3&gt;

&lt;p&gt;A few reasons, at least in my experience:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Software moves fast.&lt;/strong&gt; There’s always a new framework, a new best practice, or some new tech everyone suddenly knows but you haven’t touched yet. It feels like running a race where the finish line keeps moving.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;We normalize struggle... in private.&lt;/strong&gt; Everyone’s debugging in silence, but we only see the wins. We don’t see how long it took someone to write that “clean” code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;We compare the worst of ourselves to the best of others.&lt;/strong&gt; You see someone’s elegant GitHub project and think &lt;em&gt;“I could never build that,”&lt;/em&gt; while ignoring the 40 tabs you have open just to write one function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;There’s a myth of the “10x engineer.”&lt;/strong&gt; And if you're not pushing PRs, writing blog posts, building side projects, and contributing to open source, it’s easy to feel like you're falling behind. (Spoiler: you're not.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Mindset Shifts That Helped Me
&lt;/h3&gt;

&lt;p&gt;I’m someone who deals with this regularly. But I’ve found a few things that make those voices a little quieter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Track what you’ve learned.&lt;/strong&gt; Sometimes I just remind myself of small wins—like finally figuring out why a bug happened or learning a new Git command. It doesn’t have to be a big deal. Even remembering those little moments helps me see that I’m making progress.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ask questions—even when it’s scary.&lt;/strong&gt; I used to think asking made me look dumb. Now I realize it shows I'm invested and curious. And more often than not, the senior dev I was afraid to ask says, “Oh, good question.”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Surround yourself with honest devs.&lt;/strong&gt; People who admit when they’re stuck. People who say “I don’t know” without shame. That’s the culture I want to be part of—and it makes a huge difference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stop aiming for perfect. Aim for progress.&lt;/strong&gt; Perfectionism and imposter syndrome are best friends. So now, I try to focus on moving forward—even if it’s a little messy.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  You’re Not Broken
&lt;/h3&gt;

&lt;p&gt;If you’ve ever felt like you don’t fully belong, that doesn’t make you weak. It makes you &lt;em&gt;human&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Confidence in tech isn’t a permanent state—it’s something you rebuild, over and over. And every time you push through, ask that question, commit that code, or help someone else, you're proving something to yourself:&lt;/p&gt;

&lt;p&gt;You belong here.&lt;/p&gt;

&lt;p&gt;Not because you're perfect. Not because you've mastered every language, every paradigm, or every tool.&lt;/p&gt;

&lt;p&gt;You belong because you're learning. Because you care. And because you're showing up—even on the hard days.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you’re reading this and nodding along, leave a comment or share your story. You’re not alone—and your experience might be exactly what someone else needs to hear.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/namanvashistha" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2F2znn4km0i2jib7ru1sm9.png" alt="" width="170" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building a Fast and Smart Chess Engine Using Bitboards</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 22 Apr 2025 08:51:58 +0000</pubDate>
      <link>https://dev.to/namanvashistha/building-a-fast-and-smart-chess-engine-using-bitboards-4265</link>
      <guid>https://dev.to/namanvashistha/building-a-fast-and-smart-chess-engine-using-bitboards-4265</guid>
      <description>&lt;p&gt;Repository: &lt;a href="https://github.com/namanvashistha/chess" rel="noopener noreferrer"&gt;https://github.com/namanvashistha/chess&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you sit down to play chess online, there’s a brain on the server side that checks whether your moves are legal, prevents cheating, and enforces the rules of the game. That brain is the &lt;strong&gt;chess engine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this post, we’ll walk through how a chess engine is implemented under the hood—specifically one written in &lt;strong&gt;Go&lt;/strong&gt;, backed by the blazing speed of &lt;strong&gt;bitboards&lt;/strong&gt;. Whether you’re building your own chess app or just curious about how engines work, this post dives into the guts of what makes the game tick.&lt;/p&gt;




&lt;h2&gt;
  
  
  ♟️ What Is the Engine Responsible For?
&lt;/h2&gt;

&lt;p&gt;At its core, the engine is the rulebook of chess in code form. It needs to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand how each piece moves&lt;/li&gt;
&lt;li&gt;Enforce all special rules (castling, en passant, promotion)&lt;/li&gt;
&lt;li&gt;Reject illegal moves&lt;/li&gt;
&lt;li&gt;Detect checks, pins, checkmates, and stalemates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s not responsible for &lt;strong&gt;persistence&lt;/strong&gt; (that’s the repository's job), nor for &lt;strong&gt;coordinating services&lt;/strong&gt; (handled by the service layer). The engine lives in its own pure Go package—no external dependencies, just logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ What Happens When You Play a Move?
&lt;/h2&gt;

&lt;p&gt;Let’s say it’s the first move of the game, and White tries &lt;code&gt;e2&lt;/code&gt; to &lt;code&gt;e4&lt;/code&gt;. Here’s what the engine does to validate this move:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check the source square (&lt;code&gt;e2&lt;/code&gt;)&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Is there a White Pawn on it?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check the target square (&lt;code&gt;e4&lt;/code&gt;)&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Is it empty?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pawn-specific rules&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Is this the pawn’s first move? If so, can it move 2 squares?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;King safety&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;After making this move hypothetically, does it leave the King in check?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The engine doesn’t just guess. It checks all these conditions explicitly and systematically.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ Enter Bitboards: The Secret Weapon
&lt;/h2&gt;

&lt;p&gt;We want our engine to be fast—like “respond in milliseconds” fast. That’s where &lt;strong&gt;bitboards&lt;/strong&gt; come in.&lt;/p&gt;

&lt;p&gt;A bitboard is a 64-bit unsigned integer (&lt;code&gt;uint64&lt;/code&gt;). Each bit corresponds to one square on the chess board. A &lt;code&gt;1&lt;/code&gt; means something is true about that square. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bitboard of White Pawns: 1s where pawns are&lt;/li&gt;
&lt;li&gt;Bitboard of all occupied squares: 1s wherever any piece is present&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagine the board as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;8 | 0 0 0 0 0 0 0 0
7 | 0 0 0 0 0 0 0 0
6 | 0 0 0 0 0 0 0 0
5 | 0 0 0 0 0 0 0 0
4 | 0 0 0 0 0 0 0 0
3 | 0 0 0 0 0 0 0 0
2 | 1 1 1 1 1 1 1 1  ← White Pawns
1 | 0 0 0 0 0 0 0 0
    a b c d e f g h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is represented in Go as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;whitePawns&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x000000000000FF00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With bitboards, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get all pawns with a single value&lt;/li&gt;
&lt;li&gt;Find empty squares: &lt;code&gt;^occupiedSquares&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Calculate legal pawn moves with shifts like &lt;code&gt;whitePawns &amp;lt;&amp;lt; 8&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bitwise operations (&lt;code&gt;AND&lt;/code&gt;, &lt;code&gt;OR&lt;/code&gt;, &lt;code&gt;SHIFT&lt;/code&gt;) are insanely fast—no loops required.&lt;/p&gt;




&lt;h2&gt;
  
  
  👨‍💻 Example: Generating Pawn Moves
&lt;/h2&gt;

&lt;p&gt;Here's how you'd generate single-step pawn moves using bitboards in Go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;singleMoves&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;whitePawns&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;occupiedSquares&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want to allow double moves from the 2nd rank?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;doubleMoves&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;whitePawns&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;rank2Mask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;occupiedSquares&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add attack logic (diagonal captures), en passant rules, and you're already halfway to a serious chess engine.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔒 Validating King Safety
&lt;/h2&gt;

&lt;p&gt;One of the trickiest parts is ensuring that a move doesn’t leave your king in check. Here's the approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make the move &lt;strong&gt;virtually&lt;/strong&gt; (don’t modify real board yet).&lt;/li&gt;
&lt;li&gt;Recalculate all opponent attack bitboards.&lt;/li&gt;
&lt;li&gt;If the king is under attack, reject the move.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This way, the engine enforces all safety rules without relying on the game state from external services.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Engine Is a Pure Go Package
&lt;/h2&gt;

&lt;p&gt;By keeping the engine as a pure Go package:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s portable and testable&lt;/li&gt;
&lt;li&gt;There are &lt;strong&gt;no dependencies&lt;/strong&gt; on HTTP, database, or external services&lt;/li&gt;
&lt;li&gt;All the logic lives in memory and runs lightning-fast&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can plug this engine into your service layer or even into a CLI-based chess app or bot.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Testing the Engine
&lt;/h2&gt;

&lt;p&gt;Unit tests are critical. Since the engine doesn’t rely on any infrastructure, it’s easy to write tests like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;True&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsMoveLegal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"e2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"e4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;whiteBoard&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;False&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsMoveLegal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"e2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"e5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;whiteBoard&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can simulate full games, generate perft (performance test) numbers, and validate against known legal positions.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 What's Next?
&lt;/h2&gt;

&lt;p&gt;Now that the engine can validate moves and generate legal positions, you can layer on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Move scoring and search (for an AI opponent)&lt;/li&gt;
&lt;li&gt;Threefold repetition detection&lt;/li&gt;
&lt;li&gt;Draws by insufficient material&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But even without AI, a robust engine ensures fair, rule-compliant play—which is essential for multiplayer games, tournaments, or bots.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Engine&lt;/strong&gt; is the brain that validates chess rules.&lt;/li&gt;
&lt;li&gt;It uses &lt;strong&gt;bitboards&lt;/strong&gt; (64-bit integers) to represent the board and calculate legal moves ultra-fast.&lt;/li&gt;
&lt;li&gt;All logic is implemented in a &lt;strong&gt;pure Go package&lt;/strong&gt;—clean, testable, and fast.&lt;/li&gt;
&lt;li&gt;Bitboards let you write elegant, blazing-fast chess logic without messy loops or nested conditionals.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building a chess app or just love systems programming, bitboards are one of the most satisfying tricks in the book.&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/namanvashistha/chess" rel="noopener noreferrer"&gt;https://github.com/namanvashistha/chess&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/namanvashistha" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2F2znn4km0i2jib7ru1sm9.png" alt="" width="170" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Create Stunning Images from Text with a Telegram Bot 🚀</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Wed, 22 Jan 2025 14:59:39 +0000</pubDate>
      <link>https://dev.to/namanvashistha/create-stunning-images-from-text-with-a-telegram-bot-2p9n</link>
      <guid>https://dev.to/namanvashistha/create-stunning-images-from-text-with-a-telegram-bot-2p9n</guid>
      <description>&lt;p&gt;In today’s fast-paced digital world, creating engaging content is a top priority for individuals and businesses alike. Imagine being able to generate aesthetically pleasing images from text messages, complete with hashtags and custom watermarks, right from Telegram. Let me introduce you to a Telegram bot that makes this a breeze!  &lt;/p&gt;

&lt;p&gt;In this article, I’ll walk you through how this bot works, its use cases, and how you can set it up in just a few steps.  &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What Does This Bot Do?&lt;/strong&gt; 🤔
&lt;/h2&gt;

&lt;p&gt;This bot takes text input from Telegram users and generates visually appealing images with:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rich text formatting&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom hashtags&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watermarks&lt;/strong&gt; (like your brand or username)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The generated images can be saved locally or shared instantly, perfect for:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Social media posts
&lt;/li&gt;
&lt;li&gt;Content creation workflows
&lt;/li&gt;
&lt;li&gt;Personal branding
&lt;/li&gt;
&lt;li&gt;Campaign visuals
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How It Works&lt;/strong&gt; 💡
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Text Parsing&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
The bot parses the input text and separates hashtags automatically.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Image Generation&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Using Python’s &lt;strong&gt;Pillow&lt;/strong&gt; library, the bot creates a clean, responsive design with:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A consistent color scheme
&lt;/li&gt;
&lt;li&gt;Wrapped text for proper alignment
&lt;/li&gt;
&lt;li&gt;Brand watermark
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Telegram Integration&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
The bot uses the &lt;strong&gt;python-telegram-bot&lt;/strong&gt; library to handle messages and respond with images dynamically.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom Fonts and Styling&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
With easily configurable fonts and colors, the output matches your brand aesthetics.  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Setting It Up&lt;/strong&gt; 🛠️
&lt;/h2&gt;

&lt;p&gt;Follow these simple steps to set up the bot:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone the Repository&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git clone https://github.com/namanvashistha/text-to-image-bot.git
   &lt;span class="nb"&gt;cd &lt;/span&gt;text-to-image-bot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install Dependencies&lt;/strong&gt;
Create a virtual environment and install the required Python libraries:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Configure Environment Variables&lt;/strong&gt;
Create a &lt;code&gt;.env&lt;/code&gt; file in the root directory with the following:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   TELEGRAM_BOT_TOKEN=your_telegram_bot_token
   IMAGE_WATERMARK=your_watermark_text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start the Bot&lt;/strong&gt;
Run the script to launch your bot:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   python bot.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Demo of the Bot&lt;/strong&gt; 🎉
&lt;/h2&gt;

&lt;p&gt;Here’s a quick example of what this bot can do:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input:
&lt;code&gt;Simple is better than complex. #Python #ZenOfPython&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Output:
&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.amazonaws.com%2Fuploads%2Farticles%2F6e4u2a5bctrxg7dkc1yq.png" alt="demo" width="800" height="784"&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Use Cases&lt;/strong&gt; 🌟
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Content Creators&lt;/strong&gt;: Generate Instagram-worthy posts or tweets instantly.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketing Teams&lt;/strong&gt;: Quickly create branded images for campaigns.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developers&lt;/strong&gt;: Extend the bot’s functionality to integrate with other platforms like Slack or WhatsApp.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Educators&lt;/strong&gt;: Create visually engaging slides or educational content.
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Repository&lt;/strong&gt; 🧑‍💻
&lt;/h2&gt;

&lt;p&gt;Check out the full source code and contribute to the project on GitHub:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/namanvashistha/text-to-image-bot" rel="noopener noreferrer"&gt;GitHub Repository: Text-to-Image Bot&lt;/a&gt;  &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What’s Next?&lt;/strong&gt; 🤔
&lt;/h2&gt;

&lt;p&gt;How would you improve this bot for your own use cases? Share your thoughts in the comments or feel free to open an issue or pull request on GitHub. &lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/namanvashistha" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2F2znn4km0i2jib7ru1sm9.png" alt="" width="170" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>telegram</category>
      <category>pillow</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Automated Job Search: LinkedIn Jobs to Notion Board</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Wed, 22 Jan 2025 14:13:24 +0000</pubDate>
      <link>https://dev.to/namanvashistha/automated-job-search-linkedin-jobs-to-notion-board-42mj</link>
      <guid>https://dev.to/namanvashistha/automated-job-search-linkedin-jobs-to-notion-board-42mj</guid>
      <description>&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.amazonaws.com%2Fuploads%2Farticles%2Fieoxf079iv70tat55ys9.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.amazonaws.com%2Fuploads%2Farticles%2Fieoxf079iv70tat55ys9.png" alt="notion board" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Python-based job scraping system that pulls LinkedIn listings into a structured Notion database. Repository: &lt;a href="https://github.com/namanvashistha/jobs-scrape-to-notion" rel="noopener noreferrer"&gt;jobs-scrape-to-notion&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repository:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/namanvashistha/jobs-scrape-to-notion
&lt;span class="nb"&gt;cd &lt;/span&gt;jobs-scrape-to-notion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install dependencies:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Configure Notion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a Notion integration at &lt;a href="https://www.notion.so/my-integrations" rel="noopener noreferrer"&gt;notion.so/my-integrations&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a new Notion database&lt;/li&gt;
&lt;li&gt;Share your database with the integration&lt;/li&gt;
&lt;li&gt;Copy the database ID from its URL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set environment variables:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update &lt;code&gt;.env&lt;/code&gt; with your credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NOTION_API_KEY=your_integration_token
NOTION_DATABASE_ID=your_database_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Job Scraping
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_jobs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_terms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results_wanted&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Scrapes LinkedIn jobs based on multiple search terms
&lt;/span&gt;    &lt;span class="c1"&gt;# Returns a pandas DataFrame with job details
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Notion Integration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Creates structured database entries&lt;/li&gt;
&lt;li&gt;Handles rich text, URLs, dates, and company logos&lt;/li&gt;
&lt;li&gt;Prevents duplicate entries&lt;/li&gt;
&lt;li&gt;Manages API rate limits&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Data Processing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sanitizes input data&lt;/li&gt;
&lt;li&gt;Formats salary ranges for Indian currency&lt;/li&gt;
&lt;li&gt;Handles company metadata&lt;/li&gt;
&lt;li&gt;Manages file attachments for logos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Running the Scraper
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Default configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search terms: ["Software Engineer", "Backend", "SDE"]&lt;/li&gt;
&lt;li&gt;Location: India&lt;/li&gt;
&lt;li&gt;Results per term: 20&lt;/li&gt;
&lt;li&gt;Platform: LinkedIn&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Customization
&lt;/h2&gt;

&lt;p&gt;Modify &lt;code&gt;main()&lt;/code&gt; in &lt;code&gt;scraper.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;search_terms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Your&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Preferred&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Terms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Your Location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;results_wanted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;  &lt;span class="c1"&gt;# Number of results per term
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Error Handling
&lt;/h2&gt;

&lt;p&gt;The system includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Comprehensive logging&lt;/li&gt;
&lt;li&gt;Rate limit management&lt;/li&gt;
&lt;li&gt;Duplicate prevention&lt;/li&gt;
&lt;li&gt;Data validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Visit the &lt;a href="https://github.com/namanvashistha/jobs-scrape-to-notion" rel="noopener noreferrer"&gt;repository&lt;/a&gt; for source code and detailed documentation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/namanvashistha" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2F2znn4km0i2jib7ru1sm9.png" alt="" width="170" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>notion</category>
      <category>linked</category>
      <category>python</category>
    </item>
    <item>
      <title>Automating Python Code Linting with GitHub Actions</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 21 Jan 2025 17:59:57 +0000</pubDate>
      <link>https://dev.to/namanvashistha/automating-python-code-linting-with-github-actions-1p6f</link>
      <guid>https://dev.to/namanvashistha/automating-python-code-linting-with-github-actions-1p6f</guid>
      <description>&lt;p&gt;Linting your Python code is crucial to maintaining code quality and consistency across your projects. GitHub Actions provides a powerful way to automate linting processes, ensuring that all code changes meet coding standards before being merged into your repository.&lt;/p&gt;

&lt;p&gt;In this article, we will explore how to set up a GitHub Action to lint Python code automatically whenever a pull request is created.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along, ensure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A GitHub repository containing Python code.&lt;/li&gt;
&lt;li&gt;Basic knowledge of GitHub Actions and workflows.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Setting Up the GitHub Action Workflow
&lt;/h2&gt;

&lt;p&gt;Below is a GitHub Actions workflow configuration that automatically lints Python code in pull requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint Python Code&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/*.py'&lt;/span&gt;  &lt;span class="c1"&gt;# Trigger workflow only when Python files change&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint Code&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check out code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get changed Python files&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get_changed_files&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tj-actions/changed-files@v35&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/*.py'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run pylint&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.get_changed_files.outputs.any_changed == 'true'&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dciborow/action-pylint@0.1.0&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;github_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;reporter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github-pr-review&lt;/span&gt;
          &lt;span class="na"&gt;glob_pattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.get_changed_files.outputs.all_changed_files }}&lt;/span&gt;
          &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;warning&lt;/span&gt;
          &lt;span class="na"&gt;filter_mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;added&lt;/span&gt;
          &lt;span class="na"&gt;fail_on_error&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Explanation of the Workflow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Triggering the workflow:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The workflow runs on &lt;code&gt;pull_request&lt;/code&gt; events.&lt;/li&gt;
&lt;li&gt;It is triggered only if changes include Python files (&lt;code&gt;'**/*.py'&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Steps in the job:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Checkout code:&lt;/strong&gt; Retrieves the repository code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identify changed Python files:&lt;/strong&gt; Uses &lt;code&gt;tj-actions/changed-files&lt;/code&gt; to detect which Python files were modified.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run pylint:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;dciborow/action-pylint&lt;/code&gt; GitHub Action runs &lt;code&gt;pylint&lt;/code&gt; on the changed files.&lt;/li&gt;
&lt;li&gt;It reports warnings directly on the pull request.&lt;/li&gt;
&lt;li&gt;The workflow fails if pylint finds any errors.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Customization Options
&lt;/h2&gt;

&lt;p&gt;You can customize the workflow based on your needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modify the &lt;code&gt;pylint_args&lt;/code&gt; to include or exclude specific checks.&lt;/li&gt;
&lt;li&gt;Change the &lt;code&gt;fail_on_error&lt;/code&gt; value to &lt;code&gt;false&lt;/code&gt; if you want warnings but don't want to block merges.&lt;/li&gt;
&lt;li&gt;Use a different pylint reporter such as &lt;code&gt;github-checks&lt;/code&gt; instead of &lt;code&gt;github-pr-review&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Viewing Linting Results
&lt;/h2&gt;

&lt;p&gt;Once the pull request is created, the pylint report will appear as a review comment on the PR, helping developers identify and fix issues efficiently.&lt;/p&gt;




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

&lt;p&gt;By automating Python code linting with GitHub Actions, you ensure that your codebase remains clean and adheres to coding standards, reducing technical debt and improving maintainability. Try integrating this workflow into your projects today!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/namanvashistha" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2F2znn4km0i2jib7ru1sm9.png" alt="" width="170" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building a Modern Chess Engine: A Deep Dive into Bitboard-Based Move Generation</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 21 Jan 2025 17:44:01 +0000</pubDate>
      <link>https://dev.to/namanvashistha/building-a-modern-chess-engine-a-deep-dive-into-bitboard-based-move-generation-345d</link>
      <guid>https://dev.to/namanvashistha/building-a-modern-chess-engine-a-deep-dive-into-bitboard-based-move-generation-345d</guid>
      <description>&lt;p&gt;Repository: &lt;a href="https://github.com/namanvashistha/chess" rel="noopener noreferrer"&gt;https://github.com/namanvashistha/chess&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chess engines have long fascinated programmers and chess enthusiasts alike. In this article, I'll walk you through the implementation of a chess engine focusing on efficient move generation using bitboards. We'll explore how bitboards work, why they're crucial for performance, and how to implement various piece movements.&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.amazonaws.com%2Fuploads%2Farticles%2F07pdkk62giqje4tkzw66.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.amazonaws.com%2Fuploads%2Farticles%2F07pdkk62giqje4tkzw66.png" alt="Chess Board" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Bitboards are a fundamental data structure in modern chess programming. At its core, a bitboard is a 64-bit integer where each bit represents a square on the chess board. This representation allows us to use efficient bitwise operations to manipulate the board state and generate moves.&lt;/p&gt;

&lt;p&gt;In our implementation, we use multiple bitboards to represent different aspects of the game:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;GameState&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;WhiteBitboard&lt;/span&gt;  &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;BlackBitboard&lt;/span&gt;  &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;PawnBitboard&lt;/span&gt;   &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;KnightBitboard&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;BishopBitboard&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;RookBitboard&lt;/span&gt;   &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;QueenBitboard&lt;/span&gt;  &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="n"&gt;KingBitboard&lt;/span&gt;   &lt;span class="kt"&gt;uint64&lt;/span&gt;
    &lt;span class="c"&gt;// ... other state information&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Move Generation Architecture
&lt;/h2&gt;

&lt;p&gt;The move generation system follows a two-step process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate pseudo-legal moves&lt;/li&gt;
&lt;li&gt;Filter out illegal moves that would leave the king in check&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 1: Pseudo-Legal Move Generation
&lt;/h3&gt;

&lt;p&gt;Let's look at how we generate moves for different pieces:&lt;/p&gt;

&lt;h4&gt;
  
  
  Pawn Move Generation
&lt;/h4&gt;

&lt;p&gt;Pawns have the most complex movement rules in chess. Here's how we handle them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;generatePawnMoves&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gs&lt;/span&gt; &lt;span class="n"&gt;dao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GameState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pseudo_legal_moves&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;legal_moves&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Single and double pushes&lt;/span&gt;
    &lt;span class="n"&gt;singleMove&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;piece&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
    &lt;span class="n"&gt;doubleMove&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;piece&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt;

    &lt;span class="c"&gt;// Diagonal captures and en passant&lt;/span&gt;
    &lt;span class="n"&gt;diagonalLeft&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;piece&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;^&lt;/span&gt; &lt;span class="m"&gt;0x0101010101010101&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;
    &lt;span class="n"&gt;diagonalRight&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;piece&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;^&lt;/span&gt; &lt;span class="m"&gt;0x8080808080808080&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single and double forward moves&lt;/li&gt;
&lt;li&gt;Diagonal captures&lt;/li&gt;
&lt;li&gt;En passant captures&lt;/li&gt;
&lt;li&gt;Promotion (handled in move execution)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Sliding Piece Movement
&lt;/h4&gt;

&lt;p&gt;For bishops, rooks, and queens, we use ray-tracing to find legal moves:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;removeBlockedMoves&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;piece&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;moves&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;allOccupied&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rayDirections&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;blockedMoves&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;rayDirections&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;blockedMoves&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="n"&gt;traceRay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;piece&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;allOccupied&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;moves&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;blockedMoves&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traces rays in all relevant directions&lt;/li&gt;
&lt;li&gt;Stops at the first occupied square&lt;/li&gt;
&lt;li&gt;Handles captures efficiently&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Check Detection and Legal Move Filtering
&lt;/h2&gt;

&lt;p&gt;One of the most critical aspects of move generation is ensuring moves are legal by verifying they don't leave the king in check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;filterLegalMoves&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gs&lt;/span&gt; &lt;span class="n"&gt;dao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GameState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;legalMoves&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pseudoLegalMoves&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;filteredMoves&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;piece&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;moves&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;pseudoLegalMoves&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Simulate each move and verify king safety&lt;/span&gt;
        &lt;span class="n"&gt;simulatedGameState&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;simulateMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;piece&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;movePosition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;isKingInCheck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;simulatedGameState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;isWhite&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;filteredMoves&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;piece&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="n"&gt;movePosition&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;filteredMoves&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Simulates each potential move&lt;/li&gt;
&lt;li&gt;Checks if the resulting position leaves the king in check&lt;/li&gt;
&lt;li&gt;Only keeps moves that maintain king safety&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Special Move Handling
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Castling Rights
&lt;/h3&gt;

&lt;p&gt;Castling requires checking several conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;King and rook haven't moved&lt;/li&gt;
&lt;li&gt;No pieces between king and rook&lt;/li&gt;
&lt;li&gt;King doesn't move through check&lt;/li&gt;
&lt;li&gt;King isn't in check
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CastlingRights&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"K"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;gs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WhiteBitboard&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PositionToIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"f1"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="n"&gt;gs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WhiteBitboard&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PositionToIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"g1"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="c"&gt;// ... additional checks&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;kingMoves&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;PositionToIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"g1"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;p&gt;The use of bitboards provides several performance benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Efficient move generation using bitwise operations&lt;/li&gt;
&lt;li&gt;Quick position evaluation&lt;/li&gt;
&lt;li&gt;Compact board representation&lt;/li&gt;
&lt;li&gt;Fast legal move filtering&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Technical Implementation Highlights
&lt;/h2&gt;

&lt;p&gt;Let's dive deeper into some key technical aspects:&lt;/p&gt;

&lt;h3&gt;
  
  
  Bit Manipulation Techniques
&lt;/h3&gt;

&lt;p&gt;The engine makes heavy use of bit manipulation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;piece &amp;amp; -piece&lt;/code&gt;: Isolates the least significant bit&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;board &amp;amp;= board - 1&lt;/code&gt;: Clears the least significant bit&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;board &amp;lt;&amp;lt; n&lt;/code&gt;: Shifts bits left (used for white piece moves)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;board &amp;gt;&amp;gt; n&lt;/code&gt;: Shifts bits right (used for black piece moves)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Move Generation Optimization
&lt;/h3&gt;

&lt;p&gt;The code uses several optimization techniques:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pre-calculated attack tables for knights and kings&lt;/li&gt;
&lt;li&gt;Efficient ray tracing for sliding pieces&lt;/li&gt;
&lt;li&gt;Smart use of bitwise operations to avoid loops&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  State Management
&lt;/h3&gt;

&lt;p&gt;The engine maintains game state efficiently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bitboards for piece positions&lt;/li&gt;
&lt;li&gt;Castling rights as string flags&lt;/li&gt;
&lt;li&gt;En passant square tracking&lt;/li&gt;
&lt;li&gt;Move history for game progression&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Building a chess engine is a fascinating exercise in both chess knowledge and computer science. The bitboard-based approach provides an elegant solution to the complex problem of move generation, offering both performance and maintainability.&lt;/p&gt;

&lt;p&gt;Some potential improvements for the future:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementation of a proper evaluation function&lt;/li&gt;
&lt;li&gt;Addition of search algorithms (minimax with alpha-beta pruning)&lt;/li&gt;
&lt;li&gt;Opening book integration&lt;/li&gt;
&lt;li&gt;Endgame tablebases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full source code demonstrates how modern programming techniques can be applied to create an efficient chess engine while maintaining readable and maintainable code.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note: This implementation focuses on move generation. For a complete chess engine, you would need to add position evaluation, search algorithms, and other features.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you're interested in diving deeper, check out the full codebase on&lt;a href="https://github.com/namanvashistha/chess" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Would you like me to expand on any particular section or provide more detailed technical explanations?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/namanvashistha" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2F2znn4km0i2jib7ru1sm9.png" alt="" width="170" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>chess</category>
      <category>postgres</category>
      <category>websocket</category>
    </item>
    <item>
      <title>Why I Love: git reset --hard</title>
      <dc:creator>Naman Vashistha</dc:creator>
      <pubDate>Tue, 21 Jan 2025 14:32:27 +0000</pubDate>
      <link>https://dev.to/namanvashistha/why-i-love-git-reset-hard-49np</link>
      <guid>https://dev.to/namanvashistha/why-i-love-git-reset-hard-49np</guid>
      <description>&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.amazonaws.com%2Fuploads%2Farticles%2Fcqsnfa536i2yrli7hins.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.amazonaws.com%2Fuploads%2Farticles%2Fcqsnfa536i2yrli7hins.png" alt="beauty of git reset --hard" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Managing version control is both an art and a science, and for many developers, Git is the tool of choice. While Git offers a plethora of commands to handle almost any situation, there is one command I hold dear to my heart: &lt;code&gt;git reset --hard&lt;/code&gt;. It’s my go-to solution when things go haywire, and it’s the unsung hero that has saved me countless times. In this article, I’ll explain why I love it, how it makes my life easier, and how you can use it effectively.&lt;/p&gt;




&lt;h3&gt;
  
  
  What Does &lt;code&gt;git reset --hard&lt;/code&gt; Do?
&lt;/h3&gt;

&lt;p&gt;At its core, &lt;code&gt;git reset --hard&lt;/code&gt; is about resetting your Git repository to a clean state. When you run this command, three things happen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HEAD Moves&lt;/strong&gt;: The HEAD pointer is moved to a specific commit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staging Area Reset&lt;/strong&gt;: The staging area is updated to match the target commit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Working Directory Reset&lt;/strong&gt;: All uncommitted changes in your working directory are discarded to match the target commit.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In simpler terms, it’s like hitting a "factory reset" button for your Git repository. Here’s the syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; &amp;lt;commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you omit the commit hash, it defaults to the latest commit.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why &lt;code&gt;git reset --hard&lt;/code&gt; Is a Game-Changer
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Undoing Mistakes Instantly&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;There have been countless times when I made experimental changes that didn’t pan out. Instead of manually reverting each file or trying to stash changes, I simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within seconds, my repository is back to its last stable state. It’s quick, efficient, and hassle-free.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Getting a Clean Slate&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;When working on large projects, the working directory can get cluttered with temporary changes. Sometimes, you just want to start fresh. &lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;You’re debugging an issue and have tried multiple approaches.&lt;/li&gt;
&lt;li&gt;None of them worked, and your directory is now a mess of temporary files and edits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of sifting through the debris, &lt;code&gt;git reset --hard&lt;/code&gt; wipes the slate clean, letting you start anew.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Recovering from Merge Chaos&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Merges don’t always go as planned, and conflicts can leave your repository in an inconsistent state. When I realize a merge has gone sideways, I use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; &amp;lt;commit-before-merge&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This resets my repository to a pre-merge state, allowing me to approach the merge more carefully.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. &lt;strong&gt;Experimentation Without Fear&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;One of the joys of being a developer is experimenting with new ideas. But experiments often lead to dead ends. Knowing I can always reset my repository gives me the freedom to try new things without worrying about breaking anything permanently.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Use It, But Use It Wisely&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As powerful as &lt;code&gt;git reset --hard&lt;/code&gt; is, it comes with a caveat: &lt;strong&gt;it’s irreversible&lt;/strong&gt;. Once you run this command, any uncommitted changes are gone for good. To avoid losing important work, here are some tips:&lt;/p&gt;

&lt;h5&gt;
  
  
  1. &lt;strong&gt;Check the Commit History&lt;/strong&gt;:
&lt;/h5&gt;

&lt;p&gt;Use &lt;code&gt;git log&lt;/code&gt; to ensure you’re resetting to the right commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  2. &lt;strong&gt;Use &lt;code&gt;git reflog&lt;/code&gt; for Recovery&lt;/strong&gt;:
&lt;/h5&gt;

&lt;p&gt;If you accidentally reset to the wrong commit, &lt;code&gt;git reflog&lt;/code&gt; can help you find your previous HEAD position.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git reflog
   git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; &amp;lt;old-commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  3. &lt;strong&gt;Commit or Stash First&lt;/strong&gt;:
&lt;/h5&gt;

&lt;p&gt;Before running &lt;code&gt;git reset --hard&lt;/code&gt;, always commit or stash any changes you might need later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git stash save &lt;span class="s2"&gt;"WIP changes"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Caution: The Double-Edged Sword&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;git reset --hard&lt;/code&gt; is incredibly powerful, but with great power comes great responsibility. It permanently discards uncommitted changes, which means there’s no way to recover them unless you’ve stashed or committed first. Always double-check your changes and use commands like &lt;code&gt;git log&lt;/code&gt; or &lt;code&gt;git reflog&lt;/code&gt; to ensure you’re targeting the correct commit. This cautionary step can save you from accidental data loss.&lt;/p&gt;




&lt;h3&gt;
  
  
  Real-World Examples
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Fixing a Botched Feature&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Imagine you’re halfway through implementing a new feature, and it’s not working as expected. You realize it’d be faster to start over. Here’s what you do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In seconds, you’re back to where you started, ready to tackle the feature with a fresh perspective.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Cleaning Up After a Failed Rebase&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Rebasing can sometimes lead to unexpected conflicts or an incomplete history. If a rebase goes wrong, here’s how you can recover:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, abort the rebase to stop the process and revert any in-progress changes:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git rebase &lt;span class="nt"&gt;--abort&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If you still need to reset your branch to its state before the rebase, use:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; ORIG_HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Additionally, if there are specific commits from the rebase you want to preserve, you can cherry-pick them individually after resetting:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git cherry-pick &amp;lt;commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This combination gives you the flexibility to recover from rebase errors without losing valuable work.  &lt;/p&gt;




&lt;h3&gt;
  
  
  Why I Love It
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;git reset --hard&lt;/code&gt; is more than just a command; it’s a safety net. It gives me the confidence to experiment, the ability to recover quickly, and the freedom to focus on solving problems without worrying about making mistakes. It’s a tool that’s simple yet incredibly powerful.&lt;/p&gt;

&lt;p&gt;If you haven’t already embraced &lt;code&gt;git reset --hard&lt;/code&gt;, I encourage you to give it a try. Just remember to use it wisely, and it’ll become one of your favorite Git commands too.&lt;/p&gt;




&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Version control is an essential skill for developers, and mastering commands like &lt;code&gt;git reset --hard&lt;/code&gt; can make your life significantly easier. While it may seem intimidating at first, understanding its nuances will empower you to handle even the messiest of repositories with confidence. For me, it’s an indispensable part of my workflow, and I hope it can be for you too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/namanvashistha" rel="noopener noreferrer"&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.amazonaws.com%2Fuploads%2Farticles%2F2znn4km0i2jib7ru1sm9.png" alt="" width="170" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
    </item>
  </channel>
</rss>
