Skip to content

samhuk/eng-notes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 

Repository files navigation

Summary

A bit about me and my thoughts and views on software and engineering.

This is a live document; thoughts and views can change and be changed.

Mantra

Make to delight, care about your work, make the world a better place, and do no evil.

General Takes

  • If stuck for ideas, make something that earns people money, saves them time, simplifies a workflow, or is required for compliance.

  • Optimize the process, then work in the optimized process. Compromise when appropriate.

  • Correctly prioritize features.

    • How long features take to complete often follows a Pareto distribution.
    • "~80% of features take ~20% of the time."
    • Focus on the 80%, with the 20% in mind for later.
  • Respect your teammate's time. Never request review of your work before you understand it and are happy with it. A PR is a proposal, not a question.

  • Optimize for the reader, not the writer. Understanding code can take 10-100x more time than writing it. The reader is another engineer, six months from now, with no context.

  • My process:

    i task
    0 Get requirement(s)/problem(s).
    1 Make sure they are the correct ones to solve. GOTO 0 until correct.
    2 Has somebody already created a solution or similar? If so, GOTO 4.
    3 Figure out solution. Research. Break the problem down. What are the behaviors? Need help?
    4 Iterate whilst liaising with stakeholders. Ensure on right track. Need initial buy-in?
    5 Iterate through releases. alpha -> beta, 0 -> 1 -> 2. Plan path to GA.
    6 Market, maintain, extend, semver, care, profit!
  • Don't be religious.

    • Optimal decisions almost always sit between 0.2 and 0.8 of a decision space, almost never at the extremes.
    • Example: optimal amount of tech debt is never at 0% or 100%. Tech debt is like fiat debt - none or lots can both be bad.
    • Be wary of anyone who is certain.
  • 1000 LoC that clearly expresses intent is better than 100 equivalent LoC that expresses nothing. See ZoP PEP 20 #2.

  • Many problems are made much easier by focusing on:

    • A simpler/toy problem first.
    • The required behaviors.
    • The required data structures and APIs/interfaces.
    • The involved data ETL processes.
    • The failure modes - what does broken look like?
  • Follow "LDD" - Library-Driven Development.

    • "Imagine the code you are writing, whatever it is for, is a 'package'."
    • This mindset promotes reusable code with room for reinterpretation.
    • Useful test: could you publish this module's index.ts (or equivalent) and feel okay about its surface area? If not, you are probably doing it wrong.
  • Name things honestly. A function called getUser that also writes to a cache and emits an event is a liar. Liars cause bugs.

  • The cost of a feature is not just making it; it's the integral of its maintenance burden over its entire lifetime.

  • Features must pay back more in profit than they cost to make, maintain, and sunset.

  • Tests must pay back more in confidence than they cost in maintenance.

  • See a pattern?

Views on Some Well-known Principles

  • Prefer composition (excluding game dev).
    • Inheritance often leads to complicated code. Sometimes it's the right path, but unlikely.
    • Composition promotes divide-and-conquer problem solving and composable architectures.
  • Follow the KISS principle (but sometimes "big" problems need "big" solutions).
  • Follow the SR principle.
  • Follow PEP 20 (Zen of Python).
    • My highlights:
      • #2 - Because implicit code is insidious.
      • #5 - Because flat lists of operations are more readable and composable than deep stacks, and promote divide-and-conquer.
      • #12 - Because decisions without data are guesses.
      • #13 - Because Go did this and it went well.
      • #17 - Because if you haven't got an elevator pitch for something you are doing, you probably don't understand it.
  • Be cautious of TDD.
    • Theoretically great in pre-defined toy scenarios, but practically less useful than its proponents claim.
    • Create tests, but don't religiously write all tests before all functional code.
  • Be cautious of SOLID.
    • Needs to be reframed and moderated by business and common sense to be useful.
    • The "I" and "D" in particular are often cargo-culted into pointless ceremony.
  • Be cautious of DRY.
    • Premature abstraction is worse than duplication. Two things that look the same but evolve in different directions are not the same thing.
    • Prefer the "rule of three": wait until you've duplicated something three times before extracting it.

Engineering Hygiene

  • Types are documentation that can't lie. Use them. Lean into the type system. as assertions are a small admission of defeat - sometimes necessary, never the default.
  • Boundaries matter. Be deliberate about what crosses module/service/network boundaries. The further data travels, the more validation it deserves.
  • Observability before optimization. You cannot fix what you cannot see. Log, trace, and meter the things that matter before you need them.
  • Idempotency is a superpower. Anything that can be retried safely will be. Anything that can't, won't be - and you'll find out at 2am.

On Tools and Stack Choices

  • Boring technology is usually correct. Choose the boringest viable tool for the job.
  • Build vs. buy: if it's not core to what you ship, prefer buy (or open source). Your differentiator should be where your effort goes.
  • Standardize at the team level, not the codebase level. Linters, formatters, and import sorters are not where creativity should live.

On Working with People

  • Most engineering problems are people problems under the hood.
  • Write things down. Decisions, trade-offs considered, why the other options were rejected. Future you (and your colleagues) will be thankful.
  • Disagree, then commit - but record the disagreement. If you were wrong, you learn. If you were right, the team learns.
  • Reviewing code is teaching and learning at the same time. Treat it as such.

Cautions

  • Common engineering pathologies:
    • Non-technical leaders.
    • Normalization of deviance.
    • Private equity financing.
    • Usage/activity based OKRs.
    • Poor handovers.
    • Consensus mistaken for correctness.
    • "We'll fix it later." - you won't.
    • "It's only temporary." - it isn't.
    • "It can't be fixed." - it can.

About

Some of my personal thoughts about engineering

Resources

Stars

Watchers

Forks

Contributors