A blog about how Swift works and iOS tricks, by Bruno Rocha.
Articles about advanced Swift development in excruciating detail, for free!
How necessary are the programming fundamentals?
I've been meaning to write an article about computer science fundamentals and how it can improve a programmer's career for a long time, but I always had trouble finding a good way of introducing this topic. The reason I'd like to talk about this is first that, well, I really like this field and I feel that most of my programming ability today is a result of having studied this, but also because this topic has been a constant source of frustration for me, and I've been hoping I could address that.
The reason? There's a part of the tech community that absolutely despises this topic, especially when it shows up in interview processes. To be specific, this part of the community is really against the fact that large companies like Google and Apple base their interview processes around a person's knowledge of programming theory, to the point where they actively fight against this practice. This has since evolved in a way where mentioning theory at all in certain places is met with severe backlash, immediately turning it into a holy war.
What do I think about this? Well, I was actually one of these people at one point. I too had my share of bashing this practice, but as my career progressed and I started learning more about programming in general I started to realize that not only things weren't so black and white, but also that there was an important reason for them to be doing that. Today I think that people misunderstand the purpose of this field, especially on why these companies are choosing to give it importance.
Everyone is free to study and specialize in what they want, but I think we as a community should be really careful when we advocate that others should be against something. I honestly believe that these misunderstandings can hurt the careers of those who believe in them and limit what we can achieve as a tech community, and I would like to give you a different point of view as an attempt to give you the full picture and resolve this misunderstanding.
In this article, we'll introduce the field of algorithms and data structures, show how this knowledge is applied in practice using an analogy, and finally use all of that to clarify why large companies like Google and Apple are so focused on it. I hope that this will give you the tools to make your own conclusions about this topic, allowing you to not only understand why they do what they do but also to help you determine if this is something you should be studying to achieve your goals.
Before we continue, an important distinction must be made: The purpose of this article is not to defend these companies' practices of applying difficult whiteboard puzzles in their interviews, but to clarify the concept of why they do so. Whether or not these companies are applying this concept efficiently however, especially when it comes to fairness and inclusion, is a separate issue that will not be touched here. Our objective is to focus solely on the engineering aspect of these interviews.
What's the confusion about?
The most common source of discussions and main source of misunderstandings is how the interview process of large tech companies like Google, Apple and Facebook work.
When regular-sized companies hire programmers, they usually look for people to perform a specific role at a specific platform (for example, iOS Developer). In this case, it's very common for the interview processes to focus on the practical aspects of these platforms, such as understanding how the platform works, the details of certain APIs, and the person's overall ability to work with that specific platform.
Larger companies, however, focus more on the theory of programming, asking questions not about what you can do in a specific platform, but about your understanding of the building blocks that allow such platforms to exist in the first place. This includes understanding the functionality of basic data structures like
Sets, your ability to predict, often in an academic fashion, the performance of your code, and your knowledge of fundamental algorithms like a binary search, often in the shape of a programming puzzle. The field that composes all of this knowledge can have multiple names, with the most common ones being Algorithms and Data Structures and CS Fundamentals.
When you study computer science at a more traditional college, these fundamentals are often introduced as the very introduction to programming. There, while you learn how to code, you will also be studying the fundamentals that will allow you to understand how computer science in general works, and instead of learning how to code for a specific platform, you'll often study programming from a generic and theoretical point of view that can be applied to any field you wish to specialize in the future.
At the same time, it's very common for people to learn programming through bootcamps and online courses. In these mediums, programming is often taught from a more practical perspective. Instead of learning the theory, you go straight to coding on a specific platform of your choice, learning the concepts of programming by seeing them work in practice. As we've seen above, because regular companies put more value on the practical aspects of programming, this is a perfectly fine learning path. In fact, this is how I got into programming!
When a person with the non-traditional background decides that it's time to apply at one of the world's main tech companies, the difference between covered topics in the interview process often catches them by surprise. Even though they have great practical programming experience, nothing they worked on could possibly answer the difficult theoretical content the companies are asking. After a very frustrating interview, the now disappointed person expresses their discomfort with the format and claims that a programmer doesn't need to know these things to perform their job. As I mentioned previously, I was this person at one point.
Here are some common complaint points from those who go through this experience:
- The questions don't reflect what the person will actually do in their job.
- The questions are not indicative of the person's skill in the role being interviewed for. (the job is often for a specific platform, but the questions are almost always completely unrelated to it)
- The questions, in general, are pointless. Why does an iOS developer need to know how sorting functions work?
People who feel this way then claim that this field is something that only academics should worry about, and a practical programmer should not have to deal with this in a job interview.
I think anyone can see why someone would have these views. If you have never been introduced to this field, it can definitely look like it's all about pieces of obscure knowledge that aren't relevant to the actual role. They are called fundamentals, but you can learn how to code without them. Are they really that fundamental? Why do these companies care about them?
What these points misunderstand is the role this knowledge plays in your programming ability. Let's take a look at the third point again:
- The questions, in general, are pointless. Why does an iOS developer need to know how sorting functions work?
Our first impression is to think that these companies are insinuating that you as a programmer need to know these things because that's what your job is going to be about, but that's just not how any of this works. Seriously, nobody is coding custom sorting functions in their apps. Stop thinking that's what the fundamentals are for!
In reality, people use what they know about these sorting functions as a reference to determine how a certain piece of code they're writing should be designed. If this sounds familiar to you, then it's because that's how most of programming works! This is certainly something you do all the time, the difference is just what you're using as a reference.
This implicitness gives people the impression that the fundamentals are useless, while in reality, they're using them all the time! They just probably never made the distinction between what part of their knowledge is platform-specific (like knowing UIKit APIs in iOS) and what is actually fundamental knowledge (like knowing the difference between an
Array and a
Set) that they picked up in practice. In short, even if you never studied CS Fundamentals, you as a professional programmer probably already know part of it, you just skipped the part where you learn how to describe them in a more generic fashion.
What about the other part though? Even though everyone can learn about things like
Arrays in practice, the fundamentals often go much deeper than that. When would knowing the ultra-complicated details of something like an index tree ever be useful for a mobile developer?
Analogy: Becoming a professional musician
To explain this, I would like to draw an analogy with a person's journey of learning a musical instrument. This is because musical instruments are accompanied by music theory, and I find the relation between them to be very similar to the one between programming and algorithms.
21-05-2021 Update: I initially wrote this article comparing FAANG companies to accomplished rock bands, but actual musicians commented saying that a classical orchestra would be a better comparison. I updated the analogy -- thank you for your inputs!
In music, music theory is the study of the practices and possibilities of music. It seeks to define the processes and general principles of music, but also the concepts that define what music itself is, defining exactly what is a note, the theoretical definition of a chord and how it can be manipulated, how chords can be grouped into keys and how musical progression works.
A person who wants to learn an instrument like the electric guitar and is doing music lessons will be introduced to the concept of music theory, but also be told that they don't really need to learn it to learn how to play the guitar. Although they will need to learn the basics of notes and chords, there's no need to get into the deeper complicated details unless the person happens to be interested in that. The learner will be perfectly capable to learn how to play their favorite songs, and maybe even play in a cover band with their friends. As we've seen above, this is exactly the same scenario we see in programming.
In the case of music, the details of music theory start becoming more relevant when the person starts wanting to compose their own songs. Although not an impossible task, if the person doesn't understand the theory, it's likely that these songs are going to be flawed in a way or two. As this person doesn't know chord theory, they will probably have a really hard time figuring out the correct way of achieving sounds that they have never played before -- assuming that they can even determine which sounds they should use. That person is perfectly capable of playing the chords and songs composed by other people, but if they never studied the theory of how that works, they will be hindered when trying to compose their own material. To make it worse, musical progression is not a thing you just come up with -- there are multiple reasons why your favorite songs are your favorite songs, and the concepts that make a song sound pleasant are explained in great detail in music theory. We can say that composing songs is the more explicit application of music theory, which could be comparable to a programmer actually being tasked to code a complicated algorithm.
However, music theory has also an implicit application, which is that people who learn music theory are great musicians in general. Even though the person might not be composing their own songs, their understanding of music likely makes them very comfortable playing and improvising any kind of song. These people are usually extremely skilled, being able to learn how to play new songs by ear without ever needing to check how the band that made the song actually plays it. The logic is simple: they don't need to, because they know what they're doing.
Another implicit benefit of music theory is that it applies to every instrument. People who understand music theory usually have a very easy time mastering different instruments because most of what they know also applies to this new instrument. All they need to learn is how the instrument is played.
These are exactly the benefits that learning CS Fundamentals provide you in everyday programming. Even though you're not "composing your own algorithms", your knowledge of how computer science works provides a serious boost to your programming ability in general. The difference between music and programming is what exactly is "boosted": While a musician that knows the theory will be better at designing and understanding music, a programmer who knows the theory will be better at designing and understanding systems. A person who doesn't know programming theory is perfectly capable of creating a good product from the user point of view, but it's likely that they will be severely hindered from a system design point of view.
It's important to understand however what it's meant by system design in this case; We are not talking about concepts like clean code and SOLID, but how correct your code is from a design, performance and resource management point of view. Note that correct doesn't mean "this code must use this ultra-fast obscure algorithm a Russian man published in 1970, otherwise it's wrong", it simply means that the code you're writing makes sense from an engineering standpoint. I'm gonna say it again: Stop thinking that the fundamentals are only about coding obscure algorithms!
If this doesn't click for you, think how correctness applies in the musician's example: Even though two musicians might be playing the exact same song, one of them might have really bad posture and a choice of chords that is all over the fretboard. The other musician however has learned the proper posture, and their knowledge of theory allows them to find the exact same chords in much more comfortable positions. It's the same song with the same result, but one of the musicians will have a much easier time playing it, while the other one will struggle and likely end up with tendonitis.
Who really needs to learn the theory?
I hope that by now you have a clear view of how a programmer can benefit from studying the fundamentals, but before clarifying why companies like Google actually require them in their interviews, let's first evaluate this knowledge from a career necessity standpoint.
If we go back to the music example, we can say that the necessity of studying music theory in a musician's career will heavily depend on what the musician wishes to achieve:
- Do I want to learn it as a hobby, and never go beyond playing in my couch for fun?
- Do I want to play in a band, and solidify myself as a musical artist?
- Do I aspire to go beyond the mere title of a "musical artist" by living and breathing classical music, becoming an integral part of the Vienna Philharmonic, traveling the world, and going down as a legend that literally shaped the concept of music itself?
It should be clear that our non-orchestra-dreamer-fanatics don't need music theory, as they can definitely achieve everything they want without it. They can still benefit from it if they want -- learning it would allow them to master their instrument, as well as open the door to every other musical instrument. However, from a pure career necessity standpoint, we can safely say that the theory is just a bonus thing they could learn to be a better musician.
The dreamer, however, has a completely different objective. This person is not looking to simply have fun, they want to be part of a group of people who dedicate their entire lives to perfecting music as an art form. A famous orchestra will obviously not accept some random joe who picked up a violin weeks ago -- you must at very least be exceptionally good and versatile as a musician. Even though some professional musicians might argue that even in this case it's technically possible for the person to achieve this goal without formally studying the theory, it's clear that not having a deeper level of knowledge about music would be a major setback in this person's career. In fact, orchestras are so serious that having formally studied music is often a minimum requirement.
Just like in this analogy, the necessity of studying algorithms in your career depends on what you as a programmer want to achieve. If you learned programming as a hobby and don't really want to work with it, then the fundamentals are not necessary at all. Similarly, if you see yourself working at a regular and more practical company, then it's also likely that you will never face a situation where the fundamentals would make a big difference. You could learn it to improve your ability in general, but from a pure necessity standpoint, you can surely live without them.
However, if you aspire to learn multiple platforms, work in a global tech company with amazing salaries and perks, working with incredibly smart people who are at the top of their field helping them literally define what tech is, then it should be clear that even though it's technically possible for you to land this job with 100% practical experience, you as a programmer would seriously benefit from having a deeper level of understanding of the field.
Why are the top-tier companies so focused on the fundamentals?
To understand why larger companies are so obsessed with the theory, we'll focus on one of the other points:
- The questions don't reflect what the person will actually do in their job.
I actually agree with this point, because these companies really do a bad job with their questions. However, what's incorrect with this point is that it misses an important detail of how these companies operate -- a common misunderstanding that we should probably be blaming bad job descriptions for.
While in regular companies you are likely to be hired to perform a very specific role as a specialist, larger companies like Google are almost always focused on engineering T-shapedness and generalism. This means that even though you might be hired to do something specific like iOS development, it's still expected that you the ability to work with different platforms if needed. I work in one of these companies -- even though I work primarily with iOS, there were many cases where a task I was doing involved checking code that was outside of iOS, like a relevant piece of Android code, the functionality of a C++ library, or even writing a new data pipeline inside our backend. This is expected, and as a generalist myself, this is something that I personally really enjoy doing.
I'd say that the reason why this happens is the nature of these companies -- while a regular company is trying to solve a small scale problem that has likely been done before, top-tier companies have to deal with enormous problems that nobody has ever faced, which often requires them to be masters in multiple platforms. It's not interesting for a company like Google to hire someone who dedicated their life to understand all about UIKit in iOS -- their problem is not that they don't know which UIKit APIs to use, is that the APIs they need don't exist at all. These problems are not solved by a person's platform knowledge, but by their understanding of computer science and their ability to craft new and efficient solutions.
Just like how music theory applies to all instruments, the fundamentals apply to all platforms. A reason why these companies focus on them is that it essentially proves that you can work with anything -- even if you never worked with a different platform, knowing the fundamentals will likely make it very easy for you to pick them up. A generalist might not know some random trivia about
UITableView APIs that a specialist would, but they don't need to because this is the programming equivalent of the musician who can learn how to play a song by just listening to it. It's easy for a generalist to learn programming languages and platforms -- what's difficult to learn are programming skills you need to have to use these languages and platforms, which is exactly what the fundamentals prepare you for.
This is why these companies choose to focus on this topic -- while in a regular company you can prove your ability by answering questions about a specific platform, in the larger companies' world of generalists it's your understanding of programming as a concept that proves you're the type of programmer they need.
It sucks to be rejected from a dream company, especially when their process is stressful and difficult, but you must understand what you're getting yourself into -- top-tier companies that have amazing salaries, benefits, free food, off-sites and all have thousands of people applying for the same role. What makes you think you're so good that these companies should drop thousands of candidates and hire you with no questions asked? Are you really sure you have absolutely no room for improvement as a programmer?
I can't help but point out that when people express discontent with interviews they almost always do so from an emotional point of view, almost like a coping mechanism where they blame the company to hide the possibility that there is something that they could improve. I certainly am one to know how that feels -- I got rejected from many companies before landing my current job, and I definitely blamed them too at first when it happened. However, you can't let this overwhelm you because this is simply how the game works -- of course their process is going to be extremely difficult and specific, just look at how many people you're competing with!
If your goal is to work for one of these companies, I think it's really important for you to ground yourself emotionally and consider that there might be many areas you'll need to study to be able to compete for a role. Although this is daunting, it can also be beneficial to you -- considering this possibility will give you a better vision of where you want to go in your career, which could very well be that these companies don't actually suit the roles you want to have. If they do suit it, then consider how important these areas are for them and how they could also benefit you. You're capable, but are you the type of capable they're looking for? They're asking for something that you might not know. What are you willing to do to reach your goals?