What I learned at Applied
About a month ago now, I left my very first full-time job after almost 3 years! To cope without the pomp and circumstance that bookended each of my previous life milestones, I've written a bunch of bullet points about what I learned and hope to carry forward.
On Engineering
- Always start with the plumbing.
- The majority of software engineering is data flow configuration - if you can confirm that data can flow from one point to another, it's much easier to iterate from that point on the type of data.
- Do things that are directionally correct, even under resource constraints.
- We work at a company, not a research lab. We will never have the privilege of infinite time or resources to solve a problem the way it should be done. But before you implement anything on a deadline, take 10% of the time it would take to implement the hack to investigate what the "ideal" solution would look like. Update your hack to at least come close to the ideal, or to be easily factored into the ideal.
- Writing hyper-specific features is actually fine, and allows you to support programs within deadlines. Just make your contracts clear that it is a small-scoped feature only meant to do a specific thing so it doesn't get abused into doing stuff it was never meant to.
- Flimsy contracts will haunt you for the entire lifetime of your product.
- It's always easier to start with a strict contract and loosen it later.
- Design your tests to make your preconditions clear, and enforce this in the production code with precondition checks.
- If you find yourself having to do a ton of set-up in a precondition, this is a code smell. Simplify the required state for the function you're implementing.
- Never store any technical knowledge in your brain. It should always be written down somewhere, in order of criticality (1) in code (2) in the PR review or (3) in a design doc.
- AI is making the "what" of your codebase cheap. One of the greatest risks is losing the "why". You can generate code easily, but sometimes there's an approach someone before you intentionally didn't take, and you shouldn't just codegen that. The only way to keep this historic context is to focus on writing "why" documentation everywhere.
- If you find yourself adding a new argument to a constructor, and it's already greater than 3 args, just make it take a config data class for construction and save yourself the headache of having to plumb it through 9 different callsites.
- Any reader should be able to read your functions as paragraphs. Do this with your function names and variables. Use helper functions for anything you copy and paste, and describe them explicitly.
- NEVER use the word "handle" in a test or function, or any stupid verb that doesn't actually tell you anything about what's happening in the function.
- Avoid using state in functions, even in class functions. Make the functions explicitly take the values they depend on, and at call time within the class you can just pass in the state variable. This makes it easy to reason about what the preconditions of a function is without having to read the whole function.
- Finding a bug should always result in 2 pieces of work. The first, is obviously, to fix it. The second immediate step is to update your testing architecture such that you never miss a bug like that in presubmit again.
- Testing frameworks make development go faster. Your iteration cycle is even more critical in the age of AI software engineering because having something you can run often and cheaply to check correctness is the biggest bottleneck of getting something working. In my opinion, it is almost always worth the effort to take time to invest in testing framework.
- Building a codebase is a long-term, asynchronous group project. Write code that makes it easy for your future collaborators to continue to build with you.
On Collaboration
- People want to work with people they want to work with. Being competent can get you in the room, but being kind will keep you in the room.
- Being kind != being easygoing / pushover. Holding people accountable and asking them to do better is kinder than allowing them to fail.
- If you're learning something new, ask questions until you could comfortably explain it yourself. If you can't explain it yourself, don't claim to understand something or make decisions on behalf of it.
- This is especially important with AI generated low-quality knowledge transfer.
- Companies are resource constrained. Always know your priorities, and don't commit to work until you know where it sits in your priorities.
- Never try to resolve a disagreement in Slack if the thread is >4 messages. 4 messages is the point where you need to move to a call, live sync, or meeting.
- The point of a meeting is to communicate something, or decide something. If you aren't prepared with something specific to communicate, or you're not communicating to the person that needs to hear something, or if you are not driving to a decision, it is a waste of time.
- It's very easy to fall into the trap of "being in a meeting makes me feel important." Remove ego, and remember the bigger picture - what is the most important work to be doing, where can you have the highest impact, and is joining a meeting going to get you closer to achieve your goals?
- The value of a meeting is in its outcome. The meeting is not finished until you've come to consensus on the decisions made and assigned action items.
- AI notetakers defeat the point of taking notes in a meeting. The act of taking notes means you are applying your own understanding of the conversation at hand, and recording it. This opens up the floor to clear up miscommunication live during the meeting. By removing accountability for a conclusion, the meeting record becomes flimsy.
- Also, taking notes is a great way to stay engaged and alert when others are explaining their perspectives. Whenever you're not speaking or not in direct conversation with someone, you should be taking notes. Likewise, you should be able to rely on your collaborators to take notes when you're the one speaking.
- Always start a technical meeting by making sure everyone is speaking the same language. Define terminology and agree on the foundational information early, or the rest of the technical debate is a waste of time.
- It's your responsibility to know your limits. Giving 110% for many days in a row is borrowed energy, and you pay that exhaustion off with interest. Step back, take time to recover, and get bored enough that you remember why you were so excited to build in the first place.
- Unblocking others is the highest leverage work you can do. Don't be precious about your focus time - give help openly and warmly whenever that help lies within your ability.
- Be a sponge. Work in a place where there's something to learn from everyone, and learn each quality wholly.
Back to Home