<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Westin Humble</title>
    <description>The latest articles on Forem by Westin Humble (@wwwestin).</description>
    <link>https://forem.com/wwwestin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F808954%2Fc5799ba0-dbad-4bbf-8fa7-32f84ba73f5a.jpeg</url>
      <title>Forem: Westin Humble</title>
      <link>https://forem.com/wwwestin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/wwwestin"/>
    <language>en</language>
    <item>
      <title>Under the Hood: How BCrypt Functions</title>
      <dc:creator>Westin Humble</dc:creator>
      <pubDate>Thu, 21 Apr 2022 01:16:52 +0000</pubDate>
      <link>https://forem.com/wwwestin/under-the-hood-how-bcrypt-functions-p9p</link>
      <guid>https://forem.com/wwwestin/under-the-hood-how-bcrypt-functions-p9p</guid>
      <description>&lt;p&gt;Something that I often experience as a student software engineer is taking a feature of a web application that I’ve used hundreds (if not thousands) of times before, and then learning how it is implemented/how it functions. It’s actually become one of my favorite aspects about learning the profession thus far! One such concept that I’ve encountered/learned recently is how passwords are securely stored and accessed. Of course, to even get to the point of understanding the above, one must first learn how a user enters that password data into a form and how that data is transferred to a database. After that, one can safely assume that every time you log in you’re just posting the input from the password form to a database, and a function checks to see if that plaintext password matches the username, then you’re good to go, right? Well, if we deploy a website where the sole intention is to compromise our user’s information, then absolutely! But that’s not what we’re about!&lt;/p&gt;

&lt;p&gt;One of the primary tools used in securing passwords (or anything regarded as sensitive information) is hashing. As alluded to above, storing plaintext passwords puts users at risk. People (myself previously very much included) have a strong tendency to use same or similar passwords for multiple websites, and it’s easy to see why. It’s hard to put a number on the average number of applications that a single person has to remember login credentials for, but even if the number was simply five, that’s a lot of effort to generate a secure unique password for each platform! Thus, a data breach has the potential to expose a single user to multiple other breaches (among other risks). Hashing combats this by taking a newly-minted password and generating a fixed-length output. This seemingly unintelligible text that the hash function generates makes password determination difficult, but not impossible.&lt;/p&gt;

&lt;p&gt;Given that a hash always produces a fixed length output, one could take many of the available breached databases on the internet and create a reference of all these known passwords/hashes and cross-reference the database in-question. From there, it’s just a matching game. This is where salting comes in! A salt is just “simply” a random string added to the beginning of a password before it is hashed. This adds another layer of complexity to obtain a databases’ sensitive information. If we could also make the hashing function very computationally expensive, such that the function requires a lot of time/space to re-run a password string, then you have a great recipe to make compromising a database at least way more effort than it’s worth. One broadly used cryptographic function to hash/salt passwords (as well as taking a very long time to do it) is BCrypt.&lt;/p&gt;

&lt;p&gt;As one would surmise, there are many widely available cryptographic functions; two examples being the SHA2 or SHA3 family. Although these perform similar tasks to BCrypt, they are computationally fast, making brute force attacks easier. In addition to the benefit of being computationally slow, BCrypt also has the advantage of scalability. As modern CPUs become predictably faster at computing hashes, BCrypt will run slower and slower given “faster” hardware.&lt;/p&gt;

&lt;p&gt;So we’ve gone over why BCrypt is used, but how exactly does it work? The function can be broken down into two phases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tfqvouv5qw9dtdfek9k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tfqvouv5qw9dtdfek9k.png" alt="BCrypt Algorithm"&gt;&lt;/a&gt;&lt;a href="https://auth0.com/blog/hashing-in-action-understanding-bcrypt/" rel="noopener noreferrer"&gt;https://auth0.com/blog/hashing-in-action-understanding-bcrypt/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Phase 1: A function named “EksBlowfishSetup” is called, taking in the desired cost, salted prepended string, and the password. This is where the bulk of BCrypt’s time is spent; generating a set of subkeys from the primary key (i.e. the password).&lt;/p&gt;

&lt;p&gt;Phase 2: From here, the 192 bit text “OrpheanBeholderScryDoubt” is encrypted 64 times using EksBlowfish in Electronic Code Book (ECB) mode with the state from the previous phase. This produces the cost and 128-bit salt value concatenated with the result of the encryption loop.&lt;/p&gt;

&lt;p&gt;The resulting hash will have some consistent features:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4f9xi97d1d4i9gybi9my.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4f9xi97d1d4i9gybi9my.png" alt="Finished BCrypt Hash"&gt;&lt;/a&gt;&lt;a href="https://blog.boot.dev/cryptography/bcrypt-step-by-step/" rel="noopener noreferrer"&gt;https://blog.boot.dev/cryptography/bcrypt-step-by-step/&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’ll be prefixed by either $2a$, $2y$, or $2b$ (i.e. the algorithm identifier)&lt;/li&gt;
&lt;li&gt;It’ll delineate the cost (10 in this case)&lt;/li&gt;
&lt;li&gt;Then the remaining characters contain the salt/password hash&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simplified: One algorithm (EksBlowfish) performs a lengthy computation based on input, and the results of those computations are encrypted alongside a fixed string (OrpheanBeholderScryDoubt) to create a fixed length hash.&lt;/p&gt;

&lt;p&gt;Once a hash is generated, we need to be able to store it to be compared for authentication purposes. The &lt;a href="https://github.com/bcrypt-ruby/bcrypt-ruby/blob/master/lib/bcrypt/password.rb" rel="noopener noreferrer"&gt;source code&lt;/a&gt; of the BCrypt Ruby Gem actually offers great insight into how this is performed in Rails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First and foremost, keep in mind that knowing what the password’s salt is is the Password object’s responsibility.&lt;/li&gt;
&lt;li&gt;The given password is run through the same function as the stored (with the same salt)&lt;/li&gt;
&lt;li&gt;Then the results are compared to the stored hash&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Viola! The password can be verified in one line of code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe08muu5s8fjac3hi1l4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe08muu5s8fjac3hi1l4g.png" alt="Password Verification in BCrypt within Rails"&gt;&lt;/a&gt;&lt;a href="https://icevans.github.io/bcrypt" rel="noopener noreferrer"&gt;https://icevans.github.io/bcrypt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Resources (url):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://auth0.com/blog/hashing-in-action-understanding-bcrypt/" rel="noopener noreferrer"&gt;https://auth0.com/blog/hashing-in-action-understanding-bcrypt/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.ubiqsecurity.com/ecb-vs-cbc-block-cipher-mode-differences/" rel="noopener noreferrer"&gt;https://www.ubiqsecurity.com/ecb-vs-cbc-block-cipher-mode-differences/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.boot.dev/cryptography/bcrypt-step-by-step/" rel="noopener noreferrer"&gt;https://blog.boot.dev/cryptography/bcrypt-step-by-step/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://icevans.github.io/bcrypt" rel="noopener noreferrer"&gt;https://icevans.github.io/bcrypt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.usenix.org/legacy/publications/library/proceedings/usenix99/full_papers/provos/provos_html/node5.html" rel="noopener noreferrer"&gt;https://www.usenix.org/legacy/publications/library/proceedings/usenix99/full_papers/provos/provos_html/node5.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.usenix.org/legacy/publications/library/proceedings/usenix99/full_papers/provos/provos_html/node4.html" rel="noopener noreferrer"&gt;https://www.usenix.org/legacy/publications/library/proceedings/usenix99/full_papers/provos/provos_html/node4.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>How to Interpret and Use Documentation as a Student Software Engineer</title>
      <dc:creator>Westin Humble</dc:creator>
      <pubDate>Wed, 30 Mar 2022 01:12:49 +0000</pubDate>
      <link>https://forem.com/wwwestin/how-to-interpret-and-use-documentation-as-a-student-software-engineer-5do7</link>
      <guid>https://forem.com/wwwestin/how-to-interpret-and-use-documentation-as-a-student-software-engineer-5do7</guid>
      <description>&lt;p&gt;Since my last blog, I’ve entered into phase 3 of my bootcamp where we’re tasked with learning an entirely new programming language (Ruby) among many other backend-centric concepts. Just like that, despite barely taking the training wheels off with Javascript, it was already time to learn and implement another language. Luckily, after hundreds of repetitions in building apps and solving problems with one programming language, the process is significantly less daunting to learn another.&lt;/p&gt;

&lt;p&gt;10,000 foot view: These languages all need to accomplish similar tasks. You need to be able to define variables. You need to be able to write functions. You need to be able to access and modify data in objects and arrays. In my experience thus far, the real differences come down to syntax and built-in methods. The bridge between your more familiar language’s syntax and built-in methods and the language you’re trying to learn is documentation! However, understanding documentation with the purpose of rapidly applying is a skill in and of itself, and one that will be the focus of this blog.&lt;/p&gt;

&lt;p&gt;In my previous career, I was a Prosthetist/Orthotist. To make that uncommon job description succinct, I used evidence-based practice to restore mobility to people with limb loss and/or a wide swath of neurological and musculoskeletal conditions. One of the toughest and most important aspects of the job was implementing best practice garnered from reading scientific articles/current research (e.g. evidence-based practice). Scientific articles are very dense and overwhelming to digest until one has read many over time, and most importantly, learned how to effectively parse through them to be able to evaluate the quality of the document and implement the findings. &lt;/p&gt;

&lt;p&gt;As I was learning the basics of javascript (and now Ruby), I noticed a lot of similarities between developer documentation (known colloquially and lovingly as “docs”) and scientific articles, and even experienced a similar amount of dread upon first glance! The initial time I had googled “MDN map” to learn how to use that built-in method in a specific case, I left the page more confused than when I arrived. This is unsurprising given that software engineering concepts, like concepts within science, have building blocks that can’t be skipped if full understanding is the goal. That said, even if a grasp on the building blocks is solid, that doesn’t mean that parsing through docs as a beginner can’t be extremely time consuming.&lt;/p&gt;

&lt;p&gt;The parallels between understanding docs and scientific articles (for me), come down to the following two general principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reading the article (or doc) in-full is rarely required. Focus on what you need! For someone practicing evidence-based rehabilitation, it came down to fully comprehending the methods and results sections. The introduction and conclusion are more important to those in academia. Similarly, to borrow from the map example above, it’s doubtful that the ES2015 implementation of your desired built-in method will be relevant to you at the start of your programming journey.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you don’t understand a concept, don’t panic- Google! It was rare that I would come across a novel scientific article and fully understand, for example, a machine they were using for testing and/or an advanced statistical method. A (relatively) quick search would fill in those “building blocks” and allow me to move on in comprehending the article. In the case of software engineering, I had no clue what a callback function was the first time I came across the reference in an MDN doc. Isn’t having unlimited information at your convenient disposal great?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Following these general principles, I’ve been able to greatly expedite my process of learning Ruby. More specifically, I like to quickly hone in on the following four items when parsing through docs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What data type the method takes in &lt;/li&gt;
&lt;li&gt;The needed parameters&lt;/li&gt;
&lt;li&gt;The return value&lt;/li&gt;
&lt;li&gt;An example of implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quickly locating the above will allow me to answer the following questions in a rapid fashion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do my intake, parameters, and return values match?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But what about the locating the example? Were we doing that just for fun? Not quite- the example allows me to have a template to quickly match syntax!&lt;/p&gt;

&lt;p&gt;If the answer is “no” to the first three questions, then chances are you will have to find another built-in method (or no built-in method) to accomplish your goal. But knowing what you can’t do is half the battle! For the rest, chances are Stack Overflow or GitHub will have what you need.&lt;/p&gt;

&lt;p&gt;Consider the following example in Active Record. You need to query in a pry session by the first name (a string) of a user within a database. You find find (pun intended). Will this specific finder method work for your purposes, and using the above questions, how quickly can you determine if it will or won’t?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cdp-XhJj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/47spgwa4b79yolvjt017.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cdp-XhJj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/47spgwa4b79yolvjt017.png" alt="Official documentation of the find findermethod in Active Record" width="880" height="514"&gt;&lt;/a&gt;&lt;a href="https://api.rubyonrails.org/v7.0.2.3/classes/ActiveRecord/FinderMethods.html#method-i-find"&gt;https://api.rubyonrails.org/v7.0.2.3/classes/ActiveRecord/FinderMethods.html#method-i-find&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One final note, learning to correct syntax and incorrect data type errors through error messages in the terminal has become increasingly valuable to (recently) indispensable for me. I suspect this is the case for everyone as they move through their software engineering journey. Remember that errors are every bit as valuable as expected output! When it stops feeling that way, there’s always docs!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
      <category>programming</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Common React Mistakes and the Student Software Engineer</title>
      <dc:creator>Westin Humble</dc:creator>
      <pubDate>Tue, 08 Mar 2022 02:23:46 +0000</pubDate>
      <link>https://forem.com/wwwestin/common-react-mistakes-and-the-student-software-engineer-4ah5</link>
      <guid>https://forem.com/wwwestin/common-react-mistakes-and-the-student-software-engineer-4ah5</guid>
      <description>&lt;p&gt;In my last blog, I had outlined a cursory overview of big O notation and how I thought the student software engineer should employ it. In the second part of this blog series, I want to switch gears to something slightly less abstract, but still emphasizing the student software engineer’s experience.&lt;/p&gt;

&lt;p&gt;Recently, I have begun learning the basics of the popular Javascript library, React. I instantly took to React’s tidy philosophy of front-end development and even got a little misty-eyed at the prospect of (generally) not having to refer to lines 99 and above.&lt;/p&gt;

&lt;p&gt;However, that’s not to say that there wasn’t a learning curve. True to software development form, many of my errors and troubleshooting resolutions came down to small syntax errors and a misunderstanding of a couple of React’s key building blocks. Below are some of the “aha” moments I had (in somewhat chronological order), in hopes that it may save other’s some time!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There’s a reason that it’s called “passing” props. You can’t assume that a child component will have access to props just by virtue of the prop being in a parent component. You must pass the props within the return statement of the parent component, and that props can then be received in the parameters of the child component function. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0r7sXLlU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x0bn61uuk9u9xe0gr45i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0r7sXLlU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x0bn61uuk9u9xe0gr45i.png" alt="Passing props to displayData" width="880" height="237"&gt;&lt;/a&gt;Passing props to displayData&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jnEeQN6S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nm9zy2s15ad8hn7wqf6u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jnEeQN6S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nm9zy2s15ad8hn7wqf6u.png" alt="Display data receiving the props" width="758" height="98"&gt;&lt;/a&gt;Display data receiving the props&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One of the aspects I like about React the most is the emphasis on the single responsibility principle. Along that vein, it’s important to ensure the props, fetches, and anything passed down the component tree has the most efficient path possible. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, it may be tempting to place your fetch in the component at the very top of the tree (let’s call it “App”) given its access to every component. However, if there exists a component that is meant to be a container (let’s call it “containerLol”) for your displayed data with access to all remaining components necessary to render this data- it’d be best to perform the fetch within containerLol (versus App) to avoid unnecessarily passing props and making debugging more time consuming.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6blpdzVZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oi05edsvkvv58b1op8m1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6blpdzVZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oi05edsvkvv58b1op8m1.png" alt="Liam Neeson wanting to render some data in React" width="380" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Although the useState hook is a great tool for right situation, it’s best not to overuse. I definitely went overboard in overusing state early on, and debugging became much more difficult than it should have been. Primarily, these problems arose from state’s asynchronous nature producing outputs from user input that were… less than predictable. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rule(s) of thumb of using state only when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Data can’t be passed via props&lt;/li&gt;
&lt;li&gt;Is not unchanged over time &lt;/li&gt;
&lt;li&gt;Is not computable from other state/props with a component &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;have been very helpful for the purposes of reinforcing good practice on using state.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You know how when you’re learning something new and your references tell you not to do a particular thing and you do it anyway? That was my experience with violating the principle of state’s immutability. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Directly modifying a state variable with a setter function produced one particularly frustrating debugging session. At least when dealing with arrays (which we often are), spread syntax and/or an array method that returns a new array are your friend!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zRFzNiaq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0tzu8v8aeiliipmu3245.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zRFzNiaq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0tzu8v8aeiliipmu3245.png" alt="The way to not update an state variable containing an array" width="876" height="242"&gt;&lt;/a&gt;The way to not update an state variable containing an array&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lhkhMSBQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/howb2nwksta2u1lvhvm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lhkhMSBQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/howb2nwksta2u1lvhvm6.png" alt="The correct way to update an state variable containing an array" width="774" height="254"&gt;&lt;/a&gt;The correct way to update an state variable containing an array&lt;br&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Big O Notation and the Student Software Engineer</title>
      <dc:creator>Westin Humble</dc:creator>
      <pubDate>Sun, 13 Feb 2022 21:32:15 +0000</pubDate>
      <link>https://forem.com/wwwestin/big-o-notation-and-the-student-software-engineer-38hb</link>
      <guid>https://forem.com/wwwestin/big-o-notation-and-the-student-software-engineer-38hb</guid>
      <description>&lt;p&gt;Greetings from (not so sunny) Brooklyn, NY during the early stages of year 2022! I’ve recently begun Flatiron’s Software Engineering 15 week immersive program, and what better way to expand-upon concepts (that the program can often only afford an honorable mention) than blogging? For this series of three blogs, I want to focus on material that I’ve found particularly interesting and how it benefits the student software engineer to at least have a cursory understanding. The first such concept is Big O notation.&lt;/p&gt;

&lt;p&gt;When first learning the basics of Javascript and how to build software/craft solutions for web development, little attention is paid to the efficiency of the algorithms employed. This is understandable, given that it seems like the equivalent of learning an entire written and spoken language in (typically) a relatively short timeframe. At first, the most critical take-aways are the tools you have at your disposal and how/when they are used. Global variables are plentiful, every function (no matter how often it is used) is named. You may even try to make the most deeply nested loop imaginable just to see if you can make it work for a specific purpose! &lt;/p&gt;

&lt;p&gt;At least in the bootcamp setting, this sandbox phase of programming comes to an end quite quickly. Much of this is for readability and best-practice reinforcement. But in the world of web development where one can’t make accurate assumptions about how up-to-date most user’s hardware/operating system is, it becomes important to your code as efficient (i.e. accomplishing as much as it can while using as little resources as possible) as can be. One way to estimate this is Big O notation.&lt;/p&gt;

&lt;p&gt;Invented by German mathematicians Paul Bachmann and Edmund Landau well before electronic computers were viable, Big O notation describes the limiting behavior of a function when the argument tends towards a particular value or infinity. As with many mathematical concepts and notations, Big O has been coopted by by other mathematical theorems as well as for more applied applications, as is the case in computer science. It’s important to note that Big O notation in computer science does not and cannot directly measure a particular algorithm’s complexity/its effect on a given computer’s hardware. It’s also important to note that most algorithms run so quickly/efficiently that their use of resources is negligible. &lt;/p&gt;

&lt;p&gt;So where does Big O notation come into play? For the student software engineer, I believe it comes down to having an understanding of how to categorize an algorithm’s runtime efficiency (expanded upon below) and when to start thinking about your program’s runtime efficiency and the effect it might have on your user’s experience. For the latter, the rule of thumb is to start reducing complexity/using the most optimal tools when you are writing a program that processes a large amount of input data, performs complex operations, and generates a large amount of output data.&lt;/p&gt;

&lt;p&gt;When it comes comes categorization of algorithmic efficiency, it is my understanding that it is not unheard-of to be asked to categorize algorithms according to Big O notation in technical interviews for jobs. Accurate categorization demonstrates that the interviewee has at least an understanding of what/when to avoid come time to start building code snippets and making pull requests.&lt;/p&gt;

&lt;p&gt;The most common categorizations of time/space complexity using Big O notation in web development are constant, logarithmic, linear, and quadratic. Both time and space complexity are measured relative to the the size of the input (i.e. the steps necessary for the algorithm to accomplish its task). Space complexity also tends to be harder to estimate given variation between environments and programming languages. Of note, both time and space complexity can be viewed as an inverse relationship, where (within reason) sacrificing one can benefit the other. &lt;/p&gt;

&lt;p&gt;At the highest level, Big O notation describes how many steps an algorithm takes based on the number of elements that it is acted upon, and classifies it according to the worst case scenario. &lt;/p&gt;

&lt;p&gt;A practical, newbie friendly, non in-depth guide of the most common categorizations are below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constant O(1). Where “1” represents the amount of steps taken to complete the function, an example would be performing a search using an element’s know index value.&lt;/li&gt;
&lt;li&gt;Linear O(n). Where “n” represents the amount of data to be traversed, an example would be iterating through an array, with time complexity increasing by one step per element.&lt;/li&gt;
&lt;li&gt;Logarithmic O(logN). These algorithms are characterized by the the number of operations increasing by one every time the data is doubled. A classic example of using a logarithmic algorithm is searching for a specific name in a phone book. Rather than searching through the whole phonebook, it’s better to start by not looking in in the letter directory where you know their name will not occur. These are especially useful algorithms for large data sets.&lt;/li&gt;
&lt;li&gt;Quadratic O(N^2). Used to characterize algorithms that are quite slow, complexity is proportional to the square of the size of the inputs (e.g. if the input array has 10 elements it will perform 100 operations). An example being a function that traverses through an array twice to find duplicates or a one that requires nested iteration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddptdgpf4bnyyl3ylw6o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddptdgpf4bnyyl3ylw6o.png" alt="Two dimensional graph displaying most common Big O notation categorizations"&gt;&lt;/a&gt;&lt;a href="https://miro.medium.com/max/1400/1*yiyfZodqXNwMouC0-B0Wlg.png" rel="noopener noreferrer"&gt;https://miro.medium.com/max/1400/1*yiyfZodqXNwMouC0-B0Wlg.png&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For further elaboration, below are some built-in array methods within Javascript and their associated Big-O notation classification (IF used on an array). Consider what the method does, the required steps, and the output (if any):&lt;/p&gt;

&lt;p&gt;.indexOf( ) = O(n)&lt;br&gt;
.push( ) = O(1)&lt;br&gt;
.unshift( ) = O(n)&lt;br&gt;
.pop( ) = O(1)&lt;br&gt;
.shift( ) = O(n)&lt;br&gt;
.slice( ) = O(n)&lt;/p&gt;

&lt;p&gt;Need a too long/didn’t read version? For the beginning software engineer, always keep algorithmic efficiency in the back of your mind (along with what tools work best for which scenarios), and make sure to understand the most common categorizations come time for technical interviews in job applications! This was a very condensed overview of a big world when it comes to time/space complexity in software engineering algorithms. There’s a lot to know, and a lot yet to be fleshed out. Feel free to drop a comment with questions, critiques, feedback, or just to say hi! Thanks for reading!&lt;/p&gt;

&lt;p&gt;Final Note === Here’s a nifty web-based tool for directly measuring the time complexity of your algorithms. Just pick a language, paste your code, and give it a run:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tio.run/#" rel="noopener noreferrer"&gt;https://tio.run/#&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sources (url):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.bigocheatsheet.com/" rel="noopener noreferrer"&gt;https://www.bigocheatsheet.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.britannica.com/science/computer-science/Information-management" rel="noopener noreferrer"&gt;https://www.britannica.com/science/computer-science/Information-management&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jackkrupansky.medium.com/what-is-algorithmic-complexity-or-computational-complexity-and-big-o-notation-9c1e5eb6ad48" rel="noopener noreferrer"&gt;https://jackkrupansky.medium.com/what-is-algorithmic-complexity-or-computational-complexity-and-big-o-notation-9c1e5eb6ad48&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://towardsdatascience.com/the-big-o-notation-d35d52f38134" rel="noopener noreferrer"&gt;https://towardsdatascience.com/the-big-o-notation-d35d52f38134&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.webpagetest.org/posts/benchmarking-javascript-memory-usage/#:%7E:text=At%20the%20median%2C%20sites%20are,and%20%7E9.6MB%20for%20mobile" rel="noopener noreferrer"&gt;https://blog.webpagetest.org/posts/benchmarking-javascript-memory-usage/#:~:text=At%20the%20median%2C%20sites%20are,and%20~9.6MB%20for%20mobile&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
