I Wish My Undergrad Degree Taught Me These Software Engineering Concepts
Yes, computer science is not the same as software engineering. The difference is like theory vs. practice. However, for many people, it the closest discipline to software engineering offered at their school. A computer science course will be filled with people with a variety of interests and goals — ranging from people that want to be software engineers at a tech company, to aspiring game devs and artists, to entrepreneurs and startup founders, and those interested in computer science research and academia. I found myself in the “wants to become a software engineer” camp and found that my CS coursework didn’t adequately prepare me for practicing software engineering after I graduated.
The basic programming, data structures and algorithms, and operating systems courses taught in a typical computer science degree are all valuable in developing a comprehensive understanding of how computers work and the building blocks of software. Yet, there is so much more in the discipline of software engineering that is not mentioned, and I had to learn the following skills on the job or on my own time.
Dependency Management
In the real-world, dependencies on other people’s code is unavoidable. In school, my professors explicitly forbid using outside code and considered it plagiarism. Of course, the best way to learn something is to do it yourself, but when we’re talking business and developing products, using solutions to problems built and tested by others is the way to go for many situations.
I did not learn about dependency management until I joined Amazon and saw the immense dependency graphs engineering teams had to deal with. I quickly became aware of the need to:
- Analyze the costs/benefits of adding a new dependency or package to a codebase.
- Make sure existing dependencies were up-to-date and secure.
- Ensuring dependency updates didn’t break the code we owned.
Funnily enough, the closest thing to dependency management in my undergrad courses were directed acyclic graphs :).
Agile Development
With the exception of the few group projects you do in school, most assignments are solo operations — and we all know how those group projects go anyways. A group of 3–5 students with no sense of how to divvy up tasks quickly devolves into unfair distribution of work. Agile development has many valid criticisms, but I assert than it’s better than that.
It would’ve been helpful to have been introduced to the agile process in school, it could have even been helpful in other non-computer science group work.
Clean Code
When you finish a course assignment, 99% of the time you submit it and never look at it ever again. I have a graveyard of GitHub repositories because of this. If I opened up one of my assignments a week later it would be an undecipherable mess of single-character variable names and novel-length functions. None of my professors cared about code readability. They all automated the grading of these assignments with their own programs that only checked the output of your work.
During code reviews at work, I quickly learned code not only had to have the correct function but also must be understandable to both you and others. The lifetime of your code can last way after you’ve left your company, and it will probably still have to be read by another engineer. Because of this, I’ve taken on the mindset that I should approach writing code like writing an essay. There should be drafts and even rewrites for especially crucial or complex pieces of logic.
I and thousands of others strongly recommend students read Clean Code by Robert C. Martin or check out this nice summary on GitHub.
Reading and Navigating Large Codebases
This follows from the previous section. Course assignments are often done in a void where you write everything from scratch and only receive any template/starter code from the professor. Regular assignments are also only 500–1000 lines of code so they’re manageable.
Panic ensues when you’re on your first job or internship and you’re faced with a code base of 10K lines of code with dependencies on outside services/teams. My computer science degree did not teach how to read other people’s code. My only advice to get better at this is to find a decently sized open source repo on GitHub and start looking around. You should also start getting familiar with your IDE’s shortcuts for searching for files and finding references and definitions for variables, functions, classes, etc.
The Takeaway
When transitioning from school to my first software engineering job, these were the skills/concepts that I realized I lacked. Even though this list might look completely different for others, I believe there are ways to close this gap on both the education side and employer side. The narrower this gap, the less we’ll see junior engineers feeling unprepared for engineering roles, less imposter syndrome, and ultimately, less burnout.
If you’re a current computer science student:
- Google these concepts and read up on them.
- Get an internship where you’ll learn these things hands on.
- Take software engineering classes and classes that emphasis group projects.
If you’re a hiring or engineering manager:
- Be understanding that there is a growing gap between what a junior developer should know and what is taught is schools.
- Provide the resources needed to train new grads.