Toward the end of my junior year in university, my algorithms professor said he was restarting the university’s competitive programming club and that he was looking for students interested in participating. I didn’t have much going on during the summer and figured it would look good on my resume after graduation. Little did I suspect the profound influence that decision would have on not only my resume, but almost every part of my programming skill set.
I started by attending the university’s club and learning basic algorithms. I ended by teaching other students and competing on the school’s top team in that year’s International Collegiate Programming Contest. I enjoyed learning new concepts and solving interesting problems, but one question always hung at the back of my mind: Will this be relevant after I graduate and begin my career as a software engineer? Now, having worked as a software engineer for over a year at Lucid, I can confidently answer that question: Yes. Specifically, competitive programming taught me to write better code, solve difficult problems, and teach myself new concepts.
Writing better code
The first benefit I reaped from competitive programming was that I got to write a lot of code. This seems a foregone conclusion, as all software engineering students need to write code for their classes. However, when I began competitive programming, I was shocked at how unnatural writing code still felt. For example, I would think, “I need to collect all the values in this map into a sorted list without duplicates,” and then freeze when it came time to write the code. What kind of for loop should I use? How should I collect the values? When should I sort? How should I deal with duplicate values? These were all seemingly small questions, but the other students and I struggled at first to answer them quickly. The solution: Answer these questions over and over again. Like a basketball player practicing free throws or a language student repeating phrases in a foreign language, I needed practice to become fluent in the language of programming. I got that practice in club meetings, where I would write more lines of code in a single evening than I would in an entire semester for some classes.
This naturally led to increased familiarity with basic data structures and algorithms. Yes, some competitive programming problems require complex, pre-learned algorithms that I will likely never use in my career. Topological sort? Disjoint set? Fast Fourier transform? They’re all useful for competitive programming, but not as helpful in software engineering. However, each of those complex tools is built of smaller, simpler tools, like arrays, sets, maps, pre-built sorting algorithms, linked lists, etc. Implicitly learning the higher level tools made me more proficient in the lower level tools, more so than any one-off homework assignment in a class could.
Solving difficult problems
Thanks to competitive programming, I no longer get hung up on the smaller questions of how to code my thoughts. Instead, I can focus more energy on the bigger picture. That leads to the next benefit of competitive programming: problem solving.
There is a timeless joke among software engineers: “I’m not good at coding. I’m just good at copying and pasting code from the internet.” While humorous, this joke fails to capture the reality of software engineering. Although the internet is a valuable tool, it cannot solve the more complex problems I face every day as a software engineer at Lucid.
I was recently working on a data flow that gets triggered by a third-party webhook. I needed to take the data from the webhook request and use it to make my own request to a third party. But to make that request I needed sensitive credentials, which should not be exposed to a public webhook endpoint. On top of that, I needed to take into account Lucid’s unique code architecture and constraints.
The solution for this problem wasn’t a simple internet search away. No one outside of Lucid is familiar with our codebase. In fact, not many within Lucid are familiar with this specific data flow. I had to rely mainly on my problem-solving abilities. Had I only encountered such challenges in classes where the solutions were always available online, I might have been stuck. Fortunately, through competitive programming competitions, I had learned to solve complex problems without accessing the internet or other resources.
Competitive programming taught me to solve problems by keeping these questions in mind:
- What data is in scope here?
- Which decisions does that data inform?
- What edge cases could break this flow?
- Is there a faster way to accomplish this?
Teaching myself new concepts
The final skill competitive programming taught me has been the most useful in my career so far. That skill is how to teach myself new programming concepts. In college, I was spoon-fed new information by professors and textbooks. While efficient, this did not reflect software engineering at Lucid. While Lucid does provide many internal training opportunities for its engineers, most of my learning is still self-lead.
In competitive programming, I researched new algorithms and data structures on my own. I would read code, dig through documentation, and write and run stress tests for my solutions. It’s the same for software engineering. To demonstrate, I’ll go back to the previous example of the webhook data flow. The webhook in this flow is programmatically constructed using the third party’s API. I had written the webhook management code several weeks prior. When I took on the assignment, no one at Lucid had ever set up a webhook this way. There was no one to spoon-feed me the information I needed. Instead, I did the same thing I’d done in competitive programming. I read through the third party’s documentation. I examined the code examples they provided. Perhaps most importantly, I wrote code that would test my implementation, discovering the constraints of the API. These same skills that made me a better competitive programmer now make me a stronger software engineer.
I joined that competitive programming club on a whim. There were many times I considered dropping out, given the challenging material and time commitment required. However, I am glad that I stuck with it. Thanks to competitive programming, I can write code more fluently, solve difficult and unique problems, and teach myself what I need to know to excel in my position at Lucid. I would encourage any budding software engineers (and any seasoned ones as well) to consider jumping into the mind-bending, stressful, and delightfully rewarding world of competitive programming.