<?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: Bhushan Rane</title>
    <description>The latest articles on Forem by Bhushan Rane (@bhushands).</description>
    <link>https://forem.com/bhushands</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%2F1271332%2F48aa2e82-783a-4779-acb6-59dcb79d8136.jpeg</url>
      <title>Forem: Bhushan Rane</title>
      <link>https://forem.com/bhushands</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bhushands"/>
    <language>en</language>
    <item>
      <title>System Design Concepts - 1</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Thu, 15 Feb 2024 14:25:36 +0000</pubDate>
      <link>https://forem.com/bhushands/system-design-concepts-1-37c4</link>
      <guid>https://forem.com/bhushands/system-design-concepts-1-37c4</guid>
      <description>&lt;h1&gt;
  
  
  System Design Concepts - 1
&lt;/h1&gt;

&lt;h6&gt;
  
  
  Here we will have a look into following important System Design Concepts.
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;Scaling&lt;/li&gt;
&lt;li&gt;Consistent Hashing&lt;/li&gt;
&lt;li&gt;CAP Theorem&lt;/li&gt;
&lt;li&gt;Load Balancing&lt;/li&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Sharding / Data Partitioning&lt;/li&gt;
&lt;li&gt;Index &lt;/li&gt;
&lt;li&gt;Proxies&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  Scaling
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vertical Scaling:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Add more memory, CPU and Hard-drive to an existing host.&lt;/li&gt;
&lt;li&gt;It can be expensive and also has a limitation on how much memory and CPU we can add to a single host.&lt;/li&gt;
&lt;li&gt;But it doesn’t have distributed systems problem.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Horizontal Scaling:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Keep one host small but add another host.&lt;/li&gt;
&lt;li&gt;Can infinitely keep adding more hosts but we need to deal with all the distributed system challenges.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Horizontal scaling is more preferred than Vertical Scaling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zsn0z4e5xljj8qxawb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zsn0z4e5xljj8qxawb9.png" alt="Image description" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Consistent Hashing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Distributed Hash Table (DHT)&lt;/strong&gt; is one of the fundamental component used in distributed scalable systems.&lt;/li&gt;
&lt;li&gt;Hash Tables need key, value and a hash function, where hash function maps the key to a location where the value is stored.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  Designing a Distributed Cache System:
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;Suppose we are designing a distributed caching system.&lt;/li&gt;
&lt;li&gt;Given ‘n’ cache servers, an intuitive hash function would be ‘key % n’.&lt;/li&gt;
&lt;li&gt;It is simple and commonly used, but it has two major drawbacks:

&lt;ol&gt;
&lt;li&gt;It is &lt;strong&gt;NOT horizontally scalable&lt;/strong&gt;. Whenever a new cache host is added to the system, all existing mappings are broken.&lt;/li&gt;
&lt;li&gt;It may &lt;strong&gt;NOT be load balanced&lt;/strong&gt;, especially for non-uniformly distributed data. In practice, it can be easily assumed that the data will not be distributed uniformly.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8w2zdvyd848xt2oemrg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8w2zdvyd848xt2oemrg.jpeg" alt="Image description" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;So, here problem is when we are adding and removing servers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In such situations, consistent hashing is a good way to improve the caching system.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  What is Consistent Hashing ?
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We need a distribution scheme that does not depend directly on the number of servers, so that, when adding or removing servers, the number of keys that need to be relocated is minimized. One such scheme—a clever, yet surprisingly simple one—is called consistent hashing, and was first described by Karger et al. at MIT in an academic paper from 1997 &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consistent hashing is a very useful strategy for distributed caching system and DHTs. It allows distributing data across a cluster in such a way that will minimize reorganization when nodes are added or removed. Hence, making the caching system easier to scale up or down.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In Consistent Hashing when the hash table is resized (e.g. a new cache host is added to the system), only k/n keys need to be remapped, where k is the total number of keys and n is the total number of servers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recall that in a caching system using the ‘mod’ as the hash function, all keys need to be remapped. In consistent hashing objects are mapped to the same host if possible. When a host is removed from the system, the objects on that host are shared by other hosts; and when a new host is added, it takes its share from a few hosts without touching other’s shares.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  How Consistent Hashing Works ?
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;As a typical hash function, consistent hashing maps a key to an integer. Suppose the output of the hash function is in the range of [0, 256). Imagine that the integers in the range are placed on a ring such that the values are wrapped around.&lt;/li&gt;
&lt;li&gt;Here’s how consistent hashing works:

&lt;ol&gt;
&lt;li&gt;Given a list of cache servers, hash them to integers in the range.&lt;/li&gt;
&lt;li&gt;To map a key to a server,

&lt;ul&gt;
&lt;li&gt;Hash it to a single integer.&lt;/li&gt;
&lt;li&gt;Move clockwise on the ring until finding the first cache it encounters.&lt;/li&gt;
&lt;li&gt;That cache is the one that contains the key.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fney935ni1y9w7vzlzdz3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fney935ni1y9w7vzlzdz3.gif" alt="Image description" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To &lt;a href=""&gt;add a new server&lt;/a&gt;, say D, keys that were originally residing at C will be split. Some of them will be shifted to D, while other keys will not be touched.&lt;/li&gt;
&lt;li&gt;To &lt;a href=""&gt;remove a cache or if a cache failed, say A&lt;/a&gt;, all keys that were originally mapping to A will fall into B, and only those keys need to be moved to B, other keys will not be affected.&lt;/li&gt;
&lt;li&gt;For &lt;a href=""&gt;load balancing&lt;/a&gt;, as we discussed in the beginning, the real data is essentially randomly distributed and thus may not be uniform. It &lt;strong&gt;may make the keys on caches unbalanced&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;To &lt;a href=""&gt;handle this issue, we add virtual replicas for caches&lt;/a&gt;. Instead of mapping each cache to a single point on the ring, we map it to multiple points on the ring, i.e. replicas. This way, each cache is associated with multiple portions of the ring.&lt;/li&gt;
&lt;li&gt; If the hash function is “mixes well,” as the number of replicas increases, the keys will be more balanced.&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  CAP (Consistency, Availability, Partition Tolerance) Theorem
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Also k/a &lt;strong&gt;Brewer's theorem&lt;/strong&gt; it states that it is impossible for a distributed data store to simultaneously provide more than two out of the following three guarantees: 

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; Every read receives the most recent write or an error. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Availability:&lt;/strong&gt; Every request receives a (non-error) response – without the guarantee that it contains the most recent write. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partition tolerance or Failure acceptance of Distributed System:&lt;/strong&gt; System continues to operate despite an arbitrary number of messages being dropped (or delayed) by the network between nodes. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In particular, the CAP theorem implies that in the presence of a network partition or failure, one has to choose between consistency and availability.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Note:&lt;/strong&gt; Consistency as defined in the CAP theorem is quite different from the consistency guaranteed in ACID database transactions. &lt;/li&gt;
&lt;li&gt;No distributed system is safe from network failures, thus network partitioning generally has to be tolerated.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;presence of a network partition or failure&lt;/strong&gt;, one is then left with two options: consistency or availability. 

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistency over Availability:&lt;/strong&gt; System will return an error or a time-out if particular information cannot be guaranteed to be up to date due to network partitioning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Availability over Consistency:&lt;/strong&gt; System will always process the query and try to return the most recent available version of the information, even if it cannot guarantee it is up to date due to network partitioning.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;absence of network failure&lt;/strong&gt; – that is, when the distributed system is running normally – both availability and consistency can be satisfied. &lt;/li&gt;
&lt;li&gt;CAP is &lt;strong&gt;frequently misunderstood&lt;/strong&gt; as if one has to choose to abandon one of the three guarantees at all times. In fact, the choice is really between consistency and availability &lt;strong&gt;only when a network partition or failure happens&lt;/strong&gt;; at all other times, no trade-off has to be made.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6itd10yuypsccanwfv86.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6itd10yuypsccanwfv86.png" alt="Image description" width="420" height="394"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Load Balancing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Load balancer (LB) is another critical piece of any distributed system which helps to distribute load across multiple resources.&lt;/li&gt;
&lt;li&gt;It does that a/c to some metric (random, round-robin, random with weighting for memory or CPU utilization, etc.).&lt;/li&gt;
&lt;li&gt;LB also keeps track of the status of all the resources while distributing requests.&lt;/li&gt;
&lt;li&gt;If a server is not available to take new requests or not responding or has elevated error rate, LB will stop sending traffic to such a server.&lt;/li&gt;
&lt;li&gt;To utilize full scalability and redundancy, we can try to balance the load at each layer of the system. We can add LBs at three places:

&lt;ul&gt;
&lt;li&gt;Between the user and the web server&lt;/li&gt;
&lt;li&gt;Between web servers and an internal platform layer, like application servers or cache servers&lt;/li&gt;
&lt;li&gt;Between internal platform layer and database.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Ways of implementing Load Balancing
&lt;/h5&gt;
&lt;/blockquote&gt;

&lt;h6&gt;
  
  
  1. Smart Clients
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;A smart client will take a pool of service hosts and balances load across them.&lt;/li&gt;
&lt;li&gt;It also detects hosts that are not responding to avoid sending requests their way.&lt;/li&gt;
&lt;li&gt;Smart clients also have to detect recovered hosts, deal with adding new hosts, etc.&lt;/li&gt;
&lt;li&gt;Adding load-balancing functionality into the database (cache, service, etc.) client is usually an attractive solution for the developer.&lt;/li&gt;
&lt;li&gt;It looks easy to implement and manage especially when the system is not large.&lt;/li&gt;
&lt;li&gt;But as the system grows, LBs need to be evolved into standalone servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  2. Hardware Load Balancers
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;The most expensive–but very high performance–solution to load balancing is to buy a dedicated hardware load balancer (something like a &lt;a href=""&gt;Citrix NetScaler&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;While they can solve a remarkable range of problems, hardware solutions are very expensive, and they are not trivial to configure.&lt;/li&gt;
&lt;li&gt;As such, even large companies with large budgets will often &lt;strong&gt;avoid using dedicated hardware for all their load-balancing needs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Instead, they &lt;strong&gt;use them only as the first point of contact for user requests to their infrastructure&lt;/strong&gt; and use &lt;strong&gt;&lt;em&gt;other mechanisms (smart clients or the hybrid approach) for load-balancing for traffic within their network&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  3. Software Load Balancers
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;If we want to avoid the pain of creating a smart client, and since purchasing dedicated hardware is excessive, we can adopt a hybrid approach, called software load-balancers. &lt;strong&gt;HAProxy&lt;/strong&gt; is a one of the popular open source software LB.&lt;/li&gt;
&lt;li&gt;Load balancer can be placed between client and server or between two server side layers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If we can control the client's machine&lt;/strong&gt; where it is running, HAProxy could be running on the same machine.

&lt;ul&gt;
&lt;li&gt;Each service we want to load balance can have a locally bound port (e.g., localhost:9000) on that machine, and the client will use this port to connect to the server.&lt;/li&gt;
&lt;li&gt;This port is, actually, managed by HAProxy; every client request on this port will be received by the proxy and then passed to the backend service in an efficient way (distributing load).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If we can’t manage client’s machine&lt;/strong&gt;, HAProxy can run on an intermediate server.&lt;/li&gt;
&lt;li&gt;Similarly, we can have proxies running between different server side components. &lt;/li&gt;
&lt;li&gt;HAProxy manages health checks and will remove or add machines to those pools.&lt;/li&gt;
&lt;li&gt;It also balances requests across all the machines in those pools.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:-&lt;/strong&gt; For most systems, we should start with a software load balancer and move to smart clients or hardware load balancing as need arises.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdjxftvwrk66i0y4hpyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdjxftvwrk66i0y4hpyj.png" alt="Image description" width="800" height="147"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Caching
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Load balancing helps us scale horizontally across an ever-increasing number of servers, but caching will enable us to make vastly better use of the resources we already have, as well as making otherwise unattainable product requirements feasible.&lt;/li&gt;
&lt;li&gt;Caches take advantage of the &lt;strong&gt;locality of reference principle&lt;/strong&gt;: recently requested data is likely to be requested again.&lt;/li&gt;
&lt;li&gt;They are &lt;strong&gt;used in almost every layer of computing&lt;/strong&gt;: hardware, operating systems, web browsers, web applications and more.&lt;/li&gt;
&lt;li&gt;A cache is like &lt;strong&gt;short-term memory&lt;/strong&gt;: it has a limited amount of space, but is typically faster than the original data source and contains the most recently accessed items.&lt;/li&gt;
&lt;li&gt;Caches &lt;strong&gt;can exist at all levels in architecture&lt;/strong&gt; but are &lt;strong&gt;often found at the level nearest to the front-end&lt;/strong&gt;, where they are implemented to return data quickly without taxing downstream levels.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  1. Application Server Cache
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;Placing a cache directly on a request layer node enables the local storage of response data.&lt;/li&gt;
&lt;li&gt;Each time a request is made to the service, the node will quickly return local, cached data if it exists. If it is not in the cache, the requesting node will query the data from disk.&lt;/li&gt;
&lt;li&gt;The cache on one request layer node could also be located both in memory (which is very fast) and on the node’s local disk (faster than going to network storage).&lt;/li&gt;
&lt;li&gt;What happens when we expand this to many nodes? If the request layer is expanded to multiple nodes, it’s still quite possible to have each node host its own cache.&lt;/li&gt;
&lt;li&gt;However, if our load balancer randomly distributes requests across the nodes, the same request will go to different nodes, thus increasing cache misses. Two choices for overcoming this hurdle are &lt;a href=""&gt;global caches&lt;/a&gt; and &lt;a href=""&gt;distributed caches&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  2. Distributed Cache
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;In a distributed cache, each of its nodes own part of the cached data.&lt;/li&gt;
&lt;li&gt;Typically, the cache is divided up using a consistent hashing function, such that if a request node is looking for a certain piece of data, it can quickly know where to look within the distributed cache to determine if that data is available.&lt;/li&gt;
&lt;li&gt;In this case, each node has a small piece of the cache, and will then send a request to another node for the data before going to origin.&lt;/li&gt;
&lt;li&gt;Hence, one of the advantages of a distributed cache is the increased cache space just by adding nodes to the request pool.&lt;/li&gt;
&lt;li&gt;A disadvantage of distributed caching is remedying a missing node.&lt;/li&gt;
&lt;li&gt;Some distributed caches get around this by storing multiple copies of the data on different nodes; however, we can imagine how this logic can get complicated quickly, especially when we add or remove nodes from the request layer.&lt;/li&gt;
&lt;li&gt;Although even if a node disappears and part of the cache is lost, the requests will just pull from the origin—so it isn’t necessarily catastrophic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  3. Global Cache
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A global cache is just as it sounds: all the nodes use the same single cache space.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This involves adding a server, or file store of some sort, faster than your original store and accessible by all the request layer nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each of the request nodes queries the cache in the same way it would a local one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This kind of caching scheme can get a bit complicated because it is very easy to overwhelm a single cache as the number of clients and requests increase, but is very effective in some architectures (particularly ones with specialized hardware that make this global cache very fast, or that have a fixed dataset that needs to be cached).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are &lt;strong&gt;2 common forms of global caches&lt;/strong&gt; depicted in the following diagram.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;First, when a cached response is not found in the cache, the cache itself becomes responsible for retrieving the missing piece of data from the underlying store.&lt;/li&gt;
&lt;li&gt;Second, it is the responsibility of request nodes to retrieve any data that is not found in the cache.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xlt9fdonfcuuxn2acl7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xlt9fdonfcuuxn2acl7.png" alt="Image description" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Most applications leveraging global caches tend to use the first type&lt;/strong&gt;, where the cache itself manages eviction and fetching data to prevent a flood of requests for the same data from the clients.&lt;/li&gt;
&lt;li&gt;However, there are some cases where the second implementation makes more sense. For example, if the cache is being used for very large files, a low cache hit percentage would cause the cache buffer to become overwhelmed with cache misses; in this situation, it helps to have a large percentage of the total data set (or hot data set) in the cache.&lt;/li&gt;
&lt;li&gt;Another example is an architecture where the files stored in the cache are static and shouldn’t be evicted. (This could be because of application requirements around that data latency—certain pieces of data might need to be very fast for large data sets—where the application logic understands the eviction strategy or hot spots better than the cache.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  4. Content Distribution Network (CDNs)
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;CDNs are a kind of cache that comes into play for &lt;strong&gt;sites serving large amounts of static media (Netflix)&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;In a typical CDN setup, a request will first ask the CDN for a piece of static media, the CDN will serve that content if it has it locally available, if not the CDN will query the back-end servers for the file and then cache it locally and serve it to the requesting user.&lt;/li&gt;
&lt;li&gt;If system we are building isn’t yet large enough to have its own CDN, we can ease a future transition by serving static medias off a separate subdomain (eg: static.ourservice.com) using a lightweight HTTP server like Nginx, &amp;amp; cutover the DNS from server to a CDN later.&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Cache Invalidation
&lt;/h5&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;While caching is fantastic, it does require some maintenance for keeping cache coherent with the source of truth (e.g., database).&lt;/li&gt;
&lt;li&gt;If the data is modified in the database, it should be invalidated in the cache, if not, this can cause inconsistent application behavior.&lt;/li&gt;
&lt;li&gt;Solving this problem is known as &lt;strong&gt;cache invalidation&lt;/strong&gt;, there are &lt;strong&gt;3 main schemes&lt;/strong&gt; that are used:&lt;/li&gt;
&lt;li&gt;
&lt;a href=""&gt;Write-through cache :&lt;/a&gt; 

&lt;ul&gt;
&lt;li&gt;Under this scheme data is written into the cache and the corresponding database at the same time.&lt;/li&gt;
&lt;li&gt;The cached data allows for fast retrieval, and since the same data gets written in the permanent storage, we will have complete data consistency between cache and storage.&lt;/li&gt;
&lt;li&gt;Also, this scheme ensures that nothing will get lost in case of a crash, power failure, or other system disruptions.&lt;/li&gt;
&lt;li&gt;Although write through minimizes the risk of data loss, since every write operation must be done twice before returning success to the client, this scheme has the disadvantage of higher latency for write operations.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href=""&gt;Write-around cache :&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;This technique is similar to write through cache, but data is written directly to permanent storage, bypassing the cache.&lt;/li&gt;
&lt;li&gt;This can reduce the cache being flooded with write operations that will not subsequently be re-read, but has the disadvantage that a read request for recently written data will create a “cache miss” and must be read from slower back-end storage and experience higher latency.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href=""&gt;Write-back cache :&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Under this scheme, data is written to cache alone, and completion is immediately confirmed to the client.&lt;/li&gt;
&lt;li&gt;The write to the permanent storage is done after specified intervals or under certain conditions.&lt;/li&gt;
&lt;li&gt;This results in low latency and high throughput for write-intensive applications, however, this speed comes with the risk of data loss in case of a crash or other adverse event because the only copy of the written data is in the cache.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Cache Eviction Policies
&lt;/h5&gt;
&lt;/blockquote&gt;

&lt;p&gt;Following are some of the most common cache eviction policies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;First In First Out (FIFO) :&lt;/strong&gt; The cache evicts the first block accessed first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Last In First Out (LIFO) :&lt;/strong&gt; The cache evicts the block accessed most recently first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Least Recently Used (LRU) :&lt;/strong&gt; Discards the least recently used items first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most Recently Used (MRU) :&lt;/strong&gt; Discards, in contrast to LRU, the most recently used items first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Least Frequently Used (LFU) :&lt;/strong&gt; Counts how often an item is needed, those that are used least often are discarded first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Random Replacement (RR) :&lt;/strong&gt; Randomly selects a candidate item and discards it to make space when necessary.&lt;/li&gt;
&lt;/ol&gt;



&lt;h2&gt;
  
  
  Sharding or Data Partitioning
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Data partitioning (also known as sharding) is a technique to break up a big database (DB) into many smaller parts.&lt;/li&gt;
&lt;li&gt;It is the process of splitting up a DB/table across multiple machines to improve the manageability, performance, availability and load balancing of an application.&lt;/li&gt;
&lt;li&gt;The justification for data sharding is that, after a certain scale point, it is cheaper and more feasible to scale horizontally by adding more machines than to grow it vertically by adding beefier servers.&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Partitioning Methods
&lt;/h5&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;There are many different schemes one could use to decide how to break up an application database into multiple smaller DBs.&lt;/li&gt;
&lt;li&gt;Below are &lt;strong&gt;3 of the most popular schemes&lt;/strong&gt; used by various large scale applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  1. Horizontal partitioning :
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;In this scheme, we put different rows into different tables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Example :-&lt;/em&gt;&lt;/strong&gt; if we are storing different places in a table, we can decide that locations with ZIP codes less than 10000 are stored in one table, and places with ZIP codes greater than 10000 are stored in a separate table. This is also called a range based sharding, as we are storing different ranges of data in separate tables.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;key problem&lt;/strong&gt; with this approach is that if the value whose range is used for sharding isn’t chosen carefully, then the partitioning scheme will lead to unbalanced servers.&lt;/li&gt;
&lt;li&gt;In the previous example, splitting location based on their zip codes assumes that places will be evenly distributed across the different zip codes, but this assumption is not valid as there will be a lot of places in a thickly populated area like Manhattan compared to other cities.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  2. Vertical Partitioning :
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;In this scheme, we divide our data to store tables related to a specific feature to their own server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Example :-&lt;/em&gt;&lt;/strong&gt; if we are building Instagram like application, where we need to store data related to users, all the photos they upload and people they follow, we can decide to place user profile information on one DB server, friend lists on another and photos on third server.&lt;/li&gt;
&lt;li&gt;Vertical partitioning is straightforward to implement and has a low impact on the application.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;main problem&lt;/strong&gt; with this approach is that if our application experiences additional growth, then it may be necessary
to further partition a feature specific DB across various servers (e.g. it would not be possible for a single server to handle all the metadata queries for 10 billion photos by 140 million users).&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  3. Directory Based Partitioning :
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;A loosely coupled approach to work around issues mentioned in above schemes is to create a lookup service which knows our current partitioning scheme and abstracts it away from the DB access code.&lt;/li&gt;
&lt;li&gt;So, to find out where does a particular data entity resides, we query our directory server that holds the mapping between each tuple key to its DB server.&lt;/li&gt;
&lt;li&gt;This loosely coupled approach means we can perform tasks like adding servers to the DB pool or change our partitioning scheme without having to impact your application.&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Partitioning Criteria
&lt;/h5&gt;
&lt;/blockquote&gt;

&lt;h6&gt;
  
  
  1. Key or Hash-based partitioning :
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;Under this scheme, we apply a hash function to some key attribute of the entity we are storing, that yields the partition number. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Example:-&lt;/em&gt; If we have 100 DB servers and our ID is a numeric value that gets incremented by one, each time a new record is inserted. Here the hash function could be &lt;strong&gt;&lt;code&gt;ID % 100&lt;/code&gt;&lt;/strong&gt;, which will give us the server number where we can store/read that record.&lt;/li&gt;
&lt;li&gt;This approach should ensure a uniform allocation of data among servers.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;fundamental problem&lt;/strong&gt; with this approach is that it effectively fixes the total number of DB servers, since adding new servers means changing the hash function which would require redistribution of data and downtime for the service.&lt;/li&gt;
&lt;li&gt;A workaround for this problem is to use &lt;strong&gt;Consistent Hashing&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  2. List partitioning :
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;In this scheme, each partition is assigned a list of values, so whenever we want to insert a new record, we will see which partition contains our key and then store it there.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Example:-&lt;/em&gt; we can decide to store users living in Iceland, Norway, Sweden, Finland or Denmark in a partition for the Nordic countries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  3. Round-robin partitioning :
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;This is a very simple strategy that ensures uniform data distribution. With ‘n’ partitions, the ‘i’ tuple is assigned to partition (i mod n).&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  4. Composite partitioning :
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;Under this scheme, we combine any of above partitioning schemes to devise a new scheme.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Example:-&lt;/em&gt; first applying a list partitioning and then a hash based partitioning. Consistent hashing could be considered a composite of hash and list partitioning where the hash reduces the key space to a size that can be listed.&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt;
&lt;h5&gt;
  
  
  Common Problems of Sharding
&lt;/h5&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;On a sharded database, there are certain extra constraints on the different operations that can be performed.&lt;/li&gt;
&lt;li&gt;Most of these constraints are due to the fact that, operations across multiple tables or multiple rows in the same table, will no longer run on the same server.&lt;/li&gt;
&lt;li&gt;Below are some of the &lt;strong&gt;constraints and additional complexities introduced by sharding&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  1. Joins and Denormalization:
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;Performing joins on a database which is running on one server is straightforward, but once a database is partitioned and spread across multiple machines it is often not feasible to perform joins that span database shards.&lt;/li&gt;
&lt;li&gt;Such joins will not be performance efficient since data has to be compiled from multiple servers.&lt;/li&gt;
&lt;li&gt;A common workaround for this problem is to denormalize the database so that queries that previously required joins can be performed from a single table.&lt;/li&gt;
&lt;li&gt;Offcourse, the service now has to deal with all the perils of denormalization such as data inconsistency.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  2. Referential integrity:
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;As we saw that performing a cross-shard query on a partitioned database is not feasible, similarly trying to enforce data integrity constraints such as foreign keys in a sharded database can be extremely difficult.&lt;/li&gt;
&lt;li&gt;Most of RDBMS do not support foreign keys constraints across databases on different database servers.&lt;/li&gt;
&lt;li&gt;Which means that applications that require referential integrity on sharded databases often have to enforce it in application code.&lt;/li&gt;
&lt;li&gt;Often in such cases, applications have to run regular SQL jobs to clean up dangling references.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  3. Rebalancing:
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;There could be many reasons we have to change our sharding scheme:

&lt;ul&gt;
&lt;li&gt;The data distribution is not uniform e.g. there are a lot of places for a particular ZIP code, that cannot fit into one database partition.&lt;/li&gt;
&lt;li&gt;There are a lot of load on a shard, e.g., there are too many requests being handled by the DB shard dedicated to user photos.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;In such cases, either we have to create more DB shards or have to rebalance existing shards, which means changing partitioning scheme and moving all existing data to new locations.&lt;/li&gt;
&lt;li&gt;Doing this without incurring downtime is extremely difficult. Using a scheme like directory based partitioning does make rebalancing a more palatable experience at the cost of increasing the complexity of the system and creating a new single point of failure (i.e. the lookup service/database).&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  Indexes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Indexes are well known when it comes to databases; they are used to improve the speed of data retrieval operations on the data store.&lt;/li&gt;
&lt;li&gt;An index makes the trade-offs of increased storage overhead, and slower writes (since we not only have to write the data but also have to update the index) for the benefit of faster reads.&lt;/li&gt;
&lt;li&gt;Indexes are used to quickly locate data without having to examine every row in a database table. Indexes can be created using one or more columns of a database table, providing the basis for both rapid random lookups and efficient access of ordered records.&lt;/li&gt;
&lt;li&gt;An index is a data structure that can be perceived as a table of contents that points us to the location where actual data lives.&lt;/li&gt;
&lt;li&gt;So when we create an index on a column of a table, we store that column and a pointer to the whole row in the index.&lt;/li&gt;
&lt;li&gt;Indexes are also used to create different views of the same data.&lt;/li&gt;
&lt;li&gt;For large data sets, it's an excellent way to specify different filters or sorting schemes without resorting to creating multiple additional copies of the data.&lt;/li&gt;
&lt;li&gt;Just as to a traditional relational data store, we can also apply this concept to larger data sets.&lt;/li&gt;
&lt;li&gt;The trick with indexes is that we must carefully consider how users will access the data.&lt;/li&gt;
&lt;li&gt;In the case of data sets being in TBs but with very small payloads (e.g, 1KB), indexes are a necessity for optimizing data access.&lt;/li&gt;
&lt;li&gt;Finding a small payload in such a large data set can be a real challenge as we can't iterate over that much data in any reasonable time.&lt;/li&gt;
&lt;li&gt;Furthermore, it is very likely that such a large data set is spread over several physical devices—this means we need some way to find the correct physical location of the desired data and indexes are the best way to do this.&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  Proxies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A proxy server is an &lt;strong&gt;intermediary piece of hardware/software that sits between the client and the back-end server&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It receives requests from clients and relays them to the origin servers.&lt;/li&gt;
&lt;li&gt;Typically, proxies are used to filter requests or log requests, or sometimes transform requests (by adding/removing headers, encrypting/decrypting, or compression).&lt;/li&gt;
&lt;li&gt;Another advantage of a proxy server is that its cache can serve a lot of requests.&lt;/li&gt;
&lt;li&gt;If multiple clients access a particular resource, the proxy server can cache it and serve all clients without going to the remote server.&lt;/li&gt;
&lt;li&gt;Proxies are also extremely helpful when coordinating requests from multiple servers and can be used to optimize request traffic from a system-wide perspective. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Example :-&lt;/em&gt; we can collapse the same (or similar) data access requests into one request and then return the single result to the user; this scheme is called &lt;strong&gt;collapsed forwarding&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Imagine there is a request for the same data across several nodes, and that piece of data is not in the cache. If these requests are routed through the proxy, then all them can be collapsed into one, which means we will be reading the required data from the disk only once.&lt;/li&gt;
&lt;li&gt;Another great way to use the proxy is to collapse requests for data that is spatially close together in the storage (consecutively on disk), this will result in decreasing request latency.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Example :-&lt;/em&gt; let’s say a bunch of servers request parts of file: part1, part2, part3, etc. We can set up our proxy in such a way that it can recognize the spatial locality of the individual requests, thus collapsing them into a single request and reading complete file, which will greatly minimize the reads from the data origin.&lt;/li&gt;
&lt;li&gt;Such scheme makes a big difference in request time when we are doing random accesses across TBs of data.&lt;/li&gt;
&lt;li&gt;Proxies are particularly useful under high load situations, or when we have limited caching since proxies can mostly batch several requests into one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkogdxaqwqfa1x15er54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkogdxaqwqfa1x15er54.png" alt="Image description" width="465" height="175"&gt;&lt;/a&gt;&lt;/p&gt;





</description>
      <category>systemdesign</category>
    </item>
    <item>
      <title>System Design : Silent Basics</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Thu, 15 Feb 2024 14:16:19 +0000</pubDate>
      <link>https://forem.com/bhushands/system-design-silent-basics-45aa</link>
      <guid>https://forem.com/bhushands/system-design-silent-basics-45aa</guid>
      <description>&lt;h1&gt;
  
  
  System Design Basics
&lt;/h1&gt;

&lt;h3&gt;
  
  
  ABCDs of System Design
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;A&lt;/em&gt;&lt;/strong&gt;sk Good Questions:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What's features to work on?&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Ask the good questions and define the Minimum Viable Product(MVP) for the system Design Problem.&lt;/li&gt;
&lt;li&gt;A problem can have many features, it’s our responsibility to work with the owner and figure out which features he cares about and which features he doesn’t care about.&lt;/li&gt;
&lt;li&gt;We need to remember that we are working under a very strict time frame, so we need to make sure our feature set is small and go deep into this feature set.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How much to scale ?&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;How much data we need to store in the database?&lt;/li&gt;
&lt;li&gt;How many requests/second need to be handled?&lt;/li&gt;
&lt;li&gt;What kind of latency is expected from the system?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;D&lt;/em&gt;&lt;/strong&gt;on't  Use Buzzwords&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Make sure whatever technologies or concept we are mentioning we do have some sort of in-depth knowledge on those technologies.&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;C&lt;/em&gt;&lt;/strong&gt;lear and Organized Thinking&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Before jumping into the minor details of the problem first we need to try to define the 50,000 feet view of the problem.&lt;/li&gt;
&lt;li&gt;Need to make sure we have defined all the APIs.&lt;/li&gt;
&lt;li&gt;Need to make sure we have drawn right boxes.&lt;/li&gt;
&lt;li&gt;Need to make sure we know who are the actors for the system.&lt;/li&gt;
&lt;li&gt;Once we have defined all those things then we go deeper into the details working with the product owner.&lt;/li&gt;
&lt;/ul&gt;



&lt;blockquote&gt;
&lt;p&gt;Drive &lt;strong&gt;&lt;em&gt;D&lt;/em&gt;&lt;/strong&gt;iscussions (80-20) Rule&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;We should be talking 80% of the time and the product owner should be talking 20% of the time.&lt;/li&gt;
&lt;li&gt;Need to make sure we lead the discussions.&lt;/li&gt;
&lt;li&gt;Need to make sure we anticipate the problems which are there in our solution and fix them pre-emptively.&lt;/li&gt;
&lt;/ul&gt;



&lt;h3&gt;
  
  
  Solving System Design
&lt;/h3&gt;

&lt;h6&gt;
  
  
  Solving system design questions could be broken down into three steps:
&lt;/h6&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scoping the problem :&lt;/strong&gt; Don’t make assumptions; Ask clarifying questions to understand the constraints and use cases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sketching up an abstract design&lt;/strong&gt; Illustrating the building blocks of the system and the relationships between them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identifying and addressing the bottlenecks&lt;/strong&gt; by using the fundamental principles of scalable system design.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href=""&gt;Note:-&lt;/a&gt; Remember there is no ONE right answer to the question because any system can be built in different ways. The only thing that is going to be looked into is your ability to rationalize ideas and inputs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h6&gt;
  
  
  Whenever we are designing a large system, we need to consider few things:
&lt;/h6&gt;

&lt;ol&gt;
&lt;li&gt;What are different architectural pieces that can be used?&lt;/li&gt;
&lt;li&gt;How do these pieces work with each other?&lt;/li&gt;
&lt;li&gt;How can we best utilize these pieces, what are the right tradeoffs?&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href=""&gt;Note:-&lt;/a&gt; Investing in scaling before it is needed is generally not a smart business proposition; however, some forethought into the design can save valuable time and resources in the future. &lt;/p&gt;
&lt;/blockquote&gt;



&lt;h3&gt;
  
  
  Getting to know the Terminologies
&lt;/h3&gt;

&lt;h6&gt;
  
  
  Designing a Restaurant
&lt;/h6&gt;

&lt;ol&gt;
&lt;li&gt;Once restaurant starts working fine, pay more to chef to increase throughput using same resource --- &lt;strong&gt;Vertical Scaling&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Preparing beforehand during non-peak hours ---- &lt;strong&gt;Preprocessing and Cron jobs.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Keeps backup and avoid single point of failure. &lt;strong&gt;--- Backups (Master - Slave Architecture)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Hire more resources. &lt;strong&gt;--- Horizontal Scaling&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Divide responsibility and scale teams at different rate a/c to need. &lt;strong&gt;--- Separation of concerns (Microservice Architecture)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Open new shop with similar functionality at a new location. &lt;strong&gt;--- Distributed System (Partitioning) - Now Fault Tolerant&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Routing request b/w shops when order received. &lt;strong&gt;--- Load Balancer&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Handling delivery agent and shops separately. &lt;strong&gt;--- Separation of System (Decoupling) - Handle more effectively&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;If something goes wrong log it to take corrective action quickly &lt;strong&gt;--- Logging and Metrics calculation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Delivery agent should not be bothered if they going to deliver pizza or burger tomorrow. &lt;strong&gt;--- Extensible&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;



&lt;h3&gt;
  
  
  High Level Design Vs. Low Level Design
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In High level we mostly talk about server, architecture and all that.&lt;/li&gt;
&lt;li&gt;Low level design deals with how we actually going to code these stuff.

&lt;ul&gt;
&lt;li&gt;Making classes, objects, functions&lt;/li&gt;
&lt;li&gt;Making signatures&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;








</description>
      <category>systemdesign</category>
    </item>
    <item>
      <title>System Design : Basics</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Thu, 15 Feb 2024 13:45:51 +0000</pubDate>
      <link>https://forem.com/bhushands/system-design-basics-1p75</link>
      <guid>https://forem.com/bhushands/system-design-basics-1p75</guid>
      <description>&lt;h1&gt;
  
  
  Back of Envolp
&lt;/h1&gt;

&lt;p&gt;Before Starting the HLD start with Back of Envolp Estimations&lt;/p&gt;

&lt;p&gt;BOE drives decision for System Design:&lt;/p&gt;

&lt;h2&gt;
  
  
  Consideration: Rough Estimation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep assumption value simple like taking multiplication in 10.&lt;/li&gt;
&lt;li&gt;Lets see cheat sheet:
Everything is is mul. 3 zeros&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Value     ----------  |  Traffic      ------------  |  Storage
&lt;/h2&gt;

&lt;p&gt;| 3 Zeros-----------&amp;gt;  |  Thousand----------- &amp;gt;  | KB&lt;br&gt;
| 6 Zeros----------- &amp;gt; |  Million-----------&amp;gt;    | MB&lt;br&gt;
| 9 Zeros----------- &amp;gt; |  Billion----------- &amp;gt;    | GB&lt;br&gt;
| 12 Zeros----------- &amp;gt; |  Trillion------ ----- &amp;gt;   | TB&lt;br&gt;
| 15 Zeros----------- &amp;gt; | Quilon ----------- &amp;gt;    | PB&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Consideration
&lt;/h3&gt;

&lt;p&gt;char        - 2 byte&lt;br&gt;
  long/double - 8 byte&lt;br&gt;
  Image       - 300 KB&lt;/p&gt;

&lt;p&gt;Formula:&lt;br&gt;
X million User * Y mb      =       XY TB&lt;br&gt;
6 zeros          6 Zeros          12 Zeros&lt;/p&gt;

&lt;p&gt;so,&lt;br&gt;
5 million User * 2 KB      =     10 GB&lt;br&gt;
6 Zeros -----------3 Zeros -----------9 Zeros&lt;/p&gt;

&lt;h1&gt;
  
  
  Lets take an example now, any Social Media
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Given Data :
&lt;/h2&gt;

&lt;p&gt;Total User  - &amp;gt; 1 Billion&lt;br&gt;
DAU (Daily Active User) - &amp;gt; 25% Total User  - &amp;gt; 250 million User&lt;br&gt;
Read &amp;amp; Write : 5 read &amp;amp; 2  write&lt;/p&gt;

&lt;h2&gt;
  
  
  a) Traffic :
&lt;/h2&gt;

&lt;p&gt;Calculations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;250 Million USer * (5 + 2) query / 1 Day (86400 sec = ~ 100000)
17500 ~= 18 K Query/Sec.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  b) Storage Assumption :
&lt;/h2&gt;

&lt;p&gt;Every user writing 2 post ( lets say each is 250 char)&lt;br&gt;
consider 10% User upload 1 image ( 1 img = 300 kb)&lt;/p&gt;

&lt;p&gt;1 post - &amp;gt; 250 char = &amp;gt; 250*2 byte. &lt;br&gt;
2 post - &amp;gt; 500 char = &amp;gt; 1000byte = &amp;gt; 1 KB. &lt;/p&gt;

&lt;p&gt;250 million user * 1 KB = (250 * 10^6) * (1 * 10^3) = 250 GB/DAY&lt;/p&gt;

&lt;p&gt;25 Million * 300 KB = 7.5 GB ~= 8 TB/DAY&lt;/p&gt;

&lt;h3&gt;
  
  
  lets say we store data for 5 year then total storage requir :
&lt;/h3&gt;

&lt;p&gt;5 year = 1825 days ~= 2000 day&lt;br&gt;
Total Storage : 2000 * 250 GB + 2000 * 8 TB = 16.5 PB&lt;/p&gt;

&lt;h2&gt;
  
  
  c) Ram Estimation :
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;For each user last 5 post we are pulling each.
1 post = 500 byte from above calculations.
5*500 = 2500 byte / user ~ = 3000&lt;/li&gt;
&lt;li&gt;250 million * 3000 = 750 GB - memory Space&lt;/li&gt;
&lt;li&gt;1 Machine = 75 GB data in memory
so 10 machine we needed for cache&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Latency : 95% 500ms (Rough Estimation)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;18 Query/sec&lt;/li&gt;
&lt;li&gt;1 server = &amp;gt; 50 thread = &amp;gt; 100 request / sec&lt;/li&gt;
&lt;li&gt;Server No : 18k/100 = 180 server&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Trade OFF
&lt;/h2&gt;

&lt;p&gt;Since it is read heavy system , consistency we can ignore &lt;br&gt;
so in CAP theorem we need AP.&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>hld</category>
    </item>
    <item>
      <title>Its Friday , Who are still in office waiting for successful submit build result</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Fri, 09 Feb 2024 15:20:28 +0000</pubDate>
      <link>https://forem.com/bhushands/its-friday-who-are-still-in-office-waiting-for-successful-submit-build-result-1djo</link>
      <guid>https://forem.com/bhushands/its-friday-who-are-still-in-office-waiting-for-successful-submit-build-result-1djo</guid>
      <description>&lt;p&gt;Imagine it's Friday evening, and the clock is ticking towards the end of the workweek. You've been eagerly awaiting the successful submission of your build result, but it seems like time has slowed down to a crawl. The tension in the office is palpable as everyone holds their breath, hoping for that sweet victory before the weekend kicks in.&lt;/p&gt;

&lt;p&gt;As minutes turn into hours, the anticipation becomes almost comical. People start pacing around the office, checking their emails and Slack messages every few seconds, as if the mere act of refreshing will magically speed up the process.&lt;/p&gt;

&lt;p&gt;In a desperate attempt to lighten the mood, someone suggests a impromptu dance-off or a round of office karaoke to pass the time. Before you know it, your team is belting out '80s classics or attempting the latest TikTok dance craze, all while keeping one eye on their screens for any sign of progress.&lt;/p&gt;

&lt;p&gt;Despite the mounting pressure, there's a sense of camaraderie as everyone bands together in solidarity, united by the shared goal of wrapping up work and kicking off the weekend on a high note.&lt;/p&gt;

&lt;p&gt;Finally, just when it seems like the wait will never end, the build result comes through, and the office erupts into cheers and applause. High-fives are exchanged, and someone even breaks out a box of celebratory donuts, because why not? It's Friday, after all, and you've earned it!&lt;/p&gt;

&lt;p&gt;As you log off for the weekend, you can't help but chuckle at the absurdity of the situation. Who knew waiting for a build result could be so entertaining? But hey, if there's one thing you've learned, it's that laughter truly is the best way to survive those long Friday evenings in the office.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>developers</category>
    </item>
    <item>
      <title>.py : Adding Password Protection</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Tue, 06 Feb 2024 11:43:11 +0000</pubDate>
      <link>https://forem.com/bhushands/py-adding-password-protection-36ig</link>
      <guid>https://forem.com/bhushands/py-adding-password-protection-36ig</guid>
      <description>&lt;h1&gt;
  
  
  Description:
&lt;/h1&gt;

&lt;p&gt;This Python script adds password protection to a PDF file. It encrypts the PDF with a password, ensuring that only those with the correct password can access the content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Python script to add password protection to a PDF
import PyPDF2
def add_password_protection(input_path, output_path, password):
with open(input_path, 'rb') as f:
pdf_reader = PyPDF2.PdfFileReader(f)
pdf_writer = PyPDF2.PdfFileWriter()
for page_num in range(pdf_reader.numPages):
page = pdf_reader.getPage(page_num)
pdf_writer.addPage(page)
pdf_writer.encrypt(password)
with open(output_path, 'wb') as output_file:
pdf_writer.write(output_file)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
    </item>
    <item>
      <title>.py : Automating PDF Operations (Extracting Text from PDFs)</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Tue, 06 Feb 2024 11:42:06 +0000</pubDate>
      <link>https://forem.com/bhushands/py-automating-pdf-operationsextracting-text-from-pdfs-2aml</link>
      <guid>https://forem.com/bhushands/py-automating-pdf-operationsextracting-text-from-pdfs-2aml</guid>
      <description>&lt;h1&gt;
  
  
  Description:
&lt;/h1&gt;

&lt;p&gt;This Python script extracts text from PDF files using the PyPDF2 library. It reads each page of the PDF and compiles the extracted text into a single string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Python script to extract text from PDFs
import PyPDF2
def extract_text_from_pdf(file_path):
with open(file_path, 'rb') as f:
pdf_reader = PyPDF2.PdfFileReader(f)
text = ''
for page_num in range(pdf_reader.numPages):
page = pdf_reader.getPage(page_num)
text += page.extractText()
return text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>.py: Automating Emails (Sending Personalized Emails)</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Tue, 06 Feb 2024 11:36:12 +0000</pubDate>
      <link>https://forem.com/bhushands/py-automating-emailssending-personalized-emails-53cj</link>
      <guid>https://forem.com/bhushands/py-automating-emailssending-personalized-emails-53cj</guid>
      <description>&lt;p&gt;Description:&lt;/p&gt;

&lt;p&gt;This Python script enables you to send personalized emails to a list of recipients. You can customize the sender’s email, password, subject, body, and the list of recipient emails. Please note that for security reasons, you should use an application-specific password when working with Gmail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Python script to send personalized emails to a list of recipients
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
def send_personalized_email(sender_email, sender_password, recipients, subject, body):
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(sender_email, sender_password)
for recipient_email in recipients:
message = MIMEMultipart()
message['From'] = sender_email
message['To'] = recipient_email
message['Subject'] = subject
message.attach(MIMEText(body, 'plain'))
server.sendmail(sender_email, recipient_email, message.as_string())
server.quit()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
    </item>
    <item>
      <title>.py : Downloading Images in Bulk</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Tue, 06 Feb 2024 11:34:20 +0000</pubDate>
      <link>https://forem.com/bhushands/py-downloading-images-in-bulk-g4l</link>
      <guid>https://forem.com/bhushands/py-downloading-images-in-bulk-g4l</guid>
      <description>&lt;h1&gt;
  
  
  Description:
&lt;/h1&gt;

&lt;p&gt;This Python script is designed to download images in bulk from a website. It assumes that the website provides a JSON API that returns an array of image URLs. The script then iterates through the URLs and downloads the images, saving them to the specified directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Python script to download images in bulk from a website
import requests
def download_images(url, save_directory):
response = requests.get(url)
if response.status_code == 200:
images = response.json() # Assuming the API returns a JSON array of image URLs
for index, image_url in enumerate(images):
image_response = requests.get(image_url)
if image_response.status_code == 200:
with open(f"{save_directory}/image_{index}.jpg", "wb") as f:
f.write(image_response.content)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>.py : Web Scraping with Python (Extracting Data from a Website)</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Tue, 06 Feb 2024 11:33:39 +0000</pubDate>
      <link>https://forem.com/bhushands/py-web-scraping-with-pythonextracting-data-from-a-website-491g</link>
      <guid>https://forem.com/bhushands/py-web-scraping-with-pythonextracting-data-from-a-website-491g</guid>
      <description>&lt;h1&gt;
  
  
  Description:
&lt;/h1&gt;

&lt;p&gt;This Python script utilizes the requests and BeautifulSoup libraries to scrape data from a website. It fetches the content of the webpage and uses BeautifulSoup to parse the HTML. You can customize the script to extract specific data like headlines, product information, or prices.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Python script for web scraping to extract data from a website
import requests
from bs4 import BeautifulSoup
def scrape_data(url):
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
# Your code here to extract relevant data from the website
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
    </item>
    <item>
      <title>What’s polymorphism ? How it’s implemented by the complier?</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Fri, 02 Feb 2024 07:13:56 +0000</pubDate>
      <link>https://forem.com/bhushands/whats-polymorphism-how-its-implemented-by-the-complier-52kc</link>
      <guid>https://forem.com/bhushands/whats-polymorphism-how-its-implemented-by-the-complier-52kc</guid>
      <description>&lt;p&gt;Polymorphism, in the context of object oriented programming, refer to the ability of objects to take on multiple forms. This is achieved through two main mechanism : Compile Time polymorphism and Run time polymorphism.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compile-Time Polymorphism (Method Overloading):
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;How it work:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Determined at Compile time.&lt;/li&gt;
&lt;li&gt;also known as Static Polymorphism.&lt;/li&gt;
&lt;li&gt;Implemented using function overloading and operator overloading.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MathOperations
{
  public:
      int add(int a, int b)
      { return a+b; }
      int add(double a, double b)
      { return a+b; }
};

int main()
{
  MathOperations math;
  int result1 = math.add(9+8);
  int result2 = math.add(9.78,45.76);

  return EXIT_SUCCESS;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;How it is implemented:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;During compilation, the compiler resolves the function calls based on the provided arguments.&lt;/li&gt;
&lt;li&gt;The generated machine code instructions to call the appropriate function based on the types and number of arguments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Run-Time Polymorphism (Method Overloading):
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;How it work&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Determined at runtime.&lt;/li&gt;
&lt;li&gt;Also known as dynamic polymorphism.&lt;/li&gt;
&lt;li&gt;Implemented using virtual functions and inheritance.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
class Shape
{
  public:
    virtual void draw() const = 0; //pure function
};

class Circle: public Shape
{
  public:
    void draw const override()
    {
      std::cout&amp;lt;&amp;lt;"Drawing a Circle \n";
    }
};

class Square:public Shape
{
  public:
    void draw const override()
    {
      std::cout&amp;lt;&amp;lt;"Drawing an Square \n";
    }
};

int main()
{
  Shape* shapes[] = {new Circle(), new Square()};
  for(const Shape* shape : shapes)
  {
    shape-&amp;gt;draw(); // runtime calls to functions
  } 

  return EXIT_SUCCESS;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;How it is implemented:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Virtual functions are implemented using a mechanism call as virtual function table.&lt;/li&gt;
&lt;li&gt;The vtable is a table of function pointers associated, with each class that has virtual functions.&lt;/li&gt;
&lt;li&gt;When a class has a virtual function, the compiler adds a pointer to the vtable in the object memory layout.&lt;/li&gt;
&lt;li&gt;The vtable contains pointers to the actual implementations of the virtual functions in the class or tis subclass.&lt;/li&gt;
&lt;li&gt;During runtime, the correct function is called based on the dynamic type of the object.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key points
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;For a every class there is only one vtable.&lt;/li&gt;
&lt;li&gt;For a every object there is only one vptr.&lt;/li&gt;
&lt;li&gt;so if there are 10 object of class A then there is 1 vtable and 10 vptr pointers.&lt;/li&gt;
&lt;li&gt;Lets say there is class A (having two function draw() and Fun() ) and class B is child of A, and overload only virtual function draw(), then below is the representation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff21udy01lapytjb7so54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff21udy01lapytjb7so54.png" alt="Image description" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>polymorphism</category>
      <category>compiler</category>
    </item>
    <item>
      <title>Who is Senior Software Developer ?</title>
      <dc:creator>Bhushan Rane</dc:creator>
      <pubDate>Fri, 02 Feb 2024 06:59:20 +0000</pubDate>
      <link>https://forem.com/bhushands/who-is-senior-software-developer--5gac</link>
      <guid>https://forem.com/bhushands/who-is-senior-software-developer--5gac</guid>
      <description>&lt;p&gt;A senior software developer is an experienced professional in the field of software development who typically has a deep understanding of programming languages, software architecture, and system design. Their role involves not only writing code but also taking a lead in various aspects of the software development lifecycle.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key characteristics of a senior software developer include:
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Experience
&lt;/h4&gt;

&lt;p&gt;: They usually have several years of experience in software development, gaining expertise in a variety of projects and technologies.&lt;/p&gt;

&lt;h4&gt;
  
  
  Leadership
&lt;/h4&gt;

&lt;p&gt;: Senior developers often take on leadership roles within development teams. They may guide junior developers, make technical decisions, and contribute to project planning.&lt;/p&gt;

&lt;h4&gt;
  
  
  Problem Solving
&lt;/h4&gt;

&lt;p&gt;: They are adept at solving complex problems and finding efficient and effective solutions. They may be involved in troubleshooting and debugging challenging issues.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Skills
&lt;/h4&gt;

&lt;p&gt;: They possess advanced skills in programming languages, frameworks, and tools relevant to their field. They stay updated with industry trends and emerging technologies.&lt;/p&gt;

&lt;h4&gt;
  
  
  Architecture and Design
&lt;/h4&gt;

&lt;p&gt;: Senior developers are involved in designing software systems and making high-level architecture decisions. They understand how different components of a system interact.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code Reviews
&lt;/h4&gt;

&lt;p&gt;: They actively participate in code reviews to ensure the quality, maintainability, and adherence to coding standards of the codebase.&lt;/p&gt;

&lt;h4&gt;
  
  
  Collaboration
&lt;/h4&gt;

&lt;p&gt;: Senior developers often collaborate with cross-functional teams, including product managers, designers, and quality assurance professionals, to deliver successful software projects.&lt;/p&gt;

</description>
      <category>seniorsoftwaredeveloper</category>
    </item>
  </channel>
</rss>
