<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Computer Science on Beyond the Bytes</title><link>https://srajesh2712.github.io/tags/computer-science/</link><description>Recent content in Computer Science on Beyond the Bytes</description><generator>Hugo -- 0.160.1</generator><language>en-us</language><lastBuildDate>Sun, 26 Apr 2026 06:00:00 +0000</lastBuildDate><atom:link href="https://srajesh2712.github.io/tags/computer-science/index.xml" rel="self" type="application/rss+xml"/><item><title>Part 2 - From $O(N^2)$ to $O(N)$ with Zero Memory Churn: A Go Optimization Story</title><link>https://srajesh2712.github.io/posts/2026/04/26/array-difference-optimization-2/</link><pubDate>Sun, 26 Apr 2026 06:00:00 +0000</pubDate><guid>https://srajesh2712.github.io/posts/2026/04/26/array-difference-optimization-2/</guid><description>&lt;p&gt;In my previous post, I optimized a slice difference algorithm ($O(n+m)$) by pre-allocating memory. But as a Software Architect, I immediately asked myself:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I do this with &lt;em&gt;zero&lt;/em&gt; extra memory for the result?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The answer is an &lt;strong&gt;in-place algorithm&lt;/strong&gt;, implemented using the &lt;strong&gt;two-pointer technique&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In high-performance systems and big data pipelines, this approach is often the gold standard because it minimizes memory churn and reduces pressure on the garbage collector.&lt;/p&gt;</description></item><item><title>Part 2 - From $O(N^2)$ to $O(N)$ with Zero Memory Churn: A Go Optimization Story</title><link>https://srajesh2712.github.io/posts/2026/04/19/array-difference-optimization-1/</link><pubDate>Sun, 19 Apr 2026 06:00:00 +0000</pubDate><guid>https://srajesh2712.github.io/posts/2026/04/19/array-difference-optimization-1/</guid><description>&lt;p&gt;🚀 From O(N2) to O(N) with Zero Memory Churn: A Go Optimization Story&lt;/p&gt;
&lt;p&gt;As a Software Architect, I believe the difference between &amp;ldquo;code that works&amp;rdquo; and &amp;ldquo;production-grade engineering&amp;rdquo; lies in understanding the runtime. Today, I’m sharing a journey of optimizing a simple Array Difference algorithm in Go (Golang), achieving a 66% reduction in RAM and a 73% drop in allocations.
🛠️ The Evolution of the Solution
Step 1: The Functional Baseline (The &amp;ldquo;Naive&amp;rdquo; Approach)&lt;/p&gt;</description></item><item><title>Part 4 - Deep Dive: How Database Indexing Works (The B-Tree)</title><link>https://srajesh2712.github.io/posts/2026/04/12/part4-index-introduction/</link><pubDate>Sun, 12 Apr 2026 05:55:00 +0000</pubDate><guid>https://srajesh2712.github.io/posts/2026/04/12/part4-index-introduction/</guid><description>&lt;p&gt;Continuation to the previous blog.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="28-the-heavy-data-reality-tsvectors"&gt;28. The “Heavy Data” Reality: TSVectors&lt;/h2&gt;
&lt;p&gt;While working on my &lt;code&gt;topic&lt;/code&gt; table, I noticed I’m building a &lt;code&gt;search_vector&lt;/code&gt; column using &lt;code&gt;to_tsvector()&lt;/code&gt;. That immediately adds a completely new layer to the “8 KB page” math I discussed earlier.&lt;/p&gt;
&lt;p&gt;Until now, my examples were based on small index keys like UUIDs.&lt;/p&gt;
&lt;p&gt;But full-text search is a different beast.&lt;/p&gt;
&lt;h3 id="why-full-text-search-becomes-heavy"&gt;Why Full-Text Search Becomes Heavy&lt;/h3&gt;
&lt;p&gt;A UUID is small:&lt;/p&gt;</description></item><item><title>Part 3 - Deep Dive: How Database Indexing Works (The B-Tree)</title><link>https://srajesh2712.github.io/posts/2026/04/05/part3-index-introduction/</link><pubDate>Sun, 05 Apr 2026 05:55:00 +0000</pubDate><guid>https://srajesh2712.github.io/posts/2026/04/05/part3-index-introduction/</guid><description>&lt;h2 id="16-visualizing-the-freed-up-space"&gt;16. Visualizing the &amp;ldquo;Freed Up&amp;rdquo; Space&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s visualize a row of pointers inside our 8 KB Page. By shrinking each &amp;ldquo;seat&amp;rdquo; from 8 bytes to 6 bytes, we allow the next pointer to start sooner.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scenario A: 8-byte Pointers&lt;/strong&gt;
&lt;code&gt;[Ptr 1: 8 bytes] [Ptr 2: 8 bytes] [Ptr 3: 8 bytes]&lt;/code&gt;
&lt;em&gt;Total used for 3 pointers: 24 bytes.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scenario B: 6-byte Pointers&lt;/strong&gt;
&lt;code&gt;[Ptr 1: 6 bytes] [Ptr 2: 6 bytes] [Ptr 3: 6 bytes] [Ptr 4: 6 bytes]&lt;/code&gt;
&lt;em&gt;Total used for 4 pointers: 24 bytes.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Part 2 - Deep Dive: How Database Indexing Works (The B-Tree)</title><link>https://srajesh2712.github.io/posts/2026/03/29/part2-index-introduction/</link><pubDate>Sun, 29 Mar 2026 05:55:00 +0000</pubDate><guid>https://srajesh2712.github.io/posts/2026/03/29/part2-index-introduction/</guid><description>&lt;h2 id="6-the-handshake-why-os-and-database-page-sizes-differ"&gt;6. The &amp;ldquo;Handshake&amp;rdquo;: Why OS and Database Page Sizes Differ&lt;/h2&gt;
&lt;p&gt;When you run &lt;code&gt;getconf PAGESIZE&lt;/code&gt; on Ubuntu, you see &lt;code&gt;4096&lt;/code&gt; (4 KB). Yet, your database often uses &lt;strong&gt;8 KB&lt;/strong&gt; or &lt;strong&gt;16 KB&lt;/strong&gt;. If the RAM can process data quickly, why is there this mismatch?&lt;/p&gt;
&lt;h3 id="the-generalist-ubuntu-vs-the-specialist-database"&gt;The Generalist (Ubuntu) vs. The Specialist (Database)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ubuntu (4 KB):&lt;/strong&gt; An Operating System is a generalist. It manages everything from tiny config files to massive videos. If the OS used 16 KB pages, a 1 KB text file would still take up 16 KB of RAM—wasting 94% of that space. 4 KB is the &amp;ldquo;Goldilocks&amp;rdquo; size for general computing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Database (8 KB+):&lt;/strong&gt; A database is a specialist. It knows its files are massive. By using a larger &lt;strong&gt;Logical Page&lt;/strong&gt;, it increases &lt;strong&gt;Fan-out&lt;/strong&gt; (the number of pointers per page). This keeps the B-Tree &amp;ldquo;short and fat&amp;rdquo; rather than &amp;ldquo;tall and skinny,&amp;rdquo; reducing the number of disk reads.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="how-they-sync"&gt;How They Sync&lt;/h3&gt;
&lt;p&gt;There is no &amp;ldquo;clash&amp;rdquo; because these sizes are multiples. When the Database asks for one 8 KB page, Ubuntu simply fetches &lt;strong&gt;two&lt;/strong&gt; 4 KB hardware blocks.&lt;/p&gt;</description></item><item><title>Part 1 - Deep Dive: How Database Indexing Works (The B-Tree)</title><link>https://srajesh2712.github.io/posts/2026/03/22/part1-index-introduction/</link><pubDate>Sun, 22 Mar 2026 05:55:00 +0000</pubDate><guid>https://srajesh2712.github.io/posts/2026/03/22/part1-index-introduction/</guid><description>&lt;h2 id="the-fundamental-problem-the-full-table-scan"&gt;The Fundamental Problem: The Full Table Scan&lt;/h2&gt;
&lt;p&gt;Imagine a table with 10 million rows. To find a specific ID without an index, the database must perform a &lt;strong&gt;Full Table Scan&lt;/strong&gt;—checking every single row from 1 to 10,000,000. This is $O(n)$ complexity.&lt;/p&gt;
&lt;p&gt;Indexing transforms this into a &amp;ldquo;search in a book&amp;rdquo; experience using a data structure called a &lt;strong&gt;B-Tree&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-what-is-an-index"&gt;1. What is an Index?&lt;/h2&gt;
&lt;p&gt;At its core, an index is a separate, sorted data structure that maps a specific value (like an ID or Name) to a &lt;strong&gt;Pointer&lt;/strong&gt; (the physical address of the row on disk).&lt;/p&gt;</description></item></channel></rss>