Many new software engineers make the mistake of thinking that programming is the only thing they have to be good at. If they focus only on writing good code they'll be successful, because at the end of the day the code is what matters, right?
Not quite. Soon, they find the project they've been working on is building the wrong thing because they failed to meet with their real stakeholder. Or they're stuck on a bug for days because they're too afraid to ask for help. Or they're constantly missing deadlines because they can't properly estimate how long something will take. Not long after they find themselves passed over for a promotion and are asking why.
The more experienced engineers also know these are the worst engineers to work with and stay away.
The reality is that software engineering is more than just writing code. In order to write great software you need to be able to communicate effectively with your team and stakeholders. This can range from microinteractions you have on Slack all the way to a very formal stakeholder meeting. Having the necessary soft skills will help progress your career much faster and get you better results. I've had to figure these things out the hard way, so I thought I'd share some of the tips (in no particular order) I've found to be most important in my career.
Be respectful of others' time
If you take nothing else away from this article, remember this: your time is not more valuable than anyone else's. Everyone has their own work to do, deadlines to hit, and personal stuff going on in their lives. There's no faster way to burn the goodwill of your teammates than wasting their time. This shows up in a number of ways:
- Asking questions that you could have easily Googled or researched
- Asking the same questions multiple times
- Making the same mistakes over and over again
- Being late or unprepared for meetings
- Having others review your unfinished pull requests
I've found most coworkers to be very understanding and willing to help when asked. But if you're constantly asking for help on things you could have figured out on your own, you're going to wear out your welcome quickly.
Be open to feedback
The more detached you can be from your code and work, the better. That's not to say you shouldn't be proud of what you build, but you should be able to take criticism without taking it personally. In the corporate world, if someone is giving you truly honest feedback, take it. Chances are the same sentiment exists in other teammates and they aren't willing to tell you.
I've worked with developers who are very defensive about their work, partly because they've built their identity around it. They take any criticism as a personal attack. I get it, I've been there, but don't be like them. Nobody writes perfect code and everyone can improve. If you're not open to feedback, you're not going to grow. From a compounding standpoint, the earlier in your career you learn this the better.
Come up with solutions to "blockers"
Inevitably you're going to run into blockers. These could be technical or non-technical. For example, you might be stuck figuring out an expected bug or system limitation. Or maybe you're waiting on a feature from another team. Regardless of the cause, the best engineers I know can figure out how to unblock themselves.
First, it's important to be upfront about what's blocking you. Don't wait until the last minute to communicate that you're blocked. It can feel embarrassing to say "Hey, I'm stuck!", but it's not a reflection of your abilities. Shit happens.
Once that's out of the way, you can start to figure out a plan of action. You'd be surprised how often a teammate will have some "random experience in X" from a past project and can help. Or sometimes the issue is that you've been stuck in the weeds for too long and the obvious solution is apparent to someone with a fresh perspective on the problem. That happens a lot too.
My favorite solution is simply changing the requirements to work around the blocker. I often see junior engineers get stuck on a piece of the project that ultimately doesn't matter, but from their perspective they don't realize there are a bunch of other options to pick from. Instead of spending two weeks down a rabbit hole of trying to get Doomed Solution A to work, they could have switched to Solution B and finished in a few days. This is why it's important to communicate early and often.
Gain a deep understanding
More often than not you will be working with code you didn't write. You're seeing the solution to a problem, and you don't always know the context of why it was written that way. It's important to take the time to learn the code you're working with. You're going to have a bad time trying to add on to a system you don't truly understand. Or if you're fixing a bug and not addressing the root cause.
When I'm working in a new system, one of the first things I try to do is sketch out the system design. Does it make sense to me? Am I understanding why it was built this way? If not, I'll try to ask the right questions and find out. Sometimes you'll even find the answer is there is no answer!
Learn to estimate
Estimating is by definition not an exact science, but it's important to still be accurate in your estimates. If you're consistently underestimating how long something will take, you're going to be seen as unreliable. If you're consistently overestimating, you're going to be seen as inefficient. Neither is good, although it's generally preferable to overestimate (hence the adage under promise and over deliver). There's a running joke that you should take your original estimate and double it.
When dealing with non-technical folks like product managers, I like to stick with "T-shirt sizing" estimates. This is where you give a rough estimate like XS/S/M/L/XL and so on, from a scale of trivial bug fix to a quarter-long project. Very easily understood by everyone.
For a more precise estimate, treat it like a regular problem you're solving. What do you do? Break the problem down into smaller problems that are easier to estimate. Then sum them all up and give yourself a little wiggle room to account for overhead. In general, the part I see most engineers struggle with is forgetting to account for the non-coding time. This includes code reviews, testing, and deployment. A feature isn't complete until it's fully deployed in production.
If you're not sure, it's best to say you're not sure than to give a bad estimate. Even better, take a couple days to do some upfront research and get a more accurate estimate. I've rarely had someone say no to this.
Become reliable and trustworthy
This is a big one. If you say you're going to do something, write it down in your TODO's and make sure you do it. If you're not going to do it, communicate that as soon as you know. This is especially important in a team setting where everyone is relying on each other to get their work done. If you're consistently dropping the ball, you're going to be seen as unreliable. This is a quick way to lose the trust of your teammates.
This shows up in a lot of little ways. For example, you just built a new feature and deployed it. Can you confirm it's actually working? Did you check the metrics? Did you update documentation? Did you let the team know it's in production? Over the years I've seen so many engineers push code and think that's it, all done. Then a bug report comes in and it's very clear the developer never actually tested their feature works, and it's actually been broken in production for a month. This is a recipe for disaster. Trust me, you don't want to become the engineer that has to be babied by your team.
Make yourself visible
I struggled with this for a long time since I don't like being in the spotlight. But if you do good work and nobody knows about it, you're only hurting your career. There's no shame in taking a little credit for yourself.
At Stripe we used to send out a "Shipped" email every time we launched a new feature. This was a company-wide mailing list and we also had an internal page to view recent ships. It was a great way to keep everyone in the loop and also get some recognition for your work. I've seen other companies do similar things with Slack channels or internal blogs. Even something as simple as posting in your team Slack channel "Hey, we just launched feature X and got our first user!" can go a long way.
Not all work is some easy to understand feature. Maybe you're fixing a very annoying piece of code that keeps sending your team alerts. You can still make yourself visible by tying it back to the business impact. "Hey, I just fixed a bug that paged us 10 times over the past month. " This is a great way to show your value to the team.
Make good use of standups
Standups are dreadful to many engineers, but it's often the only time you get to talk to your entire team at once and therefore is a good opportunity. If you spend a little bit of effort coming up with a cohesive and thoughtful update, I promise you will see some nice returns. You will look better put together instead of stammering through "oh yea, I, uh, am still working on X". Think of it like how people dress up nicely for the office. It takes a bit of work, but people subconsciously have a better impression of you which can pay off in unexpected ways.
Learn to run a good meeting
Meetings are a necessary evil in the corporate world. They can be a huge waste of time, but they can also be very productive. I've found that the best meetings are the ones that have a clear agenda, goal, and outcome. If you're running the meeting, it's your responsibility to make sure everyone knows what the goal is and what they need to do to prepare. Everyone attending should be there for a specific purpose, otherwise the scope will be unclear. Ideally the meeting should have a consensus outcome, even if it's just "we need to investigate this further". And this should all be written down somewhere in the form of meeting notes!
If you have an hour long meeting with five engineers, that's a lot of engineering time spent on a problem. And remember, there's overhead of context switching to and from a meeting, so actually more than an hour per attendee. If you think about it in monetary terms, was the meeting really worth $1000?
Figure out what people actually want
You can be the best engineer in the world, but if you're building the wrong thing, it doesn't matter. This is why it's so important to understand the business side of things. What are the goals of the company? What are the goals of your team? What are the goals of your manager? What are the goals of the person you're building the feature for? It's easy to get lost in the technical details and forget about the bigger picture.
This is especially important when you're working with someone non-technical. For example, I was once tasked by a PM with building a system that would automatically track some external data for them. The ticket as written wanted a highly complex and customizable system that would take weeks to build. Instead, I scheduled a meeting with the PM and asked them what they were actually trying to accomplish. It turned out they just wanted a simple way to track the top 100 items from a spreadsheet, maybe adding or removing a couple every month, and didn't really need any of those bells and whistles features. They agreed this wasn't something I should spend a couple weeks on, and instead I was able to build a much simpler hardcoded solution in just a couple days that did what they wanted.
Don't be afraid to talk to people
When you're stuck behind a computer monitor for most of the day chatting to coworkers on Slack, reviewing pull requests, and updating Linear tickets, it's easy to forget you can simply go talk to people. Remember there are hidden costs to having a synchronous meeting, but don't be afraid to never have them.
For example, you sent someone a pull request or design document and they left 20 comments on it. Clearly you are not on the same page. Instead of going back and forth in the comments, just get on a call and talk it out. You'll save a lot of time and frustration. The latency of async communication can be a killer for productivity, and the reviewer probably doesn't feel good about leaving so many comments either.
Conclusion
And that's all I have for now, hope you find these helpful! You'll notice that none are really groundbreaking pieces of advice. In hindsight, they are very obvious and mostly common sense. But I've seen so many engineers struggle with these things, myself included. I hope you can learn from my mistakes and progress your career faster than I did. Good luck!