<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by S. G. on Medium]]></title>
        <description><![CDATA[Stories by S. G. on Medium]]></description>
        <link>https://medium.com/@chivagarg?source=rss-7818d68e2f0f------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*2TxktfygzKwIErL1</url>
            <title>Stories by S. G. on Medium</title>
            <link>https://medium.com/@chivagarg?source=rss-7818d68e2f0f------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 04:33:54 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@chivagarg/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[+1 with comments]]></title>
            <link>https://chivagarg.medium.com/1-with-comments-45d13a366f5b?source=rss-7818d68e2f0f------2</link>
            <guid isPermaLink="false">https://medium.com/p/45d13a366f5b</guid>
            <category><![CDATA[code-review]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[S. G.]]></dc:creator>
            <pubDate>Sat, 16 Jul 2022 15:32:47 GMT</pubDate>
            <atom:updated>2022-08-05T18:47:59.123Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/528/0*B2--e9Ncw-RVRXfG" /></figure><p>At one of the big tech companies I worked at, we had comprehensive documentation around code review best practices &amp; coding style guides. This documentation has been open sourced and is publicly available (see <a href="https://google.github.io/eng-practices/review/reviewer/">code review best practices</a>, <a href="https://google.github.io/styleguide/javaguide.html">java style guide</a> etc). The standards incorporate best practices across coding languages/code reviews and are updated fairly frequently to incorporate new features as languages evolve. The big tech companies have a bunch of pretty smart folks coming up with these guidelines. However, like most things in software development, there is a caveat — the standards are ultimately a set of <em>recommendations</em> and can sometimes be subjective. For e.g. should the standard be to use tabs or spaces? (who are we kidding, tabs are clearly superior).</p><p>However, in spite of them seeming somewhat draconian at times, the standards go a long way in ensuring that code at these big tech companies is consistent, well structured and well reviewed. Most of all, it provides guidance to junior engineers who are still figuring out how to write clean, readable code.</p><p>Going from Google to Lyft, I observed two issues around code reviews on my team:</p><ol><li>PR iterations often took over a day to get reviewed</li><li>Code reviews were shallow — they were either nit-picky or simply rubber stamped without the reviewer doing due diligence</li></ol><p>This impacted my team’s velocity as well as code quality. To help mitigate these issues, I came up with some code review standards/guidelines for the team. These guidelines were developed by leveraging suggestions from my teammates, my own personal experience as a software engineer as well as various online resources. Feel free to use some or all of these guidelines for your own teams or projects, or to distribute them freely:</p><h3>On approvals</h3><ul><li>Approve a PR if <em>the change is safe to ship as-is.</em></li><li>Lean towards granting approval if all of your comments are nits/suggestions for improvements. Not giving an approval implies that the author <em>must</em> change their code in order to get the approval.</li><li>If the change is not safe to ship as-is (e.g. if it may cause an outage/SEV), lock the PR to prevent an accidental merge.</li></ul><h3>On review timeliness</h3><ul><li>Establish an SLO on the time between a code review being requested and reviewed. It’s important to get buy-in from your team so that expectations are documented and aligned. At Lyft we established an <a href="https://en.wikipedia.org/wiki/Service-level_objective">SLO</a> of 3 working hours. Once tagged for code reviews, it was expected that reviewers would be able to perform the review within 3 hours. For e.g. if the reviewer was tagged at 1 pm, they were expected to review the change by 4 pm. If they were tagged at 5 pm, they were expected to review it by 12 pm the next working day.</li><li>If the reviewer is unable to meet the SLO, they should leave a comment on the PR, setting expectations with the author.</li><li>If the SLO is breached, the author should feel comfortable pinging or retagging the reviewer. Note that the SLO wasn’t enforced via any tool but served as the north star to align on best practices for code reviews.</li></ul><h3>On authoring a PR</h3><h4>Do:</h4><ul><li>Assume competence and best intentions.</li><li>Provide sufficient context for the change by adding a description, links to relevant JIRA tickets or tech specs. Fill out the PR template. <em>It’s the author’s responsibility to help the reviewer understand what the PR is trying to accomplish.</em></li><li>Review your own code before asking reviewers to take a look.</li><li>Keep your changes small. <em>Smaller PRs are faster to review &amp; have a higher probability of reviewers catching bugs.</em> Aim for a PR which is 250 lines (including tests). A <a href="https://smartbear.com/resources/case-studies/cisco-systems-collaborator/">study</a> demonstrated that the brain can only effectively process so much information at a time &amp; beyond 400 LOC, the ability to find defects diminishes.</li><li>When disagreeing with feedback, <em>articulate why you disagree</em> and provide artifacts (coding style guides etc) explaining the advantages of your approach.</li><li>Retag your reviewers if the review SLO is breached.</li><li>Loop in the approving reviewer if you’ve made substantial changes after the approval was granted.</li></ul><h4>Don’t:</h4><ul><li>Rely on your reviewer to catch bugs. <em>You are ultimately responsible for the quality and correctness of your code.</em></li><li>Include unnecessary changes unrelated to what you are trying to accomplish in the PR. It might be tempting to refactor a class which is unrelated but will likely confuse your reviewers or require them to context switch.</li></ul><h3>On reviewing a PR</h3><h4>Do:</h4><ul><li>Assume competence and best intentions.</li><li>Ask for clarification when you don’t have sufficient context for the code that you are being asked to review.</li><li>Ask the author to break down the change into smaller PRs if the PR is longer than 250 lines.</li><li><em>Focus on overall correctness &amp; substance of the PR rather than being nit-picky.</em> Clearly prefix your review comment with the term “nit” if you are making a suggestion that is nit-picky to help the author understand your expectations.</li><li>Proofread doc-string comments.</li><li><em>Positively reinforce PRs/changes that are well written</em> and uphold the team’s standards by letting the author know that they did a good job. This will help foster a more positive team culture.</li><li>Reviewer a PR within the defined SLO. If you are swamped/busy, let the author know that the review might be delayed.</li></ul><h4>Don’t</h4><ul><li>Approve the change if the change is not safe to ship as-is.</li><li>Ask the author to change code just because you prefer code being written a certain way. Instead, provide artifacts (code review guidelines, written standards) that rationalize your comments. When possible, link to the relevant section in the style guide.</li><li>Make reviews personal. Criticize the code rather than the author. For e.g. don’t say <em>“why are you making this more complex?”</em>. Instead, prefer to word your comment as <em>“introduction of Gevents here is adding complexity without any performance gain because…”</em></li><li>Lock the PR unless the current state of the PR is clearly not acceptable to be merged, or the changes are dangerous. Locking is a blocking action and should be used with caution. If you do need to block a PR, clearly explain the issue and work with the author on resolving it.</li></ul><p>By establishing these standards, my team was able to reduce the code review time from over a day to ~ 3 hours and we were able to establish a code reviewing culture that was more positive and thorough.</p><p>How does your team do code reviews? Anything in this article that you agree or disagree with? Feel free to leave your thoughts in the comments below.</p><p><a href="https://medium.com/@chivagarg">Follow me</a> to be notified whenever I publish an article like this one. If you are interested in interviewing, you might also want to check out my article called <a href="https://chivagarg.medium.com/the-leetcode-phenomena-e9ec4de41ca"><em>“The LeetCode Phenomenon”</em></a><em> </em>or <a href="https://chivagarg.medium.com/why-microsoft-bid-me-an-irish-goodbye-de35bd60e81d"><em>“Why Microsoft didn’t love me back”</em>.</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=45d13a366f5b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Netflix is square]]></title>
            <link>https://chivagarg.medium.com/netflix-is-square-6ad0423ab840?source=rss-7818d68e2f0f------2</link>
            <guid isPermaLink="false">https://medium.com/p/6ad0423ab840</guid>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[netflix]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[team]]></category>
            <dc:creator><![CDATA[S. G.]]></dc:creator>
            <pubDate>Tue, 12 Jul 2022 17:08:29 GMT</pubDate>
            <atom:updated>2022-08-05T18:46:05.800Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*6MAnF-MqakQDxAMY" /></figure><p>I was pretty baffled when I first learnt about Netflix’s philosophy of hiring exclusively senior software engineers. What? No room for my beloved new grads or mid level engineers? How very square of them!<strong>**</strong></p><p>I recently left my job as an engineering manager at Lyft. As I’m mulling over my last 2 years in engineering leadership, I’ve come to obsess over what I call the “inverted triangle” team composition problem in tech. One of the challenges that engineering managers face is building a team composed of engineers at the right level of seniority. But let’s not get ahead of ourselves! Before we dive into team composition, let’s talk about the seniority bands in tech companies.</p><p>Roughly speaking, seniority in engineering spans across 4 bands. We have the mighty staff engineers (SE) who are experts in the fields and are responsible for setting the technical vision and overseeing multiple projects on the team. Then we have senior engineers (SR) who will typically lead a large, complex project and are expected to be able to run the day to day operations of the team (if summoned to do so). Mid level Engineers (M) have typically been in the industry for 2–5 years and work on sub-features of projects. For e.g. a senior engineer responsible for building the purchase flow for <a href="https://www.cryptokitties.co/">Crypotokittens</a> may break up the project into several features (and example of a feature may be to fetch the available token balance) which can be picked independently by a mid level team-mate. Junior Engineers are typically new to the industry and operate on tasks rather than projects or features. For e.g. to display the available token balance, one of the tasks might be to make an API call that returns the available tokens.</p><p>Here is another fun fact — the senior engineer level is considered to be the “terminal” level at many tech companies. What this means is that every junior or mid level engineer is expected to get promoted to the senior level within a recommended timeline. At Lyft, the recommendation is 24 months for a junior engineer to get promoted to mid-level and 30 months for a mid-level engineer to get promoted to the senior level. Once an engineer reaches the senior level, they can choose to stay there indefinitely (if that’s what they wish to do).</p><p>Finding the right makeup of a team is complex since it depends on factors such as the technical complexity of the team’s domain, as well as the motivations/ambitions of your team. For e.g. a team that owns projects/products in a highly technical space is likely to thrive with an inverted triangle composition (high ratio of senior to junior engineers). This is in contrast to the “classic triangle” team composition — more junior and mid level engineers than senior/staff engineers. The “inverted triangle” team composition is common at companies like Microsoft. Since Netflix hires only senior engineers, the team composition can be seen as a square:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*eT-FI-TfGXzV6CY9" /></figure><p>The reason why the classic triangle composition works pretty well is because it allows for a diverse set of team skills. Entry level engineers work on simpler tasks, mid level engineers work on features and senior/staff engineers work on a project or multiple projects. Tenured engineers grow by learning to mentor and delegate and junior engineers improve by following the examples set by more senior engineers. This dynamic keeps the entire team motivated — the senior/staff engineers on your team can focus on harder, ambiguous problems while more junior engineers focus on well defined tasks or features which are challenging for them but might feel more mundane to senior engineers.</p><p>The antithesis of the “classic triangle” is the “inverted triangle” (the “square” composition is just another flavor of this). The engineering team I inherited (and managed) at Lyft was, at one point, composed of 3 staff engineers, 4 senior engineers and 2 mid level engineers. Problems in the inverted triangle manifest if the top of the triangle is highly motivated by promotions/career growth and there aren’t enough complex problems to solve. This will typically happen on teams that are bloated — there are bound to be ego clashes and interpersonal conflicts. In the worst case, it leads to prioritization of unnecessary projects to invent scope to appease the top of your triangle. Or you may run into what is infamously known as “terrain grabbing” where you try to take on projects that don’t naturally belong in your team. To put it bluntly, shit gets political and it’s not a good place to be as an employee or a manger. At Lyft, in spite of my team being low ego, I saw many symptoms of bloat and scope grabbing.</p><p>Having said that, I’ve been in teams where the “inverted triangle” worked pretty well- when I worked as a software engineer at Google, my team was composed of 4 senior engineers and 2 junior engineers, all working on the same problem (rewriting of our funds transfer backend). Even though it’s been many years since (and the project has long been deprecated), I have fond memories of the rewrite-it’s been one of my favorite projects as I learnt a lot from the seniority around me. The team composition worked in spite of being top heavy because the team was low ego, the problem space was large and complex enough, and 3 of the 4 senior engineers weren’t fixated on getting a promotion- they were simply in it to solve cool technical problems.</p><p>Here’s another rebuttal of the “square” team composition via a rather flippant hypothetical: Let’s say that I’m a mighty <a href="https://en.wikipedia.org/wiki/Pharaoh">Pharaoh</a> and I hand you a thousand gold coins to commission you to build me the Pyramids in a year. Would you hire just 20 architects (think staff engineers) who demand wages of 50 coins a year? Or would you just hire 2 architects to come up with the blueprints and plans and use the remaining 900 precious coins to hire laborers of various skill sets? Think junior laborers, mid level laborers and maybe some foremen (senior laborers)? How ineffective it would be to have your architects with highly specialized skills spending 90% of their time laying down stone blocks in a straight line when an entry level laborer could do that job just as well.</p><p>Switching over from effectiveness to principles- I believe that the rich, capable talent in the tech industry has developed to a large extent from teams that follow the classic triangle composition — new grads emulate the patterns and styles of more senior engineers and in time grow into capable mentors themselves and the fruitful wheel of wisdom and good unit testing continues. By hiring only senior engineers, Netflix doesn’t contribute to this cycle of training Padawans and contributing to the enrichment of our industry (although they may argue that they help build <a href="https://starwars.fandom.com/wiki/Grand_Master/Legends">jedi grand masters</a> out of <a href="https://starwars.fandom.com/wiki/Jedi_Knight">jedi knights</a>).</p><p>The “inverted triangle” composition is actually a fairly common dynamic that cuts across the industry. I’ve experienced it first hand at big tech so be aware of the possibility of this dynamic creeping into your team and factor the team composition when weighing whether to join a team!</p><p><strong><em>**</em></strong><em>It seems like Netflix has </em><a href="https://www.reddit.com/r/cscareerquestions/comments/r5902r/whats_up_with_the_new_grad_salaries_at_nflix/"><em>deviated</em></a><em> from trend and has, in recent times, opened up more roles for junior/mid-level candidates. I hope that this trend continues!</em></p><p>If you enjoyed this article, you may also want to check out <a href="https://medium.com/swlh/the-leetcode-phenomena-e9ec4de41ca">The Leetcode phenomena</a>. <a href="https://medium.com/@chivagarg">Follow me on Medium</a> to be notified whenever I publish a new article.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6ad0423ab840" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[System design for dummies — part 3 (Design a donation app)]]></title>
            <link>https://chivagarg.medium.com/system-design-for-dummies-part-3-design-a-donation-app-c9f2720222ce?source=rss-7818d68e2f0f------2</link>
            <guid isPermaLink="false">https://medium.com/p/c9f2720222ce</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[system-design-interview]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[S. G.]]></dc:creator>
            <pubDate>Mon, 07 Feb 2022 16:03:13 GMT</pubDate>
            <atom:updated>2022-02-07T16:03:13.422Z</atom:updated>
            <content:encoded><![CDATA[<h3>System design for dummies — part 3 (Design a donation app)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tPETVJizZAzFtSQoEhjF7w.png" /></figure><p>This is the final part of a 4 part series on cracking the system design interview. <a href="https://chivagarg.medium.com/system-design-for-dummies-part-0-db2afd629502?sk=747a102e052e9905dd067c3552dec8b8">Part 0</a> provided an overview of this article series, p<a href="https://chivagarg.medium.com/system-design-for-dummies-part-1-27e3903435f6">art 1</a> focused on the content you need to master to nail the interview and p<a href="https://chivagarg.medium.com/system-design-for-dummies-part-2-7cfc81d49c5b">art 2</a> focused on the format you should follow during your system design interview.</p><p>In this final part I’ll provide a real life example of a system design problem — <em>designing a donation app</em>. I lifted this problem from this discussion on <a href="https://leetcode.com/discuss/interview-question/318214/DoorDash-Onsite-System-Design-question">Leetcode</a>. Here is the problem statement:</p><ul><li><em>You are required to design a donation app for a 3 day charity event across the US where you are expecting 3 million donations.</em></li><li><em>You should accept details like customer name, credit card details etc.</em></li><li><em>No pay specific knowledge is required (presume that you’d integrate with a 3rd party pay provider like Stripe or Braintree).</em></li></ul><p>If you are a visual learner like me &amp; prefer videos to words, you can skip ahead to watching the video (it’s listed at the bottom of this post) and then come back to the article. I do recommend reading through the entire article as it covers some key concepts that I didn’t cover in the video.</p><h3>Understanding requirements/goals</h3><p>Focus on understanding the requirements to establish the bounds of the problem. Focus on the functional requirements (these would typically be specified in a <a href="https://en.wikipedia.org/wiki/Product_requirements_document">PRD</a>) as well as the non functional requirements.</p><p>For functional requirements, some of the questions you can ask are — <em>Will the users be logged in? Will they be using an app? What’s the user experience if the payment fails or succeeds? Can the user view their past donations?</em></p><blockquote>Note that if you are a senior candidate, you are expected to own the problem &amp; it’s preferable that you come up with your own assumptions rather than expecting the interviewer to define constraints for you.</blockquote><p>For this problem, I’ve chosen to focus on donations and largely ignored how details about the charity are surfaced in the app.</p><p>The non-functional requirements will typically help establish the bounds/constraints of the problem. Use back of the envelope calculations to get the RPS (requests per second). 3 million donations over 3 days translates to 10 RPS. The shape of the traffic should be a consideration — e.g. most of the traffic for the donation app will come during the day time, and there might be further spikes in case of celebrity endorsements. For scale, we should build a system that can handle 100 RPS. To wrap up this section, you should comment on availability (improved via redundancy), latency (not super important here), throughput (improved via partitioning), consistency (eventual, read after write).</p><h3>Data modeling &amp; APIs</h3><p>The main entities are User, PaymentMethod, Donation, PaymentAttempt which represent different micro-services (i’ve ignored Charity to reduce the scope). Draw out the entities &amp; establish the relationship between them.</p><p>Note that Donation &amp; PaymentAttempt could be tables within a single micro-service which would allow us to leverage on the ACID properties of relational databases &amp; provide us with transactionality. However, it’s common to follow the single responsibility principle &amp; have the Donation service be separate from the PaymentAttempt service. This is justifiable if the PaymentAttempt service would be called by services other than the Donation service (e.g. a Shopping service). If we create a PaymentAttempt micro-service, it would be important not to leak donation related information into the PaymentAttempt service. For e.g. the donation_id would be renamed to something more generic like auxiliary_id (the id is called the donation_id in the video and needs to be corrected).</p><p>The biggest challenge in micro-service architecture is eventual state consistency. For e.g. if the payment attempt succeeds, we’d need to notify the Donation service so that the status of the Donation entry can be updated. If the webhook/event never reaches the Donation service, we risk being in an inconsistent state.</p><h3>System architecture (component diagrams)</h3><p>I recommend calling the 3rd party payment provider when the user is “in-session” (in-session means that the user is online &amp; attempting to make the donation live). In the happy path the client would receive a status of 200 with donation status SUCCEEDED in real time. However, to design a system that is robust, we should enqueue retries if the 3rd party provider is unavailable &amp; we receive a transient failure response. Retries can happen offline &amp; we’d need to keep the overall state of the donation in sync with the status of the latest payment attempt.</p><h3>Failure scenarios</h3><p>Failure can happen at multiple points. Network blips can cause timeouts or databases can go down. We should also monitor for data inconsistencies. We should also rely on idempotency to ensure that a single donation does not result in multiple payment attempts.</p><p>Leader nodes can fail &amp; one of the replicas will need to be promoted to be primary. Scenarios like split-brain should be prevented and replication lag should be monitored for.</p><h3>Scaling</h3><p>Partitioning can increase throughput. Partitioning by hash of the user_id is better than partitioning by range as range based partitioning can lead to more hot spots (e.g. imagine that a celebrity tweets and thousands of new users create accounts and start donating — they will all hit the same partition if user_ids are generated in an increasing order).</p><h3>Video</h3><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FmNiHK_WK5KM%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DmNiHK_WK5KM&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FmNiHK_WK5KM%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/d5c5ae2f924d3a9432bda38f0016a2f9/href">https://medium.com/media/d5c5ae2f924d3a9432bda38f0016a2f9/href</a></iframe><p>Hope that you’ve enjoyed the article series &amp; the video (sorry for the scratchy background noise — unfortunately it’s a part of the app I used to record the video).</p><p>If you have questions about the solution I presented or if you have suggestions on how this design could be improved please feel free to leave a question or comment. If you found this article useful, please consider <a href="https://chivagarg.medium.com/">following me on medium</a> or reposting this article on social media. You may also be interested in reading my article called <a href="https://medium.com/swlh/the-leetcode-phenomena-e9ec4de41ca">the LeetCode phenomenon</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c9f2720222ce" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[System design for dummies — part 2]]></title>
            <link>https://chivagarg.medium.com/system-design-for-dummies-part-2-7cfc81d49c5b?source=rss-7818d68e2f0f------2</link>
            <guid isPermaLink="false">https://medium.com/p/7cfc81d49c5b</guid>
            <category><![CDATA[interview-preparation]]></category>
            <category><![CDATA[system-design-interview]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[interview-tips]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[S. G.]]></dc:creator>
            <pubDate>Sun, 02 Jan 2022 06:42:08 GMT</pubDate>
            <atom:updated>2022-01-03T06:55:13.786Z</atom:updated>
            <content:encoded><![CDATA[<h3>System design for dummies — part 2</h3><p>Please read <a href="https://chivagarg.medium.com/system-design-for-dummies-part-0-db2afd629502">part 0</a> to get an overview of what to expect in this article series. <a href="https://chivagarg.medium.com/system-design-for-dummies-part-1-27e3903435f6">Part 1</a> lists out the study material required to nail the system design interview. In this article, we will cover the format you should follow during the system design interview.</p><p>Typically system design interviews will focus on a narrow part of a larger problem. For e.g. you are way more likely to be asked to design a service for tracking driver locations rather than to “design Uber”. Interviewers do this because it’s much easier to gauge your performance on a problem that is narrow &amp; well understood by them than something broad (which runs the risk of the interview getting derailed).</p><p>Let me start off by saying that you should be leading/driving the system design conversation. If most of the talking is done by the interviewer, you’re probably not doing too well. Your interviewer will often interject &amp; challenge what you say, so be prepared to explain the rationale behind your design recommendations &amp; decisions. Usually there is no single <em>right</em> answer — there are typically many good ways to solve the problem, and it’s about making trade-offs.</p><h3>The rubric used to assess you</h3><p>It’s important to keep in mind how you’ll be assessed. Although this will vary to some degree from company to company, by and large the rubric for the system design interview assesses the following:</p><ol><li>Can you navigate an ambiguous problem space?</li><li>Are you structured in your problem solving?</li><li>Do you make the right trade-offs?</li><li>Do you think through failure cases?</li><li>Do you identify &amp; address constraints?</li></ol><p>Some other companies (e.g. Facebook) might also assess your ability to come up with accurate back of the envelope calculations which you would be expected to translate to the physical resources necessary to make the system work. Other companies might focus more on product APIs and assess your ability to think about how your decisions impact the end user experience.</p><h3>Structure of the interview</h3><p>Start your interview by providing an outline of the structure that you intend to follow. This not only provides structure to your interview but also provides a signal to the interviewer that you intend to be comprehensive in your design. I recommend that you follow the following structure:</p><ol><li>Understanding requirements/goals</li><li>Data modeling &amp; APIs</li><li>System architecture (component diagrams)</li><li>Failure scenarios</li><li>Scaling</li></ol><p>Earlier on I used to draw the system architecture (component diagrams) <em>before</em> outlining the data model/APIs. In one of my design interviews, an interviewer correctly pointed out that the data model reflects your understanding of the problem space and has the ability to influence how services are set up. So the system architecture should follow the data modeling &amp; APIs.</p><p>Now let’s cover each section in detail:</p><h4>1. Understanding requirements/goals</h4><p>The problem can be sparsely defined and it’s your responsibility to establish the bounds of the problem. You should establish the functional and non-functional requirements separately.</p><p>Functional requirements usually relate to product features — in the industry these would be specified in a PRD (Product Requirement Document). For e.g. if the prompt is to <em>design a donation service for a charity campaign</em>, here are some questions you can ask to clarify the functional requirements- <em>Who generates the campaign &amp; how is it generated? Does the user need to be logged in to make a donation? How does the user receive confirmation that their payment was successful? Do we need to build any fraud checks?</em></p><p>In order to dig into the non functional requirements, you’ll need to perform some quick back of the envelope calculations. The back of the envelope calculations will allow you to identify the constraints that might impact your design. Are there memory constraints or can everything be served out of a cache? Are there storage or compute constraints? What is the RPS (requests per second)? Do you need to partition data onto multiple machines to handle very high throughput?</p><p>You should memorize the following numbers as it will help you come up with estimates quickly:</p><ul><li>10⁶ Bytes = 1 Million Bytes = 1 MB</li><li>10⁹ Bytes = 1 Billion Bytes = 1 GB</li><li>10¹² Bytes = 1 Trillion Bytes = 1 TB</li><li>2³² = 4 Billion</li><li>Time taken to read 1 MB serially from memory = 0.25 ms</li><li>Time taken to read 1 MB serially from SSD = 1 ms</li><li>Time taken to read 1 MB serially from disk = 20 ms</li><li>Disk seek = 10 ms</li><li>Same data centre roundtrip = 0.5 ms</li><li>Inter-datacenter roundtrip = 150 ms</li><li>Seconds in a day = 86,400 = 10⁵ (approximated to 100,000)</li><li>2³² Bytes = 4 Billion Bytes = 4 GB</li><li>Twitter generates 500 M tweets a day with 200 M daily active user (DAU) &amp; 300 M monthly active users (MAU)</li><li>Stack overflow has 5 M DAU</li><li>Wikipedia has ~ 6M articles</li><li>The average size of an image is 3 MB</li></ul><p>To illustrate with an example — if you are designing the read path for facebook’s timeline, you can use Twitter’s daily active users to estimate the RPS. You’d start by stating your assumption that facebook has 2X traffic when compared to Twitter (in reality it’s closer to 5X, but the precise multiplier is irrelevant here — what is more important is to demonstrate a consistent and logical chain of thought). So we expect 300 * 2 = 600 M DAU. Let’s also assume that a user opens facebook 5 times a day. This translate to 600 * 10⁶ * 5 requests to fetch the user timeline per day.</p><p>600 * 10⁶ * 5 = 30 * 10⁸ requests per day = 30 * 10³ requests per second (we divided by the number of seconds in a day — 10⁵). A single machine running commodity hardware will struggle to handle a throughput of 30,000 RPS so we are better off sharding this traffic across 10–15 machines.</p><p>Before proceeding to the data model, you should comment on the availability, latency, throughput and/or consistency requirements. This is important as you’re providing a signal that you think about constraints upfront.</p><p>These concepts are covered in detail in Chapter 5 — Replication &amp; Chapter 6 — Partitioning in DDIA (<a href="https://www.amazon.com/Designing-Data-Intensive-Applications-Reliable-Maintainable/dp/1449373321/ref=sr_1_1?crid=1JS3IAEJ7PA8V&amp;keywords=designing+data+intensive+applications+by+martin+kleppmann&amp;qid=1641014221&amp;sprefix=Designing+Data+Intensive+Applications%2Caps%2C328&amp;sr=8-1">Designing Data Intensive Applications</a>). For a complete list of sources that I recommend, please read <a href="https://chivagarg.medium.com/system-design-for-dummies-part-1-27e3903435f6">part 1</a> of this article series.</p><blockquote><strong><em>Availability</em></strong><em>: Most designs will have high availability as a requirement. Replication &amp; redundancy increases availability.</em></blockquote><blockquote><strong><em>Latency</em></strong><em>: If there is a latency requirement (e.g. search autocomplete), you should serve reads out of a Redis cluster/CDN.</em></blockquote><blockquote><strong><em>Throughput</em></strong><em>: Partitioning improves throughput.</em></blockquote><blockquote><strong><em>Consistency</em></strong><em>: Eventual consistency is sufficient for most designs. Read after write consistency might be desirable in most use cases where the user mutates state (e.g. when a user deposits a check and refreshes a page, they should continue to see a pending balance rather than it appearing/disappearing which can happen if the request is served by a replica that has not caught up).</em></blockquote><h4>2. Data modeling &amp; APIs</h4><p>Once you’ve established the bounds of the problem, the next step is to identify the main entities and how they relate with each other. For e.g. for Twitter’s timeline, the entities are User, Tweet &amp; Follower. You should identify the primary keys, foreign keys, indexes &amp; the relation between the entities (one-one, one-many, many-many etc).</p><p>Establishing the data model will allow you to recommend the underlying database technology. If joins and/or transactionality are required, relational databases (MySql/AuroraDB/Spanner) are an appropriate choice. If the query patterns are simple (e.g. simple gets &amp; puts), a nosql database like DynamoDB might be appropriate since it can support higher throughput and scales better than SQL databases. Nosql is also great for representing documents with a one-many schema representation forming a tree structure. DDIA’s chapter on Data Models &amp; Query languages is a good resource to help gain familiarity with the various database technologies.</p><p>At this step, you should also check with your interviewer if you should define APIs. If the data model is simple, there will be a good deal of overlap between the data model &amp; APIs so you can save some time by skipping the API definition.</p><h4>3. System architecture (component diagrams)</h4><p>Start simple — no need for drawing out load balancers and partitions at this stage. Draw out the main services &amp; talk about their interactions. Look for parts that can be made asynchronous via queues (queues can handle spiky traffic, reduce jitter &amp; can reduce latency). Zoom in on important parts of the design — How do you handle idempotency? Do you require locks to handle concurrent writes?</p><h4>4. Failure scenarios</h4><p>This is the most overlooked part of the system design &amp; is glossed over by most online resources like grokking/system design primer. This is especially relevant for Senior &amp; Staff engineers as consideration for robustness is factored into your levelling.</p><blockquote>In modern micro-service architecture, you should design with failure in mind. A system that can gracefully handle failures is superior to a system which is designed to “not fail” because when these systems do encounter failures (and they inevitably do), they tend to be difficult to recover from, or are in some cases downright catastrophic.</blockquote><p>You should cover both application level &amp; system level failures. Here are some discussion points — what happens when a request times out &amp; returns a 500? How would your system behave when the database is degraded? What happens if you mutate state and your service is unable to enqueue a message? What if the consumers of your queue fail?</p><p>Eventual consistency is typically a reasonable architecture for modern day systems. This comes with its own set of challenges of course — failures can result in two services being in an inconsistent state. How would you detect &amp; fix these inconsistencies? (typically you’d need a healing cron or another offline service which can detect &amp; mitigate inconsistencies).</p><p>It’s also worth talking about system level failures. What happens when a node goes down? Can it cause a thundering herd? How does failover happen? Would you use active-active or active-passive modes for redundancy? Bonus points for mentioning how new leaders are elected and what can go wrong when the leader dies (split brain, data loss due to replication lag etc. Read Chapter 5 — Replication from DDIA).</p><h4>5. Scaling</h4><p>You should talk about horizontal scaling &amp; how you’d increase throughput via partition and whether you’d partition by range or by hash. You should be familiar with Zookeeper &amp; how the routing tier works. Mention caching (CDNs, Caching servers) which not only decrease latency but also prevent traffic from hitting your application servers. DDIA’s chapter on Partitioning covers this in detail.</p><h3>Conclusion</h3><p>Conclude the design by commenting on observability &amp; monitoring. You should also touch on security (SSL/TLS) and data encryption.</p><p>If you manage to cover all 5 steps during your interview, you’ve probably nailed it. Time management is an important piece of the interview so keep a stop-watch on your desk.</p><p>In my next few articles, I’ll discuss the best tool (e.g. google docs, whiteboard etc) for the interview &amp; go over an example problem following the recommended format.</p><p><a href="https://medium.com/@chivagarg">Follow me on Medium</a> to be notified whenever I publish a new article. If you are preparing for a software engineering interview, you might find <a href="https://chivagarg.medium.com/be-agile-not-prolific-f0f88b86aace">this</a> article interesting.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7cfc81d49c5b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[System design for dummies — part 1]]></title>
            <link>https://chivagarg.medium.com/system-design-for-dummies-part-1-27e3903435f6?source=rss-7818d68e2f0f------2</link>
            <guid isPermaLink="false">https://medium.com/p/27e3903435f6</guid>
            <category><![CDATA[system-design-interview]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[interview-questions]]></category>
            <category><![CDATA[tech-interview]]></category>
            <dc:creator><![CDATA[S. G.]]></dc:creator>
            <pubDate>Sun, 26 Dec 2021 05:49:52 GMT</pubDate>
            <atom:updated>2022-01-02T06:43:40.891Z</atom:updated>
            <content:encoded><![CDATA[<h3>System design for dummies — part 1</h3><p>Please read <a href="https://chivagarg.medium.com/system-design-for-dummies-part-0-db2afd629502?sk=747a102e052e9905dd067c3552dec8b8">part 0</a> to get an overview of what to expect in this article series.</p><p>This part focuses on the preparation materials required to nail the system design interview. Knowledge alone isn’t sufficient to excel at the system design interview, but a solid theoretical foundation is necessary.</p><p>You’ll need to go for depth as much as for breadth. Go slow &amp; really understand the concepts. Don’t spend more than a couple of hours on a single article or video in one sitting. This is a firehose of information &amp; your ability to absorb &amp; retain knowledge diminishes beyond a certain threshold.</p><p>Be curious — if the article mentions <a href="https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average">exponential moving average</a>, spend a few minutes on wikipedia to understand what exponential moving average is about, and what the common applications are in software (trending topics, auto-complete etc). Re-read &amp; revise. For e.g. Raffi Krikorian’s <a href="https://www.infoq.com/presentations/Twitter-Timeline-Scalability/">Twitter timelines at scale</a> is a 38 minute video, but I’d expect you to spend 1.5–2 hour on watching it. Pause the video when you don’t understand a concept. Rewind, rewatch. Take notes. Truly internalize it. At the end of the video you should know every little nuance — what does it mean to scatter-gather? What happens when a user’s home timeline falls out of the redis cluster? What trade-offs did twitter make when designing for time-lines at scale (you can’t scroll more than 800 tweets etc). Go the extra mile — grab a pen &amp; paper a couple of days later &amp; reconstruct the design by yourself. That’s how you’ll internalize it.</p><p>Here are the resources I recommend covering. I recommend starting with the system design primer but don’t prescribe a specific order for the other resources. Learning isn’t linear. Jump from a video to an article and back to a chapter from Designing Data Intensive Applications. Maybe you’ll read the chapter on Stream Processing and then jump to the video on streaming a million likes a second. Go back and revise what you’ve already covered. Make your own notes that summarize key concepts that you can go over quickly when revising.</p><p><a href="https://github.com/donnemartin/system-design-primer">The System Design Primer</a>: This one is about breadth rather than depth. Read ALL of it &amp; get familiar with the various technologies (CDNs, caching strategies, RPCs, DNS etc). This source covers the basic building block which will allow you to go really deep.</p><p><a href="https://dataintensive.net/">Designing Data Intensive Applications</a>: This is an excellent book and as you read through it, you’ll understand why the System Design Primer is inadequate. This book will help you become a better engineer and generally improve your understanding of large scale distributed systems. You really need to chew &amp; digest the concepts in here. Underline things that are insightful to you. Make notes that you can refer to later. Although the book is over 500 pages long, there is very little in the book that is not useful and in spite of over a decade of building large scale systems, I learnt a lot. It will help you understand why you’d use NoSQL or RDS or GraphQL, how replication improves redundancy &amp; partitioning improves throughput, what the various levels of transactional serializability are &amp; why distributed transactions are complex and expensive. You’ll also learn about MapReduce, stream processing (Kafka) &amp; Zookeeper. If there is a single thing that I want you to take away from this article, this book is it.</p><p>Videos: InfoHQ &amp; YouTube host videos that give you an insider peek into how large scale distributed systems are built around the world. I encourage you to watch these videos even outside of your system design preparation to incorporate good design principles into your own designs. Here are some that I recommend watching:</p><ul><li><strong>Twitter timelines at scale:</strong> This is one of my favorite system design videos of all time. You’ll learn about fan-out, making the trade-offs between write time optimization vs read time optimizations, and performance optimizations between polling &amp; fan-out.</li></ul><p><a href="https://www.infoq.com/presentations/Twitter-Timeline-Scalability/">Timelines at Scale</a></p><ul><li><strong>How twitter handles 3000 images per second:</strong> Great talk on how to decouple media uploads from tweeting. The learning from this can be applied to many system design problems.</li></ul><p><a href="https://www.facebook.com/watch/?v=1708070772799353">3000 images per second - Henna Kermani</a></p><ul><li><strong>Scaling Push Messaging for Millions of Netflix Devices:</strong> It will help you understand how websockets are implemented at scale &amp; the complexities that can arise during deploys &amp; outages.</li></ul><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FIdR6N9B-S1E%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DIdR6N9B-S1E&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FIdR6N9B-S1E%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/c5121102352b9ff851363f6e5b989d65/href">https://medium.com/media/c5121102352b9ff851363f6e5b989d65/href</a></iframe><ul><li><strong>Scaling Facebook Live Videos to a Billion Users:</strong> Facebook’s live-streaming infrastructure &amp; the challenges of scaling it.</li></ul><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FIO4teCbHvZw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DIO4teCbHvZw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FIO4teCbHvZw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/c86a6afea6a8be095faf3a95bede7a81/href">https://medium.com/media/c86a6afea6a8be095faf3a95bede7a81/href</a></iframe><ul><li><strong>Streaming a Million Likes/Second:</strong> Facebook’s real-time interaction platform.</li></ul><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fyqc3PPmHvrA%3Fstart%3D1%26feature%3Doembed%26start%3D1&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dyqc3PPmHvrA&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fyqc3PPmHvrA%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/23019dc5db5ae6af2711fb505c0b7911/href">https://medium.com/media/23019dc5db5ae6af2711fb505c0b7911/href</a></iframe><p>Articles: While the videos above go pretty deep, it’s important to understand a breadth of concepts. The following articles will supplement your learnings from the videos above:</p><ul><li><a href="https://www.infoq.com/articles/apache-kafka/">Apache Kafka &amp; Zookeeper</a></li><li><a href="https://www.figma.com/blog/how-figmas-multiplayer-technology-works/">Figma’s multiplayer technology</a></li><li><a href="https://www.infoq.com/articles/whats-the-next-step-for-data-management/?topicPageSponsorship=e3a72ba4-405f-4d53-a346-2c7630f0d140&amp;itm_source=articles_about_Streaming&amp;itm_medium=link&amp;itm_campaign=Streaming">Stream processors &amp; stream joins</a></li><li><a href="https://stackoverflow.com/questions/27793721/what-is-the-difference-between-lucene-and-elasticsearch">Stackoverflow: Lucene vs Elasticsearch</a></li><li><a href="https://stackoverflow.com/questions/47085281/do-websocket-implementations-use-http-protocol-internally">Stackoverflow: Websockets vs HTTP</a></li></ul><p><a href="https://www.educative.io/courses/grokking-the-system-design-interview">Grokking the system design</a>: This series is mediocre at best. My main criticism is that there is too much hand-waving. While the author has definitely spent some time reading white-papers, it lacks the depth &amp; attention to detail that you’d expect from staff engineers. For example, the article on Typeahead suggestions doesn’t even discuss streaming as a solution to building derived data. In most of the articles, there is little/no emphasis on mitigating failure cases. For e.g. when designing Facebook Messenger, there is no mention of the thundering herd problem which will happen if a node goes down &amp; all clients reconnect to a different node at the same time (this is covered in depth in <a href="https://www.youtube.com/watch?v=IdR6N9B-S1E">this talk</a>). Nevertheless, I recommend grokking because it covers the most commonly asked system design problems and it will help guide your high level design. When studying grokking, focus on the details and understand concepts like QuadTrees (for geo-fencing), Bloom filters, Checksums for preventing storage of redundant file chunks etc. As an alternative (or supplement) to grokking, I recommend <a href="https://www.amazon.com/System-Design-Interview-Insiders-Guide-ebook/dp/B08B3FWYBX/ref=sr_1_1_sspa?keywords=system+design+interview+alex+xu&amp;qid=1640414720&amp;sprefix=system+design+interview%2Caps%2C395&amp;sr=8-1-spons&amp;psc=1&amp;spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUFNMjFQN0hYQTNBRUkmZW5jcnlwdGVkSWQ9QTA2NjA1MTkyRUNGTTZBVzZZTzkmZW5jcnlwdGVkQWRJZD1BMDM3NTc0ODNPR1pSNUowVkE3TkMmd2lkZ2V0TmFtZT1zcF9hdGYmYWN0aW9uPWNsaWNrUmVkaXJlY3QmZG9Ob3RMb2dDbGljaz10cnVl">System Design Interview</a> by Alex Xu as it goes one level deeper than Grokking.</p><p>These resources will get you 90% of the way to nailing the system design interview. I’ll repeat what I’ve said before. Don’t be in a rush — you can’t become an expert in a single sitting.</p><p>In <a href="https://chivagarg.medium.com/system-design-for-dummies-part-2-7cfc81d49c5b">part 2</a>, I recommend the format you should follow during the system design interview.</p><p><a href="https://medium.com/@chivagarg">Follow me on Medium</a> to be notified whenever I publish a new article.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=27e3903435f6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[System design for dummies — Part 0]]></title>
            <link>https://chivagarg.medium.com/system-design-for-dummies-part-0-db2afd629502?source=rss-7818d68e2f0f------2</link>
            <guid isPermaLink="false">https://medium.com/p/db2afd629502</guid>
            <category><![CDATA[interview-preparation]]></category>
            <category><![CDATA[tech-interview]]></category>
            <category><![CDATA[interview-tips]]></category>
            <category><![CDATA[system-design-interview]]></category>
            <dc:creator><![CDATA[S. G.]]></dc:creator>
            <pubDate>Fri, 24 Dec 2021 06:10:11 GMT</pubDate>
            <atom:updated>2021-12-30T05:44:33.389Z</atom:updated>
            <content:encoded><![CDATA[<h3>System design for dummies — part 0</h3><p>If the system design interview has always been your achilles heel, this article is for you. It definitely used to be mine. Unlike coding interviews which are fairly unambiguous, there isn’t much material on preparing for the design interviews. Google searches on how to prepare inevitably take you to two main sources —<a href="https://github.com/donnemartin/system-design-primer"> the System Design Primer</a> &amp; <a href="https://www.educative.io/courses/grokking-the-system-design-interview">Grokking the System Design interview</a>. Like most others, I simply relied on these two sources for my preparation. However, no matter how many times I’d read these two, I just couldn’t nail the design interviews (although I did scrape through a couple). While these two sources have some merit &amp; they should play a role in your system design preparation, they are inadequate.</p><p>I’m finally at a point where system design interviews don’t cause knots in my belly. There is some nervousness, of course, but also excitement derived from confidence. I can pass roughly 75% of my system design interviews at the T6 (staff engineer) level. I figured it out through a combination of trial &amp; error and thoughtful deliberation.</p><p>Let me preface this by saying that acing the design interview will take time &amp; deliberate practice. You just can’t cram your way through. No amount of grokking will let you ace this one (although it might allow you to clear the L4 bar).</p><blockquote>Francis Bacon said “Some books are to be tasted, others to be swallowed, and some few to be chewed and digested.”</blockquote><p>Translation: some books are to be read only in parts; others to be read, but not curiously; and some few are to be read wholly, and with diligence and attention. For the system design interview, you’ll need to put your molars to good use. There’s going to be plenty of chewing and lots of digesting. You’ll need to read &amp; re-read 100s of pages. You’ll need to watch &amp; re-watch dozens of videos. You’ll need to take notes, revise your notes &amp; become a scholar. You’ll need to understand concepts so deeply that you can recite them in your sleep.</p><p>I’ve only gotten to where I am today by failing several system design interviews. It’s hard not to feel disheartened by rejections but rejections are learning moments. <a href="https://chivagarg.medium.com/be-agile-not-prolific-f0f88b86aace?sk=b54bf971bfe4c18e9f1f7e4059e044a4">I’m a strong proponent of failing-fast</a> and I view failures as opportunities to refine my process. I’ve obsessed over my failed system design interviews for days after- replaying the interview over and over in my head — sifting through my memory for things that I could have done better. Failures have helped me internalize what not to do (<em>that time when I jumped into data-modeling without really establishing the bounds of the problem</em>) and what to do more of (t<em>hat time I forgot to talk about using locks to prevent concurrent client payment attempts</em>).</p><p>This article series is a step by step guide on preparing for (and hopefully nailing) the system design interview. I’m going to cover this in 4 parts. You’re currently reading part 0. Part 1 will list out the materials (books, articles, video series) that you need to “chew &amp; digest”. Part 2 will focus on the right format to follow during the interview &amp; the best tools (pen &amp; paper or google draw?) to use for the job. In the final part, we will incorporate our learnings into a real life interview problem (e.g. <em>design a donations app</em>) &amp; I’ll walk you through my solution.</p><p>This article series is relevant for anyone preparing for system design interviews. These interviews typically determine your level and a good systems design interview performance can be the difference between an L5 (Senior) offer and an L6 (Staff) offer. This article series might be especially pertinent for L5 engineers who are at the cusp of L6, but are unable to crack the system design interview.</p><p>Do you need real life system design experience to nail these interviews?</p><p>The short answer is: probably. If you are interviewing for an L4 role, you might be able to get away without having too much real life experience. For L5 &amp; above, it gets trickier but you can probably interpolate a lot by watching videos/reading articles that I’ll enumerate in part 1.</p><p>For further reading, see <a href="https://chivagarg.medium.com/system-design-for-dummies-part-1-27e3903435f6">part 1</a> of this article series.</p><p><a href="https://medium.com/@chivagarg">Follow me on Medium</a> to be notified whenever I publish a new article.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=db2afd629502" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why Microsoft didn’t love me back]]></title>
            <link>https://medium.com/swlh/why-microsoft-bid-me-an-irish-goodbye-de35bd60e81d?source=rss-7818d68e2f0f------2</link>
            <guid isPermaLink="false">https://medium.com/p/de35bd60e81d</guid>
            <category><![CDATA[lessons-learned]]></category>
            <category><![CDATA[interview]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[microsoft]]></category>
            <dc:creator><![CDATA[S. G.]]></dc:creator>
            <pubDate>Mon, 03 May 2021 05:20:29 GMT</pubDate>
            <atom:updated>2022-07-12T17:26:30.266Z</atom:updated>
            <content:encoded><![CDATA[<p>What are some of the biggest lessons you’ve learnt as a professional Software Engineer?” Marcus asked shyly.</p><p>“And here I was, thinking that I’m the one asking the tough questions” I replied, smiling at him encouragingly.</p><p>I was taking a sabbatical from Software Engineering at Google and spending the Fall teaching at the University of Puerto Rico.</p><p>Marcus was one of the quietest students in my class and he’d never volunteered to ask a question before. Sometimes, after I’d cracked a joke in class, my eyes would meet his, and he would smile fleetingly before looking away shyly, as if embarrassed that I’d caught him smiling. So I was both surprised and pleased when he walked over after class, patiently waited for me to gather my notes and markers and asked me this question.</p><p>I wasn’t a stranger to having students walk up to me to ask questions about being a professional Software Engineer, or about working at Google, or both. Often I’d never even met the students before, but I enjoyed these interactions. I appreciated the warm candor of these questions- the raw inquisitiveness. They likely didn’t have many opportunities to interact with Software Engineers, and were curious about the career they themselves might embark on one day.</p><p>Their questions ranged from the frivolous: “Does Google really have a rule about food being within 200 feet from employees at all times?”<em> (no)</em>, “Can you really have someone do your laundry at work?” <em>(yes)</em> to the more pragmatic- “Should I join the industry or stay in Academia?” <em>(it depends).</em></p><p>I’d been asked the same questions so many times that I always had an answer or quip ready. But this wasn’t a question I’d been asked before. I paused, contemplating how I could condense my decade long experience into a few pearls of wisdom.</p><p>“How about we set up some time to chat about that?” I offered, and Marcus nodded.</p><p>Later that night, I opened my laptop and tried to put down my thoughts into words. Not only do I find writing to be cathartic, but anchoring my thoughts into words usually help me build clarity.</p><p>Marcus’s question prompted a lot of reflection on my life as a Software Engineer. I’ve worked at a Technology Incubator in Ghana, as a Software Engineer at Microsoft &amp; Google and as an ad hoc Professor at the University of Puerto Rico. I’ve flip-flopped between optimism and pessimism. I’ve been an anti-establishment couch potato and a social justice warrior. I have both hated the man and embraced him.</p><p>I decided that I wanted to give Marcus an answer that would be useful to him. I wanted these “lessons’’ to be practical- something that he could be mindful of and get better at as he forayed into the industry. Many of these lessons were learnt from costly mistakes, and I hoped that he could avoid making the same mistakes I did. This blog post stems from my reflections from that night. I hope that you’ll find it useful.</p><h3>Lesson#1: Reputation compounds</h3><p>I worked at Microsoft from 2012 to 2016 and at Google from 2016 to 2020.</p><p>When I announced my departure from Microsoft in 2016, my boss smiled, thanked me for my work and wished me luck. That was it. There was no counter-offer, no attempt to keep me at the company. There wasn’t even a farewell dinner. Walking away from Microsoft was the easiest professional decision I’ve had to make.</p><p>I remember sulking about it to a dear friend and colleague over coffee. “Sounds like Microsoft gave you an <a href="https://en.wikipedia.org/wiki/French_leave">Irish good-bye</a>”, he said, winking.</p><p>I’ve had plenty of time to think about my mediocre 4 year stint with Microsoft. I can’t honestly say that I accumulated 4 years’ worth of knowledge. Initially, I blamed everyone but myself. I blamed the company (“Microsoft’s a dinosaur!”), my team (“It’s because of the constant re-orgs!”), my management (“It’s because I was punted from manager to manager!”) and the projects (“I was given low impact/uninteresting projects!”).</p><p>Since then, I’ve come to realize that reorgs, restructuring and changes in management are inevitable in companies at the Microsoft/Google scale. I’ve also improved at self reflection. “My experience sucked because I wasn’t given good projects” is a bit like saying “I got a speeding ticket because there were a lot of cops patrolling”. Factually correct, but obfuscates the underlying issue. What’s the <a href="https://en.wikipedia.org/wiki/First_principle">first principle</a> here? Why wasn’t I given good projects in the first place?</p><p>In the fall of 2020, when I told my manager that I intended to move on from Google, he was visibly upset. Both my manager &amp; my director tried their hardest to keep me at the company. They offered me more money and juicier projects. Former colleagues and managers messaged me about my departure, often with offers to join their teams. Walking away from Google was one of the hardest professional decisions I’ve had to make.</p><p>The main difference between my tenure at Google and Microsoft was the reputation I had for my craft. And my attitude fed my reputation.</p><p>I joined Microsoft in my early 20s and at a stage of my life where my career just wasn’t my priority. I don’t necessarily judge myself for it — I was young, single, hedonistic, living in a new city and making decent money. But I developed a reputation for someone who needed constant guidance- someone who “wanted it easy”. And this reputation was hard to shake off long after my attitude towards my job changed.</p><p>In 2014, Satya Nadella took over the reigns of Microsoft and orchestrated a <a href="https://techcrunch.com/2019/02/04/after-5-years-microsoft-ceo-satya-nadella-has-transformed-more-than-the-stock-price/">shake-up</a> of the prevailing software development process at Microsoft by ruthlessly reducing certain roles. Prior to 2014, most teams at Microsoft were staffed with one quality engineer (called Software Development Engineer in Test or SDET) for every developer. SDETs were responsible for testing the code that developers wrote. In contrast, typical companies in Silicon Valley today have 1 quality engineer per team of 12–20 developers.</p><p>As a consequence of the restructuring, majority of the SDETs on my team resigned (or were fired) and the team shrank down to 6 people who were responsible for overall quality. I was the only developer included in this team of former SDETs. I learnt from a mentor that management thought that this team would be a better fit for me since it wasn’t a critical/core team.</p><p>It didn’t matter that I had put my act together in the several months leading to this reshuffle &amp; was producing high quality work. The reputation I’d developed overrode what I was actually delivering. Once I’d been assigned to a low impact team, I ended up working on low impact projects and delivering low value to the company. This culminated into what I call the cycle of dispensability, which can be quite detrimental to career growth.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/1*6rZgVZNaqDbVb6Xfp8rFow.png" /><figcaption>Cycle of dispensability</figcaption></figure><p>First impressions matter. Once you develop a poor reputation, it takes a disproportionate amount of effort to reverse that. Your first 6 months at a new company will be your most important. The reputation you develop will determine the kind of projects you get to work on, which will further feed into your reputation. Reputation compounds.</p><p>By the time I joined Google, I was determined not to make the same mistakes again. I hit the ground running, and those first 6 months were probably the hardest I’ve worked. I taught myself mobile and backend development, learnt about java services and Spanner.</p><p>Pretty soon, I developed a solid reputation. Within a year, I was getting the pick of the projects and within a couple more, I was leading the highest impact projects for my team. Yes, there were re-orgs and manager changes but the reputation I’d developed stuck to me, and was almost magically transferred from manager to manager. My reputation gave me leverage to craft the life I wanted. Almost every year, I took a month off to travel. I often worked remotely, from different countries, and got to work on super fun projects.</p><p>Work on building a cycle of indispensability. You’ll reap the benefits of it for many years.</p><p>This is the first part of a multi-part series where I will discuss the biggest lessons I’ve learnt as a professional Software Engineer. <a href="https://medium.com/@chivagarg">Follow me</a> to be notified whenever I publish a follow-up to this article.</p><p>If you are interested in interviewing or programming, you might also want to check out <a href="https://medium.com/swlh/the-leetcode-phenomena-e9ec4de41ca">“The LeetCode Phenomenon”</a> or <a href="https://medium.com/swlh/stop-adding-comments-to-your-code-80a3575519ad">“No comments.”</a></p><p>Credits: Icons in the comic strip made by <a href="https://www.flaticon.com/authors/freepik">Freepik</a> from <a href="https://www.flaticon.com/">Flaticon</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=de35bd60e81d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swlh/why-microsoft-bid-me-an-irish-goodbye-de35bd60e81d">Why Microsoft didn’t love me back</a> was originally published in <a href="https://medium.com/swlh">The Startup</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Stop Adding Comments to Your Code]]></title>
            <link>https://medium.com/swlh/stop-adding-comments-to-your-code-80a3575519ad?source=rss-7818d68e2f0f------2</link>
            <guid isPermaLink="false">https://medium.com/p/80a3575519ad</guid>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[S. G.]]></dc:creator>
            <pubDate>Fri, 01 Jan 2021 04:27:57 GMT</pubDate>
            <atom:updated>2022-08-05T18:49:25.696Z</atom:updated>
            <content:encoded><![CDATA[<h3>// No comments</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vKbW_AO8mNssbMVsY7zdFA.png" /></figure><p>“Comments should account for 5% of the total points” my fellow teacher declared.</p><p>In the fall of 2019, I was co-teaching an introductory course in computer programming and got into a disagreement on whether the students should be required to incorporate comments into their project submission.</p><p>“I want the students to develop good practices early on in their career. Surely, you’ll agree that adding comments improves code quality?” the fellow teacher asked me, almost righteously, a little miffed at my pushback.</p><p>I disagreed, and emphatically. Being encouraged to sprinkle comments everywhere is probably the worst programming practice being taught in school. Barring certain cases where comments are justified (I cover that later), adding comments is an anti-pattern, and an excessively commented code-base suggests a need to refactor.</p><p><em>Wait, what is this heresy? Comments can’t possibly hurt. Can they?</em></p><p>Here are the two reasons why I consider comments to be an anti-pattern:</p><ol><li>They invariably go out of date. People forget to update comments as code gets refactored and features are developed. When this happens, comments become the root cause of the very thing they are meant to avoid — confusion. This is especially true at large companies where there are several people actively changing a common codebase. Imagine the plight of a poor new hire who just can’t wrap his head around why the house has an empathic comment calling it a Palm Tree.</li><li>Programmers (myself included) write comments that are redundant or poor. I’ve observed this to be the case at every company I’ve worked at and many excellent programmers are guilty of this. On my team at a prominent big tech company, we had a rule that every single protocol buffer definition needed to be preceded by a comment. So we had way too many instances of code that looked like the following:</li></ol><pre>// Represents a Dog.<br>message Dog {<br>    // The id of the dog.<br>    string id = 0;<br>    // The name of the dog.<br>    string name = 1;<br>    // The breed of the dog.<br>    string breed = 2;<br>}</pre><p>Redundant comments are noise, and can make files twice as long as they need to be.</p><p><em>Allrighty, I see your point. Redundant comments are dumb. But what about the instances where comments are needed to explain what my code is doing?</em></p><p>You can almost always find other ways to convey what your code is doing. A common strategy is to use well named temporary variables or method names to convey intention. Let’s look at a concrete example in code. I’m using python, since it’s most pseudo-code like, but the concept is programming language agnostic.</p><p>In this example, we are sending payouts to sellers when certain conditions are met. An example would be a seller on Amazon receiving lump sum payments for their sales on the platform:</p><pre># Seller is eligible to be paid under the following conditions:<br># 1. It&#39;s past 2020/5/1 when we got legal approval to make payouts<br># 2. It’s Nov/Dec since those are the only months eligible<br># 3. User is not from list of countries that are banned</pre><pre>today = date.today()</pre><pre>if today &gt; date(2020, 1, 1) and (today.month == 11 or today.month == 12) and user.country not in [&#39;Narnia&#39;, &#39;Odan&#39;, &#39;Maldonia&#39;]:<br>    # This function does the actual payout by calling Stripe<br>    # It saves the response asynchronously.<br>    payoutHandler()</pre><p>At first glance, it seems like comments are justified since they do enhance readability. Code is read many more times than it is written and so making code readable is a good thing. In this example, comments convey the following information:</p><ol><li>The conditions for making a payout. Without the comment at the start, the burden is on the reader to parse the verbose sub-conditions in the if statement to understand if the payout should happen.</li><li>Why certain constants (2020/5/1, 11, 12 and [‘Narnia’, ‘Odan’, ‘Maldonia’]) are used and what they represent.</li><li>What the payoutHandler() method will do.</li></ol><p>Now let’s look at how this code can be re-written to convey the same information without using comments:</p><pre>PAYOUT_APPROVAL_DATE = date(2020, 5, 1)<br>BANNED_COUNTRIES = [&#39;Narnia&#39;, &#39;Odan&#39;, &#39;Maldonia&#39;]<br>NOVEMBER, DECEMBER = 11, 12<br>ELIGIBLE_MONTHS = [NOVEMBER, DECEMBER]</pre><pre>today = date.today()<br>is_past_approval_date = today &gt; PAYOUT_APPROVAL_DATE<br>is_eligible_month = today.month in ELIGIBLE_MONTHS<br>is_user_from_banned_country = user.country in BANNED_COUNTRIES</pre><pre>if is_past_approval_date and is_eligible_month and not is_user_from_banned_country:<br> stripe_payout_resp = callStripeToPayout(user)<br> saveResponseAsync(stripe_payout_resp)</pre><p>You’ll notice that the information that was being conveyed by comments is now being conveyed by using temporary variables (is_past_approval_date, is_eligible_month, is_user_from_banned_country), constants (BANNED_COUNTRIES) and verbs as function names.</p><p>Good naming is a powerful tool that can replace comments and help you write self-documenting code. Now this code can be refactored mercilessly without any fear of the house being mis-documented as a tree.</p><p><em>Ok, so is it really never cool to add comments? That sounds draconian.</em></p><p>Here’s my rule of thumb — don’t use comments to explain the what. Instead, <em>use them to explain the why</em><strong><em>, </em></strong><em>and only when you can’t convey the why through naming</em>. In most cases you can leverage on good naming to convey the why. For e.g. instead of adding this comment:</p><pre># This code removes the invalid control characters because the <br># AS400 processor cannot handle them</pre><p>name your function</p><pre>def remove_AS400_incompatible_control_chars():</pre><p>If you can’t rely on naming to get the message across — for e.g. if your code is doing something subtle/non-obvious, then comments are definitely warranted. Here are some examples of useful comments:<br># Prevents a rare but severe race condition which happens when...<br># Closing this write transaction before making the RPC to prevent stale locks</p><p>It might be worth looking at your codebase to see if you can replace some of your existing comments with self-documenting code.</p><p><a href="https://medium.com/@chivagarg">Follow me</a> to be notified whenever I publish an article like this one. If you are interested in interviewing, you might also want to check out my article called <a href="https://chivagarg.medium.com/the-leetcode-phenomena-e9ec4de41ca"><em>“The LeetCode Phenomenon”</em></a><em> </em>or <a href="https://chivagarg.medium.com/why-microsoft-bid-me-an-irish-goodbye-de35bd60e81d"><em>“Why Microsoft didn’t love me back”</em>.</a></p><p>Credits: Icons in the comic strip made by <a href="https://www.flaticon.com/authors/freepik">Freepik</a> from <a href="https://www.flaticon.com/">Flaticon</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=80a3575519ad" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swlh/stop-adding-comments-to-your-code-80a3575519ad">Stop Adding Comments to Your Code</a> was originally published in <a href="https://medium.com/swlh">The Startup</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Be Agile, not Prolific]]></title>
            <link>https://medium.com/swlh/be-agile-not-prolific-f0f88b86aace?source=rss-7818d68e2f0f------2</link>
            <guid isPermaLink="false">https://medium.com/p/f0f88b86aace</guid>
            <category><![CDATA[software-interview]]></category>
            <category><![CDATA[leetcode]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[interview-tips]]></category>
            <dc:creator><![CDATA[S. G.]]></dc:creator>
            <pubDate>Fri, 25 Dec 2020 04:24:45 GMT</pubDate>
            <atom:updated>2022-08-05T18:50:37.290Z</atom:updated>
            <content:encoded><![CDATA[<h3>Agile interview preparation</h3><p><em>This is a follow-up to my previous article </em><a href="https://chivagarg.medium.com/the-leetcode-phenomena-e9ec4de41ca"><em>“The LeetCode Phenomenon”</em></a><em>. While the article is targeted at folks who are struggling with converting interviews into offers, I’ve covered several tips/strategies that will be useful to anyone who is in the process of interviewing or curious about interviewing.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*O-mYaWmWTZp2d74i_w1v2Q.png" /></figure><p>In the fall of 2019, I took a sabbatical from Software Engineering and spent a semester teaching interview preparation at the University of Puerto Rico. I co-taught and co-trail-blazed the course with a well loved and competent Professor.</p><p>I remember looking into the warm, curious eyes of the 30 students who had taken the elective. In their eyes, I saw excitement and expectation. Surely, there was no instructor better equipped to lead the course than a Software Engineer from Google?</p><p>In my first class, I made a mistake. I played <a href="https://www.youtube.com/watch?v=GLcJHC9J7l4&amp;t=30s&amp;ab_channel=LambzyCx">this</a> video. Then I told them that the only thing that stood between them and a juicy tech job offer was practice. “Let’s see how many of you can solve over 150 problems on LeetCode by the end of this semester”, I challenged them.</p><p>I do love the energy and delivery from the video. The crux of it is in this single line — “when you want to succeed, as bad as you want to breathe, then you’ll be successful”. When I was practicing for a half marathon, and struggling for motivation, the video inspired me. Showing this to a class of students who were already motivated to get better at interview preparation was a mistake. I was telling them to do a million push-ups.</p><p>Some students from my class did offers from big tech (Microsoft, Google etc) but many were unsuccessful in spite of having solved over a hundred questions on LeetCode. Friends and colleagues have share similar experiences- they just aren’t seeing success in interviews in spite of having solved hundreds of questions.</p><p>I was raised to believe in hard work. My parents worked long hours, and as a kid I saw cause and effect in action. I studied harder than my class-mates and so I did better than them academically. I’ve had a simple mantra — to master something, you need to practice till you are perfect. Do it over and over till it becomes a part of your muscle memory. 10,000 hours was the magic number proposed by Malcom Gladwell in his book ‘<a href="https://en.wikipedia.org/wiki/Outliers_(book)">Outliers</a>’. Do something for 10,000 hours and you’ll become great at it.</p><p>Let’s say that you give me a large log of wood and an axe to chop some firewood. If I don’t know anything about chopping wood, and start chopping the wood against the grain, I’m not going to get you any firewood. I can spend 10,000 hours wielding my axe against the grain, but I’m going to be a lousy woodcutter.</p><blockquote>Practice makes perfect is incomplete advice. Practice needs to be done intentionally. Only through reflection will I realize that I need to chop with the grain, and not against it.</blockquote><p>So what if you’ve solved 250 questions on LeetCode, and still can’t get an offer? Does that make you stupid? No, it just makes you bad at <a href="https://www.open.edu/openlearn/ocw/mod/oucontent/view.php?id=51386">reflection</a>.</p><p>Of course, given infinite time and infinite patience, you can brute force your way through the process by solving hundreds, or thousands of problems on LeetCode. But it’s inefficient. In reality, you’re probably studying or working full-time, and time spent on learning esoteric problems on LeetCode is time that you spend away from other things that are important.</p><p>The traditional approach to interview preparation is like this: you practice problems on LeetCode till you decide that you are interview ready. Then you line up as many interviews as you can and start interviewing. Perhaps you’ll take 2 weeks off from work and schedule the interview loops back to back. I call this the waterfall approach.</p><p>Rather than going with the traditional waterfall approach to interview preparation, make your interview preparation agile.</p><blockquote>Agile interviewing structures preparation in <a href="https://www.atlassian.com/agile/scrum/sprints">sprints</a>, with reflection at the core. Your objective is to iterate and fail fast. Each sprint should incorporate reflection, intentional practice, mock interviews and real interviews. Repeat this till you get a job that you want. The agile approach is optimal because you end up spending no more effort on preparation than is required to actually get the job that you want.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*m-N62vmlVxpQbPu-WSgZzQ.png" /></figure><p>Not all sprints will be equal. Your first sprint will be the longest, especially if you haven’t interviewed in a while or are out of touch with data structures. Don’t wait to solve a hundred problems on LeetCode before you start interviewing. Don’t line up 10 interview loops over 2 weeks. You’re depriving yourself of a chance to reflect and course correct. You’re probably going to fail your first interview. Heck, you’re probably going to fail several interviews. Stagger interviews over sprints so that you have time to reflect on how you can get better.</p><h3>Reflection</h3><p>The objective is to identify gaps in your preparation.</p><p>In your first sprint, you’ll need to spend time to understand what you don’t know. When I started interviewing this year, I quickly realized that I needed to brush up on heaps and backtracking.</p><p>Second sprint onwards, it’s about looking back at your interviews and identifying areas of improvement. Replay the interviews in your head and write down your insights. Do this soon after the interview when it’s fresh in your head. What could you have done better? Were you too nervous? Did you make some unwarranted assumptions or ignore a large part of the problem? Or maybe you really need to brush up on fundamentals of Graph theory.</p><blockquote>Be shameless in asking for feedback.</blockquote><p>Most companies will decline your request, but some will be kind enough to offer constructive feedback. For example, Shopify told me that I didn’t spend enough time discussing failure/edge cases during my System Design rounds. Square told me that my coding seemed more reactive than proactive. Feedback is gold, and you should internalize it through intentional practice.</p><h3>Intentional practice</h3><p>The objective is to work on your weaknesses and get incrementally better.</p><p>How/what you need to spend time on will depend on your reflection but here are some general tips:</p><p>Don’t shoot for solving a certain number of problems on LeetCode.</p><ul><li>Instead, go for breadth and solve different categories of problems (backtracking, merging intervals, sorting via heaps, maze traversals etc). Try to solve problems in several different ways. Focus on understanding the various techniques. Look at a couple of top-voted submissions. You’re bound to learn a thing or two.</li></ul><p>The coding problem you’ll be asked will be of a medium difficulty.</p><ul><li>Exceptions aside, interviewers aren’t going to expect you to know esoteric algorithms/data structures (e.g. Segment Trees, KMP etc). You won’t be asked to solve LeetCode hard problems in 30 minutes. When interviewing for Google, I used to like asking a very simple problem based on strings.</li></ul><p>Skip dynamic programming.</p><ul><li>It’s not worth the time and most interviews will be perfectly fine if you use recursion rather than dynamic programming to solve the problem. My friends at Facebook tell me that they are explicitly asked to avoid asking problems on dynamic programming since they aren’t a good representation of work you’d be doing. The number of times I’ve used dynamic programming at work over the last 10 years is a big fat zero.</li></ul><p>Don’t rush, and incorporate “<a href="https://en.wikipedia.org/wiki/Spaced_repetition#:~:text=Spaced%20repetition%20is%20a%20method,fact%20is%20presented%20or%20said.">spaced-repetition</a>”</p><ul><li>If you aren’t able to solve a problem, don’t just read the solution and move on. At my interview prep course, I gave my students a list of 40 questions in advance and told them that their midterm quiz would be one of the 40 questions. Students who had simply “read” through the solutions didn’t fare well.</li><li>Whenever you do end up looking at a solution, or discover a new interesting way to solve a problem, you need to revise it at frequent intervals in order to internalize it. You can keep track of what and when you need to revise by simply using a spreadsheet, or by adding events to your Google Calendar. You can use a fibonacci pattern (e.g. revise on day 3, 5, 8, 13, 21 etc). Alternatively, you can use apps like Anki that have spaced repetition built in.</li></ul><p>Practice being proactive and thinking through failure cases.</p><ul><li>This is a part of the rubric used to assess your coding. When LeetCoding, think through the edge cases and do a dry run before hitting Submit. Develop the habit of minimizing the tweaks you need to make to your code to get a passing submission.</li></ul><h3>Mock interviews</h3><p>The objective is to practice in a simulated but real interview environment. Think of this stage like releasing your feature to a staging/sandbox environment.</p><p>Talking out loud or being observed during coding isn’t natural. You need to normalize this so that you can give your best performance and avoid the dreaded “brain-freeze”.</p><p>There are plenty of free resources that will let you simulate real interviews. Sign up for <a href="https://www.pramp.com/#/">pramp</a> which lets you practice 1:1 with peers. It’s also a great resource for those who want to follow the sprint model but aren’t able to get many real interviews.</p><p>If you are privileged enough to easily get interview calls, you can skip this and go straight to the real interviews.</p><h3>Real Interviews</h3><p>The objective is to give it your best shot and collect data for your next sprint. Schedule 2–3 interviews at a time to understand where you stand.</p><p>Find the time of day that you’re most in flow. Find what works best for you. Maybe a run or a workout before the interview helps put you at ease.</p><p>Once you get an offer that you’re ready to sign, you can try to blitz your way through several more with the goal of obtaining some counter offers. Once you mention to a recruiter that you have an offer and deadline, companies will rush to finish your interview loop.</p><h3>Build a routine that works for you.</h3><p>Don’t be rigid with your sprints- the goal is to build the preparation model that works best for you. You might find that it’s best to skip mock interview entirely or you might find yourself jumping from intentional practice to reflection several times within a sprint:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2wWRFYBx9Kq0CTtN018eEQ.png" /></figure><p>The interview process is a marathon. Depending on where your skill levels are at, the process can take anywhere between 1 month to 2 years. Be patient and learn from your mistakes. At the risk of sounding cheesy, I’ll quote Confucius:</p><blockquote>Our greatest glory is not in never falling, but in rising every time we fall.</blockquote><p>This article was focused on coding interviews. The system design interview is an entirely different beast altogether, and I plan to cover that next. <a href="https://medium.com/@chivagarg">Follow me on Medium</a> to be notified whenever I publish it.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f0f88b86aace" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swlh/be-agile-not-prolific-f0f88b86aace">Be Agile, not Prolific</a> was originally published in <a href="https://medium.com/swlh">The Startup</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The LeetCode Phenomena]]></title>
            <link>https://medium.com/swlh/the-leetcode-phenomena-e9ec4de41ca?source=rss-7818d68e2f0f------2</link>
            <guid isPermaLink="false">https://medium.com/p/e9ec4de41ca</guid>
            <category><![CDATA[interview]]></category>
            <category><![CDATA[interview-preparation]]></category>
            <category><![CDATA[leetcode]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[S. G.]]></dc:creator>
            <pubDate>Mon, 09 Nov 2020 23:17:03 GMT</pubDate>
            <atom:updated>2022-08-05T18:44:33.332Z</atom:updated>
            <content:encoded><![CDATA[<h3>The LeetCode Phenomenon</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KWk2eMomW-2qNGRNpTkhLw.png" /></figure><p>In the winter of 2015, I was working as a Software Engineer at Microsoft and looking for my next Software Engineering job <a href="https://chivagarg.medium.com/why-microsoft-bid-me-an-irish-goodbye-de35bd60e81d">(here’s why)</a>, albeit with little success. I remember expressing my frustration to a friend over a velvety Stout beer at a funky bar in Seattle’s Ballard neighborhood on a cold, rainy November night. I remember his words clearly:</p><blockquote>“So, there is this platform which sort of lets you game the System”</blockquote><p>That’s when I first heard about <a href="https://leetcode.com/">LeetCode</a>- a programming platform which has now become the staple for coding interview preparation. The platform consists of interview style coding questions with an integrated, online IDE which lets you submit and verify the correctness of your solution. It also contains a stack-overflow style discussion forum which lets you post and upvote/downvote solutions to the problems.</p><p>Today, if you are interview prepping, you’re going to have to spend some late evenings practicing interview problems on LeetCode. In the words of one of my good friends and colleague:</p><blockquote>LeetCode is the great equalizer. Whether you are interviewing for an internship, as a fresh grad just out of college, or as a seasoned Engineering Manager, you’d better be LeetCoding.</blockquote><p>I crawled home from the bar that November evening and started practicing problems on LeetCode. Over the next few weeks I practiced several dozen problems. Practicing made a huge difference that time and I eventually landed and accepted an offer from Google in 2016.</p><p>I’d never seen anything like LeetCode before. Platforms I’d been using for interview preparation before LeetCode had been passive — with information flowing in one direction (from the author to me). There was the quintessential interview preparation book “<a href="https://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/0984782850/ref=sr_1_3?dchild=1&amp;gclid=Cj0KCQiA7qP9BRCLARIsABDaZzh2hz3vvmXO6wkXiVZjlQiIwvMEOVWP-CqhW3gtLv4EV1l8qHwqR5QaAibwEALw_wcB&amp;hvadid=241870593966&amp;hvdev=c&amp;hvlocphy=9033152&amp;hvnetw=g&amp;hvqmt=e&amp;hvrand=16051397797807269276&amp;hvtargid=kwd-20040243067&amp;hydadcr=16409_10304044&amp;keywords=cracking+the+coding+interview&amp;qid=1604960754&amp;sr=8-3&amp;tag=googhydr-20">Cracking the Coding Interview</a>”. Then there was CareerCup/Glassdoor which had user generated content that could be perused to find commonly asked interview questions. The main shortcomings of these platforms are:</p><ol><li>They don’t really prepare you for interviews because they diverge from how real-world interviews are conducted</li><li>They are less engaging (due to a lack of a community)</li><li>It’s harder to internalize concepts/learning due to a lack of reflection. This is because you are offered one (or zero) solution to problems which can typically be solved in many different ways.</li></ol><p>There were several programming platforms like TopCoder that were interactive and had a browser based IDE. However, these were optimized for competitive programming where the problem description itself would span multiple pages and you’d spend half the time trying to figure out the right input/output format rather than building actual algorithms.</p><p>LeetCode recognized a need and built a platform that was interactive, was closer to how interviews were being conducted in the real world and <em>just worked</em>. LeetCode does its job remarkably well- the problem definitions are succinct, the community is thriving and discussion forums have high quality discussions.</p><p>Fast forward to mid 2020, and I was interviewing again. The coding interviews seemed a lot different from 2016, not only because we were in the middle of a pandemic (not the focus of this article), but also because how LeetCode had evolved as a platform.</p><blockquote>LeetCoding was a verb now, and the system which barely had 150 questions in 2016 had over a 1000 questions now, with weekly competitions, gamification (you can earn “LeetCoins” for solving problems) and even something which I’ve named the “cheating mode”, which is a compilation of interview questions that have been reportedly asked by the various companies.</blockquote><p>Here is a screenshot of questions from the platform, showing interview questions tagged by company name:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/245/1*CnwgR3q2S1g90WmzVwLidQ.png" /><figcaption>The platform contains 905 interview questions reportedly asked by Google</figcaption></figure><p>For companies I’ve worked at, I’ve often gone through the list of all interview questions tagged for the company and found <em>several</em> of them on the internal interview question list (Some companies try to fight this by “banning” questions that are publicly known to have been asked).</p><p>The consequence of the “cheating mode” is that the interview bar ends up being raised — largely because the industry is flooded with self proclaimed “Prolific LeetCoders” who have solved over 1000 questions and are hoping to get interview questions that they’ve already solved before. Here is screenshot from the Blind app (an anonymous forum for Tech Employees), where we have a self proclaimed “Prolific LeetCoder” who has solved 1059 of the 1132 questions available on LeetCode:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/328/1*ZCt_RYozh1aUn45efYQnyg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/392/1*G99nM3YvKZakFM61KFHvdQ.png" /><figcaption>A self proclaimed “Prolific LeetCoder” who has solved 1059/1132 problems on the platform</figcaption></figure><p>I did a little thought experiment to see how long it would take me to solve 1059 questions while having a full time job. Based on my experience, it takes approximately 1–1.5 hours to attempt a solution and then look up/research alternative ways to solve the problem. So, solving 1059 questions would take 1059 hours. Assuming that you are trying to prepare while you have a full-time job, and that you dedicate 1.5 hours a day after work to LeetCoding, and never miss a single day, solving 1059 questions will take you a grand total of 1059 days, or approximately 2 years. 2 years?! Ok, WTF.</p><p>Before we get into what you can do to stay competitive, let me point out that trying to solve every single problem on LeetCode with the hope that you will get a question that you’ve already solved has a few issues:</p><ol><li>It’s ethically <em>very</em> dubious. It’s like practicing for a test with leaked questions.</li><li>It just doesn’t scale. You probably don’t have that kind of time. And even if you did, it’s not the best use of your preparation time.</li><li>You’re probably <em>not</em> going to get an interview problem from that list , anyway. This is because what’s tagged is a sub-section of interview questions. And not every company asks LeetCode style questions.</li><li>Having practiced or seen an interview question might actually work against you. As the interviewers are becoming aware of the LeetCode Phenomenon, they are likely to tweak the problems to add/remove constraints which might throw you off.</li></ol><p>Whether you love or hate LeetCode (or what the platform represents), the LeetCode Phenomenon is rampant and pervasive. A few months ago, when I screwed up the coding phone screen interview at Netflix (where I was asked a classic LeetCoding problem that I hadn’t seen before, and was able to solve, just not quickly enough), the empathetic Hiring Manager asked me to <em>brush up on my LeetCoding</em> and to take another shot at the interview in a month or so.</p><p>Companies are taking steps to fight the issue of leaked questions:</p><ol><li>Some companies actively “ban” leaked questions.</li><li>Some companies are constantly creating new questions. At Square, for example, interviewers are asked to create their own interview questions (which are then approved by a committee to keep the bar consistent).</li><li>Then there is a set of companies that don’t ask LeetCode style problems at all (my heroes). Stripe and Shopify have a refreshing approach focused on solving problems that are a more accurate representation of the problems you’d be solving day to day (e.g. sorting a list of items based on a certain constraint). Interviews at Twitter (and certain teams at Netflix) tend to be team specific as well, and usually non LeetCode style. Lyft’s onsite consists of a laptop programming challenge which is open-book and you’re encouraged to use any public library.</li></ol><p>All right, now what are you supposed to do to stay competitive with the Prolific LeetCoders? Surely, there is a better way than cramming 1059 problems? I cover that my follow-up article — <a href="https://chivagarg.medium.com/be-agile-not-prolific-f0f88b86aace">Be Agile, not Prolific.</a></p><p><a href="https://medium.com/@chivagarg">Follow me on Medium</a> to be notified whenever I publish a new article.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e9ec4de41ca" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swlh/the-leetcode-phenomena-e9ec4de41ca">The LeetCode Phenomena</a> was originally published in <a href="https://medium.com/swlh">The Startup</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>