Chad McElligott

Communication is a Superpower

14 min read

Sometimes people joke that we become software engineers because we "like computers more than people" - the implication within this being that we'd rather avoid talking with people as much as possible. The truth, however, is that we must instead develop these supposedly dreaded skills if we expect to succeed to any meaningful degree as a software engineer. I guess the joke is on us 😅. As a software engineer, having strong communication skills separates you from the pack, and is a tailwind that empowers you to achieve your career goals. Communication should be a core skill you focus on improving because it is a superpower.

The Consequences of Poor Communication 🔗

Being a software engineer in a business context is inherently a group endeavor. You will inevitably be required to collaborate to achieve meaningful goals at work, and having poor communication skills is like rust in the gears of that collaboration. This effect also compounds when multiple people that need to collaborate have poor communication skills. Things that would take days or even minutes with a high-performing, communicative team would take weeks or months - or worse, be stalled - for a team that has communication issues.

One of the cornerstones of modern agile software development is rapid iteration and feedback, but this is all but made impossible when individuals involved in the process are poor communicators. Frequently, high-performers will "route around" poor communicators to get things done, cutting them out of the process. If the poor communicator is a key contributor somehow, it holds the team back, stunting team velocity and dragging everyone down.

Besides these disastrous team outcomes, poor communication can also derail an individual's ability to even gain a position doing what they love to do. Without being able to effectively communicate your value to others, you make it difficult for the hiring manager to understand if you are a good fit for the need they are trying to fill, and as such, will likely pass over you for another candidate that makes their case more clearly.

All in all, you should think of your communication skills as one of the most important skills you can develop over your career.

The Hallmarks of Good Communication Skills 🔗

"So what do good communication skills look like?" you may be wondering. I don't claim to be the best communicator - and my spouse would attest to this - but I do see it as a core area that I work to improve upon every day. And while I may not know every trick in the book, there are a few main points I adhere to when collaborating with others.

💭 Bias towards over-communicating 🔗

In general, it's better to make your point multiple times than to leave any question. It can also be helpful to communicate your message in more than one way - in writing, speaking, using diagrams, or even examples. For communication, the DRY principle does not apply: repeat yourself frequently, saying things in different ways, as often as you need to convey your message. The more important the message, or the more fundamental, the more you should repeat it.

👂🏼 Listen more than you speak 🔗

A key component to being an effective communicator is understanding. To understand the people you are speaking to, the problems you are solving, or the context within you are working, listening to those around you and asking clarifying questions are your best tools. Sometimes the answers to the questions you want to ask have to be sought, so you'll have to invite others to the conversation. Even in 1:1 conversations, leaning towards listening more than speaking will make you a better communicator overall, as you will naturally allow the conversation to flow both ways.

🪟 Prefer transparency 🔗

Everyone makes better decisions when they understand the full context within which they are working. Being transparent means sharing anything and everything that may be meaningful or relevant to a given problem domain, where possible. It also means sharing your hunches, gut feelings, and intuition, as often these can be as telling as the facts. Share the history of a problem, the history of the people involved, previous attempts to solve this... anything that may be helpful. Speak your mind.

🙇 Be respectful 🔗

As a corollary to the advice to "speak your mind", always try to frame what you share in a way that is respectful and constructive. Look for ways to contribute to the overall goals of the group, not drag it down, demotivate, or otherwise be unhelpful or rude. Assume good intentions. Being respectful should always be at the top of your mind when communicating with others, especially within a business context.

🧠 Keep a beginner's mind 🔗

Even if you feel you are a good communicator now, always be looking for disconnects or situations in which you feel you are not getting your point across. Pay attention to the communication tactics employed by those you see as influential or effective, and see if you can incorporate some of them into your own communication style. Overall, stay humble and open.

Good Communication in Software Engineering 🔗

It's one thing to talk about good communication skills, but understanding how to apply those skills in your day-to-day work is another thing entirely. Software engineers have lots of opportunities to communicate smoothly - or fail to do so. Let's go through many of them and look at what good communication means in each context.

Code review 🔗

A company's code review process is one that every software engineer will be expected to participate in from day one. A less obvious aspect of the code review process is that its function is more social than for validation. By putting up code for review, the committer is sharing a change along with the context within which the change is being made, and is asking the reviewer to understand it and provide any commentary that may help the committer do their best work. This is a communicative process, both by the committer and the reviewer.

From the side of the code committer, they must do their best to allow the review to stand on its own. By providing clear context in the review request description, the committer shares everything the reviewer will need to know to understand why this change is being made and the considerations that went into designing the solution that is presented. They are also charged with writing code that is clear, concise, and directly addressing the requirements - avoiding changing unrelated code, unnecessary refactoring, or other distractions. A code committer is communicating well to their reviewers when the reviewers feel well equipped to play their role. When addressing any comments on the review, the committer should aim to decouple their feelings from their code and address them thinking about the bigger picture of the problem at hand.

A code reviewer is doing a good job communicating when they are directly contributing to the goals of the code committer or the goals of the team as a whole. This could be by providing useful critique on aspects of the design the team cares about, such as code quality, performance, separation of concerns, etc. It could also be providing valuable context the committer is missing, which would allow them to build a better solution. If the code does not warrant any comment, it can also be helpful to provide a supportive comment saying so! A reviewer should avoid being confrontational, combative, accusatory, or disrespectful.

Receiving help from others 🔗

Asking for help can be difficult when you see others around you excelling. It's important to remember that we all started somewhere, and you can rest assured that we all received help from others along the way. When receiving help from others, it's important that we do our best to make the process as easy as possible for the person helping us, so they have a good experience and are happy to help us in the future. If we make the process difficult by being uncommunicative, confusing, combative, or defensive, it creates an unpleasant memory for the person helping us, and they're less likely to want to assist us later.

To smooth the process of receiving help from others, learn to state as clearly as possible what you are trying to do and where you are stuck. Providing this needed context is critical, as you may be going down a bad path and getting stuck long after you should have course-corrected. A skilled mentor will know how to lead someone towards the right solution and where they took a bad path, but it is also on us to make their job easier.

Listening is critical to receiving help. It is frustrating to a mentor when they are asked for help and provide it, only for the same mistakes to be made again the next time around. We should do our best to internalize the lessons we learn when receiving help - perhaps by taking notes, recording them and listening later, or even just paying close attention and not letting ourselves get distracted while we're being helped.

Mentoring 🔗

Mentoring - the process of teaching and guiding others to learn skills you have experience in - is an important and expected activity of senior software engineers. In truth, anyone can mentor anyone in anything they have experience with.

Teaching is a skill all its own, and should not be taken lightly. The same skills you used to learn may not be what someone else needs, but the burden of translating from your own knowledge to the learning style of your mentee is on you. Varying your communication style is very helpful here - your skills in React frontend development may have been the result of reading a few tutorials and then jumping in the deep end, but your mentee may need a more curated learning experience, such as classes, walk-throughs, or regular pairing sessions. Asking questions, finding out how they learned other skills, and paying attention to how they respond to you trying different teaching tactics are all ways to tune in to how best to help them learn.

When answering one-off questions, your best bet of helping them is to ask them to completely explain the problem and where they are stuck, and anything they have tried so far. If it is clear to you what needs to be done, it can be helpful to guide them to the answer themselves instead of giving it to them directly, by asking leading questions. At times when the answer is not so clear, pairing with them and being very vocal about what you are thinking and the things you are considering will help them develop their own mental model for solving the problem in a similar way.

Most importantly of all, never treat someone as if they should already know. Comments like "you have never viewed the Logstash logs? Where have you been!" or "I would have thought you'd know this by now..." are toxic and only serve to make the other person feel bad. Be supportive and kind, and always encourage their questions.

Pair programming 🔗

Pair programming is, as its name suggests, highly collaborative. Your experience of this practice can fall anywhere between infuriating and illuminating, and the pair's communication skills have a lot to do with that.

One of the best things a pair can do when first starting out is establish how the pairing session will work. Will one person "drive" while the other "navigates"? When will you swap who is at the keyboard? How long will you go before a break? How long of a break should you take? Should the "navigator" use a computer, or should both purely work from a single computer? If any of these questions is ambiguous, it can make the experience confusing for one or both of the pair. Having clear ground rules for the session smooths the experience greatly, so take the time at the start to lay them out and form an agreement.

While pairing, it is critical that both of the pair learn to think out loud. Neither can read the other's mind, and it is natural for software engineers to retract into themselves when they are deep in thought. During a pairing session, though, speaking what you are thinking as you are thinking it allows both engineers to follow the train of thought and keeps the flow of the session moving. Without this thinking out loud, a lot of starting and stopping happens, and it can lead to one of the pair being left out, especially when the driver is not collaborating.

After a pairing session and before a break, it can be beneficial to discuss where you should pick back up when you get together again, and write that down so you don't forget. This will allow you to jump directly back into the pairing session without having to retrace your steps too much.

Retrospectives 🔗

Retrospectives lay the foundation for continuous improvement on a Scrum software engineering team. In my view, though, all software engineering teams should be running regular team retrospectives, even if they aren't using Scrum. Retrospective meetings are only effective, though, if the entire team is engaged in the process and participating by sharing their thoughts, raising concerns, and celebrating wins. By continuously engaging in this process of continuous improvement with an open, communicative group, a team can quickly go from good to great in only a matter of a few months.

Retrospectives vary in format, but a common one asks the questions: "What went well this iteration? Where can we improve?" The entire team is responsible for sharing anything they have seen in their day-to-day work - without this sharing, the exercise falls flat and the meeting results in wasted time for everyone involved. So the main thing software engineers should bring to retrospective meetings is their whole self.

Taking note of any relevant topics between retrospective meetings is a great way to bring your thoughts and experiences to bear the next time the group meets. It can also be helpful to engage other engineers in the meeting and try to drive towards concrete actions the team could take to address an issue that someone raises. If you tend to be one of the more outspoken members of your team, don't forget to save some air for others to speak their minds. Perhaps instead of speaking directly, you could encourage a teammate to share their opinion on a given topic (assuming you genuinely want to hear it).

Above all else, maintain the integrity of the meeting. Be supportive of everyone speaking their mind as long as it is on-topic. Don't blame or shame - keep the space supportive, encouraging, and safe. Don't be afraid to be lighthearted and fun! And always remember that retrospectives are intended to be in service to the development team. If it starts to suck, change it up.

Incident response 🔗

Responding to an active incident - the site is down, there's ransomware on the network, the last commit broke order submission - is some of the most stressful communication we are a part of as a software engineer. Incidents are also uncommon, so we don't get much practice. Nevertheless, having strong communication skills in these moments can make the difference between a smooth recovery and a frustrating nightmare.

Before an incident actually happens, it is helpful to read ahead of time about incident response and best-practices to follow. My favorite write-up on this topic is the PagerDuty Incident Response Guide. Having a clear picture of how incident response should go will help you frame how you may best participate and contribute.

When you are called in to be a part of an incident response, my best advice is to stay on topic. If you are unsure what is going on, ask someone how you can best get up to speed - typically there are documents being written to capture the events as they happen. Once caught up, asking where help is needed, announcing what you are doing, and announcing any findings you think may be relevant are how to stay on topic. Keep any extra chatter out of the main incident response call, and maybe even the main incident response chat room, if it is not directly related to resolving the issue.

Besides staying on topic, try to stay calm. Despite the highly stressful situation, remember that everyone is on the same team and is working towards the same goal. If needed, you can gently nudge people to take off-topic conversations off the call.

Incident postmortem 🔗

Incident Postmortems are how we reflect on all aspects of an incident and make changes to improve as an organization. This can be thought of as a "retrospective for incidents", and should be treated similarly. In essence, the postmortem is intended to be for the organization, helping it to improve and learn. A postmortem is not a root-cause analysis, a chance to lay blame, or anything other than a feedback mechanism for learning. All the rules around effective retrospectives apply here, with an emphasis on creating a safe space for sharing, because there are more likely to be sensitive topics in a postmortem than in your typical retrospective.

Strong Communication Sets You Apart 🔗

These 7 activities are only a sample of the times when our profession as software engineers calls for plentiful, clear, empathetic, and respectful communication. More can still be said about other activities such as sprint planning, project planning, collecting product requirements, cross-team collaboration, and more, but I think the point is made. Communication is a critical skill for software engineers, and it should be in the core set of skills that we work on throughout the course of our career. Strong communication skills are a superpower that will set you apart and establish you as reliable, a mentor, an asset, and a leader.

Opengraph background photo by Christina @ wocintechchat.com on Unsplash