In my sophomore year of college, I took a web development course and got really into the class, having homework assignments like building a small social networking site in PHP and making a web app with the Google Maps API. With projects like that, seeing how creative you could get building stuff with just one semester of material, I instantly knew that web development was what I wanted to do as a job. So as a junior, I declared my CS major and announced joining it on the Tufts CS department's Facebook group with this post.
Having learned to build some pretty professional stuff with just this class, I thought this major was already in the bag. However, I had to to catch up in the CS program in just two years plus the summer session. With that and having to put more effort into the more theory-heavy courses like Algorithms, the major turned out to be different from what I expected, and I spent a lot of senior year wondering how I would turn my incoming degree into a job, while feeling burned out on still being in school.
Now I'm 6 years into working in tech, so I'm going to share 4 things I wish I knew going into my CS major. One note before we start, this advice is mainly aimed at people coming into software engineering since I've never done academic computer science research on the Ph.D track. So if you are more focused on academic CS, I would love for you to comment sharing your perspective on CS careers and on the work you do!
When I started taking more advanced CS classes, I was surrounded by a lot of talented developers who were in the major for all four years. And although I was getting good grades in my courses, I saw my classmates making side projects with hundreds of stars on GitHub, doing exciting internships, and unlocking gold badges on StackOverflow. Because of that I felt super behind and thought I would graduate unemployable. I spent a lot of nights senior year hitting the energy drinks and trying to assemble some sort of side project to catch up with my classmates. This left me burnt out, slipping in my actual classes, and frustrated, having seen a lot of the mythology of the "10x engineer" to make me feel ordinary. This followed me into my computational biology engineer job at MIT, and I still often deal with it.
That feeling that everyone is doing better than you, and where you feel like you pulled the wool over people's eyes to get the success you have, has a name. It's called impostor syndrome, and it's really common in the tech industry. Impostor syndrome is good at lying to people about what great things they can do and give to the community, and making them feel like they don't belong. Personally it's kept me from applying to things like speaking at conferences, or from learning new technologies using one of the fastest strategies to learn, building stuff early and often, as I had a lot of perfectionism.
Some good news, however, is that because this is so common in tech, with even wildly successful people having impostor syndrome, a lot of people are openly telling their stories. So if you do have IS, know that you are not alone, there's nothing shameful about it, and that there are ways of doing self-care for it. How you challenge impostor syndrome is different for everyone, so at the bottom of this post, I will share a few links to great blog posts and resources I've seen for IS and having more self-compassion in tech.
For myself, the main thing I do is find really supportive communities to join with a culture that isn't condescending, so there isn't as much pressure to be a "10x" engineer. Some I am involved in are the Go community and the #CodeNewbie and #CodersTeach Twitter chats. Additionally, to unlearn the fixed mindset of having to be someone who builds a perfectly-architected "next Facebook" in a dorm in one weekend, I've tried reframing the stuff I don't know in terms of thinking about how many different things I am learning and building with. This way I can have more of a growth mindset as I learn.
However you deal with impostor syndrome, know that you are awesome coming into this new career, and that there is a lot you bring to the tech community, even if you feel like a n00b. One secret, by the way, you don't actually need to know every technology people talk about. If a project uses all of those, that sounds like a hard-to-maintain set of microservices 😉.
I became a CS major at Tufts because I knew I wanted to build apps, and in college I read a lot of tech Twitter to understand how professionals built their web apps. So it was surprising that with the exception of COMP 40 - Machine Structure and Assembly Language Programming, the core classes were often more math-focused and didn't clearly look like the tools I was reading tweets about. Similarly it was a surprise that when I started coding at work, I didn't directly use many of the algorithm skills I took classes in. Because of this it often took more effort for me to connect to mathematical, abstract CS concepts than it did for material like what I learned in web programming.
The reason these classes were so different from coding on the job was because these core courses were teaching computer science, but building software is based around software engineering. Those fields are different, but they're closely connected. CS is focused on the math that makes our computers and software work, such as how we represent data and access it efficiently. This means the work in computer science involves devising algorithms and proving theorems. Meanwhile software engineering is more focused on making the code and architecture for building technologies; it's an application of computer science.
Also, one major part of software engineering is knowing how to compose different tools and code together to build big software systems. Therefore, you're working with the algorithms each component of your software uses. Because of this, familiarity with the computer science behind a technology helps you to reason about the mathematical guarantees and limitations of different parts of the system your team is building. Most of the time in engineering, you won't be proving a theorem or big-O-notation run-time directly, but the computer science helps you understand the abstractions your code works under. And if you're familiar with an abstraction, in addition to helping you solve the problems at hand, that familiarity carries to applying that abstraction to different problems.
Speaking of connecting between math and code, since CS and software engineering both involve working with a lot of abstractions, you will want a robust way of integrating each abstraction and concept into your overall body of knowledge.
This is especially important at work because in software engineering jobs, when you're learning new concepts such as a framework or a category of algorithms, the learning often isn't as formal and linear as it is in a classroom. Rather than reading a framework's documentation like you would a textbook, it's often better to go into the docs knowing what questions would help you apply what you're reading fastest. Some of those questions might be "what are the core concepts to working with this package?", "what are the data types and interfaces at play in its codebase?", and "what's the most basic thing I can start building with this package?".
This "off-road" style helps to make the learning more active and focused, and lets you start using the concept earlier in code you write. This is important on an engineering team, and you can apply it to formal coursework as well. Although the way you learn on the job is different from in a classroom, in both places experimenting to find how you learn best will pay off. By knowing that, you can leverage your learning style to more quickly start iterating on what you understand and in turn accumulate more knowledge. You'll also be able to avoid being distracted by details that you might learn more quickly after you get the big picture.
Communication, in my opinion, is the single skill that helped me level up the most as a startup software engineer. On a dev team, everyone is working on solving different areas of a problem with different tools. Furthermore, each person's work has an intricate set of trade-offs and details that can be hard to follow without the context of why a part of the codebase was built the way it was. This is why silo-breaking communication is important, especially because every engineer at some point has to make changes to code they don't regularly work on.
As well as communicating with other engineers, it is also important to talk to product teammates. People working on delivering the product to customers are often working the closest with users. So that user feedback is highly influential in deciding what functionalities and user experiences your product will need to support. And this ultimately translates to what engineers will be working on. Because of this, I often go to product meetings at work as well as engineering ones so that I can stay familiar with the big picture of what I'm ultimately building. That information is important for an engineering team because it lets them weigh in on the trade-offs between different approaches to solving the same problem; you want to take the approach that makes it easiest to support the features customers want.
Some kinds of communication that are really key to helping your teammates are:
- Documentation in its many forms; code comments are the classic example, but there's also descriptive Git commit messages, READMEs, easy-to-follow test coverage, and descriptions of work in tickets. These help a ton with explaining the problems you're solving and the design decisions you're making.
- Refactoring code to make it more intuitive for someone to use different functions and data structures correctly.
- Knowing which parts of your work can "unblock" someone else's work. That helps get stuff done for more people, and when your teammates start using your code, you can often get good feedback on how to improve it.
- Having high-level descriptions in the front of your mind of what you're working on and what problems it's solving without delving too deep into implementation details. This is especially important in planning meetings.
These communication skills all help you and your team build your product; the best way to be a 10x engineer is to make your code easier for 9 more people to work with!
If you are making the transition toward a career in tech, while it might be overwhelming, it's an exciting change. And I hope that you find my advice helpful as you're leveling up as an engineer. Best of luck on this career change!
- A Change of Heart: How I Challenge Impostor Syndrome by Rayshauna Gray
- How to Beat Coding Frustration with Self-Compassion by April Wensel
- selfcare.tech, a curated list of self-care resources for people in tech
- burnout.io, an action plan for dealing with burnout in tech
Also shoutout to my dog Lola for being such a good sport about wearing those glasses! 😂