<?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:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[CatSays.Net]]></title><description><![CDATA[Cat says about everything you need to know from start to finish to break into and stay relevant in the software engineering industry.  
"Those who will survive in the tech industry are those who continuously adapt and learn." CatSays.Net 2024]]></description><link>https://blog.catsays.net</link><image><url>https://substackcdn.com/image/fetch/$s_!1wmy!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff91c324e-80fa-4571-8ce7-6c05467f319c_288x288.png</url><title>CatSays.Net</title><link>https://blog.catsays.net</link></image><generator>Substack</generator><lastBuildDate>Wed, 06 May 2026 11:28:12 GMT</lastBuildDate><atom:link href="https://blog.catsays.net/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Catalin Rosu]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[catrosu@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[catrosu@substack.com]]></itunes:email><itunes:name><![CDATA[Cat Rosu]]></itunes:name></itunes:owner><itunes:author><![CDATA[Cat Rosu]]></itunes:author><googleplay:owner><![CDATA[catrosu@substack.com]]></googleplay:owner><googleplay:email><![CDATA[catrosu@substack.com]]></googleplay:email><googleplay:author><![CDATA[Cat Rosu]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Brewing the Idempotency Interview Question]]></title><description><![CDATA[Decoding Consistency and Reliability: The Idempotency Principle in Software Engineering]]></description><link>https://blog.catsays.net/p/brewing-the-idempotency-interview</link><guid isPermaLink="false">https://blog.catsays.net/p/brewing-the-idempotency-interview</guid><dc:creator><![CDATA[Cat Rosu]]></dc:creator><pubDate>Mon, 26 Feb 2024 21:20:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QNw0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QNw0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png 424w, https://substackcdn.com/image/fetch/$s_!QNw0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png 848w, https://substackcdn.com/image/fetch/$s_!QNw0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png 1272w, https://substackcdn.com/image/fetch/$s_!QNw0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QNw0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png" width="476" height="316.14925373134326" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:623,&quot;width&quot;:938,&quot;resizeWidth&quot;:476,&quot;bytes&quot;:994575,&quot;alt&quot;:&quot;Software engineer in a cafe with a laptop and coffee, embodying tech work-life balance.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Software engineer in a cafe with a laptop and coffee, embodying tech work-life balance." title="Software engineer in a cafe with a laptop and coffee, embodying tech work-life balance." srcset="https://substackcdn.com/image/fetch/$s_!QNw0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png 424w, https://substackcdn.com/image/fetch/$s_!QNw0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png 848w, https://substackcdn.com/image/fetch/$s_!QNw0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png 1272w, https://substackcdn.com/image/fetch/$s_!QNw0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2dc9a17-df55-4753-86f0-ff99859ca0fc_938x623.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A passionate software engineer preparing for an interview on a laptop in a cosy caf&#233;, with a freshly brewed cup of coffee on the wooden table, symbolising the blend of technology and the comfort of coffee culture</figcaption></figure></div><p>One question I often ask in interviews and mentoring sessions, which rarely gets an answer, is subtly revealed in the story that follows. Immerse yourself in this narrative to discover the answer.</p><p>Join me on a journey inside the warm, inviting atmosphere of a coffee shop, where the concept of idempotency unfolds through a tale of consistency and unexpected outcomes.</p><h2>The Idempotent Order in the Coffee Shop</h2><p>Imagine a charming coffee shop in the city's heart, a sanctuary for those addicted to caffeine and passionate about coding. We meet Alex, a developer who, between sips of espresso and crafting code, discovers the essence of idempotency.</p><p>One crisp Monday morning, Alex orders their usual double espresso. The barista, skilled in the art of coffee and consistency, prepares the drink, exactly as requested. The next day, craving the familiar kick of caffeine, Alex orders the same double espresso. The result? Identical to the day before - same taste, temperature, and energising effect.</p><p>This routine of ordering the same coffee and receiving the exact same result every time reflects the principle of idempotency in software development. Just like Alex's double espresso, an idempotent operation ensures that no matter how many times a request is made, the outcome remains unchanged after the initial execution. This principle is crucial for developing resilient, predictable systems where repeated actions have no additional effects.</p><h2>The Non-Idempotent Twist</h2><p>Yet, on a particular Wednesday, after placing their usual order, Alex was surprised to receive something quite different: what seemed more like a caramelised flat white than their expected double espresso. This unexpected variation, despite the same request, highlights the nature of non-idempotent operations. In software terms, it's like when actions, if done over and over, lead to different results or effects, like putting a new item in your shopping cart each time or sending an email.</p><p>Disappointed, Alex uses the self-order machine the following day, Thursday, hoping for a seamless experience. Still frustrated from the previous day's surprise, Alex accidentally double-clicks the "Pay" button on the payment screen. Astonishingly, Alex is charged twice for a single coffee. This other instance of non-idempotent behaviour, where the operation behaves unexpectedly, highlights the vital need for a proper understanding and implementation of idempotency.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JsDK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JsDK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif 424w, https://substackcdn.com/image/fetch/$s_!JsDK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif 848w, https://substackcdn.com/image/fetch/$s_!JsDK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif 1272w, https://substackcdn.com/image/fetch/$s_!JsDK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JsDK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif" width="1159" height="627" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:627,&quot;width&quot;:1159,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:841854,&quot;alt&quot;:&quot;Diagram showing idempotent vs. non-idempotent operations in a coffee shop scenario, with successful repeated espresso orders versus a duplicated payment leading to the wrong coffee order.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Diagram showing idempotent vs. non-idempotent operations in a coffee shop scenario, with successful repeated espresso orders versus a duplicated payment leading to the wrong coffee order." title="Diagram showing idempotent vs. non-idempotent operations in a coffee shop scenario, with successful repeated espresso orders versus a duplicated payment leading to the wrong coffee order." srcset="https://substackcdn.com/image/fetch/$s_!JsDK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif 424w, https://substackcdn.com/image/fetch/$s_!JsDK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif 848w, https://substackcdn.com/image/fetch/$s_!JsDK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif 1272w, https://substackcdn.com/image/fetch/$s_!JsDK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc49fad9c-a650-402d-becf-07ebd9168931_1159x627.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Diagram showing idempotent vs. non-idempotent operations in a coffee shop scenario, with successful repeated espresso orders versus a duplicated payment leading to the unexpected outcome of a coffee order.</figcaption></figure></div><h2><strong>Unravelling Idempotency: The Key to Reliable Software and Microservices</strong></h2><p>The interview question, which puzzles many developers, is indeed: "<strong>What is idempotent in software development?</strong>"</p><p>The term "idempotent" comes from mathematics, specifically from algebra, where it describes an element that, when multiplied by itself, yields itself.</p><p>Idempotency is a fundamental concept in computer science and software engineering, especially relevant in distributed systems and API design. It means that no matter how many times an operation is performed, it produces the same result as doing it just once, without any additional side effects.</p><p>Designing idempotent APIs and web services is crucial to ensure that clients can retry requests after encountering errors or network issues, without risking unintended system changes. For example, if a service responsible for processing payments adheres to idempotent design, accidentally sending the same payment request multiple times will not result in a user being charged more than once.</p><p>In the world of microservices, where communication is often asynchronous, idempotency is essential. It ensures that even if the same event message is received multiple times by a service - perhaps due to message bus retries or network issues - the operation will only be executed once, preventing duplicate actions.</p><p>This characteristic is a critical safeguard in environments where services communicate without waiting for immediate responses, ensuring consistent and reliable outcomes.</p><p>Alex's experiences in the coffee shop offer a practical view of idempotency (and its absence) in technology. From API development, where idempotent methods like GET, PUT, and DELETE offer safety and reliability, to the unpredictable nature of non-idempotent POST requests, idempotency affects various software development aspects.</p><h2><strong>Reflecting on Our Coffee Shop Story</strong></h2><p>Alex's journey captures idempotency's essence in a relatable way. It reminds us that in technology, as in life, understanding the nature of our requests and their consequences is key for creating experiences that are both satisfying and consistent.</p><p>Mastering idempotency demonstrates a developer's ability to protect and improve systems with best practices, emphasising creating solutions that serve and benefit end-users.</p><p>This often misunderstood yet crucial principle is the foundation of building resilient and reliable systems. Let it guide our digital creations and coffee orders towards consistency and reliability.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.catsays.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading CatSays.Net! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Goldilocks Architecture]]></title><description><![CDATA[coming soon ...]]></description><link>https://blog.catsays.net/p/the-goldilocks-architecture</link><guid isPermaLink="false">https://blog.catsays.net/p/the-goldilocks-architecture</guid><dc:creator><![CDATA[Cat Rosu]]></dc:creator><pubDate>Mon, 08 Jan 2024 18:10:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1wmy!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff91c324e-80fa-4571-8ce7-6c05467f319c_288x288.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p>]]></content:encoded></item><item><title><![CDATA[Making it stick: Structs vs. Classes vs. Records in C# .NET - Understanding Key Differences]]></title><description><![CDATA[From Stickers to Structure: A Developer's journey through code structure and design]]></description><link>https://blog.catsays.net/p/making-it-stick-structs-vs-classes</link><guid isPermaLink="false">https://blog.catsays.net/p/making-it-stick-structs-vs-classes</guid><dc:creator><![CDATA[Cat Rosu]]></dc:creator><pubDate>Sat, 18 Nov 2023 16:53:08 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!jbBx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the dimly lit <strong>Codevania </strong>Office, in the bustling town of <a href="https://blog.agileswe.com/p/tech-debt-city-of-codeville">Codeville</a>, where algorithms buzzed like bees and keyboard strokes clicked like gentle rain, there lived a coder named Alex. Alex, like many of their fellow developers, had a deep obsession for the perfect office d&#233;cor. Not just any plant, tree, lights, wall cheatsheets, curved 49-inch monitor, fancy mouse or keyboard would do; it had to be a symbol, a representation of their coding expertise.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jbBx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jbBx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!jbBx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!jbBx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!jbBx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jbBx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1548073,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jbBx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!jbBx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!jbBx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!jbBx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c701cb9-0e5c-49b8-8f59-0063c594e6a6_1024x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The ultimate office decor of a software engineer: &#9989;Plant &#9989;Curved monitor &#9989;Dim lights &#9989;Cheatsheets &#10060;Sticker &#10060;Mini Boxes</figcaption></figure></div><p>And so, on a bright Monday morning, whilst on their break working remotely from home, Alex set out on a mission for two specific items: a unique <strong>sticker for their laptop</strong> and the perfect <strong>box for their desk</strong>.</p><h2>The laptop sticker: A tale of Structs</h2><p>Alex first found themselves at an old-fashioned little shop named &#8220;Struct's Stickers&#8221; The shopkeeper, a friendly soul with a passion for organisation, handed Alex a vibrant sticker book. &#8220;This,&#8221; she said with a smile, &#8220;is a Struct sticker, like a struct in .NET. Each sticker in this book is a value in itself. When you place a sticker somewhere, it's independent. There's no referencing back to this book. It's gone and no one else can have it or modify it.&#8221;</p><p>Alex was intrigued. &#8220;So, if I put a sticker on my laptop, it stays there as it is, no changes back here?&#8221; they asked.</p><p>&#8220;Exactly!&#8221; the shopkeeper replied. &#8220;It's simple, efficient, and self-contained. No overhead, no strings, just the value as it is. Just like a struct, it's about having a direct, value-type interaction.&#8221;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pD8Q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pD8Q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!pD8Q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!pD8Q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!pD8Q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pD8Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ab5e6a6-7a4a-4225-b717-8b69eafa98ee_1024x1024.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2182119,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pD8Q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!pD8Q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!pD8Q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!pD8Q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859665b0-34c2-4cef-8177-ea398e263253_1024x1024.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Old-fashioned little shop named &#8220;Struct's Stickers&#8221; selling stickers on the left, and a modern store called &#8220;Classy Boxes&#8221; selling catalogues of boxes on the right.</figcaption></figure></div><h2>The desk box: A story of Classes</h2><p>Next, Alex found themselves in a modern store called &#8220;Classy Boxes&#8221; The store manager, a tech-savvy individual, presented Alex with an interactive catalog of boxes. &#8220;This,&#8221; he explained, &#8220;is similar to a class in .NET. You see, each item here has a key. When you select a key, it doesn&#8217;t bring you the item directly. Instead, it references the item stored in our central repository, in our warehouse at the back.&#8221;</p><p>Alex nodded thoughtfully. &#8220;So, if the item changes in the repository, it changes for everyone who has the key?&#8221;</p><p>&#8220;That&#8217;s right,&#8221; the manager said. &#8220;It&#8217;s about shared references and connections. One update, and it's reflected wherever that key is used and for everyone sharing the key. For example, you might paint the box blue, but your partner who has a copy of the key, decides that the box looks better green. Next time you decide that you need the box, you will be surprised that the box is now green, and not blue.&#8221;</p><h2>Alex's choice: A blend of both worlds</h2><p>Returning to their desk, Alex placed the struct-like sticker book and the class-like catalogue side by side. The sticker book, a testament to independence and simplicity, and the boxes catalogue, a symbol of interconnectedness and shared states.</p><p>And so, Alex's desk became a little haven of .NET wisdom, a fine balance between the shared references of classes and the straightforward values of structs. A daily reminder that in coding, as in life, the beauty often lies in using the right approach for the right purpose.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Pz5Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Pz5Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Pz5Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Pz5Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Pz5Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Pz5Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png" width="728" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ee0a76d-8706-4f2a-a405-3a4e85a5d401_1024x1024.png&quot;,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:1450357,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Pz5Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!Pz5Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!Pz5Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!Pz5Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9974a2f-46e8-4283-aae4-8d27e14b2c50_1024x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Navigating Struct, Class, and Record in practice</h2><p>In C#, a <strong>struct </strong>is like a sticker in a Sticker Book: simple and value-based; a <strong>class </strong>is like a Catalog with Keys: more complex, with reference-based items.</p><h3>Why mastering these concepts</h3><p>Understanding the concepts of classes, structs, and records is vital not only for writing excellent code, but also for interviewing at FAANG companies (Facebook, Amazon, Apple, Netflix, Google) and Microsoft, particularly for software engineering roles. Here's why:</p><ol><li><p><strong>Fundamentals of Object-Oriented Programming (OOP):</strong> Classes are a core component of OOP, a widely-used programming paradigm. A solid grasp of OOP principles is often expected in software engineering interviews.</p></li><li><p><strong>Understanding data structures:</strong> Structs, often used for lightweight data structures, are part of the broader topic of data structures, which is a key area in technical interviews.</p></li><li><p><strong>Language-specific knowledge:</strong> If you're interviewing for a position that specifically requires or prefers experience with .NET or languages like C#, demonstrating knowledge in these areas can be advantageous.</p></li><li><p><strong>System design and performance considerations:</strong> Understanding when to use classes, structs, or records can play a significant role in designing your system or solve a problem with efficient and appropriate use of data structures, focusing on high-performance computing or optimisation.</p></li><li><p><strong>Immutability and modern programming practices:</strong> With the advent of records in C#, awareness of immutable data types and their benefits in certain programming paradigms (like functional programming or concurrent systems) can be relevant.</p></li></ol><p>These concepts are generally considered foundational for software engineering. Let's dive into each individual one next. For interview questions related to these concepts, go to <strong>Interview Questions</strong> in the <strong>Additional Insights</strong> section.</p><h3>.NET: Understanding Structs and Classes - Part 1: Structs</h3><p><strong>Why use a Struct?</strong></p><p>In .NET, a <code>struct</code> (short for structure) is a <strong>value type</strong> that represents simple, small data structures. Unlike classes, structs are <strong>stored on the stack</strong>, which can make them more efficient for certain use cases. They are ideal when you need a lightweight object that doesn&#8217;t require the overhead of a class.</p><p>Consider the <code>Sticker</code> struct:</p><pre><code><code>struct Sticker
{
    public string Image;
    public string Description;
}
</code></code></pre><p>This <code>Sticker</code> struct is a perfect example of when to use a struct in .NET. It's a simple object with two properties, <code>Image</code> and <code>Description</code>, and doesn't require the additional functionality that a class provides.</p><p><strong>When to use a Struct?</strong></p><ol><li><p><strong>Small and simple:</strong> Use structs for small data structures that have simple behaviour and don't need to inherit from other types or be a base for other types.</p></li><li><p><strong>Value semantics:</strong> If you want your type to exhibit value-like behaviour, where each instance is independent and copying creates a completely separate instance, a struct is a good choice.</p></li><li><p><strong>Performance considerations:</strong> For scenarios where performance is critical and you're dealing with a large number of instances, structs can be more efficient as they are allocated on the stack.</p></li></ol><p><strong>How to use a Struct in .NET</strong></p><p>Using the <code>Sticker</code> struct is straightforward:</p><ol><li><p><strong>Initialisation:</strong> You can create an instance of a struct without a <code>new</code> operator, but using <code>new</code><em><strong> </strong></em>ensures all fields are initialised.</p></li></ol><pre><code><code>Sticker mySticker = new Sticker { Image = "smiley.png", Description = "Smiley Face" };
</code></code></pre><ol start="2"><li><p><strong>Value type behaviour:</strong> Remember, structs are value types. Assigning a struct variable to another one copies the struct entirely, not just the reference.</p></li><li><p><strong>Limitations:</strong> Structs don&#8217;t support inheritance and have some limitations compared to classes. They can implement interfaces but cannot derive from another struct or class.</p></li></ol><p>In the next part, we'll delve into classes using the <code>Catalog with Keys</code> example, exploring their more complex and interconnected nature in .NET.</p><h3>.NET: Understanding Structs and Classes - Part 2: Classes</h3><p><strong>Why use a Class?</strong></p><p>A <code>class</code> in .NET is a <strong>reference type</strong> that can represent more complex data structures and behaviours than structs. Classes are <strong>stored on the heap</strong>, which allows for more flexibility and functionality, such as inheritance, polymorphism, and more sophisticated memory management.</p><p>Consider the <code>Catalog</code> and <code>Box</code> classes:</p><pre><code><code>class Catalog
{
    private Dictionary&lt;string, Box&gt; boxes = new Dictionary&lt;string, Box&gt;();

    public void AddBox(string key, Box box)
    {
        boxes[key] = box;
    }

    public Box GetBox(string key)
    {
        return boxes[key];
    }
}

class Box
{
    public string Name;
    public string Type;
}
</code></code></pre><p>These classes exemplify the more complex and interconnected nature of classes in .NET.</p><p><strong>When to use a Class?</strong></p><ol><li><p><strong>Complex structures:</strong> Use classes for more complex data structures that require additional functionality like inheritance or polymorphism.</p></li><li><p><strong>Reference semantics:</strong> If you need reference-type behaviour, where different instances can refer to the same object, a class is the appropriate choice.</p></li><li><p><strong>Extensibility:</strong> Classes are ideal when you need to extend the functionality, such as adding new methods or using inheritance.</p></li></ol><p><strong>How to use a Class in .NET</strong></p><p>Using the <code>Catalog</code> class involves several steps:</p><ol><li><p><strong>Initialisation:</strong> Classes must be instantiated using the <code>new</code> keyword.</p></li></ol><pre><code><code>Catalog myCatalog = new Catalog();
</code></code></pre><ol start="2"><li><p><strong>Reference type behaviour:</strong> Remember, classes are reference types. When you assign a class instance to another variable, both variables refer to the same object instance.</p></li><li><p><strong>Methods and properties:</strong> Classes can have methods, properties, and events. This allows for encapsulation and interaction with the object's data.</p></li></ol><pre><code><code>Box myBox = new Box { Name = "Gadget", Type = "Electronics" };
myCatalog.AddBox("001", myBox);
</code></code></pre><ol start="4"><li><p><strong>Inheritance and polymorphism:</strong> Classes can inherit from other classes, allowing for code reuse and polymorphic behaviour.</p></li></ol><p>The <code>Catalog</code> and <code>Box</code> classes demonstrate the advantages of using classes in .NET for complex, interconnected data structures. While structs are excellent for simple, value-type objects, classes provide the necessary infrastructure for more sophisticated and flexible programming needs.</p><p>In C# there is one more related concept which we will have a look at next: <strong>Records</strong>, a feature that was added in a more recent version of the language.</p><h3>.NET: Understanding Structs, Classes, and Records - Part 3: Records</h3><p>Additionally to Structs and Classes, it is worth talking about Records. Microsoft introduced records primarily to address specific needs in modern programming that weren't fully catered to by existing constructs like <strong>classes </strong>and <strong>structs</strong>.</p><p><strong>Why use a Record?</strong></p><p>A record in .NET is a reference type like a class, but it's primarily intended for immutable object scenarios. Introduced in C# 9.0, records provide a simpler syntax for creating data-centric types with value-based equality semantics. This makes them particularly suitable for data transfer objects (DTOs), read-only data models, and other scenarios where data immutability is critical.</p><p><strong>When to use a Record?</strong></p><ol><li><p><strong>Immutability:</strong> Records are ideal when working with data that shouldn't change after creation. This immutability ensures data consistency and thread safety.</p></li><li><p><strong>Value-Based equality:</strong> Use records when you need to compare objects based on their values rather than their references.</p></li><li><p><strong>Concise syntax:</strong> Records offer a more concise syntax for creating types that are primarily used to store data.</p></li></ol><p><strong>How to use a Record in .NET</strong></p><p>Here's an example of a record in C#:</p><pre><code><code>record Box(string Name, string Type);

record Box
{
    public string Name { get; init; }
    public string Type { get; init; }
}
</code></code></pre><p>Using a record involves:</p><ol><li><p><strong>Initialisation:</strong> Records can be instantiated similarly to classes, but with <code>init</code> properties allowing for immutable data.</p></li></ol><pre><code><code>var box = new Box { Name = "Gadget", Type = "Electronics"};
</code></code></pre><ol start="2"><li><p><strong>Value-Based equality:</strong> When you compare two record instances, the comparison is based on the values of their properties.</p></li></ol><pre><code><code>var anotherBox = new Box { Name = "Gadget", Type = "Electronics" };
bool areEqual = box == anotherBox; // true, because values are the same
</code></code></pre><p>Implementing equality is the primary distinction compared to a class. Unlike records, determining if two instances of a class are equal typically involves defining properties and handling equality manually. This often requires more code and careful consideration to ensure correctness. Please refer to <em>Implementing equality in a Class</em> in the <strong>Additional Insights</strong> section for an example of how this is achieved.</p><ol start="3"><li><p><strong>With-Expressions:</strong> Records support with-expressions which enable you to create a new record while changing some properties.</p></li></ol><pre><code><code>var updatedBox = box with { Type = "AI" };
</code></code></pre><ol start="4"><li><p><strong>Immutability:</strong> Once a record is created, its data cannot be changed, making it safe to share across different parts of an application without the risk of unintended modifications.</p></li></ol><p>Records in .NET provide an efficient way to handle immutable data structures with value-based equality. They simplify the creation of data models and ensure data consistency, making them an essential tool for modern .NET development.</p><p>This three-part sections on <strong>structs</strong>, <strong>classes</strong>, and <strong>records </strong>in .NET aims to provide a clear understanding of these fundamental types. Each part offers insights into when and how to use these constructs, helping developers to make informed decisions in their .NET coding journey.</p><h2>Conclusion</h2><p>I hope that my little story will make it easier to remember what data structure to use and when. Just think about the sticker on your laptop or picture on the wall, versus the key to a shared box that contains the toys you share with your best friends. I hope this analogy will make it stick.</p><p>In .NET programming, the choice between <strong>struct</strong>, <strong>class</strong>, and <strong>record </strong>depends on your specific needs. Structs are your go-to for lightweight data storage, classes are ideal for more complex entities with behaviours, and records shine in scenarios requiring immutability and consistency. Through these examples, you can better understand when and why to use each construct, paving the way for becoming an even more awesome, agile coder and software engineer.</p><p>Until our next coding story, I am wishing you happy coding!</p><h2>Additional Insights</h2><p>Too much information can be overwhelming, particularly for those at the beginning of their coding journey. Recognising this, I aim to keep my articles concise yet informative, ensuring they cover the essentials.</p><p>The information provided so far aims to be informative enough. In this 'Additional Insights' section, I will further expand on the initial topics and ideas of the article.</p><h3>Implementing equality in a Class</h3><p>In C#, to determine equality for two objects of a class, you typically need to override the <code>Equals</code> method and, for best practices, the <code>GetHashCode</code> method as well. This allows you to define what it means for two instances of your class to be considered "equal." By default, classes in C# compare references, so two distinct instances are not equal even if their properties have the same values.</p><p>Here's how you could implement this for the <code>Box</code> class:</p><pre><code><code>class Box
{
    public string Name { get; set; }
    public string Type { get; set; }

    public Box(string name, string type)
    {
        Name = name;
        Type = type;
    }

    public override bool Equals(object obj)
    {
        // Check for null and compare run-time types.
        if (obj == null || GetType() != obj.GetType())
        {
            return false;
        }

        Box other = (Box)obj;
        return Name == other.Name &amp;&amp; Type == other.Type;
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(Name, Type);
    }
}

// Usage Example
var box1 = new Box("Gadget", "Electronics");
var box2 = new Box("Gadget", "Electronics");

bool areEqual = box1.Equals(box2); // This will be true
</code></code></pre><h4>Key Points:</h4><ol><li><p><strong>Equals method</strong>: It's overridden to compare the properties (<code>Name</code> and <code>Type</code> in this case) of the two <code>Box</code> objects. If the properties match, the two objects are considered equal.</p></li><li><p><strong>GetHashCode method</strong>: This is overridden to provide a hash code based on the same properties used for equality. This is important for objects used in collections like hash tables.</p></li><li><p><strong>Reference equality</strong>: Without these overrides, <code>box1.Equals(box2)</code> would return <code>false</code> because, by default, equality for reference types is based on reference equality (i.e., whether both references point to the same object in memory).</p></li></ol><p>Implementing these methods gives you control over how instances of your class are compared and deemed equal, which can be crucial for certain types of applications, especially those involving collections or comparisons of object instances.</p><h3>Understanding Structs, Classes, and Records across different languages</h3><p>Different languages implement these constructs in unique ways, reflecting their individual paradigms and design philosophies. I hope that this addition will show that is not difficult to learn a new language, once you know the basics. Let's delve into how various languages, including C++, Java, Swift, F#, Kotlin, JavaScript, TypeScript, Rust, Scala and Python handle them:</p><ol><li><p><strong>C++</strong>:</p><ul><li><p><strong>Struct</strong>: Similar to classes but default to public access. Used for defining custom data types.</p></li><li><p><strong>Class</strong>: Fundamental to C++'s object-oriented programming, offering features like encapsulation and inheritance.</p></li><li><p><strong>Record</strong>: No native record; classes and structs serve similar purposes.</p></li></ul></li><li><p><strong>Java</strong>:</p><ul><li><p><strong>Struct</strong>: Not present; classes are used instead.</p></li><li><p><strong>Class</strong>: Essential for Java&#8217;s object-oriented approach.</p></li><li><p><strong>Record</strong>: Standardized in Java 16, offering a succinct way to create immutable data-carrier classes.</p></li></ul></li><li><p><strong>Swift</strong>:</p><ul><li><p><strong>Struct</strong>: Common for custom data types, especially when no inheritance is needed.</p></li><li><p><strong>Class</strong>: Supports object-oriented features like inheritance.</p></li><li><p><strong>Record</strong>: Not available; similar functionality achieved through structs and classes.</p></li></ul></li><li><p><strong>F#</strong>:</p><ul><li><p><strong>Struct</strong>: Used similarly to C# for value types.</p></li><li><p><strong>Class</strong>: Less common than in C#, but available for object-oriented programming.</p></li><li><p><strong>Record</strong>: A core feature, providing simple, immutable data containers.</p></li></ul></li><li><p><strong>Kotlin</strong>:</p><ul><li><p><strong>Struct</strong>: Not available; uses classes and data classes instead.</p></li><li><p><strong>Class</strong>: Integral to Kotlin, with modern object-oriented features.</p></li><li><p><strong>Record</strong>: Data classes in Kotlin are akin to records, facilitating the creation of immutable data-holders.</p></li></ul></li><li><p><strong>JavaScript</strong>:</p><ul><li><p><strong>Struct</strong>: Not applicable; JavaScript uses objects and prototypes.</p></li><li><p><strong>Class</strong>: Introduced in ES6, providing a more traditional object-oriented syntax over JavaScript's existing prototype-based inheritance.</p></li><li><p><strong>Record</strong>: Not a native concept; objects and arrays are typically used for similar purposes.</p></li></ul></li><li><p><strong>TypeScript</strong>:</p><ul><li><p><strong>Struct</strong>: TypeScript does not have structs; it uses interfaces and classes.</p></li><li><p><strong>Class</strong>: Similar to JavaScript but with added type safety and features like interfaces.</p></li><li><p><strong>Record</strong>: TypeScript provides a <code>Record</code> utility type, offering a way to construct objects with a common value type.</p></li></ul></li><li><p><strong>Rust</strong>:</p><ul><li><p><strong>Struct</strong>: Central to Rust, used for creating custom data types with an emphasis on safety.</p></li><li><p><strong>Class</strong>: Rust does not have classes; it uses structs and traits for similar functionalities.</p></li><li><p><strong>Record</strong>: Not explicitly present; structs along with pattern matching provide similar capabilities.</p></li></ul></li><li><p><strong>Scala</strong>:</p><ul><li><p><strong>Struct</strong>: Scala doesn't have a direct equivalent of a struct; case classes are somewhat similar.</p></li><li><p><strong>Class</strong>: Fundamental in Scala, supporting both object-oriented and functional programming paradigms.</p></li><li><p><strong>Record</strong>: Scala 3 introduces record-like structures through case classes with the <code>derives</code> keyword.</p></li></ul></li><li><p><strong>Python</strong>:</p><ul><li><p><strong>Struct</strong>: Not available as a specific type; classes are used for similar purposes.</p></li><li><p><strong>Class</strong>: A primary feature in Python, used extensively for various types of data modelling.</p></li><li><p><strong>Record</strong>: Python uses named tuples and data classes which can be seen as equivalents to records.</p></li></ul></li></ol><p>This selection encompasses languages that are widely used in various domains of software development, ranging from system programming to web and mobile applications, and represent a mix of paradigms from object-oriented to functional programming.</p><p>This diversity helps in understanding how different languages approach similar concepts, providing valuable insights for developers who work across multiple programming ecosystems or are curious about language-specific implementations of structs, classes, and records.</p><h3>Interview Questions</h3><p>We have explored several concepts in this article. Remember, reading is one thing, but doing is another. Actively engaging with the material reinforces it in our long-term memory, aiding not just in coding but also in interview situations. I would recommend examining the sample interview questions below and revisiting them after a few days for better retention.</p><h4>Basic questions</h4><ol><li><p><strong>What is the difference between a class and a struct in .NET?</strong></p><ul><li><p>This question tests basic understanding of the key differences between classes and structs.</p></li></ul></li><li><p><strong>Can you explain what immutability is and how records in C# support it?</strong></p><ul><li><p>This is to understand the candidate's knowledge of immutability and the use of records.</p></li></ul></li><li><p><strong>How do you implement inheritance in C#? Can structs inherit from other structs or classes?</strong></p><ul><li><p>A question to assess understanding of inheritance in C# and the limitations related to structs.</p></li></ul></li><li><p><strong>What are the default access modifiers for classes and structs in C#?</strong></p><ul><li><p>Tests knowledge of C# specific syntax and defaults.</p></li></ul></li></ol><h4>Intermediate questions</h4><ol start="5"><li><p><strong>When would you choose to use a struct over a class in a .NET application?</strong></p><ul><li><p>This evaluates the candidate's ability to make decisions about when to use value types (structs) versus reference types (classes).</p></li></ul></li><li><p><strong>Can you give an example of a situation where a record type would be more suitable than a class or struct in C#?</strong></p><ul><li><p>Looks for understanding of records' use cases.</p></li></ul></li><li><p><strong>Explain the concept of a constructor in a class. How does it differ in a struct?</strong></p><ul><li><p>Tests deeper understanding of object Initialisation in both classes and structs.</p></li></ul></li><li><p><strong>What is the significance of the &#8216;readonly&#8217; keyword in structs in C#?</strong></p><ul><li><p>Checks knowledge about enhancing immutability in structs.</p></li></ul></li></ol><h4>Advanced questions</h4><ol start="9"><li><p><strong>Discuss the memory allocation differences between classes and structs in .NET and how it impacts performance.</strong></p><ul><li><p>A more in-depth question about the underlying workings of .NET's memory management.</p></li></ul></li><li><p><strong>How does garbage collection work with classes and structs in .NET?</strong></p><ul><li><p>Tests understanding of .NET&#8217;s garbage collection mechanism and how it applies to different types.</p></li></ul></li><li><p><strong>Can you explain the concept of boxing and unboxing in .NET? How does it relate to structs and classes?</strong></p><ul><li><p>Evaluates understanding of an important aspect of .NET performance optimization.</p></li></ul></li><li><p><strong>In what scenarios might you use a record with a with-expression in C#?</strong></p><ul><li><p>Looks for knowledge of newer C# features and their practical applications.</p></li></ul></li></ol><h4>Scenario based questions</h4><ol start="13"><li><p><strong>Given a scenario where you need to represent a lightweight, frequently used data point (like a 2D coordinate), would you use a class or a struct? Explain your choice.</strong></p><ul><li><p>A practical application question to assess decision-making skills.</p></li></ul></li><li><p><strong>If you were designing an API response model for a high-traffic web service, would you use classes, structs, or records for the data models? Justify your answer.</strong></p><ul><li><p>Tests application of knowledge in a real-world scenario, focusing on performance and design considerations.</p></li></ul></li></ol><p>These questions can provide a comprehensive overview of a developer's understanding and application of classes, structs, and records in .NET and general programming contexts.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.catsays.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Agile Coder / Agile Software Engineering! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Tech Debt visits the City of Codeville]]></title><description><![CDATA[In the heart of a vast open area, in a hidden corner of the world, there was a growing town named Codeville.]]></description><link>https://blog.catsays.net/p/tech-debt-city-of-codeville</link><guid isPermaLink="false">https://blog.catsays.net/p/tech-debt-city-of-codeville</guid><dc:creator><![CDATA[Cat Rosu]]></dc:creator><pubDate>Mon, 06 Nov 2023 11:30:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!GbxB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GbxB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GbxB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png 424w, https://substackcdn.com/image/fetch/$s_!GbxB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png 848w, https://substackcdn.com/image/fetch/$s_!GbxB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!GbxB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GbxB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png" width="1456" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png&quot;,&quot;srcNoWatermark&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1f17ebf3-9d72-47fa-b252-2f6662d2a980_1792x1024.png&quot;,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3906087,&quot;alt&quot;:&quot;Well-planned town vs. chaotic town&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Well-planned town vs. chaotic town" title="Well-planned town vs. chaotic town" srcset="https://substackcdn.com/image/fetch/$s_!GbxB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png 424w, https://substackcdn.com/image/fetch/$s_!GbxB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png 848w, https://substackcdn.com/image/fetch/$s_!GbxB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!GbxB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad59105e-910a-4d05-a364-487c0f7a3204_1792x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Codeville: A tale of two approaches - On the left, the Proper Planning district shines with its well-organized, robust infrastructure, symbolising the foresight of meticulous software development. On the right, the Technical Debt quarter stands in disarray, a reminder of the long-term consequences of quick fixes and neglected architecture.</figcaption></figure></div><p>In the heart of a vast open area, in a hidden corner of the world, there was a growing town named Codeville. In its early days, the town was a marvel, built swiftly with vision and dreams. Its roads were straightforward, houses well-constructed, and all its systems operated in harmony. Travellers from far and wide came to admire its brilliance.</p><p>However, as the city grew, the founders started taking shortcuts. Instead of repairing the old bridge, they would hastily add planks just to keep it standing. Instead of planning new streets, they built them wherever they found space, leading to a maze of confusing alleys. Over time, these shortcuts accumulated and became part of the town&#8217;s architecture, referred to by the locals as the <em>Debt Districts</em>.</p><p>Soon, the <em>Debt Districts</em> started showing their strain. The old bridge creaked worryingly, and the streets became congested. The newer parts of the city, built atop the old, inherited its vulnerabilities. Cracks began to show, and systems failed. The once-prosperous town was now a shadow of its former self.</p><p>Then came the day when the town's main square, a beautiful area once loved by all, collapsed due to a weak foundation. The calamity served as a wake-up call for the residents of Codeville.</p><p>With a united resolve, the city decided to address their growing "debt." They brought in architects and planners, who advised them to take a step back, repair the foundations, and restructure the city. The process was slow and often painful, as they had to undo and redo much of what was hastily built. But with time, Codeville started finding its former glory.</p><h2>Introduction: A tale of Codeville</h2><p>Much like the rebuilding journey of Codeville, software development often encounters hurdles. These hurdles, often called <strong>'Technical Debt'</strong>, can jeopardise the future of projects and the businesses they support. Through this story, let's journey together to understand what technical debt is, why it matters, and how to manage it effectively.</p><h2>The birth of 'Technical Debt'</h2><p>In 1992, Ward Cunningham compared taking shortcuts in software to building up financial debt. In his paper on <a href="https://dl.acm.org/doi/10.1145/157710.157715">The WyCash portfolio management system</a>, he highlighted the core challenge facing developers: "Every minute spent on not-quite-right code counts as interest on that debt." The longer you delay addressing this debt, the more costly it becomes.</p><p>Imagine building a bridge in haste. While it may serve its immediate purpose, the flaws in its construction will, in time, require more repair effort than if it had been built correctly from the start.</p><p>In software development, <strong>Technical Debt</strong> refers to the consequences of quick solutions over optimal ones, leading to software that over time becomes challenging and expensive to update or modify.</p><h3>Tech Debt example</h3><p>Consider a web application built in 2000, using what was best and popular at that time, that never got upgraded:</p><ul><li><p>Frontend: Built using plain HTML, CSS, and JavaScript without any frontend framework.</p></li><li><p>Backend: The application's logic was crafted using PHP 5.3, without leveraging any modern MVC frameworks like Laravel, Symfony.</p></li><li><p>Database: Data was stored using MySQL 5.1.</p></li></ul><p>While the application might still function today, opting not to upgrade, at the earliest opportunity possible, incurs certain costs, naming only few:</p><ul><li><p><strong>User experience (UX)</strong>: The plain JavaScript and limited AJAX capabilities meant the site was less interactive. With the rise of single-page applications using Angular, React, Vue.js or Blazor, users came to expect a seamless browsing experience.</p></li><li><p><strong>Performance issues</strong>: Newer versions of the web framework introduce optimizations, making applications run faster and more responsively.</p></li><li><p><strong>Security vulnerabilities</strong>: The older version of the framework and database had known vulnerabilities, thereby posing risks to your application and organisation.</p></li><li><p><strong>Maintenance overhead</strong>: Developers face challenges maintaining and understanding dated code. New team members may be less acquainted with the old version, leading to extended training periods. Some features or plugins, standard with newer frameworks, might necessitate custom development in your older version.</p></li><li><p><strong>System limitations</strong>: New modern third-party tools and plugins might not always be compatible with the older tech stack, limiting potential enhancements.</p></li><li><p><strong>Missed opportunities</strong>: With a contemporary database and framework, implementing features like personalised user recommendations based on browsing history, or effective logging and auditing for compliance, would be straightforward. Yet, with such an outdated system, these either run too slowly, are too resource-intensive, or are virtually impossible.</p></li><li><p><strong>Expensive</strong>: Some old software necessitate licenses are typically pricier than other open-source alternatives. Nowadays, using platforms like Docker can offer more cost-effective hosting solutions.</p></li></ul><p>An application built two decades ago isn't inherently obsolete. With consistent maintenance and timely upgrades, such software can remain relevant and efficient in today's tech landscape. The accumulated knowledge and expertise from its long history can be its greatest strength. However, if neglected and left to age without attention, its chances, if any, of retaining relevance dramatically decrease.</p><h2>Why is it important?</h2><p>While developers might feel the pinch of tech debt the most, its implications are far-reaching:</p><ol><li><p><strong>Business operations:</strong> Delayed updates can affect business operations, leading to loss of revenue and customer trust.</p></li><li><p><strong>Team morale:</strong> Constantly firefighting issues reduces team morale and hampers innovation.</p></li><li><p><strong>Customers:</strong> Inefficient systems can lead to a poor user experience, driving customers away.</p></li></ol><p>Understanding technical debt matters for two primary reasons: its domain-specific reference and its personal nature. While the metaphor might not resonate with every business, its consequences - like potholes that evolve into gaping road hazards - affect entire communities. Think of the repercussions: damaged vehicles, raised insurance premiums, and worst of all, tragic accidents.</p><h2>Why does Technical Debt accumulate?</h2><p>Three decades on, the tech world continues wrestling with technical debt, even in the face of countless resources advocating for clean code and best practices. Why does this challenge persist? The answer lies in understanding the dynamics at play from both top-down and bottom-up perspectives.</p><h3>Top-Down view: The leadership disconnect</h3><p>Most organizations exist to grow and profit. Their leaders hire various experts to drive this growth. For most companies, the development team's output plays a crucial role. However, a disconnect often arises between the ground realities and the leadership's understanding.</p><ol><li><p><strong>Distorted communications</strong>: In hierarchical organisations, the flow of information from one level to another can sometimes undergo subtle changes. A team might communicate certain challenges they are facing, but as this information is relayed upwards through various levels, its essence might get modified due to a variety of reasons, such as unintentional over-simplifications or the nuances getting lost in translation. Consequently, by the time the message reaches the top tier, it might not fully capture the initial concerns raised at the ground level.</p></li><li><p><strong>Avoidance and consequence</strong>: When challenges aren't communicated effectively, they're likely to be ignored or sidelined. This burying of issues can lead to significant future problems. By the time the depth of the issue is realised, it may be too late for a simple fix, leading to a ripple effect of complications.</p></li><li><p><strong>Unified vision</strong>: Successful software projects demand cohesion between business objectives and technical execution. Without clear vision, transparency and shared understanding across levels, discrepancies arise, often leading to avoidable technical debt.</p></li></ol><p>True leadership requires transparency. Recognizing and addressing issues, rather than masking them, is the cornerstone of successful software engineering projects.</p><h3>Bottom-Up view: On-the-ground challenges</h3><p>The drive to achieve rapid growth and deliver quick results often pushes organisations to compromise on code quality. Combine this with evolving technologies, team turnovers, the inevitable knowledge gaps that arise, and maintaining older systems becomes a daunting task.</p><p>Key Challenges:</p><ul><li><p><strong>Rapid delivery over quality</strong>: The push for speed can overshadow the importance of quality.</p></li><li><p><strong>Evolution and turnover</strong>: Technologies evolve, and with team members coming and going, knowledge continuity is disrupted.</p></li><li><p><strong>Lack of oversight and expertise</strong>: Without regular reviews, mentoring, and a focus on skill development, code quality can suffer.</p></li><li><p><strong>Communication barriers</strong>: Even when development managers raise red flags, these alarms are sometimes ignored or deferred by higher-ups.</p></li></ul><p>Drawing a parallel with our town analogy, businesses might focus on constructing and monetizing houses, neglecting community essentials like schools or hospitals. A town without these facilities prioritises profit over the well-being of its inhabitants. Similarly, in the software world, neglecting foundational quality can lead to monumental challenges down the line.</p><p>It's crucial to remember that no structure, be it a building or software, is meant to last indefinitely without the need for adjustments.</p><h3>Google's Technical Debt case study</h3><p>When seeking tangible examples of why and how technical debt accumulates, industry giants, often referred to as the FAANG companies, serve as invaluable case studies. Their vast and intricate software systems, combined with the necessity to constantly innovate, make them prime subjects for understanding the complexities of technical debt.</p><p>One standout example is Google. In 2023, they unveiled a comprehensive paper detailing their approach to defining, measuring, and managing technical debt. This can be accessed at <a href="https://ieeexplore.ieee.org/document/10109339">Google's Technical Debt Paper</a>. The dedication Google exhibited by investing four years to thoroughly comprehend and address their technical debt underscores the significance and complexity of the issue. This deep dive into Google's strategies provides a segue into a broader discussion on the inevitability of technical debt in software development and the need for proactive management strategies.</p><p>This realisation brings us to the question of management - acknowledging that while technical debt cannot be entirely prevented, it must be meticulously managed to minimize its impact.</p><h2>Addressing the elephant in the room</h2><p>The best way to address technical debt is not have it in the first place.</p><p>The ideal strategy to manage technical debt is to anticipate it and incorporate proactive measures into the development process. It's about treating software as a continuously evolving entity, requiring regular maintenance and foresight. Similar to routine vehicle services ensuring its efficiency and safety, regular software reviews and updates are essential for its health and sustainability.</p><p>Here are some actionable steps for managing tech debt effectively:</p><ol><li><p><strong>Emphasize communication:</strong> Effective communication is paramount. Encourage developers to articulate issues in a way that resonates with stakeholders, ensuring that technical and business sides are aligned on tech debt implications.</p></li><li><p><strong>Focus on user needs:</strong> Focus on delivering functionality that aligns with actual user needs rather than perceived business requirements. Validate ideas through user research and prototyping.</p></li><li><p><strong>Tackle work effectively</strong>: Ensure that work items have clear definitions, with well defined requirements, user stories, acceptance criteria, and test scenarios. Agile methodologies can be particularly effective in managing tech debt by incorporating regular reflection and improvement into the development cycle. Apply refactoring as an ongoing practice to adapt the codebase proactively. Encourage collaborative practices such as pair programming and code reviews, and consider mob programming for complex issues.</p></li><li><p><strong>Make collaborative decisions:</strong> Involve the whole team in architectural decisions to foster ownership and ensure that designs reflect on-the-ground realities. Ensure that all decisions are made publicly and with transparency. This approach helps future team members understand the rationale behind past decisions, which may not seem optimal in hindsight but were the best given the context at the time.</p></li><li><p><strong>Establish clear guidelines:</strong> Simply asking for clean code is insufficient. No developer intentionally crafts poor code. Provide your developers with explicit processes, coding standards and best practices to align individual efforts with your project's objectives and industry benchmarks.</p></li><li><p><strong>Leverage tools effectively:</strong> Make use of tools like SonarQube, Klockwork, SQUORE, or built-in metrics and analysis tools in IDEs, to monitor and address technical debt in real-time. These tools can provide insights that pre-empt debt accumulation.</p></li><li><p><strong>Prioritize regular reviews</strong>: Implement a systematic approach to review your codebase and architectural design at regular intervals. This ensures ongoing quality control and identifies opportunities for refinement. Encourage teams to adopt a proactive stance on technical oversight, integrating these evaluations into the development lifecycle. Additionally, consider periodic external audits to provide a third-party perspective on adherence to industry standards and best practices.</p></li><li><p><strong>Invest in training and leadership development</strong>: Regular training is key to avoiding technical debt. Teach your team good coding habits and how to design systems that are easy to maintain, following the best coding and design practices. Look for the leaders in your team - the ones who are really good but also down-to-earth, smart and passionate - and help them lead the way. They can show everyone how to do things better, making sure that the team's work gets better over time.</p></li><li><p><strong>Integrate technical debt management:</strong> Allocating a specific portion of development time to manage technical debt, typically between 10-20%, could require meticulous planning. It&#8217;s crucial to determine whether this is a temporary or a permanent commitment within each sprint, as well as how to measure this allocation effectively. With time also set aside for learning (10%) and sprint meetings (10%), the remaining time for core development can significantly diminish. Integrating technical debt resolution as a standard part of development tasks - including as enabler features or work items - helps prevent it from being overlooked or treated as an afterthought. Should the time allocated for learning and innovation prove insufficient for sparking creativity, it could be repurposed to address technical debt, thereby ensuring continuous improvement.</p></li></ol><h2>A shift in perspective</h2><p>While 'Technical Debt' has been the go-to term, industry leaders like Kent Beck, the creator of Extreme Programming and an Agile Manifesto signatory, advocate for a change in narrative. Kent now speaks of <a href="https://www.mechanical-orchard.com/post/friction-over-debt">Friction</a> instead of technical debt when addressing business stakeholders.</p><p>Yet, perhaps we shouldn't be hung up on labels at all. Instead, our attention should be devoted to the actions we take - prioritizing regular maintenance and ongoing refinement; service your software the same way you service your car.</p><p>The label 'Tech Debt' often becomes a convenient excuse, a procrastinator's promise: "We'll tag it with a TODO and revisit it later." That "later" remains elusive, allowing developers and stakeholders to deflect responsibility. It's less about assigning blame and more about understanding it as an 'enabling work,' acknowledging the past without being hindered by it.</p><h2>What Technical Debt isn't</h2><p>It is important to highlight that not everything should be classed as tech debt. Just because tomorrow a new framework version is release, it does not make your code base old and obsolete.</p><p><strong>Technical Debt isn't:</strong></p><ol><li><p><strong>Simpler code in newer versions</strong>: Just because newer versions of a language or framework allow for more concise or simplified code, it doesn't automatically make the previous verbose version technical debt.</p></li><li><p><strong>Initial architectural decisions</strong>: An architectural choice that was appropriate and fit the purpose when the software was initially built isn't technical debt. If, with time, the original architecture doesn't align with emerging requirements, it's more about the system evolving and less about it being a debt. Adapting to new needs can be viewed as a feature enhancement or system evolution rather than a debt. Think of it as a house renovation to accommodate a growing family rather than a fault in the original construction.</p></li><li><p><strong>Changing best practices</strong>: The tech industry is dynamic, with best practices evolving over time. A practice or tool that was considered state-of-the-art a few years ago might be less favoured today. This evolution doesn't retroactively label the previous practice as technical debt.</p></li><li><p><strong>Code you disagree with</strong>: Personal preferences or disagreements with coding practices don't equate to technical debt. Just because you might've approached a problem differently doesn't mean the existing solution is inherently flawed or in debt.</p></li><li><p><strong>Lack of latest features</strong>: Not having the newest features or functionalities that contemporary software might have isn't necessarily technical debt. If the software serves its intended purpose efficiently and effectively, it's doing its job.</p></li></ol><h2>Conclusion: The sustainable road ahead</h2><p>The importance of discussing and addressing tech debt lies in its foundational role in software development. Just as our world leans towards sustainability in all aspects, software development should be no different.</p><p>The tale of Codeville serves as a stark reminder of the repercussions of neglect. It's not just about building; it's about building the right thing in the right way, reviewing, and adapting. It's a lesson every stakeholder, from developers to business heads, must internalise.</p><p>Good software is built with passion, when everyone, from top to bottom, cares about what and how they build products and services.</p><p>Do not make space for Tech Debt, do not allow it to enter the Tech Debt lane, and certainly do not allow it to enter the town. Make your town or city a success story that you can tell the entire world about it.</p><h3>Extras - Codeville, a pun-intended explanation</h3><p>At the heart of our discussion lies a simple play on words that encapsulates our message: 'Ville' in French means 'city' - bustling hubs of activity, growth, and innovation. Yet, remove just one 'l' and you're left with 'vile', an adjective that means horrid and unpleasant in English. Through this pun, we arrive at the core appeal of this article: to implore not just coders, but everyone involved in the creation and maintenance of software, to steer away from the 'vile' - from creating code that becomes a bane rather than a boon.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.catsays.net/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Agile Coder / Agile Software Engineering! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>