On Technical Interviews
Recently, I encountered this blogpost, titled "Getting a job at Apple without going to college or doing LeetCode". The article was written by a pre-university student who interned at Apple over the summer. Their experience in acquiring this internship was rather unique: they were reached out to by an Apple employee after promoting their own personal project on Twitter. What’s even more peculiar is that they had no technical interview — extremely rare among this era of LeetCode-esque questions, especially among FAANG companies.
The author, Andrew Zheng, shares his opinion on technical interviews in the article:
I feel like people are so fixated on LeetCode and all these other coding questions that they’re forgetting that this is just one path to getting a job. There’s plenty of other ways that aren’t as hard and don’t require hours grinding over some dumb problem. Is it really worth grinding so much? Studying the most advanced Data Structures and Algorithms that you’ll easily learn just from building? And after getting the job, are you even going to use the stuff that you spent so much time practicing?
While I think that it’s cool that he was able to work at Apple without encountering a technical round, I do somewhat think he’s missing the point of technical interviews. Yes, candidates applying to tech-centric companies are incredibly focused on LeetCode problems. Yes, they do spend significant time grinding and dissecting problems. Yes, a lot of it happens to be rote memorization of data structures and algorithms.
I do, however, think that they’re a great way to measure candidates — when we do them right. The problem with a decent amount of technical interviews today is that they’re purely testing for rote memorization of these algorithms.
Good interviews observe how you reason about invariants present in a system.
This can be broken down into several parts. First, they test how you identify invariants about a system. Second, they test how you reason about what operations you can perform on or introduce to a system that maintain its invariants. Third, they can test how you could introduce new invariants into an existing system. Finally, it shows how you communicate your awareness and handling of these invariants.
Why is this important? Invariants and properties of systems seems to be closer to computer science than software engineering, no?
The reality is that even in professional software development, when interacting with large codebases, we are constantly interacting with and understanding invariants in a system — just implicitly.
To give a personal anecdote, I interned at Amazon this summer working on an internal compiler between artifacts used at different Alexa backend services. The compiler was implemented in more idiomatic Java, and as such, involved shared, mutable state between different compiler passes. As a result, the order of compiler passes could influence the resulting generated output you received. Certain invariants became true after certain compiler passes, and certain invariants became obsolete after others. As I was introducing new compiler passes, I was more meticulous in being aware of invariants that my passes would receive when run at their specified order slot. My compiler passes also introduced new invariants, which I had to state explicitly for future maintainers of the compiler. I had to know what operations I could perform that would maintain the existing invariants, or know and state that an invariant would become obsolete.
I could talk about the various algorithms I used when implementing my compiler passes, but I don’t think that’s important nor relevant to the importance of technical interviews. Yes, I did use several algorithms and design patterns that I learned from studying for technical interviews, but the algorithms and design patterns would have changed had I been given a different project. You’re somewhat expected to be able to learn and apply these patterns in an internship. Knowing how to think and reason about invariants was significantly more useful for me.
I further believe that an algorithms class isn’t to teach purely algorithms, the same way a computer science degree doesn’t teach memorization. An algorithms class is where you first learn how to reason about invariants. When you come to this realization, then solving algorithmic problems becomes much more approachable. You can simply ask yourself what invariants are present and what operations you can perform as a result of those invariants.
While it would be a nice and less stressful process to do away with technical interviews, I think it’s important to understand a candidate’s reasoning ability regarding systems. Technical interviews are an effective way to assess that ability in a controlled, sandboxed environment on a small problem that the interviewer understands.