I’m back from my cruise – there’s truly nothing better than kicking around on a deck chair for 10 days drinking Mohitos and reading a pile of good books. I’ve now got a scant two days before I start at Blackmagic Design. I’m truly excited, exhilarated, anxious and terrified, all at once. This is the start of a new chapter, and hope the narrative winds up being another happy one like my time at Atmel.
So, it’s time for a tiny bit more reflection on the last 18 months. I think it’s important to get it down here just so I can organize my thoughts, and ensure I take what I’ve learned to heart. Here’s what I think – hopefully these will not be huge revelations to most folk.
Know what you want to build.
Engineers love to create, but as any engineer will tell you, if you don’t specify exactly what you want, you’ll end up with a dozen different implementations. It’s OK to not have every last detail on paper, but at a minimum a Product Requirement Document should be written and a Minimum Viable Product sheet should be created and agreed upon, to stop last minute “oh, why didn’t you include X” or “but I thought it would work like Y” situations.
The first pass is not the last.
I love to extend code, constantly making minor refactors while I fix bugs or add features. But a big lesson is that some times a clean break really is needed; the first design you come up with might not necessarily fit all that well a year later as product requirements constantly change. Don’t be afraid to redesign and start again once the tech debt starts to build up, but make sure you do it in parallel to ensure you can continue to push out updated in the meantime. Once the two versions reach pseudo-feature parity, develop new features on both versions for a short while to get a feel for the improvements that have been made, and to give you a redundant implementation for testing until the old version is dropped.
Don’t micromanage. Defer.
If you’re a manager, trust you have hired the right people to build what you’re after. Don’t hire skilled engineers, just to treat them as meat robots to great frustration by everyone. With a good team managers should focus on waving the baton, not strumming the strings. Tool choices should be made on technical merits (with a little fluidity) – don’t force a tool on a team (other than Git, of course) that doesn’t suit the job, just because you’re familiar with it. Ensure that a common minimal “supported” tool-set is agreed upon so that new engineers can get started more easily, but don’t force editors, compilers, diffing tools, etc. on others based on your own prejudices. Except no Eclipse. Ever.
Design for test. Automate.
This was a big one; I’ve learned much from some very skilled people on how to design for test; not just unit tests but also integration tests and automated physical tests. Testing is boring, so automate as much as you can. Ensure you have repeatable builds, a build server and a good test plan you strictly adhere to before each internal and public release.
Automated analysis is your friend.
There’s lots of great free tools around for checking your code – CPPCheck, scan-build (part of Clang), valgrind and more. Get to know at least some of them and use them regularly. No matter how good you think you are, you WILL make errors that these tools will catch.
Hire good people. Put them in positions that suit their skills, but don’t be afraid to let them branch out.
A good engineer likes to learn, and technology is a wondrous thing. If a Ruby programmer wants to have a go at firmware let them, or if a Objective-C programmer wants to see what this whole “programming” thing is all about by all means give them a look outside the locked basement for the day. Having cross-team expertise is a good asset and can help reduce integration issues between teams. Just make sure that any work done is properly scrutinized before it is merged and deployed, and that the engineer’s primary focus remains on their original job.
Engineers are not managers, and vice-versa.
This isn’t a hard rule, but so far it’s been almost universally true. It’s a rare engineer that makes a good manager and vice-versa, and chances are you haven’t found an exception to the rule. Don’t mistake engineering ability for the ability to mange people, as people are stochastic things much like raw NAND flash and are far more volatile.
Treat everyone kindly.
This should go without saying, but I now know better. Do this, or lose your entire engineering team in under a year. And make sure you treat them kindly everywhere; word gets around surprisingly fast, and you don’t want to be the employee everyone wants to throw under a (literal) bus because of those things you said about them you didn’t think they’d find out about. Respect is earned, but easily lost, and once lost becomes exponentially more difficult to regain.
Encapsulate business logic.
Copy-paste is bad when it comes to code. Don’t repeat yourself, as the old saying goes, but also abstract. Are a lot of your products similar? Do you intend on swapping out the underlying platform later on? Build simple abstractions and encapsulate all your business logic together in a reusable, retargetable library. Doing so will allow you to build emulators for your product (scalability testing, integration testing, memory analysis, yay!) but also will reduce the workload later on when you need to switch chip vendors or hardware out, as you can just alter the platform specific code leaving the abstract core intact.
DOCUMENT BUSINESS LOGIC.
There’s nothing worse than encountering “strange” logic in old code, the purposes of which are lost to time immemorial (or engineers that abandoned ship because they literally couldn’t take it any more). Without documentation on the reasons behind business logic, you’re merely building a “do what I mean” machine rather than a coherent piece of technology. Documentation shouldn’t be slapped on at the last minute; it should be done by the implementing engineer at the time of, or at least very soon after, the actual implementation is made.
Support arguments with evidence. Don’t force bad decisions on people just because you “have a feeling”.
We’re engineers, not witch doctors. If you think something is better, give a good technical argument as to why, and if possible back it up with numbers. “But that sounds slower” is a poor argument – without evidence your gut is often more wrong than right. Cache locality, internal bus speeds, network latencies and other factors can often surprise even the best of us.
Do what needs to be done, but maintain a work/life balance.
No matter how awesome or fun something is to work on, don’t routinely do it on your free time. Work/life balance is important, and believe me your efforts will not be appreciated later on, no matter how useful the work turns out to be. If it turns out to be really useful you can look forward to either having it appropriated by those who didn’t want it done on company time in the first place, or an increased workload in the future as your weekend time becomes factored into product schedules.
Use proven technologies.
Yes, new and shiny is great, but a successful company is – with the exception of Optus – one that has a product that is functional. Don’t select hardware based on business strategies or cost to the detriment of the product; saving 20 cents on the BOM to end up with a non-functional or only partially functional product is a fool’s errand. For the initial version at least select parts and software that have a proven track record, and only swap them out in future revision to reduce costs once you already have something successful. A consumer might not be happy with paying $5 more for your fabulous doohickey, but they’ll be much more unhappy if that slightly cheaper Frobulator 9000 doesn’t work the way they expected.
Admit mistakes.
Not everyone is right all the time, and everyone makes a mistake from time to time (sometimes blowing up previously perfectly good equipment, *cough*). Own up to it, and suggest a way to resolve it. Doing so will help earn the respect of your peers, and bring the team together towards a common goal. Don’t hide mistakes or try to cover them up; people will know, and they will not help or trust you in the future. Similarly, it’s OK not to know something, so admit it and try to learn rather than making up junk on the spot. Finally, don’t spend all your efforts pointing out the mistakes of others rather than getting stuff done.