PageSourceSearch

https://maxkim.dev/

html maxkim.dev collected 2026-10-09 23:12:32 UTC 84,534 bytes, 26 lines download raw bytes

1<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/0d16c72050851854.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/7ffcc02a3c67389b.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/c20e76e7d11dec32.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/59fefb2212bd5b60.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-55b36f0cd6c208fe.js"/>
1<script src="/_next/static/chunks/4bd1b696-100b9d70ed4e49c1.js" async=""></script>
1<script src="/_next/static/chunks/9da6db1e-8a4e8c23641c31bf.js" async=""></script>
1<script src="/_next/static/chunks/1255-a242e0ce0372fddf.js" async=""></script>
1<script src="/_next/static/chunks/main-app-bda8a52fe841b3aa.js" async=""></script>
1<script src="/_next/static/chunks/4554-984b480a9db5f3fe.js" async=""></script>
1<script src="/_next/static/chunks/7563-4dfa0994a9b0e37c.js" async=""></script>
1<script src="/_next/static/chunks/9216-9272709ba40c1cfd.js" async=""></script>
1<script src="/_next/static/chunks/2810-6b74d77b4b0dc790.js" async=""></script>
1<script src="/_next/static/chunks/3091-bf1537ff6571a1bd.js" async=""></script>
1<script src="/_next/static/chunks/app/layout-6ae7b4b583d4bba3.js" async=""></script>
1<script src="/_next/static/chunks/app/not-found-b861935655c5698b.js" async=""></script>
1<script src="/_next/static/chunks/5001-fae0bebdd93f95e3.js" async=""></script>
1<script src="/_next/static/chunks/2423-c8b1388240338d7d.js" async=""></script>
1<script src="/_next/static/chunks/652-f40dcb480b4e356f.js" async=""></script>
1<script src="/_next/static/chunks/730-8191af9e9424b148.js" async=""></script>
1<script src="/_next/static/chunks/app/page-cc18ae1a3a7a5ed8.js" async=""></script>
1<meta name="next-size-adjust" content=""/><title>Art and science of writing good code</title><meta name="description" content="A blog powered by Hashnode"/><link rel="canonical" href="https://maxkim.dev"/><meta property="og:title" content="Art and science of writing good code"/><meta property="og:description" content="A blog powered by Hashnode"/><meta property="og:url" content="https://maxkim.dev"/><meta property="og:site_name" content="Art and science of writing good code"/><meta property="og:image" content="https://maxkim.dev/api/og/home?og=eyJ0aXRsZSI6IkFydCUyMGFuZCUyMHNjaWVuY2UlMjBvZiUyMHdyaXRpbmclMjBnb29kJTIwY29kZSIsImlzRGVmYXVsdE1vZGVEYXJrIjpmYWxzZSwicGhvdG8iOiJodHRwczovL2Nkbi5oYXNobm9kZS5jb20vcmVzL2hhc2hub2RlL2ltYWdlL3VwbG9hZC92MTYxNzQ1NDc3Mzc4My92ODNESnhHZVUuanBlZyIsImxvZ28iOm51bGwsImxvZ29EYXJrIjpudWxsLCJpc1RlYW0iOnRydWUsImRvbWFpbiI6Im1heGtpbS5kZXYiLCJmb2xsb3dlcnMiOjE4NiwiYXJ0aWNsZXMiOjAsImZhdmljb24iOiJodHRwczovL2Nkbi5oYXNobm9kZS5jb20vcmVzL2hhc2hub2RlL2ltYWdlL3VwbG9hZC92MTYxNzQ3MjQyMDk1My8xUXhpeVlMQU0ucG5nIn0="/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:creator" content="https://twitter.com/HeyMaxKim"/><meta name="twitter:title" content="Art and science of writing good code"/><meta name="twitter:description" content="A blog powered by Hashnode"/><meta name="twitter:image" content="https://maxkim.dev/api/og/home?og=eyJ0aXRsZSI6IkFydCUyMGFuZCUyMHNjaWVuY2UlMjBvZiUyMHdyaXRpbmclMjBnb29kJTIwY29kZSIsImlzRGVmYXVsdE1vZGVEYXJrIjpmYWxzZSwicGhvdG8iOiJodHRwczovL2Nkbi5oYXNobm9kZS5jb20vcmVzL2hhc2hub2RlL2ltYWdlL3VwbG9hZC92MTYxNzQ1NDc3Mzc4My92ODNESnhHZVUuanBlZyIsImxvZ28iOm51bGwsImxvZ29EYXJrIjpudWxsLCJpc1RlYW0iOnRydWUsImRvbWFpbiI6Im1heGtpbS5kZXYiLCJmb2xsb3dlcnMiOjE4NiwiYXJ0aWNsZXMiOjAsImZhdmljb24iOiJodHRwczovL2Nkbi5oYXNobm9kZS5jb20vcmVzL2hhc2hub2RlL2ltYWdlL3VwbG9hZC92MTYxNzQ3MjQyMDk1My8xUXhpeVlMQU0ucG5nIn0="/><link rel="icon" href="https://cdn.hashnode.com/res/hashnode/image/upload/v1617472420953/1QxiyYLAM.png"/>
1<script type="text/javascript">window.addEventListener('message',function(e){var d=e.data;if(!d||d.__hnWidget!==1||typeof d.h!=='number'||d.h<=0)return;var f=document.querySelectorAll('.hn-widget-frame');for(var i=0;i<f.length;i++){if(f[i].contentWindow===e.source){f[i].style.height=d.h+'px';break;}}});</script>
1<script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script>
1</head><body class="__variable_c2612a __variable_246ccd __variable_3069d5 bg-background dark:bg-background"><div hidden=""><!--$--><!--/$--></div>
1<script>((a2, b2, c4, d3, e2, f2, g4, h3) => {
2          let i3 = document.documentElement, j2 = ["light", "dark"];
3          function k2(b3) {
4            var c5;
5            (Array.isArray(a2) ? a2 : [a2]).forEach((a3) => {
6              let c6 = a3 === "class", d4 = c6 && f2 ? e2.map((a4) => f2[a4] || a4) : e2;
7              c6 ? (i3.classList.remove(...d4), i3.classList.add(f2 && f2[b3] ? f2[b3] : b3)) : i3.setAttribute(a3, b3);
8            }), c5 = b3, h3 && j2.includes(c5) && (i3.style.colorScheme = c5);
9          }
10          if (d3) k2(d3);
11          else try {
12            let a3 = localStorage.getItem(b2) || c4, d4 = g4 && a3 === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : a3;
13            k2(d4);
14          } catch {
15          }
16        })("class","theme","system",null,["light","dark"],null,true,true)</script>
16<main id="main-content" class="min-h-screen bg-background dark:bg-background"><header class="sticky top-0 z-50 w-full py-4 bg-background backdrop-blur-sm transition-transform duration-300 translate-y-0"><a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:left-4 focus:top-4 focus:z-50 focus:rounded-md focus:bg-background focus:px-4 focus:py-2 focus:text-sm focus:shadow">Skip to main content</a><div class="relative w-full mx-auto xl:max-w-[80rem] 2xl:max-w-[90rem] px-4 sm:px-12 md:px-18 lg:px-16 xl:px-10"><div class="flex items-center justify-between gap-3 xl:hidden"><div class="flex items-center gap-3 min-w-0 flex-1"><a href="https://hashnode.com/?utm_source=https%3A%2F%2Fmaxkim.dev&amp;utm_medium=referral&amp;utm_campaign=blog_header_logo&amp;utm_content=logo" class="inline-flex items-center justify-center text-lg text-muted-foreground hover:text-foreground transition border rounded-md h-9 w-9 shrink-0 border-border hover:bg-muted"><i class="text-xl fa-brands fa-hashnode" aria-hidden="true"></i><span class="sr-only">Hashnode</span></a><a title="Art and science of writing good code" class="text-lg font-semibold text-foreground truncate min-w-0" href="/">Art and science of writing good code</a></div><div class="flex items-center gap-2 shrink-0"><button class="gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 hover:bg-accent py-2 h-9 w-9 px-0 flex items-center justify-center text-muted-foreground hover:text-foreground bg-transparent border-border shadow-none" aria-label="Open search (press Control or Command and K)"><i class="fa-jelly fa-search text-sm" aria-hidden="true"></i><span class="sr-only">Open search (press Control or Command and K)</span></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 hover:bg-accent w-9 px-3 h-9 text-muted-foreground hover:text-foreground shadow-none" type="button" id="radix-_R_2j4lfalb_" aria-haspopup="menu" aria-expanded="false" data-state="closed" data-slot="dropdown-menu-trigger"><i class="fa-jelly fa-sun text-sm scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" aria-hidden="true"></i><i class="fa-jelly fa-moon absolute text-sm scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" aria-hidden="true"></i><span class="sr-only">Toggle theme</span></button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 border border-input bg-background hover:bg-accent hover:text-accent-foreground py-2 h-9 w-10 px-0 shadow-none" type="button" aria-haspopup="dialog" aria-expanded="false" aria-controls="radix-_R_3j4lfalb_" data-state="closed" data-slot="sheet-trigger"><i class="fa-jelly fa-bars" aria-hidden="true"></i><span class="sr-only">Open menu</span></button></div></div><div class="hidden xl:grid gap-4 items-center xl:grid-cols-[1fr_auto_1fr] xl:gap-6 max-w-full xl:mx-auto xl:max-w-[80rem] 2xl:max-w-[90rem]"><div class="flex items-center w-full gap-3 min-w-0"><a href="https://hashnode.com/?utm_source=https%3A%2F%2Fmaxkim.dev&amp;utm_medium=referral&amp;utm_campaign=blog_header_logo&amp;utm_content=logo" class="inline-flex items-center justify-center text-lg text-muted-foreground hover:text-foreground transition border rounded-md h-9 w-9 border-border hover:bg-muted"><i class="text-xl fa-brands fa-hashnode" aria-hidden="true"></i><span class="sr-only">Hashnode</span></a><span class="h-6 border-l border-border"></span>
16<p class="font-semibold text-foreground min-w-0 truncate text-sm"><a title="Art and science of writing good code" href="/">Art and science of writing good code</a></p></div><nav aria-label="Main navigation" class="flex justify-center w-full"><nav aria-label="Main" data-orientation="horizontal" dir="ltr" data-slot="navigation-menu" data-viewport="false" class="group/navigation-menu relative flex flex-1 items-center max-w-max justify-center"><div style="position:relative"><ul data-orientation="horizontal" data-slot="navigation-menu-list" class="group flex flex-1 list-none items-center flex-nowrap justify-center gap-1 text-muted-foreground text-sm" dir="ltr"><li data-slot="navigation-menu-item" class="relative"><a data-slot="navigation-menu-link" class="data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground focus:bg-accent focus:text-accent-foreground [&amp;_svg:not([class*=&#x27;text-&#x27;])]:text-muted-foreground flex-col p-2 outline-none focus-visible:outline-1 [&amp;_svg:not([class*=&#x27;size-&#x27;])]:size-4 inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2" data-radix-collection-item="" href="/series/android">Android</a></li><li data-slot="navigation-menu-item" class="relative"><a data-slot="navigation-menu-link" class="data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground focus:bg-accent focus:text-accent-foreground [&amp;_svg:not([class*=&#x27;text-&#x27;])]:text-muted-foreground flex-col p-2 outline-none focus-visible:outline-1 [&amp;_svg:not([class*=&#x27;size-&#x27;])]:size-4 inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2" data-radix-collection-item="" href="/series/kotlin-features">Kotlin</a></li><li data-slot="navigation-menu-item" class="relative"><a data-slot="navigation-menu-link" class="data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground focus:bg-accent focus:text-accent-foreground [&amp;_svg:not([class*=&#x27;text-&#x27;])]:text-muted-foreground flex-col p-2 outline-none focus-visible:outline-1 [&amp;_svg:not([class*=&#x27;size-&#x27;])]:size-4 inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2" data-radix-collection-item="" href="/series/kotlin-coroutines">Kotlin Coroutines</a></li><li data-slot="navigation-menu-item" class="relative"><button id="radix-_R_1jl4lfalb_" data-state="closed" aria-expanded="false" data-slot="dropdown-menu-trigger" class="group w-max focus:bg-accent focus:text-accent-foreground data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent outline-none focus-visible:outline-1 group inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 hover:bg-accent py-2 h-9 px-3 text-muted-foreground hover:text-foreground bg-transparent shadow-none data-[state=open]:bg-transparent" type="button" aria-haspopup="menu" data-radix-collection-item="">More<!-- --> <span class="ml-1 flex items-center justify-center"><i class="fa-jelly fa-regular fa-angle-down size-3 leading-none transition duration-300 group-data-[state=open]:rotate-180" aria-hidden="true"></i></span></button></li></ul></div></nav></nav><div class="flex items-center justify-end gap-3 text-muted-foreground"><button class="gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focu
16s-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 hover:bg-accent py-2 h-9 w-9 px-0 flex items-center justify-center text-muted-foreground hover:text-foreground bg-transparent border-border shadow-none" aria-label="Open search (press Control or Command and K)"><i class="fa-jelly fa-search text-sm" aria-hidden="true"></i><span class="sr-only">Open search (press Control or Command and K)</span></button><div class="flex items-center gap-3"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 hover:bg-accent w-9 px-3 h-9 text-muted-foreground hover:text-foreground shadow-none" type="button" id="radix-_R_6t4lfalb_" aria-haspopup="menu" aria-expanded="false" data-state="closed" data-slot="dropdown-menu-trigger"><i class="fa-jelly fa-sun text-sm scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" aria-hidden="true"></i><i class="fa-jelly fa-moon absolute text-sm scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" aria-hidden="true"></i><span class="sr-only">Toggle theme</span></button><a target="_blank" rel="noopener" class="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 border border-input bg-background hover:bg-accent hover:text-accent-foreground py-2 gap-2 px-3 h-9 shadow-none" href="https://hashnode.com"><i class="text-sm fa-jelly fa-pencil" aria-hidden="true"></i>Write</a></div></div></div></div></header><div data-slot="dialog-header" class="flex flex-col gap-2 text-center sm:text-left sr-only"><h2 id="radix-_R_8lfalbH1_" data-slot="dialog-title" class="text-lg leading-none font-semibold">Command Palette</h2><p id="radix-_R_8lfalbH2_" data-slot="dialog-description" class="text-muted-foreground text-sm">Search for a command to run...</p></div><div class="px-4 sm:px-8"><div class="w-full xl:mx-auto xl:max-w-[80rem] 2xl:max-w-[90rem]"><div class="flex flex-col gap-8 pt-2 sm:pt-10"><section class="pb-16"><div class="space-y-6 max-w-5xl w-full mx-auto"><section aria-labelledby="_R_15falb_" class="flex flex-col gap-8"><h2 id="_R_15falb_" class="sr-only">Latest articles</h2><div class="flex flex-col gap-5"><div class="grid grid-cols-1 md:grid-cols-2 gap-5"><article aria-labelledby="_R_11et5falb_" class="h-full"><a class="block h-full" href="/full-guide-to-testing-android-applications-in-2022"><div class="rounded-xl border bg-card text-card-foreground transition hover:border-slate-400 dark:hover:border-slate-600 h-full flex flex-col overflow-hidden"><div class="p-4 pb-0 md:p-6 md:pb-0"><div class="relative overflow-hidden rounded-lg bg-muted aspect-[800/420] w-full"><img alt="Full Guide to Testing Android Applications in 2022" loading="lazy" decoding="async" data-nimg="fill" class="object-cover object-center" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" src="https://cdn.hashnode.com/res/hashnode/image/upload/v1652343671311/ElJ-dtU-y.png"/></div></div><div class="flex flex-col gap-4 p-4 md:p-6 grow"><header class="flex flex-col gap-3"><h3 id="_R_11et5falb_" class="text-foreground text-lg sm:text-xl font-bold leading-snug tracking-tight transition-colors line-clamp-2">Full Guide to Testing Android Applications in 2022</h3><p class="text-sm leading-relaxed text-muted-foreground line-clamp-2">Testing is quite a fascinating topic in software development. On the one hand, writing tests takes time, and it might not feel as rewarding - you cannot show a test to a client as you can a new feature. On the other hand, writing tests is an integral...</p></header><div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground mt-auto"><span class="whitespace-nowrap">May 13, 2022</span><span class="whitespace-nowrap"><span class="mr-3" aria-hidden="true">·</span>66 min read</span></div></div></div></a></article><article aria-labelledby="_R_12et5falb_" class="h-full"><a class="block h-full" href="/things-every-kotlin-developer-should-know-about-coroutines-part-5-cancellation"><div class="rounded-xl border bg-card text-card-foreground transition hover:border-slate-400 dark:hover:border-slate-600 h-full flex flex-col overflow-hidden"><div class="p-4 pb-0 md:p-6 md:pb-0"><div class="relative overflow-hidden rounded-lg bg-muted aspect-[800/420] w-full">
16<img alt="Things every Kotlin Developer should know about Coroutines. Part 5: Cancellation." loading="lazy" decoding="async" data-nimg="fill" class="object-cover object-center" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" src="https://cdn.hashnode.com/res/hashnode/image/upload/v1642174453234/N3eNVc3gR.png"/></div></div><div class="flex flex-col gap-4 p-4 md:p-6 grow"><header class="flex flex-col gap-3"><h3 id="_R_12et5falb_" class="text-foreground text-lg sm:text-xl font-bold leading-snug tracking-tight transition-colors line-clamp-2">Things every Kotlin Developer should know about Coroutines. Part 5: Cancellation.</h3><p class="text-sm leading-relaxed text-muted-foreground line-clamp-2">As much as we had talked about cancellation in the last part, in this article, we will often touch upon exception handling. Since, as discussed previously, these two concepts use the same mechanism.
17That said, cancellation in the coroutines library i...</p></header><div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground mt-auto"><span class="whitespace-nowrap">Jan 14, 2022</span><span class="whitespace-nowrap"><span class="mr-3" aria-hidden="true">·</span>15 min read</span></div></div></div></a></article><article aria-labelledby="_R_13et5falb_" class="h-full"><a class="block h-full" href="/things-every-kotlin-developer-should-know-about-coroutines-part-4-exception-handling"><div class="rounded-xl border bg-card text-card-foreground transition hover:border-slate-400 dark:hover:border-slate-600 h-full flex flex-col overflow-hidden"><div class="p-4 pb-0 md:p-6 md:pb-0"><div class="relative overflow-hidden rounded-lg bg-muted aspect-[800/420] w-full"><img alt="Things every Kotlin Developer should know about Coroutines. Part 4: Exception Handling." loading="lazy" decoding="async" data-nimg="fill" class="object-cover object-center" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641408624827/vd__E1NQR.png"/></div></div><div class="flex flex-col gap-4 p-4 md:p-6 grow"><header class="flex flex-col gap-3"><h3 id="_R_13et5falb_" class="text-foreground text-lg sm:text-xl font-bold leading-snug tracking-tight transition-colors line-clamp-2">Things every Kotlin Developer should know about Coroutines. Part 4: Exception Handling.</h3><p class="text-sm leading-relaxed text-muted-foreground line-clamp-2">In Part 3, we have discussed structured concurrency, which was introduced to the coroutines library primarily as a solution to exception handling and cancellation.
18Because of that, these two concepts go hand in hand, and even though we will not focus...</p></header><div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground mt-auto"><span class="whitespace-nowrap">Jan 5, 2022</span><span class="whitespace-nowrap"><span class="mr-3" aria-hidden="true">·</span>13 min read</span></div></div></div></a></article><article aria-labelledby="_R_14et5falb_" class="h-full"><a class="block h-full" href="/things-every-kotlin-developer-should-know-about-coroutines-part-3-structured-concurrency"><div class="rounded-xl border bg-card text-card-foreground transition hover:border-slate-400 dark:hover:border-slate-600 h-full flex flex-col overflow-hidden"><div class="p-4 pb-0 md:p-6 md:pb-0"><div class="relative overflow-hidden rounded-lg bg-muted aspect-[800/420] w-full"><img alt="Things every Kotlin Developer should know about Coroutines. Part 3: Structured Concurrency." loading="lazy" decoding="async" data-nimg="fill" class="object-cover object-center" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" src="https://cdn.hashnode.com/res/hashnode/image/upload/v1640266242099/8Rq97l9AG.png"/></div></div><div class="flex flex-col gap-4 p-4 md:p-6 grow"><header class="flex flex-col gap-3"><h3 id="_R_14et5falb_" class="text-foreground text-lg sm:text-xl font-bold leading-snug tracking-tight transition-colors line-clamp-2">Things every Kotlin Developer should know about Coroutines. Part 3: Structured Concurrency.</h3><p class="text-sm leading-relaxed text-muted-foreground line-clamp-2">If you watch a coroutines video dated before their stable launch in Kotlin 1.3, you might notice that the way coroutines were used in their &quot;experimental&quot; phase is a bit different from now.
19For example, at KotlinConf 2017, in his Introductions to Cor...</p></header><div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground mt-auto"><span class="whitespace-nowrap">Dec 23, 2021</span><span class="whitespace-nowrap"><span class="mr-3" aria-hidden="true">·</span>8 min read</span></div></div></div></a></article><div class="md:col-span-2"><aside aria-label="About the publication"><div class="rounded-xl border bg-card text-card-foreground transition hover:border-slate-400 dark:hover:border-slate-600 p-5 flex flex-col"><div class="flex flex-col items-center text-center gap-5"><div class="flex flex-col items-center gap-3"><span class="relative flex overflow-hidden rounded-full h-16 w-16 shrink-0"><span class="flex h-full w-full items-center justify-center rounded-full bg-muted text-muted-foreground font-medium text-lg">A</span></span><div class="space-y-1"><p class="text-base font-semibold text-foreground leading-tight">Art and science of writing good code</p><p class="text-sm text-muted-foreground">10<!-- --> posts</p></div></div><div class="flex flex-wrap items-center justify-center gap-3"><a href="https://twitter.com/HeyMaxKim" target="_blank" rel="noopener" class="text-muted-foreground transition-colors hover:text-foreground" aria-label="Twitter"><i class="fa-brands fa-x-twitter" aria-hidden="true"></i></a><a href="https://github.com/mkims" target="_blank" rel="noopener" class="text-muted-foreground transition-colors hover:text-foreground" aria-label="GitHub"><i class="fa-brands fa-github" aria-hidden="true"></i></a><a href="https://hashnode.com/@maxkim" target="_blank" rel="noopener" class="text-muted-foreground transition-colors hover:text-foreground" aria-label="Hashnode"><i class="fa-brands fa-hashnode" aria-hidden="true"></i></a></div></div></div></aside></div><article aria-labelledby="_R_15et5falb_" class="h-full"><a class="block h-full" href="/things-every-kotlin-developer-should-know-about-coroutines-part-2-coroutinescope"><div class="rounded-xl border bg-card text-card-foreground transition hover:border-slate-400 dark:hover:border-slate-600 h-full flex flex-col overflow-hidden"><div class="p-4 pb-0 md:p-6 md:pb-0"><div class="relative overflow-hidden rounded-lg bg-muted aspect-[800/420] w-full">
19<img alt="Things every Kotlin Developer should know about Coroutines. Part 2: CoroutineScope." loading="lazy" decoding="async" data-nimg="fill" class="object-cover object-center" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" src="https://cdn.hashnode.com/res/hashnode/image/upload/v1639477245203/xx6LcXZHC.png"/></div></div><div class="flex flex-col gap-4 p-4 md:p-6 grow"><header class="flex flex-col gap-3"><h3 id="_R_15et5falb_" class="text-foreground text-lg sm:text-xl font-bold leading-snug tracking-tight transition-colors line-clamp-2">Things every Kotlin Developer should know about Coroutines. Part 2: CoroutineScope.</h3><p class="text-sm leading-relaxed text-muted-foreground line-clamp-2">In my experience, CoroutineScope is one of the less understood parts of the coroutines library, even though it is one of the most important. In Android, we are spoiled with coroutine scopes kindly provided to us by lifecycle libraries, but for many d...</p></header><div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground mt-auto"><span class="whitespace-nowrap">Dec 14, 2021</span><span class="whitespace-nowrap"><span class="mr-3" aria-hidden="true">·</span>11 min read</span></div></div></div></a></article><article aria-labelledby="_R_16et5falb_" class="h-full"><a class="block h-full" href="/things-every-kotlin-developer-should-know-about-coroutines-part-1-coroutinecontext"><div class="rounded-xl border bg-card text-card-foreground transition hover:border-slate-400 dark:hover:border-slate-600 h-full flex flex-col overflow-hidden"><div class="p-4 pb-0 md:p-6 md:pb-0"><div class="relative overflow-hidden rounded-lg bg-muted aspect-[800/420] w-full"><img alt="Things every Kotlin Developer should know about Coroutines. 
20
21Part 1: CoroutineContext." loading="lazy" decoding="async" data-nimg="fill" class="object-cover object-center" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638386151096/lme5o9O7D.png"/></div></div><div class="flex flex-col gap-4 p-4 md:p-6 grow"><header class="flex flex-col gap-3"><h3 id="_R_16et5falb_" class="text-foreground text-lg sm:text-xl font-bold leading-snug tracking-tight transition-colors line-clamp-2">Things every Kotlin Developer should know about Coroutines. 
22
23Part 1: CoroutineContext.</h3><p class="text-sm leading-relaxed text-muted-foreground line-clamp-2">The CoroutineContext is the backbone of the coroutines library. Every coroutine you launch will have a context. However, given its nature and flexible API, it might prove pretty tricky to use it correctly.
24In Part 1 of my series about coroutines, I w...</p></header><div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground mt-auto"><span class="whitespace-nowrap">Dec 2, 2021</span><span class="whitespace-nowrap"><span class="mr-3" aria-hidden="true">·</span>8 min read</span></div></div></div></a></article><article aria-labelledby="_R_17et5falb_" class="h-full"><a class="block h-full" href="/a-practical-guide-to-kotlins-inline-modifier"><div class="rounded-xl border bg-card text-card-foreground transition hover:border-slate-400 dark:hover:border-slate-600 h-full flex flex-col overflow-hidden"><div class="p-4 pb-0 md:p-6 md:pb-0"><div class="relative overflow-hidden rounded-lg bg-muted aspect-[800/420] w-full"><img alt="A Practical Guide to Kotlin&#x27;s inline Modifier" loading="lazy" decoding="async" data-nimg="fill" class="object-cover object-center" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633257088662/baRNBzc2X.png"/></div></div><div class="flex flex-col gap-4 p-4 md:p-6 grow"><header class="flex flex-col gap-3"><h3 id="_R_17et5falb_" class="text-foreground text-lg sm:text-xl font-bold leading-snug tracking-tight transition-colors line-clamp-2">A Practical Guide to Kotlin&#x27;s inline Modifier</h3><p class="text-sm leading-relaxed text-muted-foreground line-clamp-2">I fell in love with Kotlin as soon as I switched to it from Java about 4 years ago. And although I was writing Kotlin code on a regular basis ever since, I didn&#x27;t start using some of its more advanced features until quite recently.
25I wish I had start...</p></header><div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground mt-auto"><span class="whitespace-nowrap">Oct 4, 2021</span><span class="whitespace-nowrap"><span class="mr-3" aria-hidden="true">·</span>13 min read</span></div></div></div></a></article><article aria-labelledby="_R_18et5falb_" class="h-full"><a class="block h-full" href="/understanding-layouts-in-jetpack-compose"><div class="rounded-xl border bg-card text-card-foreground transition hover:border-slate-400 dark:hover:border-slate-600 h-full flex flex-col overflow-hidden"><div class="p-4 pb-0 md:p-6 md:pb-0"><div class="relative overflow-hidden rounded-lg bg-muted aspect-[800/420] w-full"><img alt="Understanding Layouts in Jetpack Compose" loading="lazy" decoding="async" data-nimg="fill" class="object-cover object-center" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627234201356/djlV76uIc.png"/></div></div><div class="flex flex-col gap-4 p-4 md:p-6 grow"><header class="flex flex-col gap-3"><h3 id="_R_18et5falb_" class="text-foreground text-lg sm:text-xl font-bold leading-snug tracking-tight transition-colors line-clamp-2">Understanding Layouts in Jetpack Compose</h3><p class="text-sm leading-relaxed text-muted-foreground line-clamp-2">In my previous article Things you need to know before switching to Jetpack Compose, I discussed the basic principles of building UI using Jetpack Compose. 
26Today, let&#x27;s dive a little deeper into how layouts work in Compose and learn how to build a mo...</p></header><div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground mt-auto"><span class="whitespace-nowrap">Jul 25, 2021</span><span class="whitespace-nowrap"><span class="mr-3" aria-hidden="true">·</span>12 min read</span></div></div></div></a></article><article aria-labelledby="_R_19et5falb_" class="h-full"><a class="block h-full" href="/things-you-need-to-know-before-switching-to-jetpack-compose"><div class="rounded-xl border bg-card text-card-foreground transition hover:border-slate-400 dark:hover:border-slate-600 h-full flex flex-col overflow-hidden"><div class="p-4 pb-0 md:p-6 md:pb-0"><div class="relative overflow-hidden rounded-lg bg-muted aspect-[800/420] w-full"><img alt="Things you need to know before switching to Jetpack Compose" loading="lazy" decoding="async" data-nimg="fill" class="object-cover object-center" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625693138062/_rlN91Wnz.png"/></div></div><div class="flex flex-col gap-4 p-4 md:p-6 grow"><header class="flex flex-col gap-3"><h3 id="_R_19et5falb_" class="text-foreground text-lg sm:text-xl font-bold leading-snug tracking-tight transition-colors line-clamp-2">Things you need to know before switching to Jetpack Compose</h3><p class="text-sm leading-relaxed text-muted-foreground line-clamp-2">With the release of the stable version of Jetpack Compose just around the corner, here are some things you need to know before switching from the imperative, XML-based style for building UI, to the new Android’s toolkit for building native UI declara...</p></header><div class="flex flex-wrap items-center gap-3 text-sm text-muted-foreground mt-auto"><span class="whitespace-nowrap">Jul 12, 2021</span><span class="whitespace-nowrap"><span class="mr-3" aria-hidden="true">·</span>12 min read</span></div></div></div></a></article></div></div><div class="flex justify-center py-8"><button type="button" class="group flex items-center gap-2 rounded-lg px-5 py-2.5 text-sm font-medium text-muted-foreground transition hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary disabled:opacity-50" aria-controls="_R_15falbH1_" aria-label="Load more posts"><span aria-live="polite">Load more posts</span><i class="fa-regular fa-arrow-down text-sm transition-transform group-hover:translate-y-0.5" aria-hidden="true"></i></button></div></section></div></section></div></div></div>
26<script type="application/ld+json">{"@context":"https://schema.org","@type":"Blog","name":"Art and science of writing good code","url":"https://maxkim.dev","description":"Art and science of writing good code","mainEntityOfPage":{"@type":"WebPage","url":"https://maxkim.dev"},"publisher":{"@type":"Organization","name":"Art and science of writing good code","url":"https://maxkim.dev"},"image":{"@type":"ImageObject","url":"https://maxkim.dev/api/og/home?og=eyJ0aXRsZSI6IkFydCUyMGFuZCUyMHNjaWVuY2UlMjBvZiUyMHdyaXRpbmclMjBnb29kJTIwY29kZSIsImlzRGVmYXVsdE1vZGVEYXJrIjpmYWxzZSwicGhvdG8iOiJodHRwczovL2Nkbi5oYXNobm9kZS5jb20vcmVzL2hhc2hub2RlL2ltYWdlL3VwbG9hZC92MTYxNzQ1NDc3Mzc4My92ODNESnhHZVUuanBlZyIsImlzVGVhbSI6dHJ1ZSwiZG9tYWluIjoibWF4a2ltLmRldiIsImZvbGxvd2VycyI6MTg2LCJhcnRpY2xlcyI6MCwiZmF2aWNvbiI6Imh0dHBzOi8vY2RuLmhhc2hub2RlLmNvbS9yZXMvaGFzaG5vZGUvaW1hZ2UvdXBsb2FkL3YxNjE3NDcyNDIwOTUzLzFReGl5WUxBTS5wbmcifQ=="},"sameAs":["https://x.com/HeyMaxKim","https://github.com/mkims","https://hashnode.com/@maxkim"]}</script>
26<footer class="px-4 pt-8 pb-20 sm:px-8 text-muted-foreground" aria-label="Footer"><div class="w-full max-w-4xl mx-auto"><div class="flex flex-col items-center gap-4 text-center text-sm"><p class="font-medium"><time dateTime="2026"><span class="font-sans">©</span> <!-- -->2026</time> <!-- -->Art and science of writing good code</p><nav aria-label="Footer navigation"><ul class="flex flex-wrap justify-center gap-4 text-sm tracking-wide"><li><a class="transition hover:text-foreground" href="/archive">Archive</a></li><li><a class="transition hover:text-foreground" target="_blank" rel="noopener" href="https://hashnode.com/privacy-policy">Privacy</a></li><li><a class="transition hover:text-foreground" target="_blank" rel="noopener" href="https://hashnode.com/terms">Terms</a></li></ul></nav><div class="pt-8 flex justify-center gap-6"><a target="_blank" rel="noopener" class="flex items-center gap-2 text-sm transition hover:text-foreground" title="Sitemap" href="/sitemap.xml"><i class="fa-regular fa-sitemap"></i><span>Sitemap</span></a><a target="_blank" rel="noopener" class="flex items-center gap-2 text-sm transition hover:text-foreground" title="RSS Feed" href="/rss.xml"><i class="fa-regular fa-rss"></i><span>RSS</span></a></div><div class="pt-10 text-center"><a target="_blank" rel="noopener" aria-label="Visit Hashnode (opens in a new tab)" class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground h-10 rounded-md text-xl px-5 py-4" href="https://hashnode.com/?utm_source=https%3A%2F%2Fmaxkim.dev&amp;utm_medium=referral&amp;utm_campaign=blog_footer_logo&amp;utm_content=logo"><svg fill="none" viewBox="0 0 282 39" aria-hidden="true" class="h-6 w-auto min-w-[9.5rem] text-muted-foreground transition hover:text-foreground"><path fill="currentColor" d="M2.68 13.032c-3.573 3.505-3.573 9.363 0 12.936L13.032 36.32c3.505 3.573 9.363 3.573 12.936 0L36.32 25.968c3.573-3.573 3.573-9.431 0-12.936L25.968 2.68c-3.573-3.573-9.431-3.573-12.936 0zm12.211 1.935c2.507-2.521 6.582-2.544 9.104-.038s2.544 6.582.038 9.104-6.582 2.544-9.104.038-2.544-6.582-.038-9.104"></path><path fill="currentColor" d="M268.379 39q-6.322 0-10.35-4.108-4.002-4.134-4.002-10.483 0-6.296 4.002-10.43 4-4.135 10.163-4.135 6.028 0 9.817 3.734 3.814 3.735 3.814 9.497v2.8h-24.248v-4.054h17.633q-.187-2.747-2.054-4.508-1.868-1.76-4.962-1.76-3.28-.001-5.388 2.374-2.108 2.373-2.108 6.375 0 4.188 2.348 6.695 2.347 2.481 5.895 2.481 1.68 0 2.934-.453a8.5 8.5 0 0 0 2.321-1.307q1.041-.854 2.268-2.614l4.694 2.96q-1.707 2.748-3.494 4.135a12.7 12.7 0 0 1-3.975 2.081q-2.187.72-5.308.72m-33.496 0q-5.575 0-9.283-4.028-3.681-4.029-3.681-10.484 0-6.43 3.761-10.51 3.76-4.108 9.47-4.108 2.8 0 5.175 1.2 2.4 1.174 3.628 3.148l.026-.08V0h7.016v38.2h-6.722v-4.722l.64.8-.694.133q-1.28 2.108-3.788 3.361Q237.924 39 234.883 39m1.627-6.002q3.308 0 5.495-2.428t2.188-6.135q0-3.762-2.214-6.109-2.214-2.374-5.469-2.374-3.28 0-5.522 2.347-2.214 2.348-2.214 6.163 0 3.76 2.214 6.162 2.214 2.374 5.522 2.374M205.811 39q-6.376 0-10.537-4.161-4.161-4.188-4.161-10.404 0-6.321 4.161-10.456 4.188-4.135 10.537-4.135 6.348 0 10.537 4.161 4.188 4.161 4.188 10.43 0 6.216-4.188 10.404Q212.186 39 205.811 39m0-6.162q3.307 0 5.575-2.374 2.267-2.374 2.267-6.055 0-3.707-2.294-6.056-2.267-2.347-5.548-2.347-3.308 0-5.575 2.374-2.268 2.348-2.268 6.029t2.241 6.055q2.268 2.374 5.602 2.374M162.586 38.2V10.644h6.802v5.015l-.8-.987h.906q1.308-2.187 3.762-3.494 2.48-1.335 5.228-1.334 4.615 0 7.256 2.8 2.667 2.776 2.667 7.603V38.2h-7.069V21.794q0-2.854-1.387-4.401t-4.134-1.547q-2.614 0-4.402 1.974-1.76 1.974-1.76 4.881V38.2zm-30.181 0V0h6.962v14.698h.134q1.2-2.187 3.574-3.521 2.375-1.335 5.229-1.334 4.615 0 7.255 2.828 2.668 2.801 2.668 7.522V38.2h-7.069V21.794q0-2.827-1.387-4.402-1.387-1.573-4.055-1.573-2.587 0-4.428 2.027-1.814 2.027-1.814 4.962v15.391zm-14.416.8q-2.882 0-5.015-.64-2.108-.614-3.761-1.84-1.654-1.228-2.668-2.695l-.987-1.467 4.695-3.174.773 1.067a9.1 9.1 0 0 0 1.788 1.814 8.2 8.2 0 0 0 2.32 1.2q1.308.4 3.068.4 2.161 0 3.441-.8 1.308-.8 1.307-2.294 0-1.36-1.147-2.108-1.12-.747-5.068-1.654-5.335-1.253-7.656-3.334-2.32-2.107-2.321-5.362 0-3.76 3.148-6.002 3.148-2.267 7.923-2.267 2.454 0 4.348.507t3.388 1.493q1.493.988 2.454 2.188l.987 1.2-4.482 3.255-.667-.774a7.4 7.4 0 0 0-1.627-1.387 6.4 6.4 0 0 0-2.054-.88 9.5 9.5 0 0 0-2.401-.294q-1.974 0-3.201.8-1.2.774-1.2 1.921 0 1.254 1.12 2.027 1.147.748 5.229 1.681 5.334 1.227 7.629 3.308 2.294 2.055 2.294 5.308 0 4.029-3.228 6.43Q123.217 39 117.989 39M87.61 39q-4.508 0-7.335-2.454-2.828-2.481-2.828-6.482 0-4.188 3.254-6.669t8.483-2.48q2.082 0 4.028.426 1.974.427 3.361 1.12v-1.6q0-2.588-1.813-4.082-1.788-1.493-4.615-1.493-1.628 0-2.801.373a8.7 8.7 0 0 0-2.188.987q-.987.614-1.84 1.414l-.854.8-4.081-3.788 1.307-1.173a18.7 18.7 0 0 1 2.934-2.108q1.601-.933 3.601-1.44t4.589-.507q5.868 0 9.229 2.88 3.361 2.882 3.361 8.084V38.2h-6.749v-5.922l1.654 2.187h-1.76q-1.308 2.055-3.655 3.308Q90.545 39 87.611 39m1.814-4.988q3.148 0 5.149-2.187 2-2.215 2-5.309v-.08q-1.12-.693-2.72-1.094a13 13 0 0 0-3.388-.426q-2.828 0-4.562 1.2-1.734 1.173-1.734 3.521 0 2.028 1.468 3.201t3.787 1.174M49 38.2V0h6.962v14.698h.134q1.2-2.187 3.574-3.521 2.375-1.335 5.229-1.334 4.615 0 7.255 2.828 2.668 2.801 2.668 7.522V38.2h-
267.07V21.794q0-2.827-1.386-4.402-1.387-1.573-4.055-1.573-2.587 0-4.428 2.027-1.815 2.027-1.814 4.962v15.391z"></path></svg></a></div></div></div></footer></main><!--$--><!--/$-->
26<script src="/_next/static/chunks/webpack-55b36f0cd6c208fe.js" id="_R_" async=""></script>
26<script>(self.__next_f=self.__next_f||[]).push([0])</script>
26<script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[16174,[\"4554\",\"static/chunks/4554-984b480a9db5f3fe.js\",\"7563\",\"static/chunks/7563-4dfa0994a9b0e37c.js\",\"9216\",\"static/chunks/9216-9272709ba40c1cfd.js\",\"2810\",\"static/chunks/2810-6b74d77b4b0dc790.js\",\"3091\",\"static/chunks/3091-bf1537ff6571a1bd.js\",\"7177\",\"static/chunks/app/layout-6ae7b4b583d4bba3.js\"],\"ThemeProvider\"]\n3:I[82180,[\"4554\",\"static/chunks/4554-984b480a9db5f3fe.js\",\"7563\",\"static/chunks/7563-4dfa0994a9b0e37c.js\",\"9216\",\"static/chunks/9216-9272709ba40c1cfd.js\",\"2810\",\"static/chunks/2810-6b74d77b4b0dc790.js\",\"3091\",\"static/chunks/3091-bf1537ff6571a1bd.js\",\"7177\",\"static/chunks/app/layout-6ae7b4b583d4bba3.js\"],\"TooltipProvider\"]\n4:I[63851,[\"4554\",\"static/chunks/4554-984b480a9db5f3fe.js\",\"7563\",\"static/chunks/7563-4dfa0994a9b0e37c.js\",\"9216\",\"static/chunks/9216-9272709ba40c1cfd.js\",\"2810\",\"static/chunks/2810-6b74d77b4b0dc790.js\",\"3091\",\"static/chunks/3091-bf1537ff6571a1bd.js\",\"7177\",\"static/chunks/app/layout-6ae7b4b583d4bba3.js\"],\"UrqlProvider\"]\n5:I[82714,[\"4554\",\"static/chunks/4554-984b480a9db5f3fe.js\",\"7563\",\"static/chunks/7563-4dfa0994a9b0e37c.js\",\"9216\",\"static/chunks/9216-9272709ba40c1cfd.js\",\"2810\",\"static/chunks/2810-6b74d77b4b0dc790.js\",\"3091\",\"static/chunks/3091-bf1537ff6571a1bd.js\",\"7177\",\"static/chunks/app/layout-6ae7b4b583d4bba3.js\"],\"ConsentManager\"]\n6:I[9766,[],\"\"]\n7:I[98924,[],\"\"]\n8:I[33293,[\"4554\",\"static/chunks/4554-984b480a9db5f3fe.js\",\"4345\",\"static/chunks/app/not-found-b861935655c5698b.js\"],\"default\"]\n9:I[21447,[\"4554\",\"static/chunks/4554-984b480a9db5f3fe.js\",\"7563\",\"static/chunks/7563-4dfa0994a9b0e37c.js\",\"9216\",\"static/chunks/9216-9272709ba40c1cfd.js\",\"2810\",\"static/chunks/2810-6b74d77b4b0dc790.js\",\"3091\",\"static/chunks/3091-bf1537ff6571a1bd.js\",\"7177\",\"static/chunks/app/layout-6ae7b4b583d4bba3.js\"],\"Integrations\"]\na:I[35514,[\"4554\",\"static/chunks/4554-984b480a9db5f3fe.js\",\"7563\",\"static/chunks/7563-4dfa0994a9b0e37c.js\",\"9216\",\"static/chunks/9216-9272709ba40c1cfd.js\",\"2810\",\"static/chunks/2810-6b74d77b4b0dc790.js\",\"3091\",\"static/chunks/3091-bf1537ff6571a1bd.js\",\"7177\",\"static/chunks/app/layout-6ae7b4b583d4bba3.js\"],\"Analytics\"]\nc:I[24431,[],\"OutletBoundary\"]\ne:I[15278,[],\"AsyncMetadataOutlet\"]\n10:I[24431,[],\"ViewportBoundary\"]\n12:I[24431,[],\"MetadataBoundary\"]\n13:\"$Sreact.suspense\"\n15:I[57150,[],\"\"]\n:HL[\"/_next/static/media/22a5144ee8d83bca-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/72a2a501b11d0ccb.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/8934b430a4adeb19-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/8e9860b6e62d6359-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/c4b700dcb2187787-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/e4af272ccee01ff0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/0d16c72050851854.css\",\"style\"]\n:HL[\"/_next/static/css/7ffcc02a3c67389b.css\",\"style\"]\n:HL[\"/_next/static/css/c20e76e7d11dec32.css\",\"style\"]\n:HL[\"/_next/static/css/59fefb2212bd5b60.css\",\"style\"]\n0:{\"P\":null,\"b\":\"RrCGzNVHUG674hJ_sjvms\",\"p\":\"\",\"c\":[\"\",\"?x-host=maxkim.dev\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__?{\\\"x-host\\\":\\\"maxkim.dev\\\"}\",{}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/0d16c72050851854.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/7ffcc02a3c67389b.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"2\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/c20e76e7d11dec32.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"3\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/59fefb2212bd5b60.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"type\":\"text/javascript\",\"danger"])</script>
26<script>self.__next_f.push([1,"ouslySetInnerHTML\":{\"__html\":\"window.addEventListener('message',function(e){var d=e.data;if(!d||d.__hnWidget!==1||typeof d.h!=='number'||d.h\u003c=0)return;var f=document.querySelectorAll('.hn-widget-frame');for(var i=0;i\u003cf.length;i++){if(f[i].contentWindow===e.source){f[i].style.height=d.h+'px';break;}}});\"}}]}],[\"$\",\"body\",null,{\"className\":\"__variable_c2612a __variable_246ccd __variable_3069d5 bg-background dark:bg-background\",\"children\":[\"$\",\"$L2\",null,{\"attribute\":\"class\",\"defaultTheme\":\"system\",\"enableSystem\":true,\"disableTransitionOnChange\":true,\"children\":[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$L5\",null,{\"children\":[[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"$L8\",null,{}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L9\",null,{}],[\"$\",\"$La\",null,{}]]}]}]}]}]}]]}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[\"$Lb\",null,[\"$\",\"$Lc\",null,{\"children\":[\"$Ld\",[\"$\",\"$Le\",null,{\"promise\":\"$@f\"}]]}]]}],{},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[[\"$\",\"$L10\",null,{\"children\":\"$L11\"}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]],[\"$\",\"$L12\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$13\",null,{\"fallback\":null,\"children\":\"$L14\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$15\",[]],\"s\":false,\"S\":false}\n11:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\nd:null\n16:I[80622,[],\"IconMark\"]\nf:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Art and science of writing good code\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"A blog powered by Hashnode\"}],[\"$\",\"link\",\"2\",{\"rel\":\"canonical\",\"href\":\"https://maxkim.dev\"}],[\"$\",\"meta\",\"3\",{\"property\":\"og:title\",\"content\":\"Art and science of writing good code\"}],[\"$\",\"meta\",\"4\",{\"property\":\"og:description\",\"content\":\"A blog powered by Hashnode\"}],[\"$\",\"meta\",\"5\",{\"property\":\"og:url\",\"content\":\"https://maxkim.dev\"}],[\"$\",\"meta\",\"6\",{\"property\":\"og:site_name\",\"content\":\"Art and science of writing good code\"}],[\"$\",\"meta\",\"7\",{\"property\":\"og:image\",\"content\":\"https://maxkim.dev/api/og/home?og=eyJ0aXRsZSI6IkFydCUyMGFuZCUyMHNjaWVuY2UlMjBvZiUyMHdyaXRpbmclMjBnb29kJTIwY29kZSIsImlzRGVmYXVsdE1vZGVEYXJrIjpmYWxzZSwicGhvdG8iOiJodHRwczovL2Nkbi5oYXNobm9kZS5jb20vcmVzL2hhc2hub2RlL2ltYWdlL3VwbG9hZC92MTYxNzQ1NDc3Mzc4My92ODNESnhHZVUuanBlZyIsImxvZ28iOm51bGwsImxvZ29EYXJrIjpudWxsLCJpc1RlYW0iOnRydWUsImRvbWFpbiI6Im1heGtpbS5kZXYiLCJmb2xsb3dlcnMiOjE4NiwiYXJ0aWNsZXMiOjAsImZhdmljb24iOiJodHRwczovL2Nkbi5oYXNobm9kZS5jb20vcmVzL2hhc2hub2RlL2ltYWdlL3VwbG9hZC92MTYxNzQ3MjQyMDk1My8xUXhpeVlMQU0ucG5nIn0=\"}],[\"$\",\"meta\",\"8\",{\"property\":\"og:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"9\",{\"property\":\"og:image:height\",\"content\":\"630\"}],[\"$\",\"meta\",\"10\",{\"property\":\"og:type\",\"content\":\"website\"}],[\"$\",\"meta\",\"11\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}],[\"$\",\"meta\",\"12\",{\"name\":\"twitter:creator\",\"content\":\"https://twitter.com/HeyMaxKim\"}],[\"$\",\"meta\",\"13\",{\"name\":\"twitter:title\",\"content\":\"Art and science of writing good code\"}],[\"$\",\"meta\",\"14\",{\"name\":\"twitter:description\",\"content\":\"A blog powered by Hashnode\"}],[\"$\",\"meta\",\"15\",{\"name\":\"twitter:image\",\"content\":\"https://maxkim.dev/api/og/home?og=eyJ0aXRsZSI6IkFydCUyMGFuZCUyMHNjaWVuY2UlMjBvZiUyMHdyaXRpbmclMjBnb29kJTIwY29kZSIsImlzRGVmYXVsdE1vZGVEYXJrIjpmYWxzZSwicGhvdG8iOiJodHRwczovL2Nkbi5oYXNobm9kZS5jb20vcmVzL2hhc2hub2RlL2ltYWdlL3VwbG9hZC92MTYxNzQ1NDc3Mzc4My92ODNESnhHZVUuanBlZyIsImxvZ28iOm51bGwsImxvZ29EYXJrIjpudWxsLCJpc1RlYW0iOnRydWUsImRvbWFpbiI6Im1heGtpbS5kZXYiLCJmb2xsb3dlcnMiOjE4NiwiYXJ0aWNsZXMiOjAsImZhdmljb24iOiJodHRwczovL2Nkbi5oYXNobm9kZS5jb20vcmVzL2hhc2hub2RlL2ltYWdlL3VwbG9hZC92MTYxNzQ3MjQyMDk1My8xUXhpeVlMQU0ucG5nIn0=\"}],[\"$\",\"link\",\"16\",{\"rel\":\"icon\",\"href\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617472420953/1QxiyYLAM.png\"}],[\"$\",\"$L16\",\"17\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n14:\"$f:m"])</script>
26<script>self.__next_f.push([1,"etadata\"\n17:I[652,[\"4554\",\"static/chunks/4554-984b480a9db5f3fe.js\",\"7563\",\"static/chunks/7563-4dfa0994a9b0e37c.js\",\"5001\",\"static/chunks/5001-fae0bebdd93f95e3.js\",\"2423\",\"static/chunks/2423-c8b1388240338d7d.js\",\"9216\",\"static/chunks/9216-9272709ba40c1cfd.js\",\"3091\",\"static/chunks/3091-bf1537ff6571a1bd.js\",\"652\",\"static/chunks/652-f40dcb480b4e356f.js\",\"730\",\"static/chunks/730-8191af9e9424b148.js\",\"8974\",\"static/chunks/app/page-cc18ae1a3a7a5ed8.js\"],\"BlogHeader\"]\nb:[\"$\",\"main\",null,{\"id\":\"main-content\",\"className\":\"min-h-screen bg-background dark:bg-background\",\"children\":[[\"$\",\"$L17\",null,{\"publication\":{\"__typename\":\"Publication\",\"id\":\"60686941b17dc439b747a20f\",\"url\":\"https://maxkim.dev\",\"canonicalURL\":\"https://maxkim.dev\",\"urlPattern\":\"simple\",\"title\":\"Art and science of writing good code\",\"displayTitle\":null,\"hasBadges\":true,\"descriptionSEO\":\"\",\"seo\":{\"title\":null,\"description\":null,\"__typename\":\"SEO\"},\"publicMembers\":{\"totalDocuments\":1,\"__typename\":\"PublicMembers\"},\"about\":null,\"features\":{\"proTeam\":{\"isEnabled\":false,\"__typename\":\"ProTeamFeature\"},\"newsletter\":{\"isEnabled\":true,\"__typename\":\"NewsletterFeature\"},\"viewCount\":{\"isEnabled\":false,\"__typename\":\"ViewCountFeature\"},\"readTime\":{\"isEnabled\":true,\"__typename\":\"ReadTimeFeature\"},\"textSelectionSharer\":{\"isEnabled\":true,\"__typename\":\"TextSelectionSharerFeature\"},\"gptBotCrawling\":{\"__typename\":\"GPTBotCrawlingFeature\",\"isEnabled\":true},\"headlessCMS\":{\"isEnabled\":false,\"__typename\":\"HeadlessCMSFeature\"},\"__typename\":\"PublicationFeatures\"},\"aeoSettings\":{\"isEnabled\":false,\"llmsTxtEnabled\":true,\"crawlers\":{\"gptBot\":true,\"claudeBot\":true,\"perplexityBot\":true,\"googleExtended\":true,\"ccBot\":true,\"__typename\":\"AeoCrawlerSettings\"},\"__typename\":\"PublicationAeoSettings\"},\"metaTags\":null,\"ogMetaData\":{\"image\":null,\"__typename\":\"OpenGraphMetaData\"},\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"name\":\"Max Kim\",\"username\":\"maxkim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"preferences\":{\"__typename\":\"PublicationPreferences\",\"logo\":null,\"dar
26kMode\":{\"__typename\":\"DarkModePreferences\",\"logo\":null,\"enabled\":false},\"navbarItems\":[{\"__typename\":\"PublicationNavbarItem\",\"id\":\"6068a634b17dc439b747a6d6\",\"label\":\"Android\",\"url\":null,\"type\":\"series\",\"series\":{\"__typename\":\"Series\",\"id\":\"6068a57eb17dc439b747a6ce\",\"slug\":\"android\"},\"page\":null},{\"__typename\":\"PublicationNavbarItem\",\"id\":\"615ac04ee2f1936f70b2944e\",\"label\":\"Kotlin\",\"url\":null,\"type\":\"series\",\"series\":{\"__typename\":\"Series\",\"id\":\"615abf32ad6beb6f6506e793\",\"slug\":\"kotlin-features\"},\"page\":null},{\"__typename\":\"PublicationNavbarItem\",\"id\":\"61a7e5771e28ee7efba8b9bc\",\"label\":\"Kotlin Coroutines\",\"url\":null,\"type\":\"series\",\"series\":{\"__typename\":\"Series\",\"id\":\"61a7e5631e28ee7efba8b9b8\",\"slug\":\"kotlin-coroutines\"},\"page\":null},{\"__typename\":\"PublicationNavbarItem\",\"id\":\"615ac223e2f1936f70b2949e\",\"label\":\"About\",\"url\":null,\"type\":\"page\",\"series\":null,\"page\":{\"__typename\":\"StaticPage\",\"id\":\"6068a653b17dc439b747a6df\",\"slug\":\"about\"}}],\"enabledPages\":{\"__typename\":\"EnabledPages\",\"badges\":false,\"newsletter\":false,\"members\":false},\"layout\":\"grid\",\"disableFooterBranding\":false,\"isSubscriptionModalDisabled\":false},\"favicon\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617472420953/1QxiyYLAM.png\",\"headerColor\":\"#E0E0E0\",\"integrations\":{\"fbPixelID\":null,\"fathomSiteID\":null,\"fathomCustomDomainEnabled\":false,\"fathomCustomDomain\":null,\"hotjarSiteID\":null,\"matomoSiteID\":null,\"matomoURL\":null,\"gaTrackingID\":null,\"gTagManagerID\":null,\"plausibleAnalyticsEnabled\":false,\"wmPaymentPointer\":null,\"koalaPublicKey\":null,\"msClarityID\":null,\"openPanelClientId\":null,\"consentManagement\":{\"enabled\":false,\"version\":1,\"privacyPolicyURL\":null,\"__typename\":\"ConsentManagement\"},\"__typename\":\"PublicationIntegrations\"},\"imprintV2\":null,\"postsCount\":{\"totalDocuments\":10,\"__typename\":\"PostConnection\"},\"isTeam\":true,\"links\":{\"twitter\":\"https://twitter.com/HeyMaxKim\",\"instagram\":\"\",\"github\":\"https://github.com/mkims\",\"website\":\"\",\"hashnode\":\"https://hashnode.com/@maxkim\","])</script>
26<script>self.__next_f.push([1,"\"youtube\":\"\",\"dailydev\":\"\",\"linkedin\":\"\",\"mastodon\":null,\"facebook\":null,\"bluesky\":null,\"__typename\":\"PublicationLinks\"},\"domainInfo\":{\"__typename\":\"DomainInfo\",\"hashnodeSubdomain\":\"maxkim\",\"domain\":{\"__typename\":\"Domain\",\"host\":\"maxkim.dev\",\"ready\":true},\"wwwPrefixedDomain\":{\"__typename\":\"Domain\",\"host\":\"www.maxkim.dev\",\"ready\":true}},\"redirectionRules\":[],\"customRules\":[],\"totalRecommendedPublications\":0,\"allowContributorEdits\":false,\"followersCount\":186,\"pinnedPost\":null,\"seriesList\":{\"edges\":[{\"node\":{\"id\":\"6068a37eb17dc439b747a6a0\",\"name\":\"Clean Code\",\"slug\":\"clean-code\",\"coverImage\":null,\"__typename\":\"Series\"},\"__typename\":\"SeriesEdge\"},{\"node\":{\"id\":\"6068a57eb17dc439b747a6ce\",\"name\":\"Android Made Easy\",\"slug\":\"android\",\"coverImage\":null,\"__typename\":\"Series\"},\"__typename\":\"SeriesEdge\"},{\"node\":{\"id\":\"615abf32ad6beb6f6506e793\",\"name\":\"Kotlin Features\",\"slug\":\"kotlin-features\",\"coverImage\":null,\"__typename\":\"Series\"},\"__typename\":\"SeriesEdge\"},{\"node\":{\"id\":\"61a7e5631e28ee7efba8b9b8\",\"name\":\"Kotlin Coroutines\",\"slug\":\"kotlin-coroutines\",\"coverImage\":null,\"__typename\":\"Series\"},\"__typename\":\"SeriesEdge\"}],\"__typename\":\"SeriesConnection\"},\"members\":{\"edges\":[{\"node\":{\"id\":\"6745536d1b8c712f137a6558\",\"role\":\"author\",\"user\":{\"id\":\"606866b41ed1783ab0632df0\",\"name\":\"Max Kim\",\"username\":\"maxkim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"__typename\":\"User\"},\"__typename\":\"PublicationMember\"},\"__typename\":\"PublicationMemberEdge\"}],\"__typename\":\"PublicationMemberConnection\"}},\"posts\":[{\"__typename\":\"Post\",\"id\":\"627e35255cbe9ede04a91214\",\"title\":\"Full Guide to Testing Android Applications in 2022\",\"slug\":\"full-guide-to-testing-android-applications-in-2022\",\"publishedAt\":\"2022-05-13T10:38:29.748Z\",\"cuid\":\"cl34b3szt010ntpnv18ifgv81\",\"url\":\"https://maxkim.dev/full-guide-to-testing-android-applications-in-2022\",\"subtitle\":\"\",\"brief\":\"Testing is quite a fascinating topic in software development. On the one hand, writing tests takes time, and it might not feel as rewarding - you cannot show a test to a client as you can a new feature. On the other hand, writing tests is an integral...\",\"readTimeInMinutes\":66,\"views\":21144,\"tags\":[{\"id\":\"625d874d57bc361115202180\",\"slug\":\"thw-mobile-apps\",\"name\":\"THW Mobile Apps\",\"__typename\":\"Tag\"},{\"id\":\"56744723958ef13879b953d0\",\"slug\":\"android\",\"name\":\"Android\",\"__typename\":\"Tag\"},{\"id\":\"56744721958ef13879b94890\",\"slug\":\"android-app-development\",\"name\":\"android app development\",\"__typename\":\"Tag\"},{\"id\":\"56c2f39e850906a7da47cdeb\",\"slug\":\"kotlin\",\"name\":\"Kotlin\",\"__typename\":\"Tag\"},{\"id\":\"56744723958ef13879b9549b\",\"slug\":\"testing\",\"name\":\"Testing\",\"__typename\":\"Tag\"}],\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"username\":\"maxkim\",\"name\":\"Max Kim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"coverImage\":{\"__typename\":\"CoverImage\",\"url\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1652343671311/ElJ-dtU-y.png\",\"isPortrait\":false,\"isAttributionHidden\":false}},{\"__typename\":\"Post\",\"id\":\"61e1ac491f35f378644680fc\",\"title\":\"Things every Kotlin Developer should know about Coroutines. Part 5: Cancellation.\",\"slug\":\"things-every-kotlin-developer-should-know-about-coroutines-part-5-cancellation\",\"publishedAt\":\"2022-01-14T17:00:57.688Z\",\"cuid\":\"ckyend9ol0cr2s4s1960yfuok\",\"url\":\"https://maxkim.dev/things-every-kotlin-developer-should-know-about-coroutines-part-5-cancellation\",\"subtitle\":\"\",\"brief\":\"As much as we had talked about cancellation in the last part, in this article, we will often touch upon exception handling. Since, as discu
26ssed previously, these two concepts use the same mechanism.\\nThat said, cancellation in the coroutines library i...\",\"readTimeInMinutes\":15,\"views\":8001,\"tags\":[{\"id\":\"56c2f39e850906a7da47cdeb\",\"slug\":\"kotlin\",\"name\":\"Kotlin\",\"__typename\":\"Tag\"},{\"id\":\"5f081e73b587713318b74a42\",\"slug\":\"kotlin-beginner\",\"name\":\"kotlin beginner\",\"__typename\":\"Tag\"},{\"id\":\"56facb5fbac95334fc2fa50b\",\"slug\":\"coroutines\",\"name\":\"coroutines\",\"__t"])</script>
26<script>self.__next_f.push([1,"ypename\":\"Tag\"},{\"id\":\"56744723958ef13879b953d0\",\"slug\":\"android\",\"name\":\"Android\",\"__typename\":\"Tag\"},{\"id\":\"56744721958ef13879b94890\",\"slug\":\"android-app-development\",\"name\":\"android app development\",\"__typename\":\"Tag\"}],\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"username\":\"maxkim\",\"name\":\"Max Kim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"coverImage\":{\"__typename\":\"CoverImage\",\"url\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1642174453234/N3eNVc3gR.png\",\"isPortrait\":false,\"isAttributionHidden\":false}},{\"__typename\":\"Post\",\"id\":\"61d5f157955f030edd3abb32\",\"title\":\"Things every Kotlin Developer should know about Coroutines. Part 4: Exception Handling.\",\"slug\":\"things-every-kotlin-developer-should-know-about-coroutines-part-4-exception-handling\",\"publishedAt\":\"2022-01-05T19:28:23.922Z\",\"cuid\":\"cky1xo7l10048xps137huhx2v\",\"url\":\"https://maxkim.dev/things-every-kotlin-developer-should-know-about-coroutines-part-4-exception-handling\",\"subtitle\":\"\",\"brief\":\"In Part 3, we have discussed structured concurrency, which was introduced to the coroutines library primarily as a solution to exception handling and cancellation.\\nBecause of that, these two concepts go hand in hand, and even though we will not focus...\",\"readTimeInMinutes\":13,\"views\":8504,\"tags\":[{\"id\":\"56c2f39e850906a7da47cdeb\",\"slug\":\"kotlin\",\"name\":\"Kotlin\",\"__typename\":\"Tag\"},{\"id\":\"5f081e73b587713318b74a42\",\"slug\":\"kotlin-beginner\",\"name\":\"kotlin beginner\",\"__typename\":\"Tag\"},{\"id\":\"56744723958ef13879b953d0\",\"slug\":\"android\",\"name\":\"Android\",\"__typename\":\"Tag\"},{\"id\":\"56facb5fbac95334fc2fa50b\",\"slug\":\"coroutines\",\"name\":\"coroutines\",\"__typename\":\"Tag\"},{\"id\":\"56744721958ef13879b94890\",\"slug\":\"android-app-development\",\"name\":\"android app development\",\"__typename\":\"Tag\"}],\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"username\":\"maxkim\",\"name\":\"Max Kim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"coverImage\":{\"__typename\":\"CoverImage\",\"url\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1641408624827/vd__E1NQR.png\",\"isPortrait\":false,\"isAttributionHidden\":false}},{\"__typename\":\"Post\",\"id\":\"61c471953fe31f38adc314fd\",\"title\":\"Things every Kotlin Developer should know about Coroutines. Part 3: Structured Concurrency.\",\"slug\":\"things-every-kotlin-developer-should-know-about-coroutines-part-3-structured-concurrency\",\"publishedAt\":\"2021-12-23T12:54:45.571Z\",\"cuid\":\"ckxiyvwol01if71s1clmscogp\",\"url\":\"https://maxkim.dev/things-every-kotlin-developer-should-know-about-coroutines-part-3-structured-concurrency\",\"subtitle\":\"\",\"brief\":\"If you watch a coroutines video dated before their stable launch in Kotlin 1.3, you might notice that the way coroutines were used in their \\\"experimental\\\" phase is a bit different from now.\\nFor example, at KotlinConf 2017, in his Introductions to Cor...\",\"readTimeInMinutes\":8,\"views\":8947,\"tags\":[{\"id\":\"56c2f39e850906a7da47cdeb\",\"slug\":\"kotlin\",\"name\":\"Kotlin\",\"__typename\":\"Tag\"},{\"id\":\"5f081e73b587713318b74a42\",\"slug\":\"kotlin-beginner\",\"name\":\"kotlin beginner\",\"__typename\":\"Tag\"},{\"id\":\"56744723958ef13879b953d0\",\"slug\":\"android\",\"name\":\"Android\",\"__typename\":\"Tag\"},{\"id\":\"56744721958ef13879b94890\",\"slug\":\"android-app-development\",\"name\":\"android app development\",\"__typename\":\"Tag\"},{\"id\":\"56facb5fbac95334fc2fa50b\",\"slug\":\"coroutines\",\"name\":\"coroutines\",\"__typename\":\"Tag\"}],\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"username\":\"maxkim\",\"name\":\"Max Kim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"coverImage\":{\"__typename\":\"CoverImage\",\"url\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1640266242099/8Rq97l9AG.png\",\"isPortrait\":false,\"isAttributionHidden\":false}}
26,{\"__typename\":\"Post\",\"id\":\"61b89f230059f90a57a58873\",\"title\":\"Things every Kotlin Developer should know about Coroutines. Part 2: CoroutineScope.\",\"slug\":\"things-every-kotlin-dev"])</script>
26<script>self.__next_f.push([1,"eloper-should-know-about-coroutines-part-2-coroutinescope\",\"publishedAt\":\"2021-12-14T13:41:55.582Z\",\"cuid\":\"ckx65lwbi0mo61js1h0i44ghm\",\"url\":\"https://maxkim.dev/things-every-kotlin-developer-should-know-about-coroutines-part-2-coroutinescope\",\"subtitle\":\"\",\"brief\":\"In my experience, CoroutineScope is one of the less understood parts of the coroutines library, even though it is one of the most important. In Android, we are spoiled with coroutine scopes kindly provided to us by lifecycle libraries, but for many d...\",\"readTimeInMinutes\":11,\"views\":7697,\"tags\":[{\"id\":\"56c2f39e850906a7da47cdeb\",\"slug\":\"kotlin\",\"name\":\"Kotlin\",\"__typename\":\"Tag\"},{\"id\":\"5f081e73b587713318b74a42\",\"slug\":\"kotlin-beginner\",\"name\":\"kotlin beginner\",\"__typename\":\"Tag\"},{\"id\":\"56facb5fbac95334fc2fa50b\",\"slug\":\"coroutines\",\"name\":\"coroutines\",\"__typename\":\"Tag\"},{\"id\":\"56744723958ef13879b953d0\",\"slug\":\"android\",\"name\":\"Android\",\"__typename\":\"Tag\"},{\"id\":\"56744721958ef13879b94890\",\"slug\":\"android-app-development\",\"name\":\"android app development\",\"__typename\":\"Tag\"}],\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"username\":\"maxkim\",\"name\":\"Max Kim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"coverImage\":{\"__typename\":\"CoverImage\",\"url\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1639477245203/xx6LcXZHC.png\",\"isPortrait\":false,\"isAttributionHidden\":false}},{\"__typename\":\"Post\",\"id\":\"61a882aa1e28ee7efba8c224\",\"title\":\"Things every Kotlin Developer should know about Coroutines. \\n\\nPart 1: CoroutineContext.\",\"slug\":\"things-every-kotlin-developer-should-know-about-coroutines-part-1-coroutinecontext\",\"publishedAt\":\"2021-12-02T08:24:10.242Z\",\"cuid\":\"ckwooz1f503z02zs18wjm4xim\",\"url\":\"https://maxkim.dev/things-every-kotlin-developer-should-know-about-coroutines-part-1-coroutinecontext\",\"subtitle\":\"\",\"brief\":\"The CoroutineContext is the backbone of the coroutines library. Every coroutine you launch will have a context. However, given its nature and flexible API, it might prove pretty tricky to use it correctly.\\nIn Part 1 of my series about coroutines, I w...\",\"readTimeInMinutes\":8,\"views\":13134,\"tags\":[{\"id\":\"56c2f39e850906a7da47cdeb\",\"slug\":\"kotlin\",\"name\":\"Kotlin\",\"__typename\":\"Tag\"},{\"id\":\"5f081e73b587713318b74a42\",\"slug\":\"kotlin-beginner\",\"name\":\"kotlin beginner\",\"__typename\":\"Tag\"},{\"id\":\"56744723958ef13879b953d0\",\"slug\":\"android\",\"name\":\"Android\",\"__typename\":\"Tag\"},{\"id\":\"56744721958ef13879b94890\",\"slug\":\"android-app-development\",\"name\":\"android app development\",\"__typename\":\"Tag\"},{\"id\":\"56facb5fbac95334fc2fa50b\",\"slug\":\"coroutines\",\"name\":\"coroutines\",\"__typename\":\"Tag\"}],\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"username\":\"maxkim\",\"name\":\"Max Kim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"coverImage\":{\"__typename\":\"CoverImage\",\"url\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1638386151096/lme5o9O7D.png\",\"isPortrait\":false,\"isAttributionHidden\":false}},{\"__typename\":\"Post\",\"id\":\"615abfdae2f1936f70b2943f\",\"title\":\"A Practical Guide to Kotlin's inline Modifier\",\"slug\":\"a-practical-guide-to-kotlins-inline-modifier\",\"publishedAt\":\"2021-10-04T08:48:26.533Z\",\"cuid\":\"ckuceuzog0ec60gs17y6m8oa0\",\"url\":\"https://maxkim.dev/a-practical-guide-to-kotlins-inline-modifier\",\"subtitle\":\"\",\"brief\":\"I fell in love with Kotlin as soon as I switched to it from Java about 4 years ago. And although I was writing Kotlin code on a regular basis ever since, I didn't start using some of its more advanced features until quite recently.\\nI wish I had start...\",\"readTimeInMinutes\":13,\"views\":2146,\"tags\":[{\"id\":\"56c2f39e850906a7da47cdeb\",\"slug\":\"kotlin\",\"name\":\"Kotlin\",\"__typename\":\"Tag\"}],\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"username\":\"maxkim\",\"name\":\"Max Kim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"coverImage\":{\"__typename\":\"CoverImage\",\"url\":\"https://cdn.hashn"])</script>
26<script>self.__next_f.push([1,"ode.com/res/hashnode/image/upload/v1633257088662/baRNBzc2X.png\",\"isPortrait\":false,\"isAttributionHidden\":false}},{\"__typename\":\"Post\",\"id\":\"60fd9f4718fbbb77c9468462\",\"title\":\"Understanding Layouts in Jetpack Compose\",\"slug\":\"understanding-layouts-in-jetpack-compose\",\"publishedAt\":\"2021-07-25T17:28:39.380Z\",\"cuid\":\"ckrjh6ikl0u63nts1fkedf23a\",\"url\":\"https://maxkim.dev/understanding-layouts-in-jetpack-compose\",\"subtitle\":\"\",\"brief\":\"In my previous article Things you need to know before switching to Jetpack Compose, I discussed the basic principles of building UI using Jetpack Compose. \\nToday, let's dive a little deeper into how layouts work in Compose and learn how to build a mo...\",\"readTimeInMinutes\":12,\"views\":2366,\"tags\":[{\"id\":\"56744723958ef13879b953d0\",\"slug\":\"android\",\"name\":\"Android\",\"__typename\":\"Tag\"},{\"id\":\"56744721958ef13879b94890\",\"slug\":\"android-app-development\",\"name\":\"android app development\",\"__typename\":\"Tag\"},{\"id\":\"590c655dd7c4344afe6c3241\",\"slug\":\"android-apps\",\"name\":\"android apps\",\"__typename\":\"Tag\"},{\"id\":\"56c2f39e850906a7da47cdeb\",\"slug\":\"kotlin\",\"name\":\"Kotlin\",\"__typename\":\"Tag\"},{\"id\":\"5868042db99398bc30c43e77\",\"slug\":\"android-studio\",\"name\":\"Android Studio\",\"__typename\":\"Tag\"}],\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"username\":\"maxkim\",\"name\":\"Max Kim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"coverImage\":{\"__typename\":\"CoverImage\",\"url\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1627234201356/djlV76uIc.png\",\"isPortrait\":false,\"isAttributionHidden\":false}},{\"__typename\":\"Post\",\"id\":\"60ec0dc14038c357daba194d\",\"title\":\"Things you need to know before switching to Jetpack Compose\",\"slug\":\"things-you-need-to-know-before-switching-to-jetpack-compose\",\"publishedAt\":\"2021-07-12T09:39:13.317Z\",\"cuid\":\"ckr0foqtd00gucqs17xmw
26a0nr\",\"url\":\"https://maxkim.dev/things-you-need-to-know-before-switching-to-jetpack-compose\",\"subtitle\":\"\",\"brief\":\"With the release of the stable version of Jetpack Compose just around the corner, here are some things you need to know before switching from the imperative, XML-based style for building UI, to the new Android’s toolkit for building native UI declara...\",\"readTimeInMinutes\":12,\"views\":6838,\"tags\":[{\"id\":\"56744723958ef13879b953d0\",\"slug\":\"android\",\"name\":\"Android\",\"__typename\":\"Tag\"},{\"id\":\"590c655dd7c4344afe6c3241\",\"slug\":\"android-apps\",\"name\":\"android apps\",\"__typename\":\"Tag\"},{\"id\":\"5868042db99398bc30c43e77\",\"slug\":\"android-studio\",\"name\":\"Android Studio\",\"__typename\":\"Tag\"},{\"id\":\"56744721958ef13879b94890\",\"slug\":\"android-app-development\",\"name\":\"android app development\",\"__typename\":\"Tag\"},{\"id\":\"56c2f39e850906a7da47cdeb\",\"slug\":\"kotlin\",\"name\":\"Kotlin\",\"__typename\":\"Tag\"}],\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"username\":\"maxkim\",\"name\":\"Max Kim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"coverImage\":{\"__typename\":\"CoverImage\",\"url\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1625693138062/_rlN91Wnz.png\",\"isPortrait\":false,\"isAttributionHidden\":false}},{\"__typename\":\"Post\",\"id\":\"60e359a3e9aeb8301a6a3b84\",\"title\":\"7 Tips for Becoming a Better Developer\",\"slug\":\"7-tips-for-becoming-a-better-developer\",\"publishedAt\":\"2021-07-05T19:12:35.745Z\",\"cuid\":\"ckqr034zt010xi2s1f11lafap\",\"url\":\"https://maxkim.dev/7-tips-for-becoming-a-better-developer\",\"subtitle\":\"\",\"brief\":\"Most of the writing on software development is very technical, aimed at researching and solving a particular problem. Such writing provides tremendous value, and I imagine most of what I will write in this blog will be just that - posts focusing on t...\",\"readTimeInMinutes\":13,\"views\":1058,\"tags\":[{\"id\":\"5f398753c4d5973f55c912fb\",\"slug\":\"programming-tips\",\"name\":\"Programming Tips\",\"__typename\":\"Tag\"},{\"id\":\"56744723958ef13879b95319\",\"slug\":\"tips\",\"name\":\"tips\",\"__typename\":\"Tag\"},{\"id\":\"5f1c1e25e8769101a9ef64d2\",\"slug\":\"developer-blogging\",\"name\":\"Developer Blogging\",\"__typename\":\"Tag\""])</script>
26<script>self.__next_f.push([1,"},{\"id\":\"56744723958ef13879b952d7\",\"slug\":\"developer\",\"name\":\"Developer\",\"__typename\":\"Tag\"},{\"id\":\"56744723958ef13879b953d0\",\"slug\":\"android\",\"name\":\"Android\",\"__typename\":\"Tag\"}],\"author\":{\"__typename\":\"User\",\"id\":\"606866b41ed1783ab0632df0\",\"username\":\"maxkim\",\"name\":\"Max Kim\",\"profilePicture\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617454773783/v83DJxGeU.jpeg\",\"followersCount\":185},\"coverImage\":{\"__typename\":\"CoverImage\",\"url\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1625249464285/cRejdKYNs.png\",\"isPortrait\":false,\"isAttributionHidden\":false}}],\"host\":\"maxkim.dev\"}],\"$L18\",\"$L19\",\"$L1a\"]}]\n1b:I[57254,[\"4554\",\"static/chunks/4554-984b480a9db5f3fe.js\",\"7563\",\"static/chunks/7563-4dfa0994a9b0e37c.js\",\"5001\",\"static/chunks/5001-fae0bebdd93f95e3.js\",\"2423\",\"static/chunks/2423-c8b1388240338d7d.js\",\"9216\",\"static/chunks/9216-9272709ba40c1cfd.js\",\"3091\",\"static/chunks/3091-bf1537ff6571a1bd.js\",\"652\",\"static/chunks/652-f40dcb480b4e356f.js\",\"730\",\"static/chunks/730-8191af9e9424b148.js\",\"8974\",\"static/chunks/app/page-cc18ae1a3a7a5ed8.js\"],\"PostsList\"]\n18:[\"$\",\"div\",null,{\"className\":\"px-4 sm:px-8\",\"children\":[\"$\",\"div\",null,{\"className\":\"w-full xl:mx-auto xl:max-w-[80rem] 2xl:max-w-[90rem]\",\"children\":[\"$\",\"div\",null,{\"className\":\"flex flex-col gap-8 pt-2 sm:pt-10\",\"children\":[\"$\",\"section\",null,{\"className\":\"pb-16\",\"children\":[\"$\",\"div\",null,{\"className\":\"space-y-6 max-w-5xl w-full mx-auto\",\"children\":[\"$\",\"$L1b\",null,{\"initialPosts\":[\"$b:props:children:0:props:posts:0\",\"$b:props:children:0:props:posts:1\",\"$b:props:children:0:props:posts:2\",\"$b:props:children:0:props:posts:3\",\"$b:props:children:0:props:posts:4\",\"$b:props:children:0:props:posts:5\",\"$b:props:children:0:props:posts:6\",\"$b:props:children:0:props:posts:7\",\"$b:props:children:0:props:posts:8\"],\"initialCursor\":\"9\",\"initialHasNextPage\":true,\"pinnedPostId\":null,\"aboutHtml\":null,\"links\":\"$b:props:children:0:props:publication:links\",\"aboutAvatarUrl\":\"https://cdn.hashnode.com/res/hashnode/image/upload/v1617472420953/1QxiyYLAM.png\",\"aboutAvatarFallback\":\"A\",\"totalPostsCount\":10,\"aboutHeading\":\"Art and science of writing good code\",\"publication\":\"$b:props:children:0:props:publication\",\"isTeam\":true,\"showHashnodeIcon\":true,\"layout\":\"grid\",\"isHashnodeSubdomain\":false}]}]}]}]}]}]\n19:[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"Blog\\\",\\\"name\\\":\\\"Art and science of writing good code\\\",\\\"url\\\":\\\"https://maxkim.dev\\\",\\\"description\\\":\\\"Art and science of writing good code\\\",\\\"mainEntityOfPage\\\":{\\\"@type\\\":\\\"WebPage\\\",\\\"url\\\":\\\"https://maxkim.dev\\\"},\\\"publisher\\\":{\\\"@type\\\":\\\"Organization\\\",\\\"name\\\":\\\"Art and science of writing good code\\\",\\\"url\\\":\\\"https://maxkim.dev\\\"},\\\"image\\\":{\\\"@type\\\":\\\"ImageObject\\\",\\\"url\\\":\\\"https://maxkim.dev/api/og/home?og=eyJ0aXRsZSI6IkFydCUyMGFuZCUyMHNjaWVuY2UlMjBvZiUyMHdyaXRpbmclMjBnb29kJTIwY29kZSIsImlzRGVmYXVsdE1vZGVEYXJrIjpmYWxzZSwicGhvdG8iOiJodHRwczovL2Nkbi5oYXNobm9kZS5jb20vcmVzL2hhc2hub2RlL2ltYWdlL3VwbG9hZC92MTYxNzQ1NDc3Mzc4My92ODNESnhHZVUuanBlZyIsImlzVGVhbSI6dHJ1ZSwiZG9tYWluIjoibWF4a2ltLmRldiIsImZvbGxvd2VycyI6MTg2LCJhcnRpY2xlcyI6MCwiZmF2aWNvbiI6Imh0dHBzOi8vY2RuLmhhc2hub2RlLmNvbS9yZXMvaGFzaG5vZGUvaW1hZ2UvdXBsb2FkL3YxNjE3NDcyNDIwOTUzLzFReGl5WUxBTS5wbmcifQ==\\\"},\\\"sameAs\\\":[\\\"https://x.com/HeyMaxKim\\\",\\\"https://github.com/mkims\\\",\\\"https://hashnode.com/@maxkim\\\"]}\"}}]\n1c:I[52619,[\"4554\",\"static/chunks/4554-984b480a9db5f3fe.js\",\"7563\",\"static/chunks/7563-4dfa0994a9b0e37c.js\",\"5001\",\"static/chunks/5001-fae0bebdd93f95e3.js\",\"2423\",\"static/chunks/2423-c8b1388240338d7d.js\",\"9216\",\"static/chunks/9216-9272709ba40c1cfd.js\",\"3091\",\"static/chunks/3091-bf1537ff6571a1bd.js\",\"652\",\"static/chunks/652-f40dcb480b4e356f.js\",\"730\",\"static/chunks/730-8191af9e9424b148.js\",\"8974\",\"static/chunks/app/page-cc18ae1a3a7a5ed8.js\"],\"\"]\n1d:Tc98,M268.379 39q-6.322 0-10.35-4.108-4.002-4.134-4.002-10.483 0-6.296 4.002-10.43 4-4.135 10.163-4.135 6.028 0 9.817 3.734 3.814 3.735 3.814 9.497v2.8h-24.248v-4.054h17.633q-.187-2.747-2.054-4.508-1.868-1.76-4.962-1.76-3.28-.001-5.38"])</script>
26<script>self.__next_f.push([1,"8 2.374-2.108 2.373-2.108 6.375 0 4.188 2.348 6.695 2.347 2.481 5.895 2.481 1.68 0 2.934-.453a8.5 8.5 0 0 0 2.321-1.307q1.041-.854 2.268-2.614l4.694 2.96q-1.707 2.748-3.494 4.135a12.7 12.7 0 0 1-3.975 2.081q-2.187.72-5.308.72m-33.496 0q-5.575 0-9.283-4.028-3.681-4.029-3.681-10.484 0-6.43 3.761-10.51 3.76-4.108 9.47-4.108 2.8 0 5.175 1.2 2.4 1.174 3.628 3.148l.026-.08V0h7.016v38.2h-6.722v-4.722l.64.8-.694.133q-1.28 2.108-3.788 3.361Q237.924 39 234.883 39m1.627-6.002q3.308 0 5.495-2.428t2.188-6.135q0-3.762-2.214-6.109-2.214-2.374-5.469-2.374-3.28 0-5.522 2.347-2.214 2.348-2.214 6.163 0 3.76 2.214 6.162 2.214 2.374 5.522 2.374M205.811 39q-6.376 0-10.537-4.161-4.161-4.188-4.161-10.404 0-6.321 4.161-10.456 4.188-4.135 10.537-4.135 6.348 0 10.537 4.161 4.188 4.161 4.188 10.43 0 6.216-4.188 10.404Q212.186 39 205.811 39m0-6.162q3.307 0 5.575-2.374 2.267-2.374 2.267-6.055 0-3.707-2.294-6.056-2.267-2.347-5.548-2.347-3.308 0-5.575 2.374-2.268 2.348-2.268 6.029t2.241 6.055q2.268 2.374 5.602 2.374M162.586 38.2V10.644h6.802v5.015l-.8-.987h.906q1.308-2.187 3.762-3.494 2.48-1.335 5.228-1.334 4.615 0 7.256 2.8 2.667 2.776 2.667 7.603V38.2h-7.069V21.794q0-2.854-1.387-4.401t-4.134-1.547q-2.614 0-4.402 1.974-1.76 1.974-1.76 4.881V38.2zm-30.181 0V0h6.962v14.698h.134q1.2-2.187 3.574-3.521 2.375-1.335 5.229-1.334 4.615 0 7.255 2.828 2.668 2.801 2.668 7.522V38.2h-7.069V21.794q0-2.827-1.387-4.402-1.387-1.573-4.055-1.573-2.587 0-4.428 2.027-1.814 2.027-1.814 4.962v15.391zm-14.416.8q-2.882 0-5.015-.64-2.108-.614-3.761-1.84-1.654-1.228-2.668-2.695l-.987-1.467 4.695-3.174.773 1.067a9.1 9.1 0 0 0 1.788 1.814 8.2 8.2 0 0 0 2.32 1.2q1.308.4 3.068.4 2.161 0 3.441-.8 1.308-.8 1.307-2.294 0-1.36-1.147-2.108-1.12-.747-5.068-1.654-5.335-1.253-7.656-3.334-2.32-2.107-2.321-5.362 0-3.76 3.148-6.002 3.148-2.267 7.923-2.267 2.454 0 4.348.507t3.388 1.493q1.493.988 2.454 2.188l.987 1.2-4.482 3.255-.667-.774a7.4 7.4 0 0 0-1.627-1.387 6.4 6.4 0 0 0-2.054-.88 9.5 9.5 0 0 0-2.401-.294q-1.974 0-3.201.8-1.2.774-1.2 1.921 0 1.254 1.12 2.027 1.147.748 5.229 1.681 5.334 1.227 7.629 3.308 2.294 2.055 2.294 5.308 0 4.029-3.228 6.43Q123.217 39 117.989 39M87.61 39q-4.508 0-7.335-2.454-2.828-2.481-2.828-6.482 0-4.188 3.254-6.669t8.483-2.48q2.082 0 4.028.426 1.974.427 3.361 1.12v-1.6q0-2.588-1.813-4.082-1.788-1.493-4.615-1.493-1.628 0-2.801.373a8.7 8.7 0 0 0-2.188.987q-.987.614-1.84 1.414l-.854.8-4.081-3.788 1.307-1.173a18.7 18.7 0 0 1 2.934-2.108q1.601-.933 3.601-1.44t4.589-.507q5.868 0 9.229 2.88 3.361 2.882 3.361 8.084V38.2h-6.749v-5.922l1.654 2.187h-1.76q-1.308 2.055-3.655 3.308Q90.545 39 87.611 39m1.814-4.988q3.148 0 5.149-2.187 2-2.215 2-5.309v-.08q-1.12-.693-2.72-1.094a13 13 0 0 0-3.388-.426q-2.828 0-4.562 1.2-1.734 1.173-1.734 3.521 0 2.028 1.468 3.201t3.787 1.174M49 38.2V0h6.962v14.698h.134q1.2-2.187 3.574-3.521 2.375-1.335 5.229-1.334 4.615 0 7.255 2.828 2.668 2.801 2.668 7.522V38.2h-7.07V21.794q0-2.827-1.386-4.402-1.387-1.573-4.055-1.573-2.587 0-4.428 2.027-1.815 2.027-1.814 4.962v15.391z1a:[\"$\",\"footer\",null,{\"className\":\"px-4 pt-8 pb-20 sm:px-8 text-muted-foreground\",\"aria-label\":\"Footer\",\"children\":[\"$\",\"div\",null,{\"className\":\"w-full max-w-4xl mx-auto\",\"children\":[\"$\",\"div\",null,{\"className\":\"flex flex-col items-center gap-4 text-center text-sm\",\"children\":[false,[\"$\",\"p\",null,{\"className\":\"font-medium\",\"children\":[[\"$\",\"time\",null,{\"dateTime\":\"2026\",\"children\":[[\"$\",\"span\",null,{\"className\":\"font-sans\",\"children\":\"©\"}],\" \",2026]}],\" \",\"Art and science of writing good code\"]}],[\"$\",\"nav\",null,{\"aria-label\":\"Footer navigation\",\"children\":[\"$\",\"ul\",null,{\"className\":\"flex flex-wrap justify-center gap-4 text-sm tracking-wide\",\"children\":[[\"$\",\"li\",\"/archive\",{\"children\":[\"$\",\"$L1c\",null,{\"href\":\"/archive\",\"className\":\"transition hover:text-foreground\",\"target\":\"$undefined\",\"rel\":\"$undefined\",\"children\":\"Archive\"}]}],[\"$\",\"li\",\"https://hashnode.com/privacy-policy\",{\"children\":[\"$\",\"$L1c\",null,{\"href\":\"https://hashnode.com/privacy-policy\",\"className\":\"transition hover:text-foreground\",\"target\":\"_blank\",\"rel\":\"noopener\",\"children\":\"Privacy\"}]}],[\"$\",\"li\",\"https://hashn"])</script>
26<script>self.__next_f.push([1,"ode.com/terms\",{\"children\":[\"$\",\"$L1c\",null,{\"href\":\"https://hashnode.com/terms\",\"className\":\"transition hover:text-foreground\",\"target\":\"_blank\",\"rel\":\"noopener\",\"children\":\"Terms\"}]}]]}]}],[\"$\",\"div\",null,{\"className\":\"pt-8 flex justify-center gap-6\",\"children\":[[\"$\",\"$L1c\",null,{\"href\":\"/sitemap.xml\",\"target\":\"_blank\",\"rel\":\"noopener\",\"className\":\"flex items-center gap-2 text-sm transition hover:text-foreground\",\"title\":\"Sitemap\",\"children\":[[\"$\",\"i\",null,{\"className\":\"fa-regular fa-sitemap\"}],[\"$\",\"span\",null,{\"children\":\"Sitemap\"}]]}],[\"$\",\"$L1c\",null,{\"href\":\"/rss.xml\",\"target\":\"_blank\",\"rel\":\"noopener\",\"className\":\"flex items-center gap-2 text-sm transition hover:text-foreground\",\"title\":\"RSS Feed\",\"children\":[[\"$\",\"i\",null,{\"className\":\"fa-regular fa-rss\"}],[\"$\",\"span\",null,{\"children\":\"RSS\"}]]}]]}],[\"$\",\"div\",null,{\"className\":\"pt-10 text-center\",\"children\":[\"$\",\"$L1c\",null,{\"href\":\"https://hashnode.com/?utm_source=https%3A%2F%2Fmaxkim.dev\u0026utm_medium=referral\u0026utm_campaign=blog_footer_logo\u0026utm_content=logo\",\"target\":\"_blank\",\"rel\":\"noopener\",\"aria-label\":\"Visit Hashnode (opens in a new tab)\",\"children\":[\"$\",\"svg\",null,{\"fill\":\"none\",\"viewBox\":\"0 0 282 39\",\"aria-hidden\":\"true\",\"className\":\"h-6 w-auto min-w-[9.5rem] text-muted-foreground transition hover:text-foreground\",\"children\":[[\"$\",\"path\",null,{\"fill\":\"currentColor\",\"d\":\"M2.68 13.032c-3.573 3.505-3.573 9.363 0 12.936L13.032 36.32c3.505 3.573 9.363 3.573 12.936 0L36.32 25.968c3.573-3.573 3.573-9.431 0-12.936L25.968 2.68c-3.573-3.573-9.431-3.573-12.936 0zm12.211 1.935c2.507-2.521 6.582-2.544 9.104-.038s2.544 6.582.038 9.104-6.582 2.544-9.104.038-2.544-6.582-.038-9.104\"}],[\"$\",\"path\",null,{\"fill\":\"currentColor\",\"d\":\"$1d\"}]]}],\"className\":\"inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [\u0026_svg]:pointer-events-none [\u0026_svg]:size-4 [\u0026_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground h-10 rounded-md text-xl px-5 py-4\",\"ref\":null}]}]]}]}]}]\n"])</script>
26</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.