All happy families are alike; each unhappy family is unhappy in its own way.
― Leo Tolstoy, Anna Karenina
In my last post, I discussed how senior software engineers were different (in a good way), and promised to talk about how one can get there. The problem is two-fold, however. In addition to the slow, time-consuming, and complicated path of skill development, there’s a more important requirement to stop destructive behavior.
As I’ve mentioned previously, the most important step in exceeding expectations is to meet expectations – you can’t even think about being a star until you’re doing your assigned tasks well. Similarly, there are many things so basic they aren’t even thought of as requirements, because while people will miss them if they aren’t there, no one gives you credit for doing them well (“Hey, I wanted to let you know how much I appreciate the fact that you sneezed into your elbow and not my face.”)
There are some things you see over and over – negative behaviors that overshadow all of the good some engineers do, and prevent them from progressing further in their development and careers.
Sloppiness is a tough nut to crack. Instead of being a single concrete problem, there’s a whole constellation of minor mishaps, lapses of attention, missed edge cases, forgotten responsibilities, and incomplete testing. The engineer is frequently able to ship on time, and may even pride him or herself on “getting stuff done quickly.” Unfortunately, the quality of the work product is consistently poor – not necessarily because of bad architecture or planning, but because the engineer only paid attention to the most common use case.
- Poor testing
Though also a part of the more general problem of “sloppiness”, poor testing sometimes manifests by itself. Although this can lead to an erosion of trust – no matter how solid the underlying architecture, large bug counts will quickly destroy one’s credibility – it’s also one of the easier problems to fix. Even without the engineer’s buy-in, a manager can add additional QA resources, have the team do bug-hunts on the engineer’s branch, or increase the number of code reviews required. Even so, this requires significant extra effort on the part of everyone around the engineer, and as such is a highly visible failing.
People get sick. Kids get sick (requiring parents to stay home to take care of them). Everyone gets this. But taking advantage of the system by treating sick days like bonus vacation days doesn’t fool anyone. It signals to your manager and coworkers that you don’t care, that you’re going to take advantage of the system, that you lie, that you can’t be trusted. No one likes to be taken advantage of, and no matter how much you contribute on days that you do show up, this kind of employee will never be given a position with greater responsibility.
- Failure to follow through
Consistently promising things, then failing to deliver, is a fast way to destroy your credibility. Business partners will listen to your promises, and instead of giving you the benefit of the doubt, they’ll watch and wait, expecting you to fail. If you manage to succeed, they’ll assume that it’s the exception to the rule. Perhaps worse is that you’ll habituate to being late or not delivering at all.
- Childish behavior
There are many ways in which this can manifest: overreaction, petulance, defensiveness, territoriality, attention-seeking, emotional attachment to an implementation, and so on. It’s very difficult for other engineers to work with someone they view as a powder keg, ready to explode at any minute. This kind of engineer requires a lot of extra manager attention to smooth over issues with other engineers and business counterparts, and is generally ill-suited to an external-facing or leadership role.
- Failure to communicate
Some engineers just like to sit in their cube and code. And in and of itself, that isn’t a problem – being able to concentrate for long stretches of time and crank out code is a hallmark of great engineers. The problem occurs when the engineer isn’t able to communicate with peers, managers, and business partners. This can include design/architectural details, code documentation, code reviews, status reports, risk management, and so on. This can create a ceiling for a career, because the more senior you get (even as an individual contributor), the more you’re expected to be able to communicate, mentor, and lead. Even if the leadership is entirely technical, you have to be able to create consensus and drive the company forward technically, which requires an ability to communicate vision.
- Lack of concentration
As mentioned above, long stretches of uninterrupted, focused thought are required for superior design and coding. An inability to keep one’s butt in the chair and concentrate on a problem is going to significantly dimish an engineer’s effectiveness.
- Poor teamwork
Teamwork is important for a wide variety of reasons. Your code has to fit into the larger code base. The more senior you become, the more important it is to actively diffuse knowledge on your area of expertise, and to help others when they have questions. The more each member of the team contributes to creating a “gelled” team, the more effective the entire team becomes. Some people do this extremely well, and by doing so can even make up for weaker coding skills. Other people actively sabotage team esprit de corps, and drag down everyone’s productivity. Not contributing to a team’s success is grounds for suspicion. Actively sabotaging it (intentionally or not) is sufficient cause for termination.
- Not Invented Here
No one likes making changes to someone else’s code, and when faced with integration of a new feature, it’s tempting to write it from scratch instead of using a commercial or open source alternative. Not knowing when to rewrite, when to modify, and when to integrate is one of the hallmarks of a weak/junior/self-indulgent engineer, and a common cause of project schedule overruns.
Some people just can’t be happy with anything, or accept anything on face value. They believe there’s an ulterior motive to everything, that upper management is actively working to undermine the company, the team, or the individual, that the customers don’t know what they want, etc. This kind of attitude brings out the worst in everyone – it sparks demotivating, frustrating, unnecessary arguments, makes other people more cynical, and ultimately just makes coming to work less fun. It’s a huge waste of time and energy, and directly undermines the manager’s ability to motivate the team.
- Getting comfortable
You have a role with responsibility, a good salary, and (assuming the company doesn’t tank) your options look like they might be worth something one day. You like the people you work with, and enjoy your job. You’re doing well. You’re content. You’re comfortable, and the last thing you want to do is to risk what you’ve got. So instead of pushing the envelope you start playing not to lose.
It’s easy to start playing defense. When you play it safe, you stop putting in the extra work, stop being creative and taking risks, stop going above and beyond – in short, stop doing everything that helped you to succeed in the first place. You’re trying your best to keep your head down and just not screw up, but incredibly, this only makes matters worse. At first, people think your game is a little off, but before long it’s obvious to everyone what’s going on, and your credibility takes a nosedive. Playing not to lose is one of the easiest ways to fail.
- Trouble finishing
I’ve known extremely talented engineers who just weren’t interested in the last 10% of a project, when all of the cool problems have already been solved and you have to buckle down and just ship the damn thing. Unfortunately, unless you’re in a research role, your job is to ship product. Not to solve problems or write code, not to gather requirements or test or fix bugs. All of these are implementation details – your job is to get the product into a final state and get it off to the servers or app store or DVD pressing facility, or whatever your version of shipping looks like. You can’t win if you slow to a crawl right before you get to the finish line.
A related dysfunction is disorganization. This can manifest in many different ways, the most common being an inability to manage one’s tasks, up to and including those required to complete a project. There’s a joke that the first 90% of a project takes 90% of the time, and the last 10% of the project also takes 90% of the time – this can be because the engineer doesn’t test and/or fix bugs along the way; keeps a mental list of tasks that need to be completed but that aren’t accounted for officially; doesn’t know what remains to be done; doesn’t communicate progress with the customer, and gets ambushed with change requests; doesn’t communicate design decisions and gets blindsided by architectural changes demanded by a technical lead or committee.
- Poor judgment
Acting outside the usual process unnecessarily. Sending off an angry late night email to the whole company. Making controversial decisions without getting buy-in. Acting contrary to company policy. Making HR-unfriendly comments. Before giving you more responsibility, management has to believe that you will act not only with good intentions, but also with tact, diplomacy, and solid judgment. They may disagree with you from time to time (sycophancy is not the goal), but they should respect your reasons for acting as you do. If they don’t, they aren’t going to give you more autonomy.
People who don’t respect the process, regularly break the build, disregard the coding standard, and generally don’t respect the community’s values are going to have a very short half-life.
This is an incomplete list, but you get the picture.
What about coding skill?
You may notice that most of the above items aren’t related to technical skill, experience, or contribution. Doesn’t that matter too? Sure, but that’s kind of the point. No matter how smart, educated, talented, experienced, versatile, and just plain amazing you are technically, your career can easily be derailed by something completely orthogonal. Unless you’re working on your own project, in a room by yourself, completely isolated from coworkers, customers, and results, your success will be mediated to a large extent by how well you work in a team. Whether you can earn the trust and respect of your coworkers. Whether you act responsibly. Whether you can get things done. Some of these are soft skills, some combinations of soft and technical skills, but they’re all necessary. You don’t get brownie points for doing them well, because they’re simply expected of you.
Being true unto yourself
This above all: to thine own self be true.
– Polonius, Hamlet
I said to a guy, “Tell me, what is it about cocaine that makes it so wonderful,” and he said, “Because it intensifies your personality.” I said, “Yes, but what if you’re an asshole?”
– Bill Cosby, Himself
There are a lot of people in love with their own failings. “I’m always late,” they say, with a smile and outspread hands to indicate their complete helplessness in the face of genetic destiny. “I may be rude, but it’s because I don’t want to be phony.” “I’m just disorganized.” “I don’t have a filter.” “Hey, it’s just the way I am.”
Part of life is accepting yourself. You are who you are, and constantly fighting against your deepest personality traits is a losing (and incredibly frustrating) battle. Having said so, part of an effective life is not accepting the destructive parts of your behavior, and actively working to overcome them. Sometimes this means confronting them head-on (e.g., developing a healthier lifestyle if you’re trying to lose weight). Sometimes it means developing workarounds (e.g., if you’re consistently late, creating a variety of automated alarms to remind you of appointments).
No one gets a bye. Ultimately, it doesn’t matter why you’re sloppy, or childish, or unable to concentrate – what matters is that your effectiveness can be significantly undermined by your own behavior. This in turn can prevent you from developing the respect and trust of peers and managers necessary to succeed in any organization. More importantly, it can prevent you from achieving mastery in your chosen field. It’s like writing great code and screwing up on the configuration – it isn’t only getting things right that matters, it’s also making sure that you don’t screw up the basics.
Next up: Mastering the Basics
Pingback: Anti-Mastery | Dan Dreams of Coding | Justin Rodriguez