Insights and lessons I have picked up as a software engineer across research and industry.
Things I learned about Computer Science & Architectural Design
Many of these are skills I picked up before AI-assisted development. I learned many of them from our company's principal engineers.
- Break Down Questions, and Find Answers in the Codebase: The codebase is the most reliable source of truth. When I have a technical question but do not know how to find the answer in the code, it is usually because my question is not specific or small enough. I need to break the question into smaller, more manageable parts that can be answered by examining the code. A non-specific question is "How does this feature work?" More specific questions are "Where is the entry point of this feature?", "What are the key data structures involved?", "What are the inputs and outputs?", and "What issue does this feature solve?"
- Debugging: One effective way of debugging is to guess where the error is before looking closely at the code.
- Ask for documentation: If I need to ask my colleagues questions, I ask for documentation as well. If a colleague can solve an issue I am struggling with, there is often an information gap between us. Having access to documentation helps me close that gap and become more self-sufficient. It also protects my colleagues' valuable uninterrupted time.
- Build the Skeleton First, Even if It Could Be Wrong: Reading large amounts of documentation—such as during a project ramp-up—can be overwhelming. My approach is to first imagine myself as the system architect and think about how I would design the system. This gives me a mental skeleton. As I read, information that fits the skeleton gets absorbed naturally as flesh. Information that contradicts my design prompts me to revisit and refine the skeleton. This way, I can ramp up faster in unfamiliar areas.
- Don't Stop at the Interface: Follow the Logic to the Bottom: I used to focus only on understanding enough to finish the task. A system architect I greatly admire taught me to keep asking, "What is happening underneath?" and to follow the code down to its lowest level. He also constantly asked whether there were alternative ways to solve the problem. Practicing this habit has helped me eliminate unnecessary abstractions and write cleaner, more maintainable code.
- Embrace Contradicting Theories: Humans naturally seek consistency, but seemingly contradictory approaches to learning and problem-solving can both be valid at the same time.
- Depth vs. Momentum: When encountering an unfamiliar concept, there are two equally valid approaches. One is to investigate it until reaching a fundamental understanding, tracing definitions and concepts all the way down. The other is to accept temporary confusion, continue reading, and allow repeated exposure to gradually build intuition. Both approaches work. Learning is not about always choosing the "correct" method, but about maintaining curiosity and momentum.
- Master the Map vs. Explore the Territory: Sometimes I want to understand the entire architecture before moving forward. Other times, I explore the areas relevant to the task at hand and allow the broader picture to emerge over time. Both approaches are valid. Understanding often comes not from seeing everything at once, but from gradually piecing together information through exploration.
- Software Design: Sometimes violating a principle in a specific place is the right engineering decision because it provides benefits elsewhere (performance, simplicity, maintainability, delivery speed, etc.).