Friday, December 14, 2018

What I Didn't Learn During University (Lessons from Interning in Silicon Valley)

When one removes themselves from their comfort zone and settles down in a new environment, suddenly inefficiencies become glaringly apparent. It is kind of like when you spend too much time at a beach on a sunny day-- sure you feel comfortable and that you're at your best -- until you step into a hot shower later and realize through intense pain that you are burnt.
University for me is the equivalent of a sunny beach, and I had developed sunburn (inefficiencies in some areas I didn’t realize). Entering industry was like stepping into a warm shower which has burned me in some places but ultimately made me more aware of my weak spots.

Let the following anecdote from my internship set the tone.

The time is some day within some month (I think it was like, June?), it is a couple of months into my internship. I've been given the chance to give a brief presentation of my solution for a problem facing the autonomous vehicle system we're building (note that I am on a team that handles maneuver and path planning).
I was hyped. University made me well prepared for this moment. I reached into my back pocket and whipped out 3 years of undergraduate algorithms, architectures, and design principles and composed a 2-page document with an elaborate outline of exactly how we could solve the problem.

The document was pristine, elegant, focused, and one week later it was ready to present.

I booked a meeting room, invited my colleagues, and took a stance at the whiteboard.
We meet again, whiteboard. Except at this time I am not at your mercy as an interview candidate, but instead, I am presenting my intellectual capacity on your barren slate.
I firmly grasped the nearest EXPOTM  whiteboard marker and took firm stance -- as if I were the last remaining samurai of the Meiji restoration --  wielding my sword.
I started pitching.
I'd planned to start my talk by outlining the key algorithm we'd use, a system diagram I created, and lastly show it working on a couple of examples.
The problem is I never got that far...

After a couple of minutes of introducing the algorithms and definitions I'd created for the problem one of my colleagues interjected:
"So, what problem are you solving?"

I stopped where I was, a bit shook

My colleague inquired...
"Ok, walk through what your solution is going to do here."

My colleague sketches out a scenario on the board

I politely exclaimed that "I'm going to get there, I'm just explaining the underlying architecture first and why it will work."

My colleague retorted...
"Prove to me it will work here, please"

If I were a samurai, this would have felt like I was staring down the barrel of a Murata rifle right about now.

I began trying to walk through the example. "You see, since we are using [ALGORITHM] we can leverage the fact that..."

My colleague interrupts again...
"Let's talk about that after, I just want to see exactly what your solution will do here."

absolutely s h o o k

I tried to regain stance, of course he has questions... after all, I haven't finished presenting my ideas, of course! I had to keep my ego down and sell this solution to them. I had to prove that I was a good engineer.
I tried to dumb down my solution and explain it in high-level terms and began running through the example, quickly realizing what was an engineer's worst nightmare during a presentation.
an edge case.

My solution didn't work on this example.

I'm a fool, I told myself.
Another engineer commented..
"I see where you're going with this, what if we also consider using [alternative approach] instead?"

That was a brilliant idea.
Why didn't I think of it?
Speaking of introspective questions, I had a few others at the time: Why was I wasting a room of engineers time with a design that amounted to 2 pages of cryptic jargon? Why did I spend a week writing these hieroglyphics in the first place?

...Why did I get accepted into this job?

So the situation probably wasn't that brutal (my colleagues at Cruise are really supportive!); but that's how it felt. I felt the burn and realized quickly I was in over my head among highly skilled engineers at a competitive company in one of the most competitive industries centered in the tech hub of the world. It was time to adapt or perish.

My objective in this blog post is to outline some of the things I didn’t realize through University, that are strictly required to do well in Industry and have an impact in the tech world. Conveniently, these things are also beneficial in University, so in the end, I feel I’ve undergone a positive feedback loop.
I’ll run through some of the key things I’ve realized in a countdown of significance.

Simplicity in Communication and Design

Sometimes you’ll cross paths with an executive and have a question. You have to quickly communicate the key question and result. Unlike in a University essay where you are often required to hit certain topics to get marks and some arbitrary minimum word count, or in a blog post (like this one) where I have the leisure to ramble all I want, in industry you have to decide quickly: what is important? What isn’t important?  How do you present your information effectively and concisely to someone else?

Backing up your argument with real-world data.
When explaining yourself, backup key statements you make with an example based on real world data. If you don't, you will be asked to and may be embarrassed to find your secret sauce doesn't make every scenario taste good (i.e., you fail edge cases).
*clears throat*
FOR EXAMPLE:
A weak argument with unsupported claims: This is the huge problem our system faces, and my feature will resolve it!

Even if you know this to be true, it is too broad and comes across as a sales pitch, leaving the listener with more questions/concerns in some cases.

A better argument with supported claims: Based on our recent metrics, the largest % of our issues on the road attribute to this problem, my feature should address this problem in [specific scenario] and so we should invest in implementing this feature.

Both of these arguments have the same objective: to use your idea; but the latter is backed with more data.

In University we are taught to support our arguments rigorously;  however students are also encouraged to make bold statements for the sake of having a compelling narrative in an essay or project proposal. In a research context, of course, you'll have some sort of empirical or theoretical results to back up your work; but this is a longer and more elaborate process and you still often need to have a compelling research objective if you wish to maximize funding.  My point is, making some big claims can be valuable in getting someone's attention; but often during a casual discussion with another engineer, it is more useful to have smaller claims supported by a rigorous argument.

As an engineer the things you say in a company will be looked at much more rigorously and by many more people with years more experience, not a single professor marking your assignment  (or one of their TAs).  Even more so at an autonomous vehicles company, every assumption is tested to its maximum; the safety of passengers and nearby civilians depends on it.

Bottom-up reasoning
When I was given the task of solving my first major engineering problem, I immediately dove into thinking about what algorithms I can apply to it, and how it could be structured. I spent a lot of time creating a solution, designing some of the code implementation, and making a presentation (I would have gotten full marks on a software engineering course!) only to realize my solution didn’t handle all of the edge cases.

No one cares if your solution is elegant and pretty if it doesn't solve the real problem.
What I should have done is got my hands dirty and spent time exploring right from where the problem was occurring, surrounding myself by it, feeling the problem, identifying what scenarios are of concern and must be resolved. After this I could create a simple solution that handles these scenarios and then iterate on this solution to handle further cases.

Software engineering courses implicitly teach these skills in University but it was more from a theoretical perspective. If you've never been in the industry before it'd be hard to extract the key intuitions from lectures. In retrospect, during class I was too focused on getting the marks on an assignment, memorizing definitions for exams, and making my code elegant and efficient for the professor rather than correct and concise for the user. In industry, you have to get a useful MVP (minimum viable product) as quickly as possible and then iterate on it.

Analysis of incoming information: Classifying, Scoping, prioritizing, planning, executing.
During my first weeks in industry I basked my eyes in the wonders of the Company's codebase in all its glory -- as if it were a sacred tome, and a curriculum I had to fully internalize. I spent some time on the weekend mapping out how I would study it all. I wanted to understand all of the algorithms, and the definitions for things, and the design of those things and how they integrated into all of the working systems to ultimately make a car drive autonomously. It quickly became apparent that I wouldn't have time to digest it all, and this stressed me out.

I'd claim there are five key steps to collecting information and solving a problem with it.
Classification: Identifying the information, what knowledge you have vs what you lack.
Scope: Organizing your information into reasonable chunks to solve desired problems
Prioritize: Selecting key aspects of problems that need to be resolved for maximum impact.
Plan: structuring how you will solve the problem
Execute: actually following through with your plan and solving the problem

In University the majority of information we deal with has been curated and presented to us with guarantees as to if it is accepted literature or rather an open theory – the classification is done. The information has been further organized into a compact curriculum -- scoping is done. What I think is taught really well in University is how to take this well classified, scoped knowledge and as a student prioritize it given importance on exams, and then plan how to study it all and execute on this study plan. I was great at attending lectures, reading notes, extracting key definitions and study concepts and then studying them; but this is because I was analyzing a simplified curation of material and in which most of it was clear to prioritize.
For example, if I want to memorize a definition, I knew that

$\frac{P(OnExam)}{DifficultyToLearn}$ is a good heuristic estimate as to what priority I should give to studying the definition. That is, I will study something that has a higher chance of being on an exam, and that is simple to learn.

In industry, however, there are so many components and so many terms that have been defined within those components. There an endless abyss of knowledge that is valuable to be aware of and accessible but not needing to be "mastered". I was really uncomfortable with the fact that I wouldn’t have time to rigorously study it all, and didn't know what to prioritize first.
What I don’t believe I developed during University is the ability to take an arbitrarily large problem space, classify the information you are taking in, and use this to scope your own possible projects before prioritizing.

Consider the space of all possible information,
We can classify information into four quadrants (based on the Rumsfeld Ignorance Management Framework)

Known Knowns: This is information you can effectively use. An example is stuff you've learned during a University class. You have the knowledge, and you (hopefully) know how to apply it. All that is left is to execute with this information (do well on your exam).

Known Unknowns:  This is information you can reason about but may leave "implementation" details for later. For example, when you begin a course you may have access to the full curriculum, but don't yet know all of the material. Planning is an effective way to handle Known Unknowns. As a student, you should map out what you need to learn and your estimated study time. If the exam comes up and you do worse than expected, this was likely due to poor planning skills rather than you not being intellectually capable.

Unknown knowns: This is the type of information that rattled me the most in industry. It is information you understand and can use, but don't consciously have it on your mind. For example, this would be like panicking on an exam and implementing a complex algorithm to solve the problem, only to realize afterward that you could have used memoization and solved the problem in a few lines.
The best way to handle Unknown Knowns is to make them Known Knowns, by discussing your thoughts with others and bringing all of your collective knowledge to the surface so you may reason with it.

Unknown Unknown: This is unexpected information, and usually impacted by some external event. For example, you accidentally sit down in the wrong exam room and begin writing a Physics exam when you meant to write a Computer Science exam. You didn't expect this mistake to happen, and let's assume you didn't study for a physics exam.  You can't really deal with this type of information easily, but instead, make sure you're communicating frequently with others and keeping your mind open.
I try to handle unknown unknowns by reflecting on myself (like in this blog post) about things I'm learning, and analyzing them to become more aware of the things I don't know, in hopes of reducing my ignorance.

More rapid communication with others: Teamwork
This is hands down the most differing thing between University and Industry.
During my time in University, the introductory software engineering course and some later (4th year courses) begin to dabble with teamwork by enforcing group projects; however as many know, these usually result in one subset of the group being burdened with a large portion of the workload in an uneven distribution, resulting in many all-nighters because some people in the group decide to place all of the work on their friends and then disappear for a large portion of the semester.
Earlier in a University degree, you are often discouraged from true teamwork, in the sense that you must write down your own answers separately, or else be hit with academic dishonesty penalties.

This is radically different from industry. When I showed up, my manager told me of a "30-minute rule" which indicated that
"if you get stuck on something for more than 30 minutes you should book a meeting with someone who knows how to do it, and figure it out together"

There is no notion of academic dishonesty, there is only efficiency, and the distinction of either completing or failing to complete a task. Thus, most of the time my colleagues and I will group together and solve a problem on a whiteboard, and then have one person write down the solution and report back with results.

Conclusion

In short, what I've learned from my internship thus far is that school covers a lot of valuable things; but much of it is in a theoretical sense. Each one of us may extract different insights from our degrees; but if you remain in a single environment for long enough I believe you eventually become numb to what the key bottlenecks in your reasoning are. It is crucial to expose yourself to new environments and problem domains in order to highlight your local maximum in terms of effectiveness so you can reach your true potential.

1 comment:

1. Beautiful, maybe you won't abandon academia but now you've been exposed to the rapid pace of learning and doing required in industry. Great read, really good advice, love it!

Please feel free to give feedback/criticism, or other suggestions! (be gentle)