7 Skills of Highly Effective Programmers
Inspired by an ex-Google TechLead
Software engineers spend a lot of time gaining skills for interviews by practicing leet code problems and perfecting resumes.
Once they finally get that job at a startup, Google, Amazon, or another corporation, they might find the skills they used to get the job don’t match the ones they need in their everyday work.
Our team was inspired by the seven skills of highly effective programmers created by the TechLead. We wanted to provide our own take on the topic.
Here are our seven skills of effective programmers.
1. Learn How to Read Other People’s Code
Everyone but you writes terrible code.
That is why a great skill that has multiple benefits is being able to follow other people’s code.
No matter how messy or poorly thought out a previous engineer’s code is, you still need to be able to wade through it. After all, it’s your job. Even when that engineer was you one year prior.
This skill benefits you in two ways. One, being able to read other people’s code is a great chance to learn what bad design is. While you are looking through other people’s code you learn what works and what doesn’t. More importantly, you learn what type of code is easy for another engineer to follow and what code is hard to follow.
You need to make sure you gripe as much as possible as you are reading over other people’s code. That way, other engineers understand how much of a superior engineer you are.
Make sure you bring up points about the importance of maintainable code and good commenting. This further shows your dominance in the area of programming.
Your code should be so well-designed that it requires no documentation. In fact, you shouldn’t document any of your code if you are a good programmer. This is just a waste of time and you need to spend your time coding and in meetings.
Being able to read other people’s messy code also makes it easy to make updates when needed. This occasionally means updating code you lack experience in. For instance, we once followed a script from Powershell to Python to Perl. We had limited experience in Perl, but we still had enough context to figure out what was going on and make the changes needed.
This comes from having a decent understanding of all the code as well as being able to read the Perl scripts.
Reading other people’s code makes you valuable because you can follow even over-engineered systems that might stump others.
2. A Sense for Bad Projects
There are many skills that take time to learn. One of the skills we believe is worth knowing is understanding what projects are not worth doing and what projects are clearly death marches.
Large companies always have many more projects going than will probably ever be completed or impactful. There are some projects that might not make any business sense (at least not to you), and there are others that are just poorly managed. This is not to say that you should cut off an idea right when you disagree with the project. However, if the stakeholders can’t properly explain what they will be doing with the end result, then perhaps the project is not worth doing.
Also, some projects might be so focused on the technology instead of the solution that it might be clear from the beginning that there won’t be a lot of impact. This skill requires doing a lot of bad projects before you have an idea of what a bad project really is. So don’t spend too much time early on trying to discern each project.
At some point in your career, you will just have a good gut sense.
3. Avoiding Meetings
Whether you are a software engineer or data scientist, meetings are a necessity because you need to be able to get on the same page with your project managers, end-users, and clients. However, there is also a tendency for meetings to suddenly take over your entire schedule. This is why it’s important to learn how to avoid meetings that are unneeded. Maybe a better word to use is manage rather than avoid. The goal here is to make sure you spend your time in meetings that drive decisions and help your team move forward.
The most common method is to simply block out a two-hour block every day that is a constant meeting. Usually, most people will set up a recurring meeting at a time they find beneficial. They’ll use that as a time to catch up on their development work.
Another way to avoid meetings so you can get work done is to show up before anyone else does. Personally, we like showing up early because in general, the office is quieter. Most people that show up early are like you, just wanting to get work done so no one bugs you.
This is important for individual contributors because our work requires times where we focus and we don’t talk to other people. Yes, there are times you might be problem-solving where you might want to work with other people. But once you get past the blocking issues, you just need to code. It’s about getting into that zone where you are constantly holding a lot of complex ideas in your head about the work you are doing. If you are constantly stopped, it can be hard to pick up where you left off.
Some CS majors started using GitHub the day they were born. They understand every command and parameter and can run circles around professionals.
Others get their first taste of GitHub at their first job. For them, Github is a hellish landscape of confusing commands and processes. They are never 100% sure what they are doing (there’s a reason cheat sheets are popular).
No matter what repository system your company uses, the system is both helpful if you use it correctly and a hindrance if used improperly. It doesn’t take much for a simple push or commit to turn into you spending hours trying to untangle some hodgepodge of multiple branches and forks. In addition, if you constantly forget to pull the most recent version of the repository, you will also be dealing with merge conflicts that are never fun.
If you need to keep a Github command cheat sheet, then do it. Whatever makes your life simpler.
5. Writing Simple Maintainable Code
One tendency younger engineers might have is to attempt to implement everything they know into one solution. There is this desire to take your understanding of object-oriented programming, data structures, design patterns, and new technologies and use all of that in every bit of code you write. You create an unnecessary complexity because it’s so easy to be overly attached to a solution or design pattern you have used in the past.
There is a balance with complex design concepts and simple code. Design patterns and object-oriented design are supposed to simplify code in the grand scheme of things. However, the more and more a process is abstracted, encapsulated, and black-boxed, the harder it can be to debug.
6. Learn to Say No and Prioritize
This goes for really any role, whether you are a financial analyst or a software engineer. But in particular, tech roles seem to have everyone needing something from them. If you are a data engineer, you will probably get asked to do more than just develop pipelines. Some teams will need data extracts, others will need dashboards, and others will need new pipelines for their data scientists.
Now, prioritizing and saying no might really be two different skills, but they are closely intertwined. Prioritizing means that you only spend time that has high impact for the company. Whereas saying no sometimes just means avoiding work that should be handled by a different team. They do often happen in tandem for all roles.
This can be a difficult skill to acquire as it is tempting to take on every request thrown your way. Especially if you are straight out of college. You want to avoid disappointing anyone, and you have always been provided a doable amount of work.
In large companies, there is always an endless amount of work. The key is only taking on what can be done.
There are a lot of skills that aren’t tested for in interviews or even always taught in colleges. Oftentimes, this is more a limitation of the environment rather than a lack of desire to expose students to problems that exist in real development environments.
7. Operational Design Thinking
One skill that is hard to test for in an interview and hard to replicate when you are taking courses in college is thinking through how an end-user might use your software incorrectly. We usually reference this as thinking through operational scenarios.
However, this is just a polite way of saying you’re attempting to dummy proof code.
For instance, since much of programming is maintenance, it often means changing code that is highly tangled with other code. Even a simple alteration requires tracing every possible reference of an object, method, and/or API. Otherwise, it can be easy to accidentally break modules you don’t realize are attached. Even if you are just changing a data type in a database.
It also includes thinking through edge cases and thinking through an entire high-level design before going into development.
As for more complex cases where you are developing new modules or microservices, it’s important to take your time and think through the operational scenarios of what you are building. Think about how future users might need to use your new module, how they might use it incorrectly, what parameters might be needed, and if there are different ways a future programmer might need your code.
Simply coding and programming is only part of the problem. It’s easy to create software that works well on your computer. But there are a lot of ways deploying code can go wrong. Once in production, it’s hard to say how code will be used and what other code will be attached to your original code. Five years from now, a future programmer might get frustrated at the limitations of your code.