<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Zubin Pratap - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Zubin Pratap - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 16 May 2026 22:22:24 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/zeuslawyer/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Learn Solidity – A Handbook for Smart Contract Development ]]>
                </title>
                <description>
                    <![CDATA[ When I changed careers from lawyer to software engineer in 2018, I never imagined that I’d enjoy being a developer as much as I do. I also never thought I'd end up working for amazing organizations like Google and Chainlink labs. After 15 years in la... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-solidity-handbook/</link>
                <guid isPermaLink="false">66d461d437bd2215d1e24610</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Smart Contracts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Solidity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Wed, 14 Dec 2022 15:45:30 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738338914608/84596494-c070-4dd8-8c9a-399e69f2829a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When I changed careers from <a target="_blank" href="https://www.freecodecamp.org/news/from-lawyer-to-google-engineer/">lawyer to software engineer</a> in 2018, I never imagined that I’d enjoy being a developer as much as I do. I also never thought I'd end up working for amazing organizations <a target="_blank" href="https://www.freecodecamp.org/news/coding-interview-prep-for-big-tech/">like Google</a> and Chainlink labs.</p>
<p>After 15 years in law and other roles, I’d experienced a number of jobs, countries, companies, and career paths. None of them compared to the joy and thrill I get from coding.</p>
<p>The downside? Picking up new coding skills can be confusing, frustrating, and time consuming. And it’s easy to forget some of the minute but important details.</p>
<p>So I wrote this handbook. It's intended to get you started on coding Solidity ASAP. It follows the Pareto Principle (aka the 80/20 rule) by focusing on the 20% of the info that will cover 80% of your needs.</p>
<p>I started assembling these concepts when I was learning Solidity, as part of my role at <a target="_blank" href="http://chain.link">Chainlink Labs</a>. I applied many of the self-learning techniques that I learned when transitioning to coder at the age of 38.</p>
<p>This is the resource I wish I had. It is designed to give beginner and intermediate developers solid mental models to stack as you get deeper into the language (<a target="_blank" href="https://fs.blog/mental-models/#what_are_mental_models">mental models</a> massively accelerate effective learning).</p>
<p>I will keep this handbook updated, but I could really use your help! Just tweet me <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a> to let me know if I need to update this handbook.</p>
<p>I’d like to acknowledge my amazing colleagues <a target="_blank" href="https://twitter.com/@dalteco">Kevin Ryu</a>, <a target="_blank" href="https://twitter.com/@@andrej_dev">Andrej Rakic</a>, <a target="_blank" href="https://twitter.com/PatrickAlphaC">Patrick Collins</a>, and <a target="_blank" href="https://twitter.com/RGottleber">Richard Gottleber</a> for the invaluable guidance and input on this handbook.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-who-is-this-handbook-for">Who is this handbook for?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-essential-prior-knowledge">Essential prior knowledge</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-solidity">What is Solidity?</a></p>
</li>
<li><p><a class="post-section-overview" href="#what-is-a-basic-smart-contract">What is a smart contract?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-declare-variables-and-functions-in-solidity">How to declare variables and functions in Solidity?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-variable-scope-in-smart-contracts">Variable scope in Smart Contracts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-visibility-specifiers-work">How visibility specifiers work</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-constructors">What are constructors?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-interfaces-and-abstract-contracts">Interfaces and abstract contracts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-smart-contract-example-2">Smart contract example #2</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-contract-state">What is contract state?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-state-mutability-keywords-modifiers">State mutability keywords (modifiers)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-data-locations-storage-memory-and-stack">Data locations – storage, memory, and stack</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-typing-works">How typing works</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-solidity-data-types">Solidity data types</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-declare-and-initialize-arrays-in-solidity">How to declare and initialize arrays in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-function-modifiers">What are function modifiers?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-error-handling-in-solidity-require-assert-revert">Error handling in Solidity - require, assert, revert</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-inheritance-in-solidity">Inheritance in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-inheritance-with-constructor-parameters">Inheritance with constructor parameters</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-type-conversion-and-type-casting-in-solidity">Type conversion and type casting in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-work-with-floating-point-numbers-in-solidity">How to work with floating point numbers in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-hashing-abi-encoding-and-decoding">Hashing, ABI encoding and decoding</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-call-contracts-and-use-the-fallback-function">How to call contracts and use the fallback function</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-send-and-receive-ether">How to send and receive Ether</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-solidity-libraries">Solidity libraries</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-events-and-logs-in-solidity">Events and logs in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-time-logic-in-solidity">Time logic in Solidity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion-and-further-resources">Conclusion and further resources</a></p>
</li>
</ol>
<h2 id="heading-who-is-this-handbook-for">Who Is This Handbook For?</h2>
<p>This handbook is for people who are interested in exploring the <a target="_blank" href="https://chain.link/education/web3">vision behind “Web3”</a>, and who wish to acquire in-demand skills that are essential to realizing that vision.</p>
<p>Do not memorize it! Read it and then use it as a “desktop reference” companion. As you learn any new language, you will find that concepts, idioms, and usage can get a bit confusing or your memory fades with time. That’s ok! That’s what this handbook is designed to help you with.</p>
<p>Over time I may add some more advanced topics to this, or create a separate tutorial. But for now this handbook will get you most of the outcomes you require to build your first several Solidity dApps.</p>
<p>This handbook assumes you have at least a few months of experience with programming. By programming I mean at the very least you’ve written in JavaScript or Python or some compiled language (since HTML and CSS aren't actually "programming" languages, it won't be enough to know only them).</p>
<p>The only other requirements are that you are curious, committed, and not putting arbitrary deadlines on yourself.</p>
<p>As long as you have a laptop, and a browser with an internet connection, you’ll be able to run the Solidity code. You can use <a target="_blank" href="https://www.youtube.com/watch?v=JWJWT9cwFbo&amp;list=PLVP9aGDn-X0QwJVbQvuKr-zrh2_DV5M6J&amp;index=47">Remix</a> in your browser to write the code in this handbook. No other IDE required!</p>
<h2 id="heading-essential-prior-knowledge">Essential Prior Knowledge</h2>
<p>I have also assumed that you know the <a target="_blank" href="https://blog.chain.link/what-is-blockchain/">basics of blockchain technology</a>, and in particular you understand the <a target="_blank" href="https://www.youtube.com/watch?v=NsyFGzhktYA&amp;list=PLVP9aGDn-X0QwJVbQvuKr-zrh2_DV5M6J&amp;index=49">basics of Ethereum</a> and <a target="_blank" href="https://chain.link/education/smart-contracts">what smart contracts are</a> (hint: they’re programs that run on blockchains and hence provide special trust-minimized benefits!).</p>
<p>You are unlikely to need them to understand this handbook. But practically speaking, having a browser wallet like <a target="_blank" href="https://metamask.io/">Metamask</a> and understanding <a target="_blank" href="https://info.etherscan.com/understanding-ethereum-accounts/">the difference between Ethereum contract accounts and externally owned accounts</a> will help you get the most out of this handbook.</p>
<h2 id="heading-what-is-solidity">What is Solidity?</h2>
<p>Now, let’s start with understanding what Solidity is. Solidity is an <a target="_blank" href="https://www.freecodecamp.org/news/what-is-object-oriented-programming/">object-oriented programming language</a> influenced by C++, JavaScript and Python.</p>
<p>Solidity is designed to be compiled (converted from human readable to machine readable code) into bytecode that runs on the Ethereum Virtual Machine (EVM). This is the <a target="_blank" href="https://www.techopedia.com/definition/5466/runtime-environment-rte">runtime environment</a> for Solidity code, just like your browser is a runtime environment for JavaScript code.</p>
<p>So, you write Smart Contract code in Solidity, and the compiler converts it into bytecode. Then that bytecode gets deployed and stored on Ethereum (and other EVM-compatible blockchains).</p>
<p>You can get a basic introduction to the EVM and bytecode in <a target="_blank" href="https://www.youtube.com/watch?v=Z7UNjk_roXI&amp;t=1052s">this video I made</a>.</p>
<h2 id="heading-what-is-a-smart-contract">What is a Smart Contract?</h2>
<p>Here is a simple smart contract that works out of the box. It may not look useful, but you’re going to understand a lot of Solidity from just this!</p>
<p>Read it along with each comment to get a sense of what’s going on, and then move on to some key learnings.</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.8.0;<br><br>contract HotFudgeSauce {<br>&nbsp; &nbsp; uint public qtyCups;<br><br>&nbsp; &nbsp; // Get the current hot fudge quantity<br>&nbsp; &nbsp; function get() public view returns (uint) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return qtyCups;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; // Increment hot fudge quantity by 1<br>&nbsp; &nbsp; function increment() public {<br>&nbsp; &nbsp; &nbsp; &nbsp; qtyCups += 1; // same as&nbsp; qtyCups = qtyCups + 1;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; // Function to decrement count by 1<br>&nbsp; &nbsp; function decrement() public {<br>&nbsp; &nbsp; &nbsp; &nbsp; qtyCups -= 1; // same as&nbsp; qtyCups = qtyCups - 1;<br>&nbsp; &nbsp; &nbsp; &nbsp; // What happens if qtyCups = 0 when this func is called?<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>We will get to some of the details like what <code>public</code> and <code>view</code> mean shortly.</p>
<p>For now, take seven key learnings from the above example:</p>
<ol>
<li>The first comment is a machine readable line ( <code>// SPDX-License-Identifier: MIT</code>) that specifies the licensing that covers the code.</li>
</ol>
<p>SPDX license identifiers are strongly recommended, though your code will compile without it. Read more <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.6/layout-of-source-files.html#spdx-license-identifier">here</a>. Also, you can add a comment or “comment out” (suppress) any line by prefixing it with two forward slashes "<code>//</code> ".</p>
<ol start="2">
<li>The <code>pragma</code> directive must be the first line of code in any Solidity file. Pragma is a directive that tells the compiler which compiler version it should use to convert the human-readable Solidity code to machine readable bytecode.</li>
</ol>
<p>Solidity is a new language and is frequently updated, so different versions of the compiler produce different results when compiling code. Some older solidity files will throw errors or warnings when compiled with a newer compiler version.</p>
<p>In larger projects, when you use tools like Hardhat, you may need to specify multiple compiler versions because imported solidity files or libraries that you depend on were written for older versions of solidity. Read more on <a target="_blank" href="https://docs.soliditylang.org/en/develop/layout-of-source-files.html">Solidity’s pragma directive here</a>.</p>
<ol start="3">
<li><p>The <code>pragma</code> directive follows Semantic Versioning (SemVer) - a system where each of the numbers signifies the type and extent of changes contained in that version. If you want a hands-on explanation of SemVer is check out this tutorial - it is very useful to understand and it’s used widely in development (especially web dev) these days.</p>
</li>
<li><p>Semicolons are essential in Solidity. The compiler will fail if even a single one is missing. Remix will alert you!</p>
</li>
<li><p>The keyword <code>contract</code> tells the compiler that you’re declaring a Smart Contract. If you’re familiar with Object Oriented Programming, then you can think of Contracts as being like Classes.</p>
</li>
</ol>
<p>If you’re not familiar with OOP then think of contracts as being objects that hold data - both variables and functions. You can combine smart contracts to give your blockchain app the functionality it needs.</p>
<ol start="6">
<li>Functions are executable units of code that encapsulate single ideas, specific functionality, tasks, and so on. In general we want functions to do one thing at a time.</li>
</ol>
<p>Functions are most often seen inside smart contracts, though they can be declared in the file outside the smart contract’s block of code. Functions may take 0 or more arguments and they may return 0 or more values. Inputs and outputs are statically typed, which is a concept you will learn about later in this handbook.</p>
<ol start="7">
<li>In the above example the variable <code>qtyCups</code> is called a “state variable”. It holds the contract’s state - which is the technical term for data that the program needs to keep track of to operate.</li>
</ol>
<p>Unlike other programs, smart contract applications keep their state even when the program is not running. The data is stored in the blockchain, along with the application, which means that each node in the blockchain network maintains and synchronizes a local copy of the data and smart contracts on the blockchain.</p>
<p>State variables are like database “storage” in a traditional application, but since blockchains need to synchronize state across all nodes in the network, using storage can be quite expensive! More on that later.</p>
<h2 id="heading-how-to-declare-variables-and-functions-in-solidity">How to Declare Variables and Functions in Solidity</h2>
<p>Let’s break down that <code>HotFudgeSauce</code> Smart Contract so we understand more about each little piece.</p>
<p>The basic structure/syntax to defining things in Solidity is similar to other statically typed languages. We give functions and variables a name.</p>
<p>But in typed languages we also need to specify the <em>type</em> of the data that is created, passed as input or returned as output. You can jump down to the Typing Data section in this handbook if you need to understand what typed data is.</p>
<p>Below, we see what declaring a “State Variable” looks like. We also see what declaring a function looks like.</p>
<p><img src="https://lh5.googleusercontent.com/P0bkGvqTA70VN-VZlV13ICNL4sxhzHCIU_8GL0JF9iHZPn6ml4vA6grWy_dKbiMa-y_ALc8oHOyIDGLFZgIIi5pU2Ep5ENuFJd0dPRL8RCPx8bksESh44loRbFqAA9f7GZ9_e5thytMuOk3EeObhmQnG791pBviHuxrv3N3HAXcGAQL0q-4TwV2LQhoA-w" alt="(Alt: The structure variable declaration and function declaration) " width="600" height="400" loading="lazy"></p>
<p>The first snippet declares a State Variable (I’ll explain what this is soon, I promise) called <code>qtyCups</code>. This can only store values that are of type <code>uint</code> which means unsigned integers. “Integer” refers to all whole numbers below zero (negative) and above zero (positive).</p>
<p>Since these numbers have a + or - sign attached, they’re called <em>signed</em> integers. An unsigned integer is therefore always a positive integer (including zero).</p>
<p>In the second snippet, we see a familiar structure when we declare functions too. Most importantly, we see that the functions have to specify a data type for the value that the function returns.</p>
<p>In this example, since <code>get()</code> returns the value of the storage variable we just created, we can see that the returned value must be a <code>uint</code>.</p>
<p><code>public</code> is a visibility specifier. More on that later. <code>view</code> is a State-Mutability modifier. More on that below too!</p>
<p>It’s worth noting here that state variables can also be of other types - <code>constant</code> and <code>immutable</code>. They look like this:</p>
<table><tbody><tr><td><p>string constant TEXT = "abc";<br>address immutable owner = 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e;</p></td></tr></tbody></table>

<p>Constants and immutable variables have their values assigned once, and only once. They cannot be given another value after their first value is assigned.</p>
<p>So if we made the <code>qtyCups</code> state variable either constant or immutable, we would not be able to call the <code>increment()</code> or <code>decrement()</code> functions on it anymore (in fact, the code wouldn’t compile!).</p>
<p>Constants must have their values hardcoded in the code itself, whereas immutable variables can have their values set once, generally by assignment in the constructor function (we’ll talk about constructor functions very soon, I promise). You can read more in the <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.16/contracts.html#constant-and-immutable-state-variables">docs here</a>.</p>
<h2 id="heading-variable-scope-in-smart-contracts">Variable Scope in Smart Contracts</h2>
<p>There are three scopes of variables that Smart Contracts have access to:</p>
<ol>
<li><p>State Variables: store permanent data in the smart contract (referred to as persistent state) by recording the values on the blockchain.</p>
</li>
<li><p>Local Variables: these are “transient” pieces of data that hold information for short periods of time while running computations. These values are not stored permanently on the blockchain.</p>
</li>
<li><p><a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/units-and-global-variables.html#special-variables-and-functions">Global variables</a>: these variables and functions are “injected” into your code by Solidity, and made available without the need to specifically create or import them from anywhere. These provide information about the blockchain environment the code is running on and also include utility functions for general use in the program.</p>
</li>
</ol>
<p>You can tell the difference between the scopes as follows:</p>
<ol>
<li><p>state variables are generally found inside the smart contract but outside of a function.</p>
</li>
<li><p>local variables are found inside functions and cannot be accessed from outside that function’s scope.</p>
</li>
<li><p>Global variables aren’t declared by you - they are “magically” available for you to use.</p>
</li>
</ol>
<p>Here is our <code>HotFudgeSauce</code> example, slightly modified to show the different types of variables. We give <code>qtyCups</code> a starting value and we dispense cups of fudge sauce to everyone except me (because I’m on a diet).</p>
<p><img src="https://lh4.googleusercontent.com/Z9wk7BXxi-669WmSamT25cV88_RK-psGJvCA69vUxgpcs2_EzJFzLZJOitQlsuSl_AD-LdRylCaKh4Iumo_tVHmft2mtKofDu4qZfWQ8Z7BhdZ-6g4B6JAwLF57gMi-osCSDocgyE6kdqMCL4uxjBtpzjMf6rlLM0Ja6w4ndaIxEZhE3YsxmDY1BIWOwnA" alt="Annotated image showing state variables, local variables and global variables in a smart contract" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-visibility-specifiers-work">How Visibility Specifiers Work</h2>
<p>The use of the word “visibility” is a bit confusing because on a public blockchain, pretty much everything is “visible” because transparency is a key feature. But visibility, in this context, means the ability for one piece of code to be seen and accessed by another piece of code.</p>
<p>Visibility specifies the extent to which a variable, function, or contract can be accessed from outside the region of code where it was defined. The scope of visibility can be adjusted depending on which portions of the software system need to access it.</p>
<p>If you’re a JavaScript or NodeJS developer, you’re already familiar with visibility – any time you export an object you’re making it visible outside the file where it is declared.</p>
<h3 id="heading-types-of-visibility">Types of Visibility</h3>
<p>In Solidity there are <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.16/cheatsheet.html#function-visibility-specifiers">4 different types of visibility</a>: <code>public</code>, <code>external</code>, <code>internal</code> and <code>private</code>.</p>
<p><strong>Public</strong> functions and variables can be accessed inside the contract, outside it, from other smart contracts, and from external accounts (the kind that sit in your <a target="_blank" href="https://metamask.io/">Metamask</a> wallet) - pretty much from anywhere. It’s the broadest, most permissive visibility level.</p>
<p>When a storage variable is given <code>public</code> visibility, Solidity automatically creates an implicit getter function for that variable’s value.</p>
<p>So in our <code>HotFudgeSauce</code> smart contract, we don’t really need to have the <code>get()</code> method, because Solidity will implicitly provide us identical functionality, just by giving <code>qtyCups</code> a <code>public</code> visibility modifier.</p>
<p><strong>Private</strong> functions and variables are only accessible within the smart contract that declares them. But they cannot be accessed outside of the Smart Contract that encloses them. <code>private</code> is the most restrictive of the four visibility specifiers.</p>
<p><strong>Internal</strong> visibility is similar to <code>private</code> visibility, in that internal functions and variables can only be accessed from within the contract that declares them. But functions and variables marked internal can also be accessed from derived contracts (that is, child contracts that inherit from the declaring contract) but not from outside the contract. We will talk about inheritance (and derived/child contracts) later on.</p>
<p><code>internal</code> is the default visibility for storage variables.</p>
<p><img src="https://lh5.googleusercontent.com/gcNCm0-739P27Bqp_5zYT6kM_fmfW3tnrx-ZJ8iKH5Gnhpp9-JXo4NrSk7UaUPv9SF34ka7eNYtFK-FmnTGtHSupFUE6A6UvX1738cqDG0X9qhWCRdqI-jGf1BCpvK2Qi6MqMQWgN4H3VOpa5xh2zVkQrQlfGuBPRWIovNxfDH3zhFuxHKsUpXq9Oh_Saw" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The 4 Solidity Visibility specifiers and where they can be accessed from</em></p>
<p>The <strong>external</strong> visibility specifier does not apply to variables - only functions can be specified as external.</p>
<p>External functions cannot be called from inside the declaring contract or contracts that inherit from the declaring contract. Thus, they can only be called from outside the enclosing contract.</p>
<p>And that’s how they’re different from public functions – public functions can also be called from <em>inside</em> the contract that declare them, whereas an external function cannot.</p>
<h2 id="heading-what-are-constructors">What are Constructors?</h2>
<p>A constructor is a special type of function. In Solidity, it is optional and is executed once only on contract creation.</p>
<p>In the following example we have an explicit constructor and it accepts some data as a parameter. This constructor parameter must be injected by you into your smart contract at the time you create it.</p>
<p><img src="https://lh6.googleusercontent.com/51je7Hakb-_ARNnomBYpwoKpf2j86WvwRLDlaFzGLlGowJLt1T1MX2978gAGv8eZCoiZc-jZParqor28wBLx97WyrMrso-EwSRHnOBi3O956nIyHN4-cezZJk8avP7JBegFOq4DJ997t1YnC61bD4IUH08SPEbvw6HoZSbXqbOt_LwzfQAHXfeXiNC6xHw" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Solidity constructor function with input parameter</em></p>
<p>To understand when the constructor function gets called, it’s helpful to remember that a Smart Contract is created over a few phases:</p>
<ul>
<li><p>it is compiled down to bytecode (you can <a target="_blank" href="https://blog.chain.link/what-are-abi-and-bytecode-in-solidity/">read more about bytecode here</a>). This phase is called “compile time”.</p>
</li>
<li><p>it gets created (constructed) - this is when the constructor kicks into action. This can be referred to as “construction time”.</p>
</li>
<li><p>Bytecode then gets deployed to the blockchain. This is “deployment”.</p>
</li>
<li><p>The deployed smart contract bytecode gets run (executed) on the blockchain. This can be considered “runtime”.</p>
</li>
</ul>
<p>In Solidity, unlike other languages, the program (smart contract) is deployed only <em>after</em> the constructor has done its work of creating the smart contract.</p>
<p>Interestingly, in Solidity, the finally deployed bytecode does <em>not</em> include the constructor code. This is because in Solidity, the <a target="_blank" href="https://blog.openzeppelin.com/deconstructing-a-solidity-contract-part-ii-creation-vs-runtime-6b9d60ecb44c/">constructor code is part of the creation code</a> (construction time) and not part of the runtime code. It is used up when creating the smart contract, and since it’s only ever called once it is not needed past this phase, and is excluded in the finally deployed bytecode.</p>
<p>So in our example, the constructor creates (constructs) one instance of the <code>Person</code> smart contract. Our constructor expects us to pass a string value which is called <code>_name</code> to it.</p>
<p>When the smart contract is being constructed, that value of <code>_name</code> will get stored in the state variable called <code>name</code> (this is often how we pass configuration and other data into the smart contract). Then when the contract is actually deployed, the state variable <code>name</code> will hold whatever string value we passed into our constructor.</p>
<h3 id="heading-understanding-the-why">Understanding the Why</h3>
<p>You might wonder why we bother with injecting values into the constructor. Why not just write them into the contract?</p>
<p>This is because we want contracts to be configurable or “parameterized”. Rather than hard code values, we want the flexibility and reusability that comes with injecting data as and when we need.</p>
<p>In our example, let’s say that <code>_name</code> referred to the name of a given Ethereum network on which the contract is going to be deployed (like Rinkeby, Goerli, Kovan, Mainnet, and so on).</p>
<p>How could we give that information to our smart contract? Putting all those values in it would be wasteful. It would also mean we need to add extra code to work out which blockchain the contract is running on. Then we'd have to pick the right network name from a hard-coded list which we store in the contract, which takes up gas on deployment.</p>
<p>Instead, we can just inject it into the constructor, at the time we are deploying the smart contract to the relevant blockchain network. This is how we write one contract that can work with any number of parameter values.</p>
<p>Another common use case is when your smart contract inherits from another smart contract and you need to pass values to the parent smart contract when your contract is being created. But inheritance is something we will discuss later.</p>
<p>I mentioned that constructors are optional. In <code>HotFudgeSauce</code>, we didn’t write an explicit constructor function. But Solidity supports implicit constructor functions. So if we don’t include a constructor function in our smart contract, Solidity will <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.13/contracts.html#constructors">assume a default constructor</a> which looks like <code>constructor() {}</code>.</p>
<p>If you evaluate this in your head you’ll see it does nothing and that’s why it can be excluded (made implicit) and the compiler will use the default constructor.</p>
<h2 id="heading-interfaces-and-abstract-contracts">Interfaces and Abstract Contracts</h2>
<p>An <a target="_blank" href="https://docs.soliditylang.org/en/develop/contracts.html#interfaces">interface in solidity</a> is an essential concept to understand. Smart Contracts on Ethereum are publicly viewable and therefore you can interact with them via their functions (to the extent the Visibility Specifiers allow you to do so!).</p>
<p>This is what makes smart contracts “composable” and why so many Defi protocols are referred to as “money Legos” - you can write smart contracts that interact with other smart contracts that interact with other smart contracts and so on…you get the idea.</p>
<p>So when you want your smart contract A to interact with another smart contract B, you need B’s interface. An interface gives you an index or menu of the various functions available for you to call on a given Smart Contract.</p>
<p>An important feature of Interfaces is that they must not have any implementation (code logic) for any of the functions defined. Interfaces are just a collection of function names and their expected arguments and return types. They’re not unique to Solidity.</p>
<p>So an interface for our <code>HotFudgeSauce</code> Smart Contract would look like this (note that by convention, solidity interfaces are named by prefixing the smart contract’s name with an “I”:</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br><br>pragma solidity ^0.8.7;<br><br>interface IHotFudgeSauce {<br>&nbsp; &nbsp; function get() public view returns (uint);<br>&nbsp; &nbsp; function increment() public;<br>&nbsp; &nbsp; function decrement() public;<br>}</p></td></tr></tbody></table>

<p>That’s it! Since <code>HotFudgeSauce</code> had only three functions, the interface shows only those.</p>
<p>But there is an important and subtle point here: an interface does not need to include all the functions available to call in a smart contract. An interface can be shortened to include the function definitions for the functions that you intend to call!</p>
<p>So if you only wanted to use the <code>decrement()</code> method on <code>HotFudgeSauce</code> then you could absolutely remove <code>get()</code> and <code>increment()</code> from your interface - but you would not be able to call those two functions from your contract.</p>
<p>So what’s actually going on? Well, interfaces just give your smart contract a way of knowing what functions can be called in your target smart contract, what parameters those functions accept (and their data type), and what type of return data you can expect. In Solidity, that’s all you need to interact with another smart contract.</p>
<p>In some situations, you can have an abstract contract which is similar to but different from an interface.</p>
<p>An <a target="_blank" href="https://docs.soliditylang.org/en/develop/contracts.html#abstract-contracts">abstract contract</a> is declared using the <code>abstract</code> keyword and is one where one or more of its functions are declared but not implemented. This is another way of saying that at least one function is declared but not implemented.</p>
<p>Flipping that around, an abstract contract can have implementations of its functions (unlike interfaces which can have zero implemented functions), but as long as at least one function is unimplemented, the contract must be marked as abstract:</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.7;<br><br>abstract contract Feline {</p></td></tr></tbody></table>

<p>You may (legitimately) wonder what the point of this is. Well, abstract contracts cannot be instantiated (created) directly. They can only be used by other contracts that inherit from them.</p>
<p>So abstract contracts are often used as a template or a “base contract” from which other smart contracts can “inherit” so that the inheriting smart contracts are forced to implement certain functions declared by the abstract (parent) contract. This enforces a defined structure across related contracts which is often a useful design pattern.</p>
<p>This inheritance stuff will become a little clearer when we discuss Inheritance later. For now, just remember that you can declare an abstract smart contract that does not implement all its functions - but if you do, you cannot instantiate it, and future smart contracts that inherit it must do the work of implementing those unimplemented functions.</p>
<p>Some of the important differences between interfaces and abstract contracts are that:</p>
<ul>
<li><p>Interfaces can have zero implementations, whereas abstract contracts can have any number of implementations as long as at least one function is “abstract” (that is, not implemented).</p>
</li>
<li><p>All functions in an interface must be marked as “external” because they can only be called by other contracts that implement that interface.</p>
</li>
<li><p>Interfaces cannot have constructors, whereas abstract contracts may.</p>
</li>
<li><p>Interfaces cannot have state variables where abstract contracts may.</p>
</li>
</ul>
<h2 id="heading-smart-contract-example-2">Smart Contract Example #2</h2>
<p>For the next few Solidity concepts we’ll use the below smart contract. This is partly because this example contains a smart contract that is actually used in the real world. I've also chosen it because I have a clear bias to Chainlink Labs since I work there (😆) and it’s awesome. But it’s also where I learned a lot of Solidity, and it’s always better to learn with real-world examples.</p>
<p>So start by reading the code and the comments below. You’ve already learned 99% of what you need to understand the contract below, provided you read it carefully. Then move on to key learnings from this contract.</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.7;<br><br>import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";<br><br>contract PriceConsumerV3 {<br>&nbsp; &nbsp; AggregatorV3Interface internal priceFeed;<br><br>&nbsp; &nbsp; /<em>*<br>&nbsp; &nbsp; </em> Network: Goerli<br>&nbsp; &nbsp; <em> Aggregator: ETH/USD<br>&nbsp; &nbsp; </em> Address: 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e<br>&nbsp; &nbsp; */<br>&nbsp; &nbsp; constructor() {<br>&nbsp; &nbsp; &nbsp; &nbsp; priceFeed = AggregatorV3Interface(0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e);<br>&nbsp; &nbsp; }<br>&nbsp;&nbsp;&nbsp;</p></td></tr></tbody></table>

<p>This smart contract <a target="_blank" href="https://docs.chain.link/docs/get-the-latest-price/">gets the latest USD price of 1 Eth</a>, from a live Chainlink price feed oracle (<a target="_blank" href="https://goerli.etherscan.io/address/0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e#code">see the oracle on etherscan</a>). The example uses the Goerli network so you don’t end up spending real money on the Ethereum mainnet.</p>
<p>Now to the 6 essential Solidity concepts you need to absorb:</p>
<ol>
<li>Right after the <code>pragma</code> statement we have an import statement. This imports existing code into our smart contract.</li>
</ol>
<p>This is super cool because this is how we reuse and benefit from code that others have written. You can check out the code that is imported on this <a target="_blank" href="https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol">GitHub link</a>.</p>
<p>In effect, when we compile our smart contract, this imported code gets pulled in and compiled into bytecode along with it. We will see why we need it in a second…</p>
<ol start="2">
<li><p>Previously you saw that single-line comments were marked with <code>//</code>. Now you're learning about multiline comments. They may span one or more lines and use <code>/*</code> and <code>*/</code> to start and end the comments.</p>
</li>
<li><p>We declare a variable called <code>priceFeed</code> and it has a type <code>AggregatorV3Interface</code>. But where does this strange type come from? From our imported code in the import statement - we get to use the <code>AggregatorV3Interface</code> type because Chainlink defined it.</p>
</li>
</ol>
<p>If you looked at that Github link, you’d see that the type defines an interface (we just finished talking about interfaces). So <code>priceFeed</code> is a <em>reference</em> to some object that is of type <code>AggregatorV3Interface</code>.</p>
<ol start="4">
<li>Take a look at the constructor function. This one doesn’t accept parameters, but we could have just as easily passed the ETH/USD Price Feed’s oracle smart contract’s address <code>0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e</code> to it as a parameter of type <code>address</code>. Instead, we are hard-coding the address inside the constructor.</li>
</ol>
<p>But we are also creating a reference to the Price Feed Aggregator smart contract (using the interface called <code>AggregatorV3Interface</code>).</p>
<p>Now we can call all the methods available on the <code>AggregatorV3Interface</code> because the <code>priceFeed</code> variable refers to that Smart Contract. In fact, we do that next… 5. Let's jump to the function <code>getLatestPrice()</code>. You’ll recognize its structure from our discussion in <code>HotFudgeSauce</code>, but it’s doing some interesting things.</p>
<p>Inside this <code>getLatestPrice()</code> function we call the <code>latestRoundData()</code> function which exists on the <code>AggregatorV3Interface</code> type. If you <a target="_blank" href="https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol#L22">look at the source code of this method</a> you’ll notice that this <code>latestRoundData()</code> function returns 5 different types of integers!</p>
<p><img src="https://lh5.googleusercontent.com/GMqCsBxRblJ2rMQDrMPTx1iDfj6Q3h0eiPqE-RE0-MaHwDDyr6JVna6-57e4jdQxp6VJ4FbMWUMKxFpM2ot4BzqsagLpmD2clz1xCjQhAfl4tn8HhCK4uSKj1hZkDGwXJj9DhuY7nmunj4j_aDx9APc8mqXUPoR9Tl20DdYvjIoUjotmQfJByXKbW2EY5g" alt="Calling methods on another smart contract from our smart contract" width="600" height="400" loading="lazy"></p>
<p><em>Calling methods on another smart contract from our smart contract</em></p>
<p>In our smart contract, we are commenting out all 4 values that we don’t need. So this means that Solidity functions can return multiple values (in this example we are returned 5 values), and we can pick and choose which ones we want.</p>
<p>Another way of consuming the results of calling <code>latestRoundData()</code> would be:<code>( ,int price, , ,) = priceFeed.latestRoundData()</code> where we ignore 4 out of 5 returned values by not giving them a variable name.</p>
<p>When we assign variable names to one or more values returned by a function, we call it “destructuring assignment” because we destructure the returned values (separate each one out) and assign them at the time of destructuring, like we do with <code>price</code> above.</p>
<p>Since you’ve learned about interfaces, I recommend you take a look at Chainlink Labs’ <a target="_blank" href="https://github.com/smartcontractkit/">GitHub repo</a> to examine the implemented <code>latestRoundData()</code> function in <a target="_blank" href="https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.6/AggregatorProxy.sol#L211">the <code>Aggregator</code> contract</a> and how the <code>AggregatorV3Interface</code> <a target="_blank" href="https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol#L22">provides the interface</a> to interact with the <code>Aggregator</code> contract.</p>
<h2 id="heading-what-is-contract-state">What is Contract State?</h2>
<p>Before we proceed any further, it’s important to make sure that the terminology that we’re going to see a lot is comprehensible to you.</p>
<p>“State” in computer science has a <a target="_blank" href="https://en.wikipedia.org/wiki/State_\(computer_science\)">well-defined meaning</a>. While it can get very confusing, the crux of state is that it refers to all the information that is “remembered” by a program as it runs. This information can change, update, be removed, created and so on. And if you were to take a snapshot of it at various times, the information will be in different “states”.</p>
<p>So the state is just the current snapshot of the program, at a point in time during its execution - what values do its variables hold, what are they doing, what objects have been created or removed, and so on.</p>
<p>We have previously examined the three types of variables - State Variables, Local Variables, and Global variables. State variables, along with Global variables give us the state of the smart contract at any given point in time. Thus, the state of a smart contract is a description of:</p>
<ol>
<li><p>what values its state variables hold,</p>
</li>
<li><p>what values the blockchain-related global variables have at that moment in time, and</p>
</li>
<li><p>the balance (if any) lying in the smart contract account.</p>
</li>
</ol>
<h2 id="heading-state-mutability-keywords-modifiers">State Mutability Keywords (Modifiers)</h2>
<p>Now that we have discussed state, state variables, and functions, let’s understand the Solidity keywords that specify what we are allowed to do with state.</p>
<p>These keywords are referred to as <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/cheatsheet.html#modifiers">modifiers</a>. But not all of them permit you to modify state. In fact many of them expressly <em>disallow</em> modifications.</p>
<p>Here are Solidity modifiers you will see any real-world smart contract:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Modifier Keyword</strong></td><td><strong>Applies to…</strong></td><td><strong>Purpose</strong></td></tr>
</thead>
<tbody>
<tr>
<td>constant</td><td>State variables</td><td>Declared and given a value once, at the same time. Hard coded into code. Its given value can never be changed.</td></tr>
<tr>
<td>immutable</td><td>State variables</td><td>These are declared at the top of smart contracts, but given their value (only once!) at construction time - i.e. via the constructor function.  Once they receive their value, they are (effectively) constants. And their values are actually stored in the code itself rather than in a storage slot (storage will be explained later).</td></tr>
<tr>
<td>view</td><td>functions</td><td>You’ll generally see this right after the visibility specifier.  A view modifier means that the function can only “view” (read from) contract state, but cannot change it (cannot “write” to contract state).  This is effectively a read-only modifier. If the function needs to use any value that is in the contract’s state, but not modify that value, it will be a view function.</td></tr>
<tr>
<td>pure</td><td>functions</td><td>Functions that are pure are not allowed to write to (modify) contract state, nor are they allowed to even read from it!  They do things that do not, in any way, interact with blockchain state.  Often these can be helper functions that do some calculation or convert an input of one data type into another data type etc.</td></tr>
<tr>
<td>payable</td><td>functions</td><td>This keyword enables a function to receive Eth. Without this keyword you cannot send Eth while calling a function.  </td></tr>
</tbody>
</table>
</div><p>Note that in Solidity version 0.8.17, there were <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/080-breaking-changes.html?highlight=payable%20address#new-restrictions">breaking changes</a> that enabled the use of payable as a data type.  Specifically we now allowed to convert the address data type to a payable address type by doing a type conversion that looks like payable(0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF).<br>What this does is makes a given ethereum address payable, after which we can send Eth to that address.   </p>
<p>Note that this use of payable is a type conversion, and not the same as the function modifier, though the same keyword is used. We will cover the address type later, but you can read about this <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.16/types.html#address">here</a>. |
| virtual | functions | This is a slightly more advanced topic and is covered in detail in the section on Inheritance. This modifier allows the function to be “overridden” in a child contract that inherits from it.  In other words, a function with the keyword virtual can be “rewritten” with different internal logic in another contract that inherits from this one. |
| override | functions | This is the flip side to the virtual modifier.  When a child contract “rewrites” a function that was declared in a base contract (parent contract) from which it inherits, it marks that rewritten function with override to signal that its implementation overrides the one given in the parent contract. If a parent’s virtual function is not overridden by the child, the parent's implementation will apply to the child. |
| indexed | events | We will cover events later in this handbook.  They are small bundles of data “emitted” by a smart contract typically in response to noteworthy events happening.  The indexed keyword indicates that one of the pieces of data contained in an event should be stored in the blockchain for retrieval and filtering later. This will make more sense once we cover Events and Logging later in this handbook. |
| anonymous | events | The <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/cheatsheet.html#modifiers">docs</a> say “Does not store event signature as topic” which probably doesn’t mean a lot to you just yet.  But the keyword does indicate that it’s making some part of the event “anonymous”. So this will make sense once we understand events and topics later in this handbook. |</p>
<p>Note that variables that are not storage variables ( i.e. local variables declared and used inside the scope of a given function) do not need state modifiers. This is because they’re not actually part of the smart contract’s state. They’re just part of the local state inside that function. By definition then, they’re modifiable and don’t need controls on their modifiability.</p>
<h2 id="heading-data-locations-storage-memory-and-stack">Data Locations – Storage, Memory, and Stack</h2>
<p>On Ethereum and EVM-based chains, data inside the system can be placed and accessed in more than one “data location”.</p>
<p>Data locations are part of the fundamental design and architecture of the EVM. When you see the words “memory”, “storage” and “stack”, you should start thinking “data locations” - that is, where can data be stored (written) to and retrieved (read) from.</p>
<p>Data location has an impact on how the code executes at run time. But it also has very important impacts on how much <a target="_blank" href="https://ethereum.org/en/developers/docs/gas/">gas</a> gets used during deployment and running of the smart contract.</p>
<p>The use of gas requires a deeper understanding of the EVM and something called opcodes - we can park that discussion for now. While useful, it is not strictly necessary for you to understand data locations.</p>
<p>Though I’ve mentioned 3 data <em>locations</em> so far, there are 2 other ways in which data can be stored and accessed in Smart Contracts: “calldata”, and “code”. But these are not data locations in the EVM’s design. They’re just subsets of the 3 data locations.</p>
<p>Let’s start with storage. In the EVM’s design, data that needs to be stored permanently on the blockchain is placed in the relevant smart contract’s “storage” area. This includes any contract “state variables”.</p>
<p>Once a contract is deployed and has its specific address, it also gets its own storage area, which you can think of as a key-value store (like a hash table) where <strong>both</strong> the keys and the values are 256 bit (32 byte) data “words”. And “words” <a target="_blank" href="https://en.wikipedia.org/wiki/Word_\(computer_architecture\)">has a specific meaning</a> in computer architecture.</p>
<p>Because storage persists data on the blockchain permanently, all data needs to be synchronized across all the nodes in the network, which is why nodes have to achieve consensus on data state. This consensus makes storage expensive to use.</p>
<p>You’ve already seen examples of storage variables (aka contract state variables) but here is an example taken from the <a target="_blank" href="https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFConsumerBaseV2.sol">Chainlink Verifiable Random Number Consumer smart contract</a></p>
<p><img src="https://lh3.googleusercontent.com/oV_AXHhYqs7DIB_WQvzB7A97qlnVKAoQYAvLCr9euiwC-XlO8d23-HZuwGjkANpEBnMKQ8u1MrBupg8IWjdX9_YubpjQobML8AyKAQ9vnU_nBxgTAxlYHA-JJlc1xZ3wD14zzER6gAyKmkQ7yLQDCKOr2V5M48Xo5t2SfYVoPRJKI_lUJ5yJMh8YSNaT9w" alt="Storage data location. Putting data in the contract's storage layout." width="600" height="400" loading="lazy"></p>
<p><em>Storage data location. Putting data in the contract's storage layout.</em></p>
<p>When the above contract is created and deployed, whatever address that is passed into the contract’s constructor becomes permanently stored in the smart contract’s storage, and is accessible using the variable <code>vrfCoodinator</code>. Since this state variable is marked as <code>immutable</code>, it cannot be changed after this.</p>
<p>To refresh your memory from the previous section on keywords, where we last discussed <code>immutable</code> and <code>constant</code> variables, these values are not put in storage. They become part of the code itself when the contract is constructed, so these values don’t consume as much gas as storage variables.</p>
<p>Now let’s move to <code>memory</code>. This is temporary storage where you can read and write data needed during the running of the smart contract. This data is erased once the functions that use the data are done executing.</p>
<p>The <code>memory</code> location space is like a temporary notepad, and a new one is made available in the smart contract each time a function is triggered. That notepad is thrown away after the execution completes.</p>
<p>When understanding the difference between storage and memory, you can think of storage as a kind of hard disk in the traditional computing world, in the sense that it has “persistent” storage of data. But memory is closer to RAM in traditional computing.</p>
<p>The <code>stack</code> is the data area where most of the EVM’s computations are performed. The EVM follows a <a target="_blank" href="https://en.wikipedia.org/wiki/Stack_machine#Comparison_with_register_machines">stack based computation model</a> and not a register based computation model, which means each operation to be carried out needs to be stored and accessed using a <a target="_blank" href="https://en.wikipedia.org/wiki/Stack_\(abstract_data_type\)">stack data structure</a>.</p>
<p>The stack’s depth - that is the total number of items it can hold - is 1024, and each item in the stack can be 256 bits (32 bytes) long. This is the same as the size of each key and value in the storage data location.</p>
<p>You can read more about how the EVM controls access to the stack data storage area <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/introduction-to-smart-contracts.html#storage-memory-and-the-stack">here</a>.</p>
<p>Next, let's talk about <code>calldata</code>. I have assumed that you have a basic understanding about Ethereum smart contract <a target="_blank" href="https://ethereum.org/en/whitepaper/#messages">messages</a> and <a target="_blank" href="https://ethereum.org/en/developers/docs/transactions/#:~:text=An%20Ethereum%20transaction%20refers%20to,takes%20place%20within%20a%20transaction.">transactions</a>. If you don’t, you should first read those links.</p>
<p>Messages and transactions are how smart contract functions are invoked, and they contain a variety of data necessary for the execution of those functions. This message data is stored in a read-only section of the memory called <code>calldata</code>, which holds things like the function name and parameters.</p>
<p>This is relevant for externally callable functions, as internal and private functions don’t use calldata. Only “incoming” function execution data and function parameters are stored in this location.</p>
<p>Remember, <code>calldata</code> is memory except that <code>calldata</code> is read-only. You cannot write data to it.</p>
<p>And finally, <code>code</code> is not a data location but instead refers to the smart contract's compiled bytecode that is deployed and stored permanently on the blockchain. This bytecode is stored in an immutable ROM (Read Only Memory), that is loaded with the bytecode of the smart contract to be executed.</p>
<p>Remember how we discussed the difference between immutable and constant variables in Solidity? Immutable values get assigned their value once (usually in the constructor) and constant variables have their values hard-coded into the smart contract code. Because they’re hardcoded, constant values are compiled literally and embedded directly into the smart contract’s bytecode, and stored in this code / ROM data location.</p>
<p>Like <code>calldata</code>, <code>code</code> is also read-only - if you understood the previous paragraph you’ll understand why!</p>
<h2 id="heading-how-typing-works">How Typing Works</h2>
<p>Typing is a very important concept in programming because it is how we give structure to data. From that structure we can run operations on the data in a safe, consistent and predictable way.</p>
<p>When a language has strict typing, it means that the language strictly defines what each piece of data’s type is, and a variable that has a type cannot be given another type.</p>
<p>In other words, in strictly typed languages:</p>
<table><tbody><tr><td><p>int a =1&nbsp; // &nbsp; &nbsp; 1 here is of the integer type<br>string b= "1" //&nbsp; 1 here is of the string type</p></td></tr></tbody></table>

<p>But in JavaScript, which is not typed, <code>b=a</code> would totally work - this makes JavaScript “dynamically typed”.</p>
<p>Similarly, in statically typed languages you cannot pass an integer into a function that expects a string. But in JavaScript we can pass anything to a function and the program will still compile but it may throw an error when you execute the program.</p>
<p>For example take this function:</p>
<table><tbody><tr><td><p>function add(a,b){<br>&nbsp; &nbsp; return a + b<br>}<br><br>add(1, 2) // output is 3, of type integer<br><br>add(1, "2") // “2” is a string, not an integer, so the output becomes the string “12” (!?)</p></td></tr></tbody></table>

<p>As you can imagine, this can produce some pretty hard-to-find bugs. The code compiles and can even execute without failing, though it produces unexpected results.</p>
<p>But a strongly typed language would never let you pass the string “2” because the function would insist on the types that it accepts.</p>
<p>Let’s take a look at how this function would be written in a strongly typed language like Go.</p>
<p><img src="https://lh5.googleusercontent.com/KeWnVGJ3xZB9cJGLGVqM3XndabWGp5WeIbSGGn78QGzyTgZoRR6QWYJcyYw2jn150w9Y9qvZM62IW-Seeh_TjbyTmBYcnzZH5vBpCkUsBSVmgPuzFsa3q-UORkOEQZujoPa4EojQl5gWynWac5PVuNzOpS1OR6yGO_A31RsAFXIsRqJfJZ9HZRpdDW0oCQ" alt="How typing works in syntax, using Golang for illustration purposes" width="600" height="400" loading="lazy"></p>
<p><em>How typing works in syntax, using Golang for illustration purposes</em></p>
<p>Trying to pass a <code>string</code> (even if it represents a number) will prevent the program from even compiling (building). You will see an error like this:</p>
<pre><code class="lang-go">./prog.<span class="hljs-keyword">go</span>:<span class="hljs-number">13</span>:<span class="hljs-number">19</span>: cannot use <span class="hljs-string">"2"</span> (untyped <span class="hljs-keyword">string</span> constant) as <span class="hljs-keyword">int</span> value in argument to add

Go build failed.
</code></pre>
<p><a target="_blank" href="https://go.dev/play/p/SrE1CXVD_pj">Try it out for yourself</a>!</p>
<p>So types are important because data that seems the same to a human can be perceived very differently by a computer. This can cause some pretty weird bugs, errors, program crashes and even big security vulnerabilities.</p>
<p>Types also give developers the ability to create their own custom types, which can then be programmed with custom properties (attributes) and operations (behaviors).</p>
<p>Type systems exist so that humans can reason about the data by asking the question “what is this data’s type, and what should it be able to do?” and the machines can do exactly what is intended.</p>
<p>Here is another example of how data that looks the same to you and me may be interpreted in hugely different ways by a processor. Take the sequence of binary digits (that is the digits can only have a value of 0 or 1, which is the <a target="_blank" href="https://www.mathsisfun.com/binary-number-system.html">binary system</a> that processors work with) <code>1100001010100011</code>.</p>
<p>To a human, using the decimal system that looks like a very large number - perhaps 11 gazillion or something.</p>
<p>But to a computer that is binary, so it’s not 11 anything. The computer sees this as a sequence 16 bits (short for binary digits) and in binary this could mean the <em>positive number</em> (unsigned integer) 49,827 or the signed integer -15,709 or the UTF-8 representation of the British Pound symbol £ or something different!</p>
<p><img src="https://lh6.googleusercontent.com/zH0CD3sU2PRWVf0rdtAsvHgV7-7PiyOdKZbz6wOEkE2gax4KeMd7EswERIAR1iEbn_NhI-2P381GDujQ27-o-XiHIyB_lY7pjUKIK7XP-nqzLAlYNdNErYXRYuVPdKsiD4n0wSqtnxcwwP78OAYAUbZ4mFpe9hKSewPymjrSyjaUlIO2Ap28ftinejnLNw" alt="A sequence of bits can be interpreted by a computer to have very different meanings" width="600" height="400" loading="lazy"></p>
<p><em>A sequence of bits can be interpreted by a computer to have very different meanings (</em><a target="_blank" href="https://livebook.manning.com/book/programming-with-types/chapter-1/18"><em>source</em></a><em>)</em></p>
<p>So all this explanation is to say that types are important, and that types can be “inbuilt” into a language <strong>even if</strong> the language does not strictly enforce types, like JavaScript.</p>
<p>JavaScript already has <a target="_blank" href="https://www.w3schools.com/js/js_datatypes.asp">inbuilt types</a> like numbers, strings, booleans, objects, and arrays. But as we saw, JavaScript does not insist on types being stuck to the way a statically typed language like Go does.</p>
<p>Now back to Solidity. Solidity is very much a statically typed language. When you declare a variable you must also declare its type. Going further, Solidity will simply refuse to compile if you try to pass a string into a function that expects an integer.</p>
<p>In fact Solidity is very strict with types. For example, different types of integers may also fail compilation like the following example where the function <code>add()</code> expects an unsigned integer (positive) and will only add to that number thus always returning a positive integer. But the return type is specified as an <code>int</code> which means it could be positive or negative!</p>
<table><tbody><tr><td><p>function add(uint256 a) public pure returns (int256){<br>&nbsp; &nbsp; &nbsp; &nbsp; return a + 10;<br>&nbsp; &nbsp; }</p></td></tr></tbody></table>

<p>So even though the input and output are 256-bit integers, the fact that the function only receives unsigned integers makes the compiler complain that the unsigned integer type is <em>not</em> implicitly convertible to the signed integer type.</p>
<p>That’s pretty strict! The developer can force the conversion (called type casting) by rewriting the return statement as <code>return int256(a + 10)</code>. But there are issues to consider with that sort of action, and that’s out of scope for what we’re talking about here.</p>
<p>For now, just remember that Solidity is statically typed, which means that the type of each variable must be expressly specified when declaring them in the code. You can combine types to form more complex, composite types. Next, we can discuss some of these inbuilt types.</p>
<h2 id="heading-solidity-data-types">Solidity Data Types</h2>
<p>Types that are built into the language and come with it “out of the box” are often referred to as “primitives”. They’re intrinsic to the language. You can combine primitive types to form more complex data structures that become “custom” data types.</p>
<p>In JavaScript, for example, <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Primitive">primitives</a> are data that is not a JS object <em>and</em> has no methods or properties. There are 7 primitive data types in JavaScript: <code>string</code>, <code>number</code>, <code>bigint</code>, <code>boolean</code>, <code>undefined</code>, <code>symbol</code>, and <code>null</code>.</p>
<p>Solidity also has its own primitive data types. Interestingly, Solidity does <em>not</em> have “undefined” or “null”. Instead, when you declare a variable and its type, but do not assign a value to it, Solidity will assign a <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/control-structures.html#default-value">Default Value</a> to that type. What exactly that default value is depends on the data type .</p>
<p>Many of Solidity’s primitive data types are variations of the same ‘base’ type. For example the <code>int</code> type itself has subtypes based on the number of binary digits that the <code>integer</code> type can hold.</p>
<p>If that confuses you a bit, don’t worry - it isn’t easy if you’re not familiar with bits and bytes, and I’ll cover integers a bit more shortly.</p>
<p>Before we explore Solidity types, there is another very important concept that you must understand - it is the source of many bugs, and “unexpected gotchas” in programming languages.</p>
<p>This is the difference between a value type and reference type, and the resulting distinction between data in programs being “passed by value” vs “passed by reference”. I’ll go into a quick summary below but you may also find it useful to watch <a target="_blank" href="https://www.youtube.com/watch?v=1HHjKG1372E">this short video</a> to strengthen your mental model before proceeding.</p>
<h3 id="heading-pass-by-reference-vs-pass-by-value">Pass by reference vs pass by value</h3>
<p>At an operating system level, when a program is running, all data used by the program during its execution is stored in locations in the computer’s RAM (memory). When you declare a variable, some memory space is allocated to hold data about that variable and the value that is, or eventually will be, assigned to that variable.</p>
<p>There is also a piece of data that is often called a “pointer”. This pointer points to the memory location (an “address” in the computer’s RAM) where that variable and its value can be found. So the pointer effectively contains a <em>reference</em> to where the data can be found in the computer’s memory.</p>
<p>So when you pass data around in a program (for example when you assign a value to a new variable name, or when you pass inputs (parameters) into a function or method, the language’s compiler can achieve this in two ways. It can pass a pointer to the data’s location in the computer’s memory, <strong>or</strong> it can make a copy of the data itself, and pass the actual value.</p>
<p>The first approach is “pass by reference”. The second approach is “pass by value”.</p>
<p>Solidity’s data type primitives fall into two buckets - they’re either value types, or they’re reference types.</p>
<p>In other words, in Solidity, when you pass data around, the type of the data will decide whether you’re passing copies of the value or a reference to the value’s location in the computer’s memory.</p>
<p><img src="https://lh6.googleusercontent.com/Nj0wt2rDWoanEGT3onBaNxJEnoBp-7NXBrXdL07SO1qbj6PYiE-fhz2zGId-AuGqLiMMHCJIwYbEMYp5oKebmhMudnOhhM_-ZRkLBiatMR6zgcpAPbMDl4hqlLr4UJYa061Plha044IqX_pqeWnx5V1P53dYxopqlddIFmj7qHnXAclPKdLy4XYuwkeGlA" alt="Value Types and Reference Types in Solidity" width="600" height="400" loading="lazy"></p>
<p><em>Value Types and Reference Types in Solidity</em></p>
<p>In Solidity’s “value types”, integers are of two categories - <code>uint</code> is unsigned (positive integers only, so they have no plus or minus signs) and <code>int</code> is signed (could be positive or negative, and if you wrote them down, they’d have a plus or minus sign).</p>
<p>Integer types can also specify how many bits long they are - or how many bits are used to represent the <code>integer</code>.</p>
<p>An <code>uint8</code> is an integer represented by 8 binary digits (bits) and can store up to 256 different values (2^8=256). Since <code>uint</code> is for unsigned (positive) integers, this means it can store values from 0 to 255 (not including 1 to 256).</p>
<p>However when you have signed integers, like an <code>int8</code>, then one of the bits is used up to represent whether it's a positive or negative number. That means we have only 7 bits left, and so we can only represent up to 2^7 (128) different values, including 0. So an <code>int8</code> can represent anything from -127 to +127.</p>
<p>By extension, an <code>int256</code> is 256 bits long and can store +/- (2^255) values.</p>
<p>The bit lengths are <a target="_blank" href="https://docs.soliditylang.org/fr/latest/types.html#integers">multiples of 8</a> (because 8 bits makes a byte) so you can have <code>int8</code>, <code>int16</code>, <code>int24</code> etc all the way to 256 (32 bytes).</p>
<p>Addresses refer to the Ethereum account types - either a smart contract account or an externally owned account (aka “EOA”. Your Metamask wallet represents an EOA). So an address is also a type in Solidity.</p>
<p>The default value of an address (that is the value it will have if you declare a variable of type address but don’t assign it any value) is <code>0x0000000000000000000000000000000000000000</code> which is also the result of this expression: <code>address(0)</code>.</p>
<p>Booleans represent either true or false values. Finally, we have <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/types.html#fixed-size-byte-arrays">fixed size byte arrays</a> like <code>bytes1</code>, <code>bytes2</code> … <code>bytes32</code>. These are arrays of fixed length that contain bytes. All these types of values are copied when they’re passed around in the code.</p>
<p>For “reference types”, we have arrays, which can have a fixed size specified when they’re declared, or dynamically sized arrays, which start off with a fixed size, but can be “resized” as the number of data elements in the array grows.</p>
<p>Bytes are a low-level data type that refer to the data that is encoded into binary format. All data is eventually reduced to binary form by the compiler so that the EVM (or, in traditional computing, the processor) can work with it.</p>
<p>Storing and working with bytes is often faster and more efficient compared to other data types that are more human readable.</p>
<p>You may be wondering why I’ve not referred to strings in either types of data in the picture above. That’s because in Solidity, strings are actually dynamically-sized arrays, and the arrays store a sequence of bytes (just binary numbers) that are encoded in the UTF-8 encoding format.</p>
<p>They’re not a primitive in Solidity. In JavaScript they’re referred to as primitives, but even in JavaScript strings are similar (but not the same as) to arrays and <a target="_blank" href="https://tc39.es/ecma262/#sec-ecmascript-language-types-string-type">are a sequence of integer values</a>, encoded in UTF-16.</p>
<p>It is often more efficient to store a <code>string</code> as a <code>bytes</code> type in a smart contract, as converting between <code>strings</code> and <code>bytes</code> is quite easy. It is therefore useful to store <code>strings</code> as <code>bytes</code> but return them in functions as strings. You can see an example below:</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br><br>pragma solidity ^0.8.0;<br><br><br>contract StringyBytes {</p></td></tr></tbody></table>

<p>Other than Solidity strings, the <code>bytes</code> data type is a <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/types.html#dynamically-sized-byte-array">dynamically sized byte array</a>. Also, unlike its fixed-size byte array cousin, it's a reference type. The <code>bytes</code> type in Solidity is a shorthand for “array of bytes” and can be written in the program as <code>bytes</code> or <code>byte[]</code>.</p>
<p>If you’re confused by bytes and byte arrays…I sympathise.</p>
<p>The underlying gory details of strings and byte arrays are not too relevant for this handbook. The important point for now is that some data types are passed by reference and others are passed by copying their values.</p>
<p>Suffice it to say that Solidity strings and bytes without a size specified are reference types because they’re both dynamically sized arrays.</p>
<p>Finally, among Solidity’s primitives, we have <code>structs</code> and <code>mappings</code>. Sometimes these are referred to as “composite” data types because they’re composed from other primitives.</p>
<p>A <code>struct</code> will define a piece of data as having one or more properties or attributes, and specifying each property’s data type and name. Structs give you the ability to define your own custom type so that you can organize and collect pieces of data into one larger data type.</p>
<p>For example you could have struct that defines a <code>Person</code> as follows:</p>
<table><tbody><tr><td><p>struct Person {<br>&nbsp; &nbsp; string name;<br>&nbsp; &nbsp; uint age;</p></td></tr></tbody></table>

<p>You can instantiate or initialize a <code>Person</code> struct in the following ways:</p>
<table><tbody><tr><td><p>// dot notation updating. Job struct is uninitialized<br>// which means that its properties will have their respect default values<br>Person memory p;<br>P.name = "Zubin"<br>p.age = 41;<br>p.isSolidityDev = true;<br><br>// Or in a function-style call. Note I'm initializing a Job struct too!<br>Person p =&nbsp; Person("Zubin",&nbsp; "41", "true", Job("Chainlink Labs", "DevRel", true));<br><br>// Or in a key-value style<br>Job j = Job({ employer: "Chainlink Labs", "DevRel",&nbsp; true});<br>p.job = j // this is done in dot notation style.</p></td></tr></tbody></table>

<p>Mappings are similar to hashtables, dictionaries or JavaScript objects and maps, but with a little less functionality.</p>
<p>A <code>mapping</code> is also a key-value pair, and there are restrictions on the kinds of data types you can have as keys, which you can read about <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/types.html#mapping-types">here</a>. The data types associated with a mapping’s keys can be any of primitives, structs, and even other mappings.</p>
<p>Here is how mappings are declared, initialized, written to and read from - the below example is from the <a target="_blank" href="https://github.com/smartcontractkit/LinkToken/blob/f307ea6d4c02dd87ea4c1f1032e3e384ceac20c2/contracts/v0.4/token/linkStandardToken.sol">Chainlink Link Token Smart Contract source code</a>.</p>
<p><img src="https://lh5.googleusercontent.com/5x3v-NtBWU2gejrQDWU1m-D-9ZXzTi5JLDs2bMCq1d-TVoxCjFmTEEQg1af4pxEfRbrrpnQaPJLcVauLOZ-amT2hDuNhvXVuX9-cMdMWPiGiRblgcC-oX9dkt75uHzO1ieBVFl_MA6NtJMmWZQ39ypOhOE4qHQWEzk410vme9TR2_lvEzGI2O9_NPo2JGg" alt="Declaring and using the Mappings type in Solidity" width="600" height="400" loading="lazy"></p>
<p><em>Declaring and using the Mappings type in Solidity</em></p>
<p>If you try to access a value using a key that doesn’t exist in the mapping, it will return the <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/control-structures.html#default-value">default value</a> of the type that is stored in the mapping.</p>
<p>In the above example, the type of all values in the <code>balances</code> mapping is <code>uint256</code>, which has a default value of <code>0</code>. So if we called <code>balanceOf()</code> and passed in an address that does not have any LINK tokens issued to it, we’d get a value of <code>0</code> back.</p>
<p>This is reasonable in this example, but it can be a bit tricky when we want to find out whether or not a key exists in a mapping.</p>
<p>Currently there is no way to enumerate what keys exist in a mapping (that is, there is nothing equivalent to <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">JavaScript’s <code>Object.keys()</code></a> method). Retrieving using a key will only return the default value associated with the data type, which does not clearly tell us whether or not the key actually exists.</p>
<p>There is an interesting “gotcha” with mappings. Unlike other languages where you can pass key-value data structures as an argument to function, Solidity does not support passing mappings as arguments to functions except where the functions visibility is marked as <code>internal</code>. So you could not write an externally or publicly callable function that would accept key-value pairs as an argument.</p>
<h2 id="heading-how-to-declare-and-initialize-arrays-in-solidity">How to Declare and Initialize Arrays in Solidity</h2>
<p>Solidity comes with two flavors of arrays, so it is useful to understand the different ways in which they can be declared and initialized.</p>
<p>The two main types of arrays in Solidity are the fixed-size array and the dynamic-sized array.</p>
<p>To refresh your memory, fixed-size arrays are passed by value (copied when passed around in the code) and dynamic-sized arrays are passed by reference (a pointer to the memory address is passed around in the code).</p>
<p>They’re also different in their syntax and their capacity (size), which then dictates when we would use one versus the other.</p>
<p>Here’s what a fixed-size array looks like when declared and initialized. It has a fixed capacity of 6 elements, and this cannot be changed once declared. The memory space for an array of 6 elements is allocated and cannot change.</p>
<table><tbody><tr><td><p>string[6] fixedArray; // Max capacity is 6 elements.</p></td></tr></tbody></table>

<p>A fixed-size array can also be declared by just declaring a variable and the size of the array and the type of its elements with the following syntax:</p>
<table><tbody><tr><td><p>// datatype arrayName[arraySize];</p></td></tr></tbody></table>

<p>Contrast that with a dynamically-sized array that is declared and initialized as follows. Its capacity is unspecific and you can add elements using the push() method:</p>
<table><tbody><tr><td><p>uint[] dynamicArray;</p></td></tr></tbody></table>

<p>You can also declare and initialize the value of an array in the same line of code.</p>
<table><tbody><tr><td><p>string[3] fixedArray = ["a", "b", "c"]; // Fixed sized string array<br>fixedArray.push("abc"); // Won't work for fixed size arrays.<br><br>String[] dynamicArray =["chainlink", "oracles"]; /// Dynamic sized array<br>dynamicArray.push("rocks");&nbsp; // Works.</p></td></tr></tbody></table>

<p>These arrays are available in storage. But what if you needed only temporary in-memory arrays inside a function? In that case there are two rules: only fixed size arrays are allowed, and you must use the <code>new</code> keyword.</p>
<table><tbody><tr><td><p>function inMemArray(string memory firstName, string memory lastName)<br>&nbsp; &nbsp; &nbsp; &nbsp; public<br>&nbsp; &nbsp; &nbsp; &nbsp; pure<br>&nbsp; &nbsp; &nbsp; &nbsp; returns (string[] memory)<br>&nbsp; &nbsp; {</p></td></tr></tbody></table>

<p>Clearly, there are several ways to declare and initialize arrays. When you’re wanting to optimize for gas and computations you want to carefully consider which type of arrays are required, what their capacity is, and if they’re likely to grow without an upper bound.</p>
<p>This also influences and is influenced by the design of your code - whether you need arrays in storage or whether you need them only in memory.</p>
<h2 id="heading-what-are-function-modifiers">What are Function Modifiers?</h2>
<p>When writing functions, we often receive inputs that need some sort of validation, checking, or other logic run on those inputs before we go ahead with the rest of the “business” logic.</p>
<p>For example, if you’re writing in pure JavaScript, you may want to check that your function receives integers and not strings. If it’s on the backend you may want to check that the POST request contained the right authentication headers and secrets.</p>
<p>In Solidity, we can perform these sort of validation steps by declaring a function-like block of code called a modifier.</p>
<p>A modifier is a snippet of code that can run automatically before or after you run the main function (that is, the function that has the modifier applied to it).</p>
<p>Modifiers can be inherited from parent contracts too. It is generally used as a way to avoid repeating your code, by extracting common functionality and putting it in a modifier that can be reused throughout the codebase.</p>
<p>A <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/contracts.html#modifiers">modifier</a> looks a lot like a function. The key thing to observe about a modifier is where the <code>_</code> (underscore) shows up. That underscore is like a “placeholder” to indicate when the main function will run. It reads as if we inserted the main function where the underscore is currently.</p>
<p>So in the modifier snippet below, we run the conditional check to make sure that the message sender is the owner of the contract, and <em>then</em> we run the rest of the function that called this modifier. Note that a single modifier can be used by any number of functions.</p>
<p><img src="https://lh4.googleusercontent.com/Suv8g0wpHjPOgWCljmrlorL4CcqBrYS2JQWMjIpGMleXCSayt7P7dzobb_5G5sueR_v6LZu9R_RLPFWjBtgLAV9MlLIe-3zw5sG6FgfjdJUf3B994xhkZxTcTJsYx1RSIplKYZpeQhX85HG-Er6ZFu7hlBXOT9QGrmQzY7AoZFB6pzUm6s2peDf4OKkUcQ" alt="How function modifiers are written, and the role of the underscore symbol" width="600" height="400" loading="lazy"></p>
<p><em>How function modifiers are written, and the role of the underscore symbol</em></p>
<p>In this example, the <code>require()</code> statement runs before the underscore (<code>changeOwner()</code>) and that’s the correct way to ensure that only the current owner can change who owns the contract.</p>
<p>If you switched the modifier’s lines and the <code>require()</code> statement came second, then the code in <code>changeOwner()</code> would run first. Only after that would the <code>require()</code> statement run, and that would be a pretty unfortunate bug!</p>
<p>Modifiers can take inputs too - you’d just pass the type and name of the input into a modifier.</p>
<table><tbody><tr><td><p>modifier validAddress(address addr) {<br>&nbsp; &nbsp; // address should not be a zero-address.<br>&nbsp; &nbsp; require(addr != address(0), "Address invalid");<br>&nbsp;&nbsp;&nbsp;&nbsp;</p></td></tr></tbody></table>

<p>Modifiers are a great way to package up snippets of logic that can be reused in various smart contracts that together power your dApp. Reusing logic makes your code easier to read, maintain and reason about – hence the principle <a target="_blank" href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> (Don’t Repeat Yourself).</p>
<h2 id="heading-error-handling-in-solidity-require-assert-revert">Error Handling in Solidity - Require, Assert, Revert</h2>
<p>Error handling in Solidity can be achieved through a few different keywords and operations.</p>
<p>The EVM will revert all changes to the blockchain’s state when there is an error In other words, when an exception is thrown, and it’s not caught in a try-catch block, the exception will “bubble up” the stack of methods that were called, and be returned to the user. All changes made to the blockchain state in the current call (and its sub-calls) get reversed.</p>
<p>There are some exceptions, in low-level functions like <code>delegatecall</code>, <code>send</code>, <code>call</code>, and so on, where an error will return the boolean <code>false</code> back to the caller, rather than bubble up an error.</p>
<p>As a developer there are three approaches you can take to handle and throw errors. You can use <code>require()</code>, <code>assert()</code> or <code>revert()</code>.</p>
<p>A require statement evaluates a boolean condition you specify, and if false, it will throw an error with no data, or with a string that you provide:</p>
<table><tbody><tr><td><p>function requireExample() public pure {<br>&nbsp; &nbsp; require(msg.value &gt;= 1 ether, "you must pay me at least 1 ether!");<br>}</p></td></tr></tbody></table>

<p>We use <code>require()</code> to validate inputs, validate return values, and check other conditions before we proceed with our code logic.</p>
<p>In this example, if the function’s caller does not send at least 1 ether, the function will revert and throw an error with a string message: “<em>you must pay me at least 1 ether!</em>”.</p>
<p>The error string that you want returned is the second argument to the <code>require()</code> function, but it is optional. Without it, your code will throw an error with no data - which is not terribly helpful.</p>
<p>The good thing about a <code>require()</code> is that it will return gas that has not been used, but gas that was used before the <code>require()</code> statement will be lost. That’s why we use <code>require()</code> as early as possible.</p>
<p>An <code>assert()</code> function is quite similar to <code>require()</code> except that it <a target="_blank" href="https://docs.soliditylang.org/en/v0.8.17/control-structures.html#panic-via-assert-and-error-via-require">throws an error with type <code>Panic(uint256)</code> rather than <code>Error(string)</code></a>.</p>
<table><tbody><tr><td><p>contract ThrowMe { &nbsp;<br>&nbsp; &nbsp; function assertExample() public pure {<br>&nbsp; &nbsp; &nbsp; &nbsp; assert(address(this).balance == 0);<br>&nbsp; // Do something.<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>An assert is also used in slightly different situations– where a different type of guarding is required.</p>
<p>Most often you use an assert to check an “invariant” piece of data. In software development, an invariant is one or more pieces of data whose value never changes while the program is executing.</p>
<p>In the above code example, the contract is a tiny contract, and is not designed to receive or store any ether. Its design is meant to ensure that it always has a contract balance of zero, which is the invariant we test for with an assert.</p>
<p><code>Assert()</code> calls are also used in internal functions. They test that local state does not hold unexpected or impossible values, but which may have changed due to the contract state becoming “dirty”.</p>
<p>Just as <code>require()</code> does, an <code>assert()</code> will also revert all changes. Prior to Solidity’s v0.8, <code>assert()</code> used to use up all remaining gas, which was different from <code>require()</code>.</p>
<p>In general, you’d likely use <code>require()</code> more than <code>assert()</code>.</p>
<p>A third approach is to use a <code>revert()</code> call. This is generally used in the same situation as a <code>require()</code> but where your conditional logic is much more complex.</p>
<p>In addition, you can throw custom-defined errors when using <code>revert()</code>. Using custom errors can often be cheaper in terms of gas used, and are generally more informative from a code and error readability point of view.</p>
<p>Note how I improve the readability and traceability of my error by prefixing my custom error’s name with the Contract name, so we know which contract threw the error.</p>
<table><tbody><tr><td><p>contract ThrowMe { &nbsp;<br>&nbsp; &nbsp; // custom error<br>&nbsp; &nbsp; error ThrowMe_BadInput(string errorMsg, uint inputNum);<br><br>&nbsp; &nbsp; function revertExample(uint input) public pure {<br>&nbsp; &nbsp; &nbsp; &nbsp; if (input &lt; 1000 ) {<br>&nbsp; &nbsp; revert ThrowMe_BadInput("Number must be an even number greater than 999",&nbsp; input);<br>&nbsp; &nbsp; &nbsp; }<br><br>&nbsp; &nbsp; &nbsp; if (input &lt; 0) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; revert("Negative numbers not allowed");<br>&nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>In the above example, we use revert once with a custom error that takes two specific arguments, and then we use revert another time with only a string error data. In either case, the blockchain state is reverted and unused gas will be returned to the caller.</p>
<h2 id="heading-inheritance-in-solidity">Inheritance in Solidity</h2>
<p><a target="_blank" href="https://www.freecodecamp.org/news/inheritance-in-java-explained/">Inheritance</a> is a powerful concept in Object Oriented Programming (OOP). We won't go into the details of what <a target="_blank" href="https://www.freecodecamp.org/news/object-oriented-concepts/">OOP</a> is here. But the best way to reason about inheritance in programming is to think of it as a way by which pieces of code “inherit” data and functions from other pieces of code by importing and embedding them.</p>
<p><a target="_blank" href="https://goo.gl/maps/YgMqAwFfHUP8EZmS9">Inheritance in Solidity</a> also allows a developer to access, use and modify the properties (data) and functions (behaviour) of contracts that are inherited from.</p>
<p>The contract that receives this inherited material is called the derived contract, child contract or the subclass. The contract whose material is made available to one or more derived contracts is called a parent contract.</p>
<p>Inheritance facilitates convenient and extensive code reuse – imagine a chain of application code that inherits from other code, and those in turn inherit from others and so on. Rather than typing out the entire hierarchy of inheritance, we can just use a a few key words to “extend” the functions and data captured by all the application code in the inheritance chain. That way child contract gets the benefit of all parent contracts in its hierarchy, like genes that get inherited down each generation.</p>
<p>Unlike some programming languages like Java, Solidity allows for multiple inheritance. Multiple inheritance refers to the ability of a derived contract to inherit data and methods from more than one parent contract. In other words, one child contract can have multiple parents.</p>
<p>You can spot a child contract and identify its parent contract by looking for the <code>is</code> keyword.</p>
<table><tbody><tr><td><p>contract A {<br>&nbsp; &nbsp; string public constant A_NAME = "A";<br><br>&nbsp; &nbsp; function getName() public pure returns (string memory) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return A_NAME;<br>&nbsp; &nbsp; }<br>}<br><br>contract B is A {<br>&nbsp; &nbsp; string public constant B_NAME = "B";<br>}</p></td></tr></tbody></table>

<p>If you were to deploy only Contract B using the in-browser <a target="_blank" href="http://remix.ethereum.org">Remix IDE</a> you’d note that Contract B has access to the <code>getName()</code> method even though it was not ever written as part of Contract B. When you call that function, it returns “A” , which is data that is implemented in Contract A, not contract B. Contract B has access to both storage variables <code>A_NAME</code> and <code>B_NAME</code>, and all functions in Contract A.</p>
<p>This is how inheritance works. This is how Contract B reuses code already written in Contract A, which could have been written by someone else.</p>
<p>Solidity lets developers change how a function in the parent contract is implemented in the derived contract. Modifying or replacing the functionality of inherited code is referred to as “overriding”. To understand it, let’s explore what happens when Contract B tries to implement its own <code>getName()</code> function.</p>
<p>Modify the code by adding a <code>getName()</code> to Contract B. Make sure the function name and signature is identical to what is in Contract A. A child contract’s implementation of logic in the <code>getName()</code> function can be totally different from how it’s done in the parent contract, as long as the function name and its signature are identical.</p>
<table><tbody><tr><td><p>contract A {<br>&nbsp; &nbsp; string public constant A_NAME = "A";<br><br>&nbsp; &nbsp; function getName() public returns (string memory) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return A_NAME;<br>&nbsp; &nbsp; }<br>}<br><br>contract B is A {<br>&nbsp; &nbsp; string public constant B_NAME = "B";<br><br>&nbsp; &nbsp; function getName() public returns (string memory) {</p></td></tr></tbody></table>

<p>The compiler will give you two errors:</p>
<ol>
<li><p>In Contract A, it will indicate that you are “<em>trying to override non-virtual function</em>” and prompt you by asking if you forgot to add the <code>virtual</code> keyword.</p>
</li>
<li><p>In Contract B, it will complain that the <code>getName()</code> function is missing the <code>override</code> specifier.</p>
</li>
</ol>
<p>This means that your new <code>getName</code> in Contract B is attempting to override a function by the same name in the parent contract, but the parent’s function is not marked as <code>virtual</code> – which means that it cannot be overridden.</p>
<p>You could change Contract A’s function and add <code>virtual</code> as follows:</p>
<table><tbody><tr><td><p>function getName() public virtual returns (string memory) {<br>&nbsp; &nbsp; return A_NAME;<br>}</p></td></tr></tbody></table>

<p>Adding the keyword <code>virtual</code> does not change how the function operates in Contract A. And it does not require that inheriting contracts <strong>must</strong> re-implement or override it. It simply means that this function <strong>may</strong> be overridden by any derived contracts if the developer chooses.</p>
<p>Adding <code>virtual</code> fixes the compiler’s complaint for Contract A, but not for Contract B. This is because <code>getName</code> in Contract B needs to also add the <code>override</code> keyword as follows:</p>
<table><tbody><tr><td><p>function getName() public pure override returns (string memory) {<br>&nbsp; &nbsp; return B_NAME;<br>}</p></td></tr></tbody></table>

<p>We also add the <code>pure</code> keyword for Contract B’s getName() as this function does not change the state of the blockchain, and reads from a constant (constants, you’ll remember, are hardcoded into the bytecode at compile time and are not in the storage data location).</p>
<p>Keep in mind that you only need to override a function if the name and the signature are identical.</p>
<p>But what happens with functions that have identical names but different arguments? When this happens it’s not an override, but an overload. And there is no conflict because the methods have different arguments, and so there is enough information in their signatures to show the compiler that they're different.</p>
<p>For example, in contract B we could have another <code>getName()</code> function that takes an argument, which effectively gives the function a different “signature” compared to the parent Contract A’s <code>getName()</code> implementation. Overloaded functions do not need any special keywords:</p>
<table><tbody><tr><td><p>// getName() now accepts a string argument.&nbsp;</p></td></tr></tbody></table>

<p>Don’t worry about the <code>abi.encodepacked()</code> method call. I’ll explain that later when we talk about encoding and decoding. For now just understand that <code>encodepacked()</code> encodes the strings into bytes and then concatenates them, and returns a bytes array.</p>
<p>We discussed the relationship between Solidity strings and bytes in a previous section of this handbook (under Typing).</p>
<p>Also, since you’ve already learned about function modifiers, this is a good place to add that modifiers are also inheritable. Here’s how you’d do it:</p>
<table><tbody><tr><td><p>contract A {<br>&nbsp; &nbsp; modifier X virtual {<br>&nbsp; &nbsp; &nbsp; &nbsp;// … some logic</p></td></tr></tbody></table>

<p>You might wonder which version of a function will be called if a function by the same name and signature exists in a chain of inheritance.</p>
<p>For example, let's say there is a chain of inherited contracts like A → B → C → D → E and all of them have a <code>getName()</code> that overrides a <code>getName()</code> in the previous parent contract.</p>
<p>Which <code>getName()</code> gets called? The answer is the last one – the “most derived” implementation in the contract hierarchy.</p>
<p>State variables in child contracts cannot have the same name and type as their parent contracts.</p>
<p>For example, Contract B below will not compile because its state variable “shadows” that of the parent Contract A. But note how Contract C correctly handles this:</p>
<table><tbody><tr><td><p>contract A {<br>&nbsp; &nbsp; string public author = "Zubin";<br><br>&nbsp; &nbsp; function getAuthor() public virtual returns (string memory) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return author;<br>&nbsp; &nbsp; }<br>}<br><br></p></td></tr></tbody></table>

<p>It’s important to note that by passing a new value to the variable <code>author</code> in Contract C’s constructor, we are effectively overriding the value in Contract A. And then calling the inherited method <code>C.getAuthor()</code> will return ‘Hemingway’ and not ‘Zubin’!</p>
<p>It is also worth noting that when a contract inherits from one or more parent contract, only one single (combined) contract is created on the blockchain. The compiler effectively compiles all the other contracts and their parent contracts and so on up the entire hierarchy all into a single compiled contract (which is referred to as a “flattened” contract).</p>
<h2 id="heading-inheritance-with-constructor-parameters">Inheritance with Constructor Parameters</h2>
<p>Some constructors specify input parameters and so they need you to pass arguments to them when instantiating the smart contract.</p>
<p>If that smart contract is a parent contract, then its derived contracts must also pass arguments to instantiate the parent contracts.</p>
<p>There are two ways to pass arguments to parent contracts - either in the statement that lists the parent contracts, or directly in the constructor functions for each parent contract. You can see both approaches below:</p>
<p><img src="https://lh5.googleusercontent.com/8MV8HOaET3aVL30ygclKgPhUKIiMK8feTpNNN20W4qFQ880SPBFNeRb2BsS7fLR7b8iUJpRPdG1osMGT451FKOZGpuiihn8h00hTHipxe-MPh9QQ1t2bm2r-qhe4xj7vFFewg64ve9NPjlMlN3BHaX7hWG2ZJvMC8-tsHS2vV74ZluERre2fcH_52CFO9Q" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In Method 2 in the <code>ChildTwo</code> contract, you’ll note that the arguments passed to the parent contracts are first supplied to the child contract and then just passed up the inheritance chain.</p>
<p>This is not necessary, but is a very common pattern. The key point is that where parent contract constructor functions expect data to be passed to them, we need to provide them when we instantiate the child contract.</p>
<h2 id="heading-type-conversion-and-type-casting-in-solidity">Type Conversion and Type Casting in Solidity</h2>
<p>Sometimes we need to convert one data type to another. When we do so we need to be very careful when converting data and how the converted data is understood by the computer.</p>
<p>As we saw in our discussion on typed data, JavaScript can sometimes do strange things to data because it is dynamically typed. But that’s also why it’s useful to introduce the concept of type casting and type conversions generally.</p>
<p>Take the following JavaScript code:</p>
<table><tbody><tr><td><p>var a = "1"<br>var b = a +&nbsp; 9 // we get the string '19'!!<br>typeof a // string<br>typeof b // string&nbsp;</p></td></tr></tbody></table>

<p>There are two ways of converting the variable <code>a</code> into an integer. The first, called type casting, is done explicitly by the programmer and usually involves a constructor-like operator that uses <code>()</code>.</p>
<table><tbody><tr><td><p>a = Number(a) // Type casting the string to number is explicit.<br>typeof a // number</p></td></tr></tbody></table>

<table><tbody><tr><td><p>var b = a +&nbsp; 9 // 10. A number. More intuitive!</p></td></tr></tbody></table>

<p>Now let's reset <code>a</code> to a string and do an implicit conversion, also known as a type conversion. This is implicitly done by the compiler when the program is executed.</p>
<table><tbody><tr><td><p><em>a = '1'</em><br><em>var b = a * 9 // Unlike addition, this doesn't concatenate but implicitly converts 'a' to a number!&nbsp;</em></p></td></tr></tbody></table>

<p>In Solidity, type casting (explicit conversion) is permissible between some types, and would look like this:</p>
<table><tbody><tr><td><p>uint256 a = 2022;<br>bytes32 b = bytes32(a);</p></td></tr></tbody></table>

<p>In this example we converted an integer with a size of 256 bits (since 8 bits makes 1 byte, this is 32 bytes) into a bytes array of size 32.</p>
<p>Since both the integer value of 2022 and the bytes value are of length 32 bytes, there was no “loss” of information in the conversion.</p>
<p>But what would happen if you tried to convert 256 bits into 8 bits (1 byte)? Try running the following in your browser-based Remix IDE:</p>
<table><tbody><tr><td><p>contract Conversions {<br>&nbsp; function explicit256To8() public pure returns (uint8) {<br>&nbsp; &nbsp; &nbsp; uint256 a = 2022;<br>&nbsp; &nbsp; &nbsp; uint8 b = uint8(a);<br>&nbsp; &nbsp; &nbsp; return b;<em> // 230.</em>&nbsp;&nbsp;&nbsp;</p></td></tr></tbody></table>

<p>Why does the integer 2022 get converted to 230? That’s clearly an undesirable and unexpected change in the value. A bug, right?</p>
<p>The reason is that an unsigned integer of size 256 bits will hold 256 binary digits (either 0 or 1). So <code>a</code> holds the integer value ‘2022’ and that value, in bits, will have 256 digits, of which most will be 0, except for the last 11 digits which will be... (see for yourself by converting 2022 from decimal system to binary <a target="_blank" href="https://decimaltobinary.com/256-in-binary">here</a>).</p>
<p>The value of <code>b</code> on the other hand will have only 8 bits or digits, being 11100110. This binary number, when converted to decimal (you can use the same converter - just fill in the other box!) is 230. Not 2022.</p>
<p>Oopsie.</p>
<p>So what happened? When we dropped the integer’s size from 256 bits to 8 bits we ended up shaving the first three digits of data (11111100110) which totally changed the value in binary!</p>
<p>This, folks, is information loss.</p>
<p>So when you’re explicitly casting, the compiler will let you do it in some cases. But you could lose data, and the compiler will assume you know what you’re doing because you’re explicitly asking to do it. This can be the source of many bugs, so make sure you test your code properly for expected results and be careful when explicitly casting data to smaller sizes.</p>
<p>Casting up to larger sizes does not result in data lost. Since 2022 needs only 11 bits to be represented, you could declare the variable <code>a</code> as type <code>uint16</code> and then up-cast it to a variable <code>b</code> of type <code>uint256</code> without data loss.</p>
<p>The other kind of casting that is problematic is when you’re casting from unsigned integers to signed integers. Play around with the following example:</p>
<table><tbody><tr><td><p>contract Conversions {<br>&nbsp; function unsignedToSigned() public pure returns (int16, uint16) {<br>&nbsp; &nbsp; &nbsp; int16 a = -2022;<br>&nbsp; &nbsp; &nbsp; uint16 b = uint16(a);<br>&nbsp; &nbsp; &nbsp; // uint256 c = uint256(a); // Compiler will complain<br>&nbsp; &nbsp; &nbsp; return (a, b); // b is 63514<br>&nbsp; }<br>}</p></td></tr></tbody></table>

<p>Note that <code>a</code> , being a signed integer of size 16 bits holds -2022 as a (negative integer) value. If we explicitly type cast it to an <em>unsigned</em> integer (only positive) values, the compiler will let us do it.</p>
<p>But if you run the code, you’ll see that <code>b</code> is not -2022 but 63,514! Because <code>uint</code> cannot hold information regarding the minus sign, it has lost that data, and the resulting binary gets converted to a massive decimal (base 10) number - clearly undesirable, and a bug.</p>
<p>If you go further, and un-comment the line that assigns the value of <code>c</code>, you’ll see the compiler complain with '<em>Explicit type conversion not allowed from "int16" to "uint256"</em>'. Even though we are up-casting to a larger number of bits in <code>uint256</code>, because <code>c</code> is an unsigned integer, it cannot hold minus sign information.</p>
<p>So when explicitly casting, be sure to think through what the value will evaluate to after you’ve forced the compiler to change the type of the data. It is the source of many bugs and code errors.</p>
<p>There is more to Solidity type conversions and type casting and you can go deep into some of the nitty gritty in <a target="_blank" href="https://betterprogramming.pub/solidity-tutorial-all-about-conversion-661130eb8bec">this article</a>.</p>
<h2 id="heading-how-to-work-with-floating-point-numbers-in-solidity">How to Work with Floating Point Numbers in Solidity</h2>
<p>Solidity doesn’t handle decimal points. That may change in the future, but currently you cannot really work with fixed (floating) point numbers like 93.6. In fact typing <code>int256 floating = 93.6;</code> in your Remix IDE will throw an error like : <em>Error: Type rational_const 468 / 5 is not implicitly convertible to expected type int256.</em></p>
<p>What’s going on here? 468 divided by 5 is 93.6, which seems a weird error, but that’s basically the compiler saying it cannot handle floating point numbers.</p>
<p>Follow the suggestions of the error, and declare the variable’s type to be <code>fixed</code> or <code>ufixed16x1</code>.</p>
<table><tbody><tr><td><p>fixed floating = 93.6;</p></td></tr></tbody></table>

<p>You’ll get an “<em>UnimplementedFeatureError: Not yet implemented - FixedPointType</em>” error.</p>
<p>So in Solidity, we get around this by converting the floating point number to a whole number (no decimal points) by multiplying by 10 raised to the exponent of the number of decimal places to the right of the decimal point.</p>
<p>In this case we multiply 93.6 by 10 to get 936 and we have to keep track of our factor (10) in a variable somewhere. If the number was 93.2355 we would multiply it by 10 to the power 4 as we need to shift the decimal 4 places to the right to make the number whole.</p>
<p>When working with ERC tokens we will note that the decimal places are often 10, 12, or 18.</p>
<p>For example, 1 Ether is 1*(10^18) wei, which is 1 followed by 18 zeros. If we wanted that expressed with a floating point, we would need to divide 1000000000000000000 by 10^18 (which will give us 1), but if it was 1500000000000000000 wei, then dividing by 10^18 will throw a compiler error in Solidity, because it cannot handle the return value of 1.5.</p>
<p>In scientific notation, 10^18 is also expressed as 1e18, where 1e represents 10 and the number after that represents the exponent that 1e is raised to.</p>
<p>So the following code will produce a compiler error: “<em>Return argument type rational_const 3 / 2 is not implicitly convertible to expected type…int256</em>”:</p>
<table><tbody><tr><td><p>function divideBy1e18()public pure returns (int) {<br>&nbsp; &nbsp; return 1500000000000000000/(1e18); // 1.5 → Solidity can’t handle this.</p></td></tr></tbody></table>

<p>The result of the above division operation is 1.5, but that has a decimal point which Solidity does not currently support. Thus Solidity smart contracts return very big numbers, often up to 18 decimal places, which is more than JavaScript can handle. So you'll need to handle that appropriately in your front end using JavaScript libraries like <a target="_blank" href="https://docs.ethers.io">Ethersjs</a> that implement helper functions for the <a target="_blank" href="https://docs.ethers.io/v5/api/utils/bignumber/">BigNumber</a> type.</p>
<h2 id="heading-hashing-abi-encoding-and-decoding">Hashing, ABI Encoding and Decoding</h2>
<p>As you work more with Solidity, you’ll see some strange-sounding terms like hashing, ABI encoding, and ABI decoding.</p>
<p>While these can take some effort to wrap your head around, they’re quite fundamental to working with cryptographic technology, and Ethereum in particular. They’re not complex in principle, but can be a bit hard to grasp at first.</p>
<p>Let’s start with hashing. Using cryptographic math, you can convert <strong>any</strong> data into a (very large) unique integer. This operation is called hashing. There are some key properties to hashing algorithms:</p>
<ol>
<li><p>They’re deterministic - identical inputs will <strong>always</strong> produce an identical output, each time and every time. But the chance of producing the same output using different inputs is extremely unlikely.</p>
</li>
<li><p>It is not possible (or computationally infeasible) to reverse engineer the input if you only have the output. It is a one-way process.</p>
</li>
<li><p>The output’s size (length) is fixed - the algorithm will produce fixed-size outputs for all inputs, regardless of the input size. In other words the outputs of a hashing algorithm will always have a fixed number of bits, depending on the algorithm.</p>
</li>
</ol>
<p>There are many algorithms that are industry-standard for hashing but you’ll likely see SHA256 and Keccak256 most commonly. These are very similar. And the 256 refers to the size - the number of bits in the hash that is produced.</p>
<p>For example, go to <a target="_blank" href="https://emn178.github.io/online-tools/keccak_256.html">this site</a> and copy and paste “FreeCodeCamp” into the text input. Using the Keccak256 algorithm, the output will (always) be <code>796457686bfec5f60e84447d256aba53edb09fb2015bea86eb27f76e9102b67a</code>.</p>
<p>This is a 64 character hexadecimal string, and since each character in a hex string represents 4 bits, this hexadecimal string is 256 bits (32 bytes long).</p>
<p>Now, delete everything in the text input box except the “F”. The result is a totally different hex string, but it still has 64 characters. This is the “fixed-size” nature of the Keccak265 hashing algorithm.</p>
<p>Now paste back the “FreeCodeCamp” and change any character at all. You could make the “F” lowercase. Or add a space. For each individual change you make, the hash hex string output changes a lot, but the size is constant.</p>
<p>This is an important benefit from hashing algorithms. The slightest change changes the hash substantially. Which means you can always test whether two things are identical (or have not been tampered with at all) by comparing their hashes.</p>
<p>In Solidity, comparing hashes is much more efficient than comparing the primitive data types.</p>
<p>For example, comparing two strings is often done by comparing the hashes of their ABI-encoded (bytes) form. A common helper function to compare two strings in Solidity would look like this:</p>
<table><tbody><tr><td><p>function compareStrings(string memory str1, string memory str2)<br>&nbsp; &nbsp; &nbsp; &nbsp; public<br>&nbsp; &nbsp; &nbsp; &nbsp; pure<br>&nbsp; &nbsp; &nbsp; &nbsp; returns (bool)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; return (keccak256(abi.encodePacked((str1))) ==<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keccak256(abi.encodePacked((str2))));<br>&nbsp; &nbsp; }</p></td></tr></tbody></table>

<p>We’ll address what ABI encoding is in a moment, but note how the result of <code>encodePacked()</code> is a <code>bytes</code> array which is then hashed using the keccak256 algorithm (this is the native hashing algorithm used by Solidity). The hashed outputs (256 bit integers) are compared for equality.</p>
<p>Now let's turn to ABI encoding. First, we recall that ABI (Application Binary Interface) is the interface that specifies how to interact with a deployed smart contract. ABI-encoding is the process of converting a given element from the ABI into bytes so that the EVM can process it.</p>
<p>The EVM runs computation on bits and bytes. So encoding is the process of <a target="_blank" href="https://stackoverflow.com/questions/14822323/why-is-encoding-and-decoding-needed-for-any-programming-language-database">converting structured input data into bytes</a> so that a computer can operate on it. Decoding is the reverse process of converting bytes back into structured data. Sometimes, encoding is also referred to as “serializing”.</p>
<p>You can read more about the solidity built-in methods provided with the global variable <code>abi</code> that do different types of encoding and decoding <a target="_blank" href="https://docs.soliditylang.org/en/latest/cheatsheet.html#global-variables">here</a>. Methods that encode data convert them to byte arrays (<code>bytes</code> data type). In reverse, methods that decode their inputs expect the bytes data type as input and then convert that into the data types that were encoded.</p>
<p>You can observe this in the following snippet:</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.13;<br><br>contract EncodeDecode {<br><br></p></td></tr></tbody></table>

<p>I ran the above in Remix, and used the following inputs for <code>encode()</code>: 1981, 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC, [1,2,3,4].</p>
<p>And the bytes I got returned were represented in hexadecimal form as the following:</p>
<pre><code class="lang-plaintext">0x00000000000000000000000000000000000000000000000000000000000007bd0000000000000000000000003c44cdddb6a900fa2b585dd299e03d12fa4293bc000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004
</code></pre>
<p>I fed this as my input into the <code>decode()</code> function and got my original three arguments back.</p>
<p>Thus, the purpose of encoding is to convert data into the bytes data type that the EVM needs to process data. And decoding brings it back into the human readable structured data that we developers can work with.</p>
<h2 id="heading-how-to-call-contracts-and-use-the-fallback-function">How to Call Contracts and Use the Fallback Function</h2>
<p>Depending on the design of the smart contract and the visibility specifiers present in it, the contract can be interacted with by other smart contracts or by externally owned accounts.</p>
<p>Calling from your wallet via Remix is an example of the latter, as is using Metamask. You can also interact with smart contracts programmatically via libraries like EthersJS and Web3JS, the Hardhat and Truffle toolchains, and so on.</p>
<p>For the purposes of this Solidity handbook, we will use Solidity to interact with another contract.</p>
<p>There are two ways for a smart contract to call other smart contracts. The first way calls the target contract directly, by using interfaces (which we discussed previously). Or, if the Target contract is imported into the scope of the calling contract, it directly calls it.</p>
<p>This approach is illustrated below:</p>
<table><tbody><tr><td><p>contract Target {<br>&nbsp; &nbsp; int256 public count;<br><br>&nbsp; &nbsp; function decrement() public {<br>&nbsp; &nbsp; &nbsp; &nbsp; count--;<br>&nbsp; &nbsp; }<br>}<br><br>interface ITarget {<br>&nbsp; &nbsp; function decrement() external;<br>}<br><br>contract TargetCaller {<br>&nbsp; &nbsp; function callDecrementInterface(address _target) public {<br>&nbsp; &nbsp; &nbsp; &nbsp; ITarget target = ITarget(_target);<br>&nbsp; &nbsp; &nbsp; &nbsp; target.decrement();<br><br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; function callDecrementDirect(Target _target) public {<br>&nbsp; &nbsp; &nbsp; &nbsp; _target.decrement();<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>In Remix you can deploy <code>Target</code> first, and call <code>count()</code> to see that the default value for the count variable is <code>0</code>, as expected. This value will be decremented by 1 if you call the <code>decrement()</code> method.</p>
<p>Then you can deploy <code>TargetCaller</code> and there are two methods you can call, both of which will decrement the value of <code>count</code> in <code>Target</code>.</p>
<p>Note that each of these two methods access the <code>Target</code> contract using a slightly different syntax. When interacting by using the <code>ITarget</code> interface, the first method takes in <code>Target</code>’s address whereas the second method treats <code>Target</code> as a custom type.</p>
<p>This second approach is only possible when the <code>Target</code> contract is declared in, or imported into, the same file as the <code>TargetCaller</code>. Most often, you will interact with smart contracts deployed by third parties, for which they publish ABI interfaces.</p>
<p>Each time you call these methods, the value of <code>count</code> in <code>Target</code> will decrease by <code>1</code>. This is a very common way to interact with other smart contracts.</p>
<p>The second way to do it is by using the “low level” call syntax that Solidity provides. You use this when you also want to send some ether (value) to the target contract. Will talk about sending value in the next section, but for now just replace the code in Remix with the following:</p>
<table><tbody><tr><td><p>contract Target {<br>&nbsp; &nbsp; int256 public count;<br><br>&nbsp; &nbsp; function decrement(int num) public payable {<br>&nbsp; &nbsp; &nbsp; &nbsp; count = count - num;<br>&nbsp; &nbsp; }<br>}<br><br>interface ITarget {<br>&nbsp; &nbsp; function decrement(int num) external payable;<br>}<br><br>contract TargetCaller {<br>&nbsp; &nbsp; function callDecrementLowLevel(address _target) public {<br>&nbsp; &nbsp; &nbsp; &nbsp; ITarget target = ITarget(_target);<br>&nbsp; &nbsp; &nbsp; &nbsp; target.decrement{value:0}(5);<br><br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; // other decrementing functions….<br>}</p></td></tr></tbody></table>

<p>You’ll note that <code>decrement()</code> now takes an argument, and the interface and the <code>Target</code> contract are updated with this new input data.</p>
<p>Next note that <code>TargetCaller</code> implements a new function that calls <code>decrement()</code> with a new syntax, explained below.</p>
<p><img src="https://lh4.googleusercontent.com/xwOSOgsIrqRNzz2PFYziACphMXlVp1QWDItbAAaxAHGYChhIq7eyntuP6FQOrYdWL37dvD4qyUrp2SAOgwk8BC9nnm27k_0jCOCbTvEBbTPvGvd2xMoCfIjV75s6l9O7a-nEPJbpFVzKDnOdP-2S6Ot-8vtV6iD-SRYNp1pCRe8mfQDij7_c8Ek2LDux6Q" alt="Calling a contract's function and sending it value in Wei." width="600" height="400" loading="lazy"></p>
<p>In the next section we will see examples of these low level ways of calling a target smart contract to send Ether to it.</p>
<p>But what happens when you call a contract and it doesn’t actually have the function you tried to call?</p>
<p>This can happen maliciously to exploit how Solidity works on the EVM. Or, more commonly, it can happen accidentally. This occurs when, for example, there is an error in the Interface and the compiler cannot match the function and parameters you sent with any that are actually contained in the contract. What happens then?</p>
<p>For these situations, many contracts employ a special function called the fallback function. The function looks like a normal function but it doesn’t need the <code>function</code> keyword. If you want it to also handle situations where your contract is sent some ether, you must also mark it <code>payable</code>. But this is not the recommended way to enable your contract to receive payments.</p>
<p>Let’s take a look by repurposing our previous <code>Target</code>, <code>ITarget</code> and <code>TargetCaller</code> and adding a fallback function as follows:</p>
<table><tbody><tr><td><p>contract Target {<br>&nbsp; &nbsp; int256 public count;<br><br>&nbsp; &nbsp; function decrement(int num) public payable {<br>&nbsp; &nbsp; &nbsp; &nbsp; count = count - num;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; fallback() external payable&nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; count++;<br>&nbsp; &nbsp; }<br>}<br><br>interface ITarget {<br>&nbsp; &nbsp; function decrement(int num) external payable;<br>&nbsp; &nbsp; function nonExistentFunction() external;<br>}<br><br>contract TargetCaller {<br>&nbsp; &nbsp; function callFallback(address _target) public {<br>&nbsp; &nbsp; &nbsp; &nbsp; ITarget target = ITarget(_target);<br>&nbsp; &nbsp; &nbsp; &nbsp; target.nonExistentFunction();<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>Once we deploy a fresh instance of <code>Target</code>, we can call <code>count()</code> and see that it is set to the default value of zero.</p>
<p>Next we can deploy <code>TargetCaller</code> and call the <code>callFallback()</code> method which internally calls <code>nonExistentFunction()</code>.</p>
<p>It’s worth noting that the interface says that <code>nonExistentFunction()</code> is available but the actual <code>Target</code> contract does not have any such function. This is why the <code>Target</code> fallback function gets triggered and the value of count is now incremented by <code>1</code>.</p>
<p>The purpose of the fallback function is to handle calls to the contract where no other function is available to handle it. And if the fallback is marked <code>payable</code>, the fallback function will also enable the smart contract to receive Ether (though that is not the recommended use for fallback). We will cover this in the next section.</p>
<h2 id="heading-how-to-send-and-receive-ether">How to Send and Receive Ether</h2>
<p>To send Ether to a target contract from your smart contract, you need to call the target contract using one of the following three in-built Solidity methods: <code>transfer</code>, <code>send</code> or <code>call</code>.</p>
<p><code>transfer</code> will throw an exception when it fails, and <code>send</code> and <code>call</code> will return a boolean that you must check before proceeding. Of these three, <code>transfer</code> and <code>send</code> are no longer recommended for security reasons, though you can still use them and they'll work.</p>
<p>Smart Contracts cannot receive Ether except in the following scenarios:</p>
<ul>
<li><p>They implement a <code>payable</code> fallback or <code>payable</code> receive special function, or</p>
</li>
<li><p>Forcibly when the calling contract calls <code>selfdestruct</code> and forces a target contract to accept all its remaining ether. The calling contract is then deleted from the blockchain. This is a separate topic and is often used maliciously by exploiters.</p>
</li>
</ul>
<p>It is generally recommended that you use a <code>receive()</code> function if you want your smart contract to receive Ether. You can get away by just making your fallback function <code>payable</code>, but recommended practice is to use a <code>receive()</code> function instead.</p>
<p>If you rely only on the fallback function, your compiler will grumble at you with the following message: “<em>Warning: This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.”</em></p>
<p>If you have both <code>receive</code> and <code>fallback</code>, you may legitimately wonder how Solidity decides which function to receive Ether with. This design decision also tells you what these functions are designed to do.</p>
<p>Receive is meant to receive ether. And fallback is meant to handle situations where the contract has been called but, as we discussed in the previous section, there is no matching method in the contract that can handle the call.</p>
<p>Solidity matches the method that was intended to be called by checking the <code>msg.data</code> field in the transaction sent by the caller. If that field is a non-empty value, and that value does not match any other function declared in the called contract, then the fallback method is triggered.</p>
<p>If <code>msg.data</code> is empty, then it will check if there is a receive function that has been implemented. If so, it will use that to accept the Ether. If no receive exists, it will default to the fallback function. The fallback is therefore the...fallback (default) method when nothing else makes sense.</p>
<p>The <code>receive</code> function is the better way to enable your contract to receive Ether. You can use the fallback function for any scenario where your smart contract is called but there is nothing to “handle” that call.</p>
<p>Here is a super handy logic tree that shows what receive and fallback are intended to handle.</p>
<table><tbody><tr><td><p>Which function is called, fallback() or receive()?<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; send Ether<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; msg.data is empty?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / \<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; yes&nbsp; no<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / &nbsp; &nbsp; \<br>receive() exists?&nbsp; fallback()<br>&nbsp; &nbsp; &nbsp; &nbsp; / &nbsp; \<br>&nbsp; &nbsp; &nbsp; &nbsp; yes &nbsp; no<br>&nbsp; &nbsp; &nbsp; &nbsp; /&nbsp; &nbsp; &nbsp; \<br>&nbsp; &nbsp; receive() &nbsp; fallback()</p></td></tr></tbody></table>

<p>(credit: <a target="_blank" href="https://solidity-by-example.org/sending-ether/">Solidity By Example</a>)</p>
<p>Going back to our example where we explored the fallback function, we can add a <code>receive</code> function to <code>Target</code> as follows:</p>
<table><tbody><tr><td><p>contract Target {<br>&nbsp; &nbsp; int256 public count;<br><br>&nbsp; &nbsp; function decrement() public payable {<br>&nbsp; &nbsp; &nbsp; &nbsp; count = count - num;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; fallback() external payable&nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; count++;<br>&nbsp; &nbsp; }</p></td></tr></tbody></table>

<p>We already saw how <code>callFallback</code> will change the count value in <code>Target</code>. But if we deploy a fresh instance of <code>Target</code>, we can now send it 10 wei, as shown below, because it now has a <code>payable</code> <code>receive</code> function. Prior to sending 10 wei (or any other amount) <code>Target</code> has a balance of zero, as shown below.</p>
<p><img src="https://lh5.googleusercontent.com/yCKofUjShb7KqezaShYgDsPMbx9EBX1aetb9AbzJJawPz-ehvzhsHkkW_Uyd4Ah95Wmrm6nbkKCCDKAkoFU7_obDJ6zeQIB1nU9Q9laJo3o58Lg1_A_tRj-zQyEj7_DOaIeKoc1fV8wAcUbfUY2vYhVljTrewhT1PyeWZbWyAv5KYdKySqtWu3P6D_3_bQ" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Hitting the Transact button with empty calldata (<code>msg.data</code>) will change the balance as shown in the image below. We can check <code>count</code> to see that it is incremented by 5, which is the logic in the <code>receive</code> function.</p>
<p><img src="https://lh5.googleusercontent.com/dMbTEYYraIK2EwGRYdkKxBFQ6rS1inTuyvVeNwJbObQoxAyJaZ957HHDm4buyKl5le1iP_f41hOB-4ACVm8Oz0wVK1LjPfylhEfpwP9oBo5RlWcN27XemNWWwrt0S2Vng5TaQlZyfnIhqPrV8xUaR2ZVS-Oj7F0XQUALn2AxENG_1PiK_uGT3mJLw-Iklw" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Sending Wei to the Target Contract and observing the updated balance</em></p>
<p>If we call <code>callFallback</code> and give it the address of the new <code>Target</code> instance, we will note that it increments only by <code>1</code>. If we include some wei, that will increase the balance of <code>Target</code> as well.</p>
<p>So any transfer of Ether to a smart contract would require the receiving smart contract to have <code>payable</code> functions that can receive it. At the very minimum, the receiving smart contract would need a <code>payable</code> fallback function, though a <code>payable</code> <code>receive</code> function is the better approach for receiving Ether payments.</p>
<h2 id="heading-solidity-libraries">Solidity Libraries</h2>
<p>In any programming language, a library refers to a collection of helper and utility functions that are designed to be reusable across multiple code bases. These functions solve specific, recurring programming problems.</p>
<p>In Solidity, libraries serve the same purpose, but have some special attributes.</p>
<p>First, they are stateless - that is, they don't store data (other than constants because these do not change the blockchain’s state). They also can't receive value (which means they cannot have <code>payable receive</code> or <code>fallback</code> functions).</p>
<p>They also cannot inherit from other contracts or libraries, nor can libraries have child (derived) contracts.</p>
<p>All functions declared in a library must not be abstract - that is, they must all have concrete implementations.</p>
<p>Since Solidity libraries are stateless, none of the methods in them can modify the blockchain’s state. This means all methods inside libraries are <code>pure</code> or <code>view</code> functions.</p>
<p>Another interesting attribute of Solidity libraries is that they don't need to be imported into your smart contract. They can be deployed as standalone contracts and then called via their interface in all consuming smart contracts - just as you would an API service in the traditional engineering world.</p>
<p>However, this is true only where the library contains public or external methods. Then that library can be deployed as a standalone contract with its own Ethereum address, and becomes callable to all consuming smart contracts.</p>
<p>If the libraries contain only internal methods, then the EVM simply “embeds” the library code into the smart contract that uses the library (because internal functions cannot be accessed from other smart contracts).</p>
<p>Libraries in Solidity have advantages that go beyond code reuse. Deploying a library one time on the blockchain can save on future gas costs by avoiding repeated deployment or importing of the library's code.</p>
<p>Let's look at a simple library and then dissect the code to understand how to use the library’s code.</p>
<table><tbody><tr><td><p>library WeirdMath {<br>&nbsp; &nbsp; int private constant factor = 100;<br><br>&nbsp; &nbsp; function applyFactor(int self) public pure returns (int) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return self * factor;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; function add(int self, int numberToAdd) public pure returns (int) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return self + numberToAdd;<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>This library has two methods that operate on the <code>int</code> data type. The first argument is called <code>self</code> for reasons that will become clear shortly. One method takes a number and then multiplies it by a constant value that is stored in the library’s code. The second method takes in two numbers and adds them.</p>
<p>Now let’s see how we can use this in a consuming smart contract.</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br><br>pragma solidity &gt;=0.5.22 &lt;=0.8.17;<br><br>contract StrangeMath {<br>&nbsp; &nbsp; // Method 1 - using Library name with dot notation<br>&nbsp; &nbsp; function multiplyWithFactor(int num) public pure returns (int) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return WeirdMath.applyFactor(num);<br>&nbsp; &nbsp; }<br><br><br>&nbsp; &nbsp; // Method 2 - the 'using' keyword and dot notation.<br>&nbsp; &nbsp; // Syntax: using &lt;&lt;Library Name&gt;&gt; for data type of the first argument in the method to be called.<br>&nbsp; &nbsp; using WeirdMath for int;<br>&nbsp; &nbsp; function addTwoNums(int num1, int num2) public pure returns (int) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return num1.add(num2);<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>The first thing to note is that there are two ways of using the <code>WeirdMath</code> library.</p>
<p>You can use it by either:</p>
<ol>
<li><p>Invoking the library’s name followed by the function you want to call, or</p>
</li>
<li><p>calling the function directly on the data type you want the function to operate on. This data type must be identical to the type of the <code>self</code> parameter in the library’s function.</p>
</li>
</ol>
<p>The first approach is demonstrated by method 1 in the code snippet where we invoke the library with <code>WeirdMath.add(num1, num2);</code>.</p>
<p>The second approach uses the Solidity <code>using</code> keyword. The expression <code>return num1.add(num2);</code> applies the <code>WeirdMath</code> library’s add function to the <code>num1</code> variable. This is the same as passing it in as <code>self</code>, which is the first argument to the add function.</p>
<h2 id="heading-events-and-logs-in-solidity">Events and Logs in Solidity</h2>
<p>Smart Contracts can emit events. The events contain pieces of data that you the developer specify.</p>
<p>Events cannot be consumed by other smart contracts. Instead, they are stored on the blockchain as logs, and can be retrieved via the APIs that read from the blockchain.</p>
<p>This means that your application (most commonly your front end application) can “read” logs that contain the event’s data from the blockchain. In this way your user interface can respond to events on the blockchain.</p>
<p>This is how application user interfaces are updated to respond to on-chain events. Since these logs on the blockchain can be queried, logs are a cheap form of storage, as discussed previously in the discussion on storage areas.</p>
<p>Events emitted by a Smart Contract can be inspected using the relevant blockchain explorer, because everything on a public blockchain is publicly viewable. But if the smart contract’s bytecode has not been verified, the event data may not be human readable (it will be encoded). The events of verified smart contracts will be human readable.</p>
<p>Nodes and other blockchain clients can listen for (subscribe to) specific events. At the heart of it, this is how <a target="_blank" href="http://docs.chain.link">Chainlink Oracles</a> work - decentralized oracle nodes listen to events from smart contracts, and then respond accordingly. They can even pull data off from events, run complex and resource-intensive computations off-chain, and then submit cryptographically verifiable computation results back onto the blockchain.</p>
<p>Other network APIs and indexing services <a target="_blank" href="https://thegraph.com/en/">like subgraphs</a> are made possible because of the ability to query blockchain data via the events emitted by smart contracts.</p>
<p>Here is what an Event looks like in Solidity:</p>
<table><tbody><tr><td><p>// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.7;<br><br>contract SimpleStorage {<br>&nbsp; &nbsp; uint256 favoriteNumber;<br><br>&nbsp; &nbsp; event storedNumber(<br>&nbsp; &nbsp; &nbsp; &nbsp; uint256 indexed oldNumber, // up to 3 indexed params allowed<br>&nbsp; &nbsp; &nbsp; &nbsp; uint256 indexed newNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; uint256 addedNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; address sender<br>&nbsp; &nbsp; );<br><br>&nbsp; &nbsp; function store(uint256 newNumber) public {<br>&nbsp; &nbsp; &nbsp; &nbsp; emit storedNumber(<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; favoriteNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newNumber + favoriteNumber,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg.sender<br>&nbsp; &nbsp; &nbsp; &nbsp; );<br>&nbsp; &nbsp; &nbsp; &nbsp; favoriteNumber = newNumber;<br>&nbsp; &nbsp; }<br><br>&nbsp; &nbsp; function retrieve() public view returns (uint256) {<br>&nbsp; &nbsp; &nbsp; &nbsp; return favoriteNumber;<br>&nbsp; &nbsp; }<br>}</p></td></tr></tbody></table>

<p>An event is first declared, and its arguments and their data types are specified. Any piece of data that has the <code>indexed</code> keyword is indexed by the EVM so that queries on blockchain logs can use the indexed param as a filter. This makes retrieving logs faster.</p>
<p>An event can store up to 4 indexed parameters - depending on whether it is anonymous or non-anonymous. Indexed event parameters are also referred to as “Topics” in the Solidity world.</p>
<p>Most events are non-anonymous, meaning that they include data on the name and arguments of the Event.</p>
<p>Non-anonymous events allow the developer to specify only 3 topics because the first topic is reserved to specify the Event signature in ABI-encoded hexadecimal form. You can read more about anonymous and non-anonymous topics <a target="_blank" href="https://docs.ethers.io/v5/concepts/events/#events-solidity">here</a>.</p>
<p>You can also explore Events on the relevant blockchain explorer (like <a target="_blank" href="http://etherscan.io">etherscan.io</a>).</p>
<p>You can approach this from one of two entry points. You can look at the contract’s address directly and then go to the Events Tab (which will show you events emitted by that contract only). Or you can go to a transaction hash and examine all the events emitted by all contracts that were touched by that transaction.</p>
<p>For example, below is a screenshot of the <a target="_blank" href="https://docs.chain.link/vrf/v2/subscription/supported-networks#ethereum-mainnet">Chainlink VRF Coordinator smart contract’s</a> events on Ethereum mainnet.</p>
<p><img src="https://lh3.googleusercontent.com/P-Ue4bGSB4swKcUxv6DJpuZxADBw6ZKPKeo_H7_x5lZBcJGuHxYUjcYm9rRCi80TFJSkKVpXJ_2zS7Pm9s0ASs9SrmIXc9uGTeTn_9e2FBwgTlRYSKQkB4cfIWRA3K8S8RWx6-5dEb048MtvlUkvPH17So9nPyo9R36L5Zwi8aoe4BdWfw4MIOH0M3NRjw" alt="Inspecting the Chainlink VRF Coordinator Contract's events on etherscan" width="600" height="400" loading="lazy"></p>
<p><em>Inspecting the Chainlink VRF Coordinator Contract's events on etherscan</em></p>
<p>The contract tab has a green tick mark which means the contract is verified, and so the Event name and arguments are human readable. Take a moment to study this image as it contains a lot of information! If you’d like to study it directly on etherscan, <a target="_blank" href="https://etherscan.io/address/0x271682DEB8C4E0901D1a1550aD2e64D568E69909#events">click here</a>.</p>
<p>This Chainlink VRF Coordinator contract responds to requests for cryptographically verifiable random numbers, and supplies the asking smart contract with random numbers (referred to as “random words”).</p>
<p>If you want to learn what the computer science meaning of “word” is, check out my colleague and I addressing this question in this <a target="_blank" href="https://youtu.be/lu3yDJQqqY0?t=2627">Chainlink 2022 Hackathon video</a>).</p>
<p>When the VRF Coordinator contract fulfills the request for random numbers, it emits a <code>RandomWordsFulfilled</code> event. That event contains 4 pieces of data, of which the first one, <code>requestID</code>, is indexed.</p>
<p>Solidity events contain three categories of data:</p>
<ol>
<li><p>The address of the contract that emitted the event.</p>
</li>
<li><p>The topics (indexed event parameters used for filtering queries of the logs).</p>
</li>
<li><p>Non-indexed parameters, referred to as “data”, and they are ABI-encoded and represented in hexadecimal. This data needs to be ABI-decoded, in the way described in the section on ABI encoding and decoding.</p>
</li>
</ol>
<p>When working in Remix you can also inspect the Events in the console as shown below:</p>
<p><img src="https://lh4.googleusercontent.com/YyXlklkork7-lcLKXdQqWYYGZeIX8IWaqRUgjKNGG9cG4AiyAG-9MGyjWwP8hXFT9tkSWu5Q6X8qVUHWwgczo-H4W07qAsmAPny4y8FWNz5jBQ1YynBIeor7mtpbZLshRRN4hYrehAj3lhXbzxEYYguNDqeJxjowshHeVLltuzrHXM8RMnS2-82bvGOcjg" alt="Inspecting Event data in the Remix Browser IDE" width="600" height="400" loading="lazy"></p>
<p><em>Inspecting Event data in the Remix Browser IDE</em></p>
<p>You can also programmatically access the events <a target="_blank" href="https://stackoverflow.com/questions/73230175/does-etherjs-transactionreceipt-have-an-events-object">using the contract receipts object</a> in EthersJS. Using the code snippet we used above in the SimpleStorage contract, we can access the events using EthersJS and Hardhat using the following JavaScript:</p>
<table><tbody><tr><td><p>const transactionResponse = await simpleStorage.store(1981)<br>const receipt = await transactionResponse.wait()<br><br>console.log(receipt.events[0].args.newNumber.toString()) // 1981</p></td></tr></tbody></table>

<p>You can also use libraries such as the EtherJs library in your front end application to <a target="_blank" href="https://docs.ethers.io/v5/getting-started/#getting-started--events">listen to events</a> and <a target="_blank" href="https://docs.ethers.io/v5/getting-started/#getting-started--history">filter historical events</a>. Both of these are useful when your application needs to respond to events on the blockchain.</p>
<h2 id="heading-time-logic-in-solidity">Time Logic in Solidity</h2>
<p>Time in Solidity is specified in relation to each block that gets added to the blockchain.</p>
<p>The global variable <code>block.timestamp</code> refers to the time, in milliseconds, when the block was generated and added to the blockchain. The milliseconds count refers to the number of milliseconds that have passed since the beginning of the Unix Epoch (in computing, this is 1 January 1970).</p>
<p>Unlike Web2 references to timestamps in milliseconds, the value may not increment with every millisecond.</p>
<p>A block often contains several transactions, and since <code>block.timestamp</code> refers to the time at which the block was mined, all transactions in a mined block will have the same timestamp value. So the timestamp really refers to the block’s time, and not so much as to when the caller may have initiated the transaction.</p>
<p>Solidity supports directly referring to the following units of time: seconds, minutes, hours, days, and weeks.</p>
<p>So we could do something like <code>uint lastWeek = block.timestamp - 1 weeks;</code> to calculate the timestamp of exactly 1 week before this current block was mined, down to milliseconds. That value would be the same as <code>block.timestamp - 7 days;</code>.</p>
<p>You can also use this to calculate future expiry dates, where, for example, you may want an operation to be possible between now and next week. You could do this with <code>uint registrationDeadline = block.timestamp + 1 weeks;</code> and then we could use the <code>registrationDeadline</code> as a validation or guard in a function as follows:</p>
<table><tbody><tr><td><p>function registerVoter(address voter) public view {<br>&nbsp; &nbsp; &nbsp; &nbsp; require(block.timestamp &lt;= registrationDeadline, “registration deadline has passed.”);<br>&nbsp; &nbsp; &nbsp; &nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; // Register the Voter....<br>&nbsp; &nbsp; }</p></td></tr></tbody></table>

<p>In this function we register the voter only if the current block’s timestamp is not past the registration deadline.</p>
<p>This logic is used extensively when we want to make sure certain operations are performed at the right time, or within an interval.</p>
<p>This is also one of the ways in which <a target="_blank" href="https://docs.chain.link/chainlink-automation/introduction/">Chainlink Automation</a>, a decentralized way to automate the execution of your smart contract, can be configured. The Chainlink decentralized oracle network can be configured to automatically trigger your smart contracts, and you can run a wide variety of automations by checking conditions, including time related conditions. These are used extensively for airdrops, promotions, special rewards, earn-outs and so on.</p>
<h2 id="heading-conclusion-and-further-resources">Conclusion and Further Resources</h2>
<p>Congrats! You made it through this epic journey. If you’ve invested the time digesting this handbook, and run some of the code in the Remix IDE, you are now trained in Solidity.</p>
<p>From here on, it’s a question of practice, repetition and experience. As you go about building your next awesome decentralized application, remember to revisit the basics and focus on security. Security is especially important in the Web3 space.</p>
<p>You can get good information on best practices from <a target="_blank" href="https://blog.openzeppelin.com/">OpenZeppelin’s blogs</a> and the <a target="_blank" href="https://www.trailofbits.com/resources">Trail of Bits</a> resources, amongst others.</p>
<p>You can also get more practical hands on experience by doing the full <a target="_blank" href="https://www.youtube.com/watch?v=gyMwXuJrbJQ&amp;t=59657s">end-to-end full-stack blockchain developer course</a> that my colleague Patrick Collins published on freeCodeCamp (it’s free!).</p>
<p>There are other resources like blockchain.education and freeCodeCamp’s own upcoming Web3 curriculum that can consolidate your learnings.</p>
<p>In any event, this handbook can be your “desktop companion” for that quick refresh on basic concepts, regardless of what level of experience you’re at.</p>
<p>The important thing to remember is that Web3 technology is always evolving. There is a crying need for developers willing to tackle complex challenges, learn new skills, and solve important problems that come with decentralized architecture.</p>
<p>That could (and should) be you! So just follow your curiosity and don’t be afraid to struggle along the way.</p>
<p>And once again, I intend to keep this handbook updated. So if you see anything that’s not quite right, is outdated, or unclear, just mention it in a tweet and <a target="_blank" href="https://twitter.com/zubinpratap">tag me</a> and freeCodeCamp - a big shout out to you all for being part of keeping this handbook fresh.</p>
<p>Now…go be awesome!</p>
<h3 id="heading-post-script"><strong>Post Script</strong></h3>
<p>If you are serious about a career change to code, you can learn more about my journey from lawyer to software engineer. Check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a> and also <a target="_blank" href="https://lessonsfromaquitter.com/episode207/">Episode 207</a> of "Lessons from a Quitter". These provide the blueprint for my career change.</p>
<p>If you are interested in changing your career and becoming a professional coder, please reach out <a target="_blank" href="http://linktree.com/zubinpratap">here</a>. You can also check out my <a target="_blank" href="http://futurecoderstraining.com/">free webinar</a> on <a target="_blank" href="http://futurecoderstraining.com/">Career Change to Code</a> if that is what you're dreaming of.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Coding Interview Prep for Big Tech (FAANG) – And How I Became A Google Engineer ]]>
                </title>
                <description>
                    <![CDATA[ When I changed careers from lawyer to software engineer at Google, I published 10 big ideas that helped me make that massive transition. Since then I’ve had a ton of questions from people asking me questions about: How I taught myself new skills Ho... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/coding-interview-prep-for-big-tech/</link>
                <guid isPermaLink="false">66d461c933b83c4378a51861</guid>
                
                    <category>
                        <![CDATA[ career advice ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career Change ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding interview ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Interview tips ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Wed, 13 Jul 2022 14:45:30 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/Google-Mel.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When I changed careers from lawyer to software engineer at Google, I published <a target="_blank" href="https://www.freecodecamp.org/news/from-lawyer-to-google-engineer/">10 big ideas that helped me</a> make that massive transition. Since then I’ve had a ton of questions from people asking me questions about:</p>
<ul>
<li><p>How I taught myself new skills</p>
</li>
<li><p>How did I know that learning to code at 37 was not “too late”</p>
</li>
<li><p>How I prepared for big tech coding interviews</p>
</li>
<li><p>How I analyzed and minimized the risk of career change</p>
</li>
<li><p>How I worked out that software engineering was “right” for me</p>
</li>
<li><p>What languages I focused on</p>
</li>
<li><p>Whether being a FANG/FAMGA software engineer is right for everybody (hint: tempting to think so but I saw plenty of evidence of it not being right for some people’s goals)</p>
</li>
</ul>
<p>Note: I think “FAANG/FAMGA” is limiting, and prefer to refer to “big tech”since there are many highly prestigious companies other than the usual 4-5 everyone obsesses about.</p>
<h2 id="heading-why-i-wrote-this-article">Why I Wrote This Article</h2>
<p>Each of those questions I listed above deserve their own article, even though I know our contemporary culture prefers “tweet-sized tips”. However, meaningful skills can’t be internalized from a few hundred characters.</p>
<p>So today I am going to share with you my answer to one of those questions – the approach I adopted when:</p>
<ol>
<li><p>I made that first jump in careers from lawyer to coder at 38, and</p>
</li>
<li><p>How I prepared for big tech interviews at the ripe ol’ age of 39, with less than 2 years of coding behind me.</p>
</li>
</ol>
<p>If you want me to write on any of the other questions I always get, please let me know! I’m going to put my contact details in this post somewhere, and the only way to find it will be to go through the article. 😊 That is also to encourage you to carefully read this article rather than skimming for a “quick tip”.</p>
<h2 id="heading-uncovering-the-real-goal">Uncovering the Real Goal</h2>
<p>I hold the following opinions: getting coding interviews is harder than learning to code. Doing well at the interviews is often just as hard as getting the interviews. Behavioral interviews are hard if you don’t have solid experience – but your competition does.</p>
<p>When I made the switch I had zero coding background. Later, when I set my sights on Big Tech, I knew I’d be competing with PhDs, people who’d been coding since their teens (often 20+ years), and folks who'd achieved a lot more technically than I had in my one brief year’s experience as a developer.</p>
<p>And I had the added challenge of applying for big tech from outside the United States.</p>
<p>So I had to develop a plan that went well beyond just “learning to code”.</p>
<p>First, let me explain why I concluded that “learning to code” is the easy part, even though I’d tried and failed to learn to code 4 times, between 2012 and 2018.</p>
<p>This insight came to me in late 2018, when my startup was struggling. I had lost tens of thousands of dollars building my startup. I had no income for over 2 years.</p>
<p>And I decided to pull out over $40K from my mortgage. Why? I got into a top-rated bootcamp in San Francisco.</p>
<p>I left my family behind, and relocated to the US. I was meant to be there for over 14 weeks, but I withdrew from this top-rated bootcamp in week 1, and returned to Australia.</p>
<p>I had been super excited about the adventure (and scared from all the debt). But I developed grave doubts about the bootcamp strategy. I noticed that my instructors and the program were designed to help people "learn to code" rather than "becoming a coder".</p>
<p>From my experience on the hiring side in 3 other industries and 4 countries, I knew this was a mistake.</p>
<p>Learning to code is just a form of “literacy”. And literacy is not skill.</p>
<p>I was living proof: each of the 4 times I focused on “learning to code” I succeeded in a narrow sense. Whether it was HTML or Java or writing a simple Android app from a book, I always succeeded at learning how to read and write the basics. But I had no idea how to actually build anything useful. I was completely hopeless at applying my knowledge – I had no real “skill”.</p>
<p>In this century we don't get hired for what we know. We get hired for skill.</p>
<p>I quickly saw several reasons why a coding bootcamp was the wrong strategy for me.</p>
<p>This expensive bootcamp would likely give me some basic skills, the kind that may even get me an “entry level” job. But I could see things were going to be rushed, standardized, and focused on "getting out the other end".</p>
<p>I didn't want to "tick a box". I wanted skill. Competence. Confidence.</p>
<p>Moreover, bootcamps seemed to prepare everyone for entry level "junior developer" jobs.</p>
<p>I was 37 and I didn’t want to settle for an “entry-level job” mindset. Plus I don't believe anyone with 3 + years of experience is "junior" even if they're a total newbie in the field.</p>
<p>Then I discovered that several instructors and teaching assistants at the bootcamp were former students who hadn’t yet found jobs. They had never changed careers – many had never had a "career" as such. The job-search counselors had never even been on the interviewing side in tech.</p>
<p>How was I going to learn to do something from people who’d never done what I needed to do?</p>
<p>And then there was geography. Students based in San Francisco had advantages, whereas people coming from other parts of the US did not find work that easily and ran out of money in the long months after graduating and before getting their first job. Heck, I was based in Australia...how was this going to work for me?</p>
<p>I looked at my explicit goal. It was not to "learn to code" – it was to build a career that fulfilled me.</p>
<p>Plus, when researching bootcamps, I could see a path to learning “part time”. That seemed like a much more sustainable strategy to me because I could find a job and learn at night and on weekends. After over 2 years of no income, I needed to have cashflow in order to keep fear at bay, and focus on becoming a professional coder.</p>
<p>As the legendary businessman Harvey Firestone said:</p>
<blockquote>
<p><em>“Having a surplus is the greatest aid to business judgment that I know.”</em></p>
</blockquote>
<p>Having income while studying would give me the confidence to make better judgments. Better judgments are important for a career that is fulfilling in the long term.</p>
<p>I had no doubt that I would "learn to code" if I did 3-4 months in the bootcamp.</p>
<p>But would I learn enough for a good team to pay me money for my skills? I no longer believed bootcamps and online coding websites would help me achieve that.</p>
<p>Learning to code would not get me far. I had to be good enough to beat my competitors who had coding degrees, prior experience and networks. I wanted a career in code.</p>
<p>So I left the bootcamp, wrote off about $9,000 and returned to Australia. Sure, I had gained rudimentary coding literacy to pass the entrance test for the bootcamp. But I was very far from competent.</p>
<p>This analysis may be hard to understand if you’re new to the workplace. Another way to truly understand it is to notice that many of us play music, but aren’t in a band. As my mentor said:</p>
<blockquote>
<p><em>"Michael Jordan didn’t want to learn to play basketball. He wanted to be in the NBA. Huge difference."</em></p>
</blockquote>
<h2 id="heading-how-to-use-your-advantages-amp-disadvantages">How to Use Your Advantages &amp; Disadvantages</h2>
<p>That one insight made all the difference. Within 8 months, in 2019, I got all 4 developer jobs I applied for. I simply followed the program I’d developed with the help of my (non-technical!) coach.</p>
<p>Don't be misled though. I had unexpected advantages. I benefited from 2 major advantages that initially appeared to be disadvantages.</p>
<p>This was not my first career change, and for almost a decade, I had been on the hiring side in previous careers. Today I’ve been on the hiring side in engineering too, and the patterns are very similar.</p>
<p>My biggest advantage was that I was no longer thinking about the job market challenge as a candidate. I was thinking about this from the perspective of the hiring manager. That had a significant impact on my plan because I had experience of how hiring managers think – their constraints, priorities, values, business needs, dislikes, red flags...</p>
<p>My experience (age?) helped me understand what impact I could deliver to a team and organization, and to identify the right people that I could learn from, who could help me with ideas, guidance, suggestions and referrals. What was a disadvantage was now an advantage – <a target="_blank" href="https://www.freecodecamp.org/news/why-career-changers-have-an-advantage/">a career changer's advantage</a>.</p>
<p>On the point of advantages, I want to call out something important.</p>
<p>The easiest thing in the world is to dismiss others for having “killer” advantages. It's easy to shrug and say "Of course – that’s why they succeeded". It’s easy to not notice that everyone has very compelling and serious disadvantages.</p>
<p>For me, my “disadvantages” were:</p>
<ul>
<li><p>Geography – I don’t live in the US or one of the other tech hubs</p>
</li>
<li><p>No formal computer science qualifications</p>
</li>
<li><p>Zero technical background</p>
</li>
<li><p>A mortgage and financial responsibilities</p>
</li>
<li><p>My “age” – learning new skills when you’re pushing 40 is harder than when you’re 25</p>
</li>
<li><p>Cultural and social expectations, judgment, negativity</p>
</li>
<li><p>Recruiters and bosses being younger than I was and uncertain of how to deal with me</p>
</li>
<li><p>Compared to other candidates, people viewed my change as very, very “risky”</p>
</li>
<li><p>I was going to earn less in engineering than I would as a lawyer</p>
</li>
</ul>
<p>Every day I hear from people who let any one of these things stop them. While I cannot comment on whether or not they’re real reasons, I <em>can</em> say that if we argue for our limitations, we get to keep them.</p>
<p>Clinging on to our disadvantages does not help us overcome them.</p>
<p>With the help of my coach and a ton of mindset/psychology training, I was able to dig into my disadvantages and convert a few of them (not many!) into major advantages. And that’s when I realized that my experience with how interviewing, recruitment, and resourcing works would help me a lot in formulating a strategy.</p>
<h3 id="heading-priority-one-career-change">Priority one: career change</h3>
<p>When learning to code and intentionally setting the goal of becoming a professional coder, I found that I kept switching to short-term thinking and obsessing about my first role.</p>
<p>I wanted my first role to be glorious, to prove all my critics wrong, to pay me a gazillion dollars and save me from having to deal with self doubt and struggle for the rest of my life.</p>
<p>But I had to train myself to view things differently. My first role must be one that makes me learn and grow, and set me up for future success no matter what happened. It needed to pay fair market rates, but I was happy to take a slightly lower salary if the team was fantastic and the growth/learning was solid. It did <em>not</em> need to be my dream job.</p>
<p>I was very explicit in the tradeoffs I’d make:</p>
<ul>
<li><p>Team matters more than brand</p>
</li>
<li><p>Team matters more than money</p>
</li>
<li><p>Brand matters more than money (as it would set me up for future opportunities)</p>
</li>
<li><p>Money matters more than stock (this was for my first dev role, as this would make my continued learning plan sustainable, even though stock may give me more financial upside)</p>
</li>
<li><p>But, learning mattered more than brand or money – as learning more would save me time which is better than saving me money</p>
</li>
<li><p>I would not trade off between team and learning. I needed both (but I was more likely to get reliable signals on the team than I would on the actual learning/growth I’d get on the job)</p>
</li>
</ul>
<p>“Nailing it” or being comfortable was not a priority. My priority was to successfully change careers.</p>
<p>Accepting a rubbish coding job (and there are plenty of them…) would not be a “successful” career change for me. But equally I didn’t have to get into big tech (ever) for my career change to be “successful”. This was very personal – success to me meant loving the work I do and learning a lot doing it. Period.</p>
<h3 id="heading-how-i-made-a-customized-plan">How I Made a Customized Plan</h3>
<p>After analyzing my advantages and "convertible" disadvantages, the next thing I needed to develop was a customized plan. I needed one that was tailored to me, that I could believe in.</p>
<p>I needed a plan that took into account my specific context, which includes my temperament, experience, beliefs, values, goals and skills.</p>
<p>Note that I’ve still not talked about the technical interviews, the algorithms and data structures, and so on. When developing my plan, I had to focus on all the many pieces that had nothing to do with my coding skills or technical capability.</p>
<p>It would also need to account for my psychological “runway” – how much time was I prepared to invest in this career change, before I’d give up, lose hope, or change my mind? I could not answer that without understanding how long it was going to take me to learn the minimum required skills.</p>
<p>To understand that, I needed to research and analyze what the minimum set of engineering skills that the market would value were.</p>
<p>And to understand that, I needed to analyze the dozens of engineering domains in the market, and which ones would suit my temperament, interest/passion and advantages. And from that analysis I’d need to pick the domains that I would focus on and exclude all others.</p>
<p>I'd have to find the overlap between my interests, my ability and what the market valued.</p>
<p>Again, my experience on the hiring side of the market gave me some (small but important) advantages. I knew that pure technical skill would not be enough – that’s just the starting point. the “invitation to the dance”.</p>
<p>I also knew that good teams don’t just hire for raw technical skill, they hire for essential non-technical attributes as well. What those traits are depend on the technical domain, the team culture, the current composition of the team, and so on.</p>
<p>Yes, you're right. A custom plan is extremely multi-dimensional, and getting things right is only moderately helpful, whereas getting things wrong can result in a giant loss of direction and waste of time.</p>
<p>Since I was almost halfway through my career, I was determined not to repeat past mistakes. I was going to be:</p>
<ul>
<li><p>Highly specific in my goals.</p>
</li>
<li><p>Highly intentional in my choices and actions.</p>
</li>
<li><p>Focused on what I wanted, paying no attention to the things I did not want.</p>
</li>
<li><p>Willing to change myself, my habits and negative beliefs, so that I could change the world around me.</p>
</li>
<li><p>Ready to focus on building a rewarding and fulfilling career rather than just “getting the next job”.</p>
</li>
<li><p>Ready to focus on delivering value for my future team rather than a “what’s in it for me” mindset.</p>
</li>
<li><p>Willing to play the long game – think in 5-10-25 year horizons rather than the next few weeks.</p>
</li>
</ul>
<p>I must confess, doing these things consistently was much harder than I anticipated. I slipped up a lot, especially on the first three. But since I had my custom plan written down, I let that be my guide and the sole source of truth for what I needed to do.</p>
<p>My plan required me to focus on fundamental programming skills, and then narrow it down to the segment that I felt matched my long-term goals and skills. For me, this was web development. This meant completely and ruthlessly avoiding all the “shiny new things” and doing things like Python or Java.</p>
<p>And tutorials and endless videos were not going to make me beat the competition. I calculated that the minimum set of skills I’d need to develop for my city would require 900-1100 hours of focused coding, practicing the right things in the right sequence.</p>
<p>Preparing the plan took several weeks. I kept refining and strengthening it and didn’t rush it artificially. I am very inspired by Abraham Lincoln (another lawyer who changed careers!) and he once said “Give me six hours to chop down a tree and I will spend the first four sharpening the axe”.</p>
<p>I was so tempted to dive right into my plan and get “busy” but I’d learned that being busy was so not the same as being effective. Once the plan felt as complete as it could be with the information I had at my disposal, I turned to executing on that plan, with total focus.</p>
<p>This meant a lot of sacrifice, and many, many days of self doubt, battling the temptation to switch, and learning to manage my energy. I developed some amazing habits during this time, but they were only obvious to me in hindsight. During those 6 months of work, I was constantly assailed by uncertainty, fear and occasional loss of hope.</p>
<p>Later on, I adapted this planning process to create a plan for Big Tech and especially for Google. That plan took another 500-600 hours of intentional study that was completely different from my plan to become a developer. More on that later.</p>
<h2 id="heading-early-results-and-thengoogle-swe">Early Results, and then…Google SWE</h2>
<p>Another lesson I’d learned from 4 years of trial, error, and failure was that I was very likely to change plans midway, switch resources, courses or focus.</p>
<p>This is a much more serious problem than we realize because every time we switch focus or plans we throw out the hard work we’ve done, go back to square 1 and…start…all…over…again.</p>
<p>Imagine if you were driving from A to B and kept taking U-turns and going back and restarting. You’d never get anywhere.</p>
<p>But I’d made myself a promise (it’s easier to keep a single promise than to keep a bunch of them!): I was going to complete my plan and then decide whether I would keep going. This time I wasn’t going to stop until I completed my plan.</p>
<p>I didn’t have to like doing it. I just had to like the possibilities that lay at the end of doing it.</p>
<p>My plan had a specific time when I would start interviewing even if I didn’t feel ready for interviews. But to get to that stage I had to get good at generating interview opportunities.</p>
<p>Again, my past experience in other careers helped me. I applied all my learnings over 18 years and secured 4 interviews within a few weeks, and got all 4 offers even though there were plenty of candidates with more experience, skill, and qualifications than I had.</p>
<p>It wasn’t because I was better at coding. I don’t see how that could be, given that I’d only been in the game for a few months.</p>
<p>I believe I got all 4 offers because <em>during the interview process</em> I demonstrated that I was a better candidate <em>for the hiring manager</em>. This approach was critical in how I presented myself.</p>
<p>Getting the offers is great, but I had an unexpected problem. Since my plan required me to be highly intentional about the kind of work I’d pursue, all 4 roles I’d applied for were the ones I really believed would be a fantastic start to my new career. How was I going to choose?</p>
<p>Yes it’s a great problem to have, but that doesn’t make the decision easy!</p>
<p>To resolve this problem intelligently, I learned to ask myself a very important question:</p>
<blockquote>
<p><em>Do I</em> <strong><em>know</em></strong> <em>this or do I simply</em> <strong><em>think</em></strong> <em>this?</em></p>
</blockquote>
<p>Very often we make decisions based on assumptions and beliefs that are completely untested, and we mistake our opinions or fantasies for reality. What we actually know is way less than what we believe without truly knowing.</p>
<p>Being intentional required me to focus on what I know rather than what I wished, or merely thought. I had to either find evidence to back my thoughts, or disregard thoughts for what I knew.</p>
<p>That framework developed my analytical powers and helped me choose the right first role in early 2019. I turned 39 around that time.</p>
<p>Till today I continue to use this <em>know vs think</em> framework in my personal decision making as well as in my engineering decision making. I find it to be an excellent framework for analyzing tradeoffs in complex decisions.</p>
<p>Looking back, I learned a TON about sticking to my plan, revisiting my goals, self-awareness and practicing being <em>intentional</em>.</p>
<p>A few months into my new role, I noticed that a lot of lawyers were starting to reach out and ask me how I did this. Curiously, many of them were people who insisted I was making a huge mistake and that wanting to learn to code at this stage was immature and foolhardy.</p>
<p>Now they wanted to “learn to code”. And that made me think.</p>
<p>What else have others said is “not possible”? <em>Do they</em> <strong><em>know</em></strong> <em>that or do they just</em> <strong><em>think</em></strong> <em>that</em>?</p>
<p>And my goals hadn’t changed. For me learning, growth, and team were still more important than brand or money. But I was almost 40 and I also wanted to explore life in a way that I’d never had the courage to do in the first half of my career.</p>
<p>So I decided to set myself a stretch goal: I was going to find out what being a software engineer at Big Tech was like. I’d worked in huge companies before and I knew that it isn’t for everyone – that’s the reason I went into startup and smaller companies in the first place.</p>
<p>But wouldn’t I learn and grow SO much by being surrounded by some of the “best” people in their field, from engineering to product and sales? Did I know this? Or did I just think it?</p>
<p>I did the research and found that on average people were happy in Big Tech. But I also found that most people were not as intentional as I was. So I confined my research to people who were very intentional about their careers. And they (almost universally) said they grew a lot from Big Tech, even if they decided to leave. Leaving Big Tech was also intentional, in pursuit of their end goals.</p>
<p>So I decided to try for big tech (including 3 of the FAMGA companies) and several others, in Silicon Valley, New York, and Seattle. I was still based in Australia, so this was a massive challenge.</p>
<p>I re-designed my plan. Several of the steps were the same but the coding curriculum would have to be massively overhauled. I also needed to find out how US big tech recruitment is done, and be worthy of a referral.</p>
<p>About 7 months later, I started generating interviews. I worked very hard to prove myself worthy of referrals for those 7 months, and people offered to give me referrals based on my efforts and proven commitment.</p>
<p>I got referred to Meta (it was called Facebook then) but I didn't get the interview as my skills were not the right match. This was a massive learning for me as I thought I’d been careful to only apply for roles where my skills matched – and I was wrong.</p>
<p>That was when I realized that sometimes the position description is written in ways that mean one thing for the hiring company but means very different things <em>outside that company</em>. This is because different organizations use the same words to mean different things. Both the hiring side and the candidate side can be unaware of this!</p>
<p>All these learnings added up. Within 3 months I got offers from 2 big tech companies, and missed out on a third at the final interview because I just didn’t know how to write a filesystem from scratch (I didn’t understand much about the Linux world at all!).</p>
<p>And then I got an offer from Google.</p>
<p>Again, I was faced with a very difficult decision. Google is a cultural force that is very hard to be objective about. But I really wanted to stay true to my goals, my plan, and my intentions.</p>
<p>Trying to separate what I knew from what I thought was EXTREMELY hard when it came to Google. But I was absolutely sure about one thing: the team I’d interviewed with were amazing people.</p>
<p>And this is where I believe luck matters. No matter what people say about skills, brains, smarts and all that stuff, luck and "magic" have a role in life.</p>
<p>My interviewers from Google were friendly, kind, cheerful and highly focused engineers. They were not looking to prove I sucked. They wanted to help me prove I was good. They answered my questions with enthusiasm, and I felt like collaborators from the first minute.</p>
<p>Is this a Google thing? Maybe. But later, when training to be a technical interviewer at Google, I witnessed a very wide variety of interviewer/hiring manager styles and beliefs. I saw candidates with great skill losing their nerve, struggle to communicate their process, and so on. And I came to appreciate the role of chance in all this.</p>
<p>So yes – I was lucky that I had the kind of interviewers I did, and that on interview day I happened to know how to work through the code.</p>
<p>This is also where my ultra-focused preparation on <em>type of work</em> and <em>relevant</em> skills paid off. There are a very large number of engineering roles at Big Tech that I would never have been suited to (like the one at Meta). Even with my prior experience in other careers, I had no idea how HUGE the engineering world is, and how many flavors and types there are, and how hard it is to tell them apart.</p>
<p>By forcing myself to be highly intentional and not randomly and blindly applying for big tech engineering roles, I improved my chances in small but important ways. I dug deep into each role and researched them carefully by speaking to friends in the industry (again – my age and experience was an asset because I had built relationships over 15+ years never expecting that they’d be so useful later on!).</p>
<p>For each offer I got, I had researched the role deeply, and prepared for the technical interviews well. On interview day the stars were aligned, and things worked out. Though I don’t think I “nailed” my interviews, I did well enough to communicate that I was a suitable candidate <em>for the team’s needs</em>.</p>
<p>Which leads me to the question: How did I prepare for the Big Tech interviews?</p>
<h2 id="heading-how-to-prepare-for-big-tech-interviews">How to Prepare for Big Tech Interviews</h2>
<p>Answer: In two phases that took me over 500 hours to execute.</p>
<h3 id="heading-phase-1-learn-the-realities-and-competitive-landscape">Phase 1: Learn the Realities and Competitive Landscape</h3>
<p>If I wanted to tackle Big Tech, from another country, with less than a year of industry experience, and 15+ years in an unrelated career, with no Computer Science degree, I needed to have a very clear view of the realities, especially the competitive landscape.</p>
<p>This means there was room for informed hope, but no room for dreamy-eyed, pie-in-the-sky magical and wishful thinking.</p>
<p>Hard truths (see my <a target="_blank" href="https://www.youtube.com/playlist?list=PLAPuklwJx5V3XZS19AlJQayZFpiZyDT9C">initial YouTube Videos on this here</a>). Hard realities. Hard work.</p>
<p>I had to fully internalize and appreciate the following:</p>
<ul>
<li><p>Coding is just the starting point. Not the ending point. Learning to code was the first step of many, one small piece of a much larger puzzle. In other words, it is necessary, <em>but not sufficient</em> to get a coding job (and especially at big tech).</p>
</li>
<li><p>My biggest enemy would be my own mind. It would either let the negativity of others get me down, or it would turn against me and undermine my own confidence. I had to build the habits that would help me have a resilient mindset. I focused on recovering from setbacks rather than avoiding them.</p>
</li>
<li><p>My competitors would likely not be career changers. Or if they were, they’d be from closely <a target="_blank" href="https://www.linkedin.com/posts/zubinpratap_software-engineering-computer-engineering-activity-6946411823759810560-VvA-?utm_source=linkedin_share&amp;utm_medium=member_desktop_web">related fields like computer engineering, mechanical engineering, or electronics engineering</a>. The vast majority would have technical qualifications, maybe even PhDs (this turned out to be true!), and several years of industry experience.</p>
</li>
<li><p>As an outlier and a “wildcard”, the hardest part would be getting the interviews. Learning algorithms and data structures would be easier. And “cracking the coding interview” (whatever that means…) would be easier too. Why? Code is deterministic – identical code generally produces identical results. But life is not deterministic, and getting interviews is highly subjective. In the job market, identical actions do not produce identical results.</p>
</li>
<li><p>I needed to shape myself into the <em>kind of person</em> seasoned engineers would want to work with</p>
</li>
<li><p>I assumed most of my competitors would have at least 3 -5 years of experience. I couldn't catch up with them, let alone <em>overtake</em> them. Instead, I needed to outperform them on non-technical skills and compare favorably (if not outperform them) on the technical stuff.</p>
</li>
<li><p>I had to communicate better than the others. If I didn’t know something, I’d need to say so and then communicate how I’d solve it if given the right time and opportunity. I also had to communicate to show interviewers that I understood <em>their business needs</em> and wasn’t just focusing on my selfish dreams.</p>
</li>
<li><p>Which means I had to really work on understanding what the hiring team valued, was looking for, wanted, and needed.</p>
</li>
<li><p>I could not control my competitors (their skill, their performance, how much they knew, and so on), or what my interviewer was thinking, wanting, what they valued, or whether they liked career changers or not. I could not control <em>most</em> things. I could only optimize my effort, my focus, my psychology, and how much learning I extract out of each experience, good or bad. I could only control my choices and actions. So focusing on anything outside that would be a waste of precious energy.</p>
</li>
<li><p>I had to accept the role of luck. Jordan, Tendulkar, Federer – they’ve all had bad days. I would too. Or maybe I'd do great, but on the day someone else would do better. Or someone else would just be a better fit for what the team needed. No harm, no foul. I’ve made those hard decisions on the interviewing side countless times myself, so I know how these things work.</p>
</li>
<li><p>If I was successful at more than 1 offer I would need to <em>pre</em>-think and <em>pre</em>-agree with myself about what signals and factors I would use to decide (I’d learned from my experience of choosing between my first 4 offers!).<br>  If you’re wondering how I knew how to do all this…I didn’t. Not all at once. What you’re reading is a summary in hindsight. But I had to work most of this out in “real time” based on “<a target="_blank" href="https://fs.blog/first-principles/">first principles thinking</a>”. And I worked with my mentor to tighten them up as I went along. It took a lot of time and I was so impatient to “start coding”. But …I knew what advice Abraham Lincoln would give me…</p>
</li>
</ul>
<h3 id="heading-phase-2-how-i-chose-my-learning-resources">Phase 2: How I Chose My Learning Resources</h3>
<p>I know everyone thinks there is a secret “magic bullet” out there. Some blog, video, resource, tutorial, podcast, PDF cheatsheet…_something…_that will unlock the entire “secret” and make us instantly learn things.</p>
<p>Nope.</p>
<p>I’ll bang on about this till the day I die – information is a commodity.</p>
<blockquote>
<p>Learning is hard, but it’s made much harder because there is <em>too much free information</em>.</p>
</blockquote>
<p>We all fall into the trap of thinking there is some missing piece of information. There isn’t.</p>
<p>Why? Because no matter where you live, what language you speak, what color your eyes, skin, or hair are, what gender you identify with – all resources are going to teach you things that “work”. They’re all “the same” at a very fundamental level.</p>
<p>They <em>have</em> to be, because that’s how computers work.</p>
<p>If you and I write an identical function in JavaScript or Python or Java, we are going to get identical results. That’s how computers work – they’re <a target="_blank" href="https://en.wikipedia.org/wiki/Deterministic_algorithm">deterministic</a> <a target="_blank" href="https://en.wikipedia.org/wiki/Deterministic_algorithm">algorithms</a>.</p>
<p>But life (and interviewing) is most decidedly <strong>not</strong> deterministic. Identical effort, grades, skill, intelligence will not produce identical results.</p>
<p>Again, I had to <em>teach myself to</em> <em>learn</em>. I had to teach myself to shift my attention away from resources/blogs/websites/courses and put my attention on building solid mental models, identifying relevant skills, drilling down on concepts rather than code implementations, applying what I already knew in new ways, reasoning, problem solving, and communicating my reasoning <em>while</em> I reasoned.</p>
<p>Now you’re going to be surprised by the resources I used for my Google and other Big Tech interviews.</p>
<p>Yes, I used <a target="_blank" href="http://leetcode.com">Leetcode</a>, <a target="_blank" href="http://algoepxert.io">Algoexpert</a>, <a target="_blank" href="http://interviewcake.com">InterviewCake</a> and <a target="_blank" href="https://www.youtube.com/c/JennyslecturesCSITNETJRF">Jenny’s CS Lectures</a> and perhaps a few others. But I didn’t complete a single one of them.</p>
<p>This wasn’t because I switched or lost focus. I was being intentional. I realized that they all teach the same thing, but with slightly different styles and content. So I used these resources to learn concepts and mixed and matched all these resources based on my analyses of interview <em>patterns</em>.</p>
<p>My reasoning was simple. Having been on the hiring side, I know that every year the quality of candidates (at good companies) improves. I personally think that focusing on the company is a huge mistake – we should focus on the team, people and <em>kind</em> of work.</p>
<p>But the world works a certain way, and because of that, everyone rushes to the big companies. This increases competition which makes it harder for hiring managers to assess candidates.</p>
<p>The only way for hiring managers to deal with this is to raise the bar, making it harder for candidates. The overall number of candidates keeps increasing, but the “pool” of candidates that get invited to the interview stays within a narrow range – usually 2 -10 people. Regardless of how many hundreds apply that’s about the number that will even get a chance to interview.</p>
<p>Therefore, the number of candidates that don’t hear back or meet with rejection increases, especially in bull markets.</p>
<p>If the competition is increasing and the resources on the internet are also increasing, but the shortlisted number stays more or less constant, then “learning more” cannot be the solution. Everyone is “learning more”, so relative to the competition there is no change.</p>
<p>I also realized that Big Tech would have lists of interview questions (this is “efficient” as interviewing is <em>very</em> time consuming, and so it makes sense to save time by having a question bank that interviewers could use). Naturally, they would not use these questions if they were “leaked” – that would defeat the interview process.</p>
<p>So, logically, hiring managers will not ask questions that are available on Leetcode or Algoexpert or other sites. This produces a kind of “arms race” – the more questions are made publicly available, the more questions in the question bank are changed. That results in more innovation and variance in questions and hiring strategies.</p>
<p>This left me only one choice. I had to learn to solve problems using mental models and by classifying them. Chances are I was never going to be asked to sort a Linked List or to implement Dijkstra’s shortest path algorithm. Instead, I would need to know how to apply these sorts of algorithms to “real world”, practical problems.</p>
<p>Often real world problems don’t look, sound, or smell like the practice questions we study. Practice questions and competitive coding questions tend to be “neatly” packaged up with clear constraints.</p>
<p>But as an interviewer, I wanted to know how the candidate thinks, reasons, analyses, interprets information, and collaborates. Solving the problem is a bonus. Often they have the right solution but run out of time – but ask great questions and clearly know how to tackle the problem. These candidates can still get the offer.</p>
<p>Later, as an engineer at Google, I could always tell if someone <em>knew</em> how to solve something even if they were unable to solve it in time. Equally, it’s immediately obvious when a candidate does not know how to solve something (and that's OK – we are all learning).</p>
<p>By adopting my approach of understanding problem types and solutions rather than specific code implementation, I could focus on learning to reason rather than learning to write specific algorithms.</p>
<p>This approach meant that I completed less than 40% of Algoexpert (and back then it had half the questions it has now). I also did maybe 50-60 questions from Leetcode and most of them weren’t the “hard” ones.</p>
<p>I figured that “hard” questions would probably show up in 45 minute interviews about 20% of the time which means 80% of the time they’d be easy or medium questions. So it made sense to optimize for the 80% given I was still relatively new to engineering and the hard problems would get in the way of understanding easy and medium ones.</p>
<p>I used these resources to recognise patterns rather than just “complete” and get a certification. That’s why I didn’t complete any of them. And no, I didn’t use “<a target="_blank" href="https://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/0984782850">Cracking the coding interview</a>” either.</p>
<p>Along the way I also started a systematic process of understanding system design questions. I documented system design preparation in a <a target="_blank" href="https://www.freecodecamp.org/news/systems-design-for-interviews/">long form blog on the essential concepts for system design interview questions</a>.</p>
<p>I also decided to focus on one language: JavaScript. It wasn’t the best for interviewing (seasoned engineers discourage it on Quora and elsewhere) but I didn’t see how it mattered. The purpose of the interview was not to test my choice of languages – it was to test my ability to think abstractly and solve complex computer science-y problems.</p>
<p>The language is just a tool (another core belief I hold). In fact, using an untyped language like JS would give me opportunities to talk about its limitations or strengths, which is an opportunity to demonstrate that I understand the tradeoffs in language choices. That way, I could showcase broader knowledge and insight without actually having to implement it all in code.</p>
<p>But a lot of the resources I learned from used Java or C++. These languages are the dominant languages at Google. So being forced to read these languages and understand the principles forced me to not focus too much on “spitting out the code” and more on reasoning through the code so that I could write it.</p>
<p>That was my entire plan. Practice, Pattern Recognition, Mental Models/First Principle Thinking, System Design, doing fewer things really well, and focusing on getting interviews rather than just learning more code.</p>
<h3 id="heading-how-to-stand-out-during-interviews">How to Stand Out During Interviews</h3>
<p>As I mentioned, we all have advantages and disadvantages. And we all think our disadvantages are special and huge and our advantages are common, unremarkable, and probably not of much use.</p>
<p>This is not true. Logically, if we all think our disadvantages are severe, then we should all succumb to them. Yet some people overcome them. Only to find that others had it even worse and overcame <em>those</em>.</p>
<p>It’s way better to focus on what we can do well. For me, I truly believed that I could add a lot of value to the team. I don’t care about being the smartest or the best. But I care about being an outstanding learner, and maintaining my <a target="_blank" href="https://www.youtube.com/watch?v=hiiEeMN7vbQ">growth mindset</a> at all costs.</p>
<p>And so I tried to use this to stand out as best I could. I learned to ask really good questions of recruiters, interviewers, and hiring managers.</p>
<p>But there was a deeper reason for this. Asking good questions was my way of interviewing the company. Like I said, I didn’t want to repeat the mistakes of the first half of my career. So asking really good questions was important for me to assess whether the company was a fit <em>for me</em> and not just the other way around.</p>
<p>Since I had decided that I was going to value the team and the learning over all else, I never asked about the compensation until the recruiter raised it. It was going to be lower than what I earned as a lawyer anyway!</p>
<p>Instead I focused very hard on learning about the team, its dynamics, its group beliefs and values, how the manager solved problems (especially people problems), what the team was interested in, what the company division was interested in, how its balance sheet was doing, what its strategy was, what its resource allocation and budgeting looked like, and so on.</p>
<p>All these things were things I'd learned in other industries, as an individual contributor, as a manager, executive, founder and so on.</p>
<p>And all of these things also showed that I was being highly intentional. I was genuinely interested in the team, and the company, its product and its future. This wasn’t just another job I was applying for. This was active and personal…not passive and opportunistic.</p>
<p>And I believe that helped me stand out. Maybe not for all the roles I interviewed for, but for many of the offers I got.</p>
<p>When I was on the hiring side, I’d always prefer candidates who were genuinely interested in the role, the people, the product and the company. Those that showed up just “to get a job” didn’t have the kind of energy and drive we wanted.</p>
<h3 id="heading-interview-planning-and-strategy">Interview Planning and Strategy</h3>
<p>The last aspect of my roadmap required me to deeply understand the different types of coding interview processes.</p>
<p>This included technical and non-technical interviews, the format of interviews, the way companies organize them, run them, plan them, staff them, evaluate them, and weigh them. But it also required me to understand my strengths and weaknesses.</p>
<p>When going for Big Tech in the US I was aiming for 2-3 interviews per month – a huge goal given that I was not even in the US and was in a timezone that was 17 hours ahead of the west coast.</p>
<p>I had to plan and structure interviews at weird hours so I could accommodate my day job as a developer and also my study time. Some interviews took 6 hours, some took 10 or more. Some were “pair programming for a day” type interviews.</p>
<p>All this took a ton of planning, and mental training. I had to be careful to get the right sleep, the right exercise, maintain my mindset and confidence, deliver on my day job, be there for my family, study and maintain focus on my goals.</p>
<p>For this, I had to be honest with myself at what I was good at. For example, I am not a morning person. But I can endure late nights. So I structured interviews, work, sleep, or even exercise accordingly.</p>
<p>There were some interviews that were scheduled at 2am or after, and I wouldn’t sleep before (as I really am not good at waking up on time!). So I’d do a full workout at 1am to get my energy and focus up, then interview, then sleep till 10 am, then go to work and manage my schedule accordingly.</p>
<p>I would also be careful to plan interviews so that I wasn’t doing two of them back to back unless they were very similar and time bound. For example, doing a take-home test and doing a timed test in the same week require different planning from doing a take-home and a live-coding interview – all while managing work and family.</p>
<p>To schedule the interviews appropriately I’d work closely with the recruiter and be very transparent with them. This had two advantages: I gained credibility and trust with the recruiter for being collaborative and communicative, and they also got to see that I had other opportunities going, which increased the value of my candidacy. Competition is a good thing.</p>
<h2 id="heading-concluding-thoughts">Concluding Thoughts</h2>
<p>I am sure many of you were expecting this article to give “insider” tips and a specific set of languages, and DSA questions to learn. I believe I’ve given you something much better. Rather than giving you fish, I am showing you how to fish.</p>
<p>Apart from the ethics of it, insider tips are of limited value, especially in Big Tech. In huge companies things can be vastly different from team to team and city to city. You need to understand the principles of recruitment and career development, rather than just the specific languages and algorithms. Assuming that all interviews are the same is a big mistake.</p>
<p>And as for our obsession with data structures and algorithms…managing your career is the ultimate algorithm. Your mind is the ultimate data structure. Learn how to work with both and you’ll always do well, despite the occasional failures. <a target="_blank" href="https://twitter.com/ZubinPratap/status/1534341043344252929">Powerful ideas aren’t grandiose – they’re elegantly minimal</a>.</p>
<p>If you have read this article you will have noticed some of the things I linked to include multiple ways to reach me. You can also get invited to my <a target="_blank" href="https://futurecoderstraining.com">webinars, mini-courses and newsletters</a> if you want to go beyond just “learning to code” and learn how to build a career that is <em>right for you</em>.</p>
<p>Perhaps the most important message I can leave you with is that it is a mistake to obsess about big tech. Yes, they’re great to be part of, but if we believe they’re the only thing that is right for us we will miss out on all the other amazing opportunities.</p>
<p>Big Tech has glamor because of cultural trends these days. Sure, it’s nice to work for a great organization, but plenty of great organizations are not well known. Plus what is “great” for one person is pain for another.</p>
<p>Your number one priority is to be happy, fulfilled, and live the life that you want. This is not derived from a company. This comes from the people you spend time with (especially colleagues) and the kind of work you do. Big Tech companies have their share of bad managers, teammates, and work, just like any other company.</p>
<p>If you build skill, stack a great plan on top of the right mindset, and train yourself to set the right goals, you can achieve much more than you dreamed of – with or without Big Tech.</p>
<h3 id="heading-post-script">Post Script</h3>
<p>If you would like to learn more about my journey from lawyer to software engineer, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a> and also <a target="_blank" href="https://lessonsfromaquitter.com/episode207/">Episode 207</a> of "Lessons from a Quitter". These provide the blueprint for my career change.</p>
<p>If you are interested in teaching yourself to code, changing careers and becoming a professional coder, or <a target="_blank" href="https://www.freecodecamp.org/news/non-technical-and-looking-for-a-technical-co-founder-2c212c01d6da/">becoming your own technical co-founder</a>, please reach out <a target="_blank" href="http://linktree.com/zubinpratap">here</a>. You can also check out my free webinar on <a target="_blank" href="http://futurecoderstraining.com/">Career Change to Code</a> if that is what you're dreaming of.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ From Lawyer to Engineer at Google – How to Switch Careers and Learn New Skills ]]>
                </title>
                <description>
                    <![CDATA[ I was a corporate lawyer for 12 years. I never thought I'd be working at Google as a software engineer, but that's what I have been doing for the past year. I'm working remotely until COVID subsides and we can move to San Francisco. In this article I... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/from-lawyer-to-google-engineer/</link>
                <guid isPermaLink="false">66d461cb57503cc72873deec</guid>
                
                    <category>
                        <![CDATA[ career advice ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career Change ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career development  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Job Change ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Thu, 13 May 2021 16:25:03 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/05/from-lawyer-to-engineer-at-google.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I was a corporate lawyer for 12 years. I never thought I'd be working at Google as a software engineer, but that's what I have been doing for the past year. I'm working remotely until COVID subsides and we can move to San Francisco.</p>
<p>In this article I'm going to share with you ten important lessons I learned during this career transition.</p>
<p>I finished law school in Bangalore, India, a year before Google listed on the Nasdaq. That was a long time ago. The world was very different. I think Facebook was still “thefacebook”.</p>
<p>I started my career as a litigator in the courts in India. Two years later I switched to corporate law, and then ended up moving to Australia to join one of the world’s largest law firms, in their Melbourne office.</p>
<p>Several years later, after surviving the Global Financial Crisis of 2008, I became an Australian citizen and moved “in-house” – the term for when lawyers move from working at a law firm to working internally at one specific company.</p>
<p>I loved being a lawyer, because it was filled with smart, ambitious people and it paid well. But there was always a part of me that longed to code, to create, and to contribute to the internet’s repository of useful tools.</p>
<p>To me, programming a computer is such a magical act. To write text, and have machines follow your commands – there is something so powerful, so <em>limitless</em> about that. It fired my imagination.</p>
<p>But I really did not view myself as “mathematical” or “nerdy” or a “brainiac”. Every bit of social messaging around hackers, coders, programmers, and technical founders (which by 2012 was a status symbol!) reinforced the myth that programming was the domain of “wickedly smart” math wizards.</p>
<p>I unwittingly reinforced that myth to myself – I tried to teach myself to code THREE times. In 2014, in 2015 and in 2017. And all three times I quit because I tried to jump too high, set myself up for failure, and then assumed I was not smart enough (when actually, I had just tried to run before I’d learned to walk).</p>
<p>Programming felt beyond my reach. Just. Too. Hard. I had no clarity on where to begin, what bits to learn, and most frustratingly, what bits to ignore.</p>
<p>Instead, I started a tech company and hired a team of coders. One of them became my technical co-founder. He quit a year into it, and I was left with partnerships and contracts with local governments that I had to honour.</p>
<p>Faced with the choice of being defeated or learning to code, I chose to try again – to learn to code.</p>
<p>I was 37. In 2020 COVID hit, and just as it was getting very serious, I signed my contract to be an an engineer at Google. I had just turned 39.</p>
<p>It felt odd to be “starting” over. But it also feels incredibly fun to be a beginner again. In fact, I can actually truly relate to what Steve Jobs said at his famous <a target="_blank" href="https://www.youtube.com/watch?v=UF8uR6Z6KLc">2005 Stanford Commencement Address</a>:</p>
<blockquote>
<p><em>“The heaviness of being successful was replaced by the lightness of being a beginner again, less sure about everything. It freed me to enter into one of the most creative periods of my life.”</em></p>
</blockquote>
<p>I had left a successful legal career and then a less than successful startup journey to be a beginner again. As a coder and coach, I am being more creative than I’ve ever had the privilege of being.</p>
<p>This is not about Google or any other fabled tech company. This is about <em>you</em>. It doesn’t matter what your goal is. I want you to know that transformations are not “special” or “miraculous” – they just <em>feel</em> that way.</p>
<p>The people I coach have gained an understanding of how I “found” my roadmap to becoming a coder, in a world where there is way too much information and consequently way too little clarity. But there isn’t enough time here to go into that.</p>
<p>Today I want to help you by whittling down my 10 most important principles for people wanting to transform their lives and achieve their goals.</p>
<p>You’ll see that this is true of coding, or anything else. But since I am now a self-taught engineer, working at Google, it is particularly relevant to others who are coders or aspiring coders.</p>
<p>At the end of this piece, I’ve put down some ways to reach out to me if you have any questions.</p>
<h2 id="heading-5-things-not-to-do-when-changing-careers">5 Things NOT to Do When Changing Careers</h2>
<p>I am starting with the “don’ts” because it’s easier to identify things we do that hold us back, than to develop new habits. Tackling the don’ts first will give you quick wins that will build your confidence – and from there you can build up to the “Dos”.</p>
<h3 id="heading-dont-look-at-the-mountain-top">DON'T Look at the Mountain Top</h3>
<p>For a long time, you’re going to be climbing a steep mountain. It’s going to feel long in the moment, but it’s a short period in the context of Life.</p>
<p>The mountaintop will not get closer no matter how often you look at it. But the more often you look at it, the more you’ll get discouraged because somewhere, we are all in a hurry. Things take time. And as Jeff Bezos says, you can’t skip steps.</p>
<p>If you lose your optimism you lose confidence, and then you lose energy and momentum.</p>
<p>Instead, just focus on the <em>process</em> of learning. No matter how much code you write, you are always learning new tools, techniques, practices, languages, frameworks and so on. And if you rush yourself into feeling “competent” you will disappoint yourself, because at first you’re going to get suck.</p>
<p>That’s normal. You can’t skip the novice stage when you’re learning, and if you try to skip it, you will get frustrated and lose your passion.</p>
<p>The <em>process</em> of learning is to do a little bit consistently, rather than a ton of stuff in an inspired burst. 60 minutes every day for 3 months is far more effective than blitzing it for 20 hours on a weekend and then not doing anything for a month.</p>
<p>So don’t focus on “becoming a good engineer” or “getting that job”. Instead, focus on learning and getting your repetitions up until things start to feel comfortable.</p>
<h3 id="heading-dont-mistake-doubts-for-evidence">DON’T Mistake Doubts for Evidence</h3>
<p>You’re going to have doubt and fear with you every step of the way. If you think of it as a shadow, you may stop paying so much attention to it.</p>
<p>Doubts have a way of convincing us they’re real. They spotlight our weaknesses and over-emphasise our failures. And then, without realising it, we take them as evidence of our ability.</p>
<p>This one takes practice. And since you’re never going to be doubt-free no matter how much of an expert you are, you should practice making space for your doubts while not paying too much attention to them.</p>
<p>No matter what your doubts tell you, there is only one thing you know for certain: if your doubt is right, it is right only <em>right now</em>. Tomorrow it could be wrong. If not tomorrow, the day after that.</p>
<p>Your doubts don’t prove anything about tomorrow. Chances are your doubts are not right at all – they’re just insecurities and exhaustion.</p>
<p>Rather than fight doubt, it’s better to do some vigorous 10 minute exercise or take a nap. If doubts disappear (and you’ve experienced that!) then they can’t be all that real.</p>
<h3 id="heading-dont-measure-reality-against-your-secret-wishes">DON’T Measure Reality Against your Secret Wishes</h3>
<p>All of us have secret hopes and fantasies. We hope we will be recognised as brilliant and our boss will promote us without us having done much, or that we can get super-fit bodies with 2 months of going to the gym, or that our first 3 blogs will get a bazillion comments and shares on social media. We secretly wish for success, without too much effort, and very quickly.</p>
<p>Maybe. Statistically, some people will get that lucky, just as a dead clock will tell you the right time twice a day.</p>
<p>But if you’re not aware of this secret wish and its power over your mind, you will feel disappointment. And you will not find the energy and discipline to keep going.</p>
<p>The truth is pretty much any goal that is beyond your current skills takes a lot of time, energy, focus, and discipline. And it requires you to maintain those practices well past the point you were secretly hoping for instant gratification. In fact you could go for months without much positive reinforcement from the world around you.</p>
<p>So measuring your results against your secret wishes is a recipe for giving up. Instead measure your results against your previous results.</p>
<p>I use a simple technique for this – my personal motto is to be 1% better every day. As long as you’re getting a little bit better each day (maybe you just read a blog, or did some <a target="_blank" href="https://fs.blog/2021/04/deliberate-practice-guide/">deliberate practice</a> for 30 minutes), then you would have improved yourself. These micro-improvement don’t stack – they <em>compound</em>.</p>
<p>Measure yourself against your past results, not your secret fantasies and you will feel tremendous motivation to keep going.</p>
<h3 id="heading-dont-take-big-decisions-on-bad-days">DON’T Take Big Decisions on Bad Days</h3>
<p>You’re going to have a lot of bad days. Don’t negotiate with that – accept it and don’t put too much emotional weight on it. Even when you’re the best at what you do, you’re going to have bad days.</p>
<p>So you must expect a lot more of them, a lot more frequently, when you’re learning complex new skills. You must fully expect that you will have such bad days that the only rational-feeling thing to do is to quit.</p>
<p>You will have such bad days that you cannot see how things can get better. You will have such horrible days that you will assume the way you feel right then is how you’re going to feel forever unless you give yourself the relief of quitting.</p>
<p>I went through this so many times. Not just in coding – but in every single job I’ve ever had. This is why people respond so well to having a coach. A coach is “an external mind” that can see more clearly than you when you’re lost, struggling, confused, or discouraged.</p>
<p>The threat of quitting on a bad day is so high that I developed a technique to get around this. Rather than constantly arguing and negotiating with myself in my head, and confusing myself to exhaustion, I simply follow one rule: is this a bad day? Oh yes. Ok, no decisions today.</p>
<p>Rather than quit, take a break. When I was learning to code, I would sometimes stop studying and coding for a week if I was dangerously close to giving up. I figured I’d rather lose 1 week of progress than quit altogether. Most often, in 2-3 days my internal “state” would change and I’d be back at it, harder than ever.</p>
<p>In fact I found a rule from an olympic gymnast that I adopted for myself. I even <a target="_blank" href="https://www.linkedin.com/pulse/you-can-give-upif-follow-one-rule-zubin-pratap/">wrote about it when I found it</a>, as a way to ensure I followed her advice.</p>
<blockquote>
<p><em>You can give up any time you like….as long as you’re having a good day. But you cannot give up when you’re having a bad day.</em></p>
</blockquote>
<h3 id="heading-dont-assume-your-results-reflect-your-ability">DON’T Assume Your Results Reflect Your Ability</h3>
<p>It is easy to assume that your results reflect your ability. In a sense, that is true – they either reflect your effort or they reflect your <em>current</em> ability. And that’s the most important distinction to make.</p>
<p>If it’s not a failure of effort, then it is a shortcoming in your current skills. And that’s great, because skills can always be improved. It’s just hard because we secretly wish it would be faster, easier, and more glamorous to get to success!</p>
<p>Most importantly, it is critical not to let your internal dialogue switch from “I don’t know how to do X” to “I cannot do X”.</p>
<p>We often unwittingly confuse lack of knowledge or skill with lack of ability or potential. This is particularly easy to do when we’re surrounded by people who are a whole lot better than we are.</p>
<p>I felt this so many times. As a junior lawyer and then 15 years later as a junior engineer. I assumed other people were talented or gifted and I was not. As I grew in experience, other “juniors” viewed me as talented or gifted. It was just experience and learning.</p>
<p>There is a line from T. Harv Ecker that I really found to be true in my various careers:</p>
<blockquote>
<p>“<em>If you’re not doing as well as you’d like, all that means is there’s something you don’t know.</em>”</p>
</blockquote>
<p>Also, as a close cousin to this principle, follow John Wooden’s advice:</p>
<blockquote>
<p><em>"Never let what you cannot do get in the way of what you can</em>. "</p>
</blockquote>
<p>There will be many weeks when you’re grappling with something that you simply don’t know how to do. It won’t come easy. It won’t come quick. And you may feel very stuck.</p>
<p>But there will <em>always</em> be something – maybe it’s something small – that you can do to take one step forward. By always moving forward, even if it's a tiny step, you will keep your momentum. And usually those small steps are the small learnings you need to stack up to solve the bigger problem that has you so badly stuck.</p>
<h2 id="heading-5-things-to-definitely-do-when-changing-careers">5 Things to DEFINITELY Do When Changing Careers</h2>
<h3 id="heading-do-work-on-your-growth-mindset">DO Work on Your Growth Mindset</h3>
<p>If you practice the top 5 Don’ts, you will automatically start building a growth mindset. At first you may not have a growth mindset – it’s more likely to be that you will gradually remove the unproductive “fixed mindset” habits that we all have.</p>
<p>If you aren’t familiar with the concept of the growth mindset, take a look at this <a target="_blank" href="https://www.youtube.com/watch?v=hiiEeMN7vbQ">TED talk</a> by Carol Dweck. She has even published her research in a bestselling book. This is a foundational worldview that will help in everything you do.</p>
<p>Note that I say “work” on your growth mindset. This is not a weekend hack. It is a lifestyle. It requires constant practice and self-awareness.</p>
<p>In my experience, the most powerful impact of practicing a growth mindset is that I asked <em>radically</em> different questions when I was failing or struggling.</p>
<p>For example, instead of asking myself “why can’t I figure this out?” I trained myself to ask “how can I find someone or something to help me figure this out”.</p>
<p>I remember when I was learning JavaScript promises, and I was really struggling to get the concept. At first I sank into depression because I read a few blogs and I just couldn’t grasp some of the intricacies and mental models. I felt drained and frightened, overwhelmed and very alone.</p>
<p>I watched this TED talk and I immediately asked myself – do I know any JavaScript developers? I went to LinkedIn and searched my contacts (I was too shy to ask total strangers on Twitter – a sign of my fixed mindset!).</p>
<p>I found a guy I’d met at a startup event, who was self taught and had built a JavaScript webapp. I reached out to him and it turned out his office was 15 minutes from my house. Two days later he spent his lunch break showing me how to use promises. It felt easy after that.</p>
<p>Carol Dweck was right – it wasn’t that I didn’t know JavaScript promises, it was that I didn’t know them...<em>yet</em>.</p>
<h3 id="heading-do-make-friends-with-the-impostor-syndrome">DO Make Friends with the Impostor Syndrome</h3>
<p>Impostor Syndrome is when you secretly think that you’re not good enough to do what you’re doing and that you will get found out and exposed as a fraud, or an impostor. I wouldn’t say it’s common. I’d say it’s almost universal.</p>
<p>When onboarding at Google, I heard this topic come up so many times. There are tons of blogs, resources, and internal guidance on how to deal with it. Engineers feel it everywhere. Heck, the <a target="_blank" href="https://www.youtube.com/watch?v=zNBmHXS3A6I">co-founder of Atlassian did a TED talk on it</a>.</p>
<p>So, it’s a form of doubt, and we already covered how to deal with doubt in the DON’Ts section.</p>
<p>Impostor Syndrome has some added layers to it, because it typically arises in professional settings. That’s why it gets special treatment here in the DOs section.</p>
<p>Professional contexts produce more fear of embarrassment because we have all this baggage about performance, and promotions, and being reviewed by bosses. All that extra baggage gives it more power over us.</p>
<p>As you start to get successful in your coding journey, make friends with Impostor Syndrome and joke about it – it will oddly make your mindset more growth oriented, because by owning that you don’t know something, you open yourself to learning it.</p>
<p>If you hide it, you spend a lot of energy on soothing yourself that you could otherwise use to learn the thing you don’t know yet.</p>
<h3 id="heading-do-practice-reframing-failure-and-setbacks-as-moments-of-learning">DO Practice Reframing Failure and Setbacks as Moments of Learning</h3>
<p>We all hate the feeling of failing. We also can’t avoid it. What do you do when you can’t avoid something you dislike intensely?</p>
<p>You attach a different meaning to it.</p>
<p>If you classify setbacks and disappointments as failures, then you will emotionally respond to them as failures. If you classify setbacks and disappointments as information about what you need to learn, then you respond to them as lessons.</p>
<p>Let me be clear – this is not easy to do! Like everything else I’m writing about here, this takes practice. Just like coding.</p>
<p>As clichéd as it is, the <em>emotional</em> impact of the glass is half full versus the glass is half empty debate is very real. In fact marketers know this. They don’t tell you your fruity yoghurt is 20% fat. They tell you it’s 80% fat-free.</p>
<p>You’re absolutely going to fail, and if you learn from it then you have to ask yourself – did I fail or did I just learn something?</p>
<p>Put all your attention on understanding what you learned from that failure, analyse, deconstruct, and internalise it. That way, you won’t notice failing so much.</p>
<h3 id="heading-do-hold-yourself-accountable-by-making-fewer-decisions">DO Hold Yourself Accountable by Making Fewer Decisions</h3>
<p>As a lawyer, I can tell you that our minds are experts at arguing for both sides, depending on what suits it. If you ask your mind why it’s OK to skip a run today, it will tell you. If you ask your mind why running is important, it will tell you that too.</p>
<p>How do we get anything done with a mind that changes with the wind?</p>
<p>We don’t ask the mind. We simply commit to one action. If we ever discuss this action with our mind, then we will get sucked into a negotiation with, or rather against, ourselves. This wastes a lot of energy.</p>
<p>Have you ever gone around in circles in your head wondering whether you really need to do the assignment now, or whether you can finish watching the movie on Netflix and then find time for it later? We all have.</p>
<p>It’s much easier if we say, from 8 to 10pm I do nothing but X. Until I do X I will not do Y. But once I do X I will reward myself with Y, and not get distracted by Z.</p>
<p>If it sounds like a lot of effort, I can promise you that it’s way less effort than having the same internal debate every few days and then beating yourself up for it later.</p>
<p>Commit once and save yourself the headache of constantly negotiating with yourself. This is the best way I’ve found to keep myself accountable, because I don’t need to keep checking in. I just check against one rule that is not up to my mind to decide.</p>
<h3 id="heading-do-focus-on-the-insight-rather-than-the-implementation">DO Focus on the Insight Rather than the Implementation</h3>
<p>This one is important for coders and is a little less meta than the other points.</p>
<p>Ultimately, most people reading this are looking to code professionally or for economic gain of some sort. It is easy to be in a hurry when progress has taken longer than you secretly wished, or planned for.</p>
<p>As a result, we tend to try and learn “tricks” and “shortcuts”. These are tactically useful as they will help us make some progress. But they also come at a cost – those shortcuts may not help us apply the principles to unfamiliar contexts.</p>
<p>For example, if you’re learning how to use recursion, it’s tempting to memorise the approach rather than build your mental intuition around it. But if you can’t see how the same technique can be used to solve other problems or a “class” of problems, then you’re missing out on the real power of the tool.</p>
<p>This can then catch up with you in interviews or at the workplace. In interviews, you may fail to recognise the underlying “class” of problems.</p>
<p>For example, when I was first teaching myself data structures I once failed to recognise a problem about HR reporting structures as a tree/graph traversal problem. That actually happened during a mock interview! I had practiced graph traversals and memorised implementations but hadn’t fully internalised the concept.</p>
<p>Similarly, without understanding concepts you cannot communicate effectively with team members or people who come to you to learn. This will set you back at the workplace because effective engineers need to communicate abstract concepts well.</p>
<p>At a more general level, adopting this “DO” means that you won’t fake it. It will force you to be patient and persistent in developing your understanding, rather than a hack around true comprehension.</p>
<p>No matter what skill you’re learning in life, having clarity of concepts is much more scalable than knowing just one implementation of the concept.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>On a departing note – these are my top 5 Dos and Don’ts. If you make them yours I can guarantee that you will make progress, and come up with your own - that is extremely important as your own framework can only emerge from confidence and practice.</p>
<p>But having your own framework will make you a real weapon, because it’s reusable across any learning context.</p>
<p>I really hope that these lessons are of value to you. I truly believe that if one person can do it, I can too, and if you believe that, you will be able to do it, too.</p>
<h3 id="heading-post-script">Post Script</h3>
<p>If you would like to learn more about my journey from lawyer to software engineer, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a> and also <a target="_blank" href="https://lessonsfromaquitter.com/episode207/">Episode 207</a> of "Lessons from a Quitter". These provide the blueprint for my career change.</p>
<p>If you are interested in teaching yourself to code, changing careers and becoming a professional coder, or <a target="_blank" href="https://www.freecodecamp.org/news/non-technical-and-looking-for-a-technical-co-founder-2c212c01d6da/">becoming your own technical co-founder</a>, please reach out <a target="_blank" href="http://linktree.com/zubinpratap">here</a>. You can also check out my free webinar on <a target="_blank" href="http://futurecoderstraining.com/">Career Change to Code</a> if that is what you're dreaming of.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ System Design Interview Question Handbook – Concepts You Should Know ]]>
                </title>
                <description>
                    <![CDATA[ You may have heard the terms "Architecture" or "System Design." These come up a lot during developer job interviews – especially at big tech companies. I wrote this in-depth guide when preparing for my FAANG software engineering interviews. It covers... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/systems-design-for-interviews/</link>
                <guid isPermaLink="false">66d461da57503cc72873deee</guid>
                
                    <category>
                        <![CDATA[ coding interview ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Interviews ]]>
                    </category>
                
                    <category>
                        <![CDATA[ systems-engineering ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Wed, 01 Apr 2020 15:21:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/System-Design-Book-Cover.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You may have heard the terms "Architecture" or "System Design." These come up a lot during developer job interviews – especially at big tech companies.</p>
<p>I wrote this in-depth guide when preparing for my FAANG software engineering interviews. It covers the essential software system design concepts you need to reason your way through distributed systems, and it helped me get into Google as an engineer, after more than 15 years of being a corporate lawyer.</p>
<p>This is not an exhaustive treatment, since System Design is a vast topic. But if you're a junior or mid-level developer, this should give you a strong foundation.</p>
<p>From there, you can dig deeper with other resources. I've listed some of my favourite resources at the very bottom of this article.</p>
<p>I've broken this guide into bite-sized chunks by topic and so I recommend you bookmark it. I've found <a target="_blank" href="https://www.freecodecamp.org/news/use-spaced-repetition-with-anki-to-learn-to-code-faster-7c334d448c3c/">spaced learning and repetition</a> to be incredibly valuable tools to learn and retain information. And I've designed this guide to be chunked down into pieces that are easy to do spaced repetition with.</p>
<ol>
<li><p><a class="post-section-overview" href="#heading-section-1-networks-and-protocols">Section 1: Networks &amp; Protocols (IP, DNS, HTTP, TCP etc)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-2-storage-latency-amp-throughput">Section 2: Storage, Latency &amp; Throughput</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-3-system-availability">Section 3: Availability</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-4-caching">Section 4: Caching</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-5-proxies">Section 5: Proxies</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-6-load-balancing">Section 6: Load Balancing</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-7-consistent-hashing">Section 7: Consistent Hashing</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-8-databases">Section 8: Databases</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-9-leader-election">Section 9: Leader Election</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-10-polling-streaming-sockets">Section 10: Polling, Streaming, Sockets</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-11-endpoint-protection">Section 11: Endpoint Protection</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-12-messaging-amp-pub-sub">Section 12: Messages &amp; Pub-Sub</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-13-smaller-essentials">Section 13: Smaller Essentials</a></p>
</li>
</ol>
<p>Let's get started!</p>
<h2 id="heading-section-1-networks-and-protocols">Section 1: Networks and Protocols</h2>
<p>"Protocols" is a fancy word that has a meaning in English totally independent of computer science. It means a system of rules and regulations that govern something. A kind of "official procedure" or "official way something must be done".</p>
<p>For people to connect to machines and code that communicate with each other, they need a network over which such communication can take place. But the communication also needs some rules, structure, and agreed-upon procedures.</p>
<p>Thus, network protocols are protocols that govern how machines and software communicate over a given network. An example of a network is our beloved world wide web.</p>
<p>You may have heard of the most common network protocols of the internet era - things like HTTP, TCP/IP etc. Let's break them down into basics.</p>
<h3 id="heading-ip-internet-protocolhttpsenwikipediaorgwikiinternetprotocol">IP - <a target="_blank" href="https://en.wikipedia.org/wiki/Internet_Protocol">Internet Protocol</a></h3>
<p>Think of this as the fundamental layer of protocols. It is the basic protocol that instructs us on how almost all communication across internet networks must be implemented.</p>
<p>Messages over IP are often communicated in "packets", which are small bundles of information (2^16 bytes). Each packet has an <a target="_blank" href="https://en.wikipedia.org/wiki/IPv4#Packet_structure">essential structure</a> made up of two components: the Header and the Data.</p>
<p>The header contains "meta" data about the packet and its data. This metadata includes information such as the IP address of the source (where the packet comes from) and the destination IP address (destination of the packet). Clearly, this is fundamental to being able to send information from one point to another - you need the "from" and "to" addresses.</p>
<p>And an <a target="_blank" href="https://en.wikipedia.org/wiki/IP_address">IP Address</a> is a numeric label assigned to each device connected to a <a target="_blank" href="https://en.wikipedia.org/wiki/Computer_network">computer network</a> that uses the Internet Protocol for communication. There are public and private IP addresses, and there are currently two versions. The new version is called IPv6 and is increasingly being adopted because IPv4 is running out of numerical addresses.</p>
<p>The other protocols we will consider in this post are built on top of IP, just like your favorite software language has libraries and frameworks built on top of it.</p>
<h3 id="heading-tcp-transmission-control-protocolhttpsenwikipediaorgwikitransmissioncontrolprotocol">TCP - <a target="_blank" href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol">Transmission Control Protocol</a></h3>
<p>TCP is a utility built on top of IP. As you may know from reading my posts, I firmly believe you need to understand <em>why</em> something was invented in order to truly understand <em>what</em> it does.</p>
<p>TCP was created to solve a problem with IP. Data over IP is typically sent in multiple packets because each packet is fairly small (2^16 bytes). Multiple packets can result in (A) lost or dropped packets and (B) disordered packets, thus corrupting the transmitted data. TCP solves both of these by guaranteeing <em>transmission</em> of packets in an <em>ordered</em> way.</p>
<p>Being built on top of IP, the packet has a header called the TCP header in addition to the IP header. This TCP header contains information about the ordering of packets, and the number of packets and so on. This ensures that the data is reliably received at the other end. It is generally referred to as TCP/IP because it is built on top of IP.</p>
<p>TCP needs to establish a connection between source and destination before it transmits the packets, and it does this via a "handshake". This connection itself is established using packets where the source informs the destination that it wants to open a connection, and the destination says OK, and then a connection is opened.</p>
<p>This, in effect, is what happens when a server "listens" at a port - just before it starts to listen there is a handshake, and then the connection is opened (listening starts). Similarly, one sends the other a message that it is about to close the connection, and that ends the connection.</p>
<h3 id="heading-http-hyper-text-transfer-protocolhttpsenwikipediaorgwikihypertexttransferprotocol">HTTP - <a target="_blank" href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol">Hyper Text Transfer Protocol</a></h3>
<p>HTTP is a protocol that is an abstraction built on top of TCP/IP. It introduces a very important pattern called the request-response pattern, specifically for client-server interactions.</p>
<p>A client is simply a machine or system that requests information, and a server is the machine or system that responds with information. A browser is a client, and a web-server is a server. When a server requests data from another server then the first server is also a client, and the second server is the server (I know, tautologies).</p>
<p>So this request-response cycle has its own rules under HTTP and this standardizes how information is transmitted across the internet.</p>
<p>At this level of abstraction we typically don't need to worry too much about IP and TCP. However, in HTTP, requests and responses have headers and bodies too, and these contain data that can be set by the developer.</p>
<p>HTTP requests and responses can be thought of as messages with key-value pairs, very similar to objects in JavaScript and dictionaries in Python, but not the same.</p>
<p>Below is an illustration of the content, and key-value pairs in HTTP request and response messages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-44.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>source:</em> <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages"><em>https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages</em></a></p>
<p>HTTP also comes with some "verbs" or "methods" which are commands that give you an idea of what sort of operation is intended to be performed. For example, the common HTTP methods are "GET", "POST", "PUT", "DELETE" and "PATCH", but there are more. In the above picture, look for the HTTP verb in the start line.</p>
<h2 id="heading-section-2-storage-latency-amp-throughput">Section 2: Storage, Latency &amp; Throughput</h2>
<h3 id="heading-storage">Storage</h3>
<p>Storage is about holding information. Any app, system, or service that you program will need to store and retrieve data, and those are the two fundamental purposes of storage.</p>
<p>But it's not just about storing data – it's also about fetching it. We use a database to achieve this. A database is a software layer that helps us store and retrieve data.</p>
<p>These two primary types of operations, storing and retrieving, are also variously called 'set, get', 'store, fetch', 'write, read' and so on. To interact with storage, you will need to go through the database, which acts as an intermediary for you to conduct these fundamental operations.</p>
<p>The word "storage" can sometimes fool us into thinking about it in physical terms. If I "store" my bike in the shed, I can expect it to be there when I next open the shed.</p>
<p>But that doesn't always happen in the computing world. Storage can broadly be of two types: "Memory" storage and "Disk" storage.</p>
<p>Of these two, the disk storage tends to be the more robust and "permanent" (not truly permanent, so we often use the word "persistent" storage instead). Disk storage is persistent storage. This means that when you save something to Disk, and turn the power off, or restart your server, that data will "persist". It won't be lost.</p>
<p>However, if you leave data in "Memory" then that usually gets wiped away when you shut down or restart, or otherwise lose power.</p>
<p>The computer you use everyday has both these storage types. Your hard disk is<br>"persistent" Disk storage, and your RAM is transient Memory storage.</p>
<p>On servers, if the data you're keeping track of is only useful during a session of that server, then it makes sense to keep it in Memory. This is much faster and less expensive than writing things to a persistent database.</p>
<p>For example, a single session may mean when a user is logged in and using your site. After they log out, you may not need to hold on to bits of data that you collected during the session.</p>
<p>But whatever you do want to hold on to (like shopping cart history) you will put in persistent Disk storage. That way you can access that data the next time the user logs in, and they will have a seamless experience.</p>
<p>Ok, so this seems quite simple and basic, and it's meant to be. This is a primer. Storage can get very complex. If you take a look at the range of storage products and solutions your head will spin.</p>
<p>This is because different use-cases require different types of storage. They key to choosing the right storage types for your system depends on a lot of factors and the needs of your application, and how users interact with it. Other factors include:</p>
<ul>
<li><p>the shape (structure) of your data, or</p>
</li>
<li><p>what sort of availability it needs (what level of downtime is OK for your storage), or</p>
</li>
<li><p>scalability (how fast do you need to read and write data, and will these reads and writes happen concurrently (simultaneously) or sequentially) etc, or</p>
</li>
<li><p>consistency - if you protect against downtime using distributed storage, then how consistent is the data across your stores?</p>
</li>
</ul>
<p>These questions and the conclusions require you to consider your trade-offs carefully. Is consistency more important than speed? Do you need the database to service millions of operations per minute or only for nightly updates? I will be dealing with these concepts in sections later, so don't worry if you've no idea what they are.</p>
<h3 id="heading-latency">Latency</h3>
<p>"Latency" and "Throughput" are terms you're going to hear a lot of as you start to get more experienced with designing systems to support the front end of your application. They are very fundamental to the experience and performance of your application and the system as a whole. There is often a tendency to use these terms in a broader sense than intended, or out of context, but let's fix that.</p>
<p><strong>Latency</strong> is simply the measure of a duration. What duration? The duration for an action to complete something or produce a result. For example: for data to move from one place in the system to another. You may think of it as a lag, or just simply the time taken to complete an operation.</p>
<p>The most commonly understood latency is the "round trip" network request - how long does it take for your front end website (client) to send a query to your server, and get a response back from the server.</p>
<p>When you're loading a site, you want this to be as fast and as smooth as possible. In other words you want <em>low</em> latency. Fast lookups means low latency. So finding a value in an array of elements is slower (higher latency, because you need to iterate over each element in the array to find the one you want) than finding a value in a hash-table (lower latency, because you simply look up the data in "constant" time , by using the key. No iteration needed.).</p>
<p>Similarly, reading from memory is much faster than reading from a disk (read more <a target="_blank" href="https://stackoverflow.com/questions/1371400/how-much-faster-is-the-memory-usually-than-the-disk">here</a><em>).</em> But both have latency, and your needs will determine which type of storage you pick for which data.</p>
<p>In that sense, latency is the inverse of speed. You want higher speeds, and you want lower latency. Speed (especially on network calls like via HTTP) is determined also by the distance. So, <a target="_blank" href="https://wondernetwork.com/pings/London">latency from London to another city</a>, will be impacted by the distance from London.</p>
<p>As you can imagine, you want to design a system to avoid pinging distant servers, but then storing things in memory may not be feasible for your system. These are the tradeoffs that make system design complex, challenging and extremely interesting!</p>
<p>For example, websites that show news articles may prefer uptime and availability over loading speed, whereas online multiplayer games may require availability <em>and</em> super low latency. These requirements will determine the design and investment in infrastructure to support the system's special requirements.</p>
<h3 id="heading-throughput">Throughput</h3>
<p>This can be understood as the maximum capacity of a machine or system. It's often used in factories to calculate how much work an assembly line can do in an hour or a day, or some other unit of time measurement.</p>
<p>For example an assembly line can assemble 20 cars per hour, which is its throughput. In computing it would be the amount of data that can be passed around in a unit of time. So a 512 Mbps internet connection is a measure of throughput - 512 Mb (megabits) per second.</p>
<p>Now imagine freeCodeCamp's web-server. If it receives 1 million requests per second, and can serve only 800,000 requests, then its throughput is 800,000 per second. You may end up measuring the throughput in terms of bits instead of requests, so it would be N bits per second.</p>
<p>In this example, there is a <em>bottleneck</em> because the server cannot handle more than N bits a second, but the requests are more than that. A bottleneck is therefore the constraint on a system. A system is only as fast as its <em>slowest bottleneck.</em></p>
<p>If one server can handle 100 bits per second, and another can handle 120 bits per second and a third can handle only 50, then the overall system will be operating at 50bps because that is the constraint - it holds up the speed of the other servers in a given system.</p>
<p>So increasing throughput anywhere other than the bottleneck may be a waste - you may want to just increase <em>throughput</em> at the <em>lowest bottleneck</em> first.</p>
<p>You can increase throughput by buying more hardware (horizontal scaling) or increasing the capacity and performance of your existing hardware (vertical scaling) or a few other ways.</p>
<p>Increasing throughput may sometimes be a short term solution, and so a good systems designer will think through the best ways to scale the throughput of a given system including by splitting up requests (or any other form of "load"), and distributing them across other resources etc. The key point to remember is what throughput is, what a constraint or bottleneck is, and how it impacts a system.</p>
<p>Fixing latency and throughput are not isolated, universal solutions by themselves, nor are they correlated to each other. They have impacts and considerations across the system, so it's important to understand the system as a whole, and the nature of the demands that will be placed on the system over time.</p>
<h2 id="heading-section-3-system-availability">Section 3: System Availability</h2>
<p>Software engineers aim to build systems that are reliable. A reliable system is one that consistently satisfies a user's needs, whenever that user seeks to have that need satisfied. A key component of that reliability is Availability.</p>
<p>It's helpful to think of availability as the resiliency of a system. If a system is robust enough to handle failures in the network, database, servers etc, then it can generally be considered to be a fault-tolerant system - which makes it an available system.</p>
<p>Of course, a system is a sum of its parts in many senses, and each part needs to be <a target="_blank" href="https://en.wikipedia.org/wiki/High_availability">highly available</a> if availability is relevant to the end user experience of the site or app.</p>
<h3 id="heading-quantifying-availability">Quantifying Availability</h3>
<p>To quantify the availability of a system, we calculate the percentage of time that the system's primary functionality and operations are available (the uptime) in a given window of time.</p>
<p>The most business-critical systems would need to have a near-perfect availability. Systems that support highly variable demands and loads with sharp peaks and troughs may be able to get away with slightly lower availability during off-peak times.</p>
<p>It all depends on the use and nature of the system. But in general, even things that have low, but consistent demands or an implied guarantee that the system is "on-demand" would need to have high availability.</p>
<p>Think of a site where you backup your pictures. You don't always need to access and retrieve data from this - it's mainly for you to store things in. You would still expect it to always be available any time you login to download even just a single picture.</p>
<p>A different kind of availability can be understood in the context of the massive e-commerce shopping days like Black Friday or Cyber Monday sales. On these particular days demand will skyrocket and millions will try to access the deals simultaneously. That would require an extremely reliable and high-availability system design to support those loads.</p>
<p>A commercial reason for high availability is simply that any downtime on the site will result in the site losing money. Also, it could be really bad for reputation, for example, where the service is a service used by <em>other</em> businesses to offer services. If AWS S3 goes down, a lot of companies will suffer, including Netflix, and that is <em>not good</em>.</p>
<p>So uptimes are extremely important for success. It is worth remembering that commercial availability numbers are calculated based on annual availability, so a downtime of 0.1% (i.e. availability of 99.9%) is <a target="_blank" href="https://en.wikipedia.org/wiki/High_availability">8.77 hours a year</a>!</p>
<p>Hence, uptimes are extremely high sounding. It is common to see things like 99.99% uptime (52.6 minutes of downtime per year). Which is why it is now common to refer to uptimes in terms of "nines" - <a target="_blank" href="https://en.wikipedia.org/wiki/High_availability#%22Nines%22">the number of nines</a> in the uptime assurance.</p>
<p>In today's world that is unacceptable for large-scale or mission critical services. Which is why these days "five nines" is considered the ideal availability standard because that translates to a little over 5 minutes of downtime <em>per year</em>.</p>
<h3 id="heading-slas">SLAs</h3>
<p>In order to make online services competitive and meet the market's expectations, online service providers typically offer Service Level Agreements/Assurances. These are a set of guaranteed service level metrics. 99.999% uptime is one such metric and is often offered as part of premium subscriptions.</p>
<p>In the case of database and cloud service providers this can be offered even on the trial or free tiers if a customer's core use for that product justifies the expectation of such a metric.</p>
<p>In many cases failing to meet the SLA will give the customer a right to credits or some other form of compensation for the provider's failure to meet that assurance. Here, by way of example, is <a target="_blank" href="https://cloud.google.com/maps-platform/terms/sla">Google's SLA for the Maps API.</a></p>
<p>SLAs are therefore a critical part of the overall commercial and technical consideration when designing a system. It is especially important to consider whether availability is in fact a key requirement for a part of a system, and which parts require high availability.</p>
<h3 id="heading-designing-ha">Designing HA</h3>
<p>When designing a high availability (HA) system, then, you need to reduce or eliminate "single points of failure". A single point of failure is an element in the system that is the <em>sole</em> element that can produce that undesirable loss of availability.</p>
<p>You eliminate single points of failure by designing 'redundancy' into the system. Redundancy is basically making 1 or more alternatives (i.e. backups) to the element that is critical for high availability.</p>
<p>So if your app needs users to be authenticated to use it, and there is only one authentication service and back end, and that fails, then, because that is the single point of failure, your system is no longer usable. By having two or more services that can handle authentication, you have added redundancy and eliminated (or reduced) single points of failure.</p>
<p>Therefore, you need to understand and de-compose your system into all its parts. Map out which ones are likely to cause single points of failure, which ones are not tolerant of such failure, and which parts can tolerate them. Because engineering HA requires tradeoffs and some of these tradeoffs may be expensive in terms of time, money and resources.</p>
<h2 id="heading-section-4-caching">Section 4: Caching</h2>
<p>Caching! This is a very fundamental and easy-to-understand technique to speed up performance in a system. Thus caching helps to reduce <a class="post-section-overview" href="#storage-latency-throughput">"latency"</a> in a system.</p>
<p>In our daily lives, we use caching as a matter of common-sense (most of the time...). If we live next door to a supermarket, we still want to buy and store some basics in our fridge and our food cupboard. This is caching. We could always step out, go next door, and buy these things every time we want food – but if its in the pantry or fridge, we reduce the time it takes to make our food. That's caching.</p>
<h3 id="heading-common-scenarios-for-caching">Common Scenarios for Caching</h3>
<p>Similarly, in software terms, if we end up relying on certain pieces of data often, we may want to cache that data so that our app performs faster.</p>
<p>This is often true when it's faster to retrieve data from Memory rather than <a class="post-section-overview" href="#storage-latency-throughput">disk</a> because of the latency in making network requests. In fact many websites are cached (especially if content doesn't change frequently) in <a target="_blank" href="https://www.cloudflare.com/learning/cdn/what-is-caching/">CDNs</a> so that it can be served to the end user much faster, and it reduces load on the backend servers.</p>
<p>Another context in which caching helps could be where your backend has to do some computationally intensive and time consuming work. Caching previous results that converts your lookup time from a linear O(N) time to constant O(1) time could be very advantageous.</p>
<p>Likewise, if your server has to make multiple network requests and API calls in order to compose the data that gets sent back to the requester, then caching data could reduce the number of network calls, and thus the latency.</p>
<p>If your system has a client (front end), and a server and databases (backend) then caching can be inserted on the client (e.g. browser storage), between the client and the server (e.g. CDNs), or on the server itself. This would reduce over-the-network calls to the database.</p>
<p>So caching can occur at multiple points or levels in the system, including at the hardware (CPU) level.</p>
<h3 id="heading-handling-stale-data">Handling Stale Data</h3>
<p>You may have noticed that the above examples are implicitly handy for "read" operations. Write operations are not that different, in main principles, with the following added considerations:</p>
<ul>
<li><p>write operations require keeping the cache and your database in sync</p>
</li>
<li><p>this may increase complexity because there are more operations to perform, and new considerations around handling un-synced or "stale" data need to be carefully analyzed</p>
</li>
<li><p>new design principles may need to be implemented to handle that syncing - should it be done synchronously, or asynchronously? If async, then at what intervals? Where does data get served from in the mean time? How often does the cache need to be refreshed, etc...</p>
</li>
<li><p>data "eviction" or turnover and refreshes of data, to keep cached data fresh and up-to-date. These include techniques like <a target="_blank" href="https://en.wikipedia.org/wiki/Cache_replacement_policies#Last_in_first_out_(LIFO)_or_First_in_last_out_(FILO)">LIFO</a>, <a target="_blank" href="https://en.wikipedia.org/wiki/Cache_replacement_policies#First_in_first_out_(FIFO)">FIFO</a>, <a target="_blank" href="https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)">LRU</a> and <a target="_blank" href="https://en.wikipedia.org/wiki/Cache_replacement_policies#Least-frequently_used_(LFU)">LFU</a>.</p>
</li>
</ul>
<p>So let's end with some high-level, and non-binding conclusions. Generally, caching works best when used to store static or infrequently changing data, and when the sources of change are likely to be single operations rather than user-generated operations.</p>
<p>Where consistency and freshness in data is critical, caching may not be an optimal solution, unless there is another element in the system that efficiently refreshes the caches at intervals that do not adversely impact the purpose and user experience of the application.</p>
<h2 id="heading-section-5-proxies">Section 5: Proxies</h2>
<p>Proxy. What? Many of us have heard of proxy servers. We may have seen configuration options on some of our PC or Mac software that talk about adding and configuring proxy servers, or accessing "via a proxy".</p>
<p>So let's understand that relatively simple, widely used and important piece of tech. This is a word that exists in the English language completely independent of computer science, so let's start with that <a target="_blank" href="https://www.merriam-webster.com/dictionary/proxy">definition</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-08-at-12.57.03-pm.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Source:</em> <a target="_blank" href="https://www.merriam-webster.com/dictionary/proxy"><em>https://www.merriam-webster.com/dictionary/proxy</em></a></p>
<p>Now you can eject most of that out of your mind, and hold on to one key word: "substitute".</p>
<p>In computing, a proxy is typically a server, and it is a server that acts as a middleman between a client and another server. It literally is a bit of code that sits between client and server. That's the crux of proxies.</p>
<p>In case you need a refresher, or aren't sure of the definitions of client and server, a "client" is a process (code) or machine that requests data from another process or machine (the "server"). The browser is a client when it requests data from a backend server.</p>
<p>The server serves the client, but can also be a client - when it retrieves data from a database. Then the database is the server, the server is the client (of the database) and <em>also</em> a server for the front-end client (browser).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-22.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Source:</em> <a target="_blank" href="https://teoriadeisegnali.it/appint/html/altro/bgnet/clientserver.html#figure2"><em>https://teoriadeisegnali.it/appint/html/altro/bgnet/clientserver.html#figure2</em></a></p>
<p>As you can see from the above, the client-server relationship is bi-directional. So one thing can be both the client and server. If there was a middleman server that received requests, then sent them to another service, then forwards the response it got from that other service back to the originator client, that would be a proxy server.</p>
<p>Going forward we will refer to clients as clients, servers as servers and proxies as the thing between them.</p>
<p>So when a client sends a request to a server via the proxy, the proxy may sometimes mask the identity of the client - to the server, the IP address that comes through in the request may be the proxy and not the originating client.</p>
<p>For those of you who access sites or download things that otherwise are restricted (from the torrent network for example, or sites banned in your country), you may recognize this pattern - it's the principle on which VPNs are built.</p>
<p>Before we move a bit deeper, I want to call something out - when generally used, the term proxy refers to a "forward" proxy. A forward proxy is one where the proxy acts on behalf of (substitute for) the client in the interaction between client and server.</p>
<p>This is distinguished from a reverse proxy - where the proxy acts on behalf of a server. On a diagram it would look the same - the proxy sits between the client and the server, and the data flows are the same client &lt;-&gt; proxy &lt;-&gt; server.</p>
<p>The key difference is that a reverse proxy is designed substitute for the server. Often clients won't even know that the network request got routed through a proxy and the proxy passed it on to the intended server (and did the same thing with the server's response).</p>
<p>So, in a forward proxy, the server won't know that the client's request and its response are traveling through a proxy, and in a reverse proxy the client won't know that the request and response are routed through a proxy.</p>
<p>Proxies feel kinda sneaky :)</p>
<p>But in systems design, especially for complex systems, proxies are useful and reverse proxies are particularly useful. Your reverse proxy can be delegated a lot of tasks that you don't want your main server handling - it can be a gatekeeper, a screener, a load-balancer and an all around assistant.</p>
<p>So proxies can be useful but you may not be sure why. Again, if you've read my other stuff you'd know that I firmly believe that you can understand things properly only when you know <em>why</em> they exist - knowing <em>what</em> they do is not enough.</p>
<h2 id="heading-section-6-load-balancing">Section 6: Load Balancing</h2>
<p>If you think about the two words, load and balance, you will start to get an intuition as to what this does in the world of computing. When a server simultaneously receives a lot of requests, it can slow down (throughput reduces, latency rises). After a point it may even fail (no availability).</p>
<p>You can give the server more muscle power (vertical scaling) or you can add more servers (horizontal scaling). But now you got to work out how the income requests get distributed to the various servers - which requests get routed to which servers and how to ensure they don't get overloaded too? In other words, how do you balance and allocate the request load?</p>
<p>Enter load balancers. Since this article is an introduction to principles and concepts, they are, of necessity, very simplified explanations. A load balancer's job is to sit between the client and server (but there are other places it can be inserted) and work out how to distribute incoming request loads across multiple servers, so that the end user (client's) experience is consistently fast, smooth and reliable.</p>
<p>So load balancers are like traffic managers who direct traffic. And they do this to maintain <a class="post-section-overview" href="#system-availability">availability</a> and <a class="post-section-overview" href="#storage-latency-throughput">throughput</a>.</p>
<p>When understanding where a load balancer is inserted in the system's architecture, you can see that load balancers can be thought of as <a class="post-section-overview" href="#proxies">reverse proxies</a>. But a load balancer can be inserted in other places too - between other exchanges - for example, between your server and your database.</p>
<h3 id="heading-the-balancing-act-server-selection-strategies">The Balancing Act - Server Selection Strategies</h3>
<p>So how does the load balancer decide how to route and allocate request traffic? To start with, every time you add a server, you need to let your load balancer know that there is one more candidate for it to route traffic to.</p>
<p>If you remove a server, the load balancer needs to know that too. The configuration ensures that the load balancer knows how many servers it has in its go-to list and which ones are available. It is even possible for the load balancer to be kept informed on each server's load levels, status, availability, current task and so on.</p>
<p>Once the load balancer is configured to know what servers it can redirect to, we need to work out the best routing strategy to ensure there is proper distribution amongst the available servers.</p>
<p>A naive approach to this is for the load balancer to just randomly pick a server and direct each incoming request that way. But as you can imagine, randomness can cause problems and "unbalanced" allocations where some servers get more loaded than others, and that could affect performance of the overall system negatively.</p>
<h3 id="heading-round-robin-and-weighted-round-robin">Round Robin and Weighted Round Robin</h3>
<p>Another method that can be intuitively understood is called "round robin". This is the way many humans process lists that loop. You start at the first item in the list, move down in sequence, and when you're done with the last item you loop back up to the top and start working down the list again.</p>
<p>The load balancer can do this too, by just looping through available servers in a fixed sequence. This way the load is pretty evenly distributed across your servers in a simple-to-understand and predictable pattern.</p>
<p>You can get a little more "fancy" with the round robin by "weighting" some services over others. In the normal, standard round robin, each server is given equal weight (let's say all are given a weighting of 1). But when you differently weight servers, then you can have some servers with a lower weighting (say 0.5, if they're less powerful), and others can be higher like 0.7 or 0.9 or even 1.</p>
<p>Then the total traffic will be split up in proportion to those weights and allocated accordingly to the servers that have power proportionate to the volume of requests.</p>
<h3 id="heading-load-based-server-selection">Load-based server selection</h3>
<p>More sophisticated load balancers can work out the current capacity, performance, and loads of the servers in their go-to list and allocate dynamically according to current loads and calculations as to which will have the highest throughput, lowest latency etc. It would do this by monitoring the performance of each server and deciding which ones can and cannot handle the new requests.</p>
<h3 id="heading-ip-hashing-based-selection">IP Hashing based selection</h3>
<p>You can configure your load balancer to <a target="_blank" href="https://www.cs.cmu.edu/~adamchik/15-121/lectures/Hashing/hashing.html">hash</a> the IP address of incoming requests, and use the hash value to determine which server to direct the request too. If I had 5 servers available, then the hash function would be designed to return one of five hash values, so one of the servers definitely gets nominated to process the request.</p>
<p>IP hash based routing can be very useful where you want requests from a certain country or region to get data from a server that is best suited to address the needs from within that region, or where your servers cache requests so that they can be processed fast.</p>
<p>In the latter scenario, you want to ensure that the request goes to a server that has previously cached the same request, as this will improve speed and performance in processing and responding to that request.</p>
<p>If your servers each maintain independent caches and your load balancer does not consistently send identical requests to the same server, you will end up with servers re-doing work that has already been done in as previous request to another server, and you lose the optimization that goes with caching data.</p>
<h3 id="heading-path-or-service-based-selection">Path or Service based selection</h3>
<p>You can also get the load balancer to route requests based on their "path" or function or service that is being provided. For example if you're buying flowers from an online florist, requests to load the "Bouquets on Special" may be sent to one server and credit card payments may be sent to another server.</p>
<p>If only one in twenty visitors actually bought flowers, then you could have a smaller server processing the payments and a bigger one handling all the browsing traffic.</p>
<h3 id="heading-mixed-bag">Mixed Bag</h3>
<p>And as with all things, you can get to higher and more detailed levels of complexity. You can have multiple load balancers that each have different server selection strategies! And if yours is a very large and highly trafficked system, then you may need <em>load balancers for load balancers...</em></p>
<p>Ultimately, you add pieces to the system until your performance is tuned to your needs (your needs may look flat, or slow upwards mildly over time, or be prone to spikes!).</p>
<p>We've talked about VPNs (for forward proxies) and load-balancing (for reverse proxies), but there are more examples <a target="_blank" href="https://www.quora.com/What-are-the-different-uses-of-proxy-servers">here</a>.</p>
<h2 id="heading-section-7-consistent-hashing">Section 7: Consistent Hashing</h2>
<p>One of the slightly more tricky concepts to understand is hashing in the context of load balancing. So it gets its own section.</p>
<p>In order to understand this, please first understand <a target="_blank" href="https://www.cs.cmu.edu/~guna/15-123S11/Lectures/Lecture17.pdf">how hashing works at a conceptual level</a>. The TL;DR is that hashing converts an input into a fixed-size value, often an integer value (the hash).</p>
<p>One of the key principles for a good hashing algorithm or function is that the function must be <a target="_blank" href="https://en.wikipedia.org/wiki/Hash_function#Deterministic">deterministic</a>, which is a fancy way for saying that identical inputs will generate identical outputs when passed into the function. So, deterministic means - if I pass in the string "Code" (case sensitive) and the function generates a hash of 11002, then every time I pass in "Code" it must generate "11002" as an integer. And if I pass in "code" it will generate a different number (consistently).</p>
<p>Sometimes the hashing function can generate the same hash for more than one input - this is not the end of the world and there are ways to deal with it. In fact it becomes more likely the more the range of unique inputs are. But when more than one input deterministically generates the same output, it's called a "collision".</p>
<p>With this in firmly in mind, let's apply it to routing and directed requests to servers. Let's say you have 5 servers to allocate loads across. An easy to understand method would be to hash incoming requests (maybe by IP address, or some client detail), and then generate hashes for each request. Then you apply the modulo operator to that hash, where the right operand is the number of servers.</p>
<p>For example, this is what your load balancers' pseudo code could look like:</p>
<pre><code class="lang-javascript">
request#<span class="hljs-number">1</span> =&gt; hashes to <span class="hljs-number">34</span>
request#<span class="hljs-number">2</span> =&gt; hashes to <span class="hljs-number">23</span>
request#<span class="hljs-number">3</span> =&gt; hashes to <span class="hljs-number">30</span>
request#<span class="hljs-number">4</span> =&gt; hashes to <span class="hljs-number">14</span>

<span class="hljs-comment">// You have 5 servers =&gt; [Server A, Server B ,Server C ,Server D ,Server E]</span>

<span class="hljs-comment">// so modulo 5 for each request...</span>

request#<span class="hljs-number">1</span> =&gt; hashes to <span class="hljs-number">34</span> =&gt; <span class="hljs-number">34</span> % <span class="hljs-number">5</span> = <span class="hljs-number">4</span> =&gt; send <span class="hljs-built_in">this</span> request to servers[<span class="hljs-number">4</span>] =&gt; Server E

request#<span class="hljs-number">2</span> =&gt; hashes to <span class="hljs-number">23</span> =&gt; <span class="hljs-number">23</span> % <span class="hljs-number">5</span> = <span class="hljs-number">3</span> =&gt; send <span class="hljs-built_in">this</span> request to servers[<span class="hljs-number">3</span>] =&gt; Server D

request#<span class="hljs-number">3</span> =&gt; hashes to <span class="hljs-number">30</span> =&gt; <span class="hljs-number">30</span> % <span class="hljs-number">5</span> = <span class="hljs-number">0</span> =&gt; send <span class="hljs-built_in">this</span> request to  servers[<span class="hljs-number">0</span>] =&gt; Server A

request#<span class="hljs-number">4</span> =&gt; hashes to <span class="hljs-number">14</span> =&gt; <span class="hljs-number">14</span> % <span class="hljs-number">5</span> = <span class="hljs-number">4</span> =&gt; send <span class="hljs-built_in">this</span> request to servers[<span class="hljs-number">4</span>] =&gt; Server E
</code></pre>
<p>As you can see, the hashing function generates a spread of possible values, and when the modulo operator is applied it brings out a smaller range of numbers that map to the server number.</p>
<p>You will definitely get different requests that map to the same server, and that's fine, as long as there is "<a target="_blank" href="https://en.wikipedia.org/wiki/Hash_function#Uniformity">uniformity</a>" in the overall allocation to all the servers.</p>
<h3 id="heading-adding-servers-and-handling-failing-servers">Adding Servers, and Handling Failing Servers</h3>
<p>So - what happens if one of the servers that we are sending traffic to dies? The hashing function (refer to the pseudo code snippet above) still thinks there are 5 servers, and the mod operator generates a range from 0-4. But we only have 4 servers now that one has failed, and we are still sending it traffic. Oops.</p>
<p>Inversely, we could add a sixth server but that would <em>never</em> get any traffic because our mod operator is 5, and it will never yield a number that would include the newly added 6th server. Double oops.</p>
<pre><code class="lang-plaintext">// Let's add a 6th server
servers =&gt; [Server A, Server B ,Server C ,Server D ,Server E, Server F]

// let's change the modulo operand to 6
request#1 =&gt; hashes to 34 =&gt; 34 % 6 = 4 =&gt; send this request to servers[4] =&gt; Server E

request#2 =&gt; hashes to 23 =&gt; 23 % 6 = 5 =&gt; send this request to servers[5] =&gt; Server F

request#3 =&gt; hashes to 30 =&gt; 30 % 6 = 0 =&gt; send this request to  servers[0] =&gt; Server A

request#4 =&gt; hashes to 14 =&gt; 14 % 6 = 2 =&gt; send this request to servers[2] =&gt; Server C
</code></pre>
<p>We note that the server number after applying the mod changes (though, in this example, <em>not</em> for request#1 and request#3 - but that is just because in this specific case the numbers worked out that way).</p>
<p>In effect, the result is that half the requests (could be more in other examples!) are now being routed to new servers altogether, and we lose the benefits of previously cached data on the servers.</p>
<p>For example, request#4 used to go to Server E, but now goes to Server C. All the cached data relating to request#4 sitting on Server E is of no use since the request is now going to Server C. You can calculate a similar problem for where one of your servers dies, but the mod function keeps sending it requests.</p>
<p>It sounds minor in this tiny system. But on a very large scale system this is a poor outcome. #SystemDesignFail.</p>
<p>So clearly, a simple hashing-to-allocate system does not scale or handle failures well.</p>
<h3 id="heading-a-popular-solution-consistent-hashing">A popular solution - consistent hashing</h3>
<p>Unfortunately this is the part where I feel word descriptions will not be enough. Consistent hashing is best understood visually. But the purpose of this post so far is to give you an intuition around the problem, what it is, why it arises, and what the shortcomings in a basic solution might be. Keep that firmly in mind.</p>
<p>The key problem with naive hashing, as we discussed, is that when (A) a server fails, traffic still gets routed to it, and (B) you add a new server, the allocations can get substantially changed, thus losing the benefits of previous caches.</p>
<p>There are two very important things to keep in mind when digging into consistent hashing:</p>
<ol>
<li><p>Consistent hashing <em>does not eliminate the problems</em>, especially B. But it does reduce the problems a lot. At first you might wonder what the big deal is in consistent hashing, as the underlying downside still exists - yes, but to a much smaller extent, and that itself is a valuable improvement in very large scale systems.</p>
</li>
<li><p>Consistent hashing applies a hash function to incoming requests <em>and the servers</em>. The resulting outputs therefore fall in a set range (continuum) of values. This detail is very important.</p>
</li>
</ol>
<p>Please keep these in mind as you watch the below recommended video that explains consistent hashing, as otherwise its benefits may not be obvious.</p>
<p>I strongly recommend this video as it embeds these principles without burdening you with too much detail.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/tHEyzVbl4bg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>If you're having a little trouble really understanding why this strategy is important in load balancing, I suggest you take a break, then return to the <a class="post-section-overview" href="#load-balancing">load balancing section</a> and then re-read this again. It's not uncommon for all this to feel very abstract unless you've directly encountered the problem in your work!</p>
<h2 id="heading-section-8-databases">Section 8: Databases</h2>
<p>We briefly <a class="post-section-overview" href="#storage-latency-throughput">considered</a> that there are different types of storage solutions (databases) designed to suit a number of different use-cases, and some are more specialized for certain tasks than others. At a very high level though, databases can be categorized into two types: Relational and Non-Relational.</p>
<h3 id="heading-relational-databases">Relational Databases</h3>
<p>A <a target="_blank" href="https://en.wikipedia.org/wiki/Relational_database"><strong>relational database</strong></a> is one that has strictly enforced relationships between things stored in the database. These relationships are typically made possible by requiring the database to represented each such thing (called the "entity") as a structured table - with zero or more rows ("records", "entries") and and one or more columns ("attributes, "fields").</p>
<p>By forcing such a structure on an entity, we can ensure that each item/entry/record has the right data to go with it. It makes for better consistency and the ability to make tight relationships between the entities.</p>
<p>You can see this structure in the table recording "Baby" (entity) data below. Each record ("entry) in the table has 4 fields, which represent data relating to that baby. This is a classic relational database structure (and a formalized entity structure is called a <a target="_blank" href="https://en.wikipedia.org/wiki/Database_schema">schema</a>).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-46.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>source:</em> <a target="_blank" href="https://web.stanford.edu/class/cs101/table-1-data.html"><em>https://web.stanford.edu/class/cs101/table-1-data.html</em></a></p>
<p>So the key feature to understand about relational databases is that they are highly structured, and impose structure on all the entities. This structure in enforced by ensuring that data added to the table conforms to that structure. Adding a height field to the table when its schema doesn't allow for it will not be permitted.</p>
<p>Most relational databases support a database querying language called SQL - <a target="_blank" href="https://en.wikipedia.org/wiki/SQL">Structured Query Language</a>. This is a language specifically designed to interact with the contents of a structured (relational) database. The two concepts are quite tightly coupled, so much so that people often referred to a relational database as a "SQL database" (and sometimes pronounced as "sequel" database).</p>
<p>In general, it is considered that SQL (relational) databases support more complex queries (combining different fields and filters and conditions) than non-relational databases. The database itself handles these queries and sends back matching results.</p>
<p>Many people who are SQL database fans argue that without that function, you would have to fetch <em>all</em> the data and then have the server or the client load that data "<a class="post-section-overview" href="#storage-latency-throughput">in memory</a>" and apply the filtering conditions - which is OK for small sets of data but for a large, complex dataset, with millions of records and rows, that would badly affect performance. However, this is not always the case, as we will see when we learn about NoSQL databases.</p>
<p>A common and much-loved example of a relational database is the <a target="_blank" href="https://en.wikipedia.org/wiki/PostgreSQL">PostgreSQL</a> (often called "Postgres") database.</p>
<h3 id="heading-acid">ACID</h3>
<p>ACID transactions are a set of features that describe the transactions that a good relational database will support. <a target="_blank" href="https://en.wikipedia.org/wiki/ACID">ACID = "Atomic, Consistent, Isolation, Durable"</a>. A transaction is an interaction with a database, typically read or write operations.</p>
<p><strong>Atomicity</strong> requires that when a single transaction comprises of more than one operation, then the database must guarantee that if one operation fails the <em>entire</em> transaction (all operations) also fail. It's "all or nothing". That way if the transaction succeeds, then on completion you know that all the sub-operations completed successfully, and if an operation fails, then you know that all the operations that went with it failed.</p>
<p>For example if a single transaction involved reading from two tables and writing to three, then if any one of those individual operations fails the entire transaction fails. This means that none of those individual operations should complete. You would not want even 1 out of the 3 write transactions to work - that would "dirty" the data in your databases!</p>
<p><strong>Consistency</strong> requires that each transaction in a database is valid according to the database's defined rules, and when the database changes state (some information has changed), such change is valid and does not corrupt the data. Each transaction moves the database from one <em>valid</em> state to another <em>valid</em> state. Consistency can be thought of as the following: every "read" operation receives the most recent "write" operation results.</p>
<p><strong>Isolation</strong> means that you can "concurrently" (at the same time) run multiple transactions on a database, but the database will end up with a state that looks as though each operation had been run serially ( in a sequence, like a queue of operations). I personally think "Isolation" is not a very descriptive term for the concept, but I guess ACCD is less easy to say than ACID...</p>
<p><strong>Durability</strong> is the promise that once the data is stored in the database, it will remain so. It will be "<a class="post-section-overview" href="#heading-section-2-storage-latency-amp-throughput">persistent</a>" - stored on disk and not in "memory".</p>
<h3 id="heading-non-relational-databases">Non-relational databases</h3>
<p>In contrast, a <strong>non-relational database</strong> has a less rigid, or, put another way, a more flexible structure to its data. The data typically is presented as "key-value" pairs. A simple way of representing this would be as an array (list) of "key-value" pair objects, for example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// baby names</span>
[
    { 
        <span class="hljs-attr">name</span>: <span class="hljs-string">"Jacob"</span>,
        <span class="hljs-attr">rank</span>: ##,
        <span class="hljs-attr">gender</span>: <span class="hljs-string">"M"</span>,
        <span class="hljs-attr">year</span>: ####
    },
    { 
        <span class="hljs-attr">name</span>: <span class="hljs-string">"Isabella"</span>,
        <span class="hljs-attr">rank</span>: ##,
        <span class="hljs-attr">gender</span>: <span class="hljs-string">"F"</span>,
        <span class="hljs-attr">year</span>: ####
    },
    {
      <span class="hljs-comment">//...</span>
    },

    <span class="hljs-comment">// ...</span>
]
</code></pre>
<p>Non relational databases are also referred to as "NoSQL" databases, and offer benefits when you do not want or need to have consistently structured data.</p>
<p>Similar to the ACID properties, NoSQL database properties are sometimes referred to as BASE:</p>
<p><strong>Basically Available</strong> which states that the system guarantees availability</p>
<p><strong>Soft State</strong> means the state of the system may change over time, even without input</p>
<p><strong>Eventual Consistency</strong> states that the system will become consistent over a (very short) period of time unless other inputs are received.</p>
<p>Since, at their core, these databases hold data in a hash-table-like structure, they are extremely fast, simple and easy to use, and are perfect for use cases like caching, environment variables, configuration files and session state etc. This flexibility makes them perfect for using in memory (e.g. <a target="_blank" href="https://en.wikipedia.org/wiki/Memcached">Memcached</a>) and also in persistent storage (e.g. <a target="_blank" href="https://en.wikipedia.org/wiki/Amazon_DynamoDB">DynamoDb</a>).</p>
<p>There are other "JSON-like" databases called document databases like the well-loved <a target="_blank" href="https://www.mongodb.com/document-databases">MongoDb</a>, and at the core these are also "key-value" stores.</p>
<h3 id="heading-database-indexing">Database Indexing</h3>
<p>This is a complicated topic so I will simply skim the surface for the purpose of giving you a high level overview of what you need for systems design interviews.</p>
<p>Imagine a database table with 100 million rows. This table is used mainly to look up one or two values in each record. To retrieve the values for a specific row you would need to iterate over the table. If it's the very last record that would take a long time!</p>
<p>Indexing is a way of short cutting to the record that has matching values more efficiently than going through each row. Indexes are typically a data structure that is added to the database that is designed to facilitate fast searching of the database for those <em>specific</em> attributes (fields).</p>
<p>So if the census bureau has 120 million records with names and ages, and you most often need to retrieve lists of people belonging to an age group, then you would index that database on the age attribute.</p>
<p>Indexing is core to relational databases and is also widely offered on non-relational databases. The benefits of indexing are thus available in theory for both types of databases, and this is hugely beneficial to optimise lookup times.</p>
<h3 id="heading-replication-and-sharding">Replication and Sharding</h3>
<p>While these may sound like things out of a bio-terrorism movie, you're more likely to hear them everyday in the context of database scaling.</p>
<p>Replication means to duplicate (make copies of, replicate) your database. You may remember that when we discussed <a class="post-section-overview" href="#system-availability">availability</a>.</p>
<p>We had considered the benefits of having redundancy in a system to maintain high availability. Replication ensures redundancy in the database if one goes down. But it also raises the question of how to synchronize data across the replicas, since they're meant to have the same data. Replication on write and update operations to a database can happen synchronously (at the same time as the changes to the main database) or asynchronously .</p>
<p>The acceptable time interval between synchronising the main and a replica database really depends on your needs - if you really need state between the two databases to be consistent then the replication needs to be rapid. You also want to ensure that if the write operation to the replica fails, the write operation to the main database also fails (atomicity).</p>
<p>But what do you do when you've got so much data that simply replicating it may solve availability issues but does not solve throughput and latency issues (speed)?</p>
<p>At this point you may want to consider "chunking down" your data, into "shards". Some people also call this partitioning your data (which is different from partitioning your hard drive!).</p>
<p>Sharding data breaks your huge database into smaller databases. You can work out how you want to shard your data depending on its structure. It could be as simple as every 5 million rows are saved in a different shard, or go for other strategies that best fit your data, needs and locations served.</p>
<h2 id="heading-section-9-leader-election">Section 9: Leader Election</h2>
<p>Let's move back to servers again for a slightly more advanced topic. We already understand the principle of <a class="post-section-overview" href="#heading-section-3-system-availability">Availability</a>, and how redundancy is one way to increase availability. We have also walked through some practical considerations when handling the <a class="post-section-overview" href="#heading-section-6-load-balancing">routing of requests</a> to clusters of redundant servers.</p>
<p>But sometimes, with this kind of setup where multiple servers are doing much the same thing, there can arise situations where you need only one server to take the lead.</p>
<p>For example, you want to ensure that only one server is given the responsibility for updating some third party API because multiple updates from different servers could cause issues or run up costs on the third-party's side.</p>
<p>In this case you need to choose that primary server to delegate this update responsibility to. That process is called <a target="_blank" href="https://en.wikipedia.org/wiki/Leader_election">leader election</a>.</p>
<p>When multiple servers are in a cluster to provide redundancy, they could, amongst themselves, be configured to have one and only one leader. They would also detect when that leader server has failed, and appoint another one to take its place.</p>
<p>The principle is very simple, but the devil is in the details. The really tricky part is ensuring that the servers are "in sync" in terms of their data, state and operations.</p>
<p>There is always the risk that certain outages could result in one or two servers being disconnected from the others, for example. In that case, engineers end up using some of the underlying ideas that are used in blockchain to derive consensus values for the cluster of servers.</p>
<p>In other words, a <a target="_blank" href="https://en.wikipedia.org/wiki/Consensus_algorithm">consensus algorithm</a> is used to give all the servers an "agreed on" value that they can all rely on in their logic when identifying which server is the leader.</p>
<p>Leader Election is commonly implemented with software like <a target="_blank" href="https://etcd.io/">etcd</a>, which is a store of key-value pairs that offers both high availability <em>and</em> strong consistency (which is valuable and an unusual combination) by using Leader Election itself and using a consensus algorithm.</p>
<p>So engineers can rely on etcd's own leader election architecture to produce leader election in their systems. This is done by storing in a service like etcd, a key-value pair that represents the current leader.</p>
<p>Since etcd is highly available <em>and</em> strongly consistent, that key-value pair can always be relied on by your system to contain the final "source of truth" server in your cluster is the current elected leader.</p>
<h2 id="heading-section-10-polling-streaming-sockets">Section 10: Polling, Streaming, Sockets</h2>
<p>In the modern age of continuous updates, push notifications, streaming content and real-time data, it is important to grasp the basic principles that underpin these technologies. To have data in your application updated regularly or instantly requires the use of one of the two following approaches.</p>
<h3 id="heading-polling">Polling</h3>
<p>This one is simple. If you look at the <a target="_blank" href="https://en.wikipedia.org/wiki/Polling_(computer_science)">wikipedia entry</a> you may find it a bit intense. So instead take a look at its dictionary meaning, especially in the context of computer science. Keep that simple fundamental in mind.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-14-at-10.25.44-am.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Polling is simply having your client check on a server by sending it a network request and asking for updated data. These requests are typically made at regular intervals like 5 seconds, 15 seconds, 1 minute or any other interval required by your use case.</p>
<p>Polling every few seconds is still not quite the same as real-time, and also comes with the following downsides, especially if you have a million plus simultaneous users:</p>
<ul>
<li><p>almost-constant network requests (not great for the client)</p>
</li>
<li><p>almost constant inbound requests (not great for the server loads - 1 million+ requests per second!)</p>
</li>
</ul>
<p>So polling rapidly is not really efficient or performant, and polling is best used in circumstances when small gaps in data updates is not a problem for your application.</p>
<p>For example, if you built an Uber clone, you may have the driver-side app send driver location data every 5 seconds, and your rider-side app poll for the driver's location every 5 seconds.</p>
<h3 id="heading-streaming">Streaming</h3>
<p>Streaming solves the constant polling problem. If constantly hitting the server is necessary, then it's better to use something called <a target="_blank" href="https://en.wikipedia.org/wiki/WebSocket">web-sockets</a>.</p>
<p>This is a network communication protocol that is designed to work over TCP. It opens a two-way dedicated channel (socket) between a client and server, kind of like an open hotline between two endpoints.</p>
<p>Unlike the usual TCP/IP communication, these sockets are "long-lived" so that its a single request to the server that opens up this hotline for the two-way transfer of data, rather than multiple separate requests. By long-lived, we meant that the socket connection between the machines will last until either side closes it, or the network drops.</p>
<p>You may remember from our discussion on IP, TCP and HTTP that these operate by sending "packets" of data, for each request-response cycle. Web-sockets mean that there is a single request-response interaction (not a cycle really if you think about it!) and that opens up the channel through which two-data is sent in a "stream".</p>
<p>The big difference with polling and all "regular" IP based communication is that whereas polling has the client making requests to the server for data at regular intervals ("pulling" data), in streaming, the client is "on standby" waiting for the server to "push" some data its way. The server will send out data when it changes, and the client is always listening for that. Hence, if the data change is constant, then it becomes a "stream", which may be better for what the user needs.</p>
<p>For example, while using <a target="_blank" href="https://www.freecodecamp.org/news/p/51a1d601-c57e-48cf-8f8d-9bb1c333d64d/repl.it">collaborative coding IDEs</a>, when either user types something, it can show up on the other, and this is done via web-sockets because you want to have real-time collaboration. It would suck if what I typed showed up on your screen after you tried to type the same thing or after 3 minutes of you waiting wondering what I was doing!</p>
<p>Or think of online, multiplayer games - that is a perfect use case for streaming game data between players!</p>
<p>To conclude, the use case determines the choice between polling and streaming. In general, you want to stream if your data is "real-time", and if it's OK to have a lag (as little as 15 seconds is still a lag) then polling may be a good option. But it all depends on how many simultaneous users you have and whether they expect the data to be instantaneous. A commonly used example of a streaming service is <a target="_blank" href="https://en.wikipedia.org/wiki/Apache_Kafka">Apache Kafka</a>.</p>
<h2 id="heading-section-11-endpoint-protection">Section 11: Endpoint Protection</h2>
<p>When you build large scale systems it becomes important to protect your system from too many operations, where such operations are not actually needed to use the system. Now that sounds very abstract. But think of this - how many times have you clicked furiously on a button thinking it's going to make the system more responsive? Imagine if each one of those button clicks pinged a server and the server tried to process them all! If the throughput of the system is low for some reason (say a server was struggling under unusual load) then each of those clicks would have made the system even slower because it has to process them all!</p>
<p>Sometimes it's not even about protecting the system. Sometimes you want to limit the operations because that is part of your service. For example, you may have used free tiers on third-party API services where you're only allowed to make 20 requests per 30 minute interval. if you make 21 or 300 requests in a 30 minute interval, after the first 20, that server will stop processing your requests.</p>
<p>That is called rate-limiting. Using rate-limiting, a server can limit the number of operations attempted by a client in a given window of time. A rate-limit can be calculated on users, requests, times, payloads, or other things. Typically, once the limit is exceeded in a time window, for the rest of that window the server will return an error.</p>
<p>Ok, now you might think that endpoint "protection" is an exaggeration. You're just restricting the users ability to get something out of the endpoint. True, but it is also protection when the user (client) is malicious - like say a bot that is smashing your endpoint. Why would that happen? Because flooding a server with more requests than it can handle is a strategy used by malicious folks to bring down that server, which effectively brings down that service. That's exactly what a <a target="_blank" href="https://en.wikipedia.org/wiki/Denial-of-service_attack">Denial of Service (D0S) attack</a> is.</p>
<p>While DoS attacks can be defended against in this way, rate-limiting by itself won't protect you from a sophisticated version of a DoS attack - a <em>distributed</em> DoS. Here distribution simply means that the attack is coming from multiple clients that seem unrelated and there is no real way to identify them as being controlled by the single malicious agent. Other methods need to be used to protect against such coordinated, distributed attacks.</p>
<p>But rate-limiting is useful and popular anyway, for less scary use-cases, like the API restriction one I mentioned. Given how rate-limiting works, since the server has to first check the limit conditions and enforce them if necessary, you need to think about what kind of data structure and database you'd want to use to make those checks super fast, so that you don't slow down processing the request if it's within allowed limits. Also, if you have it in-memory within the server itself, then you need to be able to guarantee that all requests from a given client will come to that server so that it can enforce the limits properly. To handle situations like this it's popular to use a separate <a target="_blank" href="https://en.wikipedia.org/wiki/Redis">Redis service</a> that sits outside the server, but holds the user's details in-memory, and can quickly determine whether a user is within their permitted limits.</p>
<p>Rate limiting can be made as complicated as the rules you want to enforce, but the above section should cover the fundamentals and most common use-cases.</p>
<h2 id="heading-section-12-messaging-amp-pub-sub">Section 12: Messaging &amp; Pub-Sub</h2>
<p>When you design and build large-scale and <a target="_blank" href="https://blog.stackpath.com/distributed-system/">distributed systems</a>, for that system to work cohesively and smoothly, it is important to exchange information between the components and services that make up the system. But as we have seen before, systems that rely on networks suffer from the same weakness as networks - they are fragile. Networks fail and its not an infrequent occurrence. When networks fail, components in the system are not able to communicate and may degrade the system (best case) or cause the system to fail altogether (worst case). So distributed systems need robust mechanisms to ensure that the communication continues or recovers where it left off, even if there is an "arbitrary partition" (i.e. failure) between components in the system.</p>
<p>Imagine, as an example, that you're booking airline tickets. You get a good price, choose your seats, confirm the booking and you've even paid using your credit card. Now you're waiting for your ticket PDF to arrive in your inbox. You wait, and wait, and it never comes. Somewhere, there was a system failure that didn't get handled or recover properly. A booking system will often connect with airline and pricing APIs to handle the actual flight selection, fare summary, date and time of flight etc. All that gets done while you click through the site's booking UI. But it doesn't have to send you the PDF of the tickets until a few minutes later. Instead the UI can simply confirm that your booking is done, and you can expect the tickets in your inbox shortly. That's a reasonable and common user experience for bookings because the moment of paying and the receipt of the tickets does not have to be simultaneous - the two events can be asynchronous. Such a system would need messaging to ensure that the service (server endpoint) that asynchronously generates the PDF gets notified of a confirmed, paid-for booking, and all the details, and then the PDF can be auto-generated and emailed to you. But if that messaging system fails, the email service would never know about your booking and no ticket would get generated.</p>
<p><strong>Publisher / Subscriber Messaging</strong></p>
<p>This is a very popular paradigm (model) for messaging. The key concept is that publishers 'publish' a message and a subscriber subscribes to messages. To give greater granularity, messages can belong to a certain "topic" which is like a category. These topics are like dedicated "channels" or pipes, where each pipe exclusives handles messages belonging to a specific topic. Subscribers choose which topic they want to subscribe to and get notified of messages in that topic. The advantage of this system is that the publisher and the subscriber can be completely de-coupled - i.e. they don't need to know about each other. The publisher announces, and the subscriber listens for announcements for topics that it is on the lookout for.</p>
<p>A server is often the publisher of messages and there are usually several topics (channels) that get published to. The consumer of a specific topic subscribes to those topics. There is no direct communication between the server (publisher) and the subscriber (could be another server). The only interaction is between publisher and topic, and topic and subscriber.</p>
<p>The messages in the topic are just data that needs to be communicated, and can take on whatever forms you need. So that gives you four players in Pub/Sub: Publisher, Subscriber, Topics and Messages.</p>
<h3 id="heading-better-than-a-database">Better than a database</h3>
<p>So why bother with this? Why not just persist all data to a database and consume it directly from there? Well, you need a system to queue up the messages because each message corresponds to a task that needs to be done based on that message's data. So in our ticketing example, if 100 people make a booking in 35 minutes, putting all that in the database doesn't solve the problem of emailing those 100 people. It just stores a 100 transactions. Pub/Sub systems handle the communication, the task sequencing <em>and</em> the messages get persisted in a database. So the system can offer useful features like "at least once" delivery (messages won't be lost), persistent storage, ordering of messages, "try-again", "re-playability" of messages etc. Without this system, just storing the messages in the database will not help you ensure that the message gets delivered (consumed) and acted upon to successfully complete the task.</p>
<p>Sometimes the same message may get consumed more than once by a subscriber - typically because the network dropped out momentarily, and though the subscriber consumed the message, it didn't let the publisher know. So the publisher will simply re-send it to the subscriber. That's why the guarantee is "at least once" and not "once and only once". This is unavoidable in distributed systems because networks are inherently unreliable. This can raise complications, where the message triggers an operation on the subscriber's side, and that operation could change things in the database (change state in the overall application). What if a single operation gets repeated multiple times, and each time the application's state changes?</p>
<h3 id="heading-controlling-outcomes-one-or-many-outcomes">Controlling Outcomes - one or many outcomes?</h3>
<p>The solution to this new problem is called idempotency - which is a concept that is important but not intuitive to grasp the first few times you examine it. It is a concept that can appear complex (especially if you read the wikipedia entry), so for the current purpose, here is a user-friendly simplification <a target="_blank" href="https://stackoverflow.com/questions/1077412/what-is-an-idempotent-operation">from StackOverflow</a>:</p>
<blockquote>
<p><em>In computing, an idempotent operation is one that has no additional effect if it is called more than once with the same input parameters.</em></p>
</blockquote>
<p>So when a subscriber processes a message two or three times, the overall state of the application is exactly what it was after the message was processed the <em>first</em> time. If, for example, at the end of booking your flight tickets and after you entered your credit card details, you clicked on "Pay Now" three times because the system was slow ... you would not want to pay 3X the ticket price right? You need idempotency to ensure that each click after the <em>first</em> one doesn't make another purchase and charge your credit card more than once. In contrast, you can post an identical comment on your best friend's newsfeed N number of times. They will all show up as separate comments, and apart from being annoying, that's not actually <em>wrong.</em> Another example is offering "claps" on Medium posts - each clap is meant to increment the number of claps, not be one and only one clap. These latter two examples do not require idempotency, but the payment example does.</p>
<p>There are many flavours of messaging systems, and the choice of system is driven by the use-case to be solved for. Often, people will refer to "event based" architecture which means that the system relies on messages about "events" (like paying for tickets) to process operations (like emailing the ticket). The really commonly talked about services are Apache Kafka, RabbitMQ, Google Cloud Pub/Sub, AWS SNS/SQS.</p>
<h2 id="heading-section-13-smaller-essentials">Section 13: Smaller Essentials</h2>
<h3 id="heading-logging">Logging</h3>
<p>Over time your system will collect a lot of data. Most of this data is extremely useful. It can give you a view of the health of your system, its performance and problems. It can also give you valuable insight into who uses your system, how they use it, how often, which parts get used more or less, and so on.</p>
<p>This data is valuable for analytics, performance optimization and product improvement. It is also extremely valuable for debugging, not just when you log to your console during development, but in actually hunting down bugs in your test and production environments. So logs help in traceability and audits too.</p>
<p>The key trick to remember when logging is to view it as a sequence of consecutive events, which means the data becomes time-series data, and the tools and databases you use should be specifically designed to help work with that kind of data.</p>
<h3 id="heading-monitoring">Monitoring</h3>
<p>This is the next steps after logging. It answers the question of "What do I do with all that logging data?". You monitor and analyze it. You build or use tools and services that parse through that data and present you with dashboards or charts or other ways of making sense of that data in a human-readable way.</p>
<p>By storing the data in a specialized database designed to handle this kind of data (time-series data) you can plug in other tools that are built with that data structure and intention in mind.</p>
<h3 id="heading-alerting">Alerting</h3>
<p>When you are actively monitoring you should also put a system in place to alert you of significant events. Just like having an alert for stock prices going over a certain ceiling or below a certain threshold, certain metrics that you're watching may warrant an alert being sent if they go too high or too low. Response times (latency) or errors and failures are good ones to set up alerting for if they go above an "acceptable" level.</p>
<p>The key to good logging and monitoring is to ensure your data is fairly consistent over time, as working with inconsistent data could result in missing fields that then break the analytical tools or reduce the benefits of the logging.</p>
<h2 id="heading-resources">Resources</h2>
<p>As promised, some useful resources are as follows:</p>
<ol>
<li><p>A fantastic <a target="_blank" href="https://github.com/donnemartin/system-design-primer">Github repo</a> full of concepts, diagrams and study prep</p>
</li>
<li><p>Tushar Roy's introduction to <a target="_blank" href="https://www.youtube.com/watch?v=UzLMhqg3_Wc">Systems Design</a></p>
</li>
<li><p>Gaurav Sen's <a target="_blank" href="https://www.youtube.com/watch?v=quLrc3PbuIw&amp;list=PLMCXHnjXnTnvo6alSjVkgxV-VH6EPyvoX">YouTube playlist</a></p>
</li>
<li><p><a target="_blank" href="https://www.sitepoint.com/sql-vs-nosql-differences/">SQL vs NoSQL</a></p>
</li>
</ol>
<p>I hope you enjoyed this long-form guide!</p>
<p>If you would like to learn more about my journey from lawyer to software engineer, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a> and also <a target="_blank" href="https://lessonsfromaquitter.com/episode207/">Episode 207</a> of "Lessons from a Quitter". These provide the blueprint for my career change.</p>
<p>If you are interested in teaching yourself to code, changing careers and becoming a professional coder, or <a target="_blank" href="https://www.freecodecamp.org/news/non-technical-and-looking-for-a-technical-co-founder-2c212c01d6da/">becoming your own technical co-founder</a>, please reach out <a target="_blank" href="http://linktree.com/zubinpratap">here</a>. You can also check out my free webinar on <a target="_blank" href="http://futurecoderstraining.com/">Career Change to Code</a> if that is what you're dreaming of.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Blockchain and how does it work? ]]>
                </title>
                <description>
                    <![CDATA[ If you're interested in technology, there's a good chance you’ve probably heard the terms Bitcoin, Crypto, Ethereum, or even "distributed, decentralized ledgers." You’ve probably heard people talk about cryptocurrency and encryption algorithms, about... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-blockchain-and-how-does-it-work/</link>
                <guid isPermaLink="false">66d461de2472e5ed2fa07bdb</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Mon, 10 Feb 2020 23:48:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9ca4740569d1a4ca335e.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you're interested in technology, there's a good chance you’ve probably heard the terms Bitcoin, Crypto, Ethereum, or even "distributed, decentralized ledgers."</p>
<p>You’ve probably heard people talk about cryptocurrency and encryption algorithms, about the end of "intermediaries" and so on.</p>
<p>It's easy to assume that cryptocurrency (eg: Bitcoin, Ripple, Ethereum, Litecoin, etc.) are the same as blockchain. They're not.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Cryptocurrency">Cryptocurrencies</a> are a clever application of a much cleverer technology – <a target="_blank" href="http://en.wikipedia.org/wiki/Blockchain_(database)">the Blockchain</a>.</p>
<p>In this post, I will cover some of the basic concepts of the blockchain so you understand what it is, how it must be conceptualized, and what can be built on top of it.</p>
<p>But as with all things, they make more sense if you understand <em>why</em> they were invented, before you get into what they do. That context will help you grasp what problem the blockchain was designed to solve.</p>
<h2 id="heading-why-use-blockchain">Why use blockchain?</h2>
<p>Great question. So glad you asked. Let's sit back and do a small thought experiment.</p>
<p>What happens if you and your best friend <em>independently</em> and separately conduct the same petition campaign? Let’s say it’s for the “Free the Hamsters” cause.</p>
<p>Let's say you conduct it in an identical sequence across the same suburb, but come up with different sets of signatures on the petition. Which version of the signed petition is the “source of truth”?</p>
<p>You would need to trace back your separate trails, one signature at a time, to locate the <em>last</em> discrepancy. And then you'd have to work further back to identify the first result that diverged between your signature sheets. Prior to that root divergence, all other signatures on the two lists should match up.</p>
<p>You then know that prior to that divergence. Both lists are in accord, so those signatures represent the minimum number of people who signed to support freeing the hamsters.</p>
<p>While that may work well for hamsters and small suburban surveys, it doesn’t work so well in the digital world. Or voting, banking, financial transactions, transferring land title, discharging contractual obligations etc. You need independent and “trusted third parties” to verify a chain of events, and solemnly reassure you that the "chain of custody" was unbroken.</p>
<p>A "chain of custody" can sometimes also be called the "provenance" – they both mean the same thing: the sequence of historical events concerning the data in question.</p>
<p>That’s why you have governments having the final say on your identity, and votes need to be physically counted and recounted by hundreds of volunteers, and clerks in dingy offices maintain ledgers and certificates to confirm whether or not you own your farm/white picket-fenced bungalow.</p>
<p>That is why you need financial intermediaries to ensure that when you buy your collector's item Darth Vader doll, using a credit card, the money (value) is “removed” from your account and “put into” to the seller’s account.</p>
<p>This is technically called the “<a target="_blank" href="https://en.wikipedia.org/wiki/Double-spending">double spending problem</a>” – how do you ensure that you’re not spending the same money twice? Without someone to do this, you could spend money and at the same time continue to hold on to that money.</p>
<p>So it’s a big problem really – modern life requires that we rely on, trust in and pay for “trusted” third party intermediaries to ensure that value (money) does actually digitally “change hands”. That is why Visa and MasterCard exist, and why PayPal and others link with your bank accounts.</p>
<blockquote>
<p>At the heart of the blockchain's why is this problem: how do you know a sequence of events has not been tampered with to alter the current state?</p>
</blockquote>
<p>This is where the blockchain fits in. Clear, so far?</p>
<h2 id="heading-how-blockchain-works">How Blockchain works</h2>
<p>For the sake of communicating a concept with simplicity, I may take liberties with some of the technical, under-the-hood aspects of this technology. My aim is to get you to understand what it is and have a mental model of how it works. For that, I may need to be a little loose with precision in order to improve the odds of comprehension, especially for non-native English speakers.</p>
<p>It is essential to remember that the blockchain is a technology – mathematically complex software code to be specific. And Bitcoin (or Ethereum or any of the other cryptos on offer) are just applications of that technology.</p>
<p>So the key principles are:</p>
<ul>
<li><p>Blockchains are ‘mined” (produced through the expenditure of effort, like in gold mining) by powerful and resource-hungry computers – called nodes, that are on the same network.</p>
</li>
<li><p>Chains of digitally encrypted and timestamped records of transactions are lumped into “blocks”, which are maintained on a “ledger” by each node. As transactions are added to a block, and blocks are linked together linearly and chronologically as "chains". Then the entire record/ledger gets synchronised across the network of nodes such that all the block "chains" on the nodes should tell an identical story of the history of any given transaction. Thus we get "block + chain = blockchain". It's a long, complicated linked list.</p>
</li>
<li><p>Each block in a chain has its own id - a cryptographic hash that is unique and specific to each block. That hash is also stored in the <em>next</em> block in the chain, causing a link. A block can store thousands of transactions and the tiniest change in that block's data would result in a new hash. So if a hash changes but the next block has a different hash, then we know some data in the previous block was tampered with.</p>
</li>
<li><p>As hundreds become thousands of nodes (and more are added all the time), each node has to “agree” on the history of the blocks/ledger – this is called "critical consensus". One of the ways in which consensus is achieved is through the cryptographic hash we talked about earlier.</p>
</li>
<li><p>Where there are discrepancies in the ledger (for example the hash of a block doesn't match with the next block's reference to the previous block's hash), the ledger with the longest chain of valid transactions embedded will be the “correct” one – the source of truth. Any nodes working on other (shorter versions) of the chain switch to the longer one. This maintains the critical consensus (this bit is hugely oversimplified, but sufficient for now).</p>
</li>
<li><p>Any naughty interception or change to one ledger (again, for example, where a block's hash doesn't tally) would immediately create a discrepancy with all the other versions. It would also have a shorter block “history” to corroborate it, which makes that tampered version a suspicious character in the blockchain network where length matters (ahem).</p>
</li>
<li><p>Replicating that discrepancy across <em>all</em> the versions of the ledger – the entire blockchain network – is such a huge task that it is computationally impractical, and would only happen if the bad guys suddenly had control over the <em>majority</em> of the nodes mining blockchain and changed them all rather rapidly. This sort of coordinated attack on the majority of the nodes on the network is often called the <a target="_blank" href="https://en.bitcoin.it/wiki/Majority_attack">51% attack</a>.</p>
</li>
</ul>
<p>Interestingly, Satoshi Nakamoto says in the <a target="_blank" href="http://bitcoin.org/bitcoin.pdf">original Bitcoin white paper</a>,</p>
<blockquote>
<p>“<em>As such, the verification is reliable as long as honest nodes control the network, but is more vulnerable if the network is overpowered by an attacker.</em>”</p>
</blockquote>
<p>However, elsewhere <a target="_blank" href="http://en.wikipedia.org/wiki/Satoshi_Nakamoto">he/she/the organisation</a> (we don't know who "Satoshi" is) calmly points out that to modify past transactions in blocks, across the entire network of nodes, would require the attacker to re-do the chain of custody in those blocks, and all the blocks added after that. Then they'd have to run like mad to catch up with, and surpass, the work of nodes that aren’t under the bad guy’s control (so that they can re-write the ledger, so-to-speak).</p>
<p>And because of this, the “<em>probability of a slower attacker catching up diminishes exponentially as subsequent blocks are added</em>”.</p>
<p>The sheer programmatic complexity, pace and volume of nodal activities make it hard for counterfeiters/attackers to catch up with, let alone outrun, the new blocks mined constantly.</p>
<p>That does make sense. It’s like the lie you tell one family member about why you couldn’t attend their kid’s flute recital. And then you have to madly chase everyone else in the family and ensure you’ve told them all the same lie so that when the original person you’ve lied to brings it up, everyone is aware of this lie and plays along. Sounds exhausting.</p>
<p>To wrap up, the defining characteristic of a blockchain is that it is a distributed ledger across many, many nodes and it is extremely computationally intensive (expensive) to add nodes to that network.</p>
<p>Thus each ledger must be "aware" of all the transactions, and must have an agreed version (which will have the longest “chain of custody” behind it) across the entire network to which the next transaction will be added.</p>
<blockquote>
<p><em>As</em> <a target="_blank" href="http://bitcoin.org/bitcoin.pdf"><em>Satoshi Nakamoto declares</em></a> <em>in the original Bitcoin white paper, “ The only way to confirm the absence of a transaction is to be aware of all transactions.”</em></p>
</blockquote>
<p>Importantly, the blockchain "<a target="_blank" href="https://en.wikipedia.org/wiki/Disintermediation">dis-intermediates</a>" trust – so we don’t need to pay “trusted third parties” transaction fees for being trustworthy and keeping us, and the counter-parties we deal with, honest. The blockchain programmatically ensures truth (provenance) of the history of transaction in it.</p>
<h3 id="heading-so-why-should-we-care">So why should we care?</h3>
<p>Well, by getting rid of the need for “trusted intermediaries” any intermediary that charges a modest fee for giving us the gift of certainty needs to find a new job. And that impact banks who traditionally offer such assurance services.</p>
<p>It also means that we can program “<a target="_blank" href="https://en.wikipedia.org/wiki/Smart_contract">smart contracts</a>” between promisor and promisee that automatically recognise (digitally) whether that promise has been delivered or not.</p>
<p>This has enabled a truly tech savvy artist like <a target="_blank" href="http://fortune.com/2016/09/22/blockchain-music-disruption/">Imogen Heap to sell her music directly</a> to her listening public, and collect her dues directly from them rather than losing the bulk of earnings to record labels, managers and other “trusted intermediaries”.</p>
<p>It will likely change the way Intellectual Property is protected, accessed, shared, distributed, and developed on the internet.</p>
<p>It could even mean that Uber’s fleet of drivers transact directly with people who want a ride rather than rely on Uber to coordinate and control the flow of information and money.</p>
<p>It may mean that I could directly send you small amounts of money for virtually no fees (micro-transactions). It could mean that the millions of unbanked people in the world who have smartphones can start to transact well beyond their traditional physical-world boundaries.</p>
<p>Wonderfully enough, governments are looking beyond just cryptocurrency when it comes to deploying this technology – to <a target="_blank" href="http://www.redherring.com/startups/georgia-pilots-sweden-ponders-blockchain-future-europes-land-registries/">record land ownership</a>, <a target="_blank" href="http://dci.mit.edu/assets/papers/spielman_thesis.pdf">for example</a>.</p>
<p>In effect, we could create a world of true peer-to-peer digital transactions for the transfer of value that is distributed, horizontal, removes the need to rely on trust, and above all requires extraordinary computational power to tamper with. These transactions could be between people, machines and devices.</p>
<p>It could therefore offer a new security paradigm for the protection of data collected by and transferred through the “internet of things”.</p>
<p>I personally believe that the complexity of the modern world is obscured behind intuitive touchscreens. Blockchain technology will quickly become embedded in our technological universe without us being fully aware of it – just like we have been using yeast recombinant DNA for synthetic insulin production since the 1970s.</p>
<p>The changes and cost savings will be sweepingly referred to as technological changes, like that "interweby thing” or some other vague, all-inclusive phrase.</p>
<p>One catch: it'll work as long as we can trust that a "trust-less system" that is coded and engineered by humans (whom we trust?) will further the cause of trust-less-ness in an untrusting and untrustworthy world. You may need to read that sentence several times.</p>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>OK – you should now be reasonably aware of the basics of blockchain. But there is a lot more to learn if you're interested.</p>
<p>You can debate whether blockchain is useful or over-hyped, revolutionary or boring. But it's hard to ignore that it is pretty cool as a concept.</p>
<p>Here is a really fantastic video by Anders Brownworth that explains the whole thing with a mockup blockchain. I strongly recommend you watch it.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/_160oMzblY8" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>And as a learning exercise, you can build your own blockchain right in your browser or your command line. Here's a quick <a target="_blank" href="https://www.freecodecamp.org/news/how-does-blockchain-really-work-i-built-an-app-to-show-you-6b70cd4caf7d/">tutorial for how to build your own blockchain</a>.</p>
<p>If you have any comments about this article or think I could have explained parts of this better, Tweet at me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a></p>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript's try-catch hid my bugs! ]]>
                </title>
                <description>
                    <![CDATA[ Let me start by making one thing clear - JavaScript is a great language, and not to blame. I was totally to blame - my mental model of error handling was incomplete, and that caused the trouble. Hence, this post. But first, let me give you some conte... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascripts-try-catch-hid-my-bugs/</link>
                <guid isPermaLink="false">66d461d02472e5ed2fa07bd3</guid>
                
                    <category>
                        <![CDATA[ Code Quality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Functional Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Fri, 08 Nov 2019 14:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/thomas-smith-doI0mceCxfk-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Let me start by making one thing clear - JavaScript is a great language, and not to blame. I was totally to blame - my mental model of error handling was incomplete, and that caused the trouble. Hence, this post.</p>
<p>But first, let me give you some context. I was writing a bunch of code involving third party APIs (<a target="_blank" href="https://stripe.com/docs/billing/quickstart">Stripe's recurring billing and subscription APIs</a>, to be specific), and had written a wrapper class and some server route-handlers to respond to requests from the front-end web app. The entire application is React +TypeScript + Node, with a <a target="_blank" href="https://koajs.com/">Koa server</a>.</p>
<p>As part of this, I was trying to handle the following errors:</p>
<ol>
<li><p>Errors thrown by Stripe's API</p>
</li>
<li><p>Errors thrown by my wrapper class, especially when fetching user data from the database</p>
</li>
<li><p>Errors in route-handlers that arise from a combination of the above.</p>
</li>
</ol>
<p>During development, my most common errors were incomplete data in the server requests and incorrect data passed to Stripe.</p>
<p>To help you visualize the flow of data, let me give you some background on the server-side code. Typically this is what the function call chain looked like:</p>
<p><em>Route-Handler -&gt; Stripe Wrapper -&gt; Stripe API</em></p>
<p>The first function being called would be in the Route-Handler, then in the Stripe Wrapper class, inside which the Stripe API method would be called. So the call stack has Route-Handler at the bottom (first called function) and the Stripe API method on the top (last called function).</p>
<p>The problem was that I did not understand where to put my error handling. If I did not put an error handler in the server code, then node would crash (literally, exit execution!) and the front end would receive an error HTTP response (typically a HTTP <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500">5xx err0r</a>). So I put a few <code>try-catch</code> handlers inside the various methods being called, and added logging statements inside the <code>catch</code> block. That way I could debug the error by tracking the logs.</p>
<p>An example of the calling logic:</p>
<pre><code class="lang-javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">stripeAPI</span>(<span class="hljs-params">arg</span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'this is the first function'</span>)
    <span class="hljs-keyword">if</span>(!arg) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'no arg!'</span>)
    <span class="hljs-comment">// else</span>
    saveToDb()
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">stripeWrapper</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'this is the second function, about to call the first function'</span>)
    <span class="hljs-keyword">try</span>{
        stripeAPI()
    } <span class="hljs-keyword">catch</span>(err) {
<span class="hljs-comment">//         console.log(' this error will not bubble up to the first function that triggered the function calls!')</span>
    }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">routeHandler</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'this is the third  function, about to call the second function'</span>)
    stripeWrapper()
}


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callAll</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-keyword">try</span>{
       routeHandler() 
       <span class="hljs-keyword">return</span> <span class="hljs-string">'done'</span>
    } <span class="hljs-keyword">catch</span> (err){
       <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'error in callAll():'</span>, err)
       <span class="hljs-keyword">return</span> <span class="hljs-string">' not done '</span>
    }

}


callAll()
</code></pre>
<p>The problems?</p>
<ol>
<li><p>If I didn't log the error, I <em>lost</em> the error! In the above snippet, note that even though I've called <code>first()</code> without the required arguments, the error defined in the definition of <code>first</code> did not get thrown! Also, there is no <code>saveToDb()</code> method defined... and yet this was not caught! If you run this code above, you will see it returns 'done' - and you've got no idea that your database wasn't updated and something had gone wrong! ☠️☠️☠️</p>
</li>
<li><p>My console had way too many logs, repeating the same error. It also meant that in production, there was excessive logging... ?</p>
</li>
<li><p>The code looked ugly. Almost as ugly as my console.</p>
</li>
<li><p>Others who worked with code found it confusing and a debugging nightmare. ?</p>
</li>
</ol>
<p>None of these are good outcomes, and all are avoidable.</p>
<h2 id="heading-the-concepts">The concepts</h2>
<p>So, let's get some basics out of the way. I'm sure you know them but some people may not, and let's not leave them behind!</p>
<p>Some basic terminology:</p>
<p><strong>Error</strong> - also known as an 'exception', is when something goes wrong in the node code, and the program exits immediately. Errors, if not handled, will cause the program to come to a screeching halt, and ugly messages are spewed into the console, with a long and generally hideous error stack trace message.</p>
<p><strong>Throw</strong> <em>-</em> the <code>throw</code> operator is how the language handles an error. By using <code>throw</code> you generate an exception using the value you put after the operator. Note that the code after <code>throw</code> does not get executed - in that sense it is like a <code>return</code> statement.</p>
<p><strong>Error</strong> - there is a JavaScript <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error">object</a> called <code>Error</code>. An error gets 'thrown' in order to help the programmer know something needs to be handled. Think of it as a little ticking bomb ? that gets thrown from one function to another inside a chain of function calls. Technically, you can throw any data, including JavaScript primitives as an error, but it's generally a good idea to throw an <code>Error</code> object.</p>
<p>You typically construct the <code>Error</code> object by passing in a message string like so: <code>new Error('This is an error')</code>. But simply creating a new <code>Error</code>? object is unhelpful as that's only half the job. You've got to <code>throw</code> it so it can be caught. That's how it becomes useful.</p>
<p>Languages generally come with a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors">standard set of errors,</a> but you can create a custom error message with the <code>new Error('this is my error message')</code> constructor, and your error message should help you work out what's going on. More on <a target="_blank" href="https://nodejs.org/api/errors.html">Node errors.</a></p>
<p><strong>Catch</strong> <em>-</em> this is what you do when someone throws something at you, right? You'd probably do it reflexively even if someone threw you one of these... ?!</p>
<p>The <code>catch</code> statement in JavaScript lets you handle an error ? that gets thrown. If you don't catch the error, then the error 'bubbles up' (or down, depending on how you view the call stack) until it reaches the first called function and there it will crash the program.</p>
<p>In my example an error thrown by the Stripe API will bubble up all the way to my Route-Handler function, unless I catch it somewhere along the way and deal with it. If I don't handle the error, Node will throw an <code>uncaughtException</code> error and then terminate the program.</p>
<p>Let's return to my example:</p>
<p><strong>Call stack</strong></p>
<p><em>Route-Handler -&gt; Stripe Wrapper -&gt; Stripe API</em></p>
<p><strong>Error path</strong></p>
<p><em>Stripe API (</em>? _thrown here) -&gt; API Wrapper (<em>� �_not caught) -&gt;</em> _Route-Handler (_� �still <em>not caught) -&gt; ccrraashh</em> ???</p>
<p>We want to avoid app crashes as it can cause your data to corrupt, your state to be inconsistent, and your user to think your app sucks. So handling errors thoughtfully requires many levels of analysis.</p>
<p>There are some detailed guides to error handling in JavaScript and one of my favourites is <a target="_blank" href="http://javascript.info/try-catch">here</a>, but I will summarize my key leanings for you here.</p>
<h2 id="heading-try-catch-statement">Try-Catch statement</h2>
<p>Use these to gracefully handle errors, but be careful about <em>where</em> and <em>when</em>. When errors are caught and not handled properly they are lost. That 'bubbling up' process happens only up until the error encounters a <code>catch</code> statement. If there is a <code>catch</code> statement in the call chain that intercepts the error then the error won't crash the app, but not handling the error will hide it! Then it gets passed as an argument to <code>catch</code> and it requires you to handle it there.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">try</span>{
<span class="hljs-comment">// code logic</span>
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-comment">// handle the error appropriately</span>
}
</code></pre>
<p>So it's very important to catch <em>and</em> handle the error at a point where it makes the most logical sense for you when you have to debug it. It's tempting to think that you must catch it at the very first place it comes up (the last function called that sits right on the top of the call stack), but that isn't true!</p>
<p><em>Route-Handler -&gt; Stripe Wrapper (don't catch here!) -&gt; Stripe API</em></p>
<p>If I put my <code>try-catch</code> in the Stripe Wrapper which directly invokes Stripe's API, then I don't have information on <em>where</em> my Stripe Wrapper function was called. Maybe it was the handler, maybe it was another method inside my wrapper, maybe it was in another file altogether! In this simple example it's obviously called by Route-Handler, but in a real world app, it could be called in multiple places.</p>
<p>Instead, it makes sense for me to put the <code>try-catch</code> in the Route-Handler, which is the very first place where the function calls begin that resulted in the error. That way you can trace the call stack (also called unwinding the call stack) and drill down into the error. If I send bad data to Stripe it will throw an error, and that error will pass through my code until I catch it.</p>
<p>But when I catch it I need to handle it properly, or I could inadvertently conceal this error. Handling errors usually means deciding whether I need my front end user to know something has gone wrong (their payment didn't work, for example), or is it just an internal server error (for example, Stripe could not find the product ID I passed) that I need to handle gracefully without tripping up my front end users and crashing the Node code. If I added things to the database that are not correct, then I should clean up those false writes now.</p>
<p>When handling the error, it is a good idea to log it so I can monitor the app for bugs and failures in production and debug efficiently. So at the very, very least, handling would include logging the error in the <code>catch</code> statement. But...</p>
<pre><code class="lang-javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">stripeAPI</span>(<span class="hljs-params">arg</span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'this is the first function'</span>)
    <span class="hljs-keyword">if</span>(!arg) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'no arg!'</span>)
    <span class="hljs-comment">// else</span>
    saveToDb()
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">stripeWrapper</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'this is the second function, about to call the first function'</span>)
    <span class="hljs-keyword">try</span> {
        stripeAPI()
    } <span class="hljs-keyword">catch</span>(err) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Oops!  err will not bubble up to the first function that triggered the function calls!'</span>)
    }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">routeHandler</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'this is the third  function, about to call the second function'</span>)
    stripeWrapper()
}


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callAll</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-keyword">try</span> {
       routeHandler() 
       <span class="hljs-keyword">return</span> <span class="hljs-string">'done'</span>
    } <span class="hljs-keyword">catch</span> (err){  
       <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'error in callAll():'</span>, err)
       <span class="hljs-keyword">return</span> <span class="hljs-string">' not done '</span>
    }

}


callAll()
</code></pre>
<p>...as you can see above, if I catch it and log it in the middle level (my Stripe Wrapper class), it won't reach <code>routeHandler</code> or <code>callAll</code>, and my app will not know something went wrong. <code>callAll</code> still returns <code>done</code> and the only evidence something went wrong was in the log statement: <code>'Oops! err will not bubble up to to first function that triggered the function calls!'</code>. Had we not put a log statement there the error would have vanished without a trace.</p>
<p>This is 'error hiding' and it makes debugging a pain. If I add a <code>try-catch</code> but don't do anything in the <code>catch</code> statement, I will prevent my program from crashing. But I also end up 'hiding' the problem! It usually leads to inconsistent state - parts of my server code thinks everything is OK, and tells my front end that. But another part of my server code had indicated something was wrong!</p>
<p>In this simple example, it's easy to unravel, but think of deeply nested called across your entire application - what a nightmare!</p>
<p>If you absolutely need to handle the error in the middle of your call stack, then be sure to re-throw the error appropriately. That means ending your <code>catch</code> statement with another <code>throw error</code> operation. That way the error will get thrown again and continue to 'bubble up' towards the first function (bottom of the call stack) that triggered the call chain where it can be properly handled again.</p>
<p>Here's what it looks like, adding just one small re-throw in the <code>stripeWrapper()</code> function. Run the code and see the difference in outcome because <code>callAll()</code> now gets passed the error!</p>
<pre><code class="lang-plaintext">function stripeWrapper(){
    console.log('this is the second function, about to call the first function')
    try{
        stripeAPI()
    } catch(err) {
        console.log('Oops!  err will not bubble up to to first function that triggered the function calls!')

        throw err  // add this to re-throw!

    }
}

function callAll(){
    try{
       routeHandler() 
       return 'done'
    } catch (err){  // catches the re-thrown error and prints it to console!
       console.log('error in callAll():', err)
       return ' not done '
    }

}
</code></pre>
<p>Since you threw the error in the middle stage, it went to the outer boundary, and got caught there. The code returns <code>not done</code> and you can investigate why the error says 'no arg'. You can also then see that it never executed <code>saveToDb()</code>, as the error threw before that code could be executed! That could be a good thing in cases where you're saving things to the database <em>assuming that there were no errors until that point</em>. Imagine saving things to the database that should never have been saved - that's dirty data in the database now! ???</p>
<p>So, don't do what I did in my early days of programming and simply log the error at <em>every</em> step in the call stack and re-throw it. It just means you will get multiple logs for each error as it passes through the call stack! Only intercept the error at a place where you can most efficiently and usefully handle it, ideally once in a given chain of calls.</p>
<p>In general, it really helps if you place your <code>try catch</code> statement at the outermost (first calling) function that lies at the bottom of the call stack. You can identify this as the place the error will bubble up to <em>just before</em> throwing an <code>uncaughtException</code> error. That's a good place to catch, log, and handle it.</p>
<p>To see the difference in handling when you don't use the <code>try-catch</code> simply modify <code>callAll()</code> to look like this:</p>
<pre><code class="lang-plaintext">function callAll(){
    routeHandler()  

    // this won't run!
    console.log('This function is not contained inside a try-catch, so will crash the node program.')
}

callAll()
</code></pre>
<p>You'll note that the <code>console.log</code> statement never runs here because the program crashes when <code>routeHandler()</code> finishes executing.</p>
<h2 id="heading-rules-of-thumb">Rules of Thumb ???</h2>
<p>So let's summarize some quick rules that will cover 90+% of your needs:</p>
<ol>
<li><p>Do not litter your code with <code>try-catch</code> statements</p>
</li>
<li><p>Try as much as possible to <code>catch</code> only once in a given chain of function calls</p>
</li>
<li><p>Try and place that <code>catch</code> at the outermost boundary - the first function that starts the chain of function calls (bottom of the call stack)</p>
</li>
<li><p>Do not leave your <code>catch</code> statement empty as a way to stop your program from crashing! If you don't handle it, chances are it will lead to inconsistent state between your front end and back end. This can be dangerous and lead to a horrible user experience ?!</p>
</li>
<li><p>Do not use a <code>catch</code> statement only in the middle of the call stack, and not at the outer boundary. This will cause the error to get 'hidden' in the middle of your code where it isn't going to help you debug or manage data properly. Others who work with your code will find where you live and cut off your internet connection.</p>
</li>
<li><p>Catch it where you need to know, and where you can meaningfully do all the things necessary to clean things up.</p>
</li>
</ol>
<p><em>Stripe API (</em>? <em>thrown here) -&gt; API Wrapper (</em>? <em>passing through) -&gt;</em> <em>Route-Handler (</em>? <em>caught, handled, logged) -&gt;</em> ???</p>
<p>Thanks for reading!</p>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
<p>(Banner photo by <a target="_blank" href="https://unsplash.com/@thomastasy?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Thomas Smith</a> on <a target="_blank" href="https://unsplash.com/s/photos/bugs?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to automate your project and Github repo setup from the command line ]]>
                </title>
                <description>
                    <![CDATA[ This post comes out of an irritation I faced personally, when I was first learning to code - setting up my local repo and syncing with Github. I learned by doing projects (often freeCodeCamp ones!). But I needed to make sure I didn't lose my hard wor... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/automate-project-github-setup-mac/</link>
                <guid isPermaLink="false">66d461c438f2dc3808b7912a</guid>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Scripting ]]>
                    </category>
                
                    <category>
                        <![CDATA[ workflow ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Tue, 20 Aug 2019 08:59:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/08/octo.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>This post comes out of an irritation I faced personally, when I was first learning to code - setting up my local repo and syncing with Github.</p>
<p>I learned by doing projects (often freeCodeCamp ones!). But I needed to make sure I didn't lose my hard work, and that others could see the hard work I was putting in, so every project <em>had</em> to go on Github. <a target="_blank" href="https://www.freecodecamp.org/news/learned-to-code-job-ready-and-heres-why/">The more complete projects I had on Github, the easier it would be for recruiters</a>. But the steps required to set up a project, initialise a repo, and sync with Github were really annoying and repetitive, so I decided to solve the problem.</p>
<p>Bad news: this isn't going to be a big, fancy, detailed and technically sexy post. It's going to be very un-sexy.</p>
<p>Good news: you don't need to be a shell scripting god(dess) to do it.</p>
<p>So my typical project setup work flow usually goes like this:</p>
<ol>
<li><p>Go to my <code>../projects</code> folder and run <code>mkdir project-of-some-name</code> to create a folder with the name <code>project-of-some-name</code>.</p>
</li>
<li><p><code>cd</code> into that project folder and do <code>git init</code> to initialise a local git repo in there.</p>
</li>
<li><p>run <code>touch README.MD</code> to create the <code>README</code> file, open it and add some basic descriptions, including links to the resources / tutorials I was implementing in that project. Save the file.</p>
</li>
<li><p>run <code>git add .</code> and then <code>git commit -m ' ...some initial commit message...</code></p>
</li>
<li><p>open a browser, go to Github, login, create a new (remote) repository, copy the url, return to my terminal, make sure I was in the correct project folder <code>project-of-some-name</code>...then run the git scripts needed to set up the remote repo as the 'upstream' repo and connect my local repo to it. Then, finally, I can run a <code>git push</code> and my local commit would get pushed up</p>
</li>
<li><p>lie down and take a nap, exhausted from this repetitive process.</p>
</li>
</ol>
<p>Admittedly, this was my process, but I liked to stay organised and always be able to access my projects so I can refer to them.</p>
<p>Since automation is a great way to practice your coding skills, I decided to write a small shell script that automates these horrible and repetitive steps. The script is at the bottom of this post, and be warned - it's not sophisticated or fancy. But it sure gets the job done, and I don't need to log in to Github and fool around will all those steps!</p>
<p>Before you copy the script, you need to know how to run it on your Mac. So below are the steps you need to implement to be able to use the script to automate your setup workflow.</p>
<ol>
<li><p>I keep my scripts in my root/home folder, in a sub-folder called <code>scripts</code>. I suggest you do the same or similar. To get to the root/home folder, in your terminal type <code>cd ~</code> because the tilda ( <code>~</code> )is the symbol for the home folder. In your Mac Finder app it shows up as the one with a house icon. So all my scripts are stored in <code>~/scripts</code></p>
</li>
<li><p>This matters because to run a shell script from any directory in the terminal, you have to type out the full path. In my case I have to type out <code>~/scripts/git-script.sh</code> to run the script. But we're getting ahead of ourselves.</p>
</li>
<li><p>copy the code chunk at the bottom of this post and then open a text editor, paste it in and then save it as <code>[filename].sh</code>. The <code>.sh</code> is the extension for shell scripts. Save the file in the directory you want to save it at - again I recommend <code>~/scripts</code> as the folder to save your scripts in.</p>
</li>
<li><p>Navigate to that folder in your terminal. To be safe run <code>ls</code> in the terminal to check that you can see the script is there. If it's not you're in the wrong folder or step 3 didn't successfully complete.</p>
</li>
<li><p>Make the shell script executable. To do that you type the following in the terminal: <code>chmod +x &lt;&lt;the-correct-filename.sh&gt;&gt;</code>. This is the unix way to make a shell script "executable". I'm not confident I fully understand what that means, other than it's needed to make any shell scripts you write executable, so don't ask me and I won't lie to you.</p>
</li>
<li><p>navigate to your projects folder and make a new folder that you intend to house your project. Effectively, you've got to do this: <code>mkdir</code> - create a <code>project-of-some-name</code> inside the folder where you keep all your projects. So your project will eventually be placed inside <code>my-computer/my-projects/project-of-some-name</code>. <code>cd</code> into this folder and then type <code>pwd</code> to get the full path. Copy that - you will need to paste it shortly. It should look like <code>my-computer/my-projects/project-of-some-name</code></p>
</li>
<li><p>open your terminal again, and then type <code>~/scripts/</code>&lt;&lt;the-correct-filename.sh&gt;&gt;``. The script runs! You will be guided through some input... The main steps are:</p>
<blockquote>
<p>what do you want to call your Github repo (<strong>don't use spaces-</strong> 'my-awesome-project' is good. Don't use 'my awesome project' as the repo name.</p>
<p>Enter a description that shows up in the Github repo's description. For this it's safe to use spaces.</p>
</blockquote>
</li>
</ol>
<blockquote>
<p>Enter the project path you got in step 6, the one that you get after typing <code>pwd</code> in the terminal and getting something like <code>my-computer/my-projects/project-of-some-name</code></p>
<p>enter your Github username (not email address) and then your Github password. Be careful as you type as these values don't show up on the screen.</p>
<p>....that's it. The script will set up your git repo locally inside <code>my-computer/my-projects/project-of-some-name</code> and then create a <code>README.MD</code> (blank) and then commit it locally, then set up a remote repo in Github (log you in via API) etc and then push everything up!</p>
<p>finally, you will see that the terminal you were interacting with has changed the currently active directory to your project folder. It will now be at <code>my-computer/my-projects/project-of-some-name</code> and you can type in <code>ls</code> and see the <code>README.MD</code> file. If you then type <code>git status</code> you will see your local repo's status (the state of your local project) and if you type in <code>git remote</code> it will show you the Github url for your project!</p>
</blockquote>
<p>Done! Happy Coding!</p>
<p>Annnd.....finally......here is the script! I've commented each step so you can reason your way through it.</p>
<pre><code class="lang-plaintext"># Make executable with chmod +x &lt;&lt;filename.sh&gt;&gt;

CURRENTDIR=${pwd}

# step 1: name of the remote repo. Enter a SINGLE WORD ..or...separate with hyphens
echo "What name do you want to give your remote repo?"
read REPO_NAME

echo "Enter a repo description: "
read DESCRIPTION


# step 2:  the local project folder path
echo "what is the absolute path to your local project directory?"
read PROJECT_PATH

echo "What is your github username?"
read USERNAME

# step 3 : go to path 
cd "$PROJECT_PATH"


# step 4: initialise the repo locally, create blank README, add and commit
git init
touch README.MD
git add README.MD
git commit -m 'initial commit -setup with .sh script'


# step 5 use github API to log the user in
curl -u ${USERNAME} https://api.github.com/user/repos -d "{\"name\": \"${REPO_NAME}\", \"description\": \"${DESCRIPTION}\"}"

#  step 6 add the remote github repo to local repo and push
git remote add origin https://github.com/${USERNAME}/${REPO_NAME}.git
git push --set-upstream origin master

# step 7 change to your project's root directory.
cd "$PROJECT_PATH"

echo "Done. Go to https://github.com/$USERNAME/$REPO_NAME to see." 
echo " *** You're now in your project root. ***"
</code></pre>
<h4 id="heading-thanks-for-reading">Thanks for reading!</h4>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Get a Job in Tech as a Career Changer ]]>
                </title>
                <description>
                    <![CDATA[ Practice, persistence and deliberate improvement helps us get better at anything, no exceptions. The same applies for becoming highly effective at our work. I firmly believe that people who change careers may have a harder time moving into their new ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/career-changers-advantage-part2/</link>
                <guid isPermaLink="false">66d461c638f2dc3808b7912e</guid>
                
                    <category>
                        <![CDATA[ career advice ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career Change ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Junior developer  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Fri, 12 Jul 2019 10:12:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/07/download-1.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Practice, persistence and deliberate improvement helps us get better at anything, no exceptions. The same applies for becoming highly effective at our work. I firmly believe that people who change careers may have a harder time moving into their new domain, but have better odds at succeeding at the new domain. I also believe that cataloguing your transferable skills and feeling confident that they <em>are</em> transferable and relevant to your new domain is hugely persuasive to hiring managers.</p>
<blockquote>
<p>Make yourself compelling by removing all their objections.</p>
</blockquote>
<p>At the end of the day, when you're interviewing for roles, your job is to make yourself seem like the obvious choice. You do this by anticipating and removing any objections that the hiring manager may have to hiring you - so you need to have all the abilities of the other applicants, and then communicate your own abilities on top.</p>
<p>Here are the strategies that I've personally observed and directly used in my own careers over the years. I encourage you to think deeply about them and incorporate them into your approach.</p>
<p><em>This is part 2 of 2. In this part I will cover strategies that make you more compelling if you're worried about how your previous career will look when you interview for dev roles.</em></p>
<p><em>In</em> <a target="_blank" href="https://www.freecodecamp.org/news/why-career-changers-have-an-advantage/"><em>part 1</em></a> <em>I covered the big advantages that having one or more previous careers offers when you switch to a career in dev.</em></p>
<h3 id="heading-experience-helps-you-focus">Experience helps you focus</h3>
<p>The more experience you have, the more likely you are to have clarity into your own temperament, interests, skills and preferences. We tend to ignore or overlook these things when looking for work. I understand that if you're desperate for a job and running out of options, then you do not have the luxury of being picky. But many of us have not been targeted because not because of urgency but because we assume a scatter-gun approach is better. It's not. Being targeted increases your success rate, your effectiveness and your overall job satisfaction.</p>
<p>Also, being able to be clear on why you want that specific role goes a very long way in convincing the hiring manager that you're the right person for the job. As a hiring manager I only interview people with the required technical skills. I <em>choose</em> on the basis of their fitness for the role, which includes the clarity the candidate has about the role itself, and why they think they would enjoy the role. Use your experience to be clear on why you want the job, and let this clarity shine through in your cover letters, interviews and conversations.</p>
<h3 id="heading-experience-helps-you-play-to-your-strengths">Experience helps you play to your strengths</h3>
<p>Everyone has strengths and weaknesses, and successful invest more in developing their strengths than weaknesses. This is because you need to be outstanding only in a few things to be an outstanding contributor. So you might as well develop things that you're already good at, and aim to be outstanding.</p>
<p>Having previous experience in other roles helps career changers understand their strengths, contextualise why those strengths matter in a target role, and articulate those reasons in a way that makes sense to the hiring manager. By mapping your strengths to a role and the organisation's needs you automatically show that you've put a great deal more thought into how you can help the organisation achieve its goals. After all they're hiring you not so you can have a job, but so that the company can achieve its goals. Show them that you have strengths that will help them do that, and you're already ahead of the competition who just talk about their strengths without mapping them to the organisation's goals.</p>
<h3 id="heading-tell-a-better-story">Tell a better story</h3>
<p>The benefit of having multiple perspectives on business and roles is that you become a better story teller. By story I don't mean cooking up things - I mean telling _your_s story better. Weaving a narrative on your choices is a powerful opportunity - career changers can be mysterious and confusing to others, because most people don't have the interest, courage or freedom to change careers and sometimes this causes confusion as to whether you're serious or just flighty. If you have a powerful story, you can excite and inspire the hiring manager, and show that you're different, courageous, focused, dedicated, and willing to take chances on yourself. These are very desirable qualities in an employee. You want to show how there is a clear and compelling logic to your decisions even if it doesn't look like that from the outside looking in. The way to do that is by telling powerful stories that show how your unusual experience, mindset, interests and strengths combined in unique ways to bring you to the present day. A good story also shows self-awareness which is fast becoming a critical skill in the workplace, and in modern teams.</p>
<h3 id="heading-demonstrate-business-acumen">Demonstrate business acumen</h3>
<p>As you prepare for interviews for dev roles, use your previous experience to guide your research into the role and the target company. Understand its business context, not just the engineering set-up. Then show how the role will achieve the broader business goals. No one hires a developer just so they can have software. The software is is a part of the product, and the product is part of business strategy, and the strategy is part of the business goals, and the goals are a function of perceived and actual market needs, and the market's needs are linked to the economy and so on. See the big picture, understand where you fit in a smaller picture, and show how you understand the importance of your work for the business. That will set you miles ahead of developers who only talk about CI/CD as an essential part of the modern software development workflow without understanding why the company should care. If you can explain why the company should care about what you do, you're more likely to get better funding too.</p>
<h3 id="heading-experience-makes-you-a-better-team-player">Experience makes you a better team player</h3>
<p>While this is true for all experience, having diverse experiences shows that you're adaptable. Being adaptable is critical in being able to fit in, and work effectively with, teams. Being a better team player solves a huge risk for employers - a lot of productivity is lost when people don't gel well, or collaborate well. And this is not just true within the functional team, but across functions throughout the organisation. Career changes have a naturally broader intuition about the expanded nature of "teams" in the modern workplace. Communicate this, and you will set the interviewer's mind at ease.</p>
<p><strong>Experience makes you understand the hiring manager's needs</strong></p>
<p>By having experienced different roles and contexts before, you actually know a lot more than you realise. You already have a sense of what makes people effective in their roles - from your own direct performance and those of others in your team. Now all you got to do is ask yourself why those skills or behaviours mattered to your previous bosses. You will start to see a pattern, and this pattern is the clue to understanding what your interviewer is probably going to look for, perhaps subconsciously. Showing that you have maturity and experience to see this makes you stand out as a leader, and clued-in candidate. You <em>get it</em>. Show that you "get it" and you will stand out among the applicants.</p>
<p><strong>On practicing with rejection</strong></p>
<p>No one likes to be rejected. But no matter what you do, the odds are that you will be rejected more often than you succeed. And that's OK because you only need one acceptance at a time, and all rejections fade away. But the learnings from those rejections are hugely valuable - provided you take the time to investigate the reasons, understand and internalise them, and clearly commit to making small or big changes necessary to ensure you grow from the rejection. You should never be rejected for the same reason twice, or you're just wasting your energy doing the same thing , and expecting different results. To get better, turn each rejection into a lesson, and that way you will accumulate the skills to be an excellent interviewee. Often less capable candidates beat the others to get a role because they understand what the hiring manager is looking for, and communicate what matters.</p>
<p>So good luck, and remember to use your previous experience as an advantage!</p>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Why career changers have an advantage in the tech world ]]>
                </title>
                <description>
                    <![CDATA[ I am no stranger to changing careers. I started 16 years ago as a litigating lawyer, then moved to corporate law, and after 11 years of practice, left the law and went into middle management. Then I started my own startup. As my startup struggled to ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/why-career-changers-have-an-advantage/</link>
                <guid isPermaLink="false">66d461e1d1ffc3d3eb89de90</guid>
                
                    <category>
                        <![CDATA[ Career Change ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career development  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ engineering ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Wed, 03 Jul 2019 11:12:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/07/RATIONAL-EXPERIENCE.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I am no stranger to changing careers. I started 16 years ago as a litigating lawyer, then moved to corporate law, and after 11 years of practice, left the law and went into middle management. Then I started my own startup. As my startup struggled to attain sustainability, I discovered a love for coding (largely out of necessity, in startup-land!). I set crazy learning goals, and switched my attention from my startup to code (mainly to <a target="_blank" href="https://www.freecodecamp.org/news/non-technical-and-looking-for-a-technical-co-founder-2c212c01d6da/">become my own technical co-founder</a>). And then I figured that since I love to code, and I love technology, I might as well become a dev.</p>
<p>Looking back I see how I've grown exponentially with each career change. But here's the unexpected professional advantage : each new 'job' benefited <strong><em>enormously</em></strong> from my previous experience, even though most people (especially non-career changers) thought it was a bad idea. As it turns out all the people who had strong views about it had never done it themselves.</p>
<blockquote>
<p>Career changers have some very significant advantages that are often overlooked, and almost always underplayed</p>
</blockquote>
<p>Right after I decided to try and land a dev job late last year, I also decided to <a target="_blank" href="https://www.udemy.com/how-not-to-quit-coding/">document the strategies and plans</a> that actually worked for me when I taught myself to code - by publishing a course on Udemy targeted at people (especially those that long to get into a tech role) who want to teach themselves this vital skill of the new world. As part of that process, and based on feedback from a number of colleagues and recruiters for dev roles, I realised that us career changers have some very significant advantages that are often overlooked, and almost always underplayed.</p>
<p><em>This is part 1 of 2. In this part I will cover the big advantages of having one or more previous careers offers when you switch to a career in dev. In</em> <a target="_blank" href="https://www.freecodecamp.org/news/career-changers-advantage-part2/"><em>part 2</em></a> <em>I cover strategies that make you more compelling if you're worried about how your previous career will look when you interview for dev roles.</em></p>
<h3 id="heading-experience">Experience</h3>
<p>OK, so this is a no-brainer. But a shallow analysis of this will only mean that you don't actually leverage this asset properly. Why is experience in an unrelated, or semi-related field of any use? Most people would tell you that you need <em>direct</em> and "relevant" experience. And that is definitely the case when it comes to satisfying the specifics of the Job Description. But anyone that has actually reflected on their role will acknowledge that the real experience of the job is often quite different from the sanitized words in a JD. The difference is the same difference as a colouring in book before you colour it in and after. So here are the main reasons why experience really does matter, even if it is an unrelated field (potentially even more so then as it gives you depth and breadth of <em>life</em> experience).</p>
<ol>
<li><p><strong>Maturity</strong>. Dealing with teams teaches you soft skills, hard skills, and subconscious skills at dealing with personalities, temperaments, cultures, habits and mindsets.</p>
</li>
<li><p><strong>Insight</strong>. other roles gives you insight into other functions in an organisation. For example, if you're implementing a billing system you will have a better awareness of critical aspects of the user's experience if you understand how a sales person uses billing data to manage the sales pipelines and increase customer acquisition or reduce churn. If you were previously in sales or marketing or had your own startup, you would really have valuable skills when it comes to designing the system and selecting SaaS products.</p>
</li>
<li><p><strong>Context</strong>. Have worked in another team, in another role, in another organisation also helps you contextualise the drivers, habits, behaviours and motivations that influence how teams interact. Product, engineering, marketing, finance, they all have drivers and unique pressures and motives. Truly understanding the context of your co-workers and collaborators outside your narrow function makes you hugely valuable because it helps you cooperate better, which in turn encourages others to cooperate with you. No matter how skilled a dev you are, if you annoy the heck out of the folks who are driving revenue, you will struggle to be taken seriously, and that will impact the quality of your work life.</p>
</li>
<li><p><strong>Cultural adaptiveness</strong>. The ability to understand context, have insight, and deal with coworkers maturely adds up to an overall skills that I call your cultural adaptability. This just isn't about different ethnic, regional or anthropological cultures. This is about team-cultures too, the unique dynamics that an organisation's culture produces in its teams. Being adaptive in this way makes you highly effective, and effective team players are more valuable as employees than talented but ineffective members. Being great at your role is much, much more than pure technical skill or intellectual horse power.</p>
</li>
<li><p><strong>Communication</strong>. While a lot is written about improving communication in the engineering culture, the fact is that relatively poor communicators can still be highly <em>effective</em> if they have a broadened vocabulary in the context of their business. You may not have to know or care what Net Present Value or EBITDA is. But understanding these things will make you a better inter-team communicator. In exactly the same way that it helps if your finance person understands what a firewall, or API call is. Knowing some of the technical language spoken by other team members is flattering to them, useful to you, and beneficial for the organisation. And since these may be very boring to you (or not), the best way to pick up the vernacular is to have been in or close to those functions in a previous life, so you know not just what they mean but why they're important to your colleague.</p>
</li>
<li><p><strong>Prioritization</strong>. Effective team members prioritise in a way that benefits the team and also the larger organisation. If you have previous experience in other domains, you will understand how something that is a low priority to you has an outsized impact on another function, and vice versa. This sensitivity to the co-worker's perspective and professional pressures is a huge asset when it comes to building rapport, trust, camaraderies, and very important - organisational influence.</p>
</li>
<li><p><strong>Organisational Dynamics</strong>. This is the name for its healthy form. It's unhealthy twin is known as sh!tty politics. But it's a fact of life. You do not and should not have to participate. But it really helps to be able to detect it, foresee it, recognise it, sidestep it, and handle it. On rainy days it always helps to see a car speeding towards that puddle next to you, so you can avoid being splashed, right? In all its forms, the ability to navigate and deal constructively with Organisational Dynamics is a tremendous skill as it reduces stress, improves productivity, builds trust and credibility and delivers successful outcomes for the teams involved. If you've been only in one career or domain all your life you will become adept at recognising its forms in your specific function and in your context. But recognising it when it happens elsewhere but is coming soon to a colleague near you, is a huge strategic advantage as you can anticipate and prepare for it appropriately.</p>
</li>
</ol>
<p>Thanks for reading!</p>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learned to code !== Job Ready.  A hiring manager told me why. ]]>
                </title>
                <description>
                    <![CDATA[ When I taught myself to code, I did it because I really wanted to keep my startup dreams afloat, and finding reliable technical co-founders was a pain. I made a ton of mistakes and even quit a several times. So much so that I published a course on Ud... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learned-to-code-job-ready-and-heres-why/</link>
                <guid isPermaLink="false">66d461d537bd2215d1e24612</guid>
                
                    <category>
                        <![CDATA[ Career Change ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career development  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ jobs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn to code ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Wed, 26 Jun 2019 12:14:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/06/coding-jobs.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When I taught myself to code, I did it because I really wanted to keep my startup dreams afloat, and <a target="_blank" href="https://www.freecodecamp.org/news/non-technical-and-looking-for-a-technical-co-founder-2c212c01d6da/">finding reliable technical co-founders was a pain</a>.</p>
<p>I made a ton of mistakes and even quit a several times. So much so that I published <a target="_blank" href="https://www.udemy.com/how-not-to-quit-coding/">a course on Udemy about how</a> <a target="_blank" href="https://www.udemy.com/how-not-to-quit-coding/"><em>not</em></a> <a target="_blank" href="https://www.udemy.com/how-not-to-quit-coding/">to quit coding</a>.</p>
<p>At the end of a long, painful, and often tedious journey, I attained my goals. And as it happened, even found work, first freelance, then as a developer at a small, growing startup.</p>
<p>I never intended to become a professional dev, and it was pure luck that the curriculum I designed for myself happened to give me a huge advantage (hence the Udemy course).</p>
<p>Like almost everyone else who teaches themselves to code, I started with a <a target="_blank" href="https://medium.com/free-code-camp/what-learning-to-code-actually-taught-me-a11fd850af0a">lot of self-doubt</a>. I started timidly - trying it out in tiny bites. The easiest ways to get started were with sites like <a target="_blank" href="https://www.freecodecamp.org/news/learned-to-code-job-ready-and-heres-why/codecademy.com">Codecademy</a>. I then discovered freeCodeCamp, and <a target="_blank" href="https://www.freecodecamp.org/news/learned-to-code-job-ready-and-heres-why/courseera.org">Courseera</a>. And from there on I kept learning the theory and fundamentals of programming.</p>
<p>I did several of the courses twice, as I quickly forgot what I "learned". This turns out to be normal - like any new skill (think of walking, or driving) it takes a lot of practice and time. So I grew comfortable with not being able to memorise. I focused instead on understanding. I developed my knowledge. These resources (always used for free) gave me a sense of confidence in my understanding of the fundamentals. Thanks to these resources, I overcame my doubt, started to enjoy it, and felt like I was making progress.</p>
<p>There was one problem. I couldn't build much. Or rather, I was easily overwhelmed when I tried to to build anything more than a basic, static HTML site. I rarely could go much beyond what I learned on these sites. I was not yet able to take on "real" projects. I was not ready to solve code related problems on my own. I didn't know enough to even Google for answers correctly or efficiently.</p>
<p>So, I turned to other resources, and I will return to them in a moment. Before I tell you <em>what</em> I did that resulted in me getting 4 job offers, let me tell you <em>why</em> I happened to get those offers...</p>
<p>It wasn't just because I had the knowledge. That is easily established without an interview - most firms give you a coding test anyway. If you don't know enough to make it past that, you're not going to get the interview, let alone an offer.</p>
<p>As one interviewer put it: <em>"We don't hire for knowledge. We hire for skill."</em> And that seems perfectly logical and intuitively obvious - there is an important difference between knowledge and skill. Skill is applied knowledge.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/Visual-Merchandising-display-ideas-window-display-props.jpg_350x350-1.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here's the catch : how do you showcase your skills? A certification from online courses showcases <em>knowledge.</em> It does not demonstrate ability. Managers expect you to know the theory and syntax. They expect you to write a for loop easily, and to be able to read a switch-case statement and know what it does. But what they <em>want</em> is for you to be able to put that knowledge to work, and build things with it. You're hired to get a job done, and that's really what you need to prove you can do.</p>
<p>Which brings me to the nasty shock many people who have "learned to code" face when they struggle to find work. They're shocked that all their learning and effort does not get them much interest in the job market. Think of it this way - the finest department stores still need to showcase their wares in the shop windows right? Empty shop windows look bare and uninviting. They do not inspire confidence.</p>
<blockquote>
<p>A shop window that has certificates of quality, and standards but is bare of goods is not going to bring in customers, no matter how good the goods.</p>
</blockquote>
<p>So think about the resources you've used to learn and ask yourself this : what have you got to show for it? If it's nothing more tangible than a certificate, then consider what a potential hiring manager is going to assess you on, and how are you going to stand out from others?</p>
<p>See what I mean?</p>
<p>So this hiring manager said I was the least "experienced" candidate who'd applied, but I was very compelling. Why? I had (without meaning to) built a solid showcase. And they didn't need to look at my CV.</p>
<p>So now it's time to tell you <em>what</em> I did. I took a number of courses that were <em>long and intense</em>, but which were project-based. Because they were long and intensive, and project-based I had to use Github to store my code as I went along. And it turned out that my Github profile was what impressed the hiring managers - they loved that I had a lot of projects there.</p>
<blockquote>
<p><em>It turns out that most applicants have weak Github profiles.</em></p>
</blockquote>
<p>And that's an opportunity for you. Anyone can make claims in a CV. It's not terribly hard to make it to the end of a course and get a certificate. But you cannot argue with projects sitting in your Github repo. Especially if they're documented with a decent README file and installation instructions (this bit I didn't do so well ?).</p>
<p>Personally, I found that Udemy was the best for this - I did some great courses from Stephen Grider, Colt Steele, Andrew Mead etc. All of them had 20 -30 hours of video (which, if you code along and experiment, will take you 50+ hours). It's easiest to follow along if you've already done the basics on Freecodecamp, Codecademy etc. After a year or so of this, I had, through slow and patient persistence, made it through a bunch of courses, and accidentally built up a pretty good bunch of projects. I was even familiar and skilled enough to work on full stack projects that I dreamed up, and tackle things like Google Actions, Alexa, AR etc that were not related to the courses I'd taken. But importantly, I now had a body of work that <em>demonstrated my ability and commitment to code</em>. I had tangible evidence that any hiring manager could rely on, in addition to me passing the tests they gave me.</p>
<p>So, if I had to summarise the best approach to teaching yourself to code if you want a job as a dev, it would be this:</p>
<blockquote>
<p><em>Projects, not certificates, will teach you you enough to do it professionally</em> <strong><em>and</em></strong> <em>showcase your skills and knowledge.</em></p>
</blockquote>
<p>Keep in mind this post is targeted at new, beginner devs. If you want to see a talk version of this content, check out this video below from <a target="_blank" href="https://www.freecodecamp.org/news/learned-to-code-job-ready-and-heres-why/juniordev.io">juniordev.io's</a> Melbourne chapter. It's a fantastic group and I encourage you to think about participating in similar meetups in your city, to build your own understanding of conditions in your local market.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/OAAUtiSlXEs" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Good luck, and don't be afraid to go the extra mile. That's where the successful people are.</p>
<p>I really, truly believe your most precious resources are your time, effort and money. Of these, the single most important resource is time, because the other two can be renewed and recovered. So if you’re going to spend time on something make sure it gets you closer to this goal.</p>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Why learn-by dates make you fail when you’re learning to code ]]>
                </title>
                <description>
                    <![CDATA[ This blog is for all those who have set deadlines for their learning goals and then been discouraged when it took a great deal more time than anticipated. When we are inspired to set goals, what inspires us are the outcomes not the process. We are ne... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/why-learn-by-dates-make-you-fail-when-youre-learning-to-code-f1ac2bc41ea5/</link>
                <guid isPermaLink="false">66d461e33dce891ac3a96854</guid>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mindset ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Thu, 28 Mar 2019 17:13:39 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*r9zX6hqDel_pLmf7ZEI8FQ.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><em>This blog is for all those who have set deadlines for their learning goals and then been discouraged when it took a great deal more time than anticipated.</em></p>
<p>When we are inspired to set goals, what inspires us are the outcomes not the process. We are never eager to do 50 crunches at the gym — we are eager to walk around with flat abs.</p>
<p>Our wonderful human imagination makes us fall in love with the destination and overlook the path.</p>
<p>This is a good thing. Without this, none of us would start. But the flip side is that because of this most of us quit, or lose momentum. When the reality of the path to our dream is experienced, day in and day out, it’s very easy to slow down and eventually stop. Maybe we don’t want the dream after all. Or, more specifically, we want the result, not the work.</p>
<p>Right?</p>
<p>Sadly, this natural human habit is what stands in the way of many us learning new skills, especially complex skills like coding. Setting <em>outcome</em> goals is what drives people to action, but without <em>process</em> goals, the outcome is seriously at risk.</p>
<p>This is how I set my coding goals the first time I tried to learn to code: <em>I am going to learn HTML this month. Then next month I’m going to do JavaScript.</em></p>
<p>Sound familiar? Exciting outcome, no process.</p>
<p>That is actually a risky, ineffective way to set your coding goals. Here’s why.</p>
<p>In your head that target date seems reasonable, achievable, and importantly, encouraging. It’s motivating to think you will have results that soon. The problem is that a deadline-based goal like that is arbitrary. Learning a new skill takes a certain amount of time. Some are faster than others, but everyone has to put a minimum amount of time that <em>they</em> need to acquire that skill. The skill doesn’t care which month you want to finish by. It only demands that you put in enough time to learn it.</p>
<p>Therefore, setting a deadline-based outcome goal is incomplete — it ignores some vital math about learning.</p>
<p>For example, if you want to learn HTML and CSS in 30 days (<strong>outcome</strong>), it is absolutely achievable. But**,** what does that actually mean? How many hours, on average, does a person need to learn HTML and CSS? And then, how many hours a day or week (<strong>process</strong>) do you need to achieve that goal? If it takes 8 hours a day, 5 days a week, are you in a position to do that? Which metric really decides success: the outcome or the process? (hint: it’s not outcome).</p>
<p>Simply put: knowing how much time it takes to achieve a goal and how much time you can commit to regularly will decide when you you can expect to achieve that goal by.</p>
<p>It’s like a time and distance navigation problem — if you need to travel 100 kilometres, you cannot know when you will get to your destination unless you know how fast you’re traveling. No matter how sincere you are, you cannot do 100 kilometres in 1 hour if you’re walking. Setting that sort of goal is absurd and will result in frustration if you fooled yourself into thinking it’s possible.</p>
<p>So when you set your coding goals, work out the distance between where you are and the skill level you want, how much time will it take in total, and most importantly how much time you can guarantee you will devote to it every week. Divide total time by weekly time and you get the number of weeks it’s going to take you. That is your deadline.</p>
<p>Most learning resources online make this easy. <a target="_blank" href="http://freecodecamp.org/">freeCodeCamp.org</a> makes it super easy — the curriculum tells you clearly how much time a certification takes! Sites like <a target="_blank" href="https://www.udacity.com/">Udacity</a> and <a target="_blank" href="https://www.coursera.org/">Coursera</a> also tell you this, but it’s buried under other course data. Typically they tell you you can complete a course in X weeks if you spend a minimum of Y hours a week.</p>
<p>Even on <a target="_blank" href="https://www.udemy.com/how-not-to-quit-coding/">Udemy</a> this can be calculated. For example, <a target="_blank" href="https://www.udemy.com/how-not-to-quit-coding/">my course</a> is about 3 hours long. You can finish it in a day, if you spend 4 hours (including thinking and assignments). If you spend an hour a day you cannot finish it in less than 3 days. For more technical courses, where you learn by coding along, I would multiply the hours of video by at least 3 to get an estimate of time required to complete the course.</p>
<p>Put this way, it’s pretty clear that deadline-based outcome goals for learning are arbitrary if you don’t focus on the process goals of daily or weekly commitment. “When by” is useless without knowing “how much every day”.</p>
<p>And this one shift in approach will greatly improve your odds of success. This way you will know if something is going to take you 6 or 12 or 18 months. No nasty surprises — and you can <a target="_blank" href="https://www.udemy.com/how-not-to-quit-coding/">build a solid plan</a> around that, and prepare yourself for the journey.</p>
<p>Ultimately, every place is walking distance if you have the time. It’s no different for learning new skills. It takes the time it takes. You just got to be ready to show up and do the work until the math gets you to your destination.</p>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to become your own technical co-founder — and why it’s worth your time ]]>
                </title>
                <description>
                    <![CDATA[ Note: this blog is inspired by my recent podcast interview with freeCodeCamp’s Quincy Larson, where we talk about this in the last 15 minutes or so. Looking for a technical co-founder? I was too. For many years. It was a difficult journey, because th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/non-technical-and-looking-for-a-technical-co-founder-2c212c01d6da/</link>
                <guid isPermaLink="false">66d461d82472e5ed2fa07bd9</guid>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Entrepreneurship ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ startup ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Tue, 12 Mar 2019 00:01:58 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*Uomfdvzs-v68CZOpuGYoGg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Note</strong>: this blog is inspired by my <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer#">recent podcast interview</a> with freeCodeCamp’s Quincy Larson, where we talk about this in the last 15 minutes or so.</p>
<p>Looking for a technical co-founder? I was too. For many years. It was a difficult journey, because the prevailing “wisdom” is you need to go out and find a technical co-founder because all the successful startups had them (not true, by the way). But what happens when you're at the end of your runway, and your choice is to learn to code, or quit?</p>
<p>Technical co-founders are supposed to give you the stability, the complement of essential skills, and the accountability that are not possible being a solo founder. Of course, no one is tracking the countless examples where having a rubbish co-founder made your journey immeasurably harder, or thwarted your ability to progress altogether. But of course, what “they” mean is that you don’t need just a technical co-founder, you need the <em>right</em> technical co-founder, duh!</p>
<p>Well, of course.</p>
<p>None of this is particularly helpful advice. It’s like saying you need to be awake to have good ideas (seems obvious and intuitive, but not always true).</p>
<h3 id="heading-my-experience-as-a-non-technical-solo-founder"><strong>My experience as a non-technical (solo) founder</strong></h3>
<p>Here is what I’ve personally experienced in the many years I spent looking for technical co-founders:</p>
<ol>
<li><p>I spent a ton of time browsing forums, LinkedIn, and contact lists looking for people who met the minimum criteria</p>
</li>
<li><p>I spent a great deal of time not being able to validate much, test much, progress much because I didn’t have anything to validate, test or progress other than a well-honed pitch</p>
</li>
<li><p>I met a lot of people, and most were not interested in entrepreneurship, or didn’t have the necessary work ethic (aka masochistic streak)</p>
</li>
<li><p>I met a lot of people who were interested but for all the wrong motivations (get rich quick, glory, fame…)</p>
</li>
<li><p>I met a few people who had the right motivations and (as far as I could tell) the right skills, but who did not have the mentality to withstand the brutality of starting up</p>
</li>
<li><p>I met a very few people who had experienced starting up <em>and</em> had the skills, but none of them were enthused by my concepts (statistical inevitability)</p>
</li>
</ol>
<p>I knew diddly squat about software, though I wanted to start a technology company. So, here are my mistakes from back then:</p>
<ol>
<li><p>I had no clue about the fundamental, most basic aspects of software and its design</p>
</li>
<li><p>I grossly underestimated the complexity involved (didn’t know <em>how much</em> I didn’t know)</p>
</li>
<li><p>I grossly underestimated time involved</p>
</li>
<li><p>I grossly overestimated the people I approached to be technical co-founders</p>
</li>
<li><p>I significantly (but not knowingly) overstated my role in the initial period — “hustling” and “business development” were my skills, and I did not appreciate that some of the most successful startup companies spent a third of their time on those things, and most of their time building the product and responding to customer needs</p>
</li>
</ol>
<p>For close to 4 years I told myself “<em>I do not need to learn to code. My talents are better used elsewhere</em>”. Sound familiar?</p>
<p>It’s only partly true. As someone with very limited resources, my talents needed to be used on <em>whatever gave me the best chance at succeeding</em>. I had some spare cash I could spend on developers. I had some time I could spend managing them, and that time was mainly created by cutting down on social activity, sleep and disallowing myself weekends. I had valuable experience I could use in putting together a business plan. I had strong social skills and communication skills I could use to pitch to prospects, and also to potential co-founders.</p>
<p>I did all these things, and inched closer to my goals. But it took far too much time. Of course progress is always slow, certainly slower than we would like. But we only slow ourselves down further by not looking at the situation objectively. Even when I did have co-founders (who eventually quit because it was too hard or their life circumstances changed) I found that managing their work ethic, expectations and moods took a great deal of my time and energy. That’s ok — but no one budgets for that.</p>
<p>You see, as aspiring founders, our greatest enemy is anything that causes us to lose time. With every week that passes without results you’re more likely to quit. And we never truly know what our time-cost is when we choose a course of action. And we never know when we are victims of the <a target="_blank" href="https://youarenotsosmart.com/2011/03/25/the-sunk-cost-fallacy/">sunk-cost fallacy</a>.</p>
<p>Looking back, it cost me 4 years and quite a lot of money. And at the end of that, the only way to start again was to repeat that expenditure of time, effort and money, doing the same thing — putting together a plan, and then desperately looking for a technical co-founder.</p>
<p>Here we go again…</p>
<h3 id="heading-a-simple-time-math"><strong><em>A simple time-math</em></strong></h3>
<p>In 2014 I read a <a target="_blank" href="https://blog.samaltman.com/non-technical-founder-learn-to-hack">blog</a> by <a target="_blank" href="https://en.wikipedia.org/wiki/Sam_Altman">Sam Altman</a>, the president of <a target="_blank" href="https://en.wikipedia.org/wiki/Y_Combinator">YCombinator</a>. In it, Sam says some of the most profound truths I’ve ever disregarded. Here is the tweet that I dug up for fun.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/CCeTSXlmd1FCpjtxn8ONjwt51z9Wi8qlY6pa" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The first 2 or three times I read his piece I made really sensible sounding arguments as to why it did not apply to me. I was wrong and it cost me money, but worse, it cost me a lot of time (I made back the money).</p>
<p>He basically posits that it’s faster (<em>much faster</em>) to learn to program <em>enough to build your prototype</em> than it is to find a reliable, dependable co-founder who is a good fit, and will go the distance. Not just faster, but the odds of progress are vastly higher.</p>
<p>It’s obvious. Finding a good co-founder, technical or otherwise, is a long shot — like finding the right partner for life — and requires some degree of luck. Learning to code a bit is faster, needs no luck and therefore has a higher success rate.</p>
<p>In fact you can stop reading this blog right here if you like. Read his. It’s better. The only reason I’m writing mine is to share direct, personal experiences that confirm what he said. It’s telling that to date his blog has only had ~8,500 views — of which a dozen are mine. That is much less than the number of aspiring non-technical founders out there.</p>
<h3 id="heading-a-dating-analogy"><strong>A dating analogy</strong></h3>
<p>In high school, I remember being told that if you’re desperate for the affections of someone, you will act in ways that compromise yourself — your standards, your values and your best interests. You will settle for people, behaviours and situations that aren’t right for you.</p>
<p>It’s exactly the same with looking for co-founders. As time went on and my fear and desperation increased, I found myself compromising — reducing my standards. Negotiating against myself. Making excuses for others. Settling.</p>
<p>Over time I made bad decisions and bad compromises. Fortunately, none of those bad decisions resulted in actual co-founding relationships.</p>
<p>My point is that I was prepared to make bad compromises, just to make progress. That is a bad start to something that you may have to spend the next 10–20 years of your life on.</p>
<h3 id="heading-the-technical-stuff-doesnt-end-at-launch"><strong>The technical stuff doesn’t end at launch</strong></h3>
<p>It’s tempting to be tactical and say I just need to get to launch. That is not a sustainable plan. There is a difference between <em>planning</em> to “make it up when I get to that bridge” and <em>having</em> to do that because life left you no choice.</p>
<p>I learned the hard way that my need for technical help grew <em>after</em> launch. I thought the hard yards were getting to launch. Boy, was I wrong. Things break. Bugs emerge. Features don’t work as expected. Users have strong views on things. Iteration is the way to achieve product-market fit. And it has to be rapid, well coordinated and systematic. Data helps, and lot of valuable data comes post-launch!</p>
<p>That is why paying for developers isn’t sustainable unless you got lots of funding. And you’re not likely to get lots of funding before you even have a product. It’s possible, but not for most founders.</p>
<p>So what are you going to do when 4 weeks after launch things are breaking, users are reporting unexpected bugs, and the server crashed, or the app store has changed some policy? You spend more money. And beg the developers to hurry up. Meanwhile you’re doing your darnedest to find users, pitch, sell, etc.</p>
<p>You’re spending your time on things, for sure, and they’re important. But given a choice between fixing a bug / adding a features your users are clamoring for, and pitching your business plan to a potential seed funder, the best use of your time is product, not the pitch. And you cannot do it because you don’t know how. So you exert yourself on things of second-order consequence <em>because you cannot exert yourself on things of paramount importance</em>.</p>
<h3 id="heading-developing-technical-empathy"><strong>Developing technical empathy</strong></h3>
<p>As I mentioned on the <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer#">podcast</a>, I was (mortifyingly) one of those people who insisted that “it is a simple, quick prototype”. I totally, utterly, woefully, lacked any concept of what the development process is like.</p>
<p>Quincy, the founder of freeCodeCamp and the one who runs the podcast, summed it up very well:</p>
<blockquote>
<p><em>It gives you empathy for the developer experience, and helps you make meaningful time-estimates, not only in terms of what is possible, but also what is straightforward, and what is complex. [paraphrased]</em></p>
</blockquote>
<p>Imagine if someone who has no clue about your work comes to you and insists that something that takes a week should take 2 days — wouldn’t you want to knock them on the head, and just turn away in disgust?</p>
<p>I’m seriously embarrassed by all the times I did this (insist that it’s a simple app, not knock someone on the head).</p>
<p>Worse still, why would they take me seriously? Had I really showed them respect and commitment by at least trying to learn a little bit of their craft? From their point of view, I was hiding behind my skills and the reasonable excuse that coding is “<em>not the best use of my time</em>”.</p>
<p>Here is another sinister side effect of not being knowledgeable enough on the technical stuff. I could never evaluate the relative skills of the people I spoke to. I had to go on faith, trust or recommendations. I had no way to assess their fitness for the very purpose I needed them to fulfill.</p>
<p>Looking back, I could have saved myself a ton of money and months of effort, while building a skill that extends my runway almost indefinitely — had I learned to code earlier.</p>
<p>As <a target="_blank" href="https://blog.samaltman.com/non-technical-founder-learn-to-hack">Sam Altman says</a>:</p>
<blockquote>
<p>“When people like this say “I’ll do whatever it takes to make this business successful” (which they almost always say), I say something like “Why not learn to hack?”</p>
</blockquote>
<p>Why not indeed. Do whatever it takes. Especially if it helps <a target="_blank" href="http://www.paulgraham.com/die.html">your startup “not die”</a>.</p>
<h3 id="heading-engineering-is-not-the-be-all-end-all"><strong>Engineering is not the be-all-end-all</strong></h3>
<p>Not for one moment do I think coding is the answer to everything. If you are among those who have an interested <strong>and</strong> totally reliable technical co-founder, classmate, colleague, sibling etc, then yes it’s not the best use of your time — why? Because you’ve got a great resource in that other person. Then learning to code is duplicating skillsets.</p>
<p>But when you don’t have that skillset, learning a little of it is the best use of your time, if it saves you a lot of time in the long run. Here is the math I apply:</p>
<blockquote>
<p><em>priority = probability of outcome in a given unit of time</em></p>
</blockquote>
<p>So:</p>
<p>Find a co-founder in 6 months and start build in 7th month : 50% probability</p>
<p>Learn enough code in 6 months and start build in 7th month : 90%</p>
<p>This entire article would be totally obvious if it said that coders need to learn marketing and communication skills to pitch. Coders need to get out of the building and talk to their customers and not just code. This is now considered “obvious” advice.</p>
<p>So why isn’t the reverse just as obvious?</p>
<h3 id="heading-give-yourself-credibility"><strong>Give yourself credibility</strong></h3>
<p>Engineers are like the really good looking girl at the bar. They get “hit on” all the time. They get approached all the time. I don’t know directly, but I’m guessing that gets tired fast, and cynicism is just another “you’re going to love my startup idea” away.</p>
<p>You know what’s refreshing to someone you’re chatting up at a bar? Interest and awareness about them. The same goes for coders. If you’re aware enough of their world, and interested enough in the detail of their skills, they will respond and, at the very least, help.</p>
<p>This bit I do know from personal experience. Ever since I’ve learned to code I have many more engineers happy to give me advice, guide me, correct me, and even dive into my ideas with me. It’s not easier to find the <em>right</em> co-founder, but that has nothing to do with expertise, and more to do with their interests, priorities and life-circumstances.</p>
<h3 id="heading-and-now-what"><strong>And now what?</strong></h3>
<p>And now, for the first time in my life, I’m in a position where I can experiment with my ideas. Earlier it cost me time and money. Now it costs me a little time, and even then less time than finding developers, negotiating scope, supervising work, reviewing work, testing work. And that time is an investment as I keep improving the skill even if the idea pans out as commercially unviable.</p>
<p>I’m not a great coder. I don’t think I need to be (maybe in 5 years I will revise this view). But I know enough to build my own prototypes, and understand what is involved in building a viable product. And I know enough to take a call on which bits to outsource, how to describe what I want, not get taken for a ride, assess the output, and team up with other hackers to get results. I may never be a professional developer, and that’s fine. That is not what this is about.</p>
<p>But I have become my own technical co-founder. There may come a day when the best use of my time really is the non-technical stuff. But that day will come once I’ve built something that’s growing. I believe I’ve increased my chances of finding that something simply because I can run many more cheap, low-stress, experiments that do not involve me spending money or begging others for help.</p>
<p>All this in less than 12 months. Think about it. Maybe it really is the best use of your time if you want to be a founder.</p>
<p>I really, truly believe your most precious resources are your time, effort and money. Of these, the single most important resource is time, because the other two can be renewed and recovered. So if you’re going to spend time on something make sure it gets you closer to this goal.</p>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to implement local fulfillment for Google Assistant actions using Dialogflow ]]>
                </title>
                <description>
                    <![CDATA[ NB: this blog covers Actions on Google node.js deployments only, and presumes some basic prior knowledge of Actions on Google/ Dialogflow Google Home Devices that run the Google Assistant Hello, world! Problem statement I’ve been getting into Action... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-local-fulfillment-for-google-assistant-actions-using-dialogflow-1b3b3a13075f/</link>
                <guid isPermaLink="false">66d461cd55db48792eed3fd1</guid>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google Assistant ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Tue, 05 Mar 2019 15:04:18 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*7jmZNu-Wbc7Z4Ulo.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>NB: this blog covers Actions on Google node.js deployments only, and presumes some basic prior knowledge of Actions on Google/ Dialogflow</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/VFFY4IHPLQMJDw0QkHQf5XQL0au4uIdLTjOI" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Google Home Devices that run the Google Assistant</em></p>
<p>Hello, world!</p>
<h4 id="heading-problem-statement"><strong>Problem statement</strong></h4>
<p>I’ve been getting into <a target="_blank" href="https://developers.google.com/actions/">Actions on Google</a> quite a bit of late — enjoying myself thoroughly — My learning has been primarily designing small “party tricks” that I can amuse visitors with. I’ve been doing the same with Alexa too, but since I’m a lot more familiar with the <a target="_blank" href="https://cloud.google.com/">Google Cloud Platform</a> and <a target="_blank" href="https://firebase.google.com/">Firebase</a> especially, I have prototyped more on Google.</p>
<p>Actions and working with the Google Assistant often requires server side logic to handle the interaction with the desired level of personalisation or customization. This is called “fulfillment”.</p>
<p>The development cycle for fulfillment can be a bit tedious because you need to push your server code to the cloud each time, to see if it’s working. Every time we make changes that we want to test, we need to push code to Firebase and give it 30–60 seconds to propagate. It’s like web dev before hot reloads — ugh! So 2011.</p>
<h4 id="heading-summary-of-the-architecture"><strong>Summary of the Architecture</strong></h4>
<p>I won’t go into the details of building Actions for the Assistant, as there is plenty out there to help you with that. But a high level overview of the system now will help you understand the problem statement that inspired this blog.</p>
<p>Here is a diagram from Google that explains how Actions/ Assistant interactions are processed.</p>
<p>A user’s interaction gets picked up by the device, converted to text that is parsed by the device, and passed to a <a target="_blank" href="http://dialogflow.com/">DialogFlow</a> agent which is a <a target="_blank" href="https://en.wikipedia.org/wiki/Natural-language_understanding">NLU</a>engine. That then works out the “intent” of the user’s statement (“phrase” or “utterance”). That intent then gets matched to code that “fulfills” the intent of the user, then returns a response that is (hopefully) appropriate and acceptable.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*7jmZNu-Wbc7Z4Ulo.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you have studied the picture, you will see that a request is made in the last column, which denotes <a target="_blank" href="https://firebase.google.com/">Firebase</a>. What it really denotes is a back-end server that has a HTTP webhook that receives ‘requests’ for fulfillment and then works out how to respond appropriately. Architecturally, the Dialogflow NLU agent sends a <strong>POST</strong> request to the server webhook, which then gets processed by the server using SDKs.</p>
<p>The back end server that processes requests and responses is easily hosted on <a target="_blank" href="https://firebase.google.com/">Firebase Cloud Functions</a> (of course, Google makes it easy to use their stack — that’s just good business!).</p>
<p>Also, a locally run server will generate a webhook endpoint like <a target="_blank" href="http://localhost:3000,/">http://localhost:3000,</a> which is not accessible to Google Assistant’s POST requests.</p>
<h4 id="heading-solution-statement-local-fulfillment-dev-server"><strong>Solution Statement — local fulfillment dev server!</strong></h4>
<p>There are three steps to this solution:</p>
<ol>
<li><p>Create the back-end fulfillment server as an <a target="_blank" href="https://expressjs.com/">Express server</a>.</p>
</li>
<li><p>Handle Dialogflow requests and responses as an Express endpoint. The default Firebase Cloud Functions server users the <a target="_blank" href="https://github.com/actions-on-google/actions-on-google-nodejs">Actions on Google Nodejs Client Library</a> which has built-in functionality to receive HTTP POST requests from the Dialogflow agent. But that won’t work outside the Firebase environment (i.e. on our local development server). So we need to deploy our fulfillment server an an Express app.</p>
</li>
<li><p>use the <a target="_blank" href="https://www.npmjs.com/package/ngrok">Ngrok Node package</a> to create a temporary HTTP endpoint that tunnels HTTP requests through to our local:3000 (or whatever port you use) server.</p>
</li>
</ol>
<p>I will not go into the steps of setting up your basic code for a simple nodejs fulfillment server — the Dialogflow/ Actions on Google docs help you with all that. But I do provide here the snippets that show you how to convert that Dialogflow App into an Express App, and what your <code>package.json</code> needs to look like.</p>
<p>Let’s start with the basic setup for the Dialogflow node.js client. We will call it the Dialogflow App.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> {
  dialogflow,
  BasicCard
} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"actions-on-google"</span>);


<span class="hljs-comment">// Instantiate the Dialogflow client.</span>
<span class="hljs-keyword">const</span> app = dialogflow({ <span class="hljs-attr">debug</span>: <span class="hljs-literal">true</span> });


<span class="hljs-comment">// Handlers go here..</span>
app.intent(<span class="hljs-string">"Default Welcome Intent"</span>, <span class="hljs-function"><span class="hljs-params">conv</span> =&gt;</span> {
   <span class="hljs-comment">// handler for this intent</span>
});

app.intent(<span class="hljs-string">"Say_Something_Silly"</span>, <span class="hljs-function"><span class="hljs-params">conv</span> =&gt;</span> {
   <span class="hljs-comment">// handler for this intent</span>
});


<span class="hljs-built_in">module</span>.exports = app;
</code></pre>
<p>This is the app that ‘handles’ the intents. The above code is just scaffolding. Export the app, and import it in <code>functions/index.js</code>.</p>
<p><code>index.js</code> is the entry point in our <code>functions</code> folder, which contains the cloud functions we push up to Firebase Cloud Functions. In this file we create the Express App, and import the DialogflowApp object, and then pass it in to the Express route that will receive the HTTP POST requests from Dialogflow. <strong>Note</strong> that we need the body-parser npm package as the HTTP requests are JSON.</p>
<pre><code class="lang-js"><span class="hljs-meta">"use strict"</span>;

<span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> bodyParser = <span class="hljs-built_in">require</span>(<span class="hljs-string">"body-parser"</span>);
<span class="hljs-keyword">const</span> functions = <span class="hljs-built_in">require</span>(<span class="hljs-string">"firebase-functions"</span>);


<span class="hljs-comment">// clients</span>
<span class="hljs-keyword">const</span> dialogFlowApp = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./DialogflowApp"</span>);
<span class="hljs-keyword">const</span> expressApp = express().use(bodyParser.json());

<span class="hljs-comment">// EXPRESS APP fulfillment route (POST). The entire dialogFlowApp object (incl its handlers) is the callback handler for this route.</span>
expressApp.post(<span class="hljs-string">"/"</span>, dialogFlowApp);


<span class="hljs-comment">//  EXPRESS APP test route (GET)</span>
expressApp.get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.send(<span class="hljs-string">"CONFIRMED RECEIPT OF GET."</span>);
});



<span class="hljs-comment">/*
 *   LOCAL NGROK SERVER LOGIC. ENSURE that you "export IS_LOCAL_DEV=true" in terminal prior to start
 */</span>
<span class="hljs-keyword">if</span> (process.env.IS_LOCAL_DEV) {
  <span class="hljs-keyword">const</span> PORT = <span class="hljs-number">8000</span>;
  expressApp.listen(PORT, <span class="hljs-function">() =&gt;</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`*** SERVER RUNNING LOCALLY ON PORT <span class="hljs-subst">${PORT}</span> ***`</span>)
  );
} <span class="hljs-keyword">else</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"*** NOT LOCALLY SERVED - OR - LOCAL ENV VAR NOT SET  ****"</span>);
}

<span class="hljs-comment">//EXPORT either of the following two endpoints:  one express app, one dialogflow app</span>
<span class="hljs-built_in">exports</span>.fulfillmentExpressServer = functions.https.onRequest(expressApp);
<span class="hljs-built_in">exports</span>.dialogflowFirebaseFulfillment = functions.https.onRequest(dialogFlowApp);
</code></pre>
<p>The key parts of this code are that we create a POST route that takes, as the handler-callback, our DialogflowApp object. I created a GET route just to make quick browser GET requests to test the endpoint is working. But Dialogflow only uses the POST route.</p>
<p><strong>Note</strong> that I’ve made two exports here. One is the Express app and the other is the dialogflow App itself. This creates to Firebase functions with two endpoints which are identified by the property attached to the <code>exports</code>object. One endpoint will be &lt;……/fulfillmentExpressServer&gt; and the other will be &lt;……/dialogflowFirebaseFulfillment&gt;.</p>
<p>I can use either of these HTTP endpoints for fulfillment, once I’m done developing locally and have pushed the final code up to Firebase Cloud Functions.</p>
<h4 id="heading-ngrok-for-the-local-development-server-tunneling"><strong>NGROK for the local development server tunneling</strong></h4>
<p>There is some funny looking code in there on line 26. On my Mac terminal, I use <code>export IS_LOCAL_DEV=true</code> before I start the server locally. That codeblock on line 26 basically starts the server listening locally, which is <strong>not</strong>needed when we push the code up to Cloud Functions — it is for the local server only.</p>
<pre><code class="lang-js"><span class="hljs-string">"dependencies"</span>: {
    <span class="hljs-string">"actions-on-google"</span>: <span class="hljs-string">"^2.0.0"</span>,
    <span class="hljs-string">"body-parser"</span>: <span class="hljs-string">"^1.18.3"</span>,
    <span class="hljs-string">"express"</span>: <span class="hljs-string">"^4.16.4"</span>,
    <span class="hljs-string">"firebase-functions"</span>: <span class="hljs-string">"^2.2.0"</span>
  },
<span class="hljs-string">"devDependencies"</span>: {
    <span class="hljs-string">"ngrok"</span>: <span class="hljs-string">"^3.1.1"</span>
  },
<span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"lint"</span>: <span class="hljs-string">"eslint ."</span>,
    <span class="hljs-string">"serve"</span>: <span class="hljs-string">"firebase serve --only functions"</span>,
    <span class="hljs-string">"shell"</span>: <span class="hljs-string">"firebase experimental:functions:shell"</span>,
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"npm run shell"</span>,
    <span class="hljs-string">"deploy"</span>: <span class="hljs-string">"firebase deploy --only functions"</span>,
    <span class="hljs-string">"logs"</span>: <span class="hljs-string">"firebase functions:log"</span>,
    <span class="hljs-string">"tunnel"</span>: <span class="hljs-string">"ngrok http 8000"</span>,
    <span class="hljs-string">"dev"</span>: <span class="hljs-string">"nodemon index.js"</span>
  },
</code></pre>
<p>Which brings me to the above configuration in package.json. In the <code>scripts</code> property, you can see one called <code>tunnel</code>. Note the port number 8000 there. That can be set to anything you like, but make sure that the code in <code>index.js</code>that sets the <code>PORT</code> constant (line 27 in the Gist) is the same port number.</p>
<p>Before you run the code, check the following:</p>
<ol>
<li><p>You’ve set your environment variable and the code matches it — in my case I used <code>IS_LOCAL_DEV=true</code></p>
</li>
<li><p>Your port numbers match in <code>index.js</code> and the <code>tunnel</code> script</p>
</li>
</ol>
<p>Then you open two terminal windows and run the following:</p>
<p><code>npm run dev</code> and <code>npm run tunnel</code></p>
<p>In the terminal that ran the tunnel (ngrok) you will see something like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*N7SNAkcHzlVyWFoPTVk2eg.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Note the two ‘Forwarding’ addresses. They’re identical, except one is https. Either works. That is your endpoint, assuming your POST route is <code>/</code> and not <code>/&lt;some path&gt;.</code> If you’ve added a path to the POST handler then you need to add that path to the Forwarding address.</p>
<p><strong>Note</strong> that every time you run ngrok it generates a new, temporary URL for you. Therefore, you need to update your Dialogflow fulfillment webhook every time you run <code>npm run tunnel</code>.</p>
<p>And there you go. No more pushing every little change in code to Firebase Cloud Functions and waiting a minute or two before testing. Develop on the fly, and with nodemon, your server restarts and you can keep testing as you code!</p>
<p>And if you are a code newbie, and find this overwhelming, that is natural. You’re jumping too far ahead. I made that mistake too, and it cost me too much.</p>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Thinking of learning to code? That’s the easy bit. Here’s how to tackle the hard parts. ]]>
                </title>
                <description>
                    <![CDATA[ This article is for people who want to code, are trying to learn, or are wondering if they should learn it. _source:[https://www.freepik.com](https://www.freepik.com/free-photos-vectors/school" rel="noopener" target="blank" title=") When it comes to... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/thinking-of-learning-to-code-thats-the-easy-bit-here-s-how-to-tackle-the-hard-parts-d7151ed75d2a/</link>
                <guid isPermaLink="false">66d461ddbd438296f45cd3e6</guid>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Thu, 28 Feb 2019 17:48:10 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*ZYnbhi4ji9sLJ1JNFus-7g.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>This article is for people who want to code, are trying to learn, or are wondering if they should learn it.</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/e804PcAjUeiB7an1Wi36QrG5OngMAH3sz43t" alt="Image" width="600" height="400" loading="lazy"></p>
<p>_source:[https://www.freepik.com](https://www.freepik.com/free-photos-vectors/school" rel="noopener" target="<em>blank" title=")</em></p>
<p>When it comes to learning to code, attrition is a huge problem. The majority of people quit. And, as Steve Jobs said, quitting is the ‘rational’ thing to do when something is really, really hard. And if you don’t love it, you’re not going to see it through.</p>
<p>But here is a twist: we love things we are good at. Before we get good, we <em>like</em> things that we are “getting the hang of”. Think back to the last time you were getting the hang of something new, and you will remember that feeling of: ‘<em>Yeah — I can do this! I’m gonna get there!</em>’</p>
<p>Unfortunately, most people do not enjoy their journey to learn to code, even though it becomes one of the most addictive things you will ever do, <em>once you start to get the taste of success</em>. The trick is to start tasting small victories, early, and often.</p>
<h4 id="heading-my-story">My story</h4>
<p>But I did not know all this 4 years ago. I distinctly remember my first, confused attempts to code in 2014. I didn’t even know what an IDE was. It didn’t help that I was 34, had zero background and didn’t know a single programmer.</p>
<p>I tried to learn to code. Not once. Twice. And both times I gave up. I am a very hard worker, very focused, and hungry for a challenge. And I was defeated both times.</p>
<p>I found the challenge too hard. Until …hang on, I am jumping ahead.</p>
<p>Let me be clear and reiterate — <strong>it wasn’t coding that was hard. It was <em>learning to code</em> that was hard</strong>. And this is a very critical distinction. It’s not the subject that is hard, it’s the process of learning it.</p>
<p>It took me 3 years of giving up, trying again, needlessly wasting dollars, reading all sorts of seemingly promising things, receiving conflicting advice and trying to heed both, bleary eyed nights and frustrated days.</p>
<p>In late 2017, I launched a little startup product, at huge personal expense. I was afraid that I would not raise funding in time, and my co-founder bowed out. I had hired developers — and that couldn’t last long. One day I browsed through my diary, and I saw a pattern.</p>
<p>I was going about the learning all wrong.</p>
<p>I made a note of all the things I felt defeated me. The list had little to do with coding, but everything to do with my <strong><em>choices, behavior, priorities, and …</em></strong> here is the big one**<em>…my misconceptions</em>**.</p>
<p>Less than a year later, I was doing well at hackathons, holding my own with those that had gone to expensive US Coding Bootcamps, helping other beginners start coding, and finally, doing what I’d dreamt of doing in 2014 — programming almost every day. I had gone past “getting the hang of it” to… “wow…not daunted by it!”.</p>
<p>And the best part? I knew that if I failed at the startup, the next one would be enormously easier because I had learned enough to achieve a key goal: <strong>I had become my own “technical cofounder”.</strong> I was able to prototype my own ideas.</p>
<p>No more trying to persuade others to “build me a simple prototype”.</p>
<p>I love coding so much, and I can feel myself getting better every day. I love that I have barely scratched the surface — programming is a gift that keeps on giving!</p>
<blockquote>
<p>And I also now know that I could have achieved my objective with less than half the effort and expense.</p>
</blockquote>
<p>But I am now in danger of forgetting what it was like back in 2014, or even 2016, and what I thought, felt, worried about, and struggled with in those early, early days. And I also now know that I could have achieved my objective with less than half the effort and expense. Humans are so great at compressing decades of information into learnings that others can use — for example, every autobiography is decades of learning in a few hundred pages. Podcasts can give you in an hour what it took people years to learn.</p>
<p>And so I resolved to use my diary notes to create <a target="_blank" href="http://matchfitmastery.weebly.com">a complete course</a> that helps anyone, anywhere, prepare for the coding journey. There are plenty of courses that teach you how to code. But there is very little information that prepare you with what you need to know <em>before</em> you dive into learning.</p>
<p>I’m super pleased to announce that I’ve launched <a target="_blank" href="https://www.udemy.com/how-not-to-quit-coding/">the course on Udemy</a>! And if you’re a FreeCodeCamp reader, you’ll find in this post a clue on how to get a special promo code!</p>
<h4 id="heading-who-is-the-course-for"><strong>Who is the course for?</strong></h4>
<p>It is for people, especially those who have spent time in other careers, that are wondering if they can learn to code (you can), are interested in what it would take (a lot, but less than you expect if you learn from my mistakes!), have tried and given up (this is the majority!), are confused or overwhelmed by the tsunami of choices and decisions (too much noise, not enough guidance), or have started coding and want to make sure you achieve your outcomes with minimum wasted effort.</p>
<p>Oh, and if you want to save time, effort and money while you learn to code, then this course is for you. Because I lost over 8 months of time (more than 500 hours of time) and wasted over $1,100 in subjects that I did not need for my specific goal.</p>
<p>I designed the course to help you find the shortest path to <em>your specific coding goals**</em>.<em>* Remember that old saying ‘</em>People don’t just buy a drill — they buy the ability to hang the picture up on the wall*’? That is 100% true.</p>
<p>You don’t want to just learn to code. You want to create something with code. You want to solve problems, build a business, achieve a flow state, help others, sell things, learn things.</p>
<p>There is no shortage of drills (learn-to-code resources). There is a shortage of guidance on how to find the drill, where to get it, how to use it on your specific wall, for your specific picture.</p>
<p>And here is something you won’t hear from other courses — I even ask you to consider quitting if your objective can be achieved through a means <em>other than learning to program</em>.</p>
<p><strong>Time is your most precious non-renewable resource.</strong></p>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
<p>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to render modals in React ]]>
                </title>
                <description>
                    <![CDATA[ Modals can be a tricky topic in React because of the way React structures the DOM. If you’re familiar with the basics of React, you will know that the entire App is a component, usually called <App/> that gets gets appended as a child <div> called #r... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-render-modals-in-react-bbe9685e947e/</link>
                <guid isPermaLink="false">66d461cebd438296f45cd3e2</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zubin Pratap ]]>
                </dc:creator>
                <pubDate>Thu, 20 Dec 2018 17:12:54 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*u_CfjHWpbDQH9ayWj8pwKg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Modals can be a tricky topic in React because of the way React structures the DOM. If you’re familiar with the basics of React, you will know that the entire App is a component, usually called <code>&lt;App/&gt;</code> that gets gets appended as a child <code>&lt;div&gt;</code> called #root. The index.html file looks like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*Oyb_sJ8t8xI4n7A3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>create-react-app’s public/index.html file</em></p>
<p>Once the <code>&lt;App/&gt;</code> Component gets rendered to the DOM, the actual <code>&lt;div&gt;</code> element with id “#root” gets the entire React App rendered inside it.</p>
<p>Consequently, it’s quite common that React App Components get very deeply nested. We are talking dozens of levels deep, and often more. So if one of those deeply nested Components needs to show a modal, it’s going to face some serious CSS issues.</p>
<p>Modals put an overlay on the screen, and therefore take a higher visual precedence over <em>all</em> other elements. If you had to put it in z-index terms, it would need to be the highest number of all the elements on screen. But since it is so deeply nested, the parent elements way up the tree take CSS precedence.</p>
<p>Rather than touching the CSS which may be finely tuned, and so fiddling there could break the App, we need to find a way to render to the DOM — but <em>outside of the deep nesting</em>.</p>
<h3 id="heading-solution-react-portals"><strong>Solution — React Portals</strong></h3>
<p>One strategy is to use ReactDOM portals, and put the modal in a div that is a sibling component to the div with id “#root”. By doing so, the CSS styles applied to the modal’s div wrapper will apply only in relation to its sibling (the “#root” div), and that will not break the CSS styling of “#root”.</p>
<p>To do so we need to use the <code>createPortal()</code> method of ReactDOM. A portal is effectively such a sibling div, that bends the rule that <em>all</em> React components must be descendants of <code>&lt;div id=”root"&gt;</code>. To do so we need to do the following:</p>
<ol>
<li><strong>In index.html, inside the</strong> <code>&lt;bod**y&gt;**</code> tag:</li>
</ol>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">noscript</span>&gt;</span>
      You need to enable JavaScript to run this app.
    <span class="hljs-tag">&lt;/<span class="hljs-name">noscript</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"modal"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> .   //ADD THIS

  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p><strong>2. Create a Modal.js Component (classNames are from semantic-UI):</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom"</span>;

<span class="hljs-keyword">const</span> JSX_MODAL = (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"ui dimmer modals visible active"</span>&gt;</span>  
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"ui standard modal visible active"</span>&gt;</span>
      THIS IS SOME TEXT IN THE MODAL // add some UI features here
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
);


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Modal</span>(<span class="hljs-params">props</span>) </span>{
  <span class="hljs-keyword">return</span> ReactDOM.createPortal(JSX_MODAL, <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#modal"</span>));
}


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Modal;
</code></pre>
<p>You will see that <code>createPortal</code> takes two arguments: some JSX that gets rendered, and similar to <code>ReactDOM.render</code>, the target element under which the JSX gets rendered.</p>
<p>If you render the Component and navigate to it, you should find it shows up quite well. You now need to add the appropriate <code>onClick()</code> handler to handle click events inside the inner modal UI as well as to navigate away from the modal if the user clicks outside the inner modal UI.</p>
<p>You’d want to do this by listening for clicks in the right area and then stopping propagation so that the right behaviors arise depending on the region where the user clicks.</p>
<h3 id="heading-reusability"><strong>Reusability</strong></h3>
<p>The above example is extremely basic, and is not intended to be a ready to use code snippet. Rather, this is a solution to tackling modals. You should absolutely customise the component according to your needs. Use the React principles of reusability to ensure that you’re not hard coding data in the Modal, and pass down the content and even smaller widgets as needed.</p>
<p>For example, in one of my projects, I present a modal when the user is going to delete something from the database. So my component is, say, called <code>&lt;DeleteThis /&gt;</code>. It renders <code>&lt;Modal /&gt;</code>, which is the overlay that dims the underlying <code>&lt;DeleteThis /&gt;</code> screen.</p>
<pre><code class="lang-js">render() {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Modal</span>
          <span class="hljs-attr">content</span>=<span class="hljs-string">{this.renderContentProp()}</span>   
          <span class="hljs-attr">header</span>=<span class="hljs-string">"Delete this?"</span>                
          <span class="hljs-attr">actions</span>=<span class="hljs-string">{this.renderActionButtons()}</span>
          <span class="hljs-attr">onDismiss</span>=<span class="hljs-string">{this.onDismiss}</span>
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }

  renderActionButtons = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//return JSX that renders action buttons...</span>
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"ui button primary"</span>&gt;</span>Delete<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"ui button"</span>&gt;</span>Cancel<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  };
</code></pre>
<p>Within <code>&lt;Modal</code> /&gt; is an inner component c<code>alled &lt;Inne</code>rModal /&gt; and this has the actual interactive component, with headers, content and text.</p>
<p>So my <code>&lt;DeleteThis</code> /&gt; component creates props to pass down <code>into &lt;</code>;Modal /&gt; which in turn gets drille<code>d down into &lt;</code>;InnerModal /&gt;, and so the <code>render method</code> in looks like:</p>
<p>…with the actual Modal Component looking like:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom"</span>;
<span class="hljs-keyword">import</span> ModalInner <span class="hljs-keyword">from</span> <span class="hljs-string">'./modal-inner'</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Modal</span>(<span class="hljs-params">props</span>) </span>{
  <span class="hljs-keyword">return</span> ReactDOM
    .createPortal(
       <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ModalInner</span> {<span class="hljs-attr">...props</span>} /&gt;</span></span>,
       <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#modal"</span>)                      <span class="hljs-comment">//target DOM element</span>
     );
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Modal;
</code></pre>
<p>and now, you’re finally able to render:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*5JKvjljbrEzTxnNa.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Voilà, there you have it! Modals, with React Portal! Hope you enjoyed this!</p>
<p>And hope it saved you some time…</p>
<p>If you would like to learn more about my journey into code, check out <a target="_blank" href="http://podcast.freecodecamp.org/53-zubin-pratap-from-lawyer-to-developer">episode 53</a> of the <a target="_blank" href="http://podcast.freecodecamp.org/">freeCodeCamp podcast</a>, where Quincy (founder of freeCodeCamp) and I share our experiences as career changers that may help you on your journey. You can also access the podcast on <a target="_blank" href="https://itunes.apple.com/au/podcast/ep-53-zubin-pratap-from-lawyer-to-developer/id1313660749?i=1000431046274&amp;mt=2">iTunes</a>, <a target="_blank" href="https://www.stitcher.com/podcast/freecodecamp-podcast/e/59201373?autoplay=true">Stitcher</a>, and <a target="_blank" href="https://open.spotify.com/episode/4lG0RGpzriG5vXRMgza05C">Spotify</a>.</p>
<p>I will also hold a few AMAs and webinars in the coming months. If this is of interest to you please let me know by going <a target="_blank" href="http://www.matchfitmastery.com/">here</a>. And of course, you can also Tweet me at <a target="_blank" href="https://twitter.com/zubinpratap">@ZubinPratap</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
