<?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 Amol Jadhav on Medium]]></title>
        <description><![CDATA[Stories by Amol Jadhav on Medium]]></description>
        <link>https://medium.com/@amoljadhav_48655?source=rss-52cdb9f437f0------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*YcP62lXMvTgHMU8oTOi9qA@2x.jpeg</url>
            <title>Stories by Amol Jadhav on Medium</title>
            <link>https://medium.com/@amoljadhav_48655?source=rss-52cdb9f437f0------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 01 Jun 2026 05:58:36 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@amoljadhav_48655/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[When AI Codes the Future, What Becomes of Human Ingenuity?]]></title>
            <link>https://medium.com/@amoljadhav_48655/when-ai-codes-the-future-what-becomes-of-human-ingenuity-623deb8018f7?source=rss-52cdb9f437f0------2</link>
            <guid isPermaLink="false">https://medium.com/p/623deb8018f7</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Amol Jadhav]]></dc:creator>
            <pubDate>Sun, 24 Aug 2025 23:36:01 GMT</pubDate>
            <atom:updated>2025-08-24T23:36:01.157Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>Tomorrow’s inventions won’t ask, “Who built this?” but “Who directed this?”The genius of the future won’t be in lines of code, but in lines of thought.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*kujYD0lar_snbwmKqPb_Pw@2x.jpeg" /></figure><p>Not long ago, writing code was seen as the pinnacle of technical mastery. Engineers poured over algorithms, wrestled with bugs, and took pride in the elegance of their solutions. Today, AI systems like GitHub Copilot can write, debug, and optimize code faster than most humans ever could. The future of software engineering seems increasingly automated. But this shift raises a deeper question: if machines do the building, what becomes of human ingenuity?</p><h3><strong>A Brief History of Invention</strong></h3><p>From Edison’s light bulb to Turing’s computing machine, the story of progress has been driven by human inventors who combined persistence, imagination, and technical skill. Patents rewarded originality. Recognition flowed to those who dared to push boundaries. Human effort wasn’t just about the output — it was about the journey: years of trial, error, and eventual insight.</p><h3>The AI Shift</h3><p>Enter the era of AI copilots, agents, and autonomous systems. With a single prompt, AI can generate a website, architect a database, or even suggest entirely new algorithms. The barriers to creation are collapsing. This democratizes innovation, but it also blurs the definition of invention. If an AI builds a system from your idea, who is the true creator — the human with the vision, the AI with the execution, or the company that owns the AI model?</p><p>It is predicted that 95% of programming code will be AI-generated by 2030, fundamentally shifting developers from coders to orchestrators of AI systems.</p><h3>The Legal &amp; Ethical Gap</h3><p>Current patent law assumes humans invent. But what happens when AI drafts a novel molecule, or codes a non-obvious solution? Courts worldwide have ruled that AI can’t be listed as an inventor. Yet, this feels like a temporary patch, not a lasting answer.Future law may need to evolve toward recognizing human-AI collaboration — protecting the vision and judgment of the human while acknowledging the machine’s contribution. Then there’s ethics. AI solutions often inherit biases buried in their training data. That makes human oversight not optional, but essential.</p><h3>The New Human Frontier</h3><p>If AI automates execution, human excellence shifts upward — from hands-on building to strategic orchestration. The future innovator is less a “builder” and more a director, curator, and strategist.</p><p>1. Framing Problems: Deciding what’s worth solving matters more than solving it. A human must define the goal — “create a more efficient way to manage a city’s traffic flow” — before AI can generate solutions.</p><p>2. Taste &amp; Judgment: An AI can generate a thousand design options, but only a human has the vision and aesthetic sensibility to select the best one.</p><p>3.Ethical Curation: Just because AI can generate something, doesn’t mean it should be deployed. Humans remain the moral compass, especially in sensitive fields like medicine or finance.</p><p>4. Interdisciplinary Integration: Connecting AI outputs across law, business, and society requires a holistic perspective machines lack.</p><p>This shift may displace some traditional coding jobs, but it will also create new, higher-level roles — focused on guiding, managing, and integrating AI into the fabric of innovation.</p><h3>The Future of Recognition</h3><p>Look at chess: AI now plays better than any human. But we still celebrate grandmasters for their creativity, courage, and psychological insight. Similarly, in software and invention, recognition may evolve from who coded it to who guided it well.</p><p>Human ingenuity won’t vanish — it will simply move from execution to orchestration.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=623deb8018f7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Running Through History: 10Ks in Europe’s Greatest Cities]]></title>
            <link>https://medium.com/@amoljadhav_48655/running-through-history-10ks-in-europes-greatest-cities-e82faa2028fb?source=rss-52cdb9f437f0------2</link>
            <guid isPermaLink="false">https://medium.com/p/e82faa2028fb</guid>
            <category><![CDATA[travel]]></category>
            <category><![CDATA[europe]]></category>
            <category><![CDATA[traveling]]></category>
            <category><![CDATA[running]]></category>
            <dc:creator><![CDATA[Amol Jadhav]]></dc:creator>
            <pubDate>Mon, 18 Aug 2025 05:57:39 GMT</pubDate>
            <atom:updated>2025-08-18T05:57:39.405Z</atom:updated>
            <content:encoded><![CDATA[<p>Running has always been my way of exploring a city — it’s intimate, it’s raw, and it takes you through places tourists sometimes miss. On my recent trip to Europe, I found few beautiful 10K routes in every city I visited. From the historic streets of Rome to the riverside paths of Paris, here’s my adventure of running 10K across four incredible cities: Paris, Athens, Rome, and Munich.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XrxDMoWal1h9uiPhpZ2ztg.png" /></figure><h3>Paris — Along the Seine to the Eiffel Tower</h3><p>There’s nothing quite like running in Paris. My 10K started near the Latin Quarter and wound its way along the Seine. Each kilometer felt like a postcard — Notre Dame, the Louvre, Place de la Concorde, and finally, the Eiffel Tower waiting like a finish-line trophy.</p><p>Why it’s beautiful: The Seine is your running companion, and every bridge is a new perspective of the city. Finishing under the Eiffel Tower? It doesn’t get more iconic than that.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WW-V4_IwhZYLBTRFG3FmrQ.jpeg" /></figure><h3>Rome — From the Colosseum to Trastevere</h3><p>Rome is an open-air museum, and running here is like racing through history. My 10K route began near the Colosseum, passed Circus Maximus, and crossed the Tiber River into the vibrant Trastevere district. Every step had ancient ruins, cobblestone streets, and fountains as backdrops.</p><p>Why it’s beautiful: Few runs let you warm up with the Colosseum at sunrise and cool down in Trastevere’s lively piazzas. The mix of ancient and modern energy is unmatched.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KEEj-9aXIm8_kqOJFtOD4Q.jpeg" /></figure><h3>Athens — Through the Heart of Ancient Civilization</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dGXYUk0cO7Xwv_3U6psJuA.jpeg" /></figure><h3>Munich — The Ammersee Lakefront Escape</h3><p>Instead of city streets, Munich surprised me with a lakeside gem: Ammersee. My 10K run hugged the shoreline starting from Herrsching, with the water glistening on one side and Bavarian forests on the other. The route was calm, scenic, and refreshing.</p><p><strong>Why it’s beautiful:</strong> Running by Ammersee feels like meditation in motion — clear blue waters, sailboats drifting in the distance, and alpine air filling your lungs. It’s a perfect balance of endurance and tranquility.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lhzcmzHO_JcF_YiyE0Q5DA.jpeg" /></figure><h3>Final Thoughts</h3><p>Running 10K in each city gave me more than just fitness; it gave me a deep connection with the places I visited. Paris gave me elegance, Rome gave me history, Athens gave me legacy, and Munich gave me serenity. If you’re a running enthusiast and love travel, lace up your shoes — you’ll never see a city the same way again.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e82faa2028fb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Teamfight Tactics (TFT)Items: Your Super Simple Guide to Gearing Up Your Champions!]]></title>
            <link>https://medium.com/@amoljadhav_48655/teamfight-tactics-tft-items-your-super-simple-guide-to-gearing-up-your-champions-083bbf3a1a88?source=rss-52cdb9f437f0------2</link>
            <guid isPermaLink="false">https://medium.com/p/083bbf3a1a88</guid>
            <category><![CDATA[tft]]></category>
            <category><![CDATA[teamfight-tactics]]></category>
            <category><![CDATA[gaming]]></category>
            <dc:creator><![CDATA[Amol Jadhav]]></dc:creator>
            <pubDate>Sun, 06 Jul 2025 04:46:22 GMT</pubDate>
            <atom:updated>2025-07-06T04:46:22.157Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*80n5N2opCE_GiNF0vd1DaA.png" /></figure><h3>1. Introduction:</h3><p>In TFT, items are akin to the special equipment or superpowers that elevate your favorite superheroes. While a champion possesses inherent strength, equipping them with a magical staff, a robust shield, or a speed-boosting gauntlet unlocks their full potential. These items serve as crucial gear, making your champions stronger, faster, more resilient, or enabling them to unleash their extraordinary abilities more frequently. The strategic significance of items cannot be overstated: selecting and applying the correct items to the right champions is a pivotal factor in securing victory, allowing your team to outperform opponents in combat.</p><h3>2. The Building Blocks: Basic Item Components and Their Powers</h3><p>Every formidable item in TFT originates from fundamental building blocks, much like how intricate LEGO creations begin with individual bricks. There are nine primary basic items that form the foundation of all advanced gear, along with a distinct new addition in Set 13: the Frying Pan. Players typically acquire these components by defeating neutral monsters or by selecting them from the shared carousel rounds. Understanding the core function of each basic item is the first step toward mastering itemization.</p><ul><li><strong>B.F. Sword:</strong> This gleaming sword enhances a champion’s raw attack power, making their basic attacks hit with greater force. It is an ideal component for champions who rely on physical damage output.</li><li><strong>Chain Vest:</strong> A sturdy piece of armor, the Chain Vest provides physical defense, making champions more resistant to incoming physical attacks. It acts as a protective barrier, similar to a knight’s shield.</li><li><strong>Giant’s Belt:</strong> This substantial belt significantly increases a champion’s maximum health, allowing them to endure combat for longer durations. It effectively grants them additional survivability.</li><li><strong>Needlessly Large Rod:</strong> A mystical staff, the Needlessly Large Rod boosts the power of a champion’s spells and abilities, making their magical attacks or healing effects much more potent. It functions as a conduit for amplified magical energy.</li><li><strong>Negatron Cloak:</strong> This shadowy cloak grants magic resistance, reducing the damage taken from enemy spells and magical abilities. It provides a crucial defense against magic-focused compositions.</li><li><strong>Recurve Bow:</strong> A swift and agile bow, the Recurve Bow increases a champion’s attack speed, enabling them to launch attacks or abilities more rapidly. It is highly beneficial for champions who benefit from frequent offensive actions.</li><li><strong>Sparring Gloves:</strong> These versatile gloves offer a chance for champions to land critical strikes (attacks that deal extra damage) or to dodge incoming attacks. They introduce an element of precision and evasion to combat.</li><li><strong>Spatula:</strong> A truly unique and mysterious item, the Spatula provides no direct stats on its own. However, its true power lies in its ability to combine with any other basic item to grant a champion a new “trait,” effectively allowing them to join a new team synergy. It serves as a wildcard, capable of fundamentally altering team compositions.</li><li><strong>Tear of the Goddess:</strong> This luminous tear accelerates a champion’s mana regeneration, allowing them to cast their impactful abilities more frequently. It acts as a constant source of magical energy replenishment.</li><li><strong>Frying Pan (New!):</strong> Introduced in Set 13, the Frying Pan is more than just a cooking utensil. It provides champions with increased resilience against “critical hits” — those exceptionally strong attacks — and can even reflect a portion of the blocked damage back to the attacker. This makes it a powerful defensive tool against high-damage threats. A notable feature of the Frying Pan is its ability to be reforged into a Spatula, offering players increased flexibility in their item choices.</li></ul><p>The Frying Pan’s unique properties demonstrate a deeper layer of strategic flexibility within Set 13’s item system. Its primary defensive effect against critical strikes means that if opponents are prioritizing critical strike items, players can directly counter this strategy by building Frying Pans. Furthermore, its capacity to be reforged into a Spatula provides an adaptive pathway; if a player finds themselves needing a specific trait emblem for their composition, the Frying Pan can be converted to facilitate that need. This design choice means that item choices are not merely about accumulating raw power, but about dynamically responding to the evolving game state and opponent strategies, offering players more tools to adjust their approach.</p><h3>Table 1: Your Basic Item Toolbox</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yPnVxjp6ePl_UKpSAYxcdQ.png" /></figure><h3>3. Crafting Awesome Gear: Combined Items and Their Magic</h3><p>When two basic items are combined, they transform into a powerful “combined item,” representing the ultimate gear for your champions. These advanced items provide significant boosts and unique effects, tailored to specific champion roles.</p><h3>Items for Attackers (AD Carries): Make Them Hit Super Hard!</h3><p>These items are designed to maximize the physical damage output of champions who primarily rely on their basic attacks and attack-scaling abilities.</p><ul><li><strong>Infinity Edge:</strong> Formed by a B.F. Sword and Sparring Gloves, this item ensures that the champion’s attacks always land as critical strikes, delivering maximum damage. It is a cornerstone item for champions focused on consistent, high-impact auto-attacks.</li><li><strong>Deathblade:</strong> Created by combining two B.F. Swords, the Deathblade provides a substantial increase to a champion’s raw attack damage. This item is particularly effective on champions like Draven, whose abilities scale directly with their attack damage.</li><li><strong>Guinsoo’s Rageblade:</strong> The combination of a Needlessly Large Rod and a Recurve Bow, this item grants stacking attack speed with every attack, allowing the champion to attack progressively faster throughout combat. It is invaluable for hyper-carries who benefit from sustained, rapid attacks.</li><li><strong>Giant Slayer:</strong> Crafted from a B.F. Sword and a Recurve Bow, this item causes the champion to deal additional damage to enemies with high maximum health. It is one of the few items that offers multiplicative scaling, making it exceptionally potent against durable frontline units.</li><li><strong>Last Whisper:</strong> Combining Sparring Gloves and a Recurve Bow, this item allows a champion’s physical damage to reduce the target’s armor. This effect makes enemies easier to damage, especially those with significant defensive stats, and pairs well with Infinity Edge against armored teams.</li><li><strong>Runaan’s Hurricane:</strong> Made from a Negatron Cloak and a Recurve Bow, this item causes the champion’s basic attacks to fire an additional projectile at a nearby enemy. This effectively allows the champion to damage multiple targets simultaneously, providing multiplicative scaling for auto-attack focused champions.</li></ul><h3>Items for Spellcasters (AP Carries): Make Their Spells Powerful!</h3><p>These items are tailored to enhance the magical damage and ability casting frequency of champions who rely on their spells.</p><ul><li><strong>Blue Buff:</strong> Created by combining two Tears of the Goddess, this item is a potent mana-generating tool. It is primarily used on champions with low mana costs, enabling them to cast their abilities continuously and rapidly.</li><li><strong>Spear of Shojin:</strong> The result of combining a B.F. Sword and a Tear of the Goddess, this item restores mana to the champion with each attack. It is highly effective for champions who benefit from frequent ability casts and also have a reasonable attack speed.</li><li><strong>Jeweled Gauntlet:</strong> Crafted from Sparring Gloves and a Needlessly Large Rod, this item allows a champion’s spells to critically strike, significantly increasing their burst damage potential. It is a very powerful item for magic damage carries seeking multiplicative scaling.</li><li><strong>Rabadon’s Deathcap:</strong> Formed by combining two Needlessly Large Rods, this item provides a substantial boost to a champion’s ability power, making their spells hit much harder. It is a core item for spellcasters aiming for raw damage amplification.</li><li><strong>Archangel’s Staff:</strong> The combination of a Tear of the Goddess and a Needlessly Large Rod, this item causes a champion’s ability power to increase progressively throughout combat. This makes their spells grow stronger as the fight progresses, benefiting champions who can sustain long engagements.</li><li><strong>Morellonomicon:</strong> Made from a Giant’s Belt and a Needlessly Large Rod, this item applies a burn effect and reduces healing received by enemies hit by the champion’s spells. It is highly effective against compositions with significant healing and is particularly strong on champions with area-of-effect abilities.</li></ul><h3>Items for Tanks (Frontliners): Make Them Super Tough!</h3><p>These items are designed to maximize the durability and survivability of champions positioned on the frontline to absorb damage.</p><ul><li><strong>Warmog’s Armor:</strong> Created by combining two Giant’s Belts, this item provides an immense boost to a champion’s maximum health, making them exceptionally difficult to defeat. It is a solid choice for increasing the survivability of any unit, whether a dedicated tank or a crucial unit that needs to remain alive.</li><li><strong>Bramble Vest:</strong> Formed by combining two Chain Vests, this item reduces damage taken from critical strikes and passively deals magic damage to adjacent enemies when struck by an attack. It is excellent for tanks, particularly against physical damage compositions.</li><li><strong>Dragon’s Claw:</strong> The result of combining two Negatron Cloaks, this item provides substantial magic resistance, significantly reducing incoming magic damage. It is ideal for frontliners facing magic-heavy enemy teams.</li><li><strong>Gargoyle Stoneplate:</strong> Crafted from a Negatron Cloak and a Chain Vest, this item grants increasing armor and magic resistance for each enemy targeting the holder. It is exceptionally powerful on solo frontline units, making them incredibly durable when focused.</li><li><strong>Steadfast Heart:</strong> Combining Sparring Gloves and a Chain Vest, this item provides universal damage reduction, making the champion more durable against all forms of incoming damage. It is a strong and flexible defensive option.</li></ul><h3>Handy Utility Items: For Special Situations!</h3><p>These items offer unique effects that can turn the tide of battle or provide crucial strategic advantages.</p><ul><li><strong>Edge of Night:</strong> Made from a B.F. Sword and a Chain Vest, this item allows the champion to briefly become untargetable and shed negative effects upon reaching low health, gaining bonus attack speed afterward. It is valuable for champions who might be targeted by assassins or frontline carries needing an escape.</li><li><strong>Hextech Gunblade:</strong> The combination of a B.F. Sword and a Needlessly Large Rod, this item grants omnivamp, healing the champion for a percentage of all damage they deal, whether from attacks or spells. It benefits both spell-reliant units and most damage dealers.</li><li><strong>Ionic Spark:</strong> Crafted from a Needlessly Large Rod and a Negatron Cloak, this item reduces the magic resistance of nearby enemies and zaps them with magic damage when they cast abilities. It is a great utility item for frontliners, benefiting all magic damage compositions.</li><li><strong>Thief’s Gloves:</strong> Created by combining two Sparring Gloves, this item equips the champion with two random completed items each round. While its outcome is based on chance, it generally provides decent items and can be particularly strong on high-cost champions.</li><li><strong>Tactician’s Crown:</strong> The ultimate team-size item, formed by combining two Spatulas, this item allows a player to field one additional champion on their board, providing a significant power boost to the team.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*F7k3GM5jUdnxWOKJaGAH5Q.png" /></figure><p>The diverse range of combined items, including highly specialized effects like Guardbreaker (designed to counter shielded units), Giant Slayer (effective against high-health targets), Last Whisper (reduces enemy armor), and Ionic Spark (shreds magic resistance), highlights a critical aspect of Set 13 itemization. This is not merely about accumulating raw statistical power; it is about understanding and leveraging specific interactions. This means that achieving success in TFT Set 13 requires players to select items that directly counter their opponents’ strategies or perfectly complement their own team’s strengths. For instance, if multiple opponents are building compositions reliant on shields, Guardbreaker’s value increases dramatically. This strategic depth encourages players to actively observe their opponents’ boards and adapt their item choices accordingly, transforming itemization into a dynamic layer of strategic decision-making beyond simple power boosts.</p><h3>4. Smart Shopping: How to Pick the Best Items for Your Team</h3><p>When equipping champions in TFT, it is important to remember that simply stacking large amounts of the same statistic does not always yield the best results. For example, providing a champion with an excessive amount of attack power without balancing it with attack speed will not make them proportionally stronger. This concept is often referred to as “diminishing returns,” where adding more of the same type of power becomes less impactful beyond a certain point. Optimal itemization involves a balanced approach, combining different types of statistical boosts to create a more potent champion. For instance, a champion equipped with both additional attack power and increased attack speed will generally perform far better than one with only a massive amount of attack power.</p><h3>Tips for Different Champions:</h3><p>Understanding the primary role of each champion type is crucial for effective itemization.</p><ol><li><strong>Attackers (AD Carries):</strong> These champions excel at dealing sustained physical damage through their basic attacks. They benefit greatly from items that boost their raw attack damage, such as <strong>Infinity Edge</strong> or <strong>Deathblade</strong>. To maximize their output, items that increase attack speed, like <strong>Guinsoo’s Rageblade</strong> or <strong>Red Buff</strong>, are also vital. Furthermore, items that amplify the impact of each hit, such as <strong>Giant Slayer</strong> (for high-health targets) or <strong>Last Whisper</strong> (to bypass armor), are highly desirable. <strong>Spear of Shojin</strong> to accelerate her ability casts, which in turn reduces enemy armor and magic resistance, and <strong>Last Whisper</strong> to ensure her attacks penetrate defenses. In contrast, Jinx, known for her rapid attacks, finds <strong>Guinsoo’s Rageblade</strong> exceptionally effective for its stacking attack speed.</li></ol><p><strong>2. Spellcasters (AP Carries):</strong> These champions unleash powerful magical abilities to deal damage or provide utility. Their itemization prioritizes mana generation to enable frequent spell casts, with items like <strong>Blue Buff</strong> or <strong>Spear of Shojin</strong>. To enhance the impact of their spells, <strong>Rabadon’s Deathcap</strong> or <strong>Archangel’s Staff</strong> provide significant ability power boosts. For spellcasters whose abilities can critically strike, <strong>Jeweled Gauntlet</strong> is essential to amplify their burst damage. <strong>Spear of Shojin</strong> and <strong>Jeweled Gauntlet</strong> to cast her powerful monkey ability quickly and ensure it deals substantial damage.</p><p><strong>3. Tanks (Frontliners):</strong> These champions are designed to absorb incoming damage, protecting the rest of the team. Their item builds focus on maximizing their survivability. Items that provide substantial health, such as <strong>Warmog’s Armor</strong>, are fundamental. Defensive items like <strong>Bramble Vest</strong> (for physical damage reduction and retaliation) and <strong>Dragon’s Claw</strong> (for magic damage reduction) are crucial for mitigating specific damage types. Sett, for instance, is an excellent tank who becomes incredibly resilient when equipped with. <strong>Warmog’s Armor</strong>, <strong>Bramble Vest</strong>, and <strong>Dragon’s Claw</strong>, allowing him to sustain through prolonged engagements.</p><h3>Early Game vs. Late Game Items: When to Build What!</h3><p>Itemization also involves a crucial temporal aspect. In the early stages of a game, players often prioritize “tempo items” that provide immediate power to win fights and preserve health, which can translate into more gold later. <strong>Sunfire Cape</strong>, with its area-of-effect burn, is an excellent example of an early-game item that can help secure win streaks. As the game progresses, the focus shifts to fully equipping primary carries and tanks. It is highly advantageous to secure three completed items on your main damage dealer and main tank as quickly as possible. If item components are scarce, special “Item Augments” can provide additional components or even completed items, accelerating the itemization process.</p><p>The dynamic nature of itemization in TFT Set 13 means players must constantly weigh immediate strength against long-term scaling. This requires adapting item choices not only to the champions on the board but also to the current stage of the game and the player’s economic standing. This creates a complex and rewarding decision-making loop where strategic foresight and adaptability are paramount for success.</p><h3>5. The Mysterious Frying Pan!</h3><p>The Frying Pan, while a basic item component, warrants special attention due to its unique strategic implications:</p><ul><li><strong>Crit Counter:</strong> Its primary function is to reduce the damage taken from “critical hits” and even reflect a portion of that damage back to the attacker. This makes it an invaluable defensive tool when facing compositions that heavily rely on critical strike damage, offering a direct counterplay option.</li><li><strong>Emblem Creator:</strong> Beyond its defensive utility, the Frying Pan is also unique in its ability to combine with other basic items to forge “Emblems” for various traits, such as Bruiser, Sorcerer, or Sentinel. These Emblems are powerful because they grant a champion a new trait, which can be crucial for reaching higher, more potent trait breakpoints within a team composition.</li></ul><h3>6. Conclusion: Go Forth and Gear Up!</h3><p>The journey through Teamfight Tactics Set 13’s item system reveals that items are far more than mere statistical boosts; they are the superpowers that define a champion’s role and dictate a team’s strategic direction. Understanding the fundamental properties of each basic component is the first step, as these form the building blocks for all advanced gear. The subsequent mastery of combining these components into powerful items, tailored to the specific needs of attackers, spellcasters, and tanks, is crucial for optimizing team performance.</p><p>A key takeaway from Set 13’s itemization philosophy is the importance of balanced stat distribution. Over-investing in a single stat can lead to diminishing returns, whereas a diversified approach, combining various offensive or defensive attributes, unlocks a champion’s full potential. Furthermore, the strategic value of counter-items cannot be overstated, as they provide critical tools to adapt to and overcome opponent strategies. The game also encourages dynamic itemization, where players must weigh the immediate benefits of “tempo items” against the long-term scaling potential of core item builds, adjusting their approach based on the evolving game state and economic conditions.</p><p>Ultimately, success in TFT Set 13 hinges on a comprehensive understanding of its item system. This includes not only knowing what each item does but also grasping the deeper implications of item synergies, counter-play, and strategic flexibility. The best way to internalize these concepts is through active engagement and experimentation. Players are encouraged to embrace the dynamic nature of itemization, try different combinations, and observe their effects. Every game presents a new opportunity to refine item strategies, paving the way to becoming a true TFT master.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=083bbf3a1a88" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What Stands in the Way of AGI? The Looming Energy Crisis?]]></title>
            <link>https://medium.com/@amoljadhav_48655/what-stands-in-the-way-of-agi-the-looming-energy-crisis-9b6ffcfe5538?source=rss-52cdb9f437f0------2</link>
            <guid isPermaLink="false">https://medium.com/p/9b6ffcfe5538</guid>
            <category><![CDATA[energy]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[aritificial-intelligence]]></category>
            <dc:creator><![CDATA[Amol Jadhav]]></dc:creator>
            <pubDate>Sat, 05 Jul 2025 21:46:35 GMT</pubDate>
            <atom:updated>2025-07-05T21:50:08.749Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>Imagine you’re trying to build the smartest robot brain ever. Every time you make its brain cells (computer chips) twice as smart, they also get twice as hungry for food (electricity) and produce twice as much heat.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wR3kgYLjGFUASm-hNMVoFw.png" /></figure><h3>Introduction: The AGI Dream: Promise vs. Reality</h3><p>The idea of Artificial General Intelligence (AGI) — machines that can think, learn, and adapt like humans across many different tasks — is incredibly exciting. It promises to change our world in ways we can barely imagine. However, reaching AGI isn’t just a software challenge; it comes with some very real, physical hurdles, especially concerning the massive amounts of computing power and energy it would need. As the saying goes, “Compute &amp; Energy Chips” are hotter than rockets; AGI could gulp terawatt-hours without breakthroughs.” This isn’t just a minor technical issue; it’s a fundamental roadblock that we need to understand and address.</p><p>Even today’s advanced AI models consume huge amounts of electricity and generate a lot of heat, pushing our current technology to its limits. AGI, which would be constantly learning and adapting, is expected to need far, far more. This raises big questions about whether we can actually sustain such a future. This article will explore these compute and energy challenges, explain what they mean for AGI, and look at some of the clever solutions scientists are working on.</p><h3>What is Artificial General Intelligence?</h3><p>AGI is a theoretical concept about creating AI that has human-like intelligence. This means it could teach itself new things and perform tasks it wasn’t specifically programmed for. Unlike the AI we use today, which is very good at specific jobs (like recognizing faces or translating languages), an AGI system would be able to solve complex problems in many different areas, much like a human. It’s about replicating human thinking abilities, including being able to control itself, understand itself, and learn new skills in new situations.</p><h3>How AGI Differs from Current AI (Like ChatGPT)</h3><p>Today’s most impressive AI, including the large language models (LLMs) like ChatGPT, are forms of “narrow AI.” They are excellent at their specific tasks, whether it’s generating text, understanding speech, or identifying objects. But they can’t suddenly switch to a completely new, untrained area on their own.</p><p>For example, while ChatGPT can write amazing articles, it still relies on humans to set up the problem, design its core structure, and select the data it learns from. It’s great at “well-structured problems” (where the rules are clear), but it needs human help to simplify “ill-structured problems.” This dependence on human input means that current AI models, despite their power, aren’t truly general. To reach AGI, we need a major shift in how AI systems learn and adapt independently. Simply making current models bigger won’t be enough; it will just make the energy problem worse if the basic approach isn’t efficient for true general intelligence.</p><h3>The Current AI Energy Footprint: A Glimpse into the Future</h3><h3>How Much Power Do Today’s AI Models Use?</h3><p>The current generation of large AI models already uses a lot of energy. For instance, training a model like GPT-3 consumed between 324 to 1,287 MWh (megawatt-hours) of electricity. To put that in perspective, that’s roughly the same amount of electricity used by <strong>120 US homes in a whole year</strong>. Newer models like GPT-4 and Claude 3 Opus are even larger, likely needing 2 to 4 times more energy to train.</p><p>But it’s not just about training. The daily use of these models, called “inference,” is quickly becoming the biggest energy user. A single query to ChatGPT, especially for advanced models like GPT-4o, uses about <strong>0.43 watt-hours (Wh)</strong> of energy. This is <strong>ten times more</strong> than a typical Google search. With millions of queries happening every day, the total energy used for inference is now greater than that used for training. This is a big change. <strong>While training is a huge, but one-time, energy cost, inference is a continuous and growing demand that increases as more people use AI.</strong> For AGI, which is imagined as being “always-on” and constantly adapting, the total energy cost of its ongoing operation will be far greater than its initial training. This means we need to focus on making AI efficient for continuous use, not just for the initial setup.</p><h3>The Self-Accelerating Loop: AI Demanding More AI</h3><p>A worrying trend is that AI is now being used to design more efficient chips. As AGI develops, it could learn to re-train itself, control advanced computers to optimize its own models, and even design better hardware. This creates a cycle: “More AI → More Compute → More Energy → More Emissions.” This means the energy demand isn’t just growing linearly; it could grow exponentially and become self-perpetuating. If AGI can improve its own hardware and algorithms, its energy needs could increase much faster than human innovation can predict or control. This makes it urgent to develop sustainable solutions before AGI reaches a point where it can rapidly improve itself, as the problem could quickly become too big to manage.</p><h3>AGI’s Insatiable Appetite: Projections and the Scaling Challenge</h3><h3>How Much Compute Would Human-Level AGI Need?</h3><p>Estimates for the computing power needed for human-level AGI vary a lot. Some researchers think a powerful gaming PC (like an Nvidia GeForce RTX 4090, with about 8.3e13 FLOP/s) might be enough for human-level AGI. This is based on comparing AGI to the human brain’s computational power.</p><p>However, the median forecast from 108 AI experts is much higher, at 3e17 FLOP/s (floating point operations per second). This is orders of magnitude more powerful than current consumer hardware.</p><p>The human brain is incredibly efficient at learning. To “train” a human to be an engineer takes about 20 times the compute of one year of their work. Compare this to current AI language models, where this factor can be “several hundred million” times higher! This huge difference in efficiency, where the human brain learns and operates with far less training overhead, points to a big “algorithmic efficiency gap” between biological and artificial intelligence. If AGI is truly general and always learning, it can’t afford the current AI paradigm’s training inefficiency. This means we need fundamental breakthroughs in algorithms, perhaps inspired by how the brain works, just as much as we need raw hardware power.</p><h3>Projected Energy Demands for AGI-Scale Models</h3><p>If current trends continue and the “scaling hypothesis” proves true, AGI-scale models are expected to be “power devourers.” They will likely need constant computation, real-time adaptation, and much larger models trained with more data and longer cycles. Forecasts suggest AGI-scale models could use <strong>10 to 100 times more energy</strong> than current Generative AI.</p><p>Data center projections really show the scale of this challenge: In 2023, AI-related data centers used about 4.5 GW (gigawatts) globally. This is expected to jump to 14–18.7 GW by 2028, potentially making up 20% of all data center energy use. All global data centers together used about 415 TWh (terawatt-hours) in 2024 (about 1.5% of global electricity). This is expected to more than double by 2030, possibly reaching 1,000–1,300 TWh. The International Energy Agency (IEA) predicts that data centers’ total electricity use could exceed 1,000 TWh by 2026, which is roughly equal to <strong>Japan’s entire annual electricity consumption</strong>. In the United States, AI-driven data centers could account for almost half of the growth in electricity demand by 2030. This comparison to a whole country’s energy use shows that this isn’t a small increase, but a huge national-level energy requirement that will put immense strain on power grids worldwide. This means the energy challenge for AGI isn’t just a tech problem; it’s a global infrastructure and geopolitical issue.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vi6yyv8H7YuJ3S7-Y4SpEg.png" /></figure><h3>Conclusion: Navigating the Energy Crossroads to AGI</h3><p>While an individual’s daily use of ChatGPT uses very little electricity, the combined effect of widespread AI adoption is huge. The total daily queries for just one advanced model like GPT-4o already use as much electricity annually as tens of thousands of U.S. homes, and this includes all the significant energy used by data center infrastructure. Looking ahead, the growth of AI-driven data centers is projected to double global data center electricity consumption by 2030. This increasing demand poses major challenges for our energy grids.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9b6ffcfe5538" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Power of 2 in Computer Science: Fundamentals]]></title>
            <link>https://medium.com/@amoljadhav_48655/the-power-of-2-in-computer-science-fundamentals-79c69d1d950a?source=rss-52cdb9f437f0------2</link>
            <guid isPermaLink="false">https://medium.com/p/79c69d1d950a</guid>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[memory-management]]></category>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[fundamentals]]></category>
            <category><![CDATA[storage]]></category>
            <dc:creator><![CDATA[Amol Jadhav]]></dc:creator>
            <pubDate>Tue, 28 May 2024 14:59:37 GMT</pubDate>
            <atom:updated>2024-05-28T14:59:37.208Z</atom:updated>
            <content:encoded><![CDATA[<h4>Introduction</h4><p>Have you ever wondered why computers seem to love the number 2 so much? Well, it all starts with something called the binary system, which is the foundation of all computing. In this article, we’ll explore why the number 2 is so important, how it works, and how it’s used in computer science and various applications.</p><h4>The Magic of the Number 2</h4><p>What is Binary?</p><ul><li><strong>Binary System:</strong> The binary system is like the language of computers. Instead of using ten digits (0–9) like we do in the decimal system, binary only uses two digits: 0 and 1.</li><li><strong>Base of 2:</strong> Binary is a base-2 system, which means every number is represented using only the digits 0 and 1.</li></ul><p><strong>Why Base 2?</strong></p><blockquote><em>Computers are built using millions of tiny switches called transistors. These switches can be either off (0) or on (1). Using binary makes it simple for computers to store and process information because it matches the physical nature of the hardware.</em></blockquote><p><strong>What are Transistors? </strong>Transistors are tiny electronic devices that act as switches in a computer. They can be in one of two states: off (0) or on (1).</p><p><strong>How They Work:</strong> When electricity flows through a transistor, it turns on (1). When there is no electricity, it turns off (0). These simple on/off states are the foundation of all computer operations.</p><p><strong>Storing Data:</strong> Each bit of data (binary digit) is represented by a transistor. For example, the binary number 1011 is represented by four transistors in the states: on (1), off (0), on (1), and on (1).</p><p><strong>Characters in Binary:</strong> To represent characters like “A”, computers use a standard encoding system called ASCII (American Standard Code for Information Interchange). Each ASCII character is represented using 8 bits (1 byte). For example, the character “A” is represented by the binary number 01000001.</p><p>Example: Representing “A” in Binary:</p><ul><li>The ASCII value for “A” is 65.</li><li>The binary representation of 65 is 01000001.</li><li>Transistors Needed: Each bit in the binary representation of “A” corresponds to a transistor. Therefore, it takes 8 transistors to represent the character “A”.</li></ul><blockquote>Powers of 2 are the foundation of the binary system. Each bit (binary digit) in a computer represents a power of 2.</blockquote><blockquote>Computer memory and storage are often organized in sizes that are powers of 2, like 1 KB (kilobyte) being 1024 bytes (2¹⁰).</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1VKXFTNVP8OPPl1YdlD1Zw.png" /></figure><h4>How Computers Use Powers of 2</h4><p><strong>Memory and Storage:</strong></p><ul><li>Memory Sizes: Memory sizes in computers are always powers of 2. For example: 1 KB = 1024 bytes (2¹⁰) 1 MB = 1024 KB (2²⁰) 1 GB = 1024 MB (2³⁰)</li></ul><p><strong>Data Structures:</strong></p><ul><li>Binary Trees: In a binary tree, each node has up to two children. The height and balance of these trees often involve powers of 2.</li><li>Heaps: A binary heap is a special tree-based data structure that satisfies the heap property and relies on binary principles.</li></ul><p><strong>Algorithms:</strong></p><ul><li><strong>Divide and Conquer: </strong>Algorithms like mergesort and quicksort use a divide-and-conquer strategy, splitting data into halves, leveraging the power of 2 for efficiency.</li><li><strong>Exponentiation by Squaring: </strong>This method efficiently computes large powers by breaking the problem into smaller powers of 2.</li></ul><p><strong>Networking:</strong></p><ul><li><strong>IP Addresses:</strong> IPv4 addresses are 32-bit numbers, allowing for 2³² unique addresses.</li><li><strong>Subnets: </strong>Network subnets are often divided using powers of 2 to create efficient and manageable networks.</li></ul><h4>Why Understanding Powers of 2 is Awesome</h4><p><strong>Efficiency: </strong>Knowing about powers of 2 helps you understand how computers work efficiently. It’s like having a superpower to see behind the scenes of technology.</p><p><strong>Problem-Solving: </strong>Many problems in computer science can be simplified by understanding powers of 2. It helps in designing faster algorithms and managing data better.</p><p><strong>Hardware Design: </strong>Hardware engineers design memory, processors, and storage devices around powers of 2. It’s crucial for creating the gadgets and devices we use every day.</p><h4>Conclusion</h4><p>The power of 2 is a cornerstone of computer science, forming the basis of binary systems, memory organization, data structures, and algorithms. By understanding how powers of 2 work and their applications, you can gain a deeper appreciation for the technology we use daily and become better at solving problems and designing efficient systems. Whether you’re counting on your fingers or designing the next big app, the power of 2 is your friend in the world of computing.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=79c69d1d950a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding Sharding: Scaling Databases Horizontally]]></title>
            <link>https://medium.com/@amoljadhav_48655/understanding-sharding-scaling-databases-horizontally-9f0c53a3ed4f?source=rss-52cdb9f437f0------2</link>
            <guid isPermaLink="false">https://medium.com/p/9f0c53a3ed4f</guid>
            <category><![CDATA[database]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[sharding]]></category>
            <category><![CDATA[system-design-concepts]]></category>
            <category><![CDATA[system-design-interview]]></category>
            <dc:creator><![CDATA[Amol Jadhav]]></dc:creator>
            <pubDate>Mon, 27 May 2024 20:16:34 GMT</pubDate>
            <atom:updated>2024-05-27T20:16:34.615Z</atom:updated>
            <content:encoded><![CDATA[<p>As data grows exponentially, it becomes crucial to ensure your database can handle the increased load while maintaining performance. Sharding, a form of database partitioning, is a powerful technique that allows you to scale your system horizontally. This article will guide you through the fundamentals of sharding.</p><blockquote>Imagine you have a giant pile of LEGO bricks. Finding the right piece in this huge pile can be slow and frustrating. Sharding is like organizing these bricks into smaller piles based on color or type, making it easier and faster to find the pieces you need.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Pchc8Myv_VZw3pyjsrnBOQ.png" /></figure><h3>What is Sharding?</h3><p>At its core, sharding is the process of splitting a large database into smaller, more manageable pieces called shards. Each shard operates as an independent database, holding a subset of the total data. This distributed approach allows you to spread the data load across multiple servers, improving performance and facilitating horizontal scaling.</p><h4>Why Use Sharding?</h4><ol><li><strong>Scalability</strong>: Sharding enables horizontal scaling, allowing you to add more servers to handle increasing loads.</li><li><strong>Performance</strong>: Distributing data across multiple servers reduces the load on each server, leading to faster query response times.</li><li><strong>Availability</strong>: With data spread across multiple servers, the system can remain operational even if one server fails.</li><li><strong>Cost Efficiency:</strong> Scaling out with multiple smaller servers can be more cost-effective than continually upgrading a single large server.</li></ol><h4>Basic Sharding Strategies</h4><ol><li><strong>Range Sharding:</strong> Data is divided into shards based on ranges of a sharding key. <strong>Example</strong>: Users with IDs 1–1000 go to Shard 1, IDs 1001–2000 to Shard 2. <strong>Pros</strong>: Simple to implement and understand. <strong>Cons</strong>: Can lead to uneven distribution if data is not uniformly distributed.</li><li><strong>Hash Sharding:</strong> A hash function is applied to a sharding key, and the. result determines the shard. <strong>Example</strong>: The hash of a user ID modulo the number of shards determines the shard <strong>Pros</strong>: Evenly distributes data across shards. <strong>Cons</strong>: Range queries can be complex and less efficient.</li><li><strong>Geographic Sharding:</strong> Data is divided based on geographic location. <strong>Example:</strong> Users in North America are stored in Shard 1, users in Europe in Shard 2. <strong>Pros:</strong> Reduces latency by keeping data close to users. <strong>Cons:</strong> Managing data that spans multiple regions can be complex.</li></ol><h4>Advanced Sharding Techniques</h4><ol><li><strong>Consistent Hashing:</strong> Distributes data across nodes using a hash function that maps both data and nodes to a ring. <strong>Example:</strong> Data and nodes are assigned positions on a circular ring using a hash function. <strong>Pros:</strong> Minimizes data movement when nodes are added or removed; evenly distributes data. <strong>Cons:</strong> More complex to implement and manage.</li><li><strong>Directory-Based Sharding:</strong> Uses a lookup table to map each data item to a specific shard. <strong>Example</strong>: A central directory maintains a map of user IDs to shard numbers. <strong>Pros</strong>: Provides flexibility in shard assignment. <strong>Cons</strong>: Introduces additional complexity in maintaining the directory.</li><li><strong>Composite Sharding: </strong>Combines multiple sharding strategies to optimize data distribution. <strong>Example</strong>: Data is first sharded by geographic location and then by hash within each geographic shard. <strong>Pros</strong>: Can handle complex data distribution needs. <strong>Cons</strong>: Implementation and maintenance can be challenging.</li></ol><h4>Implementing Sharding: A Step-by-Step Guide</h4><ol><li><strong>Identify the Shard Key:</strong> Choose a key that will determine how data is distributed. A good shard key ensures even distribution and minimizes cross-shard queries.</li><li><strong>Design the Shard Schema:</strong> Plan how data will be partitioned. Decide on the number of shards and how they will grow over time.</li><li><strong>Set Up Infrastructure:</strong> Deploy the necessary hardware or cloud instances to host the shards. Ensure network configuration supports efficient communication between shards.</li><li><strong>Implement Sharding Logic:</strong> Modify your application to include sharding logic. This might involve adding middleware or using database features that support sharding.</li><li><strong>Monitor and Adjust:</strong> Continuously monitor the performance of your shards. Adjust the distribution or add more shards as needed to handle increased load.</li></ol><h4>Real-World Examples</h4><ol><li>Facebook: Uses a sharded MySQL architecture to manage billions of users’ data, ensuring scalability and performance.</li><li>Twitter: Employs sharding to handle massive amounts of tweets, user data, and interactions efficiently.</li><li>Amazon: Utilizes sharding to scale its e-commerce platform, ensuring fast and reliable service for millions of customers worldwide.</li><li>Ethereum Sharding: Sharding in Ethereum is designed to improve scalability by splitting the blockchain into multiple shards, each capable of processing its fown transactions and smart contracts.</li></ol><h4>Conclusion</h4><p>Sharding is a powerful tool for managing large-scale databases, providing scalability, improved performance, and increased availability. By understanding both basic and advanced sharding techniques, you can design a system that meets your application’s needs and efficiently handles growing data volumes. Implementing sharding requires careful planning and consideration, but the benefits make it a worthwhile investment for any large-scale application.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9f0c53a3ed4f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Message Queues: The Backbone of Scalable Software Systems]]></title>
            <link>https://medium.com/@amoljadhav_48655/message-queues-the-backbone-of-scalable-systems-2d015d9fa645?source=rss-52cdb9f437f0------2</link>
            <guid isPermaLink="false">https://medium.com/p/2d015d9fa645</guid>
            <category><![CDATA[system-design-interview]]></category>
            <category><![CDATA[message-queue]]></category>
            <category><![CDATA[scalability]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[microservices]]></category>
            <dc:creator><![CDATA[Amol Jadhav]]></dc:creator>
            <pubDate>Sun, 26 May 2024 03:51:44 GMT</pubDate>
            <atom:updated>2024-05-26T03:56:35.317Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>Think of a message queue like a school cafeteria line. Each student (producer) writes down their lunch order on a piece of paper (message) and puts it in a box (queue). The cafeteria workers (consumers) take one order at a time from the box and prepare the lunch. Even if a lot of students put their orders in the box at the same time, the cafeteria workers can still make the lunches one by one. This way, everyone gets their lunch, and the cafeteria workers don’t get overwhelmed.</blockquote><p><strong>What is a Message Queue?</strong></p><p>A message queue is a mechanism for asynchronous communication between services, commonly used in serverless and microservices architectures. It enables different components of a system to communicate and perform tasks independently by decoupling the sending and receiving processes. Essentially, a message queue serves as a buffer that temporarily holds messages (such as tasks, data, or events) until they are retrieved and processed by the receiving service. This approach enhances system reliability, scalability, and maintainability by allowing services to function and scale independently.</p><p><strong>Key Concepts:</strong></p><blockquote><strong>Producer and Consumer</strong>: <strong>Producer</strong> is the entity that sends messages to the queue. <strong>Consumer</strong> is the entity that retrieves and processes messages from the queue.</blockquote><blockquote><strong>Message: </strong>A discrete unit of data passed between the producer and the consumer via the queue. Messages can contain various types of information, such as job instructions, event notifications, or data payloads.</blockquote><pre>{<br>  &quot;orderId&quot;: &quot;12345&quot;,<br>  &quot;customerId&quot;: &quot;67890&quot;,<br>  &quot;items&quot;: [<br>    {&quot;itemId&quot;: &quot;abc&quot;, &quot;quantity&quot;: 2},<br>    {&quot;itemId&quot;: &quot;def&quot;, &quot;quantity&quot;: 1}<br>  ],<br>  &quot;orderTimestamp&quot;: &quot;2023-05-25T15:30:00Z&quot;<br>}</pre><blockquote><strong>Queue: </strong>A data structure that holds messages until they are processed. The queue ensures that messages are delivered in a reliable and ordered manner.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1010/1*wkg4tIRxrjoIBBwbuSduvw.png" /></figure><p><strong>Why Use Message Queues?</strong></p><ol><li><strong>Decoupling:</strong> Message queues enable different components of a system to function independently by acting as intermediaries between producers and consumers. This allows producers to send messages at their own pace and consumers to process those messages at a different rate, without causing disruptions. As a result, message queues enhance system modularity and flexibility, allowing each part of the system to scale and evolve independently.</li><li><strong>Scalability:</strong> By decoupling services, message queues enable systems to scale more effectively. Additional consumers can be added to process the queued messages, allowing the system to handle increased loads.</li><li><strong>Reliability: </strong>Message queues provide reliability through features like message persistence and delivery guarantees. Even if a consumer fails, the messages remain in the queue until they are successfully processed.</li><li><strong>Load Balancing:</strong> Queues can distribute work among multiple consumers, ensuring that no single consumer is overwhelmed, which enhances system performance and resource utilization.</li></ol><p><strong>Popular Message Queue Implementations:</strong></p><ol><li><strong>RabbitMQ:</strong> A widely-used open-source message broker that implements the Advanced Message Queuing Protocol (AMQP). It supports various messaging patterns and provides robust features like message acknowledgments and persistent storage. <strong>Use Case:</strong> Reddit uses RabbitMQ to manage its message queue for handling a variety of tasks. This includes background job processing, real-time message delivery, and coordination between microservices. <strong>Reason for Choice:</strong> RabbitMQ’s support for multiple messaging patterns, robust features like message acknowledgments, persistent storage, and its reliability in delivering messages make it suitable for handling Reddit’s diverse and high-volume message traffic.</li><li><strong>Apache Kafka: </strong>A distributed streaming platform often used for building real-time data pipelines and streaming applications. Kafka is known for its high throughput and fault tolerance. <strong>Use Case:</strong> Netflix uses Apache Kafka for real-time data streaming to monitor the state of its distributed systems. Kafka helps in collecting and processing event data from various microservices. <strong>Reason for Choice: </strong>Kafka’s distributed nature, scalability, and fault tolerance are essential for Netflix’s large-scale, real-time data processing requirements.</li><li><strong>Amazon SQS (Simple Queue Service):</strong> A fully managed message queuing service by AWS. It offers scalability, durability, and ease of use, making it a popular choice for cloud-based applications. <strong>Use Case:</strong> Airbnb uses Amazon SQS to decouple components of its application. SQS helps in managing background jobs, handling asynchronous processing, and ensuring reliable communication between microservices. <strong>Reason for Choice: </strong>SQS’s fully managed nature, ease of use, scalability, and integration with other AWS services make it ideal for Airbnb’s cloud-based architecture.</li><li><strong>ActiveMQ: </strong>An open-source message broker that supports multiple messaging protocols. It is often used in enterprise environments and provides features like clustering and message routing. <strong>Use Case:</strong> JPMorgan Chase uses ActiveMQ for processing financial transactions and ensuring reliable communication between different parts of their financial systems. <strong>Reason for Choice:</strong> ActiveMQ’s reliability, support for JMS (Java Message Service), and its ability to handle the demands of a financial institution with high transaction volumes and stringent reliability requirements.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/966/1*SV85uebA7abKIGgWJhW4Dw.png" /></figure><p><strong>Common Message Queue Patterns:</strong></p><blockquote><strong><em>Point-to-Point:</em></strong><em> In this pattern, each message is delivered to a single consumer. It is typically used for tasks like job processing, where each task should be handled by one worker.</em></blockquote><blockquote><strong><em>Scenario</em></strong><em>: A web application generates tasks that need to be processed, such as resizing images. Each task is sent as a message to a RabbitMQ queue. A pool of workers listens to the queue and processes tasks one by one. Each task is consumed by a single worker, ensuring that tasks are not processed multiple times.</em></blockquote><blockquote><strong><em>Technology</em></strong><em>: RabbitMQ</em></blockquote><blockquote><strong><em>Message Flow:</em></strong><em> Producer: The web application sends a task to the RabbitMQ queue → Queue: The message is stored in the queue → Consumer: A worker retrieves and processes the task from the queue.</em></blockquote><blockquote><strong><em>Publish-Subscribe:</em></strong><em> This pattern allows messages to be broadcast to multiple consumers. It is useful for event-driven architectures where multiple services need to react to the same event.</em></blockquote><blockquote><strong><em>Scenario</em></strong><em>: In a financial trading platform, real-time stock price updates need to be broadcast to multiple services, such as a trading dashboard, a risk management system, and a notification service for traders. Using the publish-subscribe pattern with Amazon SNS, a stock price update can be published to an SNS topic, and multiple subscribers can receive the update simultaneously.</em></blockquote><blockquote><strong><em>Technology</em></strong><em>: Amazon SNS (Simple Notification Service) and Amazon SQS (Simple Queue Service)</em></blockquote><blockquote><strong><em>Message Flow:</em></strong> <strong><em>Publisher</em></strong><em>: Stock price data feed publishes the update to an SNS topic → </em><strong><em>SNS Topic:</em></strong><em> Broadcasts the update to all subscribed endpoints, including SQS queues. → Subscribers: </em><strong><em>Trading Dashboard:</em></strong><em> Receives real-time updates directly from SNS. </em><strong><em>Risk Management Queue (SQS):</em></strong><em> Receives updates for risk recalibration. </em><strong><em>Notification Service Queue (SQS)</em></strong><em>: Receives updates for sending alerts. </em><strong><em>Analytics Queue (SQS): </em></strong><em>Receives updates for data analysis and storage.</em></blockquote><blockquote><strong><em>Request-Reply:</em></strong><em> A pattern where a service sends a request message and waits for a reply message. This is often used in RPC (Remote Procedure Call) systems.</em></blockquote><blockquote><strong><em>Scenario</em></strong><em>: Order Status Inquiry Service</em></blockquote><blockquote><strong><em>Technology</em></strong><em>: RabbitMQ</em></blockquote><blockquote><strong><em>Message Flow: </em></strong><em>Client: A user requests the status of their order through a web application. The request is sent to a RabbitMQ request queue → Server: The server listens for requests on the RabbitMQ request queue. When a request is received, the server processes the request by checking the order status in the database and then sends a reply message to a dedicated reply queue. → Client: The client listens for the reply message on the reply queue and processes the response to display the order status to the user.</em></blockquote><p><strong>Best Practices for Using Message Queues:</strong></p><ol><li><strong>Idempotency:</strong> Ensure that message processing is idempotent, meaning that processing the same message multiple times has the same effect as processing it once. This prevents issues from message duplication.</li><li><strong>Monitoring and Alerting: </strong>Implement robust monitoring and alerting for your message queue system. Track metrics like queue length, processing time, and error rates to identify and address issues promptly.</li><li><strong>Dead Letter Queues (DLQ):</strong> Use DLQs to handle messages that cannot be processed successfully after multiple attempts. This helps in isolating problematic messages and ensures they do not block the queue.</li><li><strong>Backpressure Management: </strong>Implement strategies to handle backpressure, such as rate limiting or shedding load, to prevent system overload when the message production rate exceeds consumption capacity.</li></ol><p><strong>Conclusion</strong>:</p><p>Message queues are a crucial component in modern system design, facilitating asynchronous communication, scalability, and reliability. By grasping their concepts, patterns, and best practices, you can effectively utilize message queues to build robust and scalable systems.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2d015d9fa645" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hashing 101: From Passwords to Blockchain]]></title>
            <link>https://medium.com/@amoljadhav_48655/hashing-101-from-passwords-to-blockchain-6b483a6d887a?source=rss-52cdb9f437f0------2</link>
            <guid isPermaLink="false">https://medium.com/p/6b483a6d887a</guid>
            <category><![CDATA[hashing-algorithm]]></category>
            <category><![CDATA[hashing]]></category>
            <category><![CDATA[interview-questions]]></category>
            <category><![CDATA[data-structure-algorithm]]></category>
            <category><![CDATA[computer-science]]></category>
            <dc:creator><![CDATA[Amol Jadhav]]></dc:creator>
            <pubDate>Tue, 21 May 2024 14:53:54 GMT</pubDate>
            <atom:updated>2024-05-21T14:53:54.230Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>Imagine you have a huge collection of toys scattered all over your room. To keep things organized, you use a magical toy box with a special scanner. This scanner gives each toy a unique number and tells you which drawer to put it in. When you need a toy, the scanner quickly points you to the right drawer, making it easy to find any toy in an instant. This is how hashing works: it organizes things so you can find what you need super fast!</blockquote><blockquote>Hashing is a fundamental concept in computer science and software engineering. It involves transforming input data of any size into a fixed-size value, usually a string of numbers and letters. This value is called a hash code, hash value, or simply hash.</blockquote><h3>What is Hashing?</h3><p>Hashing is a technique used to uniquely identify data by transforming it into a fixed-size hash value or hash code. This transformation is performed by a hash function, which maps input data of varying lengths into a consistent, fixed-length output. The main purpose of hashing is to allow for quick data retrieval and comparison, making it an essential tool in data structures like hash tables, as well as in ensuring data integrity and security in various applications.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5UJcysL10g44ccgcDCqAcQ.png" /></figure><p>Key Properties of Hash Functions</p><ol><li>Deterministic: The same input will always produce the same hash code.</li><li>Fixed Output Size: Regardless of the input size, the output hash code has a fixed length.</li><li>Efficient: Hash functions are designed to be fast to compute.</li><li>Pre-image Resistance: Given a hash code, it should be infeasible to compute the original input.</li><li>Collision Resistance: It should be difficult to find two different inputs that produce the same hash code.</li><li>Avalanche Effect: A small change in the input should produce a significantly different hash code.</li></ol><h3>Common Hash Functions</h3><ul><li><strong>MD5</strong>: Produces a 128-bit hash value. It’s fast but not suitable for cryptographic purposes due to vulnerabilities. (Hash Size: 128 bits (16 bytes, Maximum Number of Unique Hash Values: 2¹²⁸)</li><li><strong>SHA-1</strong>: Produces a 160-bit hash value. It’s more secure than MD5 but still has known weaknesses. (Hash Size: 160 bits (20 bytes), Maximum Number of Unique Hash Values: 2¹⁶⁰)</li><li><strong>SHA-256</strong>: Part of the SHA-2 family, produces a 256-bit hash value and is widely used for security purposes.</li></ul><pre># Output:<br># Input: Hello, World!<br># MD5: b10a8db164e0754105b7a99be72e3fe5<br># SHA-1: 2ef7bde608ce5404e97d5f042f95f89f1c232871<br># SHA-256: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b56ee1feb2ef8d7e6</pre><h3>Why Different Hashing Functions?</h3><p><strong>Evolution of Security Requirements:</strong> As computational power increases, the feasibility of attacks on hash functions improves. Algorithms like MD5 and SHA-1, which were once considered secure, have become vulnerable to attacks. More secure algorithms like SHA-256 were developed to address these vulnerabilities.</p><p><strong>Performance Trade-offs: </strong>Faster algorithms like MD5 are useful in scenarios where performance is critical, and security is less of a concern. In contrast, SHA-256, while slower, provides a higher level of security, making it suitable for cryptographic applications.</p><p><strong>Specific Use Cases:</strong> Different applications have different requirements. For example, MD5 is still used for non-cryptographic checksums due to its speed, while SHA-256 is used in security-sensitive contexts.</p><p><strong>Legacy Systems:</strong> Older systems and protocols were built using MD5 or SHA-1 before their vulnerabilities were discovered. Transitioning to more secure algorithms takes time, and some legacy systems still use these older functions.</p><h3>Example: Implementing a Hash Table</h3><pre>class HashTable:<br>    def __init__(self, size):<br>        self.size = size<br>        self.table = [[] for _ in range(size)]<br><br>    def hash_function(self, key):<br>        return hash(key) % self.size<br><br>    def insert(self, key, value):<br>        index = self.hash_function(key)<br>        for item in self.table[index]:<br>            if item[0] == key:<br>                item[1] = value<br>                return<br>        self.table[index].append([key, value])<br><br>    def search(self, key):<br>        index = self.hash_function(key)<br>        for item in self.table[index]:<br>            if item[0] == key:<br>                return item[1]<br>        return None<br><br># Example usage<br>hash_table = HashTable(10)<br>hash_table.insert(&quot;name&quot;, &quot;Alice&quot;)<br>hash_table.insert(&quot;age&quot;, 30)<br>print(hash_table.search(&quot;name&quot;))  # Output: Alice<br>print(hash_table.search(&quot;age&quot;))   # Output: 30</pre><h3>Real-Life Examples of Hashing</h3><p><strong>Password Storage:</strong> When you create an account on a website, your password is not stored as plain text. Instead, it’s passed through a hash function, and the resulting hash value is stored. When you log in, the system hashes the entered password and compares it to the stored hash. If they match, you’re granted access. <strong>Why It’s Important</strong>: This ensures that even if the database is compromised, attackers cannot easily retrieve the actual passwords.</p><p><strong>Version Control Systems:</strong> In systems like Git, every commit (a set of changes) is identified by a hash. This hash represents the state of the repository at that point in time and is used to track changes, revert to previous versions, and manage branches.<strong>Why It’s Important:</strong> This allows developers to collaborate effectively, maintain a history of changes, and ensure the integrity of the codebase.</p><p><strong>Hash Tables and Databases:</strong> Hash tables are used in databases to index data. For example, when you search for a record in a database, the hash of the search key is used to quickly locate the record in the hash table, providing fast access. <strong>Why It’s Important: </strong>This allows for efficient data retrieval, which is critical for performance in large databases.</p><p><strong>Blockchain and Cryptocurrencies:</strong> In blockchain technology (like Bitcoin), each block contains a hash of the previous block, forming a chain. Transactions within a block are hashed, and the resulting hash is used to ensure the integrity and immutability of the blockchain. <strong>Why It’s Important:</strong> This ensures security, prevents tampering, and maintains a trustworthy ledger of transactions.</p><h3>Conclusion</h3><p>Hashing is a powerful tool for efficient data retrieval, integrity verification, and security. Understanding the principles of hash functions and their applications is crucial for designing and implementing scalable and robust systems. Whether you’re building a simple hash table or securing passwords, hashing provides a reliable way to manage and protect data.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6b483a6d887a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Java Garbage Collection Explained]]></title>
            <link>https://medium.com/@amoljadhav_48655/java-garbage-collection-explained-7b55dab80dcb?source=rss-52cdb9f437f0------2</link>
            <guid isPermaLink="false">https://medium.com/p/7b55dab80dcb</guid>
            <category><![CDATA[garbage-collection]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[Amol Jadhav]]></dc:creator>
            <pubDate>Sat, 18 May 2024 21:39:59 GMT</pubDate>
            <atom:updated>2024-05-18T21:39:59.795Z</atom:updated>
            <content:encoded><![CDATA[<h3>Java Garbage Collection</h3><blockquote>Imagine you have an office filled with documents, and every time you work on a document, you leave it scattered on your desk. Eventually, the desk becomes so cluttered that you can’t find the documents you need, and there’s no space left to work efficiently.</blockquote><p><strong>Introduction: </strong>Java garbage collection is an automatic process in the Java Virtual Machine (JVM) that frees up memory by removing objects no longer in use. This essential feature helps prevent memory leaks and reduces the need for manual memory management.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*n0ure_CBp3QaXMMj-DESSA.png" /></figure><h3>How Does the Garbage Collector Know What to Clean Up?</h3><p>If you’re still working(referenced) on a document or it’s stored in your filing cabinet (variables and references in your program), the Garbage Collector leaves it alone.</p><p>Not in Use (Unreferenced) Documents: If you’ve left a document on your desk and forgotten about it (no variables or references pointing to it), the Garbage Collector picks it up and puts it away.</p><h3>Types of Garbage Collectors in Java</h3><ol><li><strong>Serial Garbage Collector</strong>: The Serial GC is the simplest form of garbage collector in Java. It uses a single thread to perform all garbage collection work.</li></ol><blockquote>You go through each document one by one, deciding whether it’s still needed or not. Once you’ve sorted everything, you discard the unnecessary documents and neatly organize the ones you still need. This way, you create a tidy workspace and can work efficiently again.</blockquote><p><strong>How It Works</strong>: During garbage collection, the application is paused, and the single GC thread cleans up the memory. This is known as a “stop-the-world” event.</p><p><strong>Use Case:</strong> Suitable for small applications with single-threaded environments where pause times are not critical.</p><blockquote><strong>You take a break from work to clean up the entire desk by yourself.</strong></blockquote><p>Here’s a Python example demonstrating this concept using a single-threaded garbage collection approach:</p><pre>import gc<br><br>class MyClass:<br>    def __init__(self, name):<br>        self.name = name<br>        print(f&#39;Object {self.name} created&#39;)<br><br>    def __del__(self):<br>        print(f&#39;Object {self.name} destroyed&#39;)<br><br>def create_objects():<br>    obj1 = MyClass(&#39;obj1&#39;)<br>    obj2 = MyClass(&#39;obj2&#39;)<br>    # Create a cyclic reference<br>    obj1.ref = obj2<br>    obj2.ref = obj1<br>    return obj1, obj2<br><br>def perform_serial_gc():<br>    # Disable automatic garbage collection<br>    gc.disable()<br>    <br>    # Manually invoke garbage collection<br>    print(&#39;Starting garbage collection...&#39;)<br>    gc.collect()<br>    print(&#39;Garbage collection complete&#39;)<br><br># Create objects and form cyclic references<br>obj1, obj2 = create_objects()<br><br># Manually perform garbage collection<br>perform_serial_gc()<br><br># Remove references to objects<br>del obj1<br>del obj2<br><br># Perform garbage collection again to clean up<br>perform_serial_gc()</pre><p>2. <strong>Parallel Garbage Collector:</strong> The Parallel GC, also known as the “Throughput Collector,” uses multiple threads to speed up the garbage collection process.</p><blockquote>You and several of your colleagues decide to clean up the desk together. Each of you takes a portion of the documents, sorting through them simultaneously. Some colleagues focus on sorting, while others handle discarding unnecessary documents and organizing the ones still needed. By working in parallel, you manage to clean up the desk much faster, creating a tidy workspace where everyone can work efficiently again.</blockquote><p><strong>How It Works:</strong> It uses multiple threads to collect garbage in the Young Generation, making it efficient for applications running on multi-core processors.</p><p><strong>Use Case:</strong> Ideal for applications that can tolerate longer pause times but require high throughput, such as batch processing systems.</p><blockquote><strong>You and several colleagues stop working and clean up the desk together, each handling different sections simultaneously.</strong></blockquote><p>Here’s a Python example demonstrating this concept using a parallel garbage collection approach:</p><pre>import gc<br>import threading<br><br>class MyClass:<br>    def __init__(self, name):<br>        self.name = name<br>        print(f&#39;Object {self.name} created&#39;)<br><br>    def __del__(self):<br>        print(f&#39;Object {self.name} destroyed&#39;)<br><br>def create_objects():<br>    obj1 = MyClass(&#39;obj1&#39;)<br>    obj2 = MyClass(&#39;obj2&#39;)<br>    # Create a cyclic reference<br>    obj1.ref = obj2<br>    obj2.ref = obj1<br>    return obj1, obj2<br><br>def perform_gc():<br>    print(&#39;Starting garbage collection...&#39;)<br>    gc.collect()<br>    print(&#39;Garbage collection complete&#39;)<br><br>def parallel_gc(num_threads):<br>    threads = []<br>    for _ in range(num_threads):<br>        thread = threading.Thread(target=perform_gc)<br>        threads.append(thread)<br>        thread.start()<br>    <br>    for thread in threads:<br>        thread.join()<br><br># Create objects and form cyclic references<br>obj1, obj2 = create_objects()<br><br># Perform parallel garbage collection using multiple threads<br>parallel_gc(num_threads=4)<br><br># Remove references to objects<br>del obj1<br>del obj2<br><br># Perform parallel garbage collection again to clean up<br>parallel_gc(num_threads=4)</pre><p>3. <strong>Concurrent Mark-Sweep (CMS) Collector: </strong>The CMS collector aims to minimize pause times by performing most of its work concurrently with the application.</p><blockquote>You and your colleagues decide to clean up the desk while continuing to work. One group of colleagues starts by marking all the documents you still need as they notice them, while another group continues working as usual. During a brief break, the first group sweeps through the desk, quickly discarding the documents that were not marked as needed. By marking documents in the background and only briefly pausing to discard the unnecessary ones, you manage to keep the workspace tidy without significantly interrupting your work. This way, the desk stays organized, and you can work efficiently with minimal disruption.</blockquote><p><strong>How It Works:</strong> It has four phases: initial mark, concurrent mark, remark, and concurrent sweep. Only the initial mark and remark phases cause pauses.</p><p><strong>Use Case</strong>: Suitable for applications requiring low latency and can afford some CPU overhead for concurrent GC activities.</p><blockquote><strong>One group of colleagues marks needed documents while others continue working. During a brief break, the marked documents are sorted and the unnecessary ones are discarded.</strong></blockquote><p>Here’s a Python example demonstrating this concept using a Concurrent Mark-Sweep collection approach:</p><pre>import gc<br>import threading<br>import time<br><br>class MyClass:<br>    def __init__(self, name):<br>        self.name = name<br>        print(f&#39;Object {self.name} created&#39;)<br><br>    def __del__(self):<br>        print(f&#39;Object {self.name} destroyed&#39;)<br><br>def create_objects(num_objects):<br>    objects = []<br>    for i in range(num_objects):<br>        obj = MyClass(f&#39;obj{i}&#39;)<br>        objects.append(obj)<br>    return objects<br><br>def mark_phase():<br>    print(&#39;Starting mark phase...&#39;)<br>    gc.collect()<br>    print(&#39;Mark phase complete&#39;)<br><br>def sweep_phase():<br>    print(&#39;Starting sweep phase...&#39;)<br>    gc.collect()<br>    print(&#39;Sweep phase complete&#39;)<br><br>def concurrent_mark_sweep_gc():<br>    # Concurrent Mark Phase<br>    mark_thread = threading.Thread(target=mark_phase)<br>    mark_thread.start()<br>    mark_thread.join()<br><br>    # Concurrent Sweep Phase<br>    sweep_thread = threading.Thread(target=sweep_phase)<br>    sweep_thread.start()<br>    sweep_thread.join()<br><br># Create objects<br>objects = create_objects(num_objects=10)<br>time.sleep(0.5)  # Simulate time delay for object usage<br><br># Perform CMS garbage collection<br>concurrent_mark_sweep_gc()<br><br># Remove references to objects<br>for obj in objects:<br>    del obj<br><br># Perform CMS garbage collection again to clean up<br>concurrent_mark_sweep_gc()</pre><p>4. <strong>Garbage-First (G1) Collector: </strong>The G1 collector is designed for applications with large heaps and aims to provide predictable pause times.</p><blockquote><em>You and your colleagues decide to tackle the most cluttered areas of the desk first, where the mess is the worst. Each of you targets these high-priority sections, quickly sorting through the documents to identify which ones are still needed and which ones can be discarded. Once the most cluttered areas are clean, you gradually move on to the less messy sections. By focusing on the worst messes first, you efficiently clean up the entire desk, ensuring that the workspace remains organized and easy to work in.</em></blockquote><p><strong>How It Works: </strong>G1 divides the heap into regions and collects garbage in regions that contain the most reclaimable space first. It uses a mix of concurrent and parallel phases.</p><p><strong>Use Case:</strong> Ideal for large-scale applications needing predictable pause times and efficient memory management.</p><blockquote><strong>You and your colleagues focus on the messiest parts of the desk first, working together to clean those up, and then gradually move on to less messy sections. The work stops briefly during the cleanup but is optimized to minimize disruption.</strong></blockquote><p>Here’s a Python example demonstrating this concept using a Garbage-First collection approach:</p><pre>import gc<br>import threading<br>import random<br>import time<br><br>class MyClass:<br>    def __init__(self, name):<br>        self.name = name<br>        print(f&#39;Object {self.name} created&#39;)<br><br>    def __del__(self):<br>        print(f&#39;Object {self.name} destroyed&#39;)<br><br>def create_objects(num_objects):<br>    objects = []<br>    for i in range(num_objects):<br>        obj = MyClass(f&#39;obj{i}&#39;)<br>        objects.append(obj)<br>    # Randomly create cyclic references<br>    for obj in objects:<br>        obj.ref = random.choice(objects)<br>    return objects<br><br>def perform_gc(region):<br>    print(f&#39;Starting garbage collection in region {region}...&#39;)<br>    gc.collect()<br>    print(f&#39;Garbage collection complete in region {region}&#39;)<br><br>def g1_gc(num_regions):<br>    threads = []<br>    for region in range(num_regions):<br>        thread = threading.Thread(target=perform_gc, args=(region,))<br>        threads.append(thread)<br>        thread.start()<br>    <br>    for thread in threads:<br>        thread.join()<br><br># Create objects in different regions<br>num_regions = 4<br>all_objects = []<br>for _ in range(num_regions):<br>    all_objects.extend(create_objects(num_objects=10))<br>    time.sleep(0.5)  # Simulate time delay between object creation<br><br># Perform G1 garbage collection<br>g1_gc(num_regions=num_regions)<br><br># Remove references to objects<br>for obj in all_objects:<br>    del obj<br><br># Perform G1 garbage collection again to clean up<br>g1_gc(num_regions=num_regions)</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7b55dab80dcb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Mastering EA FIFA FC 24: An In-Depth Guide to Skill Moves]]></title>
            <link>https://medium.com/@amoljadhav_48655/mastering-ea-fifa-fc-24-an-in-depth-guide-to-skill-moves-c7cbcf89c0e3?source=rss-52cdb9f437f0------2</link>
            <guid isPermaLink="false">https://medium.com/p/c7cbcf89c0e3</guid>
            <category><![CDATA[games]]></category>
            <category><![CDATA[fifa-24-guide]]></category>
            <category><![CDATA[fifa]]></category>
            <category><![CDATA[gaming]]></category>
            <category><![CDATA[fifa-24]]></category>
            <dc:creator><![CDATA[Amol Jadhav]]></dc:creator>
            <pubDate>Fri, 17 May 2024 22:29:47 GMT</pubDate>
            <atom:updated>2024-05-17T22:29:47.720Z</atom:updated>
            <content:encoded><![CDATA[<p>The thrill of outmaneuvering your opponent with a dazzling display of skill moves is one of the most exhilarating aspects of playing FIFA FC 24. Whether you’re aiming to break through a solid defense or simply add flair to your game, mastering skill moves can significantly enhance your gameplay experience. This guide provides a comprehensive list of FIFA FC 24 skill moves, categorized by their difficulty level, along with step-by-step instructions on how to execute them.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zJpVWCd81CF5AFP2xwLSeA.png" /></figure><h3>1-Star Skill Moves</h3><ul><li><strong>First-Time Feint Turn</strong>: Hold L1 + R1 + flick LS down / Hold LB + RB + flick LS down</li><li><strong>Bridge Skill</strong>: Double tap R1 / Double tap RB</li><li><strong>Directional Nutmeg</strong>: Hold L1 + R1 + RS in any direction / Hold LB + RB + RS in any direction</li><li><strong>Ball Juggle (while standing):</strong> L2 + tap R1 / LT + tap RB</li><li><strong>Open Up Fake Shot Left:</strong> Hold L1 + Square or Circle then tap X + LS top left diagonally / Hold LB + X or B then tap A + LS top left diagonally</li><li><strong>Open Up Fake Shot Right:</strong> Hold L1 + Square or Circle then tap X + LS top right diagonally / Hold LB + X or B then tap A + LS top right diagonally</li><li><strong>Flick Up for volley:</strong> Hold R1 + click RS / Hold RB + click RS</li></ul><h3>2-Star Skill Moves</h3><ul><li><strong>Feint Forward and Turn: </strong>Flick RS down twice / Flick RS down twice</li><li><strong>Body Feint right/left: </strong>Flick RS right/left / Flick RS right/left</li><li><strong>Stepover right/left: </strong>Roll RS from the top of the stick to the right/left / Roll RS from the top of the stick to the right/left</li><li><strong>Reverse Stepover right/left:</strong> Roll RS from the right/left to the top of the stick / Roll RS from the right/left to the top of the stick</li><li><strong>Ball Roll right/left:</strong> Hold RS right/left / Hold RS right/left</li></ul><h3>3-Star Skill Moves</h3><ul><li><strong>Stutter Feint:</strong> Hold L2 + flick RS left then right (or right then left) / Hold LT + flick RS left then right (or right then left)</li><li><strong>Heel Flick:</strong> Flick RS up and then down / Flick RS up and then down</li><li><strong>Roulette right:</strong> Roll RS from the bottom and clockwise to the right / Roll RS from the bottom and clockwise to the right</li><li><strong>Roulette left:</strong> Roll RS from the bottom and anti-clockwise to the left / Roll RS from the bottom and anti-clockwise to the left</li><li><strong>Fake left and go right:</strong> Roll RS from the left anti-clockwise to the right / Roll RS from the left anti-clockwise to the right</li><li><strong>Fake right and go left: </strong>Roll RS from the right clockwise to the left / Roll RS from the right clockwise to the left</li><li><strong>Heel Chop right/left (while running): </strong>Hold L2 + Square or Circle then X + hold LS right/left / Hold LT + X or B then A + hold LS right/left</li><li><strong>Heel to ball roll:</strong> Hold L1 + flick RS up then down / Hold LB + flick RS up then down</li><li><strong>Ball Hop (while standing):</strong> Hold L1 + click RS / Hold LB + click RS</li><li><strong>Heel to Heel Flick:</strong> Flick RS up and then down / Flick RS up and then down</li><li><strong>Simple rainbow: </strong>Flick RS down, then up twice / Flick RS down, then up twice</li><li><strong>Spin right:</strong> Hold R1 + roll RS from bottom clockwise to right / Hold RB + roll RS from bottom clockwise to right</li><li><strong>Spin left:</strong> Hold R1 + roll RS from the bottom anti-clockwise to the left / Hold RB + roll RS from the bottom anti-clockwise to the left</li><li><strong>Stop and Turn right/left (while running):</strong> Flick RS up then right/left / Flick RS up then right/left</li><li><strong>Ball roll cut right:</strong> Hold RS left then hold LS right / Hold RS left then hold LS right</li><li><strong>Ball roll cut left:</strong> Hold RS right then hold LS left / Hold RS right then hold LS left</li><li><strong>Fake pass (while standing):</strong> Hold R2 + Square or Circle then X / Hold RT + X or B then A</li><li><strong>Fake pass exit right/left (while standing):</strong> Hold R2 + Square or Circle then X + flick LS top right/left diagonally / Hold RT + X or B then A + flick LS top right/left diagonally</li><li><strong>Quick ball rolls:</strong> Hold RS down / Hold RS down</li><li><strong>Drag to Heel: </strong>Hold L1 + flick RS down, then right or left / Hold LB + flick RS down, then right or left</li><li><strong>Lane Change right/left: </strong>Hold L1 + hold RS right/left / Hold LB + hold RS right/left</li><li><strong>Three-touch roulette right/left: </strong>Hold L2 + flick RS down then right/left / Hold LT + flick RS down then right/left</li><li><strong>Drag backspin right/left:</strong> Flick RS down then right/left / Flick RS down then right/left</li></ul><h3>5-Star Skill Moves</h3><ul><li><strong>Elastico:</strong> Roll RS from right clockwise to left / Roll RS from right clockwise to left</li><li><strong>Reverse Elastico:</strong> Roll RS from left anti-clockwise to right / Roll RS from left anti-clockwise to right</li><li><strong>Advanced Rainbow: </strong>Flick RS down, hold up, then flick up / Flick RS down, hold up, then flick up</li><li><strong>Hocus Pocus:</strong> Roll RS from bottom clockwise to left, then roll anti-clockwise to right / Roll RS from bottom clockwise to left, then roll anti-clockwise to right</li><li><strong>Triple Elastico: </strong>Roll RS from bottom anti-clockwise to right, then roll clockwise to left / Roll RS from bottom anti-clockwise to right, then roll clockwise to left</li><li><strong>Ball Roll and Flick Left (while running):</strong> Hold RS left then flick up / Hold RS left then flick up</li><li><strong>Ball Roll and Flick Right (while running):</strong> Hold RS right then flick up / Hold RS right then flick up</li><li><strong>Heel Flick Turn:</strong> Hold L2 + R1 + flick RS up then down / Hold LT + RB + flick RS up then down</li><li><strong>Sombrero Flick (while standing): </strong>Flick RS up, up, down / Flick RS up, up, down</li><li><strong>Turn and Spin Left:</strong> Flick RS up then left / Flick RS up then left</li><li><strong>Turn and Spin Right:</strong> Flick RS up then right / Flick RS up then right</li><li><strong>Ball Roll Fake Left (while standing):</strong> Hold RS left then flick RS right / Hold RS left then flick RS right</li><li><strong>Ball Roll Fake Right (while standing):</strong> Hold RS right then flick RS left / Hold RS right then flick RS left</li><li><strong>Ball Roll Fake Turn:</strong> Hold L2 + flick RS up then flick RS either left or right / Hold LT + flick RS up then flick RS either left or right</li><li><strong>Rabona Fake (while jogging): </strong>Hold L2 + Square or Circle then X + LS down / Hold LT + X or B then A + LS down</li><li><strong>Elastico Chop Left:</strong> Hold L2 + hold R1 then roll RS from right clockwise to left / Hold LT + hold RB then roll RS from right clockwise to left</li><li><strong>Elastico Chop Right:</strong> Hold L2 + hold R1 then roll RS from left anti-clockwise to right / Hold LT + hold RB then roll RS from left anti-clockwise to right</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c7cbcf89c0e3" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>