Joe Zhou left his finance role at Uber to become the seventh iOS engineer on Uber Eats. Two and a half years into his engineering career, Joe reflects on his journey and offers advice for others considering taking the plunge into programming.

 

Prior to joining Uber, I had never considered becoming a professional engineer. I studied finance in college. I interned at an investment bank and then in corporate finance at a tech company. When I did start working as a financial analyst post-college, I quickly became the Excel nerd, ninja, and wizard of every office.

Eventually, my finance career led me to Uber. Work was a whirlwind rush that threw me into accounting, new business launches, financial systems, fundraising, budgeting, and strategic planning. Like many newly-hired analysts, I learned SQL to run my own queries: it gave me a taste of writing code.

After two years, I felt like I was stagnating. I craved the feeling I felt early in my career—the feeling of being on an extremely steep learning curve, pushed by both necessity and passion every day. To me, engineering sounded like the steepest of curves.

In my opinion, engineering gives you the power to drive massive impact. An Uber engineer that writes a new feature could save each user ten seconds every time they use their app. This small change adds up to hundreds of years saved every year for our riders, drivers, and eaters.

If you’ve never written a single line of code, try this:

  • On a PC, click the Command Prompt item in the Start Menu under Windows System, and paste: Echo Hello world
  • On a Mac, open the Terminal application and paste: printf “Hello world\n”

You just executed a line of code! Software is just lines of code that make computers do things. To me, what’s even better is building software that makes other people’s computers do something useful. What is best of all is building a tool that delivers value to millions of people. A feeling of absolute bliss for me comes from building products that are useful and beautiful.

 

Level setting

An Uber employee hard at work at our San Francisco office.

After I decided to transition to programming, I felt that I already had the equivalent of a coding bootcamp in terms of preparedness for a full-time engineering job. I was lucky; I went into my engineering interview at Uber with:

  • One college intro computer science course.
  • Eight years of finance experience. This included the proverbial 10,000 hours of Excel.
  • One time in middle school I built a web page. (Didn’t we all? #</html>)
  • Proficiency in Intermediate Python, learned from various mentors. And I used a few self-taught online resources such as Codecademy and codefights. I also wrote a few (bad) scripts for work before.
  • Proficiency in Intermediate Java. I helped my girlfriend with coursework from three classes and read two textbooks: Introductory Java and Algorithms and Data Structures in Java.
  • I learned iOS and Swift by following along with the (Apple recommended) Stanford iOS Swift class CS193P and auditing a night class at my local city college.

Queue the training music

Once I decided to interview for an engineering job, I studied and worked the hardest I ever had for two months straight. I would finish my finance work efficiently, usually by 4:00 p.m., and then find a quiet place to study for eleven hours (minus dinner). A comfortable quiet place is critical. My choice was a big conference room on the fifth floor of Uber’s San Francisco headquarters.

With the conference room lights off, the hall lights provided just enough illumination for me to stare at a computer screen for eleven hours without straining my eyes. There was a whiteboard in the room that I used for practicing problems. The room was also equally close to the coffee machine and the bathroom. Yep, very strategic. And in that room I would stay every weekday until 3:00 a.m. And on the weekends I would come in for another 18 hours of self-study.

How did I spend the time?

  • Half of the time I was solving technical interview problems. These algorithm questions are an integral part of engineering interviews that help to determine if a candidate has a baseline knowledge of how to write code. I learned to solve most problems in Python, including palindrome checking, tree traversal, and linked list node-finding.
  • I spent the other half of the time getting comfortable with iOS development. I re-watched and followed along with the CS193P videos. I hacked together a mock menu scanning app for Uber Eats that used the Tesseract OCR. Looking back, that app left much to be desired. Funny anecdote on my app: I didn’t really understand anything about network infrastructure and the app definitely did not leverage a back-end system. To “upload” a scanned menu, the app just formatted it in an email.

 

Key takeaways

I am frequently asked for advice on how to embark on a similar career switch. Here’s a few pieces of advice I wish I had gotten when I started my journey to programming:

Creating the right mindset

Picture looking beyond the computer from my desk at Uber Eats.

First, a little bit on the mindset you should have when learning to code.

It’s important to figure out your goal (becoming a professional developer vs. part-time hacker vs. learn how to code vs. back-end and/or front-end engineer). After all, it’s hard to determine how you want to travel without knowing where you want to go.

The road to becoming a professional developer is long, and becoming a really good developer will take years. There’s just so much to learn! And the technology constantly evolves so, even once you feel like you’ve taken in everything you need to know, there is even more to learn. In my experience, what makes for a good developer is primarily the ability to quickly pick up new technologies/programming languages. Time is often spent reading vague documentation or existing code and trying to decipher the intent. The faster you’re able to absorb knowledge, the more time you can spend outputting code.

Learning how to code (i.e., write a program that accomplishes something from scratch) doesn’t have to be difficult. You’ll need to learn some basics, such as writing functions and declaring variables, but that’s fairly different from working as a developer. It is like the difference between building a personal Excel budget and doing a professional financial analysis. You can spend hundreds of hours building a fancy model with ways to pull data from your bank account, forecast earnings, or breakout mandatory vs. nice-to-have spending, but this solo activity is very different than what it is like to work on a large team with multiple data sources, version control between files, and coordination. As a developer, you have to write tests, read and write documentation, integrate with other people’s code, and deal with development timelines. Similarly, as a programmer, you have to context switch between languages, codebases, and projects.

Being able to code != developer. That said, learning to code is the first step.

Engineering is more tedious than difficult

When outsiders think programming is difficult, I interpret that as them believing programmers are geniuses that compile complex algorithms in their heads. Actually, modern programming involves fitting a bunch of pieces together, much like fitting the right combination of adapters into an electrical outlet for optimal performance.

A messy series of electrical adapters representing the tedious complexity of engineering.

In other words, we spend most of our time finding the right adapter and attaching it. Or we build our own adapter that performs some simple function in a fault-tolerant way. Engineers break up large problems into ones that can be solved by a series of adapters. And when something breaks, they swap out or upgrade an adapter.

To use a more complex analogy, code is like plumbing. Data is water flowing through the pipes. The structure of the pipes needs to change once in a while because you have a new kitchen or bathroom, and engineers need to prevent leaks. That means creating robust but not over-engineered pipes. Engineers also need to be able to automatically detect leaks via sensors. And when something is broken, you need to be able to trace through a complex network of pipes to figure out where there is a leak or blockage. This part of engineering, tracing a problem through a maze, is tedious. If you need to support a new outlet for your pipes, it can be challenging to figure out exactly where to split off from your existing system.

In my opinion, good engineers are able to maintain a system that they had no part in designing. They can add a new component and have minimal impact on the rest of the system. They leave the pipes in better condition than before they worked on them. Taking this analogy a step further, I think great engineers can quickly learn how the whole system works and visualize how their change will impact the system.

Experience certainly helps, too. Experience allows you to quickly understand a system you’ve never seen before after only looking through a small part of it. A good plumber can guess the cause of a leak before cutting the walls open. Similarly, and maybe most importantly, experience allows you to have an idea of the state that you want to build towards.

You can find success after a career reset

Like the Taj Mahal, which took 20 years to build, engineering takes time and effort to execute well.

My first days as an engineer on the Uber Eats team were terrifying. Another engineer who had the same entry level title as me previously worked at Apple on Xcode, a tool we use to write iOS apps, and had his name in the acknowledgments of Snapchat because he wrote a very popular open source library. And one of our interns was, I felt, multiples more of an engineer than me. He was on his fifth internship after having two prior ones at a large social networking company. He had been writing iOS apps for years and had published an app on the app store. Fresh graduates from school often had been coding for many years already—sometimes since middle school, meaning that they had upwards of eight years of experience compared to my few months. The imposter syndrome was real.

Looking back on those days, however, I now realize two things that make me more comfortable as a professional. First, every member on a team has their own niche. You don’t need to know your niche when you join a team. There are probably a hundred features, back-end systems, engineering tools, and processes involved in the day-to-day experience of being an engineer, and It’s impossible for any one person to be a master of all of them. A well-rounded team will have some expertise in everything. And invariably, you’ll develop expertise in the things you work on. Then you will be the go-to person for your domain. Frodo adventured with a diverse team of dwarves, elves, and humans. Ocean’s Eleven had a pickpocket, conmen, mechanics, electricians, explosives experts, and an acrobat.

Second, I realized professional programmers need to do way more than just write great code.

Uber has six competencies for our engineers and writing code is only core to two of them. In order to successfully ship great features, you need to create alerts and analytics, write documentation, set up experimentation, test thoroughly, collaborate with other engineering teams, work with product and design teams, and resolve bugs. Not everything is about writing beautiful code.

Depreciation is awesome—and expected

In many ways, I believe that computer programming is one of the professions with the most depreciation in skill over time. Computer technologies are constantly evolving. iOS and Android release new patterns (i.e., APIs) and deprecate old ones every year. In fact, iOS is just eleven-years-old. There are constantly new languages, tools, databases, and patterns to learn.

The ecosystem around engineering is also changing. Best practices for design, data science, and product management are also constantly evolving. A computer engineer who takes a seven-year break will have a hard time being immediately productive.

For a new programmer, this fast-paced depreciation can seem daunting. But it’s actually awesome. Every other engineer is subject to the same depreciation. You don’t need to master old technologies to be productive. It can be helpful to learn the motivation behind a certain technology’s design, but a deep understanding of the actual implementation is often unnecessary. Additionally, some technologies are so new that there is not much legacy to learn. There are many specializations such as applications of machine learning or blockchain technologies that are so new that someone can become expert in after just a few years.

This depreciation has another interesting corollary—those who continue to learn as professional engineers have significantly higher potential. Working harder pays off a lot in engineering; It’s possible to be in the top one percent of your craft in ten years whereas it may take thirty years in other industries.

Let me illustrate what I mean with a chart of hypothetical numbers. (Did I mention I used to work in finance?)

Engineers who continue learning about new technologies throughout their careers are likely to advance faster.

The chart above plots the skill gain of Foo and Bar over the course of ten years. They start with 100 skill points each (new hires don’t start from zero!). Foo and Bar acquire skill points at a rate of 20 and 10 per month, respectively. For the purpose of this explanation, they are promoted to the next level at every 200 skill points.

Let’s assume that computer engineering changes at a rate of two percent per month, meaning that after three years, the skill points Foo and Bar have are worth about half as much as before. This depreciation costs Bar an extra two years to make it to Engineer II. The depreciation also means that Bar will hit a ceiling in his career somewhere between transitioning from an Engineer II to a Senior Engineer level. On the other hand, Foo, who keeps up-to-date with the latest technologies and dedicates himself to learning them, is able to become a Senior Engineer at their company after four years and by ten years can potentially look forward to a top role as a Principal Engineer.

 

If you want to start coding…

Here I am posing with a scorpion on Khao San Road in Thailand. No scorpions were eaten during the taking of this photo. We paid a hawker to use her scorpion. She was happy.

So, are you inspired? Here is some other advice and resources designed to help you start coding today:

  • In my experience, Python was a pretty good starter language because of the many online tools, classes, and tutorials. I liked Codeacademy. I’d even recommend you do the JavaScript section while you’re there. But there are hundreds of other resources. For instance, many people I know have gone through Learn Python the Hard Way.
  • Don’t get hung up on learning specific languages. Just find a tool or class that helps you learn and that you’re willing to commit to. An experienced developer can basically write code for a codebase by just Googling syntax. The language itself doesn’t really matter, it just depends on what resource you more readily have access to.
  • Having goals that you are working towards is important motivation. A low-stress goal is to challenge yourself to finish a massive open online course.
  • If you’re interested in the data science route, two tools popular with Uber’s data scientists are Pandas (usually used in conjunction with iPython Notebook) or Shiny (which is powered by R). Pandas offers a great ten-minute getting started guide.
  • You need to learn command line functions. There is no way around it. We just used the command line to print ‘hello world’ earlier in this article. I usually recommend this tutorial: Learn Enough Command Line to Be Dangerous. (Insert rm -rf joke). On the same site, consider reading Learn Enough Git to Be Dangerous, too.
  • No matter your industry, try to integrate coding into your current work. Build a website for your company or team; create an internal dashboard for optimizing workflows; or even play around with large data sets using Python and Pandas. See if your manager will support you. In the end, most engineering is an upfront investment that results in long run savings. Coding is about building something, which is often a combination of learning quickly (because you understand fundamentals) and searching the web efficiently.

And, most importantly, realize that you’ve already started learning! You just wrote a line of code in a command line. You saw a function that used two variables in the standard engineering naming convention of Foo and Bar. You read about the work beyond coding that is required to ship a finished engineering product.

Perhaps most importantly, you decided to approach the challenge with the mindset to always be learning. It’s not difficult. Power through the tediousness. Break down a big problem into smaller parts. Try to envision the whole system. Remember: you can become a great engineer by leaving systems in a better shape than when you found them.

 

Moving forward

Members of the Uber Eats team enjoy the beach during an offsite.

I couldn’t have chosen a better team to land on following my career transition. As an an engineer with Uber Eats, I’ve had the opportunity to create features that millions of customers have used, and my development skills have grown immensely. As a result of a prototype created during an Uber hackathon, I am an author on a pending patent. I’ve also leveraged my new skills and honed them during my personal time to create two apps for the App Store.

I also get to learn from and alongside other engineers like Benito, Aimee, Irina, and these fine folk. Most notably, however, I get to learn on a daily basis from Ferras, Isaac, Xian Xing and the discovery team. In fact, the support system I’ve found across my teams at Uber is one of the main reasons I was able to take my passion for programming and turn it into my career.

 

If you’d like hone your development skills on a diverse team, consider applying for a role on Uber Eats!

Subscribe to our newsletter to keep up with the latest innovations from Uber Engineering.