What it means to be a Senior Software Engineer


What makes a great senior software engineer? That’s the question I always ask managers and senior engineers when I meet with them.

This post discusses the traits of the excellent engineers I have had the opportunity to work with over the years.

1. Empathy

Simple: do not be a brilliant jerk. No one enjoys working with one.

Your teammates are human and have feelings – do not hurt them. No matter how brilliant you are; if you are a jerk, people will avoid interacting with you. Eventually, you will become the ‘brilliant jerk (BJ)’, the ‘respected’ guy on the team that no one wants to work with.

This means being open to opposing ideas – seek to understand what people say and see their viewpoints. Even if you disagree, you can state your thoughts in a respectful way; there is no need to belittle or point fingers.

You do not need to ‘win’ every argument, conserve your energy and emotional strength for more important matters. The trick is to find the core set of high-impact important issues to concentrate on, these are the ones you put your foot down and fight strongly for.

2. See the end to end picture

Farmer: I see a lot of trees

Pilot: I see the Amazon

Astronaut: I see South America

Seeing the big picture is a criteria that distinguishes junior engineers from seniors. As a junior, it is easy to become immersed in implementing some small piece without seeing the big picture. A senior engineer sees how that piece fits into the system, the business need and extension areas.

See the continent, the forest and the trees!

As you go up, do not blindly start coding gung-ho; such approaches will cost you money, time and effort (fixing bugs, reverting code, redesigns). Seek first to understand the full story and see the big picture.

Discuss to get more information about usage, corner cases and expected behaviour. The outcome is better-designed software that is resilient to bugs and easy to extend.

Spend some time thinking about the trade-off between risks and benefits. For tightly-coupled code, a small refactor can trigger an avalanche of downstream changes or break some remote component. This also applies to jumping on the latest fad without fully understanding its design roots; you might not even need that hadoop system.

Senior engineers try to isolate risk and keep the system always running. It is not just about shipping features – it is about shipping features optimally.

3. Crisp Clear Communication

Have you heard of any brilliant scientist that could not communicate?

Concise clear communication is an important skill that most engineers unfortunately lack. Software engineers spend a lot of time discussing designs, explaining architectural decisions and convincing people. They have to go to meetings, attend service reviews and send emails. A lack of good communication skills makes it difficult to get ideas across.

Senior engineers tailor their communication to the target audience. They use the vocabulary and terms to get their ideas across and can express their thoughts to disparate groups. Thus, designers, program managers and their peers understand them.

The good news is that you can learn how to communicate. A heuristic follows:

  1. Know the desired communication outcome
  2. Gather your thoughts
  3. Create a logical sequence for articulating your thoughts
  4. Express your thoughts using the sequence in 3
  5. Know when to stop – no point trying to convince someone who has already closed off their mind
  6. Practice, practice, practice

Learn to get your ideas across convincingly and persuasively – it is key!

4. Sangfroid

Sangfroid: self-possession or imperturbability especially under strain

I met with a high up director when I was about to join PowerBI in 2015. He told me that great engineers have the confidence to take some risk.

Everyone likes a confident person! A confident engineer can motivate teams and colleagues toward achieving a goal. Even if they end up in unfamiliar terrain, past experiences and challenges will have equipped them with the confidence to pull through.

This year, I was working on some critical core of our SaaS offering and no matter how hard I tried some mistakes always slipped through. I was a bit demoralized after one incident and asked A, a senior engineer with nearly 20 years of experience. His advice was thus:

Humans make mistakes and that’s normal, that’s how you learn. What’s bad is making the same mistake twice and not learning from it.

That made my day and I got to realize the difference between learning and building confidence. Do not be too worried about mistakes, rather be ready and fortified to handle them when they arise. That’s sangfroid…

5. Disciplined to know and choose what matters

Time is limited but the amount of work that needs to be done is not. How do you prioritize and deliver the things with optimal impact? What matters to the business is delivering high-quality high-impact outcomes consistently over time.

Choose the tasks with disproportionate impact and do them done first. If your web service is down, what matters most is mitigating issues and getting it back up; deep fixes and reviews can come immediately afterwards. This also applies to working on features that have little business impact – really? If something doesn’t matter, is it worth it investing a lot into that?

A senior engineer approaches boring tasks (e.g., unit tests and documentation) with the same level of seriousness as writing code. These tasks, which are multipliers of value, are just as important (if not even more important) in the long run.

I set up a continuous delivery system via git hooks in 2013 for my team. Pushing to the ‘prod’ branch would update the Amazon Web Service VM we had running in about 2 minutes or so. The naïve me did not write a single line of documentation; I felt it was not needed for three reasons:

  1. I had it all in memory
  2. I could always Google for it
  3. I was the only one handling administration and automation duties

As expected, I got confused after some time trying to understand how the system was set up. That was something that documentation would have helped fix.

Some activities are value multipliers – they save you time and effort. They also make it easier to bring on new developers.

Whatever you do, choose wisely and then do it well!

Conclusion

When can you say you are senior? I will give a few heuristics:

  • When you can lead a huge development project end to end and work across multiple teams to achieve your goal.
  • When you can work independently
  • When you are known as an expert and your views reveal deep wisdom, tact and insight.
  • When you can communicate clearly and express your views

Oh, there are a few other aspects I didn’t cover such as estimation and having the right computer science basics.

Thoughts?

Related

The related posts below show the evolution of my views over the years and make for interesting reading.

  1. Maturing as a software engineer
  2. Advice for aspiring programmers
  3. 10 years of programming: Lessons Learnt
  4. The Effective Programmer – 3 tips to maximize impact
  5. Becoming a Professional Programmer
  6. So you want to become a better programmer
  7. Levels of Developer Expertise
  8. Become a better programmer
Advertisements

Maturing as a software engineer


Looking back on my time as a developer, there are a lot of things I would have avoided doing if I had as much knowledge and maturity as I did now.

While I am grateful for the experiences and don’t regret them; I felt it would be a good idea to share these. These might motivate others or at least speed up their careers.

Here goes!

1. Patterns, patterns, patterns

When I take part in code reviews, I tend to look for recurring style patterns. Why? This helps to reduce the cognitive load on readers of the code (after all, code is written to be read).

I am  not advocating for bad software patterns rather having a plethora of ways for doing the same thing in a codebase creates confusion and productivity losses. How do you determine the ‘right’ pattern?

For example in JavaScript, there are several ways for creating an array.


var a = [];

var a = new Array();

var a = new Array(3);

Having a haphazard mixture only takes away brain processing cycles. Rather, have your team decide on a style and stick to it.

By the way, the first style is the ‘expected’ and preferred approach although there might be use cases for the latter two.

Ever wonder why the Google codebase is rated to be easy to work with? Well, think about consistency and established patterns.

2. Break the big picture down and make incremental progress

Building and distributing the smallest software piece you can imagine requires more effort than you would think. It is much more efficient to break down the big picture into small chunks of work that can be completed in an hour or less. Such breakdowns make you more effective and help in understanding progress and forecasting completion times (which is a tricky problem to solve).

I used to break down only the code pieces before (which itself was an improvement over my earlier dive-into-code-and-figure-it-out-as-you-go approach). Nowadays, I try to take some time and reflect on the end product itself: its behaviour, look and feel and how users would interact with it.

For a typical software project, such road maps covers:

  • Testing – unit tests, continuous integration,
  • Documentation – extensibility guides, tooling
  • Implementation
  • Discoverability and Distribution – release targets, getting started articles
  • Maintenance – handling bugs, user feedback etc

Sounds like too much work? Well, just focus on one small bit at a time and keep making progress.

3. Be lazy – start first on tasks with the largest impact/effort ratios

Two things matter: results and impact. There is no point in slaving for 20 hours to choose between blue and light blue if it has no impact on the users. Ditto for spending endless hours ‘arguing’ over what language should be used. Just choose the best usable one and deliver results.

My heuristic for tasks is thus:

  • Does completing the task move me closer towards the big picture?
  • Is this the easiest-to-achieve task with the biggest impact?

If so, I pick up that task and just do it – the goal is to maximize the impact/effort ratio.

Before I’d just stick to a task and spend endless hours on it even if it was something as trivial (and probably low-impact) as beautifying test scaffolding test output and elaborately designing test functions. Now? Common, my time is more valuable than that – I get the test functions right and try to get the coverage I want but won’t spend too much time once that is achieved and is readable for others.

Excessive polishing time can be spent on other more impactful pursuits like having fun with family or delivering high impact features.

4. Technical skills plateau

Sooner or later, you’ll get to the technical plateau. By that time, you’ll have so many successes under your belt and can detect potential pitfalls easily. Then, what next?

There are tons of ways to extend your impact and that is the way people become even better engineers. For example, I doubt if Anders Helsberg is still writing a lot of code, yet his ideas continue to empower and influence millions around the world.

Think about that, how do you scale your influence and make it possible to touch the lives of thousands of people? Are there engineering problems crippling your organization? Process pitfalls to improve with huge impact? Education ramp ups? There are always challenges to solve and problems to fix.

5. Choose career investments carefully

How would you set up an investment portfolio? Would you just go about investing in everything? Nope, you would evaluate the risks and benefits, consult experts and then invest in a select few areas while ignoring other areas.

You could spread out your risk by investing in a wide area but doing this excessively dilutes your returns. Conversely, investing in only company could be very risky too. Thus, it’s generally advised to spread  out your investment portfolio

Careers are investment portfolios. A typical career spans a long period ( upwards of 30 to 40 years) and shares some similarities with investments:

  • technologies, frameworks etc -> investment options
  • time -> funds

Just as you wouldn’t jump on every new fund, why would you do the same with your career? There is no harm in taking measured risks in careers but you should be strategic and know what your end goal is.

Every now and then a new framework pops up in the news. Before, I’d hop on the bandwagon and try figure it out. Nowadays? Well, if it really piques my interest, then I might spend some time learning about its core design principles and problem-solving approach.

If it neither solves any of my problems nor brings anything new to the table, then no thank you; I’d rather continue nurturing my current investment portfolio and hedging my bets.

Think about your bets and stick to them.

Conclusion

I am still learning and pray I continue. One thing that has struck me as being really critical is the will to try. We don’t know if something would work out or not however we can always try and then learn from the outcome (success or failure).

Don’t give up – continue learning and growing.