By Emilee Urbanek
Emilee Urbanek is a software engineer on the Uber for Business team who joined the company full-time after interning in summer 2015. In this article, Emilee shares how her experience at Uber has reframed the way she approaches her growth as a programmer.
I did not intend to become a software engineer. Midway through my first year of college, one of my closest high school friends asked me to help out with a programming assignment. Crumbling under the weight of my own college-sized workload and in desperate need of something with which to procrastinate, I jumped right in.
Lying on my lofted twin bed, I found myself tearing through documentation for Apple Basic II (a language I would never program in again), refining my code, and having a blast explaining how to best approach the problem to my friend. I lost track of time; five hours had passed before I would move on to my own homework, but none of that mattered. That was the night I decided to major in computer science and become an engineer.
As I soon discovered, programming is a challenging, time-consuming, rewarding, and exciting experience that forces you to adopt a very particular and non-linear way of problem solving. Over the next several years, my definitions of ‘work’ and ‘success’ took on new meaning.
In fact, my path from college student to full-time developer was nowhere near as straightforward nor easy as my initial decision to major in a computer science. Along the way, I encountered various scenarios that took me into unchartered territory ranging from tackling assignments that made me doubt my abilities as a programmer to navigating large group collaboration and earning buy-in for my ideas. Fortunately, a number of great people and many great experiences made my journey worthwhile, leading me to where I am today.
My first real world experience as an engineer was my 2015 internship on Uber for Business, where after just one week of being on the team, we participated in a weekend hackathon to build UberEVENTS, a custom event transportation service launched on top of the Uber for Business platform. After my internship ended in August 2015, I joined the Uber for Business team full-time as a back-end engineer, working on shipping new features and improving the quality of the overall Uber for Business customer experience.
It was on the Uber for Business team where I first truly found my voice and confidence as an engineer, and it is on this team where I continue to both grow my technical skills and practice soft ones.
Now, over two years since my internship, I would like to share three key takeaways from my time at Uber that have enabled me to grow those skills at lightning speed and develop a mindset for success, namely: build confidence, trust your first instinct, and always be learning and teaching.
1. Build confidence
“Have confidence!” is often a response to questions along the lines of “how can I be successful in my career?” That is well and good as an answer if you are a naturally confident person, but if you are anything like I was when I started at Uber (an inexperienced perfectionist), you have probably found yourself asking, “where on Earth can I find this mythical ‘confidence’?”
In my experience, confidence is not found but built both on our own fearlessness and the people who support us when we make mistakes.
Despite not having front-end experience, I was able to take on my first front-end task because I had the full support of my team and manager. I set out to reskin one of the existing forms in the Uber for Business Admin Dashboard using redux-form. While I was able to build out the basic functionality, I was learning in real-time which slows things down and I was unable to complete the task as quickly as I wanted to.
With the guidance of my team, I used what could have been an otherwise disappointing experience as a way to build confidence. Rather than highlighting where I “failed,” my manager and teammates remained positive, highlighting where I succeeded and identified areas for improvement with actionable feedback. From there, I channeled my relative failure into a new initiative, empowered to try again.
Thanks to this confidence, I could take my experience and transform it into a springboard for future success. Not long after my first front-end experience, I identified a need for and embarked on a full-stack tooling project necessary for improving Uber for Business’ billing experience and freeing up resources to re-architect the system for long-term sustainability. I even applied the shiny new front-end skills I acquired through my reskinning task to this new tooling project. Before joining Uber for Business, I would not have had the knowhow to drive forward a technical idea in such a clear and tactical way.
If you are unsure of how to build your confidence, start by finding a team that is a good fit for your experience and working style. If given the opportunity during your interview, be sure to ask your hiring manager about team work culture. Do the team’s goals and projects align with your career objectives and interests? Does the team foster a collaborative, open learning environment where it is safe to make mistakes? There is no substitute for being surrounded by people who both encourage you to try more ambitious projects while simultaneously being forgiving when endeavors take a turn toward the unexpected.
2. Trust your first instinct
A roadblock that used to prevent me from moving quickly in my first year as an engineer was not having the guts to act on my instinct. Questions would bounce around my head as I coded: “Is this the right design pattern? Have I abstracted this code far enough? Is this method extensible?” and so on. Most of the time, the responses to these questions were a resounding “yes,” but I would continue to criticize my code before submitting it for review because my solutions, while good (great even), were not always perfect. It was this perfectionist mindset that kept me from trusting my first instincts and taking chances on them.
An extreme example can be drawn from an experience I had shipping a hotfix (which took mere minutes to write and ship) after a mobile bug caused a small outage preventing business riders from taking trips.
While stylistically frightening, I can proudly say that I once shipped code that looked like this:
This code got our customers riding again over 100 times faster (and two weeks sooner) than if we had waited to release the fix with the latest app version, but if I had been a perfectionist in this scenario, this solution would never have seen the light of day.
There is a time and place for quickly written yet logically sound hotfix code, and this is an example of one of those instances. I am no longer too shy to share imperfect code with my coworkers; instead, I feel empowered to take full advantage of the code review process to answer nagging coding questions regarding style, abstraction, extensibility, and so on.
I have found that perfectionism is antithetical to making an impact. It hinders one’s ability to act on their instincts and hone intuition; it is the willingness to move quickly, but not haphazardly, that enables true impact.
3. Always be teaching. Always be learning
I like to follow the “teach a person to fish” model when it comes to training and learning on the job. For instance, when I first started building products on the Uber for Business team, I neither fully understood what a Python generator was, nor how it could be used by Tornado (a Python web framework) to create asynchronous Python code. While anybody could have given me a quick, one minute answer, my manager, who happened to be a Python expert, spent about fifteen minutes demoing how this technology worked. It is safe to say I have never needed to ask a question about Python generators again.
The next time somebody asks you for help, consider taking my manager’s approach: always be learning and teaching.
The “always be learning” portion of this mindset is a bit easier to achieve than the teaching side because it mostly involves asking questions of the “is there a better way to do this?” variety. As I have learned during my time at Uber, it is important to feel empowered to ask questions about everything from complex algorithms and system design to easing pain points with respect to your office’s elevator logistics. There is nothing too insignificant to improve upon.
Some examples of the kinds of questions I ask myself on a near-daily basis include:
- Is there a better way to keep track of everything I have learned on the job?
- Is there a stateless way to implement a summation endpoint?
- Is there a browser extension to convert timestamps into human-readable dates?
- Is there a way to reduce the number of steps involved in bootstrapping this repo?
- Is there a clean way to log a standard set of fields with every log from my application?
Once these questions pop up regularly in your head, it is easy to plug them into your favorite search engine, record the result (if you plan to refer to it later), and spend some time every so often applying the results to your workflow. If you cannot find an acceptable answer, your peers are often an even better resource. In fact, the only reason to use a search engine first is to respect their time.
I promise adopting this practice (if you have not already) will set you up for success.
With these three takeaways handy, I am shipping more and better code than ever before while delivering an increasingly tangible impact for our users on a daily basis. And none of these experiences would have been have been possible without the guidance of my Uber mentors.
I love it here and if you think you might too, we are hiring interns and full-time engineers.
Emilee Urbanek is a software engineer on the Uber for Business team, which recently wrapped up their groups and multi-policy project, and she is now focused on improving the monthly statement and billing experience. In her spare time, Emilee enjoys dabbling in extreme sports, playing stringed instruments, and acquiring relatively useless bits of information.