Josh Choo's blog

One year as a software engineer

01 August 2021

One year has passed since I started my first job as a software engineer. The one-year milestone is significant because I've dreamed of building software as a career since I was a teenager. As a teenager, I developed a fascination with how computers worked. I began learning to code after my uncle passed me a copy of The C Programming Language book by Brian Kernighan and Dennis Ritchie. At that young age, I set my mind on pursuing Computing in university. But things did not pan out as my younger self had expected.

In high school, I developed a deep fascination with physics and wanted to satisfy my curiosity in some field of applied physics, particularly in mechanics. So, I made a last moment decision to study Mechanical Engineering instead of Computing. In my heart, I reasoned that I could pivot to software engineering in the future after finishing my studies.

As a university undergraduate, I took a few introductory computing electives. But I did not make good use of the university's resources to further my software development aspirations. In retrospect, I should have taken Computing as a minor or a second major, but I didn't do so. Instead, I took electives in other fields that attracted my interest, such as the Sciences, Economics, and Accounting. As a result, I thought that my interest in software development had waned.

But things changed in my third year of university. As an Android enthusiast, I would root my Android smartphone and flash different custom Android operating systems (a.k.a, Android ROMs) to test their cool features. I admired the indie developers who created these custom Android ROMs, and I wanted to build the same awesome experiences. So one night, I followed the CyanogenMod (the most popular custom Android ROM at the time) tutorial and compiled my first custom Android ROM. The tutorial was straightforward but did not teach much beyond the minimum to start developing Android ROMs. Nevertheless, despite the shallow knowledge I gained, I felt proud to take the first step and build something complex but useful. That experience kick-started my journey in learning, building, and customizing Android ROMs. More importantly, it re-ignited my interest in software development.

For around two years, I released my own Android ROM and kernel to the public and established a community surrounding it. I also contributed to developing another popular Android ROM and collaborated with many talented individuals in the Android ROM development scene. I could write a lot more about this significant chapter of my life, but that would be better left for another blog post.

I mentioned earlier that I thought I could pivot to software engineering after attaining my degree in Mechanical Engineering. But life is rarely straightforward. Upon graduation, I entered the corporate world, working a non-tech job while continuing my Android operating system development hobby during the nights. As time flew by, I grew restless with my corporate job and desired to switch careers to software engineering. In my second year at my corporate job, I set a goal to get a software engineering job in a year. However, I faced a dilemma: I did not know which field of software engineering I wanted to pursue.

At that time, I knew I enjoyed Android operating system development. But unfortunately, there were zero jobs for this niche in my country of residence. Even so, I evaluated several other software engineering fields. Finally, after a process of elimination, I decided to explore web development because there were many public learning resources and job openings available.

I felt overwhelmed at the beginning of my web development journey. Pivoting from Android operating system development to web development was pretty much starting from scratch. There were many other university graduates with relevant internship experiences. But for me? I had zero software engineering internships, and the only relevant knowledge I had was basic HTML and CSS. I knew nothing about JavaScript, APIs, front-end frameworks, networking ports and layers, databases, micro-services, and distributed systems. If I wanted to get my foot in the door, I needed a plan. I considered the following two plans:

  1. Join a web development boot camp.
  2. Self-learn through online courses. Read many technical books and articles. Develop personal projects.

Attending a boot camp seemed appealing, but I deemed it risky because I had little money to quit my job and pay the tuition fees. I also preferred to have greater flexibility over my learning pace and material. Hence, I decided to go for the self-learning route. In August 2019, I signed up for my first Udemy course on back-end development with Python and Flask. I would later go on to complete more than ten online courses.

The self-learning route was challenging because I needed to create my learning plan and schedule. Taking online courses added a bit of structure to my learning, but I still needed to choose which online courses to take and dedicate time to work through them. To free up energy and time for learning, I made sacrifices and eliminated distractions, such as social media and YouTube. Letting go of my Android operating system development hobby was the most painful sacrifice I made.

I established a learning routine to keep myself focused and motivated. I made daily commitments to move the needle by learning something new every day. I woke up early in the mornings to go through online courses. After dinner, I continued with my online courses. I also measured the number of days of my learning streak. My learning streak surpassed 200 days by the time I began applying for software engineering jobs.

For the first three months, I completed several back-end development courses building APIs in Python. However, my API projects felt "bare" without a user interface to interact with them. I didn't like that, so I decided to learn how to build user interfaces by registering for several front-end development courses on Udemy and FreeCodeCamp. That meant I had to learn HTML, CSS, and JavaScript. I formerly held an unfounded aversion towards JavaScript because of negative comments from vocal JavaScript naysayers and the list of JavaScript WTFs behaviors that they raised. Still, I set aside my pride and started learning JavaScript.

Having used JavaScript for a few months, I developed a deep appreciation for the language. Looking past JavaScript's WTFs, its peculiar handling of this, and its lack of type annotations, I enjoyed JavaScript's expressiveness, versatility, support for multiple programming paradigms, and the massive ecosystem surrounding it. Building APIs with Node.js and Express was a pleasure! Learning React completely changed my perspective on front-end development for the better. I was hooked!

With my newfound front-end and back-end development skills, I felt ready to start building my portfolio of full-stack projects. I enjoyed optimizing performance on Android devices when I used to build Android operating systems. In continuation with my interest in Android performance, I created JankBenchX, an Android UI performance benchmark suite consisting of an Android benchmark app, a web app, and serverless functions. JankBenchX provided a comprehensive and convenient solution for indie Android operating system developers to benchmark Android UI performance, store the results, and share them with others. I'm quite proud of my JankBenchX side project because indie Android operating system developers continue using it to this day. I developed several more full-stack side projects before deciding to apply for software engineering jobs.

I never felt quite prepared when I began applying for jobs. I hadn't attended a job interview in years. I didn't know the answers to many Computer Science interview questions. I hadn't brushed up on data structures and algorithms problems. Even so, I created a resume and listed my side projects and prior experience in Android operating system development. I searched through online job portals, shortlisted several roles that interested me, and applied for eight jobs. Meanwhile, I began tackling exercises on Leetcode and cramming computer science knowledge (e.g., databases, distributed systems, networking, TCP, HTTP, etc.).

Four companies invited me for interviews. My first interview was with a food delivery company. I flunked it. I tried to sell myself too hard by rambling about my tech stack choices for one of my side projects, which wasted my interviewer's time. The interviewer was kind to provide constructive feedback and offer to schedule another interview to try again. We had a second interview, which turned out much better than the first. He liked that I had many contributions on GitHub and mentioned that he was willing to send me to the next round. Unfortunately, he later informed me that the company was suspending the hiring of junior engineers because of uncertainty around COVID-19. I felt dejected.

Besides the food delivery company, I interviewed with a major local e-commerce player ("E-Com"), a "global consumer internet company" ("Internet-Com"), and a fintech startup ("Fintech"). I later found out that I wasn't allowed to simultaneously interview at E-Com and Internet-Com because they were sister companies, and they enforced such a rule 🤷. So I chose to continue interviewing with E-Com while putting the Internet-Com interview on hold.

E-Com and Fintech had different interview approaches. E-Com favored online coding assessments, Leetcode-style whiteboarding sessions, and live coding a React component. Fintech preferred take-home assignments, systems design case studies, and interviews with colleagues and C-Suite. Both companies asked me to share about my side-projects and probed the rationale for my decisions. The entire interview experience was nerve-racking. My heart rate tracker never failed to alert me about my elevated heart rate, which made interviews more exciting terrifying 🙃. After each interview, I hoped for a favorable outcome and checked my email regularly for good terrible news. I dreaded the idea of failing all my interviews because I didn't have a backup plan.

Fortunately, E-Com and Fintech didn't think I was 💩, and they extended job offers. I felt overwhelmed and relieved when I received the offers because it marked the end of my nerve-racking job hunt and the beginning of my dream to work as a software engineer. I am grateful that they took a chance on this bloke with little relevant experience besides online courses, side projects, head knowledge, and Leetcode grinding.

It wasn't easy to decide which offer to accept. A wise human once tweeted that we make better decisions after sleeping on them 🛌. So after sleeping a few nights, I followed my guiding principle: "Choose the path of least regrets." So I searched my heart and accepted the offer to join StashAway (Fintech), as a full-stack engineer.

And so my new journey begins!

One year in...

I've been working as a full-stack engineer at StashAway for a year now. My time in StashAway has been incredibly positive because of plentiful learning opportunities, challenging and engaging work, avenues to make impactful contributions, welcoming people, and the fantastic culture.

I was the second engineer to join a new squad responsible for developing a financial planning feature. My responsibilities included building the financial planning feature on the mobile app, developing the financial planning model, and creating the APIs for onboarding and updates to the model.

During the first few months, I familiarized myself with the code contribution process, continuous integration pipelines, and deployment systems. I've read about similar systems and processes before, but this was my first time working with them. I also knew little about StashAway's internal services, which perked my curiosity and eagerness to learn more.

I remember not knowing StashAway's workflow to make code changes and merge them. At that time, I was more familiar with trunk-based development and the "fork a repository, make a change and send a pull request to the original repository" model (please let me know if there's a proper name for it) of open-source development. I needed to confirm the step-by-step process with my manager to make my first merge request (GitLab's equivalent to GitHub's pull request).

It was also my first time developing a mobile app in React-Native. Still, I picked up swiftly thanks to my prior transferable knowledge in React and because I took a Udemy (I swear they didn't sponsor me) course on React-Native development before joining StashAway.

An early lesson was the importance of breaking big problems into smaller, well-defined tasks. I learned this the painful way after sending several monstrous merge requests exceeding 10,000 lines of code to my poor manager and colleagues to review. However, I renounced my evil ways after my squad switched from free-flow development to a more structured Agile approach to scoping tasks.

Over the past year, I participated in the initial stage of designing the financial model to launching our project in Singapore and post-launch maintenance and feature development. I was most proud of designing and prototyping the architecture of the financial projections model and optimizing the performance of the projections. I also built fancy custom charts with D3 on the mobile app, although I wasn't a fan of such work. But, hey. At least my learning points from FreeCodeCamp's Data Visualization with D3 course, which I dreaded, didn't go to waste.

Outside of my squad, I've been involved in other impactful areas of work. For example, I led a (peaceful) crusade to adopt TypeScript and migrate existing JavaScript codebases to TypeScript because I would otherwise lose my sanity using JavaScript in any complex production application. I also developed several proofs of concept (e.g., micro-frontends, etc.), participated in hiring interviews, and onboarded new engineers.

Working at StashAway enabled me to grow rapidly as a software engineer. I seized opportunities to tackle new challenges, improve developer experience, push for novel solutions to difficult problems, and sharpen ideas with intelligent colleagues. A special appreciation to my manager, James, who didn't dismiss my wild ideas but instead always listened and provided constructive views to strengthen my ideas. I flourished under his leadership and support. Furthermore, I feel fortunate and grateful to work alongside outstanding squad teammates. They've set the bar for what an excellent team looks like early in my career.

I'm living my dream, doing what I love as my career. I didn't get here on merit alone. Many people took chances on me 🙇, and I was lucky to work in an optimal environment for my growth as a software engineer.

It's only been one year. Yet, there's so much more to learn and build!

I'm just getting started!