Software engineers have never been known for their interpersonal skills. In fact, HR people work too often to compensate, in vivid colours, for that gray world habited by developers, programmers and other weird-haired nerds. The lack of social skills demonstrated by engineers is not a cliché; studies show that autism is more common in tech-heavy centers and that couples who work in the industry are more likely to have children diagnosed with autism. Problem-solving skills, it seems, may come at the price of interpersonal ones.
Even off the spectrum, many developers shy away from crowds, prefer not to confront people, and do not consider themselves to be ‘people people’. Some are arrogant while others are direct, often saying what they think very bluntly. As engineers must work together and with other teams, this can pose a problem. That is engineers need to be able to review each other’s code, communicate well on the different aspects of their tasks, and ultimately deliver as a team often with a little bit of constructive criticism.
In my experience, top-talent engineers, both in junior and senior positions, are usually strongly opinionated and care deeply about the details of their work, so they are likely to clash with other workers more often. Conflicts between such high-ranked employees are common, and it is not something to fear; they should be met head-on with clear, positive, and constructive discussions. However, in a world of racing deliveries and code reviews, the atmosphere can turn dark if not addressed correctly.
This article explores the origins and underlying causes of developers’ destructive communication and offers an alternative that promotes positive, kind, and loving engineering feedback- the good, the bad, and the ugly.
Context is key
When planning engineering design efforts, an important question that is often not asked is what is the context of the effort? Do we have a deadline next week and need to solve an issue to meet it? Are we building a new project, have time, and need to make the right strategic choice? Are we in need of a patch because of a production bug?
These questions should be asked after a task is started but before the first line of code is written to avoid problems down the line. This is what we call the engineering design review. During this review, the engineer explains the motive of the project and is an opportunity for the rest of the team to get on board; to better understand why this solution is needed, what is the solution, and how it was chosen. The design will be presented to the platform tech lead and the project’s architect, and any other relevant team members. It allows everyone to get on the same page about the motivation behind the project and its context.
Context mismatches are the root of a lot of hostility that arises in engineering teams. For example, what can happen is that one engineer wants to discuss the problem’s solution and take the time learning, thinking, and analyzing the issues at hand, while another engineer is fixated on the time frame. Both will end up frustrated with one another; the first will feel like he’s being rushed and pushed towards implementing wrong solutions, and the second will feel that he’s the only one caring for the deadline, respectively. Implementing the engineering design review will help to avoid some of these rifts
The Death of the Author?
When you’re reading something, how much do you know about the author? What drove that person, what motivated them to write whatever it is that you’re reading? What were they trying to achieve?
‘The death of the author’, titled after Roland Barthes’s revolutionary essay from 1967, is a concept in mid-20 century literature that suggests the biography of the author, their background, religion, or political views are absolutely not relevant when reading their works. Ideally, the reader wouldn’t know anything about the author because that knowledge can contaminate the reader’s ability to analyze the work.
Many think that code falls under this rule; that code can be easily evaluated because it’s more of a craft than an art so what you see is what you get; that the author of such code holds no importance. The assumption is that since engineers can see and recognize bad code, the code speaks for itself and is all you need and that the people behind it are irrelevant.
That is wrong, and another reason as to why quarrels arise amongst engineers and their coworkers. The author behind any code is very much alive. Think of it like this: the author is the company, and the background is the culture and constraints under which the code was written. All of which tells much of the story behind what is written.
Other methodologies can be put in place to build a culture where these aforementioned issues don't even arise.
The code editor tells half the story
When reading a specific module, especially when not fully or properly documented, the brave developer may rise to the challenge “I’ll read this!”
And soon after, explicitly or implicitly sigh “I don’t understand this…”
And if they are young, they may add “I’ll refactor this!”
These brave souls are guided by two misconceptions:
- “If I don’t understand it either I’m bad or the code is bad (so it is the code obviously)”.
- “If I had the chance, I would have done it better”.
The underlying truth is that if they had the chance, they would have made some other mess that they would understand, and others may have suffered understanding. The missing context makes the reader believe the code was written with all the requirements in place, and with the maturity of the day of reading. That is a bit like blaming Shakespeare for patriarchal writing. The bias of the highly talented developer isn’t easy: the automatic assumption is that everyone did worse than what you could have done. You’re that good, and the rest are that bad. This bias is a product of either being the strongest in many teams for too long or working alone. It is a fallacy that leads good engineers down dark paths.
Resisting the assumption that one knows better than others comes with age. Also is understanding that there’s a thought process behind most things. A bunch of people looked and approved that code. Are they all stupid?
The smarter and younger a developer is, the bigger the temptation is to answer ‘yes’ to that question. It takes experience and competent colleagues to realize none would have done a better job. The code editor tells half the story.
Once a competent developer resists the temptation to think they would have done a better job, they can join a culture of bright, humble, democratic, and willing-to-learn developers. Let’s see how to employ these concepts day to day as a coder or as a leader.
Pick your battles: styles, design, and conventions
Engineers working in a team can and should apply different styles. While robotic code that strictly follows conventions is often easier to understand, it tends to kill developer freedom if applied too harshly. A team’s atmosphere and joy of work are keys to building a team that lasts. Strong developers want to express themselves and hate micromanagement.
On the other hand, no one wants anarchy ruled by code cowboys. This is where we pick our battles as development leaders and as team members, to distinguish conventions from styles.
Styles are things we do not wish to fight over and choose not to. My regular phrase is ‘your call’ or ‘for your consideration'. Show trust in others' judgment, as long as the system can contain their style without losing integrity or quality. Allow time for team-initiated tasks. When it comes to design, things get more strict. Treat a design like you are the one that would need to support it. Make sure to get to the bottom of it and discuss it in the engineering design review. During the code review, verify that the implementation follows the decisions taken together in the design review.
Conventions are also things we do not want to fight over, but we must, for it keeps the project's integrity intact. If someone comes up with an overly complex design, or if there are disagreements in areas that are important enough to be called conventions, use the strongest tool in your box: democracy. “Let’s talk to our amazing team and decide”. As your team makes the decision together you must be ready to win or lose the argument. Democratic culture is more important than the code looking like you want. For that, you need most of your team to be competent. This brings me to the third mechanism which is how to get the best candidates through your interviewing process. The best candidates will give you the best company culture which will lead to the least number of problems arising within your teams.
Interview tips of the day
Here is an approach to use when going about hiring your staff to ensure the best candidates. In my 15 years in the industry, I have been interviewed around 25 times. Of which, I’ve only failed to pass two interviews, which were in areas I had no experience in. In the dozens of interviews, I have successfully completed, I never once completed a question fully or did the entire interview task to the point of completion.
How do you pass dozens of interviews without completing an interview question? The answer is simple. It is not about the question, it is not (fully) about one’s knowledge, and it is certainly not about completing a coding task in a couple of hours, these are just the lights and music for the real show - you.
1. It’s all in the mind(set)
During the interviews I did throughout my career, my first goal was to write clear, clean, well-designed, SOLID code (the 5 concepts of strong code writing) and demonstrate my knowledge, and what value I could bring to the table. One should explain how the design is injectability and testability oriented; clarify how the SOLID concepts manifest in the code; describe why it is MVC or MVVC code design pattern; illustrate your motive behind the decisions and architecture of the code. The key is demonstrating your train of thought, the depth of the thought process, instead of just running for a solution. All this should be done in a pleasant, confident, and communicative way.
Usually, considering the aforementioned factors, I would naturally run out of time. When the interviewers came back and asked me for a status update, I would show them what I’ve done so far, explain what I haven’t done yet, and discuss with them how I plan on doing that.
An answer like “I wasn’t sure how to do this and would prefer to consult with you rather than write something I’m not sure of” wouldn’t get you far on a college exam, but that’s not the case for a job interview. Keeping confidence high while exploring solutions through a discussion shows you know the turf well enough not to be intimidated, but that you are willing to learn, and that above all, you practice healthy communication skills, and you’re fun to work with.
2. Practice and follow-up
To convert interview energy into a working culture is not a trivial task. However, there are useful mental tools that allow the application of these changes in an easy manner. A very productive example with instant results is to improve textual communication by following this simple cheat sheet. Simple rules of thumb: use ‘we’ instead of ‘you’, be focused, concise, and to the point when criticizing someone else’s work, and have a suggestion of your own. For example, instead of commenting “I don’t understand ‘temp’ as a variable name”, use “I would use a name that emphasizes what the variable does, for example, tempLogFileName. That would also save the reader some work”. Instead of “you need to do this again, but scalable”, say, “I understand it is quite frustrating to do this again. If I can help, let me know. We would need to redesign this with scalability in mind. With 10k more queries, that code would have a noticeable effect on the runtime”. Staying informative keeps the discussion on a professional tone. If ever in disagreement, consult democratically with other members. Try to make and request others to make measurable arguments, that is, something that with some work can be proven or disproven. Be ready to be wrong.
It takes heart to code
Ultimately, the way to build an amazing development team is to be kind and loving. These words are often not told in the context of engineering, and that is exactly the reason it is needed. Setting your eyes on the people, motives, and discussions rather than the end goal, will not only give you the bigger picture, but it will also make you enjoy the road, and that is no less important. Just like in an interview, that energy is magnetic and viral.
If you pick your candidates based not solely on their technical talents, but also on their ability to communicate and enrich the atmosphere in the team, you’ll be in a much better position A positive attitude and can-do culture that is backed by a deep sense of ownership, will allow your teams to thrive, while having fun doing so.
Written by Renen Avneri, Mobile Architect at Nexar