Monday, July 11, 2005

What makes a good software engineer?

First—well, OK, second—step in writing a résumé: identify the skills, knowledge, and experience that are needed for your job objective. (The first step: identify a job objective.)

Well, I’m a software engineer by trade, and most recently an embedded software engineer. So, what makes a good software engineer?

Technical skills

  • Programming languages. For embedded software, this means C; very rarely C++; and a passing knowledge of assembler, at least in general terms, is a bonus.
  • Scripting languages. It’s useful to know one at least; they come in handy for knocking up tools and for automating processes. I’m a big Python fan, but the choice of language is less important than the ability and willingness to wield it.
  • Real-time/multithreaded experience. Vital for embedded software, which lives or dies on reliability and response time; and arguably increasingly important on the desktop too.
  • Debugging experience: tools, techniques, mindset.
  • Testing: approaches, committment.
  • Quality. Appreciate and judge the need for code accuracy, precision, efficiency, maintainability; often these are antagonistic.
  • Tools. Familiarity with the development toolset: IDEs, compilers, debuggers, source control systems, bug trackers, build tools and processes.
  • Hardware. Specific to the embedded engineer, this, but: the ability to read a datasheet, trace a schematic, identify parts on a board really, really, helps.
Design

  • System/architecture design, including avoidance of this-is-right hubris.
  • Module design.
  • Interface design: to my mind, one of the most important, difficult, and neglected areas of design.
  • Fine-grained design: class, function structure.
  • Knowledge and appreciation of design patterns.
  • Knowledge and appreciation of object-oriented design.
Knowledge acquisition

  • Humility: there’s always something new to learn. Open-mindedness.
  • Active seeker of new knowledge.
  • Adaptable to changing environments.
  • Rapid uptake. There’s often times when you need to soak up knowledge: new projects, new technologies, new hardware. Being a quick study really shines here.
Communication

  • Clear reporting to project management.
  • Good and professional communication with suppliers, customers.
  • Presentation and training skills, both in preparation and delivery.
  • Collaboration with peers.
  • Mentoring, encouragement, development of juniors.
  • Ability to give, receive, and act upon objective reviews.
  • Ability, and willingness, to participate in process improvement activities.
  • Diplomacy. Able to form professional relationships with colleagues, suppliers, customers, even if you don't like them on a personal level or respect them on a technical level. Able to navigate politically-dangerous waters: be the bearer of bad news, respect confidentiality, manage conflicts.
Writing

  • Good written English. The great forgotten skill of the industry, in my opinion. Engineers spend a lot of time writing specifications, reviews, documentation; reviews; code comments; email communications.
  • Clear, concise, accurate writing, particularly in technical contexts.
  • Ability to structure documents, sections, paragraphs, sentences, to tell a compelling and clear technical story.
Time management

  • Estimation: accurate and reliable. Not that that’s ever really achievable, but close is better than wild.
  • Delivery: reliable delivery, or failing that, good early communication of slippage and of possible remedies.
  • Multi-tasking. Often many simultaneous demands and distractions: manage and prioritize.
  • Reactive and proactive: sometimes a difficult line to walk. Anticipate everything and you’ll have time for nothing.
What may be surprising here—and despite my awareness of it, still surprised me a little on writing it down—is just how little of the software engineer’s job is the nitty-gritty of programming. It’s the key part of the job, yes, but it’s backed up by a host of other skills.

So, any suggestions for additions?

[Updated 12th July: added testing. Doh! It’s so important, it shouldn’t have been an afterthought. Added diplomacy.]

Comments:

You've nailed almost all the attributes in a good experienced engineer (bordering on team lead/technical manager, I would say). Probably some are more personal and transferable skills though. I wish I had all those attributes anyway :)

There are a few I would add, thought one could argue they are already covered (!!) :

Communication:
* Proactivity in communications. In many respects, a key attribute to a successful engineer is proactivity in dealing with management. All too frequently I come across engineers who complain about their management not "leading" them well or not allowing them to do "quality".
Fact is, engineers will often come across managers who aren't necessarily versed in engineering practices and don't understand the problems or what they may be asking for. How many of us have worked on "demo" code that suddenly became product? It is important to inform your manager of options, consequences and recommendations, especially if you believe in quality and the practice of engineering.

* Team Spirit. Do I need to say more? Ok I will... By team spirit, I don't mean ra-ra sessions and trips down to the pub, I mean the simple recognition that projects generally work in teams. All team members have responsibilities beyond the immediate individual goals - the team has to function and work together for the project goals. You might argue that a team lead alone is responsible for this, but I'd disagree. The team members have an equal responsibility in this for the project.

Technical Skills:
Analysis and decision making. Do not get caught in analysis paralysis.

Ability to say "can I have 15 mins to think". I don't know how to make an single word attribute. Often an engineer will be called on to provide very quick answers or options at any stage of the project. Recognise that one cannot give good options and consequences without thinking about the problem and snap decisions are rarely the best ones. An experienced software manager would ask you to go and think, but that doesn't always happen.

Ability to look at even the dullest task as a challenge. There is no excuse for doing a half-assed job because you aren't interested in the specific task - ever task is important or it wouldn't be on the schedule. Can you imagine the consequences if an aeronautical engineer decided he or she could skimp on a design task because it wasn't in a technically advanced area?

Breadth of knowledge as well as learning, in order to remain flexible. Using knowledge from other spheres often marks out the resourceful engineer.

Summary:
I've looked back on what I just wrote and two words came to mind (no, not bull and cr*p): Resiliance and dependability. And verbosity.

I guess what I've been trying to say is that good professional engineers have to be resiliant in the face of quite a wacky industry and the wacky people it attracts. A good professional engineer should be dependable and able to take on even the dullest job with the same zest as something in their interest sphere.

Pigeons. Cats. Go.
A little airy fairy maybe, but for me a good attitude is the most important thing.

With the right attitude, one can achieve anything.
One can achieve a great deal with a mighty "weapon" as well :)

Just expanding on one thing in my original post:

Technical Skills:
Analysis and decision making. Do not get caught in analysis paralysis.

The ability to make decisions is nothing to be sneered at. We all can probably recollect people who we thought were making bad decisions at a point in time. Simply put, sometimes you need to make a decision that seems arbitrary and run with it and see what happens - you can't second guess every possible consquence, not should you try.

I guess this comes down to pragmatism at the end of the day: a good engineer is always balancing pragmatism and idealism - it is often critical to do so.

And on that happy note, I shall pragmatically choose to go home before my pants fall off.