Six Software Skills I Wish I Learned in College CS Courses

Matthew Binshtok
Holler Developers
Published in
8 min readAug 19, 2021

--

by Matthew Binshtok, Software Engineer, Holler

At the beginning of July, I celebrated two years working at Holler and I used the occasion as a time for self-reflection. Eventually, this led me to consider the technical knowledge and skills that I wish my classes introduced while I was completing coursework at my university. There are bootcamps that cover some of these skills, and during my junior year I participated in one such program. But in my opinion, practical skills like learning to use Github are just as fundamental to a career in computer science or software engineering as knowing how to find the time complexity of an algorithm or understanding how Turing machines work. My hope is that any educators that come across this article try to integrate at least one of these topics into their curriculum, that students find this to be a useful resource to help them prepare for internships and entry-level roles, and that developers keep these topics in mind when mentoring young software engineers.

Here are the six software engineering skills I wish I learned in my computer science courses:

1. Code Reviews

In my opinion, this one is a no brainer. For all the emphasis universities place on collaborative work as a part of the curriculum, professors do not explain how to effectively give feedback to your peers, or how to productively receive feedback about your code and learn for the future. Code reviews can help students see new solutions and better understand ideas that transcend any specific project. A benefit of becoming accustomed to the code review process is learning to consider how others will view your code. For junior engineers looking to impress, feedback about their code can often be misconstrued as criticism, when in fact it’s just feedback to help them become better engineers. Because it may be difficult to integrate code reviews into a course, a terrific alternative would be exercises to walk through code, explain concepts encoded to peers, as well as explain any assumptions made. In the wise words of Uncle Bob, the only valid way to measure clean code is WTFs/minute during a code review…

2. Debugging

print("wtfffff", badlyChosenVariableName)

Any student who has slammed their head on a keyboard at 11:59PM trying to find the mistake in their code will be familiar with the line above. It’s an easy thing to copy and paste throughout your code to assess how a program is behaving and whether or not it aligns with your expectations of how it should run. Those familiar with using debuggers know that they do a lot of this work for you (and more!), but learning to use a debugger can be intimidating. It often takes some system setup unless you’re using a fancy IDE (most students aren’t), and isn’t something that students may see as worthwhile to pick up on their own. Using a debugger effectively is an important skill that universities should teach formally. Even simple exercises like directing students to fix broken code using a debugger will enlighten them to the benefits of using one to step through code and making it a part of their development routine.

By the way, professional IDEs like JetBrains, and other tools are available for free for students! Check out Github’s compilation of offers for students here: https://education.github.com/pack

3. Testing

Spending an eternity debugging a large program is avoidable if your code is both well-organized and well-tested. These two concepts can be taught hand-in-hand as good coding practices that help students understand the benefits of investing time in considering the use cases prior to implementing a program. Even within implementation, teaching students to write smaller, independently testable functions starts building good habits. An important side effect of understanding good practice here is learning to think about special circumstances and edge cases as you’re writing code instead of waiting until you’ve completed the implementation. Otherwise, once contributing code in a professional environment, students will discover the cruel truth in Murphy’s law that anything that can go wrong, will go wrong.

4. Change Management and Deployment

For many students, one of the biggest hurdles in starting as a contributor at their first internship or full-time job is learning the basics of Git, Github, version control, and more generally the process by which their code goes from running on their machine to running in production environments. Introducing these concepts in college courses teaches students a few things:

  • To keep their code in a working state more frequently
  • To view their code as the beginning of a larger pipeline
  • To determine how to change their code in ways that can be rolled back later
  • To build confidence in functionality before it ends up in production

Furthermore, there are important practical topics such as CI/CD (continuous integration and continuous deployment) that are very difficult to understand without the basics of change management.

5. The Cloud and Cloud Service Providers

If we’re being honest, there could be an entire course for this topic, but the reality is that most students graduate university without knowledge of the cloud or its capabilities. Among curious and excited CS students, many have an itch to run their programs and applications in a way that other people can access them. Introducing the main services that cloud providers offer and their frequent use cases can catalyze students to explore the possibilities that exist for deploying their projects. The cloud is rapidly evolving, and thus the available technologies are evolving, but that should not deter instructors from providing students with a glimpse of this important space. Here are a few questions that can serve as the foundation for a simple introduction to the cloud:

  • What is “the cloud”?
  • What are some major public cloud providers?
  • How can I allow real users to access my applications?
  • What are the most common use cases for the cloud?

6. Breaking Projects Down

Last spring, Holler brought on two interns from my alma mater, Hunter College, as part of the CUNY 2X Tech Talent Pipeline. CUNY 2X Tech is a city-led initiative to double the number of CUNY graduates with CS degrees, and assist them in finding employment in the NYC Tech scene.

I sat down with the engineering team to brainstorm attainable goals for the interns as part of the overarching theme of preparing them for their future full-time roles, whether it be with us or another organization. Among the goals we drew up for them was one I felt very strongly about: learning to break down large, abstract requests into implementable pieces of work.

In university coursework, the instructions will say that a submission for a programming assignment has to do a number of highly specific things. It is usually pretty easy to translate those requirements into code. Things are a lot messier in the software industry — the problem statement is not so well-defined and all the requirements are not fleshed out. Aspiring software engineers would benefit from practicing things like:

  • Clarifying the problem space and requirements
  • Thinking about distinct implementable components
  • Defining dependencies on other developers or systems
  • Logically sequencing the work that has to be completed

This is an important step for aspiring software engineers to move from a university setting to a professional setting. The way one completes assignments for a course is inherently different to the way one contributes to continuously evolving projects.

I spent a lot of time with the interns working through the practices listed above. In the last week of their internship, they received tremendous acclaim from the rest of the company after presenting their projects. I believe that a large part of their success was due to their dedication to understanding and using these organizational principles.

Honorable Mentions

Before wrapping up, I want to give a special shoutout to two people who helped me brainstorm the skills for this article! Thank you to Maria Mahin of Disney Streaming Services, a fellow 2019 Hunter alum, and Kevin Liang of Hubspot, Northeastern University ’19, for their aid in drafting the list for this article.

Below is a list of additional topics/skills for which even a brief introduction to these concepts can go a long way in shaping how entry-level engineers think about software development.

1. Containers

What are they and how are they useful? Understanding common technologies for containers and cluster management/deployment would also be beneficial. This is the way of the tech world.

2. Technical Documentation and Design Documentation

In university, the goal is to pass your coursework and show that you know the concepts. In the professional world, technical and design documentation are a pre-requisite for building anything, even if the design is on the back of a napkin.

3. API Development

What is an API? What are some different types? What are best practices to consider when writing one? The RESTful API standard…

4. Web Development

How does the web work? Basic JavaScript, HTML, CSS. What are some common UI component frameworks? What is asynchronous programming?

5. Observability

What do you need to include in production code to make it easier to support that code. Until you have to fix something in the middle of the night, you don’t really have an appreciation for what it takes to make code easier to support.

6. Databases

Best use cases, SQL vs NoSQL, schema design, indexing, performance etc.

7. Best Practices for Writing Clean Code

Emphasizing things like modularity, naming conventions, reusability, separation of concerns, etc.

8. Contributing to an Existing Codebase

Being able to take code that someone else has written, logically trace through its execution, and build from it. Also, best practices to make your code easily extensible.

--

--