<?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: Shalini Goyall</title>
    <description>The latest articles on DEV Community by Shalini Goyall (@shalini_goyall_01f98891cf).</description>
    <link>https://dev.to/shalini_goyall_01f98891cf</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%2F3690462%2F7324c551-403f-459f-b52b-3beaf391af71.png</url>
      <title>DEV Community: Shalini Goyall</title>
      <link>https://dev.to/shalini_goyall_01f98891cf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shalini_goyall_01f98891cf"/>
    <language>en</language>
    <item>
      <title>Dynamic Programming</title>
      <dc:creator>Shalini Goyall</dc:creator>
      <pubDate>Wed, 07 Jan 2026 10:12:29 +0000</pubDate>
      <link>https://dev.to/shalini_goyall_01f98891cf/dynamic-programming-27if</link>
      <guid>https://dev.to/shalini_goyall_01f98891cf/dynamic-programming-27if</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%2Fkk2tmnpwzxu9o8i737m4.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%2Fkk2tmnpwzxu9o8i737m4.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sample Code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dp = [0] * (W + 1)
for weight in weights:
    for w in range(W, weight - 1, -1):
        dp[w] = max(dp[w], dp[w - weight] + value)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;tutorial video :  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=kvyShbFVaY8" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=kvyShbFVaY8&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Easy (Knapsack Basics)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://leetcode.com/problems/partition-equal-subset-sum/" rel="noopener noreferrer"&gt;416. Partition Equal Subset Sum&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://leetcode.com/problems/target-sum/" rel="noopener noreferrer"&gt;494. Target Sum&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://leetcode.com/problems/last-stone-weight-ii/" rel="noopener noreferrer"&gt;1049. Last Stone Weight II&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Medium (Classic 0/1 Knapsack)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://leetcode.com/problems/ones-and-zeroes/" rel="noopener noreferrer"&gt;474. Ones and Zeroes&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://leetcode.com/problems/coin-change/" rel="noopener noreferrer"&gt;322. Coin Change (0/1 variant when restricted)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://leetcode.com/problems/coin-change-ii/" rel="noopener noreferrer"&gt;518. Coin Change II&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://leetcode.com/problems/profitable-schemes/" rel="noopener noreferrer"&gt;879. Profitable Schemes&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>System Design : Calendar App</title>
      <dc:creator>Shalini Goyall</dc:creator>
      <pubDate>Tue, 06 Jan 2026 20:41:05 +0000</pubDate>
      <link>https://dev.to/shalini_goyall_01f98891cf/system-design-calendar-app-1lii</link>
      <guid>https://dev.to/shalini_goyall_01f98891cf/system-design-calendar-app-1lii</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%2Fw8jexkxge1ymvm69udjs.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%2Fw8jexkxge1ymvm69udjs.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Functional Requirement&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create event , modify event , cancel event&lt;/li&gt;
&lt;li&gt;user should be able to view calendar daily , weekly or yearly&lt;/li&gt;
&lt;li&gt;user should be able to set tup recurring meeting&lt;/li&gt;
&lt;li&gt;send notification for any change via email. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Non functional requirement&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High availability &amp;gt;&amp;gt; consistency ( eventaul consitency for syncing events)&lt;/li&gt;
&lt;li&gt;should support 1B User&lt;/li&gt;
&lt;li&gt;low latency to view calendar.&lt;/li&gt;
&lt;li&gt;read &amp;gt;&amp;gt; write&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Models&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User&lt;/li&gt;
&lt;li&gt;event &lt;/li&gt;
&lt;li&gt;Recurrence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;APIs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;POST /events/
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
   title 
   userId ( creator)
   userIds []
   start time
   end time
   json blob content - &amp;gt; video call link , description
   - recurrence schedule &amp;gt; weekly , biweekly , monhtly or yearly
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;GET / events/startDay=?&amp;amp;&amp;amp;endDay=?
return -&amp;gt; List of events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;High Level Design&lt;/strong&gt;&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%2Fzu2k0yfefnwjzgc0cs4y.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%2Fzu2k0yfefnwjzgc0cs4y.png" alt=" " width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deep Dives&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. How to store data into DB for daily or recurring events. Explain it with example.&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Event Creation &amp;amp; Storage &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Case 1: Simple (One-Time) Event&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Doctor Appointment&lt;/strong&gt;&lt;br&gt;
Jan 10, 3:00–4:00 PM (UTC)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;events&lt;/code&gt; table (single row)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| event_id | owner_id | title              | start_time_utc   | end_time_utc     | rrule | tz  | version |
| -------- | -------- | ------------------ | ---------------- | ---------------- | ----- | --- | ------- |
| evt_101  | user_1   | Doctor Appointment | 2025-01-10 15:00 | 2025-01-10 16:00 | NULL  | UTC | 1       |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GET Behavior
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Row is returned&lt;/li&gt;
&lt;li&gt;Rendered directly&lt;/li&gt;
&lt;li&gt;No expansion needed&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Case 2: Recurring Event (Weekly)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Team Sync&lt;/strong&gt;&lt;br&gt;
Every Monday, 10–11 AM&lt;br&gt;
Starting Jan 6, 2025&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`events` table (still ONE row)

| event_id | owner_id | title     | start_time_utc   | end_time_utc     | rrule                | tz  | version |
| -------- | -------- | --------- | ---------------- | ---------------- | -------------------- | --- | ------- |
| evt_201  | user_1   | Team Sync | 2025-01-06 10:00 | 2025-01-06 11:00 | FREQ=WEEKLY;BYDAY=MO | UTC | 1       |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GET Behavior (Week View)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetch base row&lt;/li&gt;
&lt;li&gt;Expand rule &lt;strong&gt;only for requested range&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Generate occurrences in memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Case 3: Recurring Event with Exception (One Cancellation)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Team Sync&lt;/strong&gt;&lt;br&gt;
Cancelled only on &lt;strong&gt;Jan 20&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;event_exceptions` table

| exception_id | event_id | exception_date | type      |
| ------------ | -------- | -------------- | --------- |
| ex_301       | evt_201  | 2025-01-20     | CANCELLED |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GET Behavior (Week of Jan 20)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Expand weekly rule → Jan 20 occurrence&lt;/li&gt;
&lt;li&gt;Match exception → drop occurrence&lt;/li&gt;
&lt;li&gt;Return remaining events&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Why This Storage Model Scales
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Rows Stored&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;One-time event&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weekly for years&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weekly + N exceptions&lt;/td&gt;
&lt;td&gt;1 + N&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;✅ Minimal storage&lt;br&gt;
✅ Fast queries&lt;br&gt;
✅ No occurrence explosion&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. View generation and low latency&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;User flow : &lt;br&gt;
    - Client fetch data from server.&lt;br&gt;
    - Server fetch data from DB.&lt;br&gt;
    - Server expands events for a time range&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server send list of events to client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Optimisation for low latency to get result&lt;/strong&gt; : &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Redis cache&lt;/strong&gt; : Server can push the events to Redis. When user    wants to see the events in couple of hours, it made request to   server. server first look into redis and serve. If events are not present , then server made call to DB, fetch events from DB and push to client and redis. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pros : &lt;br&gt;
    - Simple client - no extra logic on client side.&lt;br&gt;
    - Consistent shared views&lt;/p&gt;

&lt;p&gt;Cons&lt;br&gt;
    - Redis explosion at scale&lt;br&gt;
    - Hard cache invalidation&lt;br&gt;
    - Per-user views don’t reuse well&lt;br&gt;
    - Expensive at 1B users &lt;/p&gt;

&lt;p&gt;Conclusion:&lt;br&gt;
    ❌ Not ideal for massive scale.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Client side expansion + SQLite (Hybrid)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;User Flow &lt;br&gt;
    - User made request to Server.&lt;br&gt;
    - Server sends events rules , exceptions to client.&lt;br&gt;
    - Client expands events to multiple events&lt;br&gt;
    - Client saves occurrences into SQL lite DB.&lt;/p&gt;

&lt;p&gt;Pros&lt;br&gt;
    - Extremely fast UI&lt;br&gt;
    - Offline support&lt;br&gt;
    - No server-side expanded cache&lt;br&gt;
    - Scales naturally with users&lt;/p&gt;

&lt;p&gt;Cons&lt;br&gt;
    - More complex client&lt;br&gt;
    - Server must manage sync carefully&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;br&gt;
   ✅ Preferred at very large scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Conflict Detection and Locking Strategy&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Optimistic Locking (Default)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;low contention&lt;/li&gt;
&lt;li&gt;best of personal calendar&lt;/li&gt;
&lt;li&gt;retry logic should be there in service.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Pessimistic Locking&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High contention calendars to avoid race condition.&lt;/li&gt;
&lt;li&gt;Lock many rows.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Multi-Device Sync ( push and pull)&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pull (Delta Sync)
Used for:

&lt;ul&gt;
&lt;li&gt;Cold start&lt;/li&gt;
&lt;li&gt;Reconnect&lt;/li&gt;
&lt;li&gt;Missed updates&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Push (SSE / Push Notifications)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetches updated rule&lt;/li&gt;
&lt;li&gt;Re-expands locally&lt;/li&gt;
&lt;li&gt;Updates SQLite + UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SSE preferred:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-way&lt;/li&gt;
&lt;li&gt;Lightweight&lt;/li&gt;
&lt;li&gt;Battery friendly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hybrid model -&amp;gt; Push for freshness, pull for correctness.&lt;/p&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Database Choice: SQL vs NoSQL&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Why SQL works well:&lt;br&gt;
    - Strong consistency&lt;br&gt;
    - Transactions&lt;br&gt;
    - Overlap queries&lt;br&gt;
    - Recurrence rules stored efficiently&lt;/p&gt;

&lt;p&gt;This is not write-heavy, so SQL scales well.&lt;/p&gt;

&lt;p&gt;No SQL tradeoffs&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Conflict checks&lt;/td&gt;
&lt;td&gt;Hard without transactions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recurrence queries&lt;/td&gt;
&lt;td&gt;Poor fit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consistency&lt;/td&gt;
&lt;td&gt;Eventual by default.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity&lt;/td&gt;
&lt;td&gt;Higher for correctness&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>systemdesign</category>
      <category>interview</category>
      <category>softwareengineering</category>
      <category>calendar</category>
    </item>
  </channel>
</rss>
