<?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>Forem: Yash-007</title>
    <description>The latest articles on Forem by Yash-007 (@yash404).</description>
    <link>https://forem.com/yash404</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%2F1442386%2F24eacecb-d545-46d5-84eb-90e310de7cbe.jpg</url>
      <title>Forem: Yash-007</title>
      <link>https://forem.com/yash404</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/yash404"/>
    <language>en</language>
    <item>
      <title>LynkBin: AI-Powered Bookmark Manager</title>
      <dc:creator>Yash-007</dc:creator>
      <pubDate>Sat, 20 Dec 2025 21:45:51 +0000</pubDate>
      <link>https://forem.com/yash404/lynkbin-ai-powered-bookmark-manager-blc</link>
      <guid>https://forem.com/yash404/lynkbin-ai-powered-bookmark-manager-blc</guid>
      <description>&lt;p&gt;I save a lot of good content. LinkedIn posts, X threads, Reddit insights.&lt;br&gt;
but when I actually need them… they’re gone.&lt;/p&gt;

&lt;p&gt;Bookmarks became a black hole.&lt;/p&gt;

&lt;p&gt;so I started building &lt;a href="//lynkbin.vercel.app"&gt;LynkBin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;a simple place to dump everything you save and actually find it later.&lt;/p&gt;

&lt;p&gt;what it does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one hub for saved posts + personal notes&lt;/li&gt;
&lt;li&gt;AI auto organizes stuff (categories, tags, short descriptions based on the content)&lt;/li&gt;
&lt;li&gt;smart filters so you don’t have to scroll forever&lt;/li&gt;
&lt;li&gt;save in seconds via &lt;strong&gt;Dashboard or Telegram bot&lt;/strong&gt;
**&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;the goal isn’t to save more content. it’s to make saved content useful again.&lt;/p&gt;

&lt;p&gt;I’m actively adding more features including support for more platforms like Instagram, YouTube, and will also work on browser extension to save things even faster.&lt;/p&gt;

&lt;p&gt;I'm open to ideas on what would make this useful and super easy for you to use.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>socialmedia</category>
      <category>saas</category>
      <category>resources</category>
    </item>
    <item>
      <title>Go Concurrency: Goroutines, Channels and WaitGroups</title>
      <dc:creator>Yash-007</dc:creator>
      <pubDate>Tue, 12 Aug 2025 21:21:34 +0000</pubDate>
      <link>https://forem.com/yash404/go-concurrency-goroutines-channels-and-waitgroups-165d</link>
      <guid>https://forem.com/yash404/go-concurrency-goroutines-channels-and-waitgroups-165d</guid>
      <description>&lt;p&gt;In &lt;strong&gt;Go&lt;/strong&gt;, we can make our program do more than one thing at the same time. This is called concurrency, and it’s a great way to get things done faster.&lt;/p&gt;

&lt;p&gt;we'll walk through goroutines, channels, and WaitGroups with simple examples you can try yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is concurrency?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;imagine you’re making dinner. while the pasta is boiling, you start cutting vegetables for the salad. you’re doing both at once so the food is ready sooner.&lt;/p&gt;

&lt;p&gt;that’s how concurrency works in a program. you run different tasks side by side instead of waiting for each one to finish before starting the next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goroutines: Your Lightweight Workers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A goroutine is like hiring an extra worker for your program. it's incredibly cheap to create (we can have thousands of them) and they all work together.&lt;/p&gt;

&lt;p&gt;simple example: without Goroutines&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
    cookPasta()     // takes 10 minutes
    makeSalad()     // takes 5 minutes
    bakeBread()     // takes 15 minutes
    // Total time: 30 minutes
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with Goroutines&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
    go cookPasta()     // start cooking pasta in background
    go makeSalad()     // start making salad in background
    go bakeBread()     // start baking bread in background

    time.Sleep(16 * time.Minute) // Wait for everything to finish
    // Total time: 16 minutes (everything runs together!)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the go keyword is like saying "hey, start doing this task in the background while I continue with other things."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem: How Do We Know When Work is Done?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;here's the issue with the restaurant example above. how do we know when all the chefs are done? we used time.Sleep() which is like guessing how long it will take. that's not reliable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution 1: WaitGroups (The Team Counter)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A WaitGroup is like a counter that keeps track of how many workers are still busy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
    var wg sync.WaitGroup  // create a counter

    wg.Add(1)  // "I'm starting 1 worker"
    go func() {
        defer wg.Done()  // "this worker is finished"
        cookPasta()
    }()

    wg.Add(1)  // "I'm starting another worker"
    go func() {
        defer wg.Done()  // "this worker is finished"
        makeSalad()
    }()

    wg.Wait()  // "wait until all workers are done"
    fmt.Println("all food is ready")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;When to use WaitGroups:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you have a fixed number of tasks&lt;/li&gt;
&lt;li&gt;you just want to wait for everything to finish&lt;/li&gt;
&lt;li&gt;you don't need results back from the workers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution 2: Channels (The Communication System)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Channels are like walkie-talkies that let your goroutines talk to each other. they can send messages, data, or even just signals saying "I'm done"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;basic Channel example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
    messages := make(chan string)  // create a walkie-talkie

    // Worker sends a message
    go func() {
        time.Sleep(2 * time.Second)
        messages &amp;lt;- "Pizza is ready!"  // send message through channel
    }()

    // main goroutine receives the message
    msg := &amp;lt;-messages  // wait for and receive message
    fmt.Println(msg)   // pints: "Pizza is ready!"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Using Channels for Completion Signals&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func cookWithChannels() {
    done := make(chan bool)  // create a "done" signal channel

    go func() {
        cookPasta()
        done &amp;lt;- true  // send "finished" signal
    }()

    go func() {
        makeSalad()
        done &amp;lt;- true  // send "finished" signal
    }()

    // wait for both tasks to finish
    &amp;lt;-done  // wait for first task
    &amp;lt;-done  // wait for second task

    fmt.Println("both tasks completed!")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real World Example: Processing Multiple Files&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;let's say you want to process 100 files. here's how you'd do it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without Concurrency (Slow)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func processFiles(files []string) {
    for _, file := range files {
        processFile(file)  // process one file at a time
    }
    // If each file takes 1 second, 100 files = 100 seconds
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With Goroutines and WaitGroups (Fast)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func processFilesConcurrently(files []string) {
    var wg sync.WaitGroup

    for _, file := range files {
        wg.Add(1)
        go func(fileName string) {
            defer wg.Done()
            processFile(fileName)
        }(file)
    }

    wg.Wait()  // wait for all files to be processed
    // with 10 CPU cores, 100 files might take only 10 seconds
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With Goroutines and Channels (Getting Results Back)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func processFilesWithResults(files []string) {
    results := make(chan string, len(files))  // buffered channel

    // start workers
    for _, file := range files {
        go func(fileName string) {
            result := processFile(fileName)
            results &amp;lt;- result  // send result back
        }(file)
    }

    // Collect results
    for i := 0; i &amp;lt; len(files); i++ {
        result := &amp;lt;-results
        fmt.Println("Got result:", result)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;When to Use What?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;use Goroutines when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you want to do multiple things at the same time&lt;/li&gt;
&lt;li&gt;tasks are independent of each other&lt;/li&gt;
&lt;li&gt;you want to improve performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;use WaitGroups when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you have a known number of workers&lt;/li&gt;
&lt;li&gt;you just need to wait for everything to finish&lt;/li&gt;
&lt;li&gt;you don't need results or communication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;use Channels when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;workers need to send data back&lt;/li&gt;
&lt;li&gt;you need coordination between goroutines&lt;/li&gt;
&lt;li&gt;you want to control the flow of work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Simple Worker Pool Pattern&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func workerPool(jobs []string, numWorkers int) {
    jobChan := make(chan string)

    // start workers
    var wg sync.WaitGroup
    for i := 0; i &amp;lt; numWorkers; i++ {
        wg.Add(1)
        go func(workerID int) {
            defer wg.Done()
            for job := range jobChan {  // keep taking jobs until channel closes
                fmt.Printf("Worker %d processing %s\n", workerID, job)
                // do actual work here
                time.Sleep(1 * time.Second)
            }
        }(i)
    }

    // send jobs
    go func() {
        for _, job := range jobs {
            jobChan &amp;lt;- job
        }
        close(jobChan)  // signal no more jobs
    }()

    wg.Wait()  // wait for all workers to finish
    fmt.Println("all jobs completed!")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Goroutines are cheap and easy.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WaitGroups are perfect for "fire and forget" scenarios&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Channels are great when you need communication or results&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>go</category>
      <category>coding</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>REST vs gRPC – When to Use What</title>
      <dc:creator>Yash-007</dc:creator>
      <pubDate>Sat, 26 Jul 2025 21:37:55 +0000</pubDate>
      <link>https://forem.com/yash404/rest-vs-grpc-when-to-use-what-18f</link>
      <guid>https://forem.com/yash404/rest-vs-grpc-when-to-use-what-18f</guid>
      <description>&lt;p&gt;Most of us start building APIs with REST. It’s easy, works well in browsers and is simple to test using tools like postman or curl. you send some JSON, get a response that’s it.&lt;/p&gt;

&lt;p&gt;But recently I came across gRPC. At first, it seemed complicated. but once I understood the basics, it started to make sense. This post is just a quick summary of what I learned not a deep dive, just something simple to help others get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;First, What is RPC?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;before understanding gRPC, let’s look at RPC (Remote Procedure Call).&lt;/p&gt;

&lt;p&gt;RPC is when one program calls a function that runs on another machine, like it’s calling a local function. You don’t worry about the network or HTTP stuff just call a method, pass some data, and get back a result.&lt;/p&gt;

&lt;p&gt;It’s like saying:&lt;/p&gt;

&lt;p&gt;“Run this function somewhere else and send me the result.”&lt;/p&gt;

&lt;p&gt;that makes it a good fit for when services need to talk to each other often.&lt;/p&gt;

&lt;p&gt;gRPC is an RPC framework&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;REST – Easy, Familiar, Works Everywhere&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;REST is the most common way to build APIs. It uses HTTP/1.1 and sends data using JSON. JSON is text-based, easy to read, and works with browsers, mobile apps, and tools.&lt;/p&gt;

&lt;p&gt;Why REST is popular:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;easy to read and write&lt;/li&gt;
&lt;li&gt;simple to test (Postman, curl, browser)&lt;/li&gt;
&lt;li&gt;great for frontend-backend connections&lt;/li&gt;
&lt;li&gt;If your API is going to be used by web or mobile apps. REST is the obvious choice.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;gRPC – Some Setup, But Super Fast&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;gRPC is a better choice when your own backend services need to talk to each other like microservices or internal APIs.&lt;/p&gt;

&lt;p&gt;Instead of JSON, gRPC uses a smaller binary format called protobuf. it also uses HTTP/2, which allows faster, multiple connections and streaming.&lt;/p&gt;

&lt;p&gt;It made backend communication really fast and clean and used a lot by companies with big systems, where many services need to talk to each other quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How Does gRPC Work?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Step 1: write a .proto file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;syntax = "proto3";

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Generate code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You run a command to generate client and server code from the proto file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Use that code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Server code (in Go):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func (s *MyGreeterServer) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
  return &amp;amp;pb.HelloReply{Message: "Hello " + req.Name}, nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Client code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;conn, _ := grpc.Dial("localhost:50051", grpc.WithInsecure())
client := pb.NewGreeterClient(conn)

res, _ := client.SayHello(context.Background(), &amp;amp;pb.HelloRequest{Name: "Yash"})
fmt.Println(res.Message) // "Hello Yash"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You call a function like normal, and gRPC handles everything behind the scenes.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;When to Use What?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If your service talks to browsers or mobile apps → REST is easier.&lt;/p&gt;

&lt;p&gt;If your services talk to each other a lot → gRPC is faster and uses less data.&lt;/p&gt;

&lt;p&gt;for example, a frontend app calling your API → REST.&lt;br&gt;
two backend services sending data to each other all day → gRPC.&lt;/p&gt;

</description>
      <category>backenddevelopment</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
      <category>go</category>
    </item>
    <item>
      <title>Reflection in Go — When You Need to Work with the Unknown</title>
      <dc:creator>Yash-007</dc:creator>
      <pubDate>Fri, 25 Jul 2025 20:22:05 +0000</pubDate>
      <link>https://forem.com/yash404/reflection-in-go-when-you-need-to-work-with-the-unknown-4h6l</link>
      <guid>https://forem.com/yash404/reflection-in-go-when-you-need-to-work-with-the-unknown-4h6l</guid>
      <description>&lt;p&gt;Go is a statically typed language, which means you usually know the type of every variable at compile time. but sometimes you don’t especially when working with interface{} and that’s when reflection becomes useful.&lt;/p&gt;

&lt;p&gt;The reflect package in Go allows your program to inspect and even modify types and values at runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;reflect.TypeOf and reflect.ValueOf&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These two are the entry points for using reflection in Go:&lt;/p&gt;

&lt;p&gt;TypeOf() gives the static type.&lt;br&gt;
ValueOf() gives the runtime value.&lt;br&gt;
&lt;/p&gt;

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

t := reflect.TypeOf(x)   // float64
v := reflect.ValueOf(x)  // 3.14

fmt.Println("Type:", t)
fmt.Println("Kind:", t.Kind()) // float64

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Reading Struct Fields at Runtime&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reflection lets you loop through struct fields dynamically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

u := User{"Yash", 30}
v := reflect.ValueOf(u)
t := reflect.TypeOf(u)

for i := 0; i &amp;lt; v.NumField(); i++ {
    field := t.Field(i)
    fmt.Println("Field:", field.Name)
    fmt.Println("Value:", v.Field(i))
    fmt.Println("Tag:", field.Tag.Get("json"))
}

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

&lt;/div&gt;



&lt;p&gt;This is exactly what libraries like encoding/json or gorm do under the hood read struct fields and tags at runtime to decide how to handle data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modifying a Value Using Reflection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to update a variable through reflection, you need to pass a pointer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x := 3.4
v := reflect.ValueOf(&amp;amp;x) // pass pointer
v.Elem().SetFloat(7.1)

fmt.Println(x) // 7.1

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

&lt;/div&gt;



&lt;p&gt;Trying to modify a non-pointer value will result in a panic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dynamically Calling Methods&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can even call methods by their name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type MyType struct{}

func (m MyType) SayHello(name string) {
    fmt.Println("Hello", name)
}

v := reflect.ValueOf(MyType{})
method := v.MethodByName("SayHello")
method.Call([]reflect.Value{reflect.ValueOf("Yash")}) // Output: Hello Yash

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

&lt;/div&gt;



&lt;p&gt;Reflection is heavily used in the Go ecosystem. some common examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;encoding/json for marshaling and unmarshaling structs&lt;/li&gt;
&lt;li&gt;GORM (ORM library) to map Go structs to database tables&lt;/li&gt;
&lt;li&gt;Validation libraries (like go playground/validator)&lt;/li&gt;
&lt;li&gt;Logging tools, serialization frameworks, CLI parsers, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;End:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reflection is powerful&lt;/strong&gt;, but:&lt;/p&gt;

&lt;p&gt;It’s slower than regular code&lt;br&gt;
You lose compile time type safety&lt;br&gt;
It can make code harder to understand&lt;br&gt;
So use it only when you really need dynamic behavior.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>go</category>
      <category>development</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>A Subtle Memory Leak in Go You Might Miss</title>
      <dc:creator>Yash-007</dc:creator>
      <pubDate>Thu, 24 Jul 2025 13:36:54 +0000</pubDate>
      <link>https://forem.com/yash404/a-subtle-memory-leak-in-go-you-might-miss-48ef</link>
      <guid>https://forem.com/yash404/a-subtle-memory-leak-in-go-you-might-miss-48ef</guid>
      <description>&lt;p&gt;When we think of memory leaks, we usually imagine something obvious like forgetting to close a file or a goroutine running forever. But in Go, memory leaks can be much more subtle.&lt;/p&gt;

&lt;p&gt;One such case comes from how slices work under the hood.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How slices actually work&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;A slice in Go is not the actual data. It’s just a small structure that contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;a pointer to the underlying array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a length&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a capacity&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;so when you reslice a slice, you're not making a new copy. You're just creating another view over the same underlying array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem: memory being held unnecessarily&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Let’s say you’re reading a large file into memory and want to extract only the first group of digits from it. You might write a function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var digitRegexp = regexp.MustCompile("[0-9]+")

func FindDigits(filename string) []byte {
    b, _ := ioutil.ReadFile(filename)
    return digitRegexp.Find(b)
}

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

&lt;/div&gt;



&lt;p&gt;At first glance, this looks fine. It reads the file, finds the first digit sequence, and returns it.&lt;/p&gt;

&lt;p&gt;But here’s the issue: the returned slice still points to the original array that contains the entire file. So even though you’re only using a few bytes, the garbage collector can’t release the rest of the file from memory because it’s still being referenced by the slice.&lt;/p&gt;

&lt;p&gt;This can easily lead to memory being held longer than necessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix: copy what you need:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To prevent this, you can simply copy the slice that you actually care about into a new one. That way, the rest of the file is no longer referenced and can be cleaned up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func CopyDigits(filename string) []byte {
    b, _ := ioutil.ReadFile(filename)
    b = digitRegexp.Find(b)
    c := make([]byte, len(b))
    copy(c, b)
    return c
}

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

&lt;/div&gt;



&lt;p&gt;This way, only the required bytes are kept in memory, and the rest of the file can be garbage collected.&lt;/p&gt;

&lt;p&gt;This is a small detail that’s easy to overlook, but it can have a big impact especially in long running programs or memory heavy operations.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>go</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
