If you take programming seriously, don't neglect the fundamentals

If you take programming seriously, don't neglect the 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 because, 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, a group of people, mostly composed of mobile developers, are 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 kind of situation where you should be ashamed for even thinking of bringing this cursed knowledge to the table. This frustrates me because as someone who enjoys studying theory, I can see that people seriously misunderstand the purpose on this field, especially on the 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 on them and limit what we can achieve as tech community, and I would like to attempt to resolve this misunderstanding.

In this article, we'll introduce the field of algorithms and data structures in a neutral way, 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 extremely difficult whiteboard puzzles in their interviews, but to clarify the concept of why they ask these questions. 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 progreammers, 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 Arrays and 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 these 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 bothering with learning 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 the programming, this is a perfectly fine learning path. In fact, this is how I learnt how to code! Did you think I was graduated in computer science? :)

When a person with the more alternate 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. Some of these people even publicly express their discontent with it, claiming that these companies are delusional and that a programmer doesn't need to know these things to perform their job. Because I myself learnt programming through one of these alternative methods, I can say that I also held these opinions at first.

Among the people who are against the practice, common complaint points are:

  • The questions doesn'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 needs 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.

Even though I have a clearly biased opinion, I think anyone can see why someone would have these opinions. If you have never been introduced to this field, it can definitely look like 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 people misunderstand is the role this knowledges plays in your programming ability. Let's take a look at the third complain again:

  • The questions, in general, are pointless. Why does an iOS developer needs to know how sorting functions work?

Somehow 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 a 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 the relation between them is pretty much exactly the same as the one between programming and algorithms.

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 will only become important when the person starts wanting to compose their own songs. Although not an impossible task, if the person doesn't know the theory, it's likely that these songs are going to be hilariously bad. 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 extremely hindered when trying to compose their own material. To make it worse, musical progression is not a thing you just come up with -- songs aren't random, the chords for each song have a theoretical relation to each other. Making a decent song is a science, and one can learn it by understanding the theory. We can say that is the more explicit application of music theory, which could be comparable to a programmer actually being tasked to code these algorithms.

However, music theory has also an implicit application, which is that people who learn music theory become better musicians in general. Even though the person might not be composing their own songs, their understanding of how music works likely makes them extremely comfortable playing and improvising any kind of song. These people are usually extremely skilled, being able to learn how to play new songs by simply hearing them, 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 understand music.

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 every day programming. Even through 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 perfectably 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 bizarre obscure algorithm a Russian man authored 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 used only for coding ultra complicated 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 learnt 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 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 actually play in band, but in a sort of fun way, without taking music that seriously in my life?
  • Do I aspire to make music my life, become the lead guitarrist of Iron Maiden, tour the world, and go down as a legend that literally shaped the very concept of music itself?

It should be clear that our non-Maiden-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 opening the door to every other musical instrument. However, from a pure career necessity stand point, 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 with friends, they want to be part of a group of people that are so good that they can literally influence how the world perceives music. Iron Maiden will obviously not accept some random joe who picked up a guitar weeks ago -- you must understand what you're doing, and for this it should be clear that mastering the concept of music itself is a bare minimum.

Just like in this analogy, the necessity of studying algorithms in your career depends on what you as a programmer wants to achieve. If you learnt 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, more practical company that just happens to need software in a very specific platform, 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 trivial that you as a programmer would 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 complaints:

  • The questions doesn't reflect what the person will actually do in their job.

I actually agree with this complaint, because these companies really do a bad job with their questions. However, what's wrong about this complaint 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 smaller 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. Spotify, where I work, is one these companies -- even though I work primarely with iOS, there were many cases where I task I was doing involved checking code that was outside of iOS, like a relevant piece of Android code, the funcionality 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 really enjoy doing.

I'd say that the reason why this happens is the nature of these companies -- while a smaller company is trying to solve a small scale problem that has likely been done before, top-tier companies have to deal with enourmous 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 solvable by platform experts, but by people who understand computer science theory and can craft new and efficient solutions.

Just like how music theory apply to all instruments, the fundamentals apply to all platforms. A reason why these companies focus on them is because 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.

This is why these companies choose to focus on this topic -- while in smaller companies 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 engineer they're looking for.

I think this is ultimately what people who are frustrated with interviews have trouble seeing: the role you want might not be what a company is looking for. I can't help but point out that people who express discontent with interviews almost always do so from an emotional point of view -- almost like the companies should be delighted to have the opportunity to interview them, and that they are so good that they have no need to demonstrate their programming abilities. What is especially puzzling to me is when this is directed towards top-tier companies that have amazing salaries, benefits, free food, off-sites and all -- these are companies that 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?

It's perfectly fine to not want to get yourself deep into engineering and focus your career on a more specific and higher-level use-case, but if you do so, I think it's really important to drop your pride and manage your expectations of which companies you'll be able to work with. You're good, but are you the type of good these companies are looking for? They're asking for a skill set that you might not have. What are you willing to do to reach your goals?