Over the past 1.5 years, I've made multiple transitions in my life and career:
- Started as a senior engineer at a post-acquisition startup in San Francisco.
- Took over as manager of my engineering team.
- Quit the manager position after a year due to serious burnout.
- Briefly helped out a couple of newly-formed startups founded by former coworkers.
- Studied data structures, algorithms, and system design while interviewing for engineering positions with other Bay Area companies.
- Got fed up with the system (and/or had an early midlife crisis).
- Left the Bay Area to travel and work full-time in an RV.
- Started my own 1-person contracting and consultancy agency.
- Briefly worked as a full-time engineer for my main contracting client.
- Returned to self-employment, working on my own RV-related software product as I pay the bills through further contracting.
So you might be thinking "Thanks for the auto-biography, but how does all this relate to the title of your post?"
Each of these phases involved a very different relationship with software development as well as wildly-varying philosophies for how software should be built. Having been exposed to numerous such variations in a short period of time, I have a unique opportunity in my career to look back and compare each role before it all slips from memory.
Senior Software Engineer at Post-Acquisition Fintech Startup
- This company was run by former leadership at FAANG companies, and many processes from those companies were brought into play. Development focused largely on structured and collaborative development with a large focus on peer review. Because it was a fintech company, we also needed continual sign-off from fraud and legal representatives.
- Before writing any code, we first wrote product specs, requested spec review, responded to feedback, and (hopefully) received sign-offs.
- Development required interaction with systems of which I had little knowledge and often required outreach to multiple engineering teams.
- The challenge wasn't usually problem-solving so much as ensuring my changes worked nicely with all systems while meeting criteria of multiple stakeholders and quarterly plans.
- Any departures from normal practices typically required a request-for-comment and general approval from other experienced (typically staff) engineers.
- PR reviews were mandatory, and often required feedback from multiple engineers.
- Automated testing was mandatory for acceptance, and for many changes, it was up to the engineer to write up a user acceptance testing plan. The testing plan was then executed by multiple team members, and feedback was provided. After rounds of testing and review from engineers, product, design, and legal/fraud, changes were greenlit for release.
Coding as an Engineering Manager
- For me, becoming a manager meant a massive shift in the type of work I'd been doing as an engineer. My job was essentially 100% focused on managing with 0% focus on writing production code.
- While I didn't write production software, I still used code to solve several problems. I wrote a good bit of code to analyze customer data, generate reports, and process data used to make my case for requesting resources and proposing projects. I had a habit of taking on data-intensive but non-time-sensitive projects I didn't want to drop on my team.
- Unlike production software, the code I wrote at this stage (largely using Python, Jupyter Notebooks, and SQL) was to solve an immediate problem that was uniquely intended to support a short-term process or decision. It was often one-time-use. The quality of the code reflected that. It wasn't version-controlled or tested, and I doubt many people even know I wrote it. However, it made a major difference in how I was able to tackle my problems and make my case as a manager while supporting my team.
Helping out with Pre-Seed Startups
- While assisting with a couple super-early-stage startups, all my software designs and code (if I wrote any at all) were focused entirely on proof-of-concept.
- The main focus was developing a prototype to help gain early customer and investor interest. I knew that while my early designs and code might set the direction, the code would likely be obliterated.
- The goal was to write as little software as possible for most of these projects while still demonstrating and conveying an idea. I mostly just remember quickly iterating on wireframes in Figma and recording narrations while quickly developing proofs-of-concept to validate direction.
- Engineering feedback was largely non-existent (for one startup, I was the only one with engineering experience at all).
Prepping for FAANG-Style Interviews
- I hesitate to even mention this phase of my last year, but it's a real software development experience that most aspiring Big Tech or Big Tech-adjacent engineers have to deal with at various points in their career.
- Very few skills needed to succeed in a technical interview are practiced during real-life engineering work. This means that day-to-day professional experience typically doesn't contribute much to your technical interviewing capability. If you want to succeed in interviews, you have to set aside hours, days, weeks even months to prepare.
- Software engineering interviews are a timed performance you must choreograph on the fly. They require you to solve problems quickly and concisely while simultaneously explaining your logic and responding to the interviewer's questions and suggestions. You need to be constantly aware of remaining time. Short-term time constraints are something you almost never experience in a professional engineering role. More slow, deliberate thinkers like me really have to work hard to rewire our approach.
- Following a common path of many engineers, I prep for these interviews by dividing up my time into a few different categories: memorizing common data structures and algorithms, grinding through code-based challenges on a platform like LeetCode, and reviewing system design best practices. Depending on the role, I've also focused up on specific skills and languages.
- The code I've written during interviews and related prep is almost alien-like compared to the code I would write on a typical day at work. That's why it's worth mentioning in this post: interviewing and related prep creates level of coding muscle confusion that forces me outside of my comfort zone.
Contracting and Consultancy
- In contracting and consulting, the product I'm selling is my time and expertise. While it's important to build quality software, my focus is more on delivering value as a hired professional.
- Compared to full-time employment, everyone is more acutely aware of my time costing money. As a full-time employee in past roles, I was more at liberty to help out a coworker or take detours in the name of long-term improvement. As a contractor, not so much. I need to focus on delivering the agreed-upon deliverables, whether that be a specific project or just billable hours.
- Engineering practices and philosophy can change for every client, and it requires that I quickly adapt to their expectations. The approach may vary depending on their own engineering culture, or it may just depend on how they want me to spend my limited time. Maybe they want tests. Maybe they don't. Or maybe they want tests written eventually, but they don't want me to spend my limited time writing them. In one project, may embed with an engineering team and follow their practices. In another, I may work and ship as quickly as possible on a project I own as a solo engineer.
- From a collaborative standpoint, focus is often less on debates and discussion and more on transactional elements: communicating estimates, sharing progress, and delivering tangible results. The quality of the product I deliver and the speed at which I deliver will likely impact whether I get repeat business or referrals in the future.
Bootstrapping my own Software Product
- This is a new experience for me and requires perhaps the biggest change of approach. It also introduces new stressors that I'm not yet very adept at handling. In addition to software development, I'm also responsible for determining market viability, product-market fit, price sensitivity of potential customers, ad spend, customer support, and other non-technical problems.
- As a bootstrapped founder, I also have to grapple with the fact that the code I'm writing on any given day may literally be a waste of my time and money. Maybe the entire product isn't a bust, but maybe the current new feature. It may sound facetious, but when I'm writing software for someone else, it's never a wasted effort ... for me! I get paid regardless of whether the product succeeds. The business takes the loss if the product fails. As a founder without any funding, everything I work on is an educated guess on what is the best use of my time. Losing time is losing money when I could be doing something else more profitable.
- It's challenging not to let these stressors impact how I build software. I want to work quickly, get to market, and start acquiring customers and feedback. However, sacrificing too much quality in the name of accelerated speed to market may create buggy software that gets in the way of determining product viability. I want my product to get rejected because people hate the idea rather than because they hate the experience of using my software. I need a clean signal, and that requires a balance of speed and quality in engineering.
- In a sense, my approach to building software as a solo founder is quite similar to my approach to contracting and consulting. However, I'm both the client and the consultant. Just like in consulting, I need to maximize value (but this time, do it for myself).
Lessons Learned
As I look back on all these experiences over the last year, I'm grateful for all the opportunities I've had to grow as an engineer. The demands and objectives of each role have pushed me to think critically about what to bring to the table for any given task. There is no canonical "right way" to build software. Instead, it's a balancing act that takes into account the value of short- or long-term investments, maturity of the company, clarity of product direction, and a plethora of other factors.
Finally, it's worth pointing out that soft skills are critical at each level. Externally, my quality of communication and interpersonal skills have played a significant part in my effectiveness. Internally, learning how to handle stress and uncertainty will play a major role in my success as an entrepreneur. That's where I see my greatest opportunity and greatest necessity for growth in the coming year.
I'm not just an engineer. No one is just an engineer. How you interact with the people around you, how you talk to yourself, and how you show up as a person will have a much bigger impact than any specific level of hard skill.
Engineering Manager at Cedar
1 年I loved this read. We should catch up!