<?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[Jeremy Winterberg]]></title><description><![CDATA[Welcome to my blog! Follow along as I write about growing as a software engineer and my passion for aviation. I’ll be posting about the things I’m nerding out on and tips I’ve picked up along the way.]]></description><link>https://www.jeremywinterberg.com</link><image><url>https://substackcdn.com/image/fetch/$s_!2X7r!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F31a4f4f4-dcc4-4d46-9ee0-91bf7dd47e19_512x512.png</url><title>Jeremy Winterberg</title><link>https://www.jeremywinterberg.com</link></image><generator>Substack</generator><lastBuildDate>Wed, 06 May 2026 10:48:56 GMT</lastBuildDate><atom:link href="https://www.jeremywinterberg.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Jeremy Winterberg]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[jeremywinterberg@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[jeremywinterberg@substack.com]]></itunes:email><itunes:name><![CDATA[Jeremy Winterberg]]></itunes:name></itunes:owner><itunes:author><![CDATA[Jeremy Winterberg]]></itunes:author><googleplay:owner><![CDATA[jeremywinterberg@substack.com]]></googleplay:owner><googleplay:email><![CDATA[jeremywinterberg@substack.com]]></googleplay:email><googleplay:author><![CDATA[Jeremy Winterberg]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Stop Following Tutorials]]></title><description><![CDATA[It's hurting your growth as an engineer.]]></description><link>https://www.jeremywinterberg.com/p/stop-following-tutorials</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/stop-following-tutorials</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Sun, 24 Mar 2024 22:50:51 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="2048" height="1369" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1369,&quot;width&quot;:2048,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;man wearing white top using MacBook&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="man wearing white top using MacBook" title="man wearing white top using MacBook" srcset="https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxmcnVzdHJhdGVkJTIwY29tcHV0ZXJ8ZW58MHx8fHwxNzExMzE0NTE1fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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">Photo by <a href="https://unsplash.com/@punttim">Tim Gouw</a> on <a href="https://unsplash.com">Unsplash</a></figcaption></figure></div><p>Like everyone else, I&#8217;ve fallen victim to tutorial hell more times than I care to admit. It even happened to me this week accidentally. I&#8217;m building a side project called <a href="https://www.jobsearch.wtf">JobSearch.wtf</a> to better navigate my job search, and I&#8217;m doing it while learning React/Typescript/Next.js. </p><p>Because I have minimal experience with React and Typescript, I bought a book on test driven development in React. To my surprise it was just a glorified tutorial in book form.<br><br>I followed the book about halfway through, just to see if I&#8217;d learn anything useful and eventually got stuck. For some reason JavaScript library maintainers don&#8217;t understand the concept of backwards compatibility or stability. Syntax versions changed drastically even with only minor version bumps to what was used in the book. It&#8217;s a beta release book, so I assumed most library versions would be up to date, I was wrong.</p><p>Wrought by frustration, I turned off my kindle.</p><p></p><h2>When are tutorials worth using?</h2><p>I believe that there are valid reasons to read or watch a tutorial. </p><ol><li><p>You&#8217;re a new and aspiring developer and have no clue what you&#8217;re doing, but what to learn by building things.</p></li><li><p>You&#8217;re an experienced developer and want to see how other people build things.</p></li></ol><p>If you don&#8217;t fall into the first category, you should not &#8220;code along&#8221; with tutorials. You will not learn anything by copy pasting someone else&#8217;s code. It&#8217;s the equivalent to taking a snippet from StackOverflow and hoping it works.</p><p>If you&#8217;re new to coding, I think it&#8217;s a valuable way to see how other people build things. You see the thought process other people follow, you learn about project structure, and sometimes pick up small nuggets of best practices.</p><p>You will still, of course, need to learn the fundamentals of writing code. I highly recommend learning and continuous practice of data structures, algorithms, and system design. Staying on top of those skills will be mandatory throughout your career.</p><h2>What should you do instead?</h2><p>It&#8217;s quite simple:</p><blockquote><p>Build things and RTFM (read the fu.. friendly manual)</p></blockquote><p>When you get stuck on your own, you have the context of what you were doing and what you wanted to do. This empowers you to search for how to get yourself unblocked. The most valuable resource for this typically is the documentation written by the maintainers of whatever libraries you&#8217;re using. They built the software, so they know it inside and out.</p><p>I can&#8217;t go into the science behind it because I&#8217;m not smart enough, but this helps you learn more efficiently as well. You comprehend and remember things more when you think critically about them versus regurgitating someone else&#8217;s work. It&#8217;s the same concept as studying in school. Read the material, take notes on the material, apply the material in some realistic way. During the process of applying the knowledge you learn to understand it. Understanding how something works is what cements it into your brain.</p><h2>How&#8217;s that going for me?</h2><p>Once I got past initial blockers, I&#8217;ve actually started having fun learning new things and building out this side project. I&#8217;m now able to move relatively quickly and translate the ideas in my head into something that kind of resembles what I wanted. I&#8217;m not a frontend developer, so it&#8217;s a process of trial and error still haha.</p><p>I have been looking at some &#8220;tutorial&#8221; videos, from who I would consider experts, but specifically with the intention of learning how they are using the same technology. I&#8217;m not copying any of their code, I&#8217;m just taking notes and learning.</p><p>Go forth and build cool shit on your own my friends. You&#8217;ll become a stronger engineer because of it.</p><p>Jeremy</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/p/stop-following-tutorials?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/p/stop-following-tutorials?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Merge Two Sorted Arrays]]></title><description><![CDATA[Technical Interview Gone Wrong? Just fix it in post!]]></description><link>https://www.jeremywinterberg.com/p/merge-two-sorted-arrays</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/merge-two-sorted-arrays</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Tue, 13 Feb 2024 05:57:19 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="3456" height="3456" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3456,&quot;width&quot;:3456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;bird's-eye view photo of two people standing on gray concrete road in front of hill&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="bird's-eye view photo of two people standing on gray concrete road in front of hill" title="bird's-eye view photo of two people standing on gray concrete road in front of hill" srcset="https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1436377991866-f9af228d2b47?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxtZXJnZXxlbnwwfHx8fDE3MDc4MDM3MjB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><h2>I think I failed an interview</h2><p>Technically, as of writing this I don&#8217;t know for sure yet if I failed or not&#8230; the company hasn&#8217;t rejected me officially. However, I definitely feel like I failed myself. This is a relatively easy problem to solve, and I froze in the moment.</p><p>So, I decided this evening to suck it up and fix my mistakes. Answer the dreaded question every interviewer asks: &#8220;How would you change this?&#8221;</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/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">Jeremy Winterberg is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</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><p>I know the engineer who interviewed me had read some of my blog, but I doubt he&#8217;ll see this. If you did happen to come back, hi haha &#128075;. I&#8217;m only doing this to learn from my mistakes and become a stronger engineer for the next interview. I hope I don&#8217;t get rejected, I think it&#8217;s a cool company and would like to work there, but I know this likely won&#8217;t change the outcome.</p><h3>The coding challenge</h3><blockquote><p>Given two sorted arrays, merge them into one array.</p></blockquote><p><strong>Constraints</strong>:</p><ul><li><p>will always contain numbers</p></li><li><p>will always be sorted</p></li><li><p>will never have nil values</p></li></ul><h3>What I wrote during the interview</h3><p>At first, I was trying to do something with enumerators and an n^2 solution. My brain froze and he gave me some hints that put me back on track. This is similar to the solution I came up with in the end. It took maybe 15 minutes of our time to get to this solution, and it probably should&#8217;ve taken me less than 5 without any hints.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7hZl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7hZl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.png 424w, https://substackcdn.com/image/fetch/$s_!7hZl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.png 848w, https://substackcdn.com/image/fetch/$s_!7hZl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.png 1272w, https://substackcdn.com/image/fetch/$s_!7hZl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7hZl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.png" width="1456" height="1953" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1953,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:372006,&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_!7hZl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.png 424w, https://substackcdn.com/image/fetch/$s_!7hZl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.png 848w, https://substackcdn.com/image/fetch/$s_!7hZl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.png 1272w, https://substackcdn.com/image/fetch/$s_!7hZl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49a8f9b0-7a44-4b6d-be65-0aecf6ffb711_1740x2334.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><h4>What&#8217;s wrong with this?</h4><ol><li><p>There&#8217;s duplicated logic over and over.</p></li><li><p>The break point isn&#8217;t technically part of the loop.</p></li><li><p>It&#8217;s doing extra work by removing the values from the array.</p></li><li><p>It&#8217;s not easily readable or maintainable.</p></li></ol><h3>My attempt to fix it</h3><ol><li><p>I wanted to clean up the logic. So to do that I loop off the length of the arrays and then do the &#8220;cleanup&#8221; afterwards outside of the while loop.</p></li><li><p>I made the loop a while loop against the lengths of the arrays.</p></li><li><p>No longer removing values from the arrays, only tracking the index we&#8217;re looking at for each array in the variables L and R.</p></li><li><p>It&#8217;s much shorter and cleaner without duplicated logic. This is much easier to maintain in the future. I wouldn&#8217;t leave the comments in there like I did here, but for the purpose of this post I wanted to explain why that was ok to do.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Hx7M!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Hx7M!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.png 424w, https://substackcdn.com/image/fetch/$s_!Hx7M!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.png 848w, https://substackcdn.com/image/fetch/$s_!Hx7M!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.png 1272w, https://substackcdn.com/image/fetch/$s_!Hx7M!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Hx7M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.png" width="1456" height="1597" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1597,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:348574,&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_!Hx7M!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.png 424w, https://substackcdn.com/image/fetch/$s_!Hx7M!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.png 848w, https://substackcdn.com/image/fetch/$s_!Hx7M!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.png 1272w, https://substackcdn.com/image/fetch/$s_!Hx7M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e6d5056-3ab3-4cbd-ad41-fdc9ae5d7d2e_1840x2018.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><p></p><h2>What did I learn?</h2><p>Coding wise, not much. The concepts used in the cleaned-up version are nothing new to me. The main differentiator is time. I spent maybe 45 minutes on the new version thinking about and cleaning up the code. I don&#8217;t do well under the compressed timeline of technical interviews.</p><p>I need to brush up on some common syntax in ruby still. For example, I couldn&#8217;t remember how to do a basic loop because I basically always use enumerators. </p><p>I&#8217;m doing a lot of context switching between programming languages while I work on side projects, and it really threw me off in this interview. I want to continue growing my knowledge of Go, Typescript and React/Nextjs but it might be best if I focus entirely on ruby until I get hired somewhere.</p><p>I believe my best chance at getting hired is going to be with a ruby stack because almost all of my experience is in ruby. The market right now doesn&#8217;t support engineers who are looking to step outside their primary tech stack unfortunately. Companies can pick an engineer from thousands who are looking for work right now, so they can find someone who matches exactly what they&#8217;re looking for with ease.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/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">Jeremy Winterberg is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.</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[DSA - Simple Search vs Binary Search]]></title><description><![CDATA[Interview Skills Series]]></description><link>https://www.jeremywinterberg.com/p/dsa-simple-search-vs-binary-search</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/dsa-simple-search-vs-binary-search</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Thu, 18 Jan 2024 00:00:00 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="5760" height="3840" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3840,&quot;width&quot;:5760,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;two women sitting beside table and talking&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="two women sitting beside table and talking" title="two women sitting beside table and talking" srcset="https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1573497491208-6b1acb260507?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxpbnRlcnZpZXd8ZW58MHx8fHwxNzA3NjY4NDE4fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><h2>Interview Skills Series</h2><p>I&#8217;ve been doing a lot of interview prep and studying for technical interviews. And the one topic that always has myself and thousands of other engineers depressed is data structures and algorithms, aka <strong>DSA</strong>.</p><p>For some reason companies like to think that DSA and leetcode is the only way to tell someone is good at programming. And those companies are simultaneously correct and incorrect.</p><p>There are plenty of examples of folks who get hired into FAANG and ace the interview process because they have memorized DSA and a thousand leetcode questions. But once they get on the job they can&#8217;t build anything resilient or performant.</p><p>Likewise, there are people like me, who are not great at leetcode questions. But once I&#8217;m on the job I understand the business and scalability needs and build really strong systems that perform well under load.</p><p>So, I&#8217;ve decided enough is enough and I&#8217;m cracking out my older copy of <a href="https://amzn.to/422mJjG">The Algorithm Design Manual</a> I bought back in college, and I&#8217;m going to strengthen and maintain my interviewing skills. I will be tagging posts with #interviewing if you care to search for them on my blog.</p><p>To start off this series I&#8217;m going to go over two very simple search algorithms, and when you would use them in the real world. Simple Search and Binary Search.</p><h2>Simple Search</h2><p>Now, there isn&#8217;t really an algorithm called simple search, but I can guarantee you&#8217;ve all use this one. If you have an array of data such as [1,2,3,4,5,6,7,8,9].</p><p>Simple search would iterate over every index of the array and comparing the value to what you&#8217;re looking for. For simplicity, and to follow general conventions, I&#8217;m going to call the array haystack and the target value needle. Find the needle in the haystack.</p><pre><code>def simple_search(needle, haystack)
 haystack.each.with_index do |val, idx|
 return idx if val == needle
 end
end

...

haystack = [1, 2, 3, 4, 5, 6, 7, 8, 9]
simple_search(8, haystack)
=&gt; 7
</code></pre><p>This returns the index of the array where the needle is found.</p><p>This looks fairly innocent for a small dataset like this, but once you scale this to potentially millions of values it slows down considerably.</p><p>Using Big Oh notation this is <strong>O(n)</strong>, linear. As the number of values in the array increase, the time required to complete is increased as well.</p><h2>Binary Search</h2><p>Enter Binary Search. Now, there is a caveat to using binary search. The array must already be sorted. Say we have that same array [1,2,3,4,5,6,7,8,9] and we&#8217;re looking for the index of 8. You could iterate over the entire array to get index 7. Or you can use binary search.</p><pre><code>def binary_search(low, high, needle, haystack)
 return -1 if low &gt; high

 middle = (low+high)/2
 return middle if haystack[middle] == needle

 if haystack[middle] &gt; needle
 return binary_search(low, middle-1, needle, haystack)
 else
 return binary_search(middle+1, high, needle, haystack)
 end
end

...

haystack = [1, 2, 3, 4, 5, 6, 7, 8, 9]
binary_search(0, haystack.length, 8, haystack)
=&gt; 7
</code></pre><p>Walking through this code, we have an array of length 9. So we call binary search against a low of 0, and a high of 9, searching for 8 in the haystack.</p><p>(0+9)/2 = 4.5, ruby rounds this down to 4. The value at index 4 is 5</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YGfd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YGfd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png 424w, https://substackcdn.com/image/fetch/$s_!YGfd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png 848w, https://substackcdn.com/image/fetch/$s_!YGfd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png 1272w, https://substackcdn.com/image/fetch/$s_!YGfd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YGfd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png" width="652" height="148" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:148,&quot;width&quot;:652,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:18381,&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_!YGfd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png 424w, https://substackcdn.com/image/fetch/$s_!YGfd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png 848w, https://substackcdn.com/image/fetch/$s_!YGfd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png 1272w, https://substackcdn.com/image/fetch/$s_!YGfd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8a820e2b-5819-4b06-9ff1-1fd28124ed6f_652x148.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><p>5 does not equal 8 so we continue down. 5 is less than 8 so we enter the else condition and pass the middle index + 1 to set our low index to 5 (the next index after 4).</p><p>(5+9)/2 = 7. The value at index 7 is 8. We&#8217;ve found our value and return 7.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L4_s!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L4_s!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png 424w, https://substackcdn.com/image/fetch/$s_!L4_s!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png 848w, https://substackcdn.com/image/fetch/$s_!L4_s!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png 1272w, https://substackcdn.com/image/fetch/$s_!L4_s!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L4_s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png" width="690" height="182" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:182,&quot;width&quot;:690,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:20430,&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_!L4_s!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png 424w, https://substackcdn.com/image/fetch/$s_!L4_s!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png 848w, https://substackcdn.com/image/fetch/$s_!L4_s!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png 1272w, https://substackcdn.com/image/fetch/$s_!L4_s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd49d6fa-43e7-4929-b2e7-7d46a7baa961_690x182.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3>Whats the difference?</h3><p>These both found the same answer, index 7. However, they did it in a different number of steps.</p><p>Simple Search took 8 steps to find index 7.<br>Binary Search took 2.</p><p>Binary search has a run time complexity of <strong>O(log n)</strong>. Admittedly I&#8217;m not great at math, so I&#8217;m not going to pretend I can explain logarithms. But the general idea that makes an algorithm logarithmic is dividing the set you loop over in half each iteration.</p><p>I do this in the calculation of middle <code>(low+high)/2</code> and then passing middle+1 or middle-1 in the recursive calls to change the low or high respectively.</p><h3>When would you use Binary Search?</h3><p>In any dataset that is sorted. Page numbers, a word dictionary, phone book, etc..</p><p>E.G. If you open a (physical book) dictionary looking for the word <strong>map</strong>, and you open to the B&#8217;s, you know M comes after B so you keep your finger in the B section and flip further back. You are now at the Q&#8217;s and have gone too far. so you split the difference between B and Q, and repeat this until you find the M&#8217;s and eventually the word map.</p><p>If you were using simple search, you would scan every single word from A onwards until you found map. Not very efficient eh?</p><h2>Conclusion</h2><p>This was a rather simple algorithm to digest. I obviously already knew what binary search was, but it was nice to refresh memory on it. I will get into more complex algorithms as we go along. I also plan on covering common Design Patterns in software engineering.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/p/dsa-simple-search-vs-binary-search?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/p/dsa-simple-search-vs-binary-search?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Consistency Is Difficult]]></title><description><![CDATA[Taking on too many things at once can lead to burnout.]]></description><link>https://www.jeremywinterberg.com/p/consistency-is-difficult</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/consistency-is-difficult</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Thu, 28 Dec 2023 03:36:05 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="4888" height="2916" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2916,&quot;width&quot;:4888,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;man sitting on chair covering his eyes&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="man sitting on chair covering his eyes" title="man sitting on chair covering his eyes" srcset="https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1517669375942-946a1f02d705?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxzdHJ1Z2dsZXxlbnwwfHx8fDE3MDc2NjgyNDB8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><p>I think I owe you an explanation.</p><h2>What Happened To Advent Of Code?</h2><p>I&#8217;ve been crazy busy these past couple of weeks with the holidays. And to be completely honest I didn&#8217;t feel like AOC was the best use of my time right now.</p><p>I&#8217;m in the thick of interview prep and interviewing, and parsing text files isn&#8217;t going to help me land a job. I wanted to do AOC this year, but once I started going through the problems I realized it wasn&#8217;t a good use of my time.</p><h2>What Have You Been Doing Then?</h2><h3>I did stick with my goal of learning Go</h3><p>I went through the entire <a href="https://exercism.org">Exercism</a> learning tracks for Go and Ruby. Ruby to see if there were any fundamentals I was missing because most of the jobs I&#8217;m getting contacted about are for Ruby. I think I&#8217;ve learned enough Go that I could be productive on a team right away. I don&#8217;t know that it would be Senior+ level quality code, but it would get the job done and then in a code review, someone more experienced could help with the best practices side of things.</p><h3>I&#8217;ve been reading a few books</h3><p>I finished <a href="https://amzn.to/41C5oO6">Tidy First?</a> by Kent Beck a couple of weeks ago. Highly recommend that for all software engineers as it essentially permits you to clean up your code instead of passing it off as tech debt that never gets refactored.</p><p>I&#8217;m currently about 3/4ths of the way through <a href="https://amzn.to/3RFF3Kr">The Software Engineer&#8217;s Guidebook</a> by Gergely Orosz, the <a href="https://www.pragmaticengineer.com">Pragmatic Engineer</a>. This book has been an excellent read so far because it took the experiences that I had at my previous employers and gave me the proper words to describe things the way the rest of the industry would expect to hear them. I&#8217;m not learning a lot of new things personally because I&#8217;ve experienced most of what he&#8217;s writing about, but its another book I highly recommend for all software engineers, particularly ones looking to grow into the Senior+ level.</p><p>And then after I finish that I plan on reading through System Design Interview <a href="https://amzn.to/3GZPIuL">Volume 1</a> and <a href="https://amzn.to/3RH8zj4">Volume 2</a> by Alex Xu of <a href="https://bytebytego.com">ByteByteGo</a>. I&#8217;ve gone through most of his first book in the past, but now he&#8217;s released a second volume with even more knowledge. But in addition to the books, the <a href="https://blog.bytebytego.com">ByteByteGo</a> blog/newsletter is incredibly valuable and I plan on going through the archives there for even more system design knowledge.</p><h3>Job Interviews Galore</h3><p>I&#8217;ve been doing multiple interviews a day. Granted most are just introduction calls because of the holidays there aren&#8217;t any engineers working to do technical interviews.</p><p>Unfortunately, it&#8217;s very difficult to find work right now. I&#8217;ve had multiple interviews get to the final stages and then I get ghosted by the company with no reason given. The only thing I can think of is someone who fit the position better on paper came into their pipeline and so they moved on to them. There are thousands of engineers looking for work right now, many of whom are coming from layoffs in big tech with very impressive resumes.</p><p>What I&#8217;m doing to set myself apart is some good old-fashioned work ethic. I&#8217;m busting my ass building projects and networking. I&#8217;m spending 10-15 hours a day either interviewing, applying to jobs, growing my skills and knowledge, networking with industry peers and recruiters, etc.</p><p>I refuse to be passive in this search. I will find a job and I will continue this hustle into the future to stay on top of these skills. I will never allow myself to feel stuck at a company again because I&#8217;m rusty at technical interviews.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/p/consistency-is-difficult?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/p/consistency-is-difficult?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Advent of Code 2023 - Day 2 Cube Conundrum]]></title><description><![CDATA[Problem Summary]]></description><link>https://www.jeremywinterberg.com/p/advent-of-code-2023-day-2</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/advent-of-code-2023-day-2</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Mon, 11 Dec 2023 08:51:47 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="6016" height="3904" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3904,&quot;width&quot;:6016,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;orange and white square illustration&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="orange and white square illustration" title="orange and white square illustration" srcset="https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1586173806725-797f4d632f5d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw2fHxjdWJlfGVufDB8fHx8MTcwNzY2ODE5NHww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><h2>Problem Summary</h2><p>As you walk, the Elf shows you a small bag and some cubes which are either red, green, or blue. Each time you play this game, he will hide a secret number of cubes of each color in the bag, and your goal is to figure out information about the number of cubes.</p><p>ou play several games and record the information from each game (your puzzle input). Each game is listed with its ID number (like the 11 in Game 11: &#8230;) followed by a semicolon-separated list of subsets of cubes that were revealed from the bag (like 3 red, 5 green, 4 blue).</p><p>For example, the record of a few games might look like this:</p><pre><code>Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green
</code></pre><p>The Elf would first like to know which games would have been possible if the bag contained only 12 red cubes, 13 green cubes, and 14 blue cubes?</p><p>In the example above, games 1, 2, and 5 would have been possible if the bag had been loaded with that configuration.</p><p>If you add up the IDs of the games that would have been possible, you get 8.</p><p>Determine which games would have been possible if the bag had been loaded with only 12 red cubes, 13 green cubes, and 14 blue cubes. What is the sum of the IDs of those games?</p><h2>Let&#8217;s Solve it</h2><p>Github: <a href="https://github.com/JeremyDwayne/advent_of_code/tree/main/2023/day2">View my solution</a></p><p>We can reuse some of the code from day 1. I suspect a lot of the boilerplate will be similar each day of advent of code. I&#8217;m not sure if I want to extract it into a utility package just yet, so for now, I&#8217;ll just do some good old-fashioned copy-pasting.</p><p>When looking at the sample input a few things stand out to me initially.</p><ol><li><p>There are multiple delimiters, <code>:</code> <code>,</code> <code>;</code>, which tells me we can do some string splitting or regex.</p></li><li><p>We probably can&#8217;t assume there will always be the same number of games per line, or that all colors will be pulled every time.</p></li></ol><h3>String Split &amp; Regex</h3><p>I know regex shouldn&#8217;t be the first thing you go to because it&#8217;s so hard to get right, but in this situation, I think it&#8217;s the best way to capture the game ID.</p><p>I looked up how to do regex matchers in go, but to be completely honest it is still rather confusing for me. But I think I&#8217;ve got a decent grasp on it for now.</p><p>Because we&#8217;re looping over every line of the file, go recommends that you compile outside the loop. So we create the <code>regexp</code> pattern to pull out the game id and the list of games. Then inside the scanner loop we&#8217;ll find all strings that match that regex.</p><pre><code>matcher := regexp.MustCompile(`Game (\d+): (.*)`)
...
matched := matcher.FindAllStringSubmatch(line, -1)[0]
</code></pre><h3>Plan for Variability</h3><p>Even without looking at the sample input, it&#8217;s smart to assume these values can vary. But if we were to cheat, that assumption is backed up. Some have fewer games, and some don&#8217;t have all of the colors. So we&#8217;re doing the right thing by parsing and looping through what <em>is</em> there.</p><p>Now that we have the list of games, we can do some <code>strings.Split</code> to loop through each round, and then again to get each set of cubes. Each round is separated by a <code>;</code> and each cube by a <code>,</code>.</p><h3>My Solution</h3><p>That&#8217;s all there is to this. I&#8217;m not sure if this is an optimal solution, particularly because of how many loops there are. But it does work, and gives the correct answer.</p><pre><code>package main

import (
 "bufio"
 "fmt"
 "os"
 "regexp"
 "strconv"
 "strings"
)

func main() {
 file, err := os.Open("input.txt")
 if err != nil {
 panic(err)
 }
 defer file.Close()

 scanner := bufio.NewScanner(file)

 bag := map[string]int{"red": 12, "green": 13, "blue": 14}
 sum := 0
 matcher := regexp.MustCompile(`Game (\d+): (.*)`)

 for scanner.Scan() {
 line := scanner.Text()
 ok := true
 matched := matcher.FindAllStringSubmatch(line, -1)[0]

 id, err := strconv.Atoi(matched[1])
 if err != nil {
 panic(err)
 }
 games := strings.Split(matched[2], "; ")

 for _, game := range games {
 cubes := strings.Split(game, ", ")
 for _, cube := range cubes {
 rolls := strings.Split(cube, " ")
 quantity, err := strconv.Atoi(rolls[0])
 if err != nil {
 panic(err)
 }
 color := rolls[1]

 if bag[color] &lt; quantity {
 ok = false
 }
 }
 }
 if ok {
 sum += id
 }
 }
 fmt.Println(sum)
}
</code></pre><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/p/advent-of-code-2023-day-2?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/p/advent-of-code-2023-day-2?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Advent of Code 2023 - Day 1 Trebuchet?!]]></title><description><![CDATA[Problem Summary]]></description><link>https://www.jeremywinterberg.com/p/advent-of-code-2023-day-1</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/advent-of-code-2023-day-1</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Sat, 09 Dec 2023 03:30:18 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="3000" height="2000" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2000,&quot;width&quot;:3000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;ray of light near body of water&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="ray of light near body of water" title="ray of light near body of water" srcset="https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1457364887197-9150188c107b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxsYXVuY2h8ZW58MHx8fHwxNzA3NjY4MTMwfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><h2>Problem Summary</h2><blockquote><p>On each line, the calibration value can be found by combining the first digit and the last digit (in that order) to form a single two-digit number. For example:</p></blockquote><pre><code>1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
</code></pre><blockquote><p>In this example, the calibration values of these four lines are 12, 38, 15, and 77. Adding these together produces 142. Consider your entire calibration document.</p><p>What is the sum of all of the calibration values?</p></blockquote><p>They provide you with a text file that looks a lot like the sample input above.</p><h3>Lets Solve It</h3><p>Github: <a href="https://github.com/JeremyDwayne/advent_of_code/tree/main/2023/day1">View my solution</a></p><p>My initial thought process when reading the question is that I&#8217;ll need to do a few things.</p><ol><li><p>Read a file</p></li><li><p>Parse each character of each line of that file</p></li><li><p>Find the first digit and last digit for each line, combine them for a 2-digit code for that line</p></li><li><p>Calculate a sum as we go, and output it at the end</p></li></ol><h4>Read a File</h4><p>I have no clue how to read a file in Go or how to read each line, so we&#8217;re already learning something new. I&#8217;m assuming I&#8217;ll probably have to use the <code>os</code> package as I believe that&#8217;s used for operating system actions. Reading a file falls under that category.</p><p>Looking up <a href="https://pkg.go.dev/os">the docs</a> I see there are a few methods for reading a file, <code>Read</code> and <code>Open</code>. I&#8217;ll put a pin in that because I don&#8217;t see something like ReadLine as an option. So for now I&#8217;m going to look into bullet 2, how to read each line of a file.</p><h4>Read Lines of a file</h4><p>Typically when wanting to read through a file you use a buffer. When I search for this I see there is a package for go called <code>bufio</code>. I see a few familiar options like <code>Read</code> and <code>ReadLine</code>. Read doesn&#8217;t seem to be what I&#8217;m looking for, and ReadLine recommends using <code>ReadString</code> or to use a <code>Scanner</code>. Since ReadString also recommends using a Scanner for simplicity, I&#8217;ll go ahead and use that.</p><p><code>Scanner</code> has an example for reading lines, so let&#8217;s take a look at that.</p><pre><code>func main(){
 scanner := bufio.NewScanner(os.Stdin)
 for scanner.Scan() {
 fmt.Println(scanner.Text()) // Println will add back the final '\n'
 }
 if err := scanner.Err(); err != nil {
 fmt.Fprintln(os.Stderr, "reading standard input:", err)
 }
}
</code></pre><p>It seems all we need to do is pass the file pointer to a <code>bufio.NewScanner</code> and then we can <code>scanner.Scan()</code> each line of the file, and pull out that line with <code>scanner.Text()</code>. This is great because it also answers bullet one of which file option we should use, <code>Open</code> to get a pointer to that file.</p><p><em>Note: I don&#8217;t know if it&#8217;s called a pointer to a file in go, that&#8217;s just my recollection of how things work in c/c++</em></p><h4>Parse The line</h4><p>Now that we have each line of the file, we need to find the first and last digits of that line.</p><p>Following, and modifying, their example <code>pqr3s1234tu8vwx</code> 3 and 8 are the first and last digits, which we then need to combine to 38 to be the code for that line.</p><p>The combination of digits means we need to treat them as characters and not integers, but we need to detect that they are integers. In ruby you can do something like <code>.to_i</code> so I looked for the equivalent in go and there is a <code>strcov</code> package with a <code>ParseInt</code> and an <code>Atoi</code> function. The Atoi function seems easier to use so we&#8217;ll go with that.</p><p>We&#8217;ll keep track of the first and last digits and loop through each character of the line. If we find an integer we&#8217;ll set both the first and last variables to that value. If the <code>first</code> variable isn&#8217;t empty we&#8217;ll only set the last variable.</p><p>Once we&#8217;ve made it to the end of the line we&#8217;ll combine those two strings and convert them to an integer, then add them to the running total being tracked by <code>sum</code>.</p><h3>My solution</h3><p>If I take all of the above and slap it together, I get the following code. I&#8217;m just printing out the results for debugging purposes, and because all we care about is getting that final sum value. If this was code that was part of a larger system we would return the sum so that it could be used elsewhere in our codebase.</p><pre><code>package main

import (
 "bufio"
 "fmt"
 "os"
 "strconv"
)

func main() {
 file, err := os.Open("../input.txt")
 if err != nil {
 panic(err)
 }
 defer file.Close()

 scanner := bufio.NewScanner(file)

 sum := 0
 for scanner.Scan() {
 first := ""
 last := ""
 for _, char := range scanner.Text() {
 if _, err := strconv.Atoi(string(char)); err == nil {
 if first == "" {
 first = string(char)
 }
 last = string(char)
 }
 }
 if value, err := strconv.Atoi(first + last); err == nil {
 sum += value
 }
 fmt.Printf("%s + %s = %s\n", first, last, first+last)
 }
 fmt.Println("--------------------")
 fmt.Println("Sum: ", sum)
}
</code></pre><p>Output:</p><pre><code>...
7 + 1 = 71
4 + 7 = 47
7 + 7 = 77
7 + 8 = 78
3 + 8 = 38
--------------------
Sum: 55834
</code></pre><h3>Conclusion</h3><p>This was a rather fun exercise. I learned about files, buffers, string conversion, and type-casting. I looked into Part 2 a little, and it&#8217;s not something I want to work on at this time. I may come back and update it later on. What is interesting about it, is that I would learn more about how go uses hashmaps.</p><p>Off to a great start! I look forward to solving Day 2 next!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/p/advent-of-code-2023-day-1?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/p/advent-of-code-2023-day-1?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Advent of Code 2023 - Introduction]]></title><description><![CDATA[I&#8217;m using Advent of Code this year to expand my knowledge of the Go programming language]]></description><link>https://www.jeremywinterberg.com/p/advent-of-code-2023-introduction</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/advent-of-code-2023-introduction</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Sat, 09 Dec 2023 02:42:49 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="3178" height="4768" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:4768,&quot;width&quot;:3178,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;green christmas tree with string lights&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="green christmas tree with string lights" title="green christmas tree with string lights" srcset="https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1612979168796-bcae1575b8c5?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjaHJpc3RtYXMlMjB0cmVlfGVufDB8fHx8MTcwNzY2Nzk4N3ww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><p>I&#8217;m a little late to the party as I&#8217;m starting on the 8th of December instead of the 1st, but I&#8217;ll catch up.</p><p>I&#8217;m using Advent of Code this year to expand my knowledge of the Go programming language. So, my goal is to solve at least the first part of each day and document my solution on the blog. I&#8217;ll go over anything that I need to look up and what I&#8217;ve learned.</p><h2>I need a break from Ruby</h2><p>For the last 8 years, I&#8217;ve felt a little stuck in a niche, ruby and ruby on rails. While ruby is an excellent language, and rails is an excellent framework, it is in decline. The number of jobs out there is dwindling, and in general, the industry is moving away from it to more performant frameworks or those that allow for faster iteration.</p><p>There are plenty of examples of companies scaling and doing very well with ruby. That is not my point. I&#8217;ve been searching for work casually for the last 6 months, and actively for the last 2 months. I was laid off in November and am struggling to find work in the ruby space. Some recruiters are reaching out, and I&#8217;ve applied to a few positions directly, however, the ruby marketplace is nowhere near as vast as it was 2 to 5 years ago.</p><p>There is an alternate problem at work here: tech layoffs are abundant this year. Just this week two tech giants, Spotify and Twilio, laid off massive portions of their workforce. So there is yet another giant influx of talent on the market that is incredibly difficult to compete with. I was watching an interview with a director at a tech company who is involved with hiring for their company. They said for any given position they have 1,000-5,000 applicants. Yes, I wrote that correctly.. OVER A THOUSAND APPLICANTS FOR ONE ROLE!</p><p>You have to do everything you can to stand out. And when you&#8217;re working in a language and framework on the decline it&#8217;s even harder to find work when those companies are willing to hire anyone, not just someone with that niche experience.</p><h2>Why Go?</h2><p>I think the interesting thing about Go is that it can be used for so many different applications. Most notably it&#8217;s been attributed to being extremely well-suited to web applications. So I can start by building for the web and then down the road be able to transition to some other area that writes software with go be it a native application or CLI tooling, etc.</p><p>I recently started building out a side project which is using go for the backend API. However, one thing I&#8217;ve noticed is that building a web server in go is rather simple. I haven&#8217;t had to explore more complex aspects of coding practices yet, so enter coding challenges.</p><p>Instead of the basic LeetCode route, I&#8217;m going to kick this off using the Advent of Code challenges since it&#8217;s currently relevant and fun to participate in.</p><p>The one thing that I do plan on doing going forward is keeping up with regular blog posts to document my learning as well as my job-hunting progress. If you know anyone hiring a senior software engineer I&#8217;d love to connect and talk to them. I will accept and use all the help I can get during this process.</p><h2>AoC Warning: SPOILERS INCLUDED!</h2><p>If you want to solve the advent of code challenges, solve them yourself then come back and read my post! I&#8217;m not going to paste the problem or input here, however, I will post the summarized question and then link to the AoC page each day for you to solve it yourself.</p><p>The first 8-9 days of AoC will be spammed back to back until I&#8217;m caught up. Once caught up I&#8217;ll go to a daily post schedule throughout December.</p><p>My goal isn&#8217;t necessarily to go for the most optimal solution. I will try to do so where possible. My only goal is to work through these problems daily and learn more about go. If I have to do an incredibly naive solution to figure it out, so be it.</p><p>If you&#8217;re ready to jump into things, the next post will be for day 1 of the challenges! Advent of Code - Day 1</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/p/advent-of-code-2023-introduction?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/p/advent-of-code-2023-introduction?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Threads And Queues In Ruby]]></title><description><![CDATA[Should your code be written with threads, or should you rely on asynchronous job execution systems like Sidekiq?]]></description><link>https://www.jeremywinterberg.com/p/threads_and_queues_in_ruby</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/threads_and_queues_in_ruby</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Tue, 03 Jan 2023 08:12:44 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="5355" height="4016" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:4016,&quot;width&quot;:5355,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;three men sitting while using laptops and watching man beside whiteboard&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="three men sitting while using laptops and watching man beside whiteboard" title="three men sitting while using laptops and watching man beside whiteboard" srcset="https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1557804506-669a67965ba0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwxfHxjb25jdXJyZW5jeXxlbnwwfHx8fDE3MDc2NjY0NjZ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><h2>Technical Interviews Are Hard</h2><p>I recently tried solving a coding challenge that required concurrent processing of data. This is something I&#8217;ve honestly never done before in code. At work, almost everything is event driven, and tasks that do need to be done asynchronously or concurrently have been done through systems like Sidekiq, Redis or message queues like Kafka.</p><p>I want to introduce the problem to you, go over my solution, and describe my thought process along the way.. as best I can. I&#8217;m in no way trying to even claim I solved the problem correctly, or used Threads and Queues in the way they&#8217;re intended. What I can do, however, is document what I did and continue to learn and grow from here.</p><p>I found this to be incredibly engaging for me, because it was a new concept that I hadn&#8217;t attempted to write code for before.</p><h2>The Problem</h2><p>A user&#8217;s identity is flagged, and they must meet with a support rep to validate they are who they say they are. Design a system that ingests the users, assigns a support rep to the case, and validates their identity.</p><h3>Requirements</h3><ol><li><p>A new user will be added to the queue every 2 seconds</p></li><li><p>An identity will be verified after 4 seconds</p></li><li><p>A support rep can only work on one validation at a time.</p></li></ol><h3>Expected Output</h3><ol><li><p><code>User &lt;ID&gt; has been verified and removed from the queue</code></p></li><li><p>Metrics to demonstrate the progress of the queue.</p></li></ol><h3>Provided data</h3><pre><code>users = [
 { id: 1 },
 { id: 2 },
 { id: 3 },
 { id: 4 },
 { id: 5 },
 { id: 6 },
 { id: 7 },
 { id: 8 },
 { id: 9 },
 { id: 10 }
]

support_reps = [
 { id: 1 },
 { id: 2 },
 { id: 3 },
 { id: 4 }
]
</code></pre><h2>The Attempted Solution</h2><p>Since we&#8217;re building out a queue data structure, we can use the Queue class that Ruby provides. The alternative approach, and what I used initially, is to use an array as a basic queue.</p><p>Something like this technically works, but is a basic approach and isn&#8217;t as straightforward to process in parallel.</p><pre><code>users = []
users.push({ id: 1})
users.shift
</code></pre><p>Once I remembered there actually is a standard Queue class, I noticed that it intrinsically supports Threads. Threads are how I plan on processing multiple users simultaneously.</p><pre><code>class VerificationQueue
 attr_reader :users, :support_reps

 def initialize
 @users = Queue.new
 @support_reps = []
 end

 def verify_users
 workers = support_reps.size.times.map do
 Thread.new do
 begin
 while user = users.pop
 support_rep = available_support_rep
 if support_rep &amp;&amp; user
 support_rep.update_status('busy')
 session = VerificationSession.new(user, support_rep)
 self.to_s
 until(session.verified?)
 end
 support_rep.update_status('available')
 puts "User #{user[:id]} has been verified and removed from the queue"
 puts session.to_s
 end
 end
 rescue ThreadError
 end
 end
 end

 workers.map(&amp;:join)
 end

 def available_support_rep
 support_reps.each do |ref|
 next if ref.status == 'busy'
 return ref
 end
 end

 def add_user(user)
 users.push(user)
 puts "User #{user[:id]} added to the queue."
 end

 def add_support_rep(support_rep)
 support_reps.push(support_rep)
 puts "support_rep #{support_rep.id} has started working."
 end

 def to_s
 puts "==== Queue Status ===="
 puts "Users still in queue: #{users.size}"
 puts "support_reps"
 puts support_reps
 puts "======================"
end
</code></pre><p>I spin up a new thread for each support rep, so the code can verify the users simultaneously. When each support rep becomes available again, it picks up the next user in the queue.</p><p>The algorithm I used to select an available support rep isn&#8217;t elegant. It just loops through the reps and chooses the next available. If I really cared about work-life balance I would implement some sort of weighted priority system that could determine how much work each rep had taken on recently.</p><p>The verification process is managed through a VerificationSession. Due to the simplicity of the challenge, it just tracks the time elapsed and completes after 4 seconds. In a real implementation you would trigger whatever logic would be necessary to verify the identity of a user.</p><pre><code>class VerificationSession
 TIME_COMPLETED = 4.0

 attr_reader :user, :support_rep, :start_time

 def initialize(user, support_rep)
 @user = user
 @support_rep = support_rep
 @start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
 end

 def elapsed_time
 end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
 end_time - start_time
 end

 def verified?
 elapsed_time &gt;= TIME_COMPLETED
 end

 def to_s
 "VerificationSession: User: #{user[:id]} Rep: #{support_rep} Elapsed: #{elapsed_time.round(4)}"
 end
end
</code></pre><p>There&#8217;s a couple of approaches we can take to build out our SupportRep objects. The first that came to mind was creating a class which would allow future expansion of functionality. The more simplistic route would be to create a Struct. What I struggle with in these coding challenges is the trade-offs between expressing good design and keeping the solution short and sweet.</p><p>So first is the more traditional class route that I actually wrote, followed by how I think I would approach this in the future with a Struct.</p><pre><code>class SupportRep
 attr_reader :id, :status

 def initialize(id, status = 'available')
 @id = id
 @status = status
 end

 def update_status(status)
 @status = status
 end

 def to_s
 "id: #{id}, status: #{status}"
 end
end
</code></pre><p>Here&#8217;s an example of how I might do it with a Struct.</p><pre><code>SupportRep = Struct.new(:id, :status)

queue = VerificationQueue.new

for id in 1..4 do
 support_rep = SupportRep.new(id, 'available')
 queue.add_support_rep(support_rep)
end

# Then when I need to change the status I could just do
support_rep.status = 'busy'
</code></pre><p>Exploring the alternate Struct method is for another time. For now let&#8217;s try to run it with the code as is using classes.</p><h3>Let&#8217;s Try To Run It!</h3><p>Here is some simple code to build up the data we need to run this. In order to simulate a new user being added every 2 seconds, I also am using threads to start the validation queue and then add users to it.</p><pre><code>users = [
 { id: 1 },
 { id: 2 },
 { id: 3 },
 { id: 4 },
 { id: 5 },
 { id: 6 },
 { id: 7 },
 { id: 8 },
 { id: 9 },
 { id: 10 }
]

support_reps = [
 { id: 1 },
 { id: 2 },
 { id: 3 },
 { id: 4 }
]

start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
queue = VerificationQueue.new

support_reps.map do |ref|
 support_rep = SupportRep.new(ref[:id])
 queue.add_support_rep(support_rep)
end

threads = []

queue.add_user(users.shift)

threads &lt;&lt; Thread.new do
 begin
 queue.verify_users
 rescue ThreadError
 end
end

threads &lt;&lt; Thread.new do
 begin
 while user = users.shift
 start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
 until(elapsed_time(start_time) &gt;= 2.0)
 end
 queue.add_user(user)
 end
 rescue ThreadError
 end
end

threads.map { |thread| thread.join(10) }
queue.to_s


def elapsed_time(start_time)
 end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
 end_time - start_time
end
puts "/nElapsed Time: #{elapsed_time(start_time).round(4)}"
</code></pre><p>The output is a bit messy, but you can get the gist of it. It processes 10 users in 19 seconds, each user taking 4 seconds. Without using threads, this would&#8217;ve taken a minimum of 40 seconds. Add more support reps and it takes even less time.</p><pre><code>&#10095; ruby threads.rb
support_rep 1 has started working.
support_rep 2 has started working.
support_rep 3 has started working.
support_rep 4 has started working.
User 1 added to the queue.
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: available
id: 3, status: available
id: 4, status: available
======================
User 2 added to the queue.
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: busy
id: 3, status: available
id: 4, status: available
======================
User 1 has been verified and removed from the queue
VerificationSession: User: 1 Rep: id: 1, status: available Elapsed: 4.0
User 3 added to the queue.
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: busy
id: 3, status: available
id: 4, status: available
======================
User 4 added to the queue.
User 2 has been verified and removed from the queue
VerificationSession: User: 2 Rep: id: 2, status: available Elapsed: 4.0
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: busy
id: 3, status: available
id: 4, status: available
======================
User 5 added to the queue.
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: busy
id: 3, status: available
id: 4, status: available
======================
User 3 has been verified and removed from the queue
VerificationSession: User: 3 Rep: id: 1, status: busy Elapsed: 4.6134
User 4 has been verified and removed from the queue
VerificationSession: User: 4 Rep: id: 2, status: busy Elapsed: 4.289
User 6 added to the queue.
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: busy
id: 3, status: available
id: 4, status: available
======================
User 5 has been verified and removed from the queue
VerificationSession: User: 5 Rep: id: 1, status: available Elapsed: 4.2006
User 7 added to the queue.
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: busy
id: 3, status: available
id: 4, status: available
======================
User 6 has been verified and removed from the queue
VerificationSession: User: 6 Rep: id: 2, status: available Elapsed: 4.0884
User 8 added to the queue.
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: busy
id: 3, status: available
id: 4, status: available
======================
User 7 has been verified and removed from the queue
VerificationSession: User: 7 Rep: id: 1, status: available Elapsed: 4.0001
User 9 added to the queue.
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: busy
id: 3, status: available
id: 4, status: available
======================
User 8 has been verified and removed from the queue
VerificationSession: User: 8 Rep: id: 2, status: available Elapsed: 4.0943
User 10 added to the queue.
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: busy
id: 3, status: available
id: 4, status: available
======================
==== Queue Status ====
Users still in queue: 0
support_reps
id: 1, status: busy
id: 2, status: busy
id: 3, status: available
id: 4, status: available
======================
Elapsed Time: 19.3081
</code></pre><h2>Recap</h2><p>Threads are still something I&#8217;m learning how to best utilize. But this was a very engaging coding challenge.</p><p>I want to do more of these exercises regularly. They introduce me to new concepts and push me to be a better engineer. All I want is to grow my skills, both technical leadership and coding.</p><p>Hopefully along the way I can improve on how I am able to articulate how I solved the problem.. This blog post is a mess, but its better than never posting anything.</p><p>Happy New Year, and I wish you all the best in 2023.</p><p>Jeremy</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/p/threads_and_queues_in_ruby?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/p/threads_and_queues_in_ruby?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[I'm a staff software engineer now?]]></title><description><![CDATA[Two promotions in 8 months, but at what cost?]]></description><link>https://www.jeremywinterberg.com/p/two-promotions-in-8-months</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/two-promotions-in-8-months</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Fri, 08 Jul 2022 01:11:46 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="6016" height="4016" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:4016,&quot;width&quot;:6016,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;two people shaking hands&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="two people shaking hands" title="two people shaking hands" srcset="https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwcm9tb3Rpb258ZW58MHx8fHwxNzA3NjY2MjQzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><h2>Two Promotions In 8 Months??</h2><p>I&#8217;m probably just as shocked as you are reading that title. I still can&#8217;t believe I&#8217;ve received two promotions in the past 8 months. I had intended to do a number of posts on what I was learning and the progress of my career into a staff+ role.. But I&#8217;ve already made it. So instead I&#8217;m going to talk about the last 8 months, what I&#8217;ve been up to since my last post, and what my goals are going forward.</p><h2>What happened?</h2><p>I&#8217;ve been extremely busy with my new job. I quickly became a top performer on my team and kept taking on new challenges. I&#8217;m now on a new team, and I am contributing to several high priority efforts aiming to improve our systems and engineering practices across the board.</p><h3>My original role and how I got the first promotion</h3><p>I was hired as a software engineer on the tier 3 support team to provide expert knowledge and solutions for production incidents. This wasn&#8217;t my ideal role, as I wouldn&#8217;t be writing features and mostly providing operations support. But I was promised we would be creating internal tooling and that eventually coding would be a factor.</p><p>No system gets deployed without bugs, which is why tier 3 support teams like this exist. Some companies do a rotation within engineering, some have dedicated headcount for it like my company does.</p><p>In addition to the &#8216;day to day&#8217; problems cusomers experienced, I was heavily involved with every single incident that came in. From sev 4 incidents that only affected a small portion of customers, to sev 1 outages, which affected everyone. I made a concious effort to be a part of every incident, no matter how late it was, or if it was over the weekend. This insight into what issues our system has, getting to a root cause, and finding a solution, allowed me to amass a considerable amount of knowledge into the product we offer.</p><p>It has led to just about everyone in engineering, product and leadership coming to me with questions about how something works, or for my opinon on how to improve things. This knowledge provided visibility into who I was, and what value I bring, across the entire company. That visibility and knowledge gave me leverage to ask for my first promotion to senior software engineer back in February.</p><p>I had felt that I was incorrectly leveled when I was hired, so pushing for the promotion to senior was a high priority for me. When a coworker of mine left the company, I felt the timing was right to make the ask, and it paid off. Leadership agreed and gave me the promotion to senior.</p><h3>Why did I change teams?</h3><p>A few months passed after my promotion and things were going well. I implimented new procedures and setup communication boundaries with stakeholders, which made things more efficient for the team. We also hired some new folks and were placed under the care of a new director. The additions to the team took a lot off my plate, thus allowing me to focus on more challenging issues. So I finally was able to start planning for the internal tooling I was promised around 6 months prior.</p><p>After creating some initial PRD and STOP proposals engineering leadership recognized the importance of the project and agreed to greenlight it. However, they took it up a knotch and decided I needed to have my own team to focus entirely on this project. Seemingly overnight I was swapped over to a new engineering team who were being pulled off a different project to work on my proposed project.</p><p>I&#8217;ve been with this new team for around 2 months now, and we&#8217;re about to deploy the MVP to production in a week. I couldn&#8217;t be happier with what we have accomplished, and I am proud to work alongside talented people.</p><h3>The coveted promotion to Staff Software Engineer</h3><p>Shortly after this new project started, a series of events led to my workload being increased dramatically. I was asked to fix platform wide issues and take a large role in our efforts to migrate off our current hosting platform to AWS.</p><p>This increase in responsibility in addition to the existing major project I was involved in prompted me to start inquiring about career advancement yet again. My intentions were only to develop a roadmap for how to move towards the promotion. What standards of work was expected, what kind of projects I need to participate in, what technical design and leadership I needed to display, etc..</p><p>I had a few conversations about this with my engineering manager without much progress towards building such a plan. He promised to look into it, so I patiently waited. Then during a one on one meeting he said,</p><blockquote><p>&#8220;Congratulations, you&#8217;re being promoted to Staff effective immediately.&#8221;</p></blockquote><p>The news completely came out of nowhere. I wasn&#8217;t expecting the promotion till sometime next year at the earliest, let alone a few months after my promotion to senior. So, I guess I&#8217;ve made it. This was my long term goal.</p><h3>What advice do I have for those seeking a promotion</h3><p>This probably should be its own blog post, but I&#8217;ll give you the basic strategy I used. I&#8217;m not sure if this is the way everyone should approach it, but it certainly worked for me.</p><ol><li><p>Care about your coworkers</p></li><li><p>Care about the work you output</p></li><li><p>Have a strong work ethic &#8211; get shit done.</p></li><li><p>Gain visibility through inserting yourself into key situations</p></li><li><p>Make it known to leadership that you want to grow to the next level</p></li><li><p>Take advantage of opportunities that are presented to you</p></li></ol><h2>What&#8217;s next?</h2><p>Well.. the goal now is to become the strongest software engineer I can become. Grow my skills, grow my peers, ship solid code, and try to live up to the title bestowed apon me.</p><p>I do feel slightly trapped because of this promotion. I don&#8217;t believe I would be able to interview at another company of similar or larger size and be leveled at staff. So my goals are to free myself of imposter syndrome yet again and be able to go anywhere.</p><p>I like the company I work at, but I know I won&#8217;t work here forever. Being able to work without feeling trapped is quite liberating, and I wish to return to that state soon. So, I plan on leveling up myself while documenting what I can here on my blog.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/p/two-promotions-in-8-months?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/p/two-promotions-in-8-months?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[How I Doubled My Income, and My 2021-Year Review]]></title><description><![CDATA[I Bought a House before 30!]]></description><link>https://www.jeremywinterberg.com/p/how-i-doubled-my-income-and-2021-year-review</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/how-i-doubled-my-income-and-2021-year-review</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Wed, 22 Dec 2021 05:38:00 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="5616" height="3744" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3744,&quot;width&quot;:5616,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;fan of 100 U.S. dollar banknotes&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="fan of 100 U.S. dollar banknotes" title="fan of 100 U.S. dollar banknotes" srcset="https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1553729459-efe14ef6055d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxpbmNvbWV8ZW58MHx8fHwxNzA3NjY2MTc2fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><h2>I Bought a House before 30!</h2><p>The last several years has been a bit rough for me. I had been living with my parents for many years. At first, I was taking care of my grandfather as his primary caregiver, then as I went back to college for Computer Science, and then continued after graduating as I job hunted, did freelance gigs, and got my first &#8220;real job&#8221; in industry. I didn&#8217;t have a lot of money, and my income was sporadic at best. My parents welcomed the help around the house, and I didn&#8217;t mind it. They&#8217;re approaching the retirement age and any bit I can help them makes their lives much easier.</p><p>Now, because they&#8217;re approaching the retirement age, they decided they wanted to move to Florida. They had been talking about it for a while, but it was always a &#8220;maybe in 5 years&#8221; plan. In the middle of 2020 and the insanely rough beginnings of the Covid-19 pandemic, they decided to go through with those plans and started designing a house to retire in in Florida.</p><p>They bought land, signed off on all the blueprints and broke ground on construction. (this was a very long process, of which I&#8217;m very tired of hearing about and won&#8217;t bore you with the details)</p><p>So this left me with 2 choices. Move into an apartment either in my town or to a larger city (Seattle or Minneapolis were the top 2 on my lists), or buy my parents&#8217; home and not have to move at all. Since my job at the time was local, and I wasn&#8217;t making that bad of money for my area, I decided to stay and buy the house.</p><p>So, I own a home now!</p><p>I&#8217;m slowly making upgrades and making everything a smart device or IOT where it makes sense. I highly recommend doing lights, doorbell video, and thermostat at least. In August 2020 I built a home garage gym, then promptly never used it (2022 goal is to actively use it). The next major upgrade I plan on doing will be rewiring the house with cat-6 ethernet and ubiquiti networking gear.</p><h2>I Bought a Car!</h2><p>I had been sharing a car with my dad since like 2012. I got better gas mileage, and he drove across the state for work, so it just worked out well for him to use my car, and I use his pickup. But, my car that used to run well, turned into a junker with 200k miles with how much he drove it every day. When my dad took a new job down in Florida, preparing for the eventual move, I decided to sell the old car and buy a new one.</p><p>My 2011 Chevy Impala, with 200k miles, sold for over $4k! Thank you Covid-19 used car prices. The dealerships I talked to didn&#8217;t even want to give me $1k trade-in.</p><p>Initially I wanted a Tesla, I was dead set on getting a Model Y. But then I started hearing about corners being cut because of parts shortages, and there was a 3-4 month waiting period for production. So I decided I&#8217;d skip Tesla for now, and maybe try again the next time I&#8217;m in the market for a car.</p><p>I still wanted to be eco-friendly and considered two routes: Hybrid vs Other Brands&#8217; Electric Vehicles; the Chevy volts of the world for example. After thinking really hard on it, I decided to skip the EV route for now and go for a hybrid. I really want to kit out my house with a Tesla Powerwall, and solarpanels (need to do research on snow and performance in Wisconsin) before I buy an EV. That way I can set up a proper charging station in the garage for the car at the same time. And I just can&#8217;t afford that now. Maybe in 5-10 years that project will be more feasible. I need to pay off my student loans first!</p><p>I ended up going with a 2021 Toyota Venza Hybrid. I wanted a Toyota Rav 4 Hybrid, but it would&#8217;ve been 4-6 months to get one. They&#8217;re high in demand, and with the parts shortages production was only going to be delayed further. If I didn&#8217;t take the Venza offered to me, they had a buyer lined up to call right after me. I know that typically would be considered a sales tactic, but in this case I believe them. There were 4 cars I was wanting to TEST DRIVE to see if I liked the car, and they were sold before they even arrived at the dealership. I had to test drive a Venza that belonged to someone who worked at the dealership!</p><p>I&#8217;ve had it since August, and really like it a lot. It has enough smart features that it feels like a luxury car, and it gets great gas mileage at 30-40 mpg if you drive efficiently.</p><h2>I turned 30!</h2><p>A few weeks after buying the Venza I celebrated my 30th birthday! My mom flew in to visit, and we went to see Shang-Chi at the movie theater. I don&#8217;t have much else to say here other than I feel old now but at least I live alone and own a house.</p><h2>I Bought a New BED!!</h2><p>Ok, this is the one I&#8217;m the MOST excited for because it has direct impact on everything I do (sleep is important yo). I finally replaced my mattress that has a distinct Jeremy shaped dent in it. For those curious, I went with a <a href="https://www.saatva.com/mattresses/saatva-classic">Saatva Classic Matress</a> in Luxury Firm. It&#8217;s a bit stiffer than I&#8217;m used to, but after a few nights I started getting used to it.</p><p>But it gets better than that. I also bought the <a href="https://www.saatva.com/bases/lineal-adjustable-base">Saatva Lineal Adjustable Base</a>, which was &#128175;% worth it! I can adjust the bed how I want for watching tv and to be in a comfy position for sleeping.</p><h2>I Changed Jobs and Doubled My Income!??</h2><p>That&#8217;s right, this is NOT click bait! I actually doubled my income. And you can too with this easy trick!</p><p><em>Get a new job at a company that pays market value and provides benefits.</em></p><p>There&#8217;s not really a trick, just interview a lot and eventually get a higher paying job (I will talk about interviewing tips in another post sometime). I went from being severely underpaid without any benefits to being properly compensated with a great salary and actual benefits. It just happened to be over double what I was making previously.</p><p>This is partially thanks to the Great Resignation that came with Covid-19. Senior software engineers across the industry left their jobs due to Covid-19 and burnout. This caused a HUGE increase in companies trying to hire software engineers, which led to big bumps in base pay due to the shortage of experienced SE&#8217;s on the market. If you&#8217;re making less than 100k-200k (depending on experience) anywhere in the country as a software engineer, leave your job and find a new one.</p><p>To give you an example of the market need. Every single day I would get a message from 5-10 different recruiters trying to get me. Most of them were also recruiting for roles at multiple companies. Without any of my profiles being set to looking for work. I was &#8220;off the market&#8221; and getting SPAMMED, by small and large well known companies trying to hire senior&#8217;ish level SE&#8217;s.</p><p>I accepted an offer from a fintech infrastructure startup that&#8217;s well known in the industry. For now, I won&#8217;t name them, but I really am enjoying working there and will hapily talk to people about it in private if you&#8217;re interested. I moved from a &#8220;startup&#8221; with 17 employees, to one with over 300 employees. Boy what a difference!</p><p>There are a few things that this gave me:</p><ol><li><p>I&#8217;m finally working at a company that does its best to follow industry standards and best practices. This is teaching me skills I&#8217;ve been begging to develop for years but never worked at a place large enough.</p></li><li><p>I learned that money isn&#8217;t everything, but when you&#8217;re paid under the market rate, you feel like you&#8217;re not valued, and the quality of my work suffered. Being properly compensated has made me feel confident in my abilities and that I belong in this industry. I look forward to logging in for work every day.</p></li><li><p>I&#8217;m happier. I&#8217;m not stressed about money, if I have health insurance still, or if I&#8217;ll get my next paycheck on time. I like the people I work with, I respect them, and I am learning from them.</p></li><li><p>I want to grow my career down the Individual Contributor path and land in a staff/principal software engineer role someday. Before I thought management might be the right route, but now I know I just want to be a solid engineer.</p></li></ol><p>I have a long ways to go, and plenty of time to get there. I went from thinking I was senior level at a small startup to realizing I&#8217;m still probably considered mid-level. But that&#8217;s ok, it just means I have more room to grow.</p><p>I have renewed excitement for growing my skills again. Which is why I&#8217;m starting to blog again.</p><p>Last time I got hung up on the blog infrastructure so this time it&#8217;s just a simple Hugo blog, with a pre-made theme, hosted on Netlify. I&#8217;m done with the Digital Ocean Droplet VPS, self-managed, and not optomized websites. I went with static site generator like Hugo because I dont need a CMS like WordPress. I was overthinking the setup and got turned off on actually writing the content.</p><p>Expect lots of posts to come about the things I&#8217;m learning. I&#8217;m still trying to determine a posting schedule that works for me, but for now we&#8217;ll see you soon!</p><p>Cheers, Jeremy</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/p/how-i-doubled-my-income-and-2021-year-review?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/p/how-i-doubled-my-income-and-2021-year-review?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Making the Best of an Old School Dev Environment]]></title><description><![CDATA[No Local Dev Environment??]]></description><link>https://www.jeremywinterberg.com/p/making-the-best-of-an-old-school-dev-environment</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/making-the-best-of-an-old-school-dev-environment</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Fri, 26 Feb 2021 04:58:04 GMT</pubDate><enclosure url="https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="7500" height="11000" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:11000,&quot;width&quot;:7500,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;black Fayorit typewriter with printer paper&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="black Fayorit typewriter with printer paper" title="black Fayorit typewriter with printer paper" srcset="https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/reserve/LJIZlzHgQ7WPSh5KVTCB_Typewriter.jpg?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHw0fHxvbGQlMjBzZXJ2ZXIlMjB0ZXJtaW5hbHxlbnwwfHx8fDE3MDc2NjYxMDJ8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><h2>No Local Dev Environment??</h2><p>At the company I (used to) work at, we write code off our remote server without setting up a local environment. Finding the best remote dev environment has been a journey for me. The extension FTP Simple has worked well so far, but it has some draw backs.</p><p>You need to verify that the new version of the file downloaded off the server, and when you save that it actually uploaded. Otherwise you might overwrite something accidentally. It can be a little slow if its downloading a large file Sometimes if you refresh the browser faster than the file saved you&#8217;ll get a fatal error</p><h3>What&#8217;s the solution?</h3><p>Running VS Code through Remote SSH. This setup allows you to use tools that require the full scope of the project&#8217;s files.</p><p>You can now access all of the Git tools/extensions vs code has instead of doing it through the web interface. Robust extensions like PHP Intelephense work completely. We can start writing and running automated testing suites with tools like phpunit/selenium etc.. The biggest takeaway that I got from this switch, is that it feels like I&#8217;m working in a local dev environment again. Which makes me very happy. The following guide was written for my co-workers, but I decided to strip out specifics to share on the blog.</p><h4>Required Extensions:</h4><p>Name: Remote &#8211; SSH</p><p>Description: Open any folder on a remote machine using SSH and take advantage of VS Code&#8217;s full feature set. VS Marketplace Link: <a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh">https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh</a> Name: Remote &#8211; SSH: Editing Configuration Files</p><p>Description: Edit SSH configuration files VS Marketplace Link: <a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh-edit">https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh-edit</a> Recommended Extensions For PHP Testing:</p><p>Ignore if you don&#8217;t write php</p><p>Name: PHPUnit</p><p>Description: Run PHPUnit tests from VSCode. VS Marketplace Link: <a href="https://marketplace.visualstudio.com/items?itemName=emallin.phpunit">https://marketplace.visualstudio.com/items?itemName=emallin.phpunit</a> Name: PHPUnit Watcher</p><p>Description: Run PHPUnit on file changes VS Marketplace Link: <a href="https://marketplace.visualstudio.com/items?itemName=HerisIT.phpunit-watcher">https://marketplace.visualstudio.com/items?itemName=HerisIT.phpunit-watcher</a></p><h2>Steps for Setup</h2><ol><li><p>Generate an SSH Key on your local machine.</p></li></ol><ul><li><p>Follow the steps there for checking existing keys, generating a new key, adding it to the SSH Agent, and copying it to github.</p></li><li><p><a href="https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh">https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh</a></p></li></ul><ol start="2"><li><p>Add the SSH Key to the server.</p></li></ol><ul><li><p>You should have an account on the server, if you aren&#8217;t sure, speak to your server administrator.</p><ul><li><p>The FTP account used in FTP-Simple should work for ssh as well</p></li><li><p>However, currently you probably only have password access. You will need that password!</p></li></ul></li><li><p>run the command ssh-copy-id @</p><ul><li><p>This will prompt you for your password, enter it.</p></li></ul></li><li><p>You should be able to SSH to the server without a password now!</p><ul><li><p>test this by doing ssh @, if it doesn&#8217;t prompt for a password you&#8217;re set.</p></li></ul></li></ul><ol start="3"><li><p>In VS Code, with the Remote SSH extension installed, bring up your command pallette (ctrl/cmd + shift + p)</p></li></ol><ul><li><p>type in Remote-SSH and open configuration file, this should be at ~/.ssh/config or somewhere similar</p></li><li><p>enter the following config, replacing the values with your own.</p></li></ul><pre><code>Host &lt;devsite&gt;
User &lt;ssh account&gt;
HostName &lt;devsite url&gt;
Port 22
</code></pre><ol start="4"><li><p>In VS Code, with the Remote SSH extension installed, bring up your command pallette (ctrl/cmd + shift + p)</p></li></ol><ul><li><p>This time you&#8217;re going to type Remote-SSH and select connect to host</p></li><li><p>Select the Host you created in the ssh config</p></li></ul><ol start="5"><li><p>You should now be connecting to the server over SSH.</p></li><li><p>Extensions may need to be reinstalled on the SSH host, I know I did</p></li></ol><ul><li><p>I believe its due to them installing various dependencies to run.</p></li></ul><ol start="7"><li><p>I also recommend opening your remote project directory, then saving the workspace locally on your computer. Then when you open vs code you can instantly go to that folder on the server in the future with ease.</p></li></ol><ul><li><p>Saving on the server was causing me issues.</p></li></ul><h2>Conclusion</h2><p>I hope this helps someone get away from the clutches of FTP! I&#8217;ve been struggling with how to work remotely ever since I joined my company almost 2 years ago. This is finally the best dev environment I&#8217;ve come up with and am happy about. It feels like I&#8217;m working locally again!</p><p>I&#8217;m sure this guide will need many tweaks and adjustments. If you have an issues, feel free to reach out for help. If you&#8217;re not a co-worker, join the discord server, DM on twitter, or email me through the contact form and I&#8217;ll try to help. I wrote this largely off memory of what I did, and I&#8217;m sure I missed a few things.</p><p>Always strive to make your development environment work for you, and make your life more convenient. If you ever catch yourself frustrated, think about how to solve it. Don&#8217;t push it off because you don&#8217;t have time to look into it.</p><h2>Commands to run on the server</h2><p><em>These commands are really just for my coworkers. We write a web application in PHP.</em></p><ul><li><p>add to ~/.bashrc for global composer installations to work as commands</p><ul><li><p>Only really needed if you want to run phpunit-watcher in the terminal vs the vs code extension</p></li></ul></li></ul><pre><code>export PATH="$PATH:$HOME/.config/composer/vendor/bin"
</code></pre><p>You will need to install php-cs-fixer to format your php code</p><pre><code>composer global require friendsofphp/php-cs-fixer
</code></pre><p>Additionally you will need the following vs code settings to point to your executablePath</p><pre><code>"php-cs-fixer.executablePath": "/home/&lt;account&gt;/.config/composer/vendor/bin/php-cs-fixer",
"php-cs-fixer.config": "/sc/config/.php_cs",
"beautify.config": "/sc/config/.jsbeautifyrc",
</code></pre><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/subscribe?"><span>Subscribe now</span></a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.jeremywinterberg.com/p/making-the-best-of-an-old-school-dev-environment?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.jeremywinterberg.com/p/making-the-best-of-an-old-school-dev-environment?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p>]]></content:encoded></item><item><title><![CDATA[Why I Decided to Quit MMORPG Games]]></title><description><![CDATA[You never really quit, you just take extended breaks.]]></description><link>https://www.jeremywinterberg.com/p/why-i-decided-to-quit-mmorpg-games</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/why-i-decided-to-quit-mmorpg-games</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Fri, 25 Dec 2020 04:33:36 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/9535fcde-582a-4604-aba1-53792d3d8a96_480x360.jpeg" 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://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="3840" height="2160" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2160,&quot;width&quot;:3840,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;black flat screen tv turned on near white wall&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="black flat screen tv turned on near white wall" title="black flat screen tv turned on near white wall" srcset="https://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1616588589676-62b3bd4ff6d2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwzfHxwYyUyMGdhbWluZ3xlbnwwfHx8fDE3MDc2NjA2MzN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><h2>My Experience With Gaming Addiction</h2><p>I&#8217;ve been a gamer my entire life, like most millennials. The first games I remember playing were Tetris on the original black and white gameboy, DOS computer games like Crystal Cave, Brick Breaker, and Jazz Jackrabbit, and the early NES games like mario bro&#8217;s and duck hunt. My whole life I played games till I beat them, then moved on. This is a relatively healthy relationship with games. But then a new genre came to my attention, MMORPG (Massively Multiplayer Online Role-Playing Game).</p><p>These are the social games that suck away your life force till you bleed dry. They&#8217;re created intentionally to get you to play longer, to use their paid services, to create relationships with friends and rivals, to join the Horde or Alliance against each other as one body. It&#8217;s not a new concept that these games are highly addicting. I&#8217;ve been playing them since 2005, and I&#8217;ve finally said enough.</p><h3>Runescape</h3><p>My first MMORPG was Runescape. I started playing the game because a friend of mine convinced me to try it. Very quickly, I became hooked. From grinding all of my skills to reach quest requirements to logging on every couple of hours to do farm runs. I spent hundreds of hours killing the same monsters in hopes to get the super rare drops. I believe I had over 400 days of game time logged when I finally quit the game after 12 years. There&#8217;s another side to that story, my youtube career, which I can touch on another time.</p><p>Runescape was my life. All of my friends played that game, which slowly changed to all of my friends were only met online through that game. I slowly lost contact with everyone who lived near me who wasn&#8217;t playing runescape. I&#8217;m still friends and talk to most of the people I met through gaming. I even was the best man at one of their wedding&#8217;s a couple years ago.</p><p>But, when you stop doing an activity that takes up all of your free time.. you fill it with something else. Which is when I was introduced to World of Warcraft.</p><h3>World of Warcraft</h3><p>WoW is arguably the largest, most popular MMORPG. Its been around as long as Runescape, but easily has over 5 times the player base across the globe. I started playing wow at the end of Cataclysm, but really my addiction started in Mists of Pandaria in 2012. I was introduced to progression raiding, and have been hooked on that competition since then.</p><p>There&#8217;s nothing quite like the feeling of working together with a large group of people to clear a raid for the first time. Coming up with strategies, analyzing your gameplay to improve pull after pull, picking up tips from watching other people play on stream or in videos, etc.. its an ecosystem of competition, and I ate it up. I never got to play at any insane level, I peaked at US 37th, and was often in the top 100 players of my class. But the rush is the same regardless of when you get there. Working as a team to fix each small issue till the fight finally clicks and you get the kill. The ferocious war cry of nerd screams is something you just dont experience in any other atmosphere.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://www.youtube.com/watch?v=FFnePWEub94&amp;t=317s" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3D6H!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c157101-6b62-4fec-9cb0-685b4916a28d_480x360.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3D6H!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c157101-6b62-4fec-9cb0-685b4916a28d_480x360.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3D6H!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c157101-6b62-4fec-9cb0-685b4916a28d_480x360.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3D6H!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c157101-6b62-4fec-9cb0-685b4916a28d_480x360.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3D6H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c157101-6b62-4fec-9cb0-685b4916a28d_480x360.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c157101-6b62-4fec-9cb0-685b4916a28d_480x360.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;N&amp;rsquo;Zoth Limit Nerd Screams&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:&quot;https://www.youtube.com/watch?v=FFnePWEub94&amp;t=317s&quot;,&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="N&amp;rsquo;Zoth Limit Nerd Screams" title="N&amp;rsquo;Zoth Limit Nerd Screams" srcset="https://substackcdn.com/image/fetch/$s_!3D6H!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c157101-6b62-4fec-9cb0-685b4916a28d_480x360.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3D6H!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c157101-6b62-4fec-9cb0-685b4916a28d_480x360.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3D6H!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c157101-6b62-4fec-9cb0-685b4916a28d_480x360.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3D6H!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c157101-6b62-4fec-9cb0-685b4916a28d_480x360.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://www.youtube.com/watch?v=19tXeHJns1E&amp;t=664s" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KLbW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697f25ff-d7a4-464e-a3b6-06ad5a16c640_480x360.jpeg 424w, https://substackcdn.com/image/fetch/$s_!KLbW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697f25ff-d7a4-464e-a3b6-06ad5a16c640_480x360.jpeg 848w, https://substackcdn.com/image/fetch/$s_!KLbW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697f25ff-d7a4-464e-a3b6-06ad5a16c640_480x360.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!KLbW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697f25ff-d7a4-464e-a3b6-06ad5a16c640_480x360.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KLbW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697f25ff-d7a4-464e-a3b6-06ad5a16c640_480x360.jpeg" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/697f25ff-d7a4-464e-a3b6-06ad5a16c640_480x360.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Limit VS Sire Denathrius WORLD FIRST&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:&quot;https://www.youtube.com/watch?v=19tXeHJns1E&amp;t=664s&quot;,&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="Limit VS Sire Denathrius WORLD FIRST" title="Limit VS Sire Denathrius WORLD FIRST" srcset="https://substackcdn.com/image/fetch/$s_!KLbW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697f25ff-d7a4-464e-a3b6-06ad5a16c640_480x360.jpeg 424w, https://substackcdn.com/image/fetch/$s_!KLbW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697f25ff-d7a4-464e-a3b6-06ad5a16c640_480x360.jpeg 848w, https://substackcdn.com/image/fetch/$s_!KLbW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697f25ff-d7a4-464e-a3b6-06ad5a16c640_480x360.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!KLbW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F697f25ff-d7a4-464e-a3b6-06ad5a16c640_480x360.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h2>It&#8217;s wonderful, until it isn&#8217;t.</h2><p>About 2 years ago I joined a guild that I had looked up to for years. They were often one of the top guilds on my server and had a few big name streamers. It was also the start of my anxiety. I would over analyze everything that people said directly about me. Anything indirect would automatically be assumed to be about me. My brain was convinced that I was trash at the game. I pushed so hard to improve and become an expert at my class, but the thoughts still were there. &#8220;Why did this loot get assigned to that person instead of me when its a bigger upgrade for me? They must be thinking about kicking me off the team&#8221;.</p><p>People in my guild would rarely respond to me. Anytime I would post a suggestion, an opinion, or even joke, they would be met with opposition or simply ignored. I can genuinely say that I only ever had 2 friends in that guild, the rest I still have no clue if they like me or not. This fed into my anxiety and the idea that I didn&#8217;t belong there.</p><p>This anxiety, and a desire to focus on my career as a software engineer, made me consider quitting the game for a very long time. In DM&#8217;s with these friends I talked about how I wanted to step away from the game. What prevented me from biting the bullet came down to a few factors. 1. I didn&#8217;t want to leave my team without an adequate replacement for me. 2. I just didn&#8217;t quite have a reason to throw away all of my experience and status as a raider at this level yet. When you stop raiding for any amount of time, it is INCREDIBLY hard to get back into it at the same level. You typically have to slum around and work your way back up unless you have connections.</p><h3>Nothing lasts forever.</h3><p>On December 20th, 2020, I was informed I would no longer be on the raid team of my guild. I was welcomed to stay as a friends and family member, but I would not be in on any fight. I raided for progression, farm doesn&#8217;t bring the same challenges that make it fun. My anxiety and paranoia believes there were some politics that went into that decision, but I will never truly know if that&#8217;s accurate.</p><p>When I was given the news, I had a few initial reactions.</p><ul><li><p>Betrayal: this was the team I&#8217;ve been with for 2 years. They discounted all of that time and my experience because I had a rough week where I performed poorly.</p></li><li><p>Self-doubt: This was confirmation that my skill level, I was so anxious about, was actually bad, and this wasn&#8217;t just in my head.</p></li><li><p>Anger: Mad that the people who made the decision weren&#8217;t delivering the news. Mad that I was silently being pushed away off the team. Hurt that no one cared that I was removed from the team except 2-3 people.</p></li><li><p>Relief: I finally had a reason to quit the game. I responded to the news with my final feedback and advice for the leadership team. The overall gist of it was they need to fix their communication. I posted my farewell to the team in the guild discord channel, cancelled my wow subscription, and uninstalled the game. WoW has been removed from my life after 8 years, and thousands of hours of gametime played.</p></li></ul><h3>How am I doing now?</h3><p>Its been a few days now, and I&#8217;m writing this post as a way to decompress my thoughts. A personal therapy session. In that time I&#8217;ve been able to get quite a lot done. I finally got around to doing some workshop upgrades, and was incredibly productive at work. I feel free to do whatever I want to do.</p><p>I&#8217;m no longer tied down to a Mon-Wed, 7:45-11:30pm raid schedule, with 20 hours of maintenance chores every week. No longer plagued by a constant thought that I need to analyze my gameplay again to see where I could improve. Relief is an understatement of what I&#8217;ve felt these past days.</p><p>I talked to a friend today and he said I genuinely sounded happier/more upbeat than I have in a long time. I dont know if what I&#8217;m feeling is happiness, but I definitely feel great. My stress and anxiety have subsided, and I&#8217;m hopeful for the opportunities this will allow me to do.</p><h2>What&#8217;s my advice?</h2><p>So, I&#8217;ve quit MMORPGs. I do no plan on playing another one any time soon. I highly recommend evaluating what you gain by playing the game like I did. WoW became a job I wasn&#8217;t paid to play. I clocked in and out on a set schedule that brought me no joy. I stopped experiencing the nerd cries and instead would sigh in relief that we finally finished. It wasn&#8217;t happiness, it was the end of a work day.</p><p>If you feel that way, try to remember what made the game fun for you and only do that thing. For me, there was nothing left that was fun. And there&#8217;s no point in playing a game, if you&#8217;re not having fun.</p><p>Good luck my dudes,</p><p>Jeremy</p><blockquote><p>Update 2021: I started playing Runescape again.. but only casually. It&#8217;s been pretty healthy so far and I only play when I have time and while I&#8217;m having fun.</p></blockquote>]]></content:encoded></item><item><title><![CDATA[The Rebirth of a Hackintosh Dev Environment]]></title><description><![CDATA[Why should you consider using a hackintosh for software development?]]></description><link>https://www.jeremywinterberg.com/p/the-rebirth-of-a-hackintosh-dev-environment</link><guid isPermaLink="false">https://www.jeremywinterberg.com/p/the-rebirth-of-a-hackintosh-dev-environment</guid><dc:creator><![CDATA[Jeremy Winterberg]]></dc:creator><pubDate>Sun, 18 Oct 2020 04:26:24 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" 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://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080" width="5243" height="3495" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:3495,&quot;width&quot;:5243,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;MacBook Pro on top of brown table&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpg&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="MacBook Pro on top of brown table" title="MacBook Pro on top of brown table" srcset="https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 424w, https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 848w, https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 1272w, https://images.unsplash.com/photo-1496181133206-80ce9b88a853?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wzMDAzMzh8MHwxfHNlYXJjaHwyfHxjb21wdXRlcnxlbnwwfHx8fDE3MDc2NjA0NTR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=1080 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></figure></div><h2>My History</h2><p>A few years back I went all-in on a setting up a Hackintosh pc. I even made a blog post about it, which you can&#8217;t find anymore. But, I had everything running perfectly and was productive in my work. Then I gave up on it due to the inconvenience of needing to boot back into windows constantly.</p><blockquote><p>A Hackintosh is a regular pc with macOS installed on it. It&#8217;s a rather finicky process that requires getting drivers and kexts for your specific hardware.</p></blockquote><h2>OpenCore</h2><p>Now there is a new kid on the block of bootloaders, and it&#8217;s called OpenCore. The experience I had while setting up my install drive this time around was extremely straightforward and easy. Pair this with the community around AMD, and I have the most stable hack I&#8217;ve ever used.</p><p>Why did I do this? Well, I have to do some ios app development for work, and you kind of need a mac for that! Other than that I probably wont be using it for like 99% of the work I do. And here&#8217;s why: I can get a lot done on windows between vscode and WSL.</p><h2>Why do so many developers prefer MacOS?</h2><p>The main reason why macOS is so popular in the programming community is that its unix based at its core. Unix is basically the original Operating System that was created at Bell Labs back in the &#8217;70s. Since then operating systems like Linux and macOS/OSX have been created based on unix. Unix OS Tree</p><p>The reason this history lesson is important is because the terminals between linux and macOS are basically the same. They share almost all of the same tools because they&#8217;re both capable of running the same bash shell software. Most developers need to use a terminal at some point in their workflow. Common uses include managing git versioning, compiling an application, or using vim for their text editor environment.</p><h3>It&#8217;s Aesthetically pleasing</h3><p>While you can do this terminal work on both mac and linux, many opt for the mac because of aesthetics. They may have other apple devices that can communicate, and a vast selection of macOS applications available to them.</p><p>I kind of care about the desktop apps on macos for productivity, but otherwise I&#8217;m impartial between macos and linux. When I run linux, I always choose pop!_OS these days, and I highly recommend it as your distro of choice! It&#8217;s an Ubuntu based distro maintained by System76, a company that specializes in creating open-sourced systems for the STEM community.</p><p>Anyways, this is all just an update on what I&#8217;m using for my OS these days. I primarily work in Windows through vscode. I use the vim extension and do things in the WSL when I need to. . I&#8217;ll do another post in the future going over my actual dev environment in detail.</p><p>Do any of you also use a hackintosh? What has been your experience with it, and has that evolved over the years as support strengthens?</p><blockquote><p>Update 2021: I no longer use a hackintosh due to the M1 chipset coming and the bleak outlook for the hackintosh community&#8217;s longevity</p></blockquote>]]></content:encoded></item></channel></rss>