<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Golang on Ou David | Systems Engineer</title><link>https://preview.vvivid.dev/tags/golang/</link><description>Recent content in Golang on Ou David | Systems Engineer</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sat, 13 Jun 2026 10:34:19 +0700</lastBuildDate><atom:link href="https://preview.vvivid.dev/tags/golang/index.xml" rel="self" type="application/rss+xml"/><item><title>String Concatenation vs strings.Builder in Go</title><link>https://preview.vvivid.dev/posts/go_string_concat_vs_string_builder/</link><pubDate>Sat, 13 Jun 2026 10:34:19 +0700</pubDate><guid>https://preview.vvivid.dev/posts/go_string_concat_vs_string_builder/</guid><description>&lt;p&gt;I often leave the same comment when I see string concatenation inside a loop:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you build a string in a loop, use &lt;code&gt;strings.Builder&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That comment sometimes gets pushback from the team: the two operations probably will not matter much. Today, I want to show a simple benchmark to demonstrate why &lt;code&gt;strings.Builder&lt;/code&gt; is superior to doing &lt;code&gt;+=&lt;/code&gt; inside a loop.&lt;/p&gt;
&lt;p&gt;The runnable code and raw benchmark output are available in the public repo: &lt;a href="https://gitlab.vvivid.dev/showcase/go-lang-case-study"&gt;gitlab.vvivid.dev/showcase/go-lang-case-study&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Go Language Case Studies</title><link>https://preview.vvivid.dev/projects/go-lang-case-study/</link><pubDate>Sat, 13 Jun 2026 00:00:00 +0000</pubDate><guid>https://preview.vvivid.dev/projects/go-lang-case-study/</guid><description>&lt;p&gt;This is where I keep small Go case studies that support the technical writing on this site. Each topic is built as a runnable example with tests or benchmarks, so the discussion can point to code instead of relying only on explanation.&lt;/p&gt;
&lt;p&gt;Public repo: &lt;a href="https://gitlab.vvivid.dev/showcase/go-lang-case-study"&gt;gitlab.vvivid.dev/showcase/go-lang-case-study&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The first case study compares normal string concatenation with &lt;code&gt;strings.Builder&lt;/code&gt;, including benchmark output and allocation counts.&lt;/p&gt;</description></item><item><title>The Silent Timezone Mismatch: Go vs MongoDB</title><link>https://preview.vvivid.dev/posts/the_silent_timezone_mismatch_go_vs_mongodb/</link><pubDate>Fri, 16 Jan 2026 18:33:20 +0100</pubDate><guid>https://preview.vvivid.dev/posts/the_silent_timezone_mismatch_go_vs_mongodb/</guid><description>&lt;p&gt;I recently encountered a subtle bug that cost more time than I&amp;rsquo;d like to admit. It’s a classic example of how implicit defaults in our tools can lead to unexpected behavior in distributed systems.&lt;/p&gt;
&lt;h3 id="the-real-problem"&gt;The Real Problem&lt;/h3&gt;
&lt;p&gt;I was implementing a validation function, &lt;code&gt;isValidCiaoPayment&lt;/code&gt;. The logic was simple: check if a payment record from MongoDB matches a specific check date (e.g., &amp;ldquo;2026-01-15&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Here is the logic:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Convert payment time to string YYYY-MM-DD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;paymentUpdatedAtDate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UpdatedAt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DateOnly&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Compare with the target date&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;paymentUpdatedAtDate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;checkDate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The function kept returning &lt;code&gt;false&lt;/code&gt; even when the data looked correct in the database.&lt;/p&gt;</description></item><item><title>Building a JSON-RPC Server in Go: Complete Implementation Guide</title><link>https://preview.vvivid.dev/posts/jsonrpc_example/</link><pubDate>Sat, 30 Aug 2025 10:00:00 +0000</pubDate><guid>https://preview.vvivid.dev/posts/jsonrpc_example/</guid><description>&lt;p&gt;Last week, I posted about &lt;a href="https://preview.vvivid.dev/posts/json_rpc_the_protocol_behind_mcp/"&gt;JSON-RPC and the Model Context Protocol&lt;/a&gt;. Today, we&amp;rsquo;re going to see an example of how we can create a simple application following the JSON-RPC standard. We&amp;rsquo;ll build a simple JSON-RPC calculator together, and I hope you&amp;rsquo;ll enjoy it.&lt;/p&gt;
&lt;h2 id="request-flow-overview"&gt;Request Flow Overview&lt;/h2&gt;
&lt;div class="mermaid"&gt;
flowchart LR
A[Client Request] --&gt; B[Parse JSON]
B --&gt; C{Valid?}
C --&gt;|No| D[Error Response]
C --&gt;|Yes| E{Type?}
E --&gt;|Request| F[Match Method]
E --&gt;|Notification| G[Execute &amp; End]
F --&gt; H{Method Found?}
H --&gt;|No| I[Method Not Found]
H --&gt;|Yes| J[Execute Method]
J --&gt; K[Build Response]
I --&gt; K
K --&gt; L[Send Response]
D --&gt; L
L --&gt; M[End]
G --&gt; M
&lt;/div&gt;&lt;h2 id="message-parsing-and-validation"&gt;Message Parsing and Validation&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s recap JSON-RPC message types. We have 3 types of messages: Request, Response, and Notification. For request and response types, we can send them in batches, and responses must be returned in a batch matching the request IDs in any order. We can distinguish between a request and a notification by checking the ID field. If there&amp;rsquo;s an ID, it&amp;rsquo;s a request; if not, it&amp;rsquo;s a notification.&lt;/p&gt;</description></item><item><title>The HTTP Request Journey in Go: From Network to Handler</title><link>https://preview.vvivid.dev/posts/http_in_golang/</link><pubDate>Fri, 08 Aug 2025 10:00:00 +0000</pubDate><guid>https://preview.vvivid.dev/posts/http_in_golang/</guid><description>&lt;p&gt;As a backend guy, I&amp;rsquo;ve been tasked with building various APIs for different projects, and most of them I built using Go. For the majority of the time, what most people do is write a handler or middleware to process and respond to requests. Today, we&amp;rsquo;re going to do something different. We&amp;rsquo;ll go down a rabbit hole together into the abstractions that Go has taken away from us. We&amp;rsquo;ll see all the interesting things that Go does before handing us the request and response objects in our handler. After this deep dive, we&amp;rsquo;ll understand how to parse requests, how routing matching works, middleware execution, and finally the architecture that Go uses to handle each request.&lt;/p&gt;</description></item></channel></rss>