6 ms·
Ability to make complex things simple is what sets apart a great programmer from an average one. So why do most programmer interviews at companies such as Googl
by flowerlad 7y ago
Ability to make complex things simple is what sets apart a great programmer from an average one. So why do most programmer interviews at companies such as Google focus on writing performant code instead?
Most professional programmers only occasionally need to look into performance issues, but need to take complex things and simplify them with every line of code they write. And yet most programming interviews don’t evaluate this ability. I think this should change.
- james_s_tayler 7y agoWe have this discussion on HN every month. So far the answer I've worked out is: Because its optimal solution to let talent flow through BigCo in SV. There is no domain or tech-stack specific stuff. So studying for the interview process allows the applicant to apply for multiple companies. At the same time it's a pretty hardcore process, so the company knows they are getting engineering talent that is a) smart and b) obedient. For the rest of the world it absolutely doesn't make sense and that's why where I live, you don't see that style of interviews at all.
- flr03 7y agoI came up with the same conclusion. It's not a technical test in such, it's more a competition/motivation test.
- wpietri 7y agoOne thing I'd add: One possible function of an interview process is to find qualified interviewees. Another is to make interviewers feel smart. I think typical BigCo interview processes are optimized for the latter. David Epstein's new book Range talked about academic research splitting domains into kind vs wicked. Kind learning domains are ones where "feedback links outcomes directly to the appropriate actions or judgments and is both accurate and plentiful", while wicked ones are "situations in which feedback in the form of out-comes of actions or observations is poor, misleading, or even missing". [1] The hard parts of real-world software development are generally in the "wicked" bucket. Schoolwork and puzzle questions are both generally "kind" in the sense that there's a right answer and you're expected to figure it out. It's impossible to be too smug working on "wicked" problems because you get your ass kicked often enough to stay humble. But in "kind" domains it's quite easy to indulge one's desire to feel superior by dragging people through things you know well. Personally, when I interview people I try to set things up so that there's no right answer; the goal is to see how well they get to good answers, and how well they collaborate during that process. I'd love to see more people do that. [1] https://pdfs.semanticscholar.org/5c5d/33b858eaf38f6a14b3f042202f1f44e04326.pdf https://pdfs.semanticscholar.org/5c5d/33b858eaf38f6a14b3f042...
- deleted 7y ago[deleted]
- WalterBright 7y agoI don't think simplicity can be appreciated unless one has taken a long detour through complexity. For example, I never understood Calculus I until I took Calculus II. I never understood Calculus II until I took the next class. Etc. I am reluctant to believe someone has mastered simplicity until after they've mastered complexity, hence the complex interview does have value.
- JadeNB 7y ago> I am reluctant to believe someone has mastered simplicity until after they've mastered complexity, hence the complex interview does have value. While I buy the premise, this seems like a strange conclusion. If a mastery of simplicity requires a mastery of complexity first, then testing for an ability to be simple tests for both kinds of knowledge, whereas testing for an ability to handle complexity tests only one–so what's the point?
- AlexCoventry 7y agoYou're generally not going to be able to write the simple code until you've found the right abstractions by writing the complicated code.
- WalterBright 7y agoI spend much time staring at code thinking there's got to be a simpler way. Sometimes I find one.
- JadeNB 7y agoI think that's my point: if you write the simple code, then you've probably demonstrated both that you can write complicated code, and that you can simplify it.
- AlexCoventry 7y agoMy point was that getting people to demonstrate facility with complex code is sensible because that's a prerequisite for writing novel simple code.
- seanmcdirmid 7y agoSimplicity comes to me when tackling a hard problem after a few days as well as contemplation over multiple showers. I’m not sure how I could ever incorporate a shower into an interview loop. Interviews suck at evaluating anything that requires more than 40 minutes.
- flowerlad 7y agoAll kinds of ideas are apt to come when you are in the shower... ideas for simplification, ideas for improving performance, ideas for new features. That doesn’t mean we should incorporate a shower in the interview schedule! We can simple review the interviewee’s code prioritizing simplicity over things like did he/she consider every corner case.
- seanmcdirmid 7y agoAn interview doesn’t allow for any digestion, it is pure performance, either follow the proper practiced steps correctly, or fail. Your approach is just more of that.
- TeMPOraL 7y ago> We can simple review the interviewee’s code prioritizing simplicity over things like did he/she consider every corner case. That sounds like a recipe for disaster, though. Simplicity that doesn't account for every corner case in the domain of the code[0] is false simplicity, a bad abstraction. The challenge of writing simple code is this: threading a single, unifying concept through all corner cases. -- [0] - I.e. when writing a function, you don't necessarily have to account for e.g. the off chance of heap getting corrupted externally in the middle of execution of your code. But you'd better account for all the values your function might be called with, in all combinations.
- flowerlad 7y ago>threading a single, unifying concept through all corner cases Some corner cases influence the core algorithm some don’t. Checking for degenerate cases and so on may not influence the core algorithm, if so need not be done in an interview.
- ummonk 7y agoWhat? I guess some systems design interviews talk about performance but most interviews are algorithms / data structures and have nothing to do with writing performant code.
- greymalik 7y agoAny interview involving data structures and algorithms will certainly expect you to be able to categorize the big O of your solution in both space and time. Your interviewer will probably also challenge you to at least speculate on how you could improve on the big O if needed. What is that about if not writing performant code?
- ummonk 7y agoIf you consider “write code that doesn’t timeout or OOM on pathological inputs” to be writing performant code, sure. But as it is normally understood, writing performant code is more about writing for fast performance with low time constant on everyday small inputs - something which algorithms and data structures interviews never touch on. Big O complexity is not directly related to performance, except for pathological inputs.
- Splines 7y agoRe: performant code, the developer writes the code once, it is read many times, and it is run many many many times. Several orders of magnitude more. Yes, making code that is easy to read and less bug-prone is good. But at the end of the day the customers are going to be running your code millions of times a day, and if you need to make the code slightly harder to read to improve performance, then by all means do so. If your code is only going to be run once and must be reliable, then you can make a different trade-off.
- theshrike79 7y agoJust make sure you actually _need_ to make the code more performant, because we all know what premature optimization is the root of.
- exo762 7y agoWhat is premature and what is not? Is choosing fit for a job data structures a premature optimization? I don't think so. But I've seen people arguing against it.
- theshrike79 7y agoFirst you make it work, then you benchmark it. Then you see if that particular part is a bottleneck and whether there is a business case for optimisation. I know it's fun and exciting to optimise a function to perform at maximum efficiency, but people tend to forget that someone has to read that piece of code in the future and understand it. All the fancy tricks might've given a 2% increase in performance, but made it 200% less understandable by anyone except the codegolfing optimizer trying to be clever. =)
- TeMPOraL 7y agoTL;DR: Spectrum of performance: LO |---*-------*--------*------------*-------| HI ^ ^ ^ ^ | | | |_root of all evil if premature | | |_you should be here | |_you can be here if you don't do stupid things |_you are here -- > All the fancy tricks might've given a 2% increase in performance, but made it 200% less understandable by anyone except the codegolfing optimizer trying to be clever. This applies to hairy, last-ditch effort optimizations. The kind of your average programmer isn't even capable of doing. It's nothing like the optimizations most real-world code needs. It's why I consider the "premature optimization" adage to be actively harmful, as it legitimizes lack of care and good craftsmanship. From what I've seen, a lot of code can be trivially optimized with no net loss to readability (and sometimes a gain!), by simply removing dumb things, mostly around data structures. Fixes involve using vectors instead of lists or hash tables, depending on size and access and add/delete patterns. Using reference equality checks instead of string comparisons. Not recalculating the same value all over again inside a loop. The kind of things above are ones that bleed performance all over your application, for no good reasons. I consider it a difference between a newbie and a decent programmer - whether or not they internalized how to code without stupid performance mistakes, so that the code they write is by default both readable and reasonably performant. Then you go to actual optimizations, the kind that benefit from a benchmark - not because doing them elsewhere is wrong in principle, but because they take time and noticeably alter code structure. Using better algorithm, and/or using a better data structure, both come here. They don't have to impact readability, as long as you isolate them from the rest of the system behind a simple interface. (Like, e.g. one day I achieved 100x boost of performance of an application component by replacing a school-level Dijkstra implementation with a two-step A* -based algorithm and data structure specifically designed for the problem being solved, and easily managed to wrap it in an even simpler interface than original. Since the component was user-facing, it pretty much single-handedly changed the perception of application from sluggish to snappy. The speedup itself probably saved many people-hours for users who were a captive audience anyway (this was an internal tool).) Only then you get to the "premature optimization is a root of all evil" part, which is hairy tricks and extreme levels of micromanagement. Making sure you don't cons anything, or more than absolutely necessary. Counting cycles, exploiting cache-friendly data layouts, etc. This can have such a big impact on a system and surrounding code that it does really benefit from not being done until absolutely needed (except if you know you'll need it from the start - e.g. in some video games).
- paulddraper 7y agoBecause you only have time to write a little code for a little problem. You can't spend two hours just setting up the tasks to be performed.