From research to software engineering: things I learned
Over the past few years I’ve had the interesting perspective of moving from a research oriented embedded systems role, working with ROS and some open source autopilots, to a full stack web engineer in a late-stage startup.
I did a 180 degree change from research work to private company work, from embedded systems to web development, from a team of research engineers to a team of sotware engineers, from a set of projects to a set of products.
Here are a few things that I would like to go back in time and yell at myself.
They’re opinionated and generated from very limited experience, so please take all this with a grain of salt.
Programming Languages
- Don’t decide to use a new language at work without team buy-in because you read a blog post.
- If a simpler language like GoLang gives you a toolbox of features, C++ gives you a warehouse of arcane tools some of which shoot nails in reverse. Try to generally use the same subset of features the rest of your team uses and get team buy in before promoting some new gizmo you found.
Code Style
- Code style debates are a waste of time. Use an autoformatter and run a style check in CI.
Prioritization + Shortcuts
- Decide if you want to do R&D or if you want to hack away on build systems (CMakeLists anyone?). If it’s the former, try not to invent build systems - stick to what the docs and community suggest.
- You can get surprisingly far committing generated files (ie protobuf generated code) to your git repo, it’s not always worth investing tons of time tuning and perfecting build scripts to avoid committing a generated file. Just make sure the generated file has a comment with instructions on how to regenerate it.
- Same for libraries, committing a source library in a pinch is no great sin.
- The worst feature you’ll ever build will start with a mandated implementation imposed on you (as opposed to a problem) and a lack of early and repeated feedback from those that have to use the feature.
Workstyle
- Merge a little code into mainline everyday, especially when you’re starting out. Even if it’s just fixing a comment or cleaning up some naming, it’s tangible and something to build on.
Git + Reviews
- If you actually want someone to read your code in a review, make each commit a bite-sized chunk
with a clear goal. Don’t use
git commit -m "..."
, usegit commit
to bring up an editor and write a multi-line message that a human can read. Don’t commit unrelated changes together. git rebase -i
is your friend, re-order/squash commits to tell a story, not just create a log of noisy nonsense.- 5 small, well-scoped PRs are easier to review than 1 large PR.
- It’s on the engineer trying to merge code to prove to the reviewer that it works. Explain why you think it works - did you add automated tests, did you manually test, do you have any screenshots?
- Code review is more about maintaining standards and team cohesion and less about catching subtle bugs.
- Make sure it’s clear what parts of your PR feedback are blocking and which parts are nit picks.
Testing
- Unit tests let you develop code locally, debug locally, and avoid deployment for testing. This lets you develop code faster, not slower.
- Newly written code without basic unit testing is definitely broken, it’ll just take another 15 minutes for you to stage the whole environment manually just right to realize that it is in fact broken.
- If you’re writing automated tests as you go, you almost never need a debugger.
- Tests protect your code from your future self and from colleagues that lack full context.
- Tests give you the confidence to make large code changes without manually testing the change (this gives you superpowers).
- You can go overboard writing verbose tests. Make sure you’re testing core business logic and that your tests communicate intent over everything else.
- Write lots of unit tests, write a small number of integration tests, and try to only very occasionally manually test.