<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Aloksinghst on Medium]]></title>
        <description><![CDATA[Stories by Aloksinghst on Medium]]></description>
        <link>https://medium.com/@aloksingh1st?source=rss-b5baeb4818e9------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*gnf8TPYFONA-bcS_ip7muQ.jpeg</url>
            <title>Stories by Aloksinghst on Medium</title>
            <link>https://medium.com/@aloksingh1st?source=rss-b5baeb4818e9------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 10:35:56 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@aloksingh1st/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[From CRUD to Distributed Systems: Why I’m Building a Twitter Timeline Service]]></title>
            <link>https://medium.com/@aloksingh1st/from-crud-to-distributed-systems-why-im-building-a-twitter-timeline-service-516a74dd908f?source=rss-b5baeb4818e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/516a74dd908f</guid>
            <category><![CDATA[backend-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[design-systems]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[distributed-systems]]></category>
            <dc:creator><![CDATA[Aloksinghst]]></dc:creator>
            <pubDate>Mon, 27 Jul 2026 10:51:09 GMT</pubDate>
            <atom:updated>2026-07-27T11:05:28.654Z</atom:updated>
            <content:encoded><![CDATA[<p>When we first start learning backend development, we learn networking, APIs, databases, CRUD. We build applications that create, read, update, and delete data. Those projects teach us the fundamentals, and they’re an essential part of becoming a developer.</p><p>Then we look around.</p><p>WhatsApp delivers billions of messages. Netflix streams to millions of users. Twitter refreshes personalised timelines almost instantly.</p><p>These products don’t just work — they continue to work at scale. That isn’t luck. It’s engineering.</p><p>I spend my day job writing Laravel/PHP at a startup. This project is how I’m forcing myself to think in distributed systems — and I’m building it in the open, phase by phase, with a full write-up after each one.</p><h3>Why Backend Engineers Should Build Systems, Not Clones</h3><p>Two friends sketch a few screens, write some code, connect a database, and launch v1. Months later, millions of people use it every day.</p><p>Except that’s almost never how it happens.</p><p>Between the first line of code and the product we use today are years of failures, redesigns, bottlenecks, and thousands of engineering decisions. Systems that worked for a thousand users stopped working for a million. Databases were redesigned. New technologies were introduced — not because they were trendy, but because they solved real problems.</p><p>I think the same lesson applies to us as developers. There’s nothing wrong with building clones — they teach us what to build. Building systems teaches us why.</p><p>When something breaks, you’re forced to ask better questions. Why is this query slow? Should this run in the background? Do I really need a cache? Is this an application problem or a database problem? Over time, you stop copying architecture and start understanding it.</p><p>That’s the experience I’m after.</p><h3><strong>Why a Twitter Timeline?</strong></h3><p>On the surface, a timeline looks simple: you follow people, they post, you open the app and see their posts.</p><p>Behind that simple experience is one of the more interesting backend problems out there. Every user&#39;s timeline is different. New posts are constantly being created, users expect their feed to load instantly, and the system has to balance reads, writes, storage, and latency all at once.</p><p>A timeline isn&#39;t just:</p><p>sql</p><pre>SELECT * FROM posts;</pre><p>It&#39;s a distributed systems problem disguised as a social media feature. That&#39;s why I picked it — not for another Twitter clone, but because it naturally forces problems around database design, pagination, caching, background processing, and architectural trade-offs.</p><h3>One Rule Before Writing Any Code</h3><p>Before writing a single line, I made one promise to myself: don’t optimise before you measure.</p><p>It’s tempting to start every project with Redis, Kafka, and microservices because that’s what large companies use. But those companies didn’t start there — every piece of infrastructure was introduced because it solved a specific bottleneck. I want this project to follow the same philosophy: start with the simplest correct solution, and only add complexity once I understand exactly why it’s needed.</p><h3>The Series</h3><p>I’m building this in phases, and I’ll be writing up each one as it lands — architecture decisions, benchmarks, what broke, what I’d do differently.</p><p><strong>Phase 1 — Foundation.</strong> Users, follow relationships, posts, a timeline API, cursor pagination, and a baseline benchmark. The question here: how far can a well-designed PostgreSQL app go before you need anything else?</p><p><strong>Phase 2 — Scaling reads and writes.</strong> Redis, BullMQ, background workers, and the fan-out question: do you write to followers’ timelines when a post is made, or read and merge at request time?</p><p><strong>Phase 3 — Thinking like a distributed system.</strong> Hybrid timeline generation for high-follower accounts, cache invalidation, observability, load testing, and horizontal scaling — not because they’re buzzwords, but because the earlier phases will force them.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XCq-wx13TDXOUHOLIIhLbQ.png" /></figure><h3>Building in Public</h3><p>This isn’t a tutorial and it isn’t a finished project — it’s a build log. I’ll share the decisions, the mistakes, the trade-offs, and the benchmarks along the way. Some ideas will hold up under load. Some will look fine in testing and fall apart the moment real traffic hits — and those are usually the ones worth writing about.</p><p>If you’re curious what happens past CRUD, follow along — Part 1 (the foundation and first benchmarks) is coming next.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=516a74dd908f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[You Can’t console.log Your Way Out of a Distributed System]]></title>
            <link>https://medium.com/@aloksingh1st/you-cant-console-log-your-way-out-of-a-distributed-system-3d025f0939b9?source=rss-b5baeb4818e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/3d025f0939b9</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[system-design-interview]]></category>
            <category><![CDATA[observability]]></category>
            <category><![CDATA[distributed-systems]]></category>
            <category><![CDATA[backend-development]]></category>
            <dc:creator><![CDATA[Aloksinghst]]></dc:creator>
            <pubDate>Thu, 18 Jun 2026 03:43:03 GMT</pubDate>
            <atom:updated>2026-06-18T03:43:03.414Z</atom:updated>
            <content:encoded><![CDATA[<p>What DDIA Chapter 1 forced me to understand about partial failure — and why monitoring tools like Zipkin exist</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pcAn0d-jbKO9y8zuyZmtDQ.png" /><figcaption>Partial Failure</figcaption></figure><p>I’ve been building backends for two years. Laravel, Node.js, Redis, PostgreSQL — real production systems, real traffic. I thought I had a decent mental model of how things fail.</p><p>Then I opened <em>Designing Data-Intensive Applications,</em> and Chapter 1 quietly dismantled something I didn’t even know I assumed.</p><p><strong>The assumption I didn’t know I had</strong></p><p>On a single machine, failure is binary.</p><p>A process either runs or it crashes. A database is either up or it’s down. Your server either responds or it times out. You always <em>know</em> — even if what you know is bad news.</p><p>This assumption is so deeply baked in that we don’t even think about it. It shapes how we debug. It shapes how we write error handling. It shapes what we reach for when something goes wrong: logs, stack traces, <em>console.log</em>.</p><p>And it works. Until it doesn’t.</p><p><strong>Partial failure — the thing that breaks the mental mode</strong></p><p>Here’s the scenario DDIA introduced that stopped me cold:</p><blockquote><em>Node A is up. Node B is up. The network between them is silently dropping packets.</em></blockquote><p>No exception is thrown. No alert fires. Both nodes are healthy by every metric you’re watching. But your system is producing wrong results — or worse, inconsistent results — and you have no idea.</p><p>This is a <strong>partial failure</strong>. And it’s a fundamentally different class of problem than anything you encounter on a single machine.</p><p>On one server, failure is an event. In a distributed system, failure is a <em>state</em> — one that your system can be in without knowing it.</p><p><strong>Why this matters beyond theory</strong></p><p>The moment this clicked, I finally understood something that had always felt like over-engineering to me: observability tooling.</p><p>I knew what Zipkin and OpenTelemetry <em>were</em>. I’d seen them in job descriptions. I’d nodded along when senior engineers talked about distributed tracing. But I never deeply understood <em>why</em> they were necessary — not just useful, but necessary.</p><p>Now I do.</p><p>When your system is distributed, a single request touches multiple services. Service A calls Service B calls Service C. Any one of those hops can degrade silently. The request completes — maybe slowly, maybe with a subtle data inconsistency — but no single service logged an error.</p><p>You can’t reconstruct what happened from individual service logs. The failure lives <em>between</em> the services, not inside any of them.</p><p>That’s what distributed tracing solves. A trace ID propagates through every hop. Zipkin correlates the spans. OpenTelemetry standardises the instrumentation. You get a timeline of the entire request across every service boundary.</p><blockquote>You’re not debugging a process. You’re debugging a <em>conversation between processes</em>.</blockquote><p><strong>What does this change about how I think</strong></p><p>Before DDIA: I thought about failure as “something broke, find the error.”</p><p>After DDIA Chapter 1: I think about failure as “something might be degrading silently right now, and the only way to know is to have built the observability before you needed it.”</p><p>That’s a different engineering posture entirely. It means:</p><ul><li>You instrument before incidents, not after</li><li>You treat network calls as inherently unreliable, not just occasionally unreliable</li><li>You design for partial availability, not just uptime</li><li>You build tracing into your services because console.log only tells you what happened inside one box</li></ul><h3>Where I’m taking this</h3><p>I’m currently building HookRelay — a webhook delivery service — in TypeScript and PostgreSQL. Webhook delivery is inherently distributed: your server, the queue, the delivery worker, the client’s endpoint.</p><p>Partial failure is not a theoretical concern for me. It’s the default operating condition.</p><p>DDIA didn’t just teach me vocabulary. It gave me a framework to think about what I’m actually building. Chapter 1 alone reframed two years of production intuition.</p><p>I’m reading the rest of the book the same way: not to memorise concepts, but to find the next thing I was wrong about without knowing it.</p><p>Reading DDIA 2nd edition and writing about it as I go. If this resonated, follow along — one chapter at a time.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3d025f0939b9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding Synchronous and Asynchronous JavaScript with Analogies]]></title>
            <link>https://medium.com/@aloksingh1st/understanding-synchronous-and-asynchronous-javascript-with-analogies-434eb46030f9?source=rss-b5baeb4818e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/434eb46030f9</guid>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Aloksinghst]]></dc:creator>
            <pubDate>Wed, 23 Apr 2025 11:54:06 GMT</pubDate>
            <atom:updated>2025-04-23T11:54:06.664Z</atom:updated>
            <content:encoded><![CDATA[<p>JavaScript, being a single-threaded language, follows a unique execution model. Understanding the difference between <strong>synchronous</strong> and <strong>asynchronous</strong> code is essential for writing efficient and responsive programs.</p><p>Let’s break down these concepts through real-life analogies.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sP0LH8fCUMyeB9eH2J6KGQ.png" /></figure><h3>🧵 Synchronous JavaScript — The Queue Analogy</h3><p>Imagine you’re standing in a <strong>bank queue</strong>. Each customer (task) is served <strong>one at a time</strong>. No matter how small or big the task is, the next person in line <strong>must wait</strong> until the current one is fully served.</p><p>In the same way, <strong>synchronous JavaScript</strong> executes code <strong>line by line</strong>, one statement after another. If a line takes time (like reading a file or fetching data), it blocks everything else.</p><h3>Example:</h3><pre>console.log(&quot;1&quot;);<br>console.log(&quot;2&quot;);<br>console.log(&quot;3&quot;);</pre><p><strong>Output:</strong></p><pre>1<br>2<br>3</pre><p>Each line runs in order. No skipping. No multitasking.</p><h3>⏳ The Problem with Synchronous Code</h3><p>Now imagine one customer in the queue is filling out a <strong>loan application</strong> that takes 10 minutes. Everyone behind them is stuck doing nothing.</p><p>That’s exactly the issue with synchronous JavaScript. If a task takes time (like downloading a file), everything else has to <strong>wait</strong>.</p><h3>🎭 Asynchronous JavaScript — The Restaurant Analogy</h3><p>Now imagine you’re at a restaurant. You place an order (a task), and the waiter (JavaScript engine) <strong>takes your request</strong> but doesn’t make you wait. Instead, you go back to your table and continue chatting (doing other tasks).</p><p>When your food is ready (task is done), the waiter comes back and serves it. That’s <strong>asynchronous behavior</strong>.</p><p>In JavaScript, you can use <strong>callbacks</strong>, <strong>promises</strong>, or <strong>async/await</strong> to tell the engine:<br><strong>“Go do this, and when you’re done, let me know.”</strong></p><h3>Example with setTimeout:</h3><pre>console.log(&quot;1&quot;);</pre><pre>setTimeout(() =&gt; {<br>  console.log(&quot;2&quot;);<br>}, 2000); // 2-second delay</pre><pre>console.log(&quot;3&quot;);</pre><p><strong>Output:</strong></p><pre>1<br>3<br>2</pre><p>Even though console.log(&quot;2&quot;) appears earlier in the code, it runs <strong>later</strong> because JavaScript continues without waiting for the 2-second timer.</p><h3>🧠 What’s Really Happening Behind the Scenes?</h3><p>JavaScript uses something called the <strong>Event Loop</strong> and a <strong>Task Queue</strong> to manage asynchronous tasks.</p><ul><li>Think of the <strong>Call Stack</strong> as the chef preparing food orders.</li><li>The <strong>Task Queue</strong> is like a counter where finished dishes (callbacks) are placed.</li><li>The <strong>Event Loop</strong> keeps checking: “Is the chef (call stack) free?” If yes, it grabs the next ready dish (task) from the counter (queue) and serves it.</li></ul><h3>📦 Promises — The Amazon Analogy</h3><p>Think of a <strong>Promise</strong> like ordering a product from Amazon.</p><ul><li><strong>Pending:</strong> You placed the order.</li><li><strong>Fulfilled:</strong> The product is delivered.</li><li><strong>Rejected:</strong> The order failed.</li></ul><p>While you’re waiting for the delivery, you can do other things. When the delivery arrives, you get notified (via .then() or await).</p><h3>Example:</h3><pre>fetch(&#39;https://api.example.com/data&#39;)<br>  .then(response =&gt; response.json())<br>  .then(data =&gt; console.log(data));</pre><p>The request is sent, JavaScript moves on, and when the data is ready, it processes it.</p><h3>🧘‍♂️ Async/Await — The Netflix Analogy</h3><p>With async/awaitYour code <strong>looks synchronous</strong> but behaves asynchronously.</p><p>Imagine binge-watching a Netflix series. You watch one episode, wait for it to finish, then go to the next. You’re still watching at your pace, but <strong>each episode “awaits” the end of the previous one</strong>.</p><h3>Example:</h3><pre>async function getData() {<br>  const response = await fetch(&#39;https://api.example.com/data&#39;);<br>  const data = await response.json();<br>  console.log(data);<br>}</pre><pre>getData();</pre><p>It’s easier to read and understand than chaining .then() calls, but under the hood, it’s still non-blocking.</p><h3>📏 Conclusion</h3><p>Features: Synchronous, Asynchronous, Blocking, Yes, No. Execution: One at a time, can skip and come back later. Example Analogy Bank queue Restaurant or Amazon delivery JavaScript Tools Default behaviorsetTimeout, Promises, async/await</p><p>Understanding the difference helps you write <strong>faster, non-blocking code</strong> — a must for modern web apps. Just remember:</p><blockquote><strong><em>“Let JavaScript take the order, but don’t force it to cook before serving the next customer!”</em></strong></blockquote><h3>🎥 Bonus Learning Resource</h3><p>For a more detailed explanation, you can check out the beautifully explained video:<br><a href="https://www.youtube.com/watch?v=fFd8OhrHfIM&amp;list=PLinedj3B30sDi0keEOQU3n5p3Op28eN2e&amp;index=3">Understanding Sync vs Async JavaScript</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=434eb46030f9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding JavaScript Array Methods: some, every, find, includes, and forEach with Analogies]]></title>
            <link>https://medium.com/@aloksingh1st/understanding-javascript-array-methods-some-every-find-includes-and-foreach-with-analogies-345a6701a713?source=rss-b5baeb4818e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/345a6701a713</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[arrays]]></category>
            <category><![CDATA[array-methods]]></category>
            <category><![CDATA[javascrıpt]]></category>
            <dc:creator><![CDATA[Aloksinghst]]></dc:creator>
            <pubDate>Tue, 18 Feb 2025 02:47:01 GMT</pubDate>
            <atom:updated>2025-02-18T02:47:01.926Z</atom:updated>
            <content:encoded><![CDATA[<p>JavaScript provides several powerful array methods that help in searching, filtering, and iterating over data. However, beginners often get confused about their usage. To make them easy to understand, let’s explore them with relatable Indian analogies.</p><h3>1. .some(): &quot;Koi toh hoga!&quot; (At least one should match)</h3><p>Imagine a group of friends discussing where to eat. One person suggests a pure vegetarian restaurant. The question is:<br><em>“Is there at least one person in the group who prefers vegetarian food?”</em></p><p>Using .some(), we check if at least one person meets the conditions:</p><p>Copy</p><p>Copy</p><pre>javascriptCopyEditlet friends = [&quot;Rohan&quot;, &quot;Amit&quot;, &quot;Pooja&quot;, &quot;Neha&quot;];<br>let prefersVegetarian = name =&gt; name === &quot;Pooja&quot;; </pre><pre>console.log(friends.some(prefersVegetarian)); // true</pre><p>In an Indian context, it’s like checking if at least one person in a family is a cricket fan during IPL season. If even one person watches, the TV is tuned to cricket!</p><h3>2. .every(): &quot;Sabko pasand hona chahiye!&quot; (Everyone should match)</h3><p>Imagine a family trip to Kedarnath. The trip will happen only if everyone in the family agrees to go.</p><p>Let’s check if all members are interested:</p><p>Copy</p><p>Copy</p><pre>javascriptCopyEditlet family = [&quot;Papa&quot;, &quot;Mummy&quot;, &quot;Bhaiya&quot;, &quot;Didi&quot;];<br>let wantsToVisitKedarnath = name =&gt; name !== &quot;Bhaiya&quot;; </pre><pre>console.log(family.every(wantsToVisitKedarnath)); // false</pre><p>Here, if even one person (Bhaiya) disagrees, the whole trip gets canceled!</p><h3>3. .find(): &quot;Ek hi banda chahiye!&quot; (Find the first matching element)</h3><p>Imagine searching for a chaiwala in a railway station. You don’t need all chaiwalas, just one to get your tea.</p><p>Copy</p><p>Copy</p><pre>javascriptCopyEditlet vendors = [<br>    { name: &quot;Raju&quot;, sells: &quot;Pani&quot; },<br>    { name: &quot;Amit&quot;, sells: &quot;Chai&quot; },<br>    { name: &quot;Vikas&quot;, sells: &quot;Samosa&quot; }<br>];</pre><pre>let chaiwala = vendors.find(vendor =&gt; vendor.sells === &quot;Chai&quot;);</pre><pre>console.log(chaiwala); // { name: &quot;Amit&quot;, sells: &quot;Chai&quot; }</pre><p>This returns Amit, as he is the first chaiwala found.</p><h3>4. .includes(): &quot;List mein hai ya nahi?&quot; (Check if an item exists)</h3><p>Imagine you are making Aloo Paratha but aren’t sure if you have ajwain (carom seeds) in your kitchen. Instead of checking each item manually, .includes() helps:</p><p>Copy</p><p>Copy</p><pre>javascriptCopyEditlet spices = [&quot;Haldi&quot;, &quot;Jeera&quot;, &quot;Dhaniya&quot;, &quot;Ajwain&quot;];<br>console.log(spices.includes(&quot;Ajwain&quot;)); // true<br>console.log(spices.includes(&quot;Elaichi&quot;)); // false</pre><p>This is just like checking if Amitabh Bachchan is in a Bollywood movie cast — if yes, it’s an instant hit! 🎬</p><h3>5. .forEach(): &quot;Sabke liye chai banao!&quot; (Perform an action for every element)</h3><p>Imagine a Halwai (sweet shop owner) preparing Laddoos for Diwali. He needs to apply silver foil (chandi ka warq) to each laddoo. Instead of doing it manually, .forEach() automates the task:</p><p>Copy</p><p>Copy</p><pre>javascriptCopyEditlet laddoos = [&quot;Besan&quot;, &quot;Motichoor&quot;, &quot;Coconut&quot;];</pre><pre>laddoos.forEach(laddoo =&gt; console.log(`Applying silver foil on ${laddoo} laddoo`));</pre><pre>// Applying silver foil on Besan laddoo<br>// Applying silver foil on Motichoor laddoo<br>// Applying silver foil on Coconut laddoo</pre><p>This ensures that every laddoo gets special treatment. Similarly, .forEach() is useful when performing actions on each element in an array.</p><h3>Conclusion</h3><p>These array methods can be powerful when used correctly:</p><p>MethodMeaning in the ContextUse Case.some()<em>At least one</em> cricket fanDoes at least one element satisfy the condition?.every()<em>Everyone</em> must agree to the Kedarnath tripDo all elements meet the condition?.find()Finding the <em>first</em> chaiwalaGet the first element that matches.includes()Checking if ajwain is in the kitchenDoes an item exist in the array?.forEach()Applying foil to <em>every</em> laddooExecute a function for every element</p><p>By associating these methods with relatable Indian scenarios, learning them becomes easier and more enjoyable! 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=345a6701a713" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding Map, Reduce, and Filter in JavaScript with Analogies]]></title>
            <link>https://medium.com/@aloksingh1st/understanding-map-reduce-and-filter-in-javascript-with-analogies-7425f378769d?source=rss-b5baeb4818e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/7425f378769d</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[arrays]]></category>
            <dc:creator><![CDATA[Aloksinghst]]></dc:creator>
            <pubDate>Sat, 15 Feb 2025 09:52:02 GMT</pubDate>
            <atom:updated>2025-02-15T09:52:02.107Z</atom:updated>
            <content:encoded><![CDATA[<p>JavaScript provides powerful array methods like map, reduce, and filter, which helps in transforming and processing data efficiently. To make these concepts easier to understand, let&#39;s relate them to real-life Indian scenarios.</p><h3>1. map(): Transforming Every Element</h3><h3>Analogy: Preparing Masala Chai from Tea Leaves</h3><p>Imagine running a tea stall (chai tapri) and having a batch of tea leaves. You aim to convert all these raw tea leaves into a masala chai.</p><ul><li>The input: Tea leaves</li><li>The transformation: Boiling them with milk, sugar, and spices</li><li>The output: A delicious cup of masala chai for each tea leaf batch</li></ul><p>In JavaScript, map works similarly—it takes each item in an array, transforms it, and returns a new array.</p><pre>const teaLeaves = [&quot;Assam&quot;, &quot;Darjeeling&quot;, &quot;Masala&quot;, &quot;Green&quot;];<br>const masalaChai = teaLeaves.map(leaf =&gt; leaf + &quot; Chai&quot;);</pre><pre>console.log(masalaChai);</pre><pre>// Output: [&quot;Assam Chai&quot;, &quot;Darjeeling Chai&quot;, &quot;Masala Chai&quot;, &quot;Green Chai&quot;]</pre><p>Each tea leaf is transformed into a flavored chai, just like map() applies a function to each element in an array.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*N7sIihHJk1V_GFGm.png" /></figure><h3>2. filter(): Selecting What Matters</h3><h3>Analogy: Picking the Freshest Mangoes from a Market</h3><p>In a mango market, a vendor has a pile of mangoes, but not all are good for sale. The vendor picks only the ripest mangoes to sell.</p><ul><li>The input: A pile of mangoes</li><li>The condition: Only ripe mangoes are selected</li><li>The output: A new pile of ripe mangoes</li></ul><p>In JavaScript, filter is used to create a new array containing only elements that meet a certain condition.</p><pre>const mangoes = [<br>  { name: &quot;Alphonso&quot;, ripe: true },<br>  { name: &quot;Dasheri&quot;, ripe: false },<br>  { name: &quot;Langda&quot;, ripe: true },<br>  { name: &quot;Totapuri&quot;, ripe: false }<br>];</pre><pre>const ripeMangoes = mangoes.filter(mango =&gt; mango.ripe);<br>console.log(ripeMangoes);<br>// Output: [{ name: &quot;Alphonso&quot;, ripe: true }, { name: &quot;Langda&quot;, ripe: true }]</pre><p>Just like a vendor picks only the best mangoes, filter() selects only elements that satisfy a condition.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1009/0*5r6e5kq8ccY3W1pb.png" /></figure><h3>3. reduce(): Summarizing Data</h3><h3>Analogy: Collecting Donations for a Temple Festival</h3><p>Suppose a temple committee is collecting donations from people for an annual festival. Each person contributes some amount, and in the end, the total sum needs to be calculated.</p><ul><li>The input: Individual donations</li><li>The operation: Adding all the donations together</li><li>The output: Total donation amount</li></ul><p>In JavaScript, reduce helps in accumulating values into a single result.</p><pre>const donations = [100, 500, 250, 150, 1000];<br>const totalDonation = donations.reduce((sum, amount) =&gt; sum + amount, 0);<br>console.log(totalDonation);<br>// Output: 2000</pre><p>Just like the committee collects donations from individuals and sums them up, reduce() accumulates array values into a single output.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*gLt0Qj5Wq-IjCF1c.png" /></figure><h3>Conclusion</h3><p>Each of these methods plays a unique role in JavaScript:</p><ul><li>map() transforms elements (like making chai from tea leaves).</li><li>filter() selects elements based on a condition (like choosing ripe mangoes).</li><li>reduce() combines elements into a single value (like totaling donations).</li></ul><p>These functions make JavaScript arrays more powerful and help write cleaner, more efficient code. Next time you use map, filter, or reduce, just think about chai, mangoes, and temple donations!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7425f378769d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Stack Implementation using Linked List]]></title>
            <link>https://medium.com/@aloksingh1st/stack-implementation-using-linked-list-665a4f4dae69?source=rss-b5baeb4818e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/665a4f4dae69</guid>
            <category><![CDATA[data-structure-algorithm]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[computer-science]]></category>
            <dc:creator><![CDATA[Aloksinghst]]></dc:creator>
            <pubDate>Mon, 09 Dec 2024 02:19:58 GMT</pubDate>
            <atom:updated>2024-12-09T02:19:58.556Z</atom:updated>
            <content:encoded><![CDATA[<p>When It comes to data structure and alogirithms, stack is one of important data structure.Stack follow the <strong>LIFO</strong> (Last In, First Out) principle, where the last element added to the stack is the first one to be removed. While arrays are commonly used to implement stacks, using a <strong>Linked List</strong> provides dynamic memory allocation and avoids the fixed-size constraint of arrays.</p><p>In this article, I’ll walk you through how to implement a Stack using a Linked List in C++.</p><h3>Why Use a Linked List for a Stack?</h3><ul><li><strong>Dynamic Size</strong>: Unlike arrays, linked lists allow stacks to grow or shrink dynamically.</li><li><strong>Memory Efficiency</strong>: No need to allocate extra memory upfront; each element is created only when needed.</li><li><strong>No Size Limit</strong>: You don’t have to worry about exceeding a predefined capacity.</li></ul><h3>Operations on a Stack</h3><p>A stack supports three primary operations:</p><ol><li><strong>Push</strong>: Add an element to the top of the stack.</li><li><strong>Pop</strong>: Remove and return the top element from the stack.</li><li><strong>Peek (or Top)</strong>: View the top element without removing it.</li><li><strong>isEmpty</strong>: Check if the stack is empty.</li></ol><h3>Linked List Structure</h3><p>To implement a stack using a linked list:</p><ol><li>Each node in the linked list represents an element of the stack.</li><li>The head of the linked list acts as the <strong>top</strong> of the stack.</li></ol><p><strong>C++ Code Implementation:</strong></p><pre>#include &lt;iostream&gt;<br>using namespace std;<br>// Node structure for the linked list<br>struct Node {<br> int data;<br> Node* next;<br>};<br>// Stack class<br>class Stack {<br>private:<br> Node* top; // Pointer to the top of the stack<br>public:<br> // Constructor<br> Stack() {<br> top = nullptr;<br> }<br>// Push an element onto the stack<br> void push(int value) {<br> Node* newNode = new Node();<br> newNode-&gt;data = value;<br> newNode-&gt;next = top;<br> top = newNode;<br> cout &lt;&lt; &quot;Pushed &quot; &lt;&lt; value &lt;&lt; &quot; onto the stack.\n&quot;;<br> }<br>// Pop the top element from the stack<br> int pop() {<br> if (isEmpty()) {<br> cout &lt;&lt; &quot;Stack underflow! Cannot pop from an empty stack.\n&quot;;<br> return -1; // Return an invalid value to indicate error<br> }<br>int poppedValue = top-&gt;data;<br> Node* temp = top;<br> top = top-&gt;next;<br> delete temp;<br> return poppedValue;<br> }<br>// Peek at the top element without removing it<br> int peek() {<br> if (isEmpty()) {<br> cout &lt;&lt; &quot;Stack is empty! No top element.\n&quot;;<br> return -1; // Return an invalid value to indicate error<br> }<br>return top-&gt;data;<br> }<br>// Check if the stack is empty<br> bool isEmpty() {<br> return top == nullptr;<br> }<br>// Destructor to free memory<br> ~Stack() {<br> while (!isEmpty()) {<br> pop();<br> }<br> }<br>};</pre><h3>How It Works</h3><p>Let’s break down each function:</p><ol><li><strong>push</strong>:</li></ol><ul><li>Creates a new Node with the given value.</li><li>Updates the next pointer of the new node to point to the current top.</li><li>Sets the new node as the new top.</li></ul><ol><li><strong>pop</strong>:</li></ol><ul><li>Checks if the stack is empty.</li><li>Stores the value of the current top node.</li><li>Moves the top pointer to the next node.</li><li>Deletes the old top node and returns the stored value.</li></ul><ol><li><strong>peek</strong>:</li></ol><ul><li>Simply returns the value of the top node without removing it.</li></ul><ol><li><strong>isEmpty</strong>:</li></ol><ul><li>Checks if the top pointer is nullptr.</li></ul><h3>Time and Space Complexity</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JGfe53MZuWGpuUdumONCxw.png" /></figure><p>The space complexity for the entire stack depends on the number of elements and is O(n), where n is the number of nodes in the linked list.</p><h3>Advantages of Linked List-Based Stack</h3><ul><li>No need for a predefined size.</li><li>Dynamically grows as needed.</li></ul><h3>Disadvantages</h3><ul><li>Slightly more memory usage compared to arrays due to pointer storage.</li><li>Requires additional pointer management.</li></ul><h3>Conclusion</h3><p>Using a linked list to implement a stack provides flexibility and dynamic memory management, making it an excellent choice in situations where the size of the stack cannot be determined beforehand. While arrays might be simpler, linked lists offer greater scalability for larger applications.</p><p>Now you can implement your stack using linked lists and explore its potential in your projects! 🚀</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3n4XHJVeHfI-oI9-a7K_3w.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=665a4f4dae69" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Practical DSA: Breaking Down the Intuition vs. Implementation Struggle]]></title>
            <link>https://medium.com/@aloksingh1st/practical-dsa-breaking-down-the-intuition-vs-implementation-struggle-b974d66d45a2?source=rss-b5baeb4818e9------2</link>
            <guid isPermaLink="false">https://medium.com/p/b974d66d45a2</guid>
            <category><![CDATA[dsa-training]]></category>
            <category><![CDATA[data-structure-algorithm]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[dsa-courses]]></category>
            <category><![CDATA[engineering]]></category>
            <dc:creator><![CDATA[Aloksinghst]]></dc:creator>
            <pubDate>Mon, 07 Oct 2024 15:04:06 GMT</pubDate>
            <atom:updated>2024-10-07T15:04:06.705Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AlY9p7c9wr-qCshhv50EVQ.png" /></figure><p>In the world of competitive programming and technical interviews, Data Structures and Algorithms (DSA) are essential skills to master. While many of us can grasp the intuition behind a problem, translating that understanding into working code often feels like a completely different battle, especially in a language like C++. This gap between intuition and implementation can be frustrating, but with the right mindset and strategies, it’s possible to bridge it. In this article, I’ll break down why this gap exists and offer actionable techniques to help you improve your implementation skills.</p><h4>The Intuition-Implementation Gap: Why Does It Happen?</h4><p>Understanding a problem, also called “intuition,” involves recognizing patterns, choosing the right data structure, and coming up with a high-level approach to solve it. You might even be able to visualize how the solution works in theory. However, once you sit down to write the code, things might fall apart. Here’s why:</p><ul><li><strong>Over-simplification in Understanding</strong>: When we think about a problem abstractly, we often skip over the intricate details, such as edge cases, corner scenarios, or the actual mechanics of working with data structures.</li><li><strong>Lack of Familiarity with the Language</strong>: For those working in C++, understanding the problem is one thing, but knowing how to manipulate pointers, use STL containers effectively, or manage memory efficiently can be challenging. C++ is powerful but requires careful handling.</li><li><strong>Unrefined Coding Habits</strong>: Even with the right idea, poor habits like skipping planning, writing unstructured code, or neglecting to break the problem down into smaller tasks can derail your progress.</li><li><strong>Anxiety or Overthinking</strong>: Sometimes, knowing the solution in theory but not being able to implement it correctly can lead to self-doubt or over-complicating the problem, making the task feel overwhelming.</li><li><strong>The “I’ll Figure It Out” Trap</strong>: Often, we dive into coding without a concrete plan, assuming that we’ll figure out edge cases as we go. This leads to getting stuck midway through the implementation, causing frustration and time wastage.</li></ul><p>Now that we know why this happens, let’s focus on bridging the gap.</p><h4>Techniques for Improving Implementation Skills</h4><ol><li><strong>Break Down the Problem Into Sub-Problems:</strong></li></ol><p>One of the key steps to move from intuition to implementation is to decompose the problem into smaller, more manageable tasks. For example, if you’re working on a linked list problem, start by outlining the major steps like:</p><ul><li>Iterating through the linked list.</li><li>Identifying when a condition is met (e.g., detecting a loop).</li><li>Applying the solution logic (e.g., reversing part of the list).</li></ul><p>Write pseudocode for each part before jumping into C++ code. This will help you keep track of what you need to implement without getting lost in the details.</p><h4>3. Learn to Identify Edge Cases Early</h4><p>One common reason for implementation struggles is overlooking edge cases until you start writing code. To fix this:</p><ul><li><strong>Analyze the problem deeply</strong>: Before writing the solution, list potential edge cases — empty inputs, large inputs, negative values, etc.</li><li><strong>Implement small checks</strong>: In C++, be cautious about handling these edge cases, especially when dealing with arrays or pointers. Write conditional checks early in your code to ensure you’re not accessing invalid memory or exceeding array bounds.</li></ul><p>For example, when working with a linked list, always check if the head is null before proceeding.</p><h4>4. Work Incrementally: Test as You Go</h4><p>Instead of writing the entire solution and then running into a wall of bugs, break your code into chunks and test each chunk as you go:</p><ul><li><strong>Write functions for individual tasks</strong>: Break down complex problems into smaller, manageable functions. In C++, separating your code into helper functions also makes debugging easier.</li><li><strong>Run simple test cases first</strong>: Don’t wait until the full implementation is done to run tests. Test simple cases (like the smallest input) and work your way up to more complex cases.</li></ul><p>This approach helps you isolate issues and correct them without getting overwhelmed by multiple bugs at once.</p><h4>5. Practice, Reflect, and Reimplement</h4><p>You won’t bridge the gap by solving a problem once and moving on. Instead:</p><ul><li><strong>Revisit old problems</strong>: Go back to problems you’ve already solved and try to re-implement them from scratch. Doing this repeatedly helps you internalize patterns and techniques.</li><li><strong>Analyze others’ solutions</strong>: After solving a problem, review other solutions in C++. You might discover more efficient or cleaner ways to implement the same logic.</li><li><strong>Reflect on your mistakes</strong>: Keep a log of the errors and challenges you faced, especially in C++ (e.g., memory management issues or infinite loops). Reflecting on these will help you avoid repeating the same mistakes.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b974d66d45a2" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>