<?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[ fundamentals - 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[ fundamentals - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 27 Jul 2026 15:22:50 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/fundamentals/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Teach Yourself Computer Science – Key CS Concepts You Should Know ]]>
                </title>
                <description>
                    <![CDATA[ Software development may feel like a bit of a race to keep up with new technologies. There's always a new frontend framework to learn, or a new database or language that's a variation of another language. It's never ending and feels like you always h... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-every-software-engineer-should-know/</link>
                <guid isPermaLink="false">66bb8c9aa5fd14123a8b4a10</guid>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Computer Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fundamentals ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software architecture ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tamerlan Gudabayev ]]>
                </dc:creator>
                <pubDate>Thu, 22 Jun 2023 22:06:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/pexels-christina-morillo-1181298--2-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Software development may feel like a bit of a race to keep up with new technologies.</p>
<p>There's always a new frontend framework to learn, or a new database or language that's a variation of another language. It's never ending and feels like you always have to keep up.</p>
<p>But it doesn't have to be this way. </p>
<h2 id="heading-everything-is-built-from-the-fundamentals">Everything is Built From the Fundamentals</h2>
<p>If you learn the fundamentals, then everything else will become easier. </p>
<p>For example, if you <a target="_blank" href="https://www.freecodecamp.org/news/what-is-tcp-ip-layers-and-protocols-explained/">learn how the TCP/IP protocol works</a>, then from that you can easily learn all the other protocols that are built on top of it. </p>
<p>You're essentially having to cover less ground. The more fundamentals you know, the less you will struggle learning new things.</p>
<p>I believe there are 10 core subjects which, if you learn them, will give you a solid foundation. </p>
<h2 id="heading-why-should-you-learn-these-key-concepts">Why Should You Learn These Key Concepts?</h2>
<p>Learning the fundamentals will really put you in the top 5% of all programmers.</p>
<p>If we look at it from a different perspective, here's a great quote from Ras Bodik.</p>
<blockquote>
<p>Don’t be a boilerplate programmer. Instead, build tools for users and other programmers. Take historical note of textile and steel industries: do you want to build machines and tools, or do you want to operate those machines?</p>
</blockquote>
<h2 id="heading-but-there-are-a-million-different-courses-to-choose-from">But There are a Million Different Courses to Choose From</h2>
<p>Well, look no further. </p>
<p>Below, I've compiled a bunch of helpful resources on each subject – with some alternatives, of course. So you can focus on learning and not on mindlessly researching which books/videos/courses are the best. </p>
<h3 id="heading-a-few-notes">A few notes</h3>
<p>This article is well-suited for self-taught developers or developers who don't feel quite comfortable with certain computer science concepts. </p>
<p>If you are learning to program for the first time, I would recommend <a target="_blank" href="https://www.reddit.com/r/learnprogramming/">r/learnprogramming</a> community on Reddit. </p>
<p>This article was heavily inspired by <a target="_blank" href="https://twitter.com/oznova_">Oz Nova</a> and <a target="_blank" href="https://twitter.com/quackingduck">Myles Byrne</a> who authored the site <a target="_blank" href="https://teachyourselfcs.com/">teachyourselfcs.com</a>. If you enjoy this article, feel free to check out and share their site. </p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-programming">Programming</a></li>
<li><a class="post-section-overview" href="#heading-computer-architecture">Computer Architecture</a></li>
<li><a class="post-section-overview" href="#algorithms-and-data-structures">Algorithms and Data Structures</a></li>
<li><a class="post-section-overview" href="#heading-math-for-computer-science">Math for Computer Science</a></li>
<li><a class="post-section-overview" href="#heading-operating-systems">Operating Systems</a></li>
<li><a class="post-section-overview" href="#heading-computer-networking">Computer Networking</a> </li>
<li><a class="post-section-overview" href="#heading-databases">Databases</a></li>
<li><a class="post-section-overview" href="#language-and-compilers">Languages and Compilers</a></li>
<li><a class="post-section-overview" href="#heading-distributed-systems">Distributed Systems</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/p/dfc9104e-85e4-4749-88dc-1859e6c643b9/web-security">Web Security</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/p/dfc9104e-85e4-4749-88dc-1859e6c643b9/conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-programming">Programming</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-84.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://dabeaz.com/sicp.html">Source</a></em></p>
<p>I'm not talking about syntax here. But actually programming or problem solving. Things such as abstraction, functions as data, recursion, and the different kinds of programming paradigms (object-oriented, functional, and declarative). </p>
<p>The book I recommend to learn programming is <a target="_blank" href="https://sarabander.github.io/sicp/html/index.xhtml">Structures and Interpretations of Computer Programs</a> (SICP) (It's also known as the wizard book). </p>
<p>The book is free and has a set of <a target="_blank" href="https://ocw.mit.edu/courses/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video_galleries/video-lectures/">MIT lectures</a>. But the MIT lectures are a bit hard to watch due to the poor quality of that time (2005). So I recommend <a target="_blank" href="https://archive.org/details/ucberkeley-webcast-PL3E89002AA9B9879E?sort=titleSorter">Brian Harvey’s SICP lectures</a> (for the 61A course at Berkeley) instead.</p>
<h3 id="heading-why-this-book">Why this book?</h3>
<p>Because this book focuses on the big picture. </p>
<p>It doesn't care about the programming language. It uses a variation of Lisp called Scheme. Scheme is very easy to learn (you can probably learn it in less than an hour), so it let's you focus on ideas not syntax. </p>
<p>Because of its simplicity, it makes it possible to examine different programming paradigms. It's a functional first approach, but you can implement your own OOP. </p>
<p>Scheme is a great language for teaching because it takes the focus away from the language and puts it on the big ideas. </p>
<p>If you're worried about it not being used in the industry, it's ok – you can always learn a more commonly-used programming languages after you grasp these high-level concepts.</p>
<h3 id="heading-but-what-if-i-really-dont-want-to-learn-scheme">But what if I REALLY don't want to learn Scheme?</h3>
<p>Okay, you can follow the new version of the book which uses Python. The book is called <a target="_blank" href="http://composingprograms.com/">Composing Programs</a>. It also has its own <a target="_blank" href="https://cs61a.org/">set of lectures</a>. </p>
<p>But, I highly recommend at least trying to do the Scheme version. It's just magical once you get it. </p>
<h3 id="heading-okay-ive-tried-it-but-its-really-hard">Okay, I've tried it but it's really hard</h3>
<p>Yes, I understand. </p>
<p>Some of you will find SICP a bit too hard. It's not meant for purely beginner programmers. </p>
<p>If that's the case, then I would recommend <a target="_blank" href="https://htdp.org/">How to Design Programs (HTDP)</a>. It uses a language very similar to Scheme and is generally more slower paced. You can use this book and its <a target="_blank" href="https://www.edx.org/course/how-to-code-simple-data">course on edX</a>.</p>
<h3 id="heading-tips-on-studying">Tips on Studying</h3>
<p>Don't read these books like a story. </p>
<p>It's not meant to be read cover to cover. Instead, <strong>focus on the exercises</strong>. You don't have to do them all, but just make sure you know how to solve most of them. </p>
<p>The lectures are optional and only needed if they help. It's really up to you. </p>
<h3 id="heading-additional-resources">Additional Resources</h3>
<ul>
<li><a target="_blank" href="https://www.youtube.com/playlist?list=PLVFrD1dmDdvdvWFK8brOVNL7bKHpE-9w0">Virtual meetups that talk about SICP</a> </li>
<li><a class="post-section-overview" href="#https://racket-lang.org/">Racket</a> (IDE for Scheme) (<a target="_blank" href="https://stackoverflow.com/a/25096066">Checkout this StackOverFlow answer for Scheme setup</a>)</li>
</ul>
<h2 id="heading-computer-architecture">Computer Architecture</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-128.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://github.com/ahmeducf/computer-systems-CS-APP3e">Source</a></em></p>
<p>You wrote some code and it magically runs. </p>
<p>How does that work? Well, this is what you will learn with computer architecture. This is by far the most neglected subject by most self taught engineers. </p>
<p>As engineers, we don't believe in magic. We have to unravel the magic behind computers. You will also learn some useful stuff such as:</p>
<ul>
<li>What is the L1, L2 cache? </li>
<li>Why does cyberpunk lag?</li>
</ul>
<p>The book I recommend here is <em><a target="_blank" href="http://csapp.cs.cmu.edu/3e/home.html">Computer Systems: A Programmer's Perspective</a></em>. I would also recommend an <a target="_blank" href="https://www.cs.cmu.edu/afs/cs/academic/class/15213-f16/www/schedule.html">introductory course</a> that will cover chapters 1-6 of the book (That was made by the authors of the book). </p>
<h3 id="heading-but-theres-a-catch">But there's a catch</h3>
<p><strong>This book is not meant to be read cover to cover</strong>. It has a lot of content, that may not well be presented in the optimal order.</p>
<p>So I recommend that you follow the course and do the labs. </p>
<h3 id="heading-what-if-i-find-it-too-hard">What if I find it too hard?</h3>
<p>A lot of people will find the content a bit heavy, so to ease into it, I would recommend doing the following:</p>
<ul>
<li>Read <a target="_blank" href="https://www.amazon.com/Code-Language-Computer-Hardware-Software/dp/0735611319">Code: The Hidden Language of Computer Hardware and Software</a>\</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/an-introduction-to-software-architecture-patterns/">Read this handbook on Software Architecture</a></li>
<li>Watch all 4 videos of <a target="_blank" href="https://www.youtube.com/playlist?list=PLFt_AvWsXl0dPhqVsKt1Ni_46ARyiCGSq">Exploring How Computers Work</a></li>
<li>Watch all 41 videos of <a target="_blank" href="https://www.youtube.com/playlist?list=PLH2l6uzC4UEW0s7-KewFLBC1D0l6XRfye">Crash Course: Computer Science</a></li>
<li>Take the course <a target="_blank" href="https://www.coursera.org/learn/build-a-computer">NAnd2Tetris</a> </li>
<li>Learn a bit of C by reading the book: <a target="_blank" href="https://www.amazon.com/C-Programming-Modern-Approach-2nd/dp/0393979504">C Programming a Modern Approach</a></li>
</ul>
<p>Once you finish that you can then come back to Computer Systems: A Programmers Perspective. </p>
<h2 id="heading-data-structures-and-algorithms">Data Structures and Algorithms</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-131.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://twitter.com/StevenSkiena/status/1336050368875290629">Source</a></em></p>
<p>Everyone wants to work at a FAANG company, but no one wants to learn Data Structures and Algorithms. </p>
<p>Nevertheless, I don't want you to learn these just because of technical interviews. Data structures and algorithms are important because they help build your problem solving skills. </p>
<p>There are many great books and courses on Data Structures and Algorithms but the one I would recommend is a book named <em><a target="_blank" href="https://www.amazon.com/Algorithm-Design-Manual-Steven-Skiena/dp/1849967202">The Algorithm Design Manual</a></em> by Steven Skiena. You can also check out his course <a target="_blank" href="https://www3.cs.stonybrook.edu/~skiena/373/videos/">here</a>. </p>
<h3 id="heading-dont-forget-to-practice">Don't forget to practice</h3>
<p>Same rules apply here. Don't just learn about data structures, but create them in whatever language you want. Don't just memorize algorithms but implement them and see where and how you can use them. </p>
<p>A good tip is solving some <a target="_blank" href="https://leetcode.com/">Leetcode</a> problems while going through the book/course. </p>
<h3 id="heading-what-if-i-find-it-too-hard-1">What if I find it too hard?</h3>
<p>If you find the material a bit heavy, then I would recommend the following resources:</p>
<ul>
<li>Read the book: <a target="_blank" href="https://www.amazon.com/Grokking-Algorithms-illustrated-programmers-curious/dp/1617292230">Grokking Algorithms</a> </li>
<li>Read the book: <a target="_blank" href="https://www.amazon.com/How-Solve-Mathematical-Princeton-Science/dp/069111966X#:~:text=Polya%2C%20How%20to%20Solve%20It,winning%20a%20game%20of%20anagrams.">How to Solve It: A New Aspect of Mathematical Method</a></li>
</ul>
<p>In general there are many different books/courses that teach Data Structures and Algorithms – Here are some other great resources:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/algorithms-and-data-structures-free-treehouse-course/">Data Structures and Algorithms course on freeCodeCamp</a></li>
<li><a target="_blank" href="https://algorithmsilluminated.org/">Algorithms Illuminated</a> </li>
<li><a target="_blank" href="https://www.coursera.org/learn/algorithms-part1">Princeton Algorithms Course</a> </li>
<li><a target="_blank" href="https://frontendmasters.com/courses/algorithms/">ThePrimegeans Data Structures and Algorithms Course</a></li>
<li><a target="_blank" href="https://ocw.mit.edu/courses/6-006-introduction-to-algorithms-fall-2011/">MIT Introduction to Algorithms</a> </li>
</ul>
<h2 id="heading-math-for-computer-science">Math for Computer Science</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-144.png" alt="Image" width="600" height="400" loading="lazy">
<em>Don't worry, this is some random math photo found <a target="_blank" href="https://unsplash.com/photos/h3kuhYUCE9A">here</a></em></p>
<p>Many new developers skip this. </p>
<p>But, hear me out – computer science is essentially a branch of mathematics. Learning it will make you a better developer by honing your problem solving skills. </p>
<h3 id="heading-the-most-relevant-area-for-cs-is-discrete-mathematics">The most relevant area for CS is Discrete Mathematics</h3>
<p>Discrete mathematics is the branch of mathematics that deals with countable or finite numbers. </p>
<p>The topics in discrete mathematics are many, but the ones which are relevant for CS are:</p>
<ul>
<li>Logic </li>
<li>Combinatorics </li>
<li>Discrete Probability </li>
<li>Set Theory </li>
<li>Graph Theory</li>
<li>Number Theory </li>
</ul>
<h3 id="heading-how-to-study-discrete-mathematics">How to Study Discrete Mathematics</h3>
<p>I would suggest starting with a set of <a target="_blank" href="https://cims.nyu.edu/~regev/teaching/discrete_math_fall_2005/dmbook.pdf">lecture notes by László Lovász</a>. </p>
<p>Professor Lovász notes are easier to digest than formal texts and are just generally fun. He starts of with a problem and solves it using discrete mathematics. </p>
<p>After that, you can take an MIT book called <em><a target="_blank" href="https://courses.csail.mit.edu/6.042/spring17/mcs.pdf">Mathematics for Computer Science</a>.</em> The book comes with video lectures that are <a target="_blank" href="https://ocw.mit.edu/courses/6-042j-mathematics-for-computer-science-fall-2010/video_galleries/video-lectures/">freely available</a>. </p>
<h3 id="heading-what-if-its-too-hard">What if it's too hard?</h3>
<p>Don't worry – sometimes you just have to accept that <strong>you won't always get it right away</strong>. </p>
<p>It's fine. </p>
<p>But if you feel like you're missing some fundamental knowledge, then it's a different story. The fundamental prerequisite subjects for discrete mathematics are:</p>
<ul>
<li>Algebra</li>
<li>Geometry</li>
<li>Calculas</li>
</ul>
<p>There are many free resources, but the ones I would recommend are:</p>
<ul>
<li><a target="_blank" href="https://www.khanacademy.org/">Khan Academy</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/college-algebra-course-with-python-code/">College Algebra course</a> </li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/learn-college-calculus-in-free-course/">Calculus 1 course</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/learn-calculus-2-in-this-free-7-hour-course/">Calculus 2 course</a></li>
</ul>
<h2 id="heading-operating-systems">Operating Systems</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-228.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://pages.cs.wisc.edu/~remzi/OSTEP/">Source</a></em></p>
<p>Remember when I told you that we as developers want to remove the magic in computing?</p>
<p>Same thing applies here – operating systems seem like some sort of magical black box. But they're not – it's just a lot of clever engineering. </p>
<p>If you know how these operating systems are built and work, then you will definitely be in a league of your own. </p>
<p>It's somewhat difficult to find good resources online for operating systems but the most recommend book is <a target="_blank" href="https://pages.cs.wisc.edu/~remzi/OSTEP/">Operating Systems: Three Easy Pieces (OSTEP).</a> There isn't any official video lecture online that fully covers the book but I found this <a target="_blank" href="https://www.youtube.com/playlist?list=PLhtZD20ADU45ADsAIxlNpFowP3iYvGXvJ">playlist on YouTube</a>. </p>
<h3 id="heading-recommend-prerequisites">Recommend Prerequisites</h3>
<p>I would suggest learning computer architecture first and a little bit about C before embarking on the operating systems journey. </p>
<h3 id="heading-optional-resources">Optional Resources</h3>
<p>Now, I recommend finishing OSTEP first and then checking out the other recommend resources. They are all optional. </p>
<ul>
<li>Want to build your own Linux system? Check out <a target="_blank" href="https://www.linuxfromscratch.org/">Linux from Scratch</a>. </li>
<li>Want an in-depth overview of Linux, MacOS, and Windows? <a target="_blank" href="https://www.freecodecamp.org/news/an-introduction-to-operating-systems/">Here's a handbook for you</a>.</li>
<li>Want to build your own OS? Check out <a target="_blank" href="https://wiki.osdev.org/Introduction">OSDEV</a></li>
<li>Want to build your own Sockets? Check out <a target="_blank" href="https://beej.us/guide/bgnet/">Beej's Guide to Network Programming</a> </li>
</ul>
<h2 id="heading-computer-networking">Computer Networking</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-237.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://github.com/topics/top-down-approach">Source</a></em></p>
<p>Since the dawn of the internet, computer networking has been one the most important subjects for software engineers. </p>
<p>If you don't know things like IP, TCP, UDP, HTTP, TLS, DNS, SMTP, and so on — then you should learn about computer networking (especially if you are a backend engineer).</p>
<p>The recommended book here is <a target="_blank" href="https://gaia.cs.umass.edu/kurose_ross/wireshark.php">Computer Networking: A Top-Down Approach</a>. You can also check out the <a target="_blank" href="https://www.youtube.com/playlist?list=PLByK_3hwzY3Tysh-SY9MKZhMm9wIfNOas">video lectures</a> from the author of the book himself. </p>
<p>But before beginning that I would recommend to check out this <a target="_blank" href="https://www.youtube.com/playlist?list=PLowKtXNTBypH19whXTVoG3oKSuOcw_XeW">video crash course on computer networking</a> from a bottom up approach. And <a target="_blank" href="https://www.freecodecamp.org/news/computer-networking-how-applications-talk-over-the-internet/">here's a helpful tutorial</a> that covers the basics well.</p>
<h2 id="heading-databases">Databases</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-229.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://www.astera.com/type/blog/a-quick-overview-of-different-types-of-databases/">Source</a></em></p>
<p>Databases are somewhat new – they came around the 1970s and have since become integral parts of many applications.</p>
<p>I highly recommend the below courses from the <a target="_blank" href="https://www.youtube.com/@CMUDatabaseGroup/featured">CMU Database Group</a>. They're all freely available on YouTube. I would recommend going through at least the first one. </p>
<ol>
<li><a target="_blank" href="https://www.youtube.com/playlist?list=PLSE8ODhjZXjaKScG3l0nuOiDTTqpfnWFf">Introduction To Databases</a></li>
<li><a target="_blank" href="https://www.youtube.com/playlist?list=PLSE8ODhjZXjZKp-oX_75aBnznulk7nubu">Database Seminars</a></li>
<li><a target="_blank" href="https://www.youtube.com/playlist?list=PLSE8ODhjZXjYzlLMbX3cR0sxWnRM7CLFn">Advanced Databases</a></li>
</ol>
<p>Also, <a target="_blank" href="https://www.freecodecamp.org/news/learn-sql-free-relational-database-courses-for-beginners/">here's a great collection of resources</a> to help you learn about SQL databases. And <a target="_blank" href="https://www.freecodecamp.org/news/learn-nosql-in-3-hours/">here's a free course on NoSQL databases</a>.</p>
<h2 id="heading-languages-and-compilers">Languages and Compilers</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-230.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://chidiwilliams.com/post/crafting-interpreters-a-review/">Source</a></em></p>
<p>You may know how to code in one or more programming languages. </p>
<p>But do you know how to create or design one? That's what you will learn by studying programming languages and compilers.</p>
<p>The recommended introductory book is called <a target="_blank" href="https://craftinginterpreters.com/contents.html">Crafting Interpreters</a>. </p>
<p>After that you can move on to <em><a target="_blank" href="https://smile.amazon.com/Compilers-Principles-Techniques-Tools-2nd/dp/0321486811">Compilers: Principles, Techniques &amp; Tools</a></em>, also called “the Dragon Book”. The book is covers a lot of topics so I highly recommend taking a course with it. The one I recommend is from <a target="_blank" href="https://www.edx.org/course/compilers">Alex Aiken on edX</a>.</p>
<p>And <a target="_blank" href="https://www.freecodecamp.org/news/what-is-a-compiler-in-c/">here's a helpful beginner-friendly tutorial</a> on how the compiler works in C programming.</p>
<h2 id="heading-distributed-systems">Distributed Systems</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-231.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://vvsevolodovich.dev/designing-data-intensive-applications-by-martin-kleppmann/">Source</a></em></p>
<p>If you choose to study only one subject from the list, make it distributed systems. It's the holy grail for tech companies, and if you want to get a developer job, you should be proficient about distributed systems. </p>
<p>My recommend path in learning the subject is:</p>
<ol>
<li>Read the book: <a target="_blank" href="https://www.amazon.com/gp/product/1838430202/ref=as_li_qf_asin_il_tl?ie=UTF8&amp;tag=utsavized0d-20&amp;creative=9325&amp;linkCode=as2&amp;creativeASIN=1838430202&amp;linkId=8f3007bbed9b958980492f5c0bb1105f">Understanding Distributed Systems</a> </li>
<li>Read the book: <a target="_blank" href="https://www.amazon.com/Designing-Data-Intensive-Applications-Reliable-Maintainable/dp/1449373321">Designing Data Intensive Applications</a> also known as the "red book"</li>
<li>While reading the "red book", take its accompanying <a target="_blank" href="https://www.youtube.com/@6.824/videos">MIT course on YouTube</a>. </li>
<li>Read the book: <a target="_blank" href="https://www.amazon.com/dp/1492086894?psc=1&amp;linkCode=sl1&amp;tag=utsavized0d-20&amp;linkId=64e15d236bb8c1015661423e5be849ac&amp;language=en_US&amp;ref_=as_li_ss_tl">Software Architecture: The Hard Parts</a> (Optional) </li>
<li>You can also <a target="_blank" href="https://www.freecodecamp.org/news/design-patterns-for-distributed-systems/">check out my handbook about design patterns for distributed systems</a>.</li>
</ol>
<h2 id="heading-web-security">Web Security</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-232.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://www.ifourtechnolab.com/blog/principles-of-web-security">Source</a></em></p>
<p>There have been a lot of security breaches in the last 2-3 years. </p>
<p>It's getting dangerous out there – and as a software engineer, knowing some fundamentals of web security will give you an edge. </p>
<p>The course I recommend first is <a target="_blank" href="https://web.stanford.edu/class/cs253/">CS253 Web Security by Stanford</a>. It gives a comprehensive overview of web security. So expect topics like web app vulnerabilities, injection, denial-of-service, and many more. </p>
<p>You can also <a target="_blank" href="https://www.freecodecamp.org/news/technical-dive-into-owasp/">review these common vulnerabilities</a> and learn how to prevent attacks that take advantage of them.</p>
<p>Later on, if you want, you could learn how to hack using <a target="_blank" href="https://pwn.college/">pwn.college</a>. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Learning all these subjects will take you a while, and will require consistent effort. But if you like what you do and are interested in the subject, then it should feel like play and not a chore. </p>
<p>Regardless of the subjects you choose to study. The most important tip I can give you is...</p>
<h3 id="heading-dont-be-a-passive-learner">Don't be a passive learner</h3>
<p>Don't just watch videos – do the exercises as well. Build the projects along with the tutorials. </p>
<p>Don't just read books but engage in the book by asking questions and doing your own research. </p>
<p>You want the information to stick, so you don't forget it. And to make it stick you have to actively engage in the subject. </p>
<p>I sincerely hope that I encouraged you to study some of these subjects. As always I want to end it of by thanking you for reading this article. </p>
<p>I wish you all the best. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Learn the Fundamentals of Software Engineering – in a More Interesting and Less Painful Way ]]>
                </title>
                <description>
                    <![CDATA[ This article is intended to be an introductory guide to the fundamentals of software engineering. I have written it with the assumption that you, dear reader, may not know much about the basics of the field, why they are important, and when you shoul... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-the-fundamentals-of-software-engineering/</link>
                <guid isPermaLink="false">66d460cfc7632f8bfbf1e499</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ education ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fundamentals ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mathematics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 16 Dec 2020 17:17:09 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5fd4eb92e6787e098393e070.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>This article is intended to be an introductory guide to the fundamentals of software engineering.</p>
<p>I have written it with the assumption that you, dear reader, may not know much about the basics of the field, why they are important, and when you should bother to learn them.</p>
<p>We shall go into each of these questions and finish by discussing some ways in which I recommend you learn and approach them.</p>
<p>For those who do happen to be familiar with this subject, there may still be some interesting new perspectives, and particularly in the last section, useful ways to speed up your learning process.</p>
<p>In this article we will discuss:</p>
<ul>
<li><p>What made software engineering spooky and intimidating for me, and how that changed</p>
</li>
<li><p>The reason for, and metrics by which we look at some code and conclude that it is less efficient than another approach (computational complexity)</p>
</li>
<li><p>A simple but hopefully useful introduction to Data Structures and Algorithms</p>
</li>
<li><p>The things I personally do to learn topics in software engineering for maximum efficiency and understanding</p>
</li>
<li><p>A way to motivate your efforts by adding in some basic tests to measure correctness and efficiency of your algorithms</p>
</li>
</ul>
<p>Please be aware that I have tried to structure this article in a logical progression where each section (apart from the next which is more about getting over the fear of diving into this subject) builds upon or motivates the next.</p>
<p>I am condensing over a thousand hours of practice and study into one article, and have done my best to explain things clearly and simply as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-275.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Photo by [Unsplash](https://unsplash.com/@thisisengineering?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;ThisisEngineering RAEng / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit)</em></p>
<h2 id="heading-where-the-problems-began">Where The Problems Began</h2>
<p>Throughout my limited formal education, I did not have the best relationship with the field of mathematics. And by extension, this impacted my relationship with a great deal of computer science (CS) and software engineering (SEng).</p>
<p>To be specific, it is not that I am bad at math, but I am poor at arithmetic and bad at remembering formulae.</p>
<p>I also found that the way in which mathematics, CS, and SEng are usually taught in schools does not tend to work for me either.</p>
<p>My own learning process to this day is largely driven by pragmatism (emphasis on practical over theoretical knowledge), curiosity about nature, and how this information can help me earn a living – three things I saw rarely emphasized in my western education.</p>
<p>Apart from my uneasy relationship with dry and boring presentations of things which are predominantly of a mathematical nature, I am a self-taught programmer.</p>
<p>To be clear, I took a single programming class at a community college (circa 2013), and the rest of my knowledge comes from self-directed studies. During my early years of that process, I also had to work various day jobs in order to pay the rent, which left me very little spare time and energy to learn my craft.</p>
<p>The end result was that I chose to spend most of my time building personal projects and learning topics specifically for those projects.</p>
<p>This led to me being really quite good at the skill of writing code, learning new technologies, and solving problems. However, if I did apply any concepts in CS and SEng to the code I was writing, it was largely by accident.</p>
<p>To summarize this introduction, I am trying to say that the biggest obstacle in my study of SEng was that I just was not very interested in learning it.</p>
<p>I did not know the sense of accomplishment you can get from making a small change to an algorithm which reduces its runtime to completion by a factor of tens or hundreds of times.</p>
<p>I did not know how important it was to pick a data structure based on the nature of the problem I was trying to solve, let alone how to make that decision.</p>
<p>And I had no idea how it was relevant to me slinging mobile apps for a living.</p>
<p>So just in case you are in the same boat, before we get to the technical details, I would like to attempt to answer some of those questions for you. To make things less boring, I will motivate this topic by sharing a true story about what changed my attitude towards this subject.</p>
<h2 id="heading-swimming-with-the-big-fish">Swimming With the Big Fish</h2>
<p>Towards the end of 2019, I had taken a break from studying Android Development in order to take a deep dive into UNIX Operating Systems and C/C++ programming.</p>
<p>I felt very comfortable with the Android SDK, but many years of JVM programming had left me with a strong sense of having no idea how computers actually worked under the hood. Which bothered me quite a bit.</p>
<p>I was not really looking for work, but at the time a recruiter from a big tech company had reached out to me about my interest in an Android Software Engineer position.</p>
<p>Despite being many months out of practice with Android, I did well in the first interview (it was all core Android concepts that I was familiar with) and was sent an email detailing the topics to be covered in future interviews.</p>
<p>The first section of this email, which detailed Android specific knowledge, was extensive, but I was at least somewhat familiar which most topics and not intimidated. However, when I scrolled down to the section on Data Structures and Algorithms, I suddenly felt like I did when I first started writing code: Like a fish out of water.</p>
<p>It is not that I had never applied any of these concepts in my code, but I certainly had not formally studied any of them.</p>
<p>Although I will do my best to give you a soft and clear introduction to these topics, SEng will immediately hit you with a wall of jargon terms, and my face was figuratively very sore and bruised after reading the entire list of DS and Algos I had to learn in that email.</p>
<p>I was very up front about that with my recruiter, who kindly gave me four weeks to prepare before the next interview.</p>
<p>I knew I could not cover every topic in four weeks, but I did hope that learning a year or two of SEng in a few weeks would show some talent and initiative.</p>
<p>I would love to tell you a juicy story about how I epically failed, or completely dazzled in the next interview, but the reality is that things fell apart before I even got the chance.</p>
<p>I am a Canadian citizen, and the position required relocation to one of many campuses in the United States, in either California or Washington State.</p>
<p>Two weeks into my first deep dive into SEng, I received an email from my recruiter stating that their immigration department did not want to sponsor me. I suspect it had to do with some difficulties around sponsoring a worker who had no degree, but the brewing global pandemic may also have been a factor.</p>
<p>In the end, even though I wanted the chance to succeed or fail in real time, I was happy knowing that I had a very clear idea of the knowledge I was lacking to be a software engineer in a big tech company.</p>
<p>With a clear but difficult path in front of me, I resolved to no longer let the field of SEng intimidate me. I wanted to know what it truly means to be a software developer versus a software engineer.</p>
<p>With that in mind, we shall go into the core ideas in SEng, and how to make the learning of them easier. Not easy – just easier.</p>
<h2 id="heading-the-big-three-topics-in-software-engineering-and-why-they-matter">The "Big Three" Topics in Software Engineering –And Why They Matter</h2>
<p>The main topics in software engineering can be summarized using a bunch of big scary words and phrases – as is the tradition in anything related to computer science and mathematics. To avoid confusion, I will instead explain them using the English language and examples which prioritize clarity above all else.</p>
<p>I suggest you follow this section in the order I have laid out, as I have deliberately structured it in a logical progression.</p>
<h3 id="heading-first-what-are-runtime-and-memory-space">First - What Are Runtime And Memory Space?</h3>
<p>I want to start off by explaining the reason why we study these topics to begin with.</p>
<p>Being a fan of physics, I was happy to learn that the interplay of time and space which we see in nature is also directly observed in any kind of computer.</p>
<p>However, in this field, we refer to these qualities as <strong>runtime</strong> and <strong>memory space</strong>.</p>
<p>To better understand what runtime is, I suggest you pull up your Task Manager, Activity Monitor, or whatever program you have that tells you about your system’s active “processes.”</p>
<p>A process is just a “running program,” and through the magic of having multiple “processors”, CPU virtualization, and time slicing, it can appear that we have tens or hundreds of processes running at the same time.</p>
<p>I threw those jargon terms in so that you can look them up if you are curious about how operating systems work, but <strong>doing so it is not necessary to proceed with this article.</strong></p>
<p>In any case, a process’s runtime can generally be thought of as any point in time during which it can be viewed in your system’s process tracking tool.</p>
<p>I use this definition to point out that <strong>an active process does not need to have a user interface or even do anything useful</strong> even though it may still be <strong>taking up runtime in the CPU and memory space.</strong></p>
<p>Speaking of memory space, in order for something to have run time, it has to be somewhere too. That somewhere is the physical memory space of the computer, which is <em>virtualized</em> (again, look up <em>virtualization</em> on your own time but it is not necessary for this article) in order to make it more secure and easier to use.</p>
<p>Every process is allocated its own distinct and protected virtual memory space, which can grow or shrink up to certain boundaries and depending on various factors.</p>
<p>Let us take a break from theory to <strong>talk about why we should care about it.</strong> Since runtime and memory space <strong>can be accurately measured</strong> but are also <strong>limited</strong>, humans like you and I can really screw things up if we do not pay attention to these limitations!</p>
<p>To be clear, here are two very important things we want to care about as programmers and engineers:</p>
<ul>
<li><p>Will our program or even the whole system crash because we have <strong>mismanaged the finite resource of memory space</strong>?</p>
</li>
<li><p>Will our programs solve problems for our users in a <strong>timely and efficient manner</strong>, or will they hang so long that our users decide to <strong>force quit, demand a refund, and leave a nasty review?</strong></p>
</li>
</ul>
<p>These question largely dictate the success of our programs whether you formally study them or not. With any luck I have motivated you to learn what I call the big three topics in software engineering, which we shall go into now.</p>
<h3 id="heading-how-we-measure-runtime-and-memory-space">How We Measure Runtime And Memory Space</h3>
<p>The first of the big three topics is described using a big scary term: <strong>Asymptotic Runtime &amp; Space Complexity</strong>.</p>
<p>Having already described runtime and memory space, I think a serviceable replacement for the word complexity here is “efficiency." And asymptotic is related to the fact that we can represent this efficiency (or lack thereof) on a two dimensional Cartesian Graph. You know, <em>x</em> and <em>y</em>, rise over run, and all that stuff.</p>
<p>Do not worry if you are unfamiliar with this stuff. You only need a very basic understanding of these things to apply it in your code.</p>
<p>Also, note that there is such a thing as a <strong>Graph data structure</strong>, but that concept is far removed from a Cartesian Graph and not what I am referring to.</p>
<p>Since we can represent our code and how it behaves with respect to either runtime or memory space on a Cartesian Graph, it follows that there must be <strong>functions which describe how to draw such a graph</strong>.</p>
<p>The way in which we describe how efficient our code in this way is to use “Big O” notation.</p>
<p>Here is the simplest introduction I can give you in order to understand this topic. I will use the modern programming language Kotlin for my code samples which will hopefully provide a happy middle ground for you web and native developers.</p>
<p>Suppose three functions (also sometimes known as methods, algorithms, commands, or procedures):</p>
<p>Function <code>printStatement</code>:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">printStatement</span><span class="hljs-params">()</span></span>{
    <span class="hljs-comment">//print to the system or program’s textual output stream/console</span>
    println(“Hello World!”)
}
</code></pre>
<p>Function <code>printArray</code>:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">printArray</span><span class="hljs-params">(arr: <span class="hljs-type">Array</span>&lt;<span class="hljs-type">String</span>&gt;)</span></span>{
    <span class="hljs-comment">//if 'arr' was {“Hello”, “World!”} then the output of this function would be:</span>
    <span class="hljs-comment">//Hello</span>
    <span class="hljs-comment">//World!</span>
    arr.forEach { string -&gt;
        <span class="hljs-comment">// "string" is a temporary reference given to each element of 'arr'</span>
        println(string)
    }
}
</code></pre>
<p>Function <code>printArraySums</code>:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">printArraySums</span><span class="hljs-params">(arrOne: <span class="hljs-type">Array</span>&lt;<span class="hljs-type">Int</span>&gt;, arrTwo: <span class="hljs-type">Array</span>&lt;<span class="hljs-type">Int</span>&gt;)</span></span>{
    <span class="hljs-comment">//Prints the sum of every value in both Arrays</span>
    arrOne.forEach { aInt -&gt;
        arrTwo.forEach { bInt -&gt;
            println(aInt + bInt)
        }
    }
}
</code></pre>
<p>For ease of understanding, suppose that every time <code>println(...)</code> is called, it takes 100ms, or 1/10th of a second on average to complete (in reality 100ms for a single print command is terribly slow but it's easier to imagine than a microsecond or picosecond).</p>
<p>With that in mind, let us think critically about how these functions can be <strong>expected to behave differently</strong>, based on <strong>what inputs they are given</strong>.</p>
<p><code>printStatement</code>, barring anything other than a catastrophic failure of the system itself, will always take an average time of 100ms to complete.</p>
<p>In fact, while Big O notation is very concerned about the size of the arguments given to a function (that will make more sense shortly), this function does not even have any arguments to change its behaviour.</p>
<p>Therefore, we can say that the runtime complexity (time taken until completion), is <em>constant</em>, which can be represented by the following mathematical function and graph:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/constant_complexity.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The runtime (T) for</em> <code>printStatement</code> is always an average of 100 milliseconds and is therefore constant.</p>
<p>In the above graphic, T represents the runtime for <code>println(...)</code> which we established to be an average of 100 milliseconds. I will explain what <em>n</em> refers to momentarily.</p>
<p><code>printArray</code> presents a new problem. It stands to reason that the time it takes for <code>printArray</code> to complete will be <strong>directly proportionate</strong> to the size of the Array, <code>arr</code>, which is passed into it.</p>
<p>If the Array has four elements, that would result in println(...) being called four times, for a total average runtime of 400ms for <code>printArray</code> itself. To be more mathematically precise, we would say that the runtime complexity of <code>printArray</code> is <em>linear</em>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/linear_complexity.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The number of times</em> <code>println(...)</code> is called, is directly proportionate (i.e. grows linearly) with respect to n.</p>
<p><code>printArraySums</code> takes things a step further into something which <strong>you should be concerned about</strong> even as a junior or intermediate level developer. The <em>number</em> of arguments/inputs to any given function is referred to with a small <em>n,</em> when using Big O notation.</p>
<p>In our second function, this refers exclusively to the size of the Array (that is, <code>arr.size</code>), but in the third function it refers to the collective size of multiple arguments (that is, <code>arrOne</code> and <code>arrTwo</code>).</p>
<p>In Big O notation, there are actually three different qualities of a given piece of code that we can pay attention to:</p>
<ul>
<li><p>How efficient is the code if <em>n</em> is small (best-case performance)?</p>
</li>
<li><p>How efficient is the code if <em>n</em> is of an average expected size (average performance)?</p>
</li>
<li><p>How efficient is the code if <em>n</em> is near or at the its maximum allowable value for the system (worst-case performance)?</p>
</li>
</ul>
<p>Generally speaking, in the same sense that a civil engineer is most concerned about the maximum number of vehicles a bridge can support, a software engineer is usually most concerned about worst-case performance.</p>
<p>By looking at <code>printArraySums</code>, you should be able to reason that we can represent its worst-case runtime complexity (the number of times println(...) will be called) as <em>n \</em> n;<em> where </em>n* is at or near to the maximum allowable size of an Array in the system.</p>
<p>In case it is not clear, we are not just pairing and summing the elements of <code>arrOne</code> and <code>arrTwo</code> at the same indexes, we are literally summing every value of them together in a <strong>nested loop</strong>.</p>
<p>From here you can start to truly understand the importance of asymptotic runtime and space complexity. In a worst-case scenario, the runtime grows exponentially in a quadratic curve:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/quadratic_complexity.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><code>printArraySums(...)</code> has its runtime grow in a quadratic curve. For T = 100ms, n does not even need to be that large to result in a <strong>bad user experience</strong>.</p>
<p>Two final notes on this topic: Firstly, if I suddenly made you a bit fearful of nested loops (and yes, <strong>each nested loop potentially adds another factor of <em>n</em></strong>), then I have done a good job.</p>
<p><em>Even so</em>, understand that if you are <strong>certain that <em>n</em> will not exceed a reasonable size</strong> even in a function which has exponential growth, then there is <strong>not actually a problem</strong>.</p>
<p>If you would like to know how to determine if <em>n</em> will have a negative impact on performance, <strong>stick around for the last section of this article.</strong></p>
<p>Secondly, you may have noticed that all of my examples were about runtime complexity, not memory space complexity.</p>
<p>The reason for this is simple: We represent space complexity in exactly the same manner and notation. Since we do not actually allocate any new memory apart from a temporary reference or two within each frame of the <code>forEach{...}</code> loops, <em>asymptotically speaking</em>, the second and third functions are still linear, O(<em>n</em>), with respect to memory allocation.</p>
<h3 id="heading-data-structures">Data Structures</h3>
<p>The term Data Structure, despite what any single teacher may tell you, does not have a singular definition.</p>
<p>Some teachers will emphasize their abstract nature and how we can represent them in mathematics, some teachers will emphasize how they are physically arranged in memory space, and some will emphasize how they are implemented in a particular language specification.</p>
<p>I hate to tell you this, but this is actually a very common problem in computer science and engineering: One word meaning many things and many words meaning one thing, all at the same time.</p>
<p>Therefore, rather than trying to make every kind of expert from every kind of academic or professional background happy by using a plethora of technical definitions, <strong>let me upset everyone equally by explaining things as clearly as I can in plain English</strong>.</p>
<p>For the purposes of this article, Data Structures (DS) refer to the ways in which we represent and group together our application’s data in our programs. Things like user profiles, friends lists, social networks, game states, high scores and so on.</p>
<p>When considering DS from the <em>physical</em> perspective of the hardware and operating system, there are two main ways to build a DS. Both ways take advantage of the fact that physical memory is discrete (a fancy word for countable), and therefore addressable.</p>
<p>An easy way to imagine this is to think about street addresses and how, depending on which direction you are physically moving (and depending on how your country organizes street addresses), the address increases or decreases in value.</p>
<h3 id="heading-physical-array">Physical Array</h3>
<p>The first way takes advantage of the fact that we can group pieces of data (for example a list of friends in a social media application) into a chunk of contiguous (physically next to each other) memory space.</p>
<p>This turns out to be a very fast and efficient way for a computer to traverse memory space. Instead of giving the computer an <em>n</em> sized list of addresses for each piece of data, we give the computer a single address denoting the start of this DS in physical memory, and the size of (that is, <em>n</em>) the DS as a single value.</p>
<p>The instruction set for doing this could be as simple as telling the machine to move from left to right (or whatever direction), decrement the value of <em>n</em> by 1 each move, and to stop/return when that value hits 0.</p>
<h3 id="heading-lists-of-links-addresses">Lists Of Links (Addresses)</h3>
<p>The second way requires each piece of data in the structure itself to contain the address(es) of the next or previous (maybe both?) item within itself.</p>
<p>One of the big problems with contiguous memory spaces is that they present problems when it comes to growing (adding more elements) or shrinking (this can <em>fragment</em> the memory space, which I will not explain but suggest a quick google search).</p>
<p>By having each piece of data <em>Link</em> to the other pieces (usually just the previous or next one), it becomes largely irrelevant where each piece sits in physical memory space.</p>
<p>Therefore, we can grow or shrink the data structure with relative ease. You should be able to reason that since each part of the structure stores not just its own data, but the address of the next (or more than that) element, then each piece would necessarily require more memory space than with the contiguous Array approach.</p>
<p>However, whether it is ultimately more efficient depends on what kind of problem you are trying to solve.</p>
<p>The two approaches I have discussed are generally known as an <em>Array</em> and a <em>Linked List</em>. With very little exception, most of what we care about in the study of DS is how to group collections of data which have some kind of reason to be grouped together, and how best to do that.</p>
<p>As I tried to point out, what makes one structure better in a certain situation can make it worse in another.</p>
<p>You should be able to reason from the previous few paragraphs that a <em>Linked List</em> is typically more suitable for a dynamic (changing) collection, whereas an <em>Array</em> is typically more suitable for a fixed collection – <strong>at least with respect to runtime and space efficiency</strong>.</p>
<p>Do not be misled, however! It is not always the case that our primary concern is to pick the most efficient DS (or algorithm) with respect to runtime and memory space. Remember, if <em>n</em> is very small then worrying about a nanosecond or a few bits of memory here and there are not necessarily as important as ease of use and legibility.</p>
<p>The last thing I would like to say about DS is that I have observed a profound lack of consensus about the difference between a DS and a Data Type (DT).</p>
<p>Again, I think this is largely due to different experts approaching this from different backgrounds (mathematics, digital circuits, low level programming, high level programming) and the fact that it is really quite hard to make a verbal definition of one that does not at least partially (or entirely) describe the other.</p>
<p>At the risk of making the situation even more confusing, on a <em>purely practical</em> level_,_ I think of data structures as things which are independent of a high level programming language’s Type System (assuming it has one). On the other hand, a data type is defined by and within such a Type system.</p>
<p>But I know that Type Theory itself is independent of any particular Type system, so you can hopefully see how tricky it is to say anything concrete about these two terms.</p>
<h3 id="heading-algorithms">Algorithms</h3>
<p>I took quite a long time to explain the previous two topics because they allow me to introduce and motivate this topic rather easily.</p>
<p>Before we continue, I must very briefly try to untangle another mess of jargon. To explain the term “algorithm” in my own way, it is actually very simple: An algorithm is a set of instructions (commands) which can be understood and executed (acted upon) by an Information Processing System (IPS).</p>
<p>For example, if you were to follow a recipe to cook something, then you would be the IPS, the algorithm would be the recipe, and the ingredients and cookware would be the data inputs (arguments).</p>
<p>Now, by that definition the words function, method, procedure, operation, program, script, subroutine and algorithm all point to the same underlying concept.</p>
<p>This is not by accident – these words all fundamentally mean the same thing. The confusion is that different computer scientists and language designers will implement (build) the same idea in a slightly different way. Or even more depressingly, they will build them the same way but give a different name. I wish this was not the case, but the best I can do is to warn you.</p>
<p>That is all you need to know about algorithms in general, so let us be more specific about how they can help us to write better code.</p>
<p>Recall that our primary concern as software engineers is to write code which is guaranteed to be efficient (at least such that it keeps our users happy) and safe with respect to limited system resources.</p>
<p>Also recall that I previously stated that some DS perform better than others with respect to runtime and memory space, particularly as <em>n</em> gets large.</p>
<p>The same is true of algorithms. Depending on what you are trying to do, different algorithms will perform better than others.</p>
<p>It is also worth noting that the DS will tend to shape which algorithms can be applied to the problem, so selecting the right DS and the right algorithm is the true <strong>art of software engineering.</strong></p>
<p>To finish off this third main topic, we will look at two common but very different ways to solve the one problem: <em>Searching an ordered Array</em>. By ordered, I mean to say that it is ordered something like least to greatest, greatest to least, or even alphabetically.</p>
<p>Also, assume that the algorithm is given some kind of target value as an argument, which is what we use to locate a particular element. This should become clear in the example in case there is any confusion.</p>
<p>The example problem is as follows: We have a collection of Users (perhaps loaded from a database or server), which is sorted from least to greatest by a field called userId, which is an Integer value.</p>
<p>Suppose that this userId comes from taking the system time (look up Unix Time for more info) just prior to creating the new User. Rounded to the smallest value that still guarantees no repeated values.</p>
<p>If that previous sentence did not make sense, all you need to know is that this is <strong>a sorted collection with no repeats.</strong></p>
<p>A simple way to write this algorithm would be to write what we will call a Naive Search (NS). Naive, in this context, means <em>simple, but in a bad way</em>, which refers to the fact that we just tell the computer to start from one end of the collection and move to the other until it finds a match to the target index.</p>
<p>This is generally achieved by using some kind of loop:</p>
<p>Function <code>naiveSearch</code>:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//this function accepts an Integer targetId to match against,</span>
<span class="hljs-comment">// and an Array of User objects as arguments. </span>
<span class="hljs-comment">// Assume for simplicity's sake that it is guaranteed to find a User.</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">naiveSearch</span><span class="hljs-params">(targetId: <span class="hljs-type">Int</span>, a: <span class="hljs-type">Array</span>&lt;<span class="hljs-type">User</span>&gt;)</span></span>: User {
    a.forEach { user -&gt;
        <span class="hljs-keyword">if</span> (targetId == user.userId) <span class="hljs-keyword">return</span> user
    }
}
</code></pre>
<p>If we happen to only have a few hundred, or even a few thousand users in this collection, then we can expect this function to return quite quickly all the same.</p>
<p>But let us assume we are working in a successful social media tech start up, and we have just hit one million users.</p>
<p>You should be able to reason that naiveSearch has O(<em>n</em>) asymptotic complexity as its worst case runtime complexity. The reason in short is that if the target User happens to be located at <em>n</em>, then we must invariably traverse the entire collection to get there.</p>
<p>If you are not already familiar with the Binary Search (BS) algorithm, then you should prepare to have your mind blown.</p>
<p>What if I told you that by using a BS algorithm to search our collection with one million elements, you will only ever make, at most, 20 comparisons? That is right; 20 comparisons (as opposed to 1 million with NS) <em>is the worst case scenario</em>.</p>
<p>Now, I will explain how BS works in principle, but my one piece of homework for you to do is to implement it in your preferred programming language. It may be that the language you choose already has a BS implementation from its standard library, but this is an important learning exercise!</p>
<p>In principle, rather than searching an <em>ordered</em> collection one by one, unidirectionally, we start by looking at the value at index <em>n</em>/2. So in a collection with 10 elements, we would check the fifth element. The ordering is important, because we can then compare the element at <em>n</em>/2 with our target:</p>
<ul>
<li><p>If the value of that element is greater than the target, we know that the element we want must be located earlier in the collection</p>
</li>
<li><p>If the value of that element is less than the target, then we know that the element we want must be located further ahead in the collection</p>
</li>
<li><p>You should be able to guess what happens if we have a match</p>
</li>
</ul>
<p>Now, the idea is that we are cutting the dataset in half every iteration. Suppose the value at element <em>n</em>/2 was less than our target value. We would next select the middle index between <em>n</em>/2 and <em>n</em>.</p>
<p>From there, our algorithm keeps slicing back or forth using the same logic over a smaller and smaller range of indexes in our collection.</p>
<p>This brings us to the beauty of the BS algorithm applied to a sorted collection: Rather than the time it takes to complete growing linearly, or exponentially with respect to <em>n</em>, it grows logarithmically:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/logarithmic_complexity.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>A Binary Search has logarithmic runtime complexity, which means that it handles large values of n like a boss (very well)</em></p>
<p>If this article really is your first introduction to the main ideas in software engineering, then please do not expect everything to make sense immediately.</p>
<p>While I hope that some of my explanations helped, my primary goal was to give you a basic list of ideas to study yourself, and what I believe to be a good order in which to study those ideas.</p>
<p>The next step for you is to make a plan for learning this field, and to take action on it. The following section is all about how to do that.</p>
<h2 id="heading-how-to-learn-software-engineering-some-practical-advice">How to Learn Software Engineering – Some Practical Advice</h2>
<p>I will now discuss some ideas and approaches which I have personally used to make the process of learning various DS and algorithms easier (but not easy!), both practically, and from motivational perspective.</p>
<p>I am confident that there will at least be one or two points here which will be useful (assuming you have not already arrived at them yourself), but I also want to emphasize that our brains might work slightly differently. Take what is useful and throw away the rest.</p>
<p>As a learning aid, you might also want to watch my live lesson on youtube where I cover this topic. Do not skip the rest of this article though; I go into much more detail here!</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/UwMJtq6bvXg" 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>
<h3 id="heading-follow-a-project-based-learning-approach">Follow A Project-Based Learning Approach</h3>
<p>This is actually the first thing I tell any new programmer who asks me the “best way” to learn how to code. I have given a longer version of this explanation many times, but I will summarize the general idea.</p>
<p>In any field of programming, you will notice that there is an incredibly large number of topics to study, and the field itself is constantly evolving both for academics and industry professionals.</p>
<p>As I mentioned in the introduction, not only did I have no curriculum to guide my studies, but I also had limited time to study because I had rent due at the end of each month. This led me out of sheer necessity to develop and follow my project based learning approach.</p>
<p>In essence, what I suggest you do is to avoid learning DS &amp; Algorithms by simply studying things topic by topic and just taking notes about each one.</p>
<p>Instead, you will start by picking a basic topic (like the ones I covered before) and immediately writing a code snippet or small application which uses it.</p>
<p>I created a repository which had a package for every family of DS &amp; algorithm that I wanted to learn. For general algorithms it was mostly the sorts and searches (Bubble Sort, Merge Sort, Quick Sort, Binary Search, and so on). For more specific DS like Linked Lists, Trees, Heap, Stack, and others, I wrote both the DS itself and a few algorithms specific to that particular DS.</p>
<p>Now, I found that some kinds of DS were difficult to understand and implement at first.</p>
<p>One family of DS which gave me trouble for quite some time were called “Graphs.” The field in general is full of some particularly awful and overloaded jargon, but this particular topic even has a misleading name (hint: a better name would be “Networks”).</p>
<p>After spinning my wheels for several weeks (although in fairness I was learning this on the side), I finally admitted to myself that I needed a clear reason to use this DS in some application code. Something to justify and motivate the many hours I was going to spend learning this topic.</p>
<p>Having previously built a Sudoku game using algorithms that worked with two and one dimensional Arrays, I recalled reading somewhere that it was possible to represent and solve a Sudoku game using an <em>Undirected Colored Graph</em>.</p>
<p>This was incredibly useful, as I was already familiar with the problem domain of Sudoku, so I could focus intensively on DS and algorithms.</p>
<p>While there is plenty more that I have to learn, I cannot describe how satisfying it was when I wrote an algorithm that generated and solved 102 Sudoku puzzles in 450 milliseconds.</p>
<p>Speaking of, let me talk about another way to write better algorithms which can also be a great source of motivation and goal setting.</p>
<h3 id="heading-test-your-code">Test Your Code</h3>
<p>Look, I know many people make the subject of testing a complete nightmare for beginners. This happens because they confuse the very simple idea of how to test code with some very elaborate and confusing tools one can <em>optionally</em> use to test their code. But this one is important so please stay with me.</p>
<p>To go back to basics, without even talking about Big O notation, how do we know if one algorithm is more efficient than another? Of course, we have to test them both.</p>
<p>Now, it is important to mention that benchmark tests can give you a good (or even great) general idea, but they are also strongly influenced by the system in which they are tested.</p>
<p>The more precise your tests need to be, the more concerned you will need to be about your test environment, set up, and accuracy. However, for the kind of code I typically write, a good general idea is all I need.</p>
<p>There are two kinds of tests which I find most useful for when I am writing my algorithms, both for practice and production code. The first kind of test answers a very simple question: Does it work?</p>
<p>To take an example from my Graph Sudoku application, one of the first hurdles for me was to build what is called an Adjacency List for Sudokus of varying sizes (I tested 4, 9, 16, and 25, which are, not by accident, perfect squares (mathematically speaking).</p>
<p>I cannot explain what an Adjacency List is in detail, but think of it conceptually as a Network of nodes and lines (called <em>edges</em> for some reason). In practice, it forms the virtual structure of the “Graph.”</p>
<p>In the rules for Sudoku, every column, row, or subgrid of numbers may not contain any repeats. From these rules, we can deduce that in a 9x9 Sudoku, there must be 81 nodes (one for each number), and each node ought to possess 21 edges (one for every other node in a given column, row, or subgrid).</p>
<p>The first step was to simply check to make sure that I was building the correct number of nodes:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Test</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">verifyGraphSize</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">//note: In Kotlin, brackets following a class name denotes </span>
    <span class="hljs-comment">//an assignment statement; it does not use a "new" keyword</span>
    <span class="hljs-keyword">val</span> fourGraph = SudokuPuzzle(<span class="hljs-number">4</span>, Difficulty.MEDIUM)
    <span class="hljs-keyword">val</span> nineGraph = SudokuPuzzle(<span class="hljs-number">9</span>, Difficulty.MEDIUM)
    <span class="hljs-keyword">val</span> sixteenGraph = SudokuPuzzle(<span class="hljs-number">16</span>, Difficulty.MEDIUM)
    assert(fourGraph.graph.size == <span class="hljs-number">16</span>)
    assert(nineGraph.graph.size == <span class="hljs-number">81</span>)
    assert(sixteenGraph.graph.size == <span class="hljs-number">256</span>)
}
</code></pre>
<p>The algorithm for that was really quite easy to write, but things were slightly more difficult for the next one.</p>
<p>Now I needed to, as they say in Graph jargon, build the <em>edges</em>. This was a bit trickier as I had to write some algorithms to select for rows, columns, and subgrids of dynamic size. Again, to confirm that I was on the right track, I wrote another test:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Test</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">verifyEdgesBuilt</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">val</span> fourGraph = SudokuPuzzle(<span class="hljs-number">4</span>, Difficulty.MEDIUM)
    <span class="hljs-keyword">val</span> nineGraph = SudokuPuzzle(<span class="hljs-number">9</span>, Difficulty.MEDIUM)
    <span class="hljs-keyword">val</span> sixteenGraph = SudokuPuzzle(<span class="hljs-number">16</span>, Difficulty.MEDIUM)
    fourGraph.graph.forEach {
        assert(it.value.size == <span class="hljs-number">8</span>)
    }
    nineGraph.graph.forEach {
        assert(it.value.size == <span class="hljs-number">21</span>)
    }
    sixteenGraph.graph.forEach {
        assert(it.value.size == <span class="hljs-number">40</span>)
    }
}
</code></pre>
<p>Sometimes I followed the Test Driven Development (TDD) approach and wrote the tests before the algorithms, and sometimes I wrote the tests after the algorithms.</p>
<p>In any case, once I was able to verify the correctness of each algorithm to the point that I was generating a solved, variably sized Sudoku puzzle, it was time to write a different set of tests: Benchmarks!</p>
<p>This particular kind of benchmark testing is quite blunt, but that is all I needed. To test the efficiency of my algorithms, which at this stage could build and solve a randomly generated Sudoku, I wrote a test which generated 101 Sudoku puzzles:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Test</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">solverBenchmarks</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">//Run the code once to hopefully warm up the JIT</span>
    SudokuPuzzle(<span class="hljs-number">9</span>, Difficulty.EASY).graph.values.forEach {
        assert(it.first.color != <span class="hljs-number">0</span>)
    }
    <span class="hljs-comment">//loop 100 times</span>
    (<span class="hljs-number">1</span>..<span class="hljs-number">100</span>).forEach {
        SudokuPuzzle(<span class="hljs-number">9</span>, Difficulty.EASY)
    }
}
</code></pre>
<p>Initially I had two calls to System.nanoTime() immediately before and after generating 100 puzzles, and subtracted the difference to get an unintelligible number.</p>
<p>However, my IDE also kept track of how long a test would take to complete in minutes, seconds, and milliseconds, so I eventually just went with that. The first set of benchmarks (for 9x9 puzzles) went as follows:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">/**
* First benchmarks (101 puzzles):
* 2.423313576E9 (4 m 3 s 979 ms to completion)
* 2.222165776E9 (3 m 42 s 682 ms to completion)
* 2.002508687E9 (3 m 20 s 624 ms ...)
* ...
*/</span>
</code></pre>
<p>Although I did not have much of a reference point, I knew that it was taking longer than a second to generate a 9x9 Sudoku, which was a <em>very bad sign</em>.</p>
<p>I was not happy about how I was preloading the Graph with some valid numbers ahead of time, so I decided to refactor my approach there.</p>
<p>Naturally, the result after thinking up a new way to do that was worse:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">/**
* ...
* Second benchmarks after refactoring seed algorithm:  (101 puzzles)
* 3.526342681E9 (6 m 1 s 89 ms)
* 3.024547185E9 (5 m 4 s 971 ms)
* ...
*/</span>
</code></pre>
<p>After quite a few more benchmarks which seemed to get slightly worse over time, I was pretty demoralized and wondering what to do.</p>
<p>I had what I thought was a very ingenious way to make my algorithm more or less picky based on how certain it was about placing a number into the puzzle. It was not working out so well in practice, though.</p>
<p>As is often the case, on roughly the 400th pass of my code via a code stepper (part of a debugging tool), I noticed that I had a slight mistake which had to do with how I was adjusting the value which dictated how picky my algorithm was.</p>
<p>What happened next blew my mind.</p>
<p>I ran another benchmark test, and got a weird result:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">/**
* ...
* Fifth benchmarks niceValue only adjusted after a 
* fairly comprehensive search (boundary * boundary) 
* for a suitable allocation 101 puzzles:
* 3774511.0 (480 ms)
* ...
*/</span>
</code></pre>
<p>I was in complete disbelief, so the first thing I did was to undo the change I just made and rerun the test. After 5 minutes I stopped the test as this was clearly the game changing difference, and proceeded to run five more benchmarks:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">/**
* 3482333.0 (456 ms)
* 3840088.0 (468 ms)
* 3813932.0 (469 ms)
* 3169410.0 (453 ms)
* 3908975.0 (484 ms)
* ...
*/</span>
</code></pre>
<p>Just for the hell of it, I decided to try building 101 16x16 puzzles. Previously I couldn't even build one of these (at least I stopped trying after the test ran for 10 minutes):</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">/**
* 16x16 (all previous benchmarks were for 9 * 9):
* 9.02626914E8 (1 m 31 s 45 ms)
* 7.75323967E8 (1 m 20 s 155 ms)
* 7.06454975E8 (1 m 11 s 838 ms)
* ...
*/</span>
</code></pre>
<p>The point I am trying to communicate is this: It is not just that writing tests allowed me to <strong>verify that my algorithms were working</strong>. They allowed me to have an objective way to establish their efficiency.</p>
<p>By extension, this gave me a very clear way to know which of the 50 different tweaks to the algorithm I made actually had a positive or negative effect on the outcome.</p>
<p>This is important for the success of the application, but it was also incredibly positive for my own motivation and psychological health.</p>
<p>What I did not yet mention is that the time it took me to get from the first benchmark to the fifth (the fast one), was approximately 40 hours (four days at 10 hours per day).</p>
<p>I really was quite demoralized by the fourth day, but when I finally tweaked things the right way, it was the first time I ever felt like a real software engineer instead of just someone studying it for fun.</p>
<p>To leave you with a great image, after I ran the 16x16 tests and saw they were promising, I took a full 15 minutes to run around my rural property hollering like an excited chimpanzee that just got dosed with adrenaline.</p>
<h2 id="heading-my-final-suggestion">My Final Suggestion</h2>
<p>I will keep this one short and sweet. The worst thing you can do as a student, upon not being able to understand something difficult and complicated, is to blame yourself.</p>
<p>Good teachers and explanations are rare, and this is particularly true of topics which most of us find relatively dry and boring.</p>
<p>I had to watch approximately four videos, read approximately five articles/textbook chapters, and blindly dive into writing some code which did not initially make sense to me, just to even get started with <em>Graphs</em>.</p>
<p>This may be good or bad news for you, but I work very hard at what I do, and I very rarely find things in my field which are natural or easy for me.</p>
<p>My goal with this article has never been to imply that learning software engineering was easy for me, nor that it will be easy for you.</p>
<p>The difference is that I am told from time to time that I explain things well, and that unlike people who just regurgitate what other teachers say, I put the time in to find out what works or does not work for me, and try to share that with you.</p>
<p>I truly hope that something in this article was useful for you. Good luck with your learning goals, and happy coding!</p>
<h3 id="heading-before-you-go">Before you go...</h3>
<p>If you like my writing, you will probably like my video content. I create everything from dedicated tutorials on specific topics, to weekly live Q&amp;A sessions, to 10+ hour coding marathons where I build an <a target="_blank" href="https://youtu.be/Fs0q_LsgLDk"><strong>entire application in one sitting</strong></a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Your Future Self Up for Success with Good Coding Habits ]]>
                </title>
                <description>
                    <![CDATA[ Think before you code. You have the power to make your future self's life Heaven on Earth or a living hell. In this article we'll explore what kinds of things you can do to make it a little easier on your future self. Revisiting "prior art" We've all... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/set-future-you-up-for-success-with-good-coding-habits/</link>
                <guid isPermaLink="false">66bee9536769d2581da6f951</guid>
                
                    <category>
                        <![CDATA[ Self-awareness ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 100Days100Projects ]]>
                    </category>
                
                    <category>
                        <![CDATA[ clean code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Code Quality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ code review ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fundamentals ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Self Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Thu, 16 Apr 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/04/set-up-for-success.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Think before you code. You have the power to make your future self's life Heaven on Earth or a living hell.</p>
<p>In this article we'll explore what kinds of things you can do to make it a little easier on your future self.</p>
<h2 id="heading-revisiting-prior-art">Revisiting "prior art"</h2>
<p>We've all been there. Six months into a project, you're trying to squash a bug, and what you find is shocking. You might be asking yourself, "who would write this kind of code?"</p>
<p>So you dig through your <a target="_blank" href="https://git-scm.com/">git</a> commit history using <code>git log -p filename.js</code> showing changes for a specific file, trying to see who would come up with something like that. And then your heart drops – you're the one who wrote it!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/tituss-burgess-shocked.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Tituss Burgess shocked</em></p>
<p>This is a common scenario for any developer, experienced or new. If you haven't hit that scenario, I promise if you stick with coding long enough, you will.</p>
<h2 id="heading-becoming-more-conscious-about-our-coding-habits">Becoming more conscious about our coding habits</h2>
<p>That six month reflection point is inevitable. That's a lot of time which you've most likely been using to work on other parts of the project or another project completely. Chances are, you've leveled up which has changed the way you write code.</p>
<p>On the other hand, sometimes it takes stepping outside of the code to see the bigger picture and get a better look at how all the pieces fit together. We can naturally dig ourselves too deep into a solution and can become a little narrowly focused as we work to solve those challenges.</p>
<p>But either way, while part of the code journey will simply be gaining more experience and learning more about your craft, there are other small habits you can get used to early on that will help you down the road.</p>
<p>So let's jump in.</p>
<h2 id="heading-improving-the-readability-of-your-code">Improving the readability of your code</h2>
<h3 id="heading-what-is-the-challenge">What is the challenge?</h3>
<p>Part of the fun about our craft is there are a ton of ways you can do the same thing. Think an <code>if</code> statement is too many lines? Well we can write it <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator">ternary</a> style!</p>
<pre><code class="lang-js"><span class="hljs-comment">// Example ternary statement</span>
<span class="hljs-keyword">const</span> isFreezing = temperature &lt;= <span class="hljs-number">32</span> ? <span class="hljs-literal">true</span> : <span class="hljs-literal">false</span>;
</code></pre>
<p>But sometimes this takes a toll on the readability of your code. While it might seem like it looks nice and super clean on one line, imagine that as that ternary gets more complex, someone will have to spend more time understanding what it means.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> minutes = <span class="hljs-number">30</span>;
<span class="hljs-keyword">const</span> cookie = {
  <span class="hljs-attr">color</span>: <span class="hljs-string">'black'</span>
};

<span class="hljs-keyword">const</span> cookieStatus = minutes &gt; <span class="hljs-number">20</span> ? cookie.color === <span class="hljs-string">'black'</span> ? <span class="hljs-string">'burned'</span> : <span class="hljs-string">'done'</span> : <span class="hljs-string">'not done'</span>;
</code></pre>
<h3 id="heading-what-can-we-do-better">What can we do better?</h3>
<p>Now I would imagine most of us can figure out what <code>cookieStatus</code> is in this example (spoilers: <code>burned</code>). But think about the time you spent figuring it out. Whether an extra 1s or 2s, it forces you to spend additional cognitive energy to read through the code.</p>
<p>On the other hand:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> minutes = <span class="hljs-number">30</span>;
<span class="hljs-keyword">const</span> cookie = {
  <span class="hljs-attr">color</span>: <span class="hljs-string">'black'</span>
};
<span class="hljs-keyword">let</span> cookieStatus;

<span class="hljs-keyword">if</span> ( minutes &lt;= <span class="hljs-number">20</span> ) {
  cookieStatus = <span class="hljs-string">'not done'</span>;
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ( cookie.color === <span class="hljs-string">'black'</span> ) {
  cookieStatus = <span class="hljs-string">'burned'</span>;
} <span class="hljs-keyword">else</span> {
  cookieStatus = <span class="hljs-string">'done'</span>;
}
</code></pre>
<p>No, it may not be as clean or clever as the 1-line ternary statement, but the next time you visit it, the less you'll have to think about what the answer is. </p>
<p>It's also going to make it that much easier for bugs to creep up and get past your code reviewers when all of your code changes are in a 1-line git diff.</p>
<p>And yes, this is a simple example. But imagine this in a real world scenario with important business logic where you could run into these situations frequently.  </p>
<p>Say you need to add another condition – that ternary is just going to keep getting more complex! You're just making it more difficult to debug or extend, where the <code>if</code> statements can continue on in an easily readable way.</p>
<p>For what it's worth, ternaries and other shortcuts can be simple and effective in code, but don't abuse that effectiveness and end up making things more difficult.</p>
<h2 id="heading-keeping-things-consistent">Keeping things consistent</h2>
<h3 id="heading-what-is-the-challenge-1">What is the challenge?</h3>
<p>We all have our favorite way to code. Though I'd argue not including a semicolon at the end of your JavaScript is just completely wrong, you might prefer to write your code the wrong way without them.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Jim's code style</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleOnClick</span>(<span class="hljs-params"></span>) </span>{
    alert(<span class="hljs-string">'Click!'</span>)
  }
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleOnClick}</span>&gt;</span>My Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  )
}

<span class="hljs-comment">// Creed's code style</span>

<span class="hljs-keyword">const</span> MyComponent = <span class="hljs-function">() =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> alert('Click!')}&gt;My Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
</code></pre>
<p>But it's not always about what <em>you</em> prefer. When working with a team, chances are, everyone's opinion on how code should look is slightly different. You might agree about the semi-colon, but disagree about whitespace.</p>
<p>And no one is wrong (except for the non-semi-coloners)! There are valid arguments to most code styles, whether for or against, but the solution isn't for everyone to write their code their own way.</p>
<h3 id="heading-what-can-we-do-better-1">What can we do better?</h3>
<p>Keeping code consistent is important to maintain code health. A typical goal is to "make the codebase look like one person wrote it."</p>
<p>The point isn't that one person gets their way, it's that the team came to a conclusion about a set of rules they would use that everyone would follow. Having this consistency provides less cognitive overhead as people work through the code. It gives everyone the ability to know what to expect when reading the code.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/linting-code.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Errors from linting code</em></p>
<p>And achieving this doesn't need to be hard. There are tools that can simply <a target="_blank" href="https://www.colbyfayock.com/2019/10/what-is-linting-and-how-can-it-save-you-time">check for these inconsistencies</a> like <a target="_blank" href="https://eslint.org/">Eslint</a> for Javascript. And even better, there is another level of tools like <a target="_blank" href="https://prettier.io/">Prettier</a> that <a target="_blank" href="https://www.colbyfayock.com/2019/11/dont-just-lint-your-code-fix-it-with-prettier">will fix it for you</a>!</p>
<h2 id="heading-commenting-your-code">Commenting your code</h2>
<h3 id="heading-what-is-the-challenge-2">What is the challenge?</h3>
<p>Keeping up with commenting your code is an important way to put context to complex logic. As much as we all want our code to be self-documenting, that's rarely the case.</p>
<p>Too often we find ourselves dealing with a block of code that just doesn't make sense. And even if it makes sense on its own, we might not be able to figure out how it fits in to the rest of the application.</p>
<h3 id="heading-what-can-we-do-better-2">What can we do better?</h3>
<p>By providing a good set of comments, you're setting up the next person who touches that code to have a better understanding of what the code is doing before they make a change.</p>
<pre><code class="lang-js"><span class="hljs-comment">// DONT CHANGE - WILL STOP MAKING MONEY</span>

<span class="hljs-keyword">const</span> shouldMakeMoney = <span class="hljs-literal">true</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">makeMoney</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">if</span> ( shouldMakeMoney ) {
    <span class="hljs-keyword">return</span> noMoney;
  }
  <span class="hljs-keyword">return</span> moreMoney;
}
</code></pre>
<p>While this is a silly example, it brings up a real world case. Businesses are increasingly dependent on being able to maintain a reliable website to make money. Whether this is as an ecommerce business or an ad giant, these websites rely on business logic that determine things like cost, taxes, discounts, and other math related things we tend to not want to think about, but could make or break a business on the internet.</p>
<p>But it's not all about the company you work for. Touching old code can be scary. It's even scarier when no one on your team was around when it was written, so no one knows what it does!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/patton-oswalt-hands-over-mouth.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Patton Oswalt hands over mouth</em></p>
<p>While you might not be the next person who touches that code, try to help out your future friend who's tackling the next ticket involving that code. Because there's also a good chance you will be that person and you'll wish you remembered how it worked.</p>
<h2 id="heading-documenting-your-solutions">Documenting your solutions</h2>
<h3 id="heading-what-is-the-challenge-3">What is the challenge?</h3>
<p>Documentation is similar to commenting your code, but from a different perspective. Documentation and commenting are both about finding ways to describe a solution in a human-readable way that will ultimately give more context. But documentation is more about the overall solution rather than the implementation details.</p>
<p>Having a high performing application is everyone's goal. But how did we get there? There's a realistic chance that someone will have to be working on the same project you are like onboarding a new team member. How will they be able to maintain that high performance if they don't know how it works?</p>
<h3 id="heading-what-can-we-do-better-3">What can we do better?</h3>
<p>Whether it's introducing that new team member to the project or trying to share knowledge with another project team, documentation is an important part of maintaining a project. It helps keep everyone on the same page so we all confidently know what we're working towards.</p>
<p>For example, if we're still working with our ecommerce project with our business logic, there will be rules that the code needs to implement. While commenting might give details inline about how the rules were implemented, the documentation would define those rules.</p>
<pre><code class="lang-js"><span class="hljs-comment">/**
 * DOCUMENTATION
 * Order Total &gt;= 25: Discount %10
 * Order Total &gt;= 50: Discount %15
 * Order Total &gt;= 100: Discount %20
 * Order Total &gt;= 75: Free Shipping
 */</span>

<span class="hljs-keyword">const</span> orderSubTotal = <span class="hljs-number">84.00</span>;
<span class="hljs-keyword">let</span> orderTotal = orderSubTotal;

<span class="hljs-comment">// If the order total is under 75, apply shipping discount</span>

<span class="hljs-keyword">if</span> ( orderTotal &lt; <span class="hljs-number">75</span> ) {
  orderTotal = addShipping(orderTotal);
}

<span class="hljs-comment">// If the order total reaches a threshold, apply given discount</span>

<span class="hljs-keyword">if</span> ( orderTotal &gt;= <span class="hljs-number">100</span>) {
  orderTotal = applyDiscount(orderTotal, <span class="hljs-number">.2</span>);
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ( orderTotal &gt;= <span class="hljs-number">50</span> ) {
  orderTotal = applyDiscount(orderTotal, <span class="hljs-number">.15</span>);
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ( orderTotal &gt;= <span class="hljs-number">25</span> ) {
  orderTotal = applyDiscount(orderTotal, <span class="hljs-number">.1</span>);
}
</code></pre>
<p>This is a minimal example, but we can see the difference between the rules at the top and how we apply them. The documentation should clearly explain what the rules are, but it shouldn't care about how those rules were implemented.</p>
<p>On the other hand, the comments might not care about what the rules are, but need to implement them in an efficient and logical way. We should be able to update the code with the business rules, such as changing the top level discount tier from $100 to $80, without having to rework the code.</p>
<p>But documentation is much more than business rules – it's providing a way for anyone to understand your work from a higher level. This could include anything from architectural diagrams to the theory behind your core algorithm.</p>
<p>While maybe code isn't the best place for details like this to live, it's really important information that can help instill confidence in your project and give others an opportunity to understand more about the work.</p>
<h2 id="heading-creating-effective-pull-requests">Creating effective Pull Requests</h2>
<h3 id="heading-what-is-the-challenge-4">What is the challenge?</h3>
<p>Pull requests (or merge requests) are a core part of any development team's project lifecycle. It provides a way to package and present your code in a consumable way for your peers to review and understand your work.</p>
<p>There's a lot that can go into a pull request from a single commit to the entirety of the next version of your website. That's a lot of context to expect someone to understand by reading through the commits alone.</p>
<h3 id="heading-what-can-we-do-better-4">What can we do better?</h3>
<p>Pull requests don't need to be an art. There should be one primary goal of the preparation you put into it – providing context into your changes. At a minimum, it should answer the questions of "what" and "why".</p>
<p>We can even use tools like pull request templates to push us in the right direction. <a target="_blank" href="https://www.freecodecamp.org/news/why-you-should-write-merge-requests-like-youre-posting-to-instagram-765e32a3ec9c/">Define an outline</a> of what you want explained and chances are, people will follow that outline. This helps avoid the 1-line "closes [ticket]" description or even worse, an empty description.</p>
<p>With my projects, I hope to have a few questions answered before I dive into a code review:</p>
<ul>
<li>What is the change?</li>
<li>What does it impact?</li>
<li>How do I reproduce or test the change?</li>
</ul>
<p>Just a few details around the change set can provide much needed context for those reviewing your code. It's easy to look at code, but it's harder to understand it without knowing how it fits into the bigger picture.</p>
<h2 id="heading-hardening-your-code-with-tests">Hardening your code with tests</h2>
<h3 id="heading-what-is-the-challenge-5">What is the challenge?</h3>
<p>Tests are a way to ensure your code runs the same way each time. Being able to prove that the same input will always have the same output will help provide you and your team with a higher level of confidence that your application won't come crashing down with the next small change.</p>
<p>Without them, we're left with human error, where no matter how good your QA Engineer is (shoutout to my testers out there), something will always slip through. And that's not to say your tests will always catch every problem, but we can use the tools available to help prevent it.</p>
<h3 id="heading-what-can-we-do-better-5">What can we do better?</h3>
<p>Where comments are a way of providing the context of how something works, test are a way to ensure they work. Providing test cases that are repeatable helps enforce that.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">applyDiscount</span>(<span class="hljs-params">value, discount</span>) </span>{
  <span class="hljs-keyword">const</span> discountAmount = value * discount;
  <span class="hljs-keyword">return</span> value - discountAmount;
}

expect(applyDiscount(<span class="hljs-number">10</span>, <span class="hljs-number">.1</span>)).toEqual(<span class="hljs-number">.9</span>);
expect(applyDiscount(<span class="hljs-number">532151235</span>, <span class="hljs-number">.1054</span>)).toEqual(<span class="hljs-number">476062494.831</span>);
</code></pre>
<p>If I fudge the math on our <code>applyDiscount</code> function above, there's a high probability that the test would fail (never say never).</p>
<p>But testing doesn't need to be hard. There are many tools out there that help from different perspectives. For example, you might use <a target="_blank" href="https://jestjs.io/">Jest</a> to run your unit tests or add <a target="_blank" href="https://enzymejs.github.io/enzyme/">Enzyme</a> on top to test your React components. But you can also bring in <a target="_blank" href="https://www.cypress.io/">Cypress</a> as an integration test solution that will work like a robot clicking through your application to make sure all the components actually work together.</p>
<p>There's also different methodologies of testing. While you probably see most teams write their tests after they have a working solution, some people swear by <a target="_blank" href="https://en.wikipedia.org/wiki/Test-driven_development">test-driven development</a>. They might write their tests first where the code has to pass the tests rather than the other way around. This is a great way to define the requirements of the code before diving right in.</p>
<p>Whatever the method, capture the points that are most likely to break or the functions that add the most business value. You'll be helping to prevent a potential business loss or even simpler, a headache.</p>
<h2 id="heading-what-can-we-learn-from-this">What can we learn from this?</h2>
<p>That might be a lot to digest, but they're important points to consider as you grow as a developer. Starting these habits early in your career will help you naturally build these skills and work that way by default.</p>
<p>And if you're late in your career, it's never too late to start. We should all want to strive to be the best developer we can be and do our best to help make our teammate's lives easier, as we're all in this together.</p>
<h2 id="heading-looking-for-more-to-learn">Looking for more to learn?</h2>
<ul>
<li><a target="_blank" href="https://www.colbyfayock.com/2019/08/put-down-the-javascript-learn-html-css">Put Down the Javascript - Learn HTML &amp; CSS</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/02/how-to-become-a-full-stack-web-developer-in-2020">How to Become a Full Stack Web Developer in 2020</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2020/02/what-is-the-jamstack-and-how-do-i-get-started">What is the JAMstack and how do I get started?</a></li>
<li><a target="_blank" href="https://www.colbyfayock.com/2019/10/what-is-linting-and-how-can-it-save-you-time">What is linting and how can it save you time?</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/why-you-should-write-merge-requests-like-youre-posting-to-instagram-765e32a3ec9c/">Why you should write merge requests like you’re posting to Instagram</a></li>
</ul>
<h2 id="heading-whats-your-advice-for-growing-as-a-developer">What’s your advice for growing as a developer?</h2>
<p><a target="_blank" href="https://twitter.com/colbyfayock">Share with me on Twitter!</a></p>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
