Some thoughts on building software
- For http services, instrument trace ids asap. New requests should either generate a randomized trace uid and store it in context or inherit one from a header
- Always set up structured logging so that you can index and query by various properties
- Set up global exception handling
- Set up testing asap, even if project is early stage, it is easier to build for testing from the start rather than cobbling afterwards when there are possible roadblocks like global state, singletons, brittle interfaces and dependencies.
- The higher up the callstack, the more abstraction and declarative a component should be. For example, things written inside the main() should be high level and semantic. More specific code can be more imperative, but it helps to have readability from the top of the program so that the big picture/taxonomy of components is readily apparent.
- Unix philosophy is paramount and applies to many other contexts
- Database migration on start up is a simple way of tackling schema changes and avoids manual intervention. The codebase will always be synced with the schema and rollbacks can be introduced with new migration files. Have to understand implications/feasibility of replicas trying to migrate concurrently. Ideal scenario is fastest replica should stick and the others should fail-restart.
- Try to write comment that syntactically integrates with the language or IDE. For example, golang/godoc requires a certain format but will generate beautiful docs.
- Simple code is hard. Designing elegant, concise interfaces is hard and time consuming but the end product is easier to use and reason about.
- Avoid programming for specific application problems, most of time a block of code can be distilled into smaller generic problems. Think about making generic helper functions where the implementation can be plugged in. Similar to how
map
andreduce
and other common functional primitives are designed. - Be pragmatic; don't clutch to any guidelines or rules if it gets in the way of making progress
- Incremental change is powerful. Don't try to batch more than a few hundred lines of code at a time in a pull request, it makes it harder to review and ends up not getting attention. Inert changes are recommended so that new code can be fully understood without extraneous context distracting. Later PRs will integrate previous changes together.
- https://12factor.net/
- Optimize hiring for team that is willing to learn and don't give up. Prior experience is overrated to a degree if you can find evidence of high competency in another area. The most valuable candidates will be able to figure things out on the job. Probe for tough situations where candidates had to take ownership, make critical decisions and drive it to success.
- Empathy is important; don't assume carelessness or oversight; Sometimes priorities necessitated cutting corners or deferring issues;