Early in my career, I interviewed at Google. One of the interviewer asked me to recite the algorithm for constructing a Convex Hull. Since I hadn't done anything related to convex hulls since my algorithms class as a sophomore in college (several years earlier), I couldn't remember all the details. At some point, I said, I know where in CLRS (https://www.amazon.com/Introduction-Algorithms-3rd-MIT-Press...) this is. The interviewer didn't like this, so he said "Pretend you're an engineer at Google. You need to have a convex hull. What do you do?" And I said probably the most correct thing I've said in any interview: "I would go look it up." He really didn't like this answer, but we struggled together for an hour, with him frustrated that I couldn't remember the details of an algorithm I last had seen 6 years earlier and couldn't recite in 60 minutes what took our professor 180 minutes of lectures to cover, and me frustrated that would have taken me 30 seconds to look up.
I did not get the job at Google.
I do make sure as a more senior engineer at my current company I use what leverage I have to make sure other interviewers don't ask pointless questions like this.
Yea I interview (and have sat on HC) at Google, and interviewers who ask these types of questions really frustrate me.
If your question requires having previously memorized or being able to come up with some tricky algorithm on the fly in 45 minutes and code a solution using it, your question is probably bad.
I get why they ask them - they're easy to ask, they're easy to score, and when your question inevitably gets burned because someone posted it all over the internet in their blog post titled "How I got a job at Google!!" and then bumped way up the list on hackerrankcode-whatever I forget the websites... it's easier to come up with a new one, because you just pick a new esoteric algorithm and ask that.
And honestly, coming up with interview questions can take awhile. When you have 5 or 6 very calibrated questions and all of them get burned and banned in a one quarter span, you now have to spend the better part of a whole workweek, plus dozens of more interviews coming up with new questions and recalibrating.
But, I just refuse to ask those types of questions anymore. They really don't give useful signal. The only three bits of signal you get are "does the candidate already know this algorithm (or are they a supergenius who just figured it out under time pressure)? can they communicate it to another engineer? can they write code?"
Importantly if the answer to the first question is no, then you get zero signal on the other two parts. That basically means as an interviewer you just failed your job.
I think they may also ask them because they want to see how you do at the specific task of taking a problem you remember the pseudocode algorithm for, and actually turning that into working code in a real programming language. You know, the "schlep" part of programming.
I feel like they don't realize that this is the goal they're calibrating these questions toward, though. If they did, they wouldn't require the "from memory" component—instead, they'd break the question into two parts:
1. tell me what algorithm you would use to solve this problem; or, failing that, tell me what criteria you'd use to select the best algorithm for solving this problem out of a set of candidate algorithms.
2. Here's a journal paper, explaining a particular data structure + set of algorithms that can† be used to solve the problem we're talking about. All the algorithms in the journal paper are in that sort of declarative, math-proof-phrased pseudo-pseudo-code form. Now take this journal paper and turn it into an implementation in your language of choice. Explain your thinking as you go.
† The paper chosen is not the one corresponding to the algorithm the candidate chose; nor is it the one corresponding to the algorithm that's "right" to pick for solving the problem. It is, in fact, randomly-chosen from the pool of sub-optimal solutions to the problem, filtered for the ones that get rarely used in practice and so have no easy non-journal-paper presentations of a reference impl laying about on the web to study. Alternately—if the interviewer has enough time to explain a second problem—it could even be a paper randomly-chosen from the pool of all algorithms papers!
Benefits:
• Both task 1 and task 2 are things "senior" engineers do every day in the real world.
• There's no component of memorization; the step "between" step 1 and step 2, where you'd look up the journal paper corresponding to the algorithm you thought of, is dropped.
Yup if you are willing to explain the algorithm to the candidate and not dock them any "points" (or whatever) for having to explain the algorithm, then this works fine. I have no qualms about having a discussion about an algorithm that's tricky, and seeing how the candidate works through it.
That's not what I see in practice though. Not remembering the whole algorithm at best ends up wasting half of the interview (code the remainder in 20 minutes??), and at worst gets explicit language from the interviewer like "TC couldn't figure out <insert tricky algorithm> and I had to explain the algorithm to them explicitly, WEAK/BORDERLINE on algorithms".
I should also say, I dislike doing any engineer interviews that are purely talk-about-algorithm without any code, because I've interviewed a disturbingly large number of candidates who cannot write about 10 lines of mostly-bug-free code with a single state variable and like one loop, in 30+ minutes.
> That's not what I see in practice though. Not remembering the whole algorithm at best ends up wasting half of the interview (code the remainder in 20 minutes??), and at worst gets explicit language from the interviewer like "TC couldn't figure out <insert tricky algorithm> and I had to explain the algorithm to them explicitly, WEAK/BORDERLINE on algorithms".
It is kind of hilarious to get an algorithm problem which took eminent computer scientists years to solve the first time. "Why yes, I am Donald Knuth/Edsger Dijkstra/et al. – only smarter, luckier, and much faster!"
As you note, the initial question is basically "how well do you recall the solution to this problem?"
What on earth is wrong with asking to see the interviewee's code? Skim over it looking for neatness, how they comment, what build procedure is there and quiz them about what you see: anything from language choice, to build reproducibility, from architecture to install. And of course quiz them on algos you see.
All of these 'tricky' exam style questions don't show a thing about the person sitting in the interview room.
I've hired based on a good discussion alone, without code... And got a great engineer.
In addition to the sibling's excellent "candidates who work at companies that don't let them show you their current code, and have a home life that occupies their time outside of work", here's another category of candidates you lose: people who code differently in their downtime than they do at work.
If you looked over my github, you would see most of my commits are ones that, at work, I wouldn't accept from anyone. The code is sloppy, there are no tests, it looks like someone was just trying to get something working as quickly as possible with no thought for maintainability or understandability. But, of course, that's exactly what I was doing! When I code in my spare time, I'm solving problems that I've run into in my spare time, and I approach it very differently from in my work life. The constraints are different, and so the solutions are different.
You lose out on candidates who work at companies that don't let them show you their current code, and have a home life that occupies their time outside of work.
So, you can ask to see candidate's existing code if you work at a small enough shop and/or don't care about missing out on candidates who don't have shareable code. But if you are trying to hire at a larger scale, it does not work.
Many great hiring schemes work until a certain scale and then they fall apart. Some hiring schemes also severely tilt your candidate pool towards a certain subset of the population. I'm sure whiteboard style interviewing also has similar issues.
My favorite question to ask in software engineering interviews is one that I believe to be un-burnable.
> It's 2140 AD, New York is under water up to X feet high. Buildings have been retrofitted with <magical-ish material> to withstand the water. You are in charge of keeping your building dry. If water gets in and damages the foundation, a few thousand people die or become homeless.
> Design a system that ensures that doesn't happen.
How candidates approach this, how they think about redundancy, how they deal with additional constraints or extra scenarios thrown at them tells a lot about how they approach things. The question is not about software (explicitly) on purpose so that it gets people out of the coding mindset.
With more software-focused systems you always get candidates who starts writing code and designing objects and classes and stuff. No, I want you to design a system. Stop writing code.
The reason this question is unburnable is that there's no right answer. You're being asked to show how you work through an abstract problem and design a solution. You aren't being asked for an answer.
So far everyone who did well on that question has turned out to be a great engineer. Whether they were fresh out of college (and learned a lot fast) or they were already experienced.
This is a terrible question. Problem solving ability doesn't exist in a vacuum. Our experiences give us resources to draw from to combine in new ways that allow us to solve novel problems. Asking a software engineer to solve a problem in a dissimilar domain is badly missing the point of screening software engineers.
Sure, you may say that everyone who does well turns out to be a great engineer. I'm sure Google says the same thing about their algorithm trivia tests. Presumably the goal is to move away from these seemingly arbitrary and irrelevant tests. Just replacing one arbitrary and irrelevant test with another isn't improving the state of things.
I disagree. The goal of this question is to see how you utilize domain experts as a resource, add your software expertise, and design a comprehensive solution. It is specifically not a question about what you already know.
In the interview I play the domain expert.
This is exactly what your job will look like: collaborate with domain experts, use your software skills, solve real world problems.
I don’t need an engineer who can build a queue. I need an engineer who can use a queue.
Properly testing for a "solution engineer" (which is what you appear to be testing for) would pose a question that is a legitimate "software" problem and "domain experts" would be in areas such as say "electronic payments". Candidate would be expected to demonstrate ability to devise proposals for a 'functional solution to a business requirement' using available domain experts.
The key phrase is yours: "real world problems". Your hypothetical misses that by a generous mile.
And I apologize about this but we're discussing actual issues with software recruitment:
One major problem noted by senior engineers subject to these interviews is the competence level of the interviewer. I had this one guy, a "principal engineer", ask me about "Optimistic locks" as his initial query into my knowledge of concurrent systems. It took a lot of self-restraint to not blurt out "You mean optimistic locking?"
It is amazing to me that we somehow managed to hire very good software workers in the 90s without any of these shenanigans. One thing that does stand out from my memory of the 90s: we had senior colleagues (with literal white hair) in senior engineering positions. Go figure.
Seems reminiscent of the tales of early 2000s Google interviews, of the "estimate how many golf balls fit in an airplane" variety.
I'm not convinced this offers a useful selection criteria other than boosting your unconscious bias on who "seems smart", but on the other hand I'm also not convinced it's any worse than the standard modern Leetcode interview.
I don't think they were looking for the right answer; I think the goal of that type of questions is to see how does the candidate approaches it. It's especially valuable with college hires.
Some candidates will simply freeze if they don't know the answer. Some will try to estimate the dimensions and come up with an estimate. I think Google wanted to try to anticipate what a person would do when stuck by asking these types of questions.
Funnily that old style of question is far closer to my day-to-day as an engineer than a leetcode algorithms question. Most of my job involves figuring out solutions to fuzzy problems based on unknown constraints, undiscovered requirements, and often unclear end-goals.
"How would you fill this airplane with golf balls?" is a fantastic question. If the candidate doesn't reply with "Why? What are you really trying to achieve?", they're gonna do poorly in modern software development.
Caveat: This does not apply to junior positions where you are expected to bang out code based on super fleshed out requirements and constraints.
Why? Isn't the better question "how would you solve <the actual thing they are being hired to solve>"?
I hire people to track objects via computer vision. I ask them "hey, here's a system I want, what approaches would you take", and explain that this is a 3 year research project, of course they will be giving simplistic and wrong answers and there is knowledge asymmetry here, but I'll inform you as you go as to what works and not. "Optical flow". Okay, why? What's the general algorithm? Okay, so it turns out it doesn't work in our situation because X,Y,Z. Any ideas on what you'd look at next. And so on. Because that is exactly how my day-to-day conversations and work goes. Bounce ideas off of co-workers, latch onto something that seems promising, explore, maybe it works, maybe it fails. If it fails, what does that tell you about what to try next. Along the way you can have them code a tiny piece of something they mentioned if you want to see some code. But basically you are seeing if they understand the domain you are working in (which is not golf balls on airplanes), if they have some (not comprehensive) knowledge of the domain, and if they understand book solutions don't necessarily deal with the messiness of the real world and can adapt approaches to appropriately (i.e. a 20sec/frame algorithm is not going to cut it when I need 180fps).
It bothers me that this is still somewhat unfair due to the vast information asymmetry, but I try to deal with that. And my own biases can creep in. Are they mostly using 1980s style image processing techniques? Do they understand Bayes? Do they throw ML at problems that aren't tractable that way? It's unlikely that their past experience & preferences reflect exactly what we need. What is important - can they adapt, or even better, communicate why my choices are wrong and theirs are right (I don't need a robot to grind out code reflecting my ideas, I need them to figure things out and solve things in a fairly scientific manner).
So those are the questions I try to ask. I have no evidence that I get it right, but I haven't been disappointed with the hires.
Interesting you mention 80’s style image processing techniques. Please take care with these kinds of biases. Often older techniques are superior than ones that are merely fashionable today. I’ve also been around long enough to see pendulums go back and forth at least once in the AI realm, never mind tech in general.
Mind you, I’m not saying you’re wrong to discount people who fail to stay abreast in their field, just know that sometimes there is wisdom in ignoring popular trends, or revisiting old techniques that might benefit from a different landscape.
I think your approach is pretty optimal, but at larger companies the candidates might be interviewing for the company as a whole and not for a specific team.
I suppose it depends on how you grade the answers. Like I have bad spatial awareness in terms of how big things like planes are. I genuinely don't really have an idea how long a commercial airliner is, or how big a ping pong ball is. I feel like I'd do ok if I could get reasonable approximate values for things like the size of the plane, the balls, the seats, etc. if I also have to supply those values myself the end result is likely to be off
The end result being off is fine if I am being graded based on my thought process, but a disaster if I am being graded at having an idea of the size of airplanes before walking into the interview.
Like I said, the point of this question isn’t to seek your domain expertise, the point is to see how you use other people’s domain expertise to create a [software] system.
The way you ask it sure. I'm just not sure that is how everyone asks it, though maybe it is. I've never been asked something quite like that before but some comments I've seen around seem to imply some people want a close to accurate answer.
Me: "I'm a software developer, so I would let a material science engineer figure it out."
You: "You can't do that... All the material science engineers have drowned."
Me: "That's not very realistic..."
You: "Thank you for your time. Don't call us, we'll call you."
"Ok the material science engineer gave you the fancy material. It was applied. As you know, nothing is perfect and lasts forever. How do you ensure your building doesn't sink?"
I'd let the material science engineer figure that one out too. No way in hell would I risk my ignorance of building maintenance be the cause of thousands of deaths.
One thing I learned in getting my engineering degree is that it’s unethical to practice engineering in an area you don’t understand. No way would I ever try to apply my software engineering skills to a materials problem
I feel it's only unethetical if there are "real" stakes on the line. E.g. Where people can get hurt. I don't mind a mechanical engineer writing code for a company that makes the zillionth vapid webapp nor do I mind a software engineer designing a mechanical watch.
Use <magic material> to build a wall around the city? Have the people who maintained each individual building form a team that can keep an eye on sections in shifts? If we have enough magic material, build a double wall system for breaches?
> Use <magic material> to build a wall around the city?
That sounds expensive. Do we need to do that? Does it solve the problem better? Does it maybe create a worse solution? How would you find out?
> Have the people who maintained each individual building form a team that can keep an eye on sections in shifts?
How would you make this less time intensive? Can you use automation?
> If we have enough magic material, build a double wall system for breaches?
Is there a cost-benefit analysis you can run here? How would you find out? Should we keep adding walls ad infinitum or does each additional wall have diminishing returns?
It would be probably cheeper - simply because the perimeter would be shorter than the sum of perimeters for most of buildings included in the city/district. That is what cities did since at least Neolithic til moment when cities become undefendable (because of cannons and airstrike).
But that is probably not the point. In order to build wall around the city, you need to have power or consensus in society to deliver this decision. And achieve that in reasonable time might be unreal for someone in charge of one building.
I can't tell if you're asking these questions to elicit a longer discussion, or if you are doing so because you don't like the idea of a simple solution.
It’s unfortunate that this bizarre and arbitrary stab at analytical thinking assessment is still used to evaluate the skill of software developers.
Here’s another idea: have them write software. Not algorithm trivia, but actual software. Keep the scope small so there isn’t an onerous time commitment and have them explain their choices.
I would love to ask questions like that. I'm pretty sure hiring committee would not like it though lol.
I do worry about asking questions that give candidates extremely large advantages if they have certain backgrounds. For example someone coming from mech, civ, or petroleum engineering will get a huge leg up on that question.
It is also worth noting that the structure for interviewing at a company with 30-50k+ engineers is different than the structure you need for interviewing at a company with <<1k engineers.
IMHO, this is not particular better than an algorithm question.
Why not just summarizes the traits of the technical skills you expect from the candidate, lay it out, and come up appropriate questions for each interview?
General software engineering interview does not work. But there can be more specific measures to improve the experience.
> Why not just summarizes the traits of the technical skills you expect from the candidate, lay it out, and come up appropriate questions for each interview?
That won't work; it's aimed at a different kind of skill.
The skill the GP is looking for is ability to solve a problem you have never seen before, for a problem that bears little resemblance to anything you've done before, by transferring your existing general problem solving skills. It's a test of your ability to solve new things, which is a capability the company finds useful.
This is a very useful skill, and you can learn to do it better, but it's not a "technical" skill as we usually mean it. However it is one of the things which might be associated with "great engineer".
Listing technical skills and testing them will not tell you if the candidate has developed the above capability.
The GP isn't asking a very good question to identify that skill, is the point. Interviews in other technical industries don't ask these kinds of questions, because they're not really useful as a gauge of, well, anything useful.
> It's a test of your ability to solve new things, which is a capability the company finds useful.
Correct.
I work with early-ish stage startups. There's always a library that solves any given known problem. We don't have the scale or nuance to need to reinvent the wheel.
Where I really need engineers to shine is in solving the parts that don't have a library because we've stumbled onto something new. Or at least something new to the team. Or the way we've cobbled libraries together creates something new.
The important work is the work you haven't done before. We're engineers not line cooks.
November should involve completely different work and a whole new set of problems than February. If you're still doing the same thing you did in February, something's gone wrong.
I had a very similar experience interviewing for Google. I was asked to do a task that eventually boiled down to a topological sort, and I thought the question consisted of recognizing that the answer was a topological sort and moving on because it was over the phone.
However, that was not the case. The interviewer wanted me to code it all out over Google Docs, but I didn't remember the exact algorithm so I basically had to re-figure it out on the fly, which took most of the interview (I even similarly mention "in any real situation I would just look this up", but that didn't help). At the end, I had a bunch of pseudo-C++-code that should do it correctly.
I thought I was done, then the interviewer said she would go go copy my code and compile it after the interview to see if I was right, which blew my mind. It was never mentioned previously that the code would actually be compiled and run, and with no syntax highlighting or ability to compile and test the code myself there is zero chance it was ever going to work.
I never heard back, so I'm assuming my code failed and they left it at that. Anyway, I'm much happier now that I think I would have been at Google.
Man, one time I had an interview at a startup. They asked me some fairly trivial questions and I wrote some pseudocode which they were fine with. Then in the last 5 minutes they were like, "well, let's get this ready to run in a browser." I was shocked and stuttered out something like "wait, this was pseudocode, I'm definitely not going to be able to make this run in the last 5 minutes," and they said something like "oh, OK" and wrapped up.
That was the entire phone screen, and they failed me. This still burns me years later because it was such an obvious communication failure on their part - if you're one of the rare interviews that actually require me to write working code, you better be darn sure to mention that upfront, rather than 5 minutes before the end of the hour! - and yet I was the one who failed.
A passage from one of Jon Bentley's Programming Pearls:
As soon as we settled on the problem to be solved, I ran to my nearest copy of Knuth's _Seminumerical Algorithms_ (having copies of Knuth's three volumes both at home and at work has been well worth the investment). Because I had studied the book carefully a decade earlier, I vaguely recalled that it contained several algorithms for problems like this. After spending a few minutes considering several possible designs that we'll study shortly, I realized that Algorithm S in Knuth's Section 3.4.2 was the ideal solution to my problem.
If Bentley needed to go look up an algorithm that he vaguely recalled studying in the past, just how awful of programmers are the rest of us that look things up, really?
"Never memorize what you can look up in books" is often attributed to Albert Einstein; the long version is "[I do not] carry such information in my mind since it is readily available in books. ...The value of a college education is not the learning of many facts but the training of the mind to think."
The entire concept of asking someone to write code in Google Docs is just insane to me. No one would ever do that on a job, because it's remarkably awful and difficult, and the editor will fight against you every step of the way (auto-capitalization, just to name one thing).
And yet somehow interviewers think that this will give them a good picture of how you'd do work on the job. Baffling.
They're doing it so that they can see your edits live, "prooving" that you're not cheating in some way.
But yes, this is asinine. Sharing your desktop through a video conferencing program and using the IDE of your choice would be far more realistic test, but Google likes to put hoops up to jump through that are smaller than your body.
Why can't you contort yourself like an octopus!? Fail!
Nah, it's because this is the process for phone, not video, interviews, which are somewhat more accessible. And you need the ability to record the code at the end anyway (which docs provides and a video doesn't).
Yep, it was a struggle even when I thought I was supposed to be writing pseudocode. I've had some really great interviews using coderpad and similar software (including the company I'm at now), and it's such a better representation of how the interviewee actually codes.
I don't get how my interviewer (an engineer), didn't see the problem with it. I know that Google wants to use their own products, but that can't possibly be the norm for other Google interviews.
Yeah, Google's interviews are whack. I've been rejected twice -- I think because of flubbing an algorithm question -- and after that I designed a new algorithm for my work that's getting published in OSDI this year, I think.
I had the opposite experience in a Google interview.
I just said, that can be solved with a topological sort, and then we moved on.
But I failed with another interviewer. He kept asking how to prevent hashing from producing collisions. The answer was universal hashing, but I had forgotten about that
Typical. Universal Hashing as a concept is only interesting to cryptographers, and people who are completely obsessed with obscure hashmap trivia (i.E. FAANG interviewers).
I made the mistake of answering Google recruiter without a CS degree and "only" an EE/CompE and 10 years Software experience. Junior interviewer would not proceed past some algorithm question regarding boxes of pennies by weight, as he wanted a specific algorithm to be used in my solution, which I clearly didn't know. Recruiter then ghosted me, so F off Google for wasting my limited time like this.
Your story reminds me of when I interviewed at Google and did great on four interviews but the fifth one sunk me. I was asked an inheritance question which didn't make much sense (coming from a heavy Perl and Ruby background) but probably would have made more sense if I were a heavy C++ developer. I explained how the question wasn't really an issue in Ruby but the interviewer didn't like that and angrily said "you should have learned this in your compilers class at Georgia Tech!"
I'm glad that the interviewer read my resume closely to learn my alma mater, but not closely enough to realize I had a biology degree from it.
I tried again a year later and got luckier with my allocation of interviewers. I never did end up using any algorithms there.
For a company whose main claim-to-fame is indexing the web (rather than mirroring it in their databases), Google sure doesn't seem to understand that CS learning is done by mentally indexing textbooks (rather than mirroring them in your brain.)
If I had any wit, I would have responded to the convex hull question: "I would look this up on the Internet, assuming there is a search engine good enough to find the algorithm."
That may be true. But then why hire someone with just look-up skills before hiring someone who really tries, and enjoys the challenge?
I'm interviewing engineers frequently and although I agree that the question asked by GP is maybe not the best it still gives the signal if someone is willing to power through a problem with minimal guidance and/or ambiguous constraints. Something I'm willing to find out at the peril of pissing off a few candidates.
I work with novel algorithms all day (I'm writing a decompiler.) The more I learn, the more I have confidence in the fact that I have absolutely no hope of inventing an algorithm that doesn't already exist; and that I shouldn't waste my time trying, when instead I could be spending that time digging through the nigh-infinite vault of potential solutions to my problem known as "the output of CS academia."
Software engineers aren't mathematicians. We don't invent algorithms or data-structures. That's not our trade-skill. And even actual mathematicians don't sit down to solve a real-world problem that no maths they're aware of directly solve—and then produce novel maths, and then use them to solve the problem—the very same year, let alone the same hour.
What I can do, as a software engineer, is to take algorithms that exist, and repurpose them or glue them together in novel ways that the designers of those algorithms never thought of, to do something new. Bitcoin, for one example, is a feat of pure software-engineering: it takes four or five existing well-known algorithms, and puts them together in a novel combination to solve a problem. I could maybe invent Bitcoin. But I can't invent Floyd-Warshall, if I don't know about it.
Google doesn't employ computer scientists (i.e. mathematicians who invent algorithms.) Alphabet does, under DeepMind and Waymo; but Google itself only employs—and only needs—software engineers.
Asking a software engineer, under pressure, to derive a novel algorithm, is a bit like asking a chemist, under pressure, to derive a novel class of chemical reaction; or a materials scientist, under pressure, to derive a novel material.
That's not the type of pressure that a real-world person in these jobs will ever be under. And moreover, it's precisely the type of pressure that people with experience in these positions have learned to mentally associate with "going in the wrong direction, toward wasted effort", flinch away from, and to turn around and study the literature instead.
It's ironic that Google expects its employees to all have university degrees. If there's one skill people who've gone to university are guaranteed to know (and to have built up a reliance on), it's consulting the literature.
I think the point is that no one is being asked to derive a novel algorithm. It’s taken for granted that a person with enough experience will have an understanding of broad categories of algorithms and should be able to reason about the small changes to those algorithms that would be necessary for practical application.
I don’t think the point is being able to use a specific language or to know a specific algorithm, unless the role requires it. If the goal is to test a person’s knowledge and understanding, then the actual implementation is probably less important than their ability to explain and reason about the problem. OTOH, if the goal is to find out whether the person is highly skilled in a specific language and has a lot of experience with an algorithmic domain, then what you’re asking isn’t unreasonable.
I think if it this way (very simplified): there are candidates that like challenges and who don't mind imperfect interviewing situations, and i had my fair share of people who dislike it would fare better if we just let them work on a real world problem. We did both for each candidate for some time, but the latter was much more costly and didn't provide such a good signal in the end.
Open-mindedness goes a long way. Also typically our interview questions are set up in a way where it's expected you won't finish but try, which reveals a lot about personality and how problems are attacked.
> why hire someone with just look-up skills before hiring someone who really tries, and enjoys the challenge
This attitude will keep you from hiring someone who will just "do the right thing," which is to look up stuff that can be looked up, and also persevere when an off-the-shelf solution won't be sufficient. Plenty of engineers will spend time trying to reinvent the wheel when it is totally unncesssary.
At some point we had a brilliant junior dev who had a task to add some logic to some ES plugins in Java. When the code review went up, it was all a single Java 8 stream statement. He went out of his way to convert everything to a stream because he enjoyed the challenge I guess. It was 3 pages of nested declarations and inscrutable.
He left eventually but person was hard to work with because you had to beat back this kind of shenanigans every step of the way.
I don't really see a hard distinction between meat memory and silicone memory, so I've never bothered to memorize stuff that I could simply lookup. To me, it seems almost ridiculously inefficient to carry around large amounts of indepth data in your brain, which is limited, costs constant energy to maintain, and isn't even particularly good when it comes to fidelity of recollection and searchability.
It's much more efficient to remember the general shape of problems, to remember where you can find further information (books, chapters, etc). Remembering that something is a well-studied problem, and where to find a solution, is straight-up more efficient than remembering that solution.
Dijkstra once remarked that trying to make a computer act like a human brain was far less interesting than seeing what the limits are of a computer as something that is unlike a human brain. It seems the reverse observation is also true - human brains, once freed from rote memorization and computation (that's literally what programming does to us), can tackle much larger, more interesting, and more complex problems.
Another anecdote of an incompetent interviewer blindly looking for a certain answer:
I once had an interview where, for a pretty long question, one trivial step was to check that one set was a subset of another set. Neither set had any special preconditions, just two plain unordered Java HashSets. Not thinking twice about it, I wrote a simple for loop that checked if every element in the smaller set was present in the bigger set.
When I finished the question, the interviewer started questioning me about the runtime of the for loop. He started hinting that it could be more efficient, which confused me, since it seemed impossible to check every element of a set in faster than O(n) time. I also didn't see how it was useful to think so carefully about the runtime of such a trivial thing, seeing as the "story" of the problem indicated that the sets would never be particularly large and the task wasn't one that would be sensitive to a couple microseconds difference in runtime.
We spent about 20 minutes stuck on this, with me awkwardly repeating I didn't see how it was possible to be faster and him telling me to just think harder and look at the problem "mathematically", "forget about the code, just think, in math, if you have a set A and a set B, how do you efficiently find if one is a subset of the other?". Eventually we ran out of time for the interview. As we wrapped up, he revealed to me the elusive answer: "Since you're checking if it's a subset, you should use the built-in isSubset() method that Java sets have". Of course, he hadn't conveyed to me at all that he was looking for a specific built-in method, so I thought there was some secret algorithm that I would have to write to make it go faster. I didn't mention that though, and instead replied that even if it were a built-in method I didn't see how it could be faster than O(n) in its implementation. He didn't have response, and just stammered something like "well it's built in and it's actually the most efficient way" and the interview ended awkwardly. Anyways, I had my doubts, so when I got home I checked.
There is no isSubset() in Java sets.
There is a containsAll(). It's implemented as a while loop that runs in O(n) time, making it no more efficient than writing your own loop.
Three years ago I interviewed in house (after several hours of phone screens) at an SF tech company that has since gone public. The position was for a senior software engineer doing mostly backend Rails stuff.
The biggest portion of the in-house interview was some fairly simple algorithm puzzle involving solving some word game given some rules and a list of valid English words. That section of the interview ended with me explaining how hash table lookups are constant time and the interviewer insisting that they are linear time.
To be clear, there was no “gotcha” about collision resolution or anything subtle like that. My claim just came up as an obvious step in my explanation of the running time of my proposed solution and the interviewer jumped on it.
I thought I was quite cordial, but I didn’t back down, and the interviewer seemed quite aggressive. The other interviewer in the room at the time seemed very uncomfortable with the fact that I would question something so basic, but didn’t intervene or express any “opinion” on the “debate.”
I interviewed at Google quite a few years ago and had a similar experience but over multiple interviews. I had 5 interviews slowly getting harder and harder questions. By the fifth interview I got past the first question pretty fast so he moved onto a second harder one that my answer did not seem to impress. After all these interviews they just never called me back again. The whole process was senseless.
It was as if they wanted to find the point at which I would fail so they could stop. I'll probably hate Google forever after that. I am sure they have great people but I am always very interested when I meet someone who works there so I can ask them about what they do and they always seemed kinda average good not amazing.
My experience at Google was that the secret sauce wasn't that it was full of geniuses. It's that everyone was _reliably_ competent and very smart. It's hard to overstate how valuable that certainty is, and how impressive it is to manage that at scale. It enables an entirely new world of employer-employee relationships, including their famous transparency and policies that could (and would) be abused by people too dumb to understand coordination problems. The cost of this is of course going to be plenty of false negatives. (Bear in mind they were a fifth of their current size when I was there, so I don't know how much this applies anymore)
I'll play devil's advocate and say I don't dislike coding interviews. Most of the time they are done completely wrong however.
They are extremely useful to filter out candidates that simply cannot program, and who won't be able to no matter how much mentoring time you 'invest' in them. I've heard about interviews for senior engineers that were totally derailed by a simple FizzBuzz. I like wordcount (the wc *nix command) as a warmup/screening question simply because either: The candidate comes up with an algorithm for it and test cases OR starts counting whitespace and derails the implementation with a cascade of if-else for every new test cases that breaks the previous implementation (I've seen if-else to check for the n cases I suggested...).
But honestly I feel there is so much cargo-culting for coding interview. Especially if you ask for compliable code of well known (as described by a textbook) algorithms you ultimately assess rote memorizations skills and not engineering.
Convex Hull doesn't sound so bad to be honest. If I was using this question I would expect someone to be able to come up with the gift wrapping algorithm with maybe a little bit of help. What, as an interviewer, would really want to see is if the candidate can come up with test cases and a way to test whether his solution is actually a convex hull and then try to break down the problem and come up with an algorithm. I sure wouldn't expect to be able to type what's on the board and for it to compile right away (it's a board, not an IDE!) but I expect the candidate to be able to walk me through the code and run it line by line through some test cases.
I don't dislike coding interviews either. But if I were asked about a Convex Hull, my response would have to be, "What is a convex hull?" otherwise I'd have to guess. I have a computer science degree, did I miss something? Is that common knowledge? Right now I have the power to look it up, but it's a little strange to me that I could be asked about that in an interview and my pass/fail would potentially depend on it (granted when I am the interviewer, my pass/fail rarely depends on the response to the coding questions).
So the next question is, will interviewers explain the problem if you're unfamiliar and not "fail" you if you can explain how you'd approach a solution?
That was a terrible interview experience. Of course anyone would look it up. I used to work at google and interviewed people as part of my job as a regular software engineer. I occasionally heard about these kinds of stories. Google didn't give much feedback to individual interviewers, no one told them if they were terrible or great questions or whatever. I also saw better interviews.
Well, I probably used it last time 10 years ago and still remember it.
All you need to remember is that you sort points by angle from a fixed point on the convex hull, and you can easily work out the rest of the algorithm as well as the proof of correctness.
Not knowing it is a relevant signal that you did not seriously attempt to compete in computer science competitions during high school and college and did not otherwise have a burning desire to learn algorithms and data structures nor a specific interest in computational geometry. Whether it's in Google's interest to select for that of course is debatable.
> Whether it's in Google's interest to select for that of course is debatable.
I'd argue it does not. Computational geometry is a niche. It's not even a niche that's particularly relevant to most of Google's development operations.
In modern software development, knowing the detail of specific algorithms off the top of your head and being able to implement them unaided is, at best, a parlor trick. I doubt very much that it even correlates to one's effectiveness as a developer. Even for development tasks which involve algorithmic work -- which many don't! -- knowing that various algorithms exist, and what they're used for, is much more valuable than having memorized the details of how those algorithms are implemented.
The idea is that you might need to invent a new algorithm where a technique from an existing algorithm is used in a modified way or in a new setting, and then knowing the actual technique can be essential to find an inspiration.
E.g. if you know that convex hulls can be computed by sorting by angle and sweeping, then you might come up with the idea of sorting by angle and sweeping in problems that are unrelated to convex hulls (e.g. determining what is visible from a given point in an environment with obstacles).
In general, if you know a lot of those techniques and heuristics, you will be much more effective at problem solving in domains where these techniques apply.
It is relatively rare for this to be a big factor in routine software development, so that's probably something one should filter for only if interviewing for roles where you might need to design novel algorithms (which Google probably has more than the average company).
One day I will understand why seemingly half of all CS papers seem to be concerned with convex hulls and Voronoi decomposition. What is so fascinating about these two topics as to warrant hundreds, if not thousands of papers? I've never heard of anyone using them anywhere ever for any purpose in industry, yet these topics are a focus of concentrated intellectual study as if they were the cure for cancer.
An entire industry – geospatial – and a variety of related industries depend on high-performance CH, Voronoi, and line simplification algorithms, among others. Not to mention their importance in medical imaging applications, tomography (so, in a sense, they directly contribute to healthcare improvements). This should be self-evident, but I can provide further direct evidence if need be; I’ve implemented QuickHull, Visvalingam-Whyatt etc from the papers, and the resulting libraries see enthusiastic use in a variety of sometimes surprising fields. They get lots of attention because the problem domain is well-understood and often resistant to low-hanging optimisation efforts (computational geometry algorithms tend to be difficult to optimise)
“I would probably look it up” is the correct answer unless you’re interviewing for a very specialized role. I had a similar experience interviewing at google (and I regret not walking out), and a much more pronounced experience at MS (where I did walk out and don’t regret it).
> with him frustrated that I couldn't remember the details of an algorithm I last had seen 6 years earlier and couldn't recite in 60 minutes what took our professor 180 minutes of lectures to cover, and me frustrated that would have taken me 30 seconds to look up.
Sounds like a very effective way to filter out people who haven't taken algorithms courses recently and/or don't spend hours every week on algorithm puzzle contests or solving algorithm puzzles for "fun." They could probably save a lot of time by asking your graduation year and looking at your hackerrank score.
Exactly my experience twice over phone interviews with them, after the second one I actually got some kind of survey question, my answer was not to ever bother me again with stupid emails how great my CV looks like, that I would be the right person that they are looking for and then waste a couple of hours of my life with such exercises.
And for what? Anyone that works with Android only has to wonder where do those algorithm magicians land at Google.
I work at Google and have performed plenty of interviews over the years. We're specifically trained not to do this. We have "feedback feedback" in our interview systems specifically for this type of situation.
Your surprise comes from the fact that you're modeling an institution as a single person when it in reality consists of a hundred thousand people. It's obviously less mental effort to reason about large entities this way, but it's obviously much less accurate.
That's funny because institutions can only be modeled as a statistical average of all of the humans who contribute to a given property of the institution.
Untrue (there's plenty of emergent behavior in large organizations), and ignoring that, irrelevant. An obvious trivial example is looking at the property of consistency in actions: an organization consisting of a hundred thousand people is going to be far less consistent in many sequences of actions than any given person would be.
Not to troll, but have you considered that you perhaps were not qualified for the job? There are people that can recite details of convex hull construction algorithms.
I had several similar experiences through and after college. One in particular was while I was still in school, they had asked a question relative to performance when using views in an SQL database, and my answer wasn't satisfactory to them. Despite the interview going well up until that point, you could feel the tone shift immediately after, like they were just asking the rest of their questions as a formality and wanted me out of there as quick as possible. Didn't get called for a follow up, of course. Found out later that place was actually preying on foreign-based students (who received funding from the university to cover their out-of-state tuition difference if they worked up to 20 hours / week max for a company associated with campus) by making them work 60-80 hour weeks along side school and threatening to fire them if they told anyone, which would cause them to lose their funding and likely have to drop out / move back to their home country.
I received offers from several others, some never called back. Ended up turning all those down though, as I had an interview with someone who helped step through the few mistakes I made as a learning process during the interview. One particular question I remember was basically building front-end components with Javascript, and my example had a loop with a write call in it. He mentioned he would compile the markup in the loop, then write it after it was finished, and asked why that would be better or worse. Had to think on it for a minute, but came up with a trade-off between more memory usage but less DOM writes, resulting in faster rendering. Worked that into the next coding example too, since it was similar but more complex. After the interview, when they called to schedule a follow up interview before I even made it home, I realized he was more concerned about whether I would ask for help, learn, and not make the same mistakes again. Worked there, learned a ton, became a senior dev just few years out of college, now I manage a suite of products for my current company. I don't think I would have gotten that kind of opportunity had I not had that first manager and job, so I strive to emulate that in my interviews.
One of my favorite questions is something like "describe a crisis that occurred and the steps you took to resolve it," and give an example of one of my many stories of pushing bad code to production, having a server crash, etc, etc. I love the question because it involves no coding, no memorization, no regurgitating of info. Instead, it resolves around the person being a hero, which in my experience usually gets them relaxed, comfortable, and talking. You also learn a lot about their thought process: How did they first notice the issue? What was their process for triaging it? How did they debug it? If something involved in it was out of their wheelhouse did they go to someone else more experienced for help, or did they search for similar problems online to try and narrow it down? Did they delegate tasks if the workload was too high for them? Once it was fixed what was the procedure it went through for testing / verification? Did you monitor the issue afterwards to make sure it didn't come back? Once it was deployed, did you search for similar issues affecting your other systems? Did it ever come up again in new code and you were able to identify it before it was deployed?
Obviously not all of these will apply to everyone, but the open-endedness of the question means you can probe a bit here and there throughout their story and gain a ton of relevant insight. And most importantly, it answers the question of "when things get tough, can you keep a cool head and think critically?" I can teach code, data structures, algorithms, whatever, to anyone. But the difference between someone who is always trying to learn and grow, takes initiative, asks for help, etc, and someone who just wants to do the bare minimum is night and day.
Side benefit is this usually takes up several minutes of an interview so they can't be used on BS questions like the one you mentioned.
I've used Dijkstra algorithm for calculating distance in a graph once. It was a highlight of that month. Of course I had to look it up(despite learning it and implementing it at university). Who remembers this stuff exactly after years of glueing libraries together? And even if you remember - won't you check it anyway just to be sure?
It's OK to ask people general questions (what's algorithmic complexity, what kind of algorithms and data structures they know about, what are the tradeofs, etc).
But expecting people to remember the exact steps of an algorithm they last used 10 years ago at university is just stupid. It's like asking engineers to remember the tensile strength of a material they could use once a decade. That's what the documentation is for. It will take 3 minutes to look it up when I need it (if I need it at all).
We always tell our candidates in advance what algorithms we'll be quizzing them on. And it's pretty much always:
+ fibbonacci
+ a sort
+ a linked list
I like having candidates write out these problems on paper because it shows that they know how to think about code. Fibbonacci allows us to see that they have basic recursion understanding, and basic iterative loop understanding. Linked lists shows us that they understand pointers. And a sort shows us that you can structure more complex code well.
If you truly want the job, you'll take 15 minutes the night before to remind yourself how all of these things work, none of them should be particularly foreign or confusing to an experienced programmer.
That covers the coding part of our interview. For the problem solving part of the interview, we may give you problems that require using heaps or skiplists or graph algorithms, but for this part of the interview we're happy to let you import imaginary libraries that do all the hard work.
I already don't want the job because of the interview process. Talking to someone about code they have written and the decisions and thinking around their own code is so much more respectful and gives better signal. You should be doing everything you can to put the candidate on their own turf and letting them shine. I have a lot of advice about interviews but one of the best I've heard over the years: whatever impression you have of the candidate try to prove yourself wrong. Using that advice, I've found a lot of great programmers that other companies skip over. Some people who are great at coding are bad at interviews and bad at live problem solving with an audience. If you really feel the need for a test, a paid take home coding assignment will give you the best signal.
I agree. I really dislike being asked to produce code of any complexity in an interview setting, although I do think it's important to see a candidate's code to understand how they solve problems for more senior roles.
Personally I'm way too anxious in interview settings to produce decent code. In interviews I find myself trying to get everything right first time, but in reality that's not how I work. I prefer to develop iteratively and debug as I go.
I'm also quite a slow and deep thinker. It's not uncommon for me to think about a problem for a good 15-20 minutes before writing any code. In this case I guess you would have some time to prep the night before, but I'd still be very nervous about coding on the day.
I prefer home assignments and that's typically what I'll do when interviewing people. I like to keep it simple and open ended. Simple because I don't want to waste their time and open ended to allow them some room for creativity because often we don't have explicit requirements in the real world. This has always worked quite well.
Takehomes:
The minute you allow for them to ask for 2-3 hours of work. That's the moment that they'll ask for 40+hours of work for free (and call it 2-3 hours).
Also they'll try to claim copyright on your work (with pay) and reject you outright.
I agree you have to be careful. However the takehomes I have had were a few hours of work paid at 50% of the hiring rate and that was where it ended. Great experience. There are companies out there doing this to make a great interview process and companies out there who want free work. It should become obvious which is which very quickly.
How could I be mad if you are guaranteeing pay for this moonlighting? At that time it's freelance work. However, if you're going to limit to 4 hours: If I don't have doc building copy, and tests done on that 4 hour mark, you're not getting those extras.
>I agree. I really dislike being asked to produce code of any complexity in an interview setting, although I do think it's important to see a candidate's code to understand how they solve problems for more senior roles.
I've never been a big fan of giving code interviews, however when I have to give them, I'm far more interested in the candidate's thought process around how they understand the problem and what needs to be considered in building the solution.
I agree, and I think this is where the value in these kinds of interview techniques lie. As the interviewee though, I have to say that the high-pressure situation makes me feel very... exposed(?) when I have to elucidate my thought process in real time.
I will say that one of the best "interviews" I've had included a portion where I worked with one of their engineers on a design problem they were actually having. It felt very collaborative, which allowed me to relax a bit, and I think we came up with a pretty good solution. I didn't mind doing "free work," because for me, it's fun to solve problems like these.
>I agree. I really dislike being asked to produce code of any complexity in an interview setting, although I do think it's important to see a candidate's code to understand how they solve problems for more senior roles.
I've been around the block a few times and I LOVE system design interviews, both as an interviewer and interviewee. They are much more collaborative and "fun" for me. The good news is that I've been managing for several years at this point, so those types of interviews are far more prevalent than coding.
I'd also like to add that because of this I adapted the traditional whiteboarding exercise at my current company to be about problem solving and design, and not about how many data structures you've memorized.
When a candidate comes in, I give them a fake-yet-realistic product requirement (like count elements in a real-time stream from field sensors) and let them run with it however they see fit. I put zero restrictions on the tech side of things in order to let the candidate shine (hopefully) in whatever tech they are most comfortable with.
I make sure to ask for feedback on the exercise and I've gotten all positive feedback from candidates.
It sounds like you're trying which is encouraging. I'll give you a few tips that I hope help.
> I adapted the traditional whiteboarding exercise
Lots of engineer types freeze when they have to make a presentation. I remember a meeting early in my career with literally three people in a conference room and I almost had a panic attack. No white board. People I already knew. All I had to to do is explain my ideas to three people. I did improve. I've given many public talks sometimes to hundreds of people and today I like public speaking. But I'll never forget where I started and that the person I'm interviewing might be very nervous. Putting them up on a whiteboard and into presentation mode only amplifies that nervousness. Just talk to people. Get them into that flow that comes from talking about something familiar that they are excited about. For most people a whiteboard test is not exciting. But if you give me a paid take home coding exercise, that's exciting. I like code, and I like to get paid for it. So if you really think you need a test, consider a very high signal test that is the exact work they will be doing.
> I make sure to ask for feedback on the exercise and I've gotten all positive feedback from candidates.
In an unequal relationship like that you are going to get a lot of false positives. If I really needed a job my response would be "loved the exercise, looking forward to talking to you more and discussing next steps if I'm the right candidate".
>Lots of engineer types freeze when they have to make a presentation. I remember a meeting early in my career with literally three people in a conference room and I almost had a panic attack.
That's definitely an unfortunate experience, but isn't giving presentations to explain your ideas - sometimes to people you don't really know - actually a significant part of the job? I'm an IC, and I present designs and project plans for feedback to groups of up to a couple dozen people, or to VPs, on a pretty regular basis. If I couldn't do that competently I would be failing at my job, because that kind of communication is just as important as actually writing the code. If I were conducting an interview and discovered that "public" speaking on the order of a few people in a conference room was extremely difficult for you, I'd probably consider that an important red flag.
> isn't giving presentations to explain your ideas - sometimes to people you don't really know - actually a significant part of the job?
For many engineering positions it is not. There are loads of shops where the developers, even senior developers, mostly just write code. I have hired many of them and put them to work successfully building stuff while I deal with the meetings.
> If I were conducting an interview and discovered that "public" speaking on the order of a few people in a conference room was extremely difficult for you
And yet I worked very successfully as a junior developer for a couple of years before I ever had to attend a meeting like that. Among the other 100 devs in the shop, I was considered a top talent at coding. That's not to brag but to point out that I was adding lots of value to the company without having to attend meetings with people from other departments. My manager did that. My manager did not code, although he could if he wanted to. In fact at that company they created a separate path for highly talented engineers who wanted to continue coding but wanted to avoid management and meetings. That was a couple of decades ago and less common, but I think it's a lot more common now.
And the fact that I can now publicly speak in front of hundreds of people should hopefully encourage you that it's something people can learn if they want to. Some people don't want to. There are roles for them too.
Individual Contributor, used to contrast with "Manager". Point being, my main job is to design systems and write code, but I still have to do some of the organizational stuff sometimes.
>There are loads of shops where the developers, even senior developers, mostly just write code.
Okay, so your experience is different from mine. I'm surprised that there are places where this is really not a meaningful job requirement, and I've never worked at one, but I believe you.
>it's something people can learn if they want to
Sure... but so is coding. Part of the point of an interview is to see what skills and traits you already have. If you're missing some, that can be balanced against the ones you do have - it's not a dealbreaker, but it is still a negative.
>Some people don't want to. There are roles for them too.
Again, not where I work. Engineering, even at relatively junior levels, includes collaboration and explaining your work. You can't just say you don't want to do that - or rather, you can, but you'll have no upward mobility and be managed out pretty quickly.
Isn't there just a bit of condescension in that title? It always sounds to me like something invented by a manager to be dismissive of someone who doesn't manage anyone.
I never got the vibe that "IC" was intended to be dismissive, or intended to be a pejorative or anything. I think it's more of an HR thing, because the distinction between IC vs Manager usually affects compensation and blah, etc. Whether or not that should be the case is a separate question.
I always assumed the term just leaked out of the HR world and into the general parlance.
If you're in a place where an IC can potentially make half a million or million dollars a year and drive some very interesting project work and be highly respected, no.
If you're in a place where not making it into manager track puts a very low ceiling on earning potential and respect, then yes it can be condescending.
You’re right. But what are you trying to prove with on the spot coding challenges? That the candidate can implement a hash table from scratch in 15 minutes with O(1) performance?
Is that something they’re going to do on the job? Very unlikely. So why are you not only testing for it but testing for it in a fake time-pressured stressful situation that also rarely exists on the job? (Yes , we all have deadlines but when are they ever 15 minutes on the spot?)
Perhaps you should have entered the education field where you could give such exams day after day to your heart’s content?
People giving on the spot coding exams, or worse whiteboard coding exams are just assholes. They're trying to haze interviewees and make themselves feel better. There's zero actual utility to such tasks in an interview.
> Lots of engineer types freeze when they have to make a presentation.
I've seen one place that wanted developers to do a full presentation with slides and all to a group of people.
The topic of the presentation was completely up to you, didn't even have to be a technical subject. You could do a presentation on baking if you wanted.
Was doing presentations a part of the job of the developer? No. They wouldn't have to do presentations in their day job...
I didn't go for the job and have never understood what they were looking for.
I do something similar: I ask the candidate to take 30 minutes or so to design a system like an online library. What are the objects in the system, how do they relate, can you design a REST or graphQL API for CRUD operations.
Then if it’s a front-end position we can move onto UI components for it; for back-end or full stack I focus on implement a couple of the CRUD operations.
You really get to see how people think and will work on the job with questions like this.
Implementing a sorting algorithm from scratch is a waste of time in many projects: use your libraries and get on with life. That’s why such interview questions are not important to me.
>> You really get to see how people think and will work on the job with questions like this.
Interviewing is hard and I applaud you for trying something newer and more realistic but I'd be cautious in thinking "spend 30 minutes designing a system and be prepared to defend your work with massive risk/reward hanging in the balance. Begin... NOW!!!!" is representative of how someone will work on the job. There are an awful lot of people who will solve the crux problems driving home after the interview or the next morning in the shower vs. on-demand.
I certainly don’t say BEGIN NOW! It’s a conversation. I continually ask questions during the design and ask the candidate to speak about the decisions being made.
In all honesty this process can easily last more than 30 minutes.
This is not a hard problem for someone with the experience I want, and there are many different correct answers.
Agree. Its far more valuable to see how a candidate approaches problems than some memorized recital show. I don't expect perfection, but if their reasoning is sound that becomes clear fairly quickly. I usually also include some imperfect questions purposely to see how they handle that. While we wish client projects were nice and clean with orderly data and tight requirements, the truth is that is rarely the case. It's useful to see how the candidate responds to those types of things. I had one gentleman argue with me about one of those questions claiming you would never see primary and foreign keys between tables not perectly match in the real world. Well when you are matching data from entirely disparate systems, you typically do. Anyway I digress.
> Talking to someone about code they have written and the decisions and thinking around their own code is so much more respectful and gives better signal.
Agreed. The best jobs I've taken had interviews like this, or paid assignments.
Talking about code that someone has already written is missing the element of productivity. Since we pay you by the week and only get so many hours a week out of you, we need some way before we hire you to understand what type of output we can expect.
The best way I know would be to work with someone for a week or two on a real problem, but that's way too expensive to trial a junior role.
At least for us, the system is more optimized around avoiding false positives than ensuring we don't pass over someone good.
Due to a lack of imagination and people who don't host interviews on a regular basis so they never put in the effort to get good at it. When I conduct a technical interview we are going to end up doing some stuff you do in your 9-5. And you probably won't even notice it. And if there is a budget available for it, I'm going to pay you to do a very small coding assignment. A few hours. Almost exactly your 9-5.
The fundamental difference is that a job is directly at stake based on your performance. For many people, this makes them more nervous than they would ever generally be during work. Due to the nature of interviews, I don't think there's really a way for it to be otherwise.
>> The best way I know would be to work with someone for a week or two on a real problem,
So if I get the job will we just touch base ever week or so? This sounds unlikely. Why can't you break work down to the point that you can pay me for 3-4 hours of real output and then use that to evaluate my quality?
All these tests around recursion and linked lists, etc are a feel-good proxy for actually measuring suitability, If someone is actually implementing them (IF!) it's not the junior, new-person; it's the senior architect who does it once every few years in a shared library. I can count the number of times I've used recursion in (a) a non-toy implementation and (b) not ripped it out and replaced with a faster, clearer iterative implementation on one hand.
> Talking to someone about code they have written and the decisions and thinking around their own code is so much more respectful and gives better signal
where have you been all my life? ;)
I'm an autodidact, zero formal bg in comp sci. I suck at timed tests and algo interviews. Fifteen years I've been at this and I've worked with several 'full stack' teams, none of which had a single engineer who was within a thousand miles of what I could do with CSS (and they're mostly utter slobs wrt HTML). And as to the endless javascript demands, I will never be of interest to google (and the feeling's mutual) but I always get the job done, and often the job is something FE that none of my esteemed colleagues would know the first thing about how to achieve, comp sci degrees and recursion expertise notwithstanding ... not to mention that every one of them has as many stack overflow tabs open as me.
I'll get back to my sorry little js projects now, maybe I'll get another job before I grow old and die ;)
This sounds like a reasonable approach and that is why software interviews remain broken. I'm sure it works for your organization, not saying you are bad at hiring or anything but it still smacks of the kind of hoop-jumping that turned me off so much from the process last time I was interviewing. This included on-the-spot coding exercises, massive take-home projects that required many hours of undifferentiated grunt work, totally useless whiteboard sketching and pseudo-code sessions, obscure Google-like quiz questions.
The interview process for the job I have now was a massive breath of fresh air.
The application asked for code samples and a cv. It was a small company and the CEO, CTO and direct co-workers all drove the interview process. The process was entirely conversational. First an intro phone call with the CTO and then a questionnaire via email in which I answered about 30 questions on various topics that were all very practical daily software development type stuff. It was painless to respond to each with about a paragraph in detail. Then a call with a direct co-worker about the questionnaire and this was my opportunity to ask questions of him about the company. Before getting the interview they actually read my code samples and reviewed my Github account. In the interview there was a ton of discussion about the company, its culture and all the of the above discussions. Following this was compensation negotiation with the CEO.
Everything about the hiring process said to me yes this is the place, they get it!
Many people would consider a 30 question take home project massive. You discuss your second experience as if it is some novel Utopian experience but when I read it sounds like an experience that was well suited to your strengths but wouldn't be suited to mine.
It definitely favored verbal skills, I am assuming that was a feature not a bug in the hiring process. The questions were not a project but a conversation in the context of my experience With a specific tech stack such as... “How do you keep a server from getting hacked”, “how do you handle conflicting dependencies”, “how do you know your code is ready to deploy to production”
I write on paper so infrequently that I actually find it pretty difficult to write more than a few words. I certainly wouldn't want to write something out longhand in an interview!
Edit: It seems to me it would be rather unfair of me to ask people to write out their thoughts in Org Mode in VS Code just because that's how I happen to like writing notes :-)
I had to do a timed exercise to write code on paper IN PEN at a job interview. Talk about feeling like I had to get it correct the first time. Glad they didn't give me an offer because I would've had to consider accepting it.
It's not a matter of writing speed, it's familiarity. I've been programming for 30 years and I don't think I've ever written code down on paper. Why ask an interview candidate to do something they've never done before and will never do again? You might as well ask them to type their code using only one hand.
> Fibbonacci allows us to see that they have basic recursion understanding
I see no reason to use recursion when asked to calculate Fibonacci numbers. A loop looks like a more reasonable choice that also avoids typical pitfalls associated with recursion. Maybe that's because I did embedded programming for a while.
I suspect recursion is introduced in CS classes with this example, but people understand it as "you are supposed to use recursion to calculate Fibonacci numbers".
Recursion is often less efficient but looks more elegant and simpler. It breaks the problem down to is essence. Then you can trade some complexity for more run-time efficiency.
Beauty is in the eye of the beholder, but a loop is hard to beat as far as simplicity goes, and you don't depend on your compiler being clever enough to optimize tail recursion.
If you need to traverse a tree then sure, but with Fibonacci you don't even need the stack to begin with. You only need to keep a previous number.
You don't even need a loop. Binet's formula gives a closed-form expression for the Fibonacci sequence. (And of course I don't remember that formula off the top of my head, but I know it exists, so I'd be 90% of the way to solving a problem which required it.)
This sounds like an inspection of whether the person has had a class in basic algorithms rather than if they have ever coded anything in real life.
In school I played with sorting algorithms, in business if I ever found a developer manually writing a sorting algorithm, I would consider them inept (unless there were very specific reasons to do so).
If someone didn’t know how to sort a list using the built in or standard library of whatever language they are using, I would know very quickly that they have almost no experience writing anything useful.
If you're given a blank slate and asked to sort a list without using a library without any gotchas, complexity requirements, space requirements, expectations that the code is completely free of small bugs etc.; and you can't do that after some thinking even to a basic degree, then you're just not a good programmer.
As a programmer, your task is to find algorithms to solve problems. Sure, sorting numbers is a solved problem and in real life you should use a library. But you will not find a library for each problem you encounter, and sorting is a very simple problem to solve compared to anything you'll find in real life.
I agree, but how is applying pre-learned algorithms significantly better than using pre-build libraries? Both is about using an existing solution, instead of coming up with it on your own. The real approach would be to ask candidates to solve a problem that doesn't easily fit into any popular category, so that they have to come up with an original approach - but that is first hard to come up with, and 2nd it would require investing extra time on both sides, which usually neither candidates nor interviewer can afford.
Yes, that's a good point, and in our interviews we do try to take a slightly less well-known problem, at least one that doesn't have a dozen well-known named algorithms.
Still, even using a pre-learned algorithm demonstrates some level of confort with algorithms in general, and can be used as a stepping stone during the interview to shift the problem slightly to see how they adapt the algorithm.
For example, if a candidate is clearly taking their time and essentially working out the algorithm themselves, and succeeding, that demonstrates the skill and we can move to other problems. If the candidate just breezes through and finishes in 2 minutes, then we can change the problem ad-hoc to try to get them off the beaten track a bit (say, if they wrote quicksort, maybe ask about making it stable, or sorting even numbers differently from odd numbers, off the top of my head).
My point was that if testing for a skillset, using something that favors those who have toyed with a specific algorithm is the same as asking trivia questions.
Trivia does not provide evidence of skill, it demonstrates prior knowledge.
It would be better to introduce a unique situation that would place everyone at the same starting point.
If the expectation of the interviewer is to see if they know quicksort, then I fully agree with you. If the sorting problem is simply used as a (rather uninspired, granted) stepping stone to checking that the candidate has basic algorithm-finding skills, then I think it can serve this purpose (though less well-known but still relatively simple problems would be better). I gave an example in another thread as well, but in principle I would change the problem up a bit if the candidate is obviously producing a well-known algorithm; whereas, if the candidate is working out the solution themselves, I would be happy with that and move to other topics.
Even so, knowing very widely talked about programming trivia is still a signal for interest in the art. I'm not sure that sorting algorithms are a good example of what I'm thinking, but I always award extra mental points to candidates who seem knowledgeable about the field (e.g. they know the general consensus on manual memory management vs garbage collection). Still, I wouldn't consider these sorts of things dealbreakers by any stretch of the imagination.
In fact now that I think about it, it might be a good test to see if they are passionate enough to be a great problem solver:
When was the last time you wrote a sorting algorithm?
Acceptable answers:
- You mean sorting a list?
- In school
- Why would I write a sorting algorithm?
- Never
- (Glazing eyes and other body language that indicates frustration)
Red Flags:
- Anything that indicates they think writing a sorting algorithm is a perfectly logical thing to do during the course of software development.
(Note: The problem is sorting may seem like a well-understood problem, but it’s actually not. Only a person who studied the algorithms in school as an assignment would feel comfortable with that code.)
Acceptable answer: it depends on what I'm sorting. Is it a primitive like char strings, numbers, or a more complex data type? Could it have null values and type mismatches, am I using a strongly typed language? Does it need to be cleaned first?
I think the ability to come up with relevant and important questions to ask about the task given is more crucial than whether they can solve it. You can look up answers to questions from hundreds of good sources, but you need to be able to generate the right questions that need to be answered first.
In my experience it's pretty necessary to do this. Probably depends on your local job market, but there are a shocking number of candidates that just don't know how to code.
The explanation I've heard is that good devs generally get hired after only a handful of interviews, whereas really bad devs are going to do a lot more interviews on average before they get hired, so you get a pretty skewed sampling even if there aren't that many really bad candidates around.
Yes, Joel Spolsky and IIRC Jeff Atwood have written somewhat extensively about it.
We are in a bubble, if we read programming blogs and think about programming in our free time, we are definitely not the kind that FizzBuzz exists to filter out. But from the perspective of companies, it makes sense if they really understood pointers or recursion or graph manipulation, because there are so many people lying on their resumes, not having sufficient analytical skills despite doing some resume driven cargo cult development etc.. And as an industry we don't really have an alternative to these algorithm interviews at scale, at the point we rely on non technical HR people to filter out resumes for us and they literally grep for framework/language experience.
Real jobs have certificates and degrees that mean something, where you can avoid the whole "do you know literal 101 things" phases of the interview process by just going "do you see the line on my resume that says M.Sc."
I don't know what your hiring experience with this is, but there is an entire market around "coding interviews" where people will learn how to pass these. I found algorithmic interviews completely useless to assess junior engineers because of how many just learn just to pass interviews, but then have very little experience with real problems.
If you want an example of this, check out r/cscareerquestions. The standard advice is not to practice any practical coding with projects, but to "grind leetcode" to get past interview filters.
If you want experience with real problems, they juniors should not be your thing. Juniors are supposed to be people with little experience that are able to work if given tasks by seniors.
A lot of candidates can't reason past the simple stuff so rarely do I have go beyond a simple coding problem. The FAANGs and unicorns maybe get lots of candidates so they can be very choosy.
I’ve been interviewing at a lot of places lately. I _never_ white board interviewed before this round of interviews I’ve done And at first I have to say that I hated it so much.
In a weird way though, I’ve at least grown to understand why it’s so popular, and I don’t think it’s just because FAANGS do it (though I think that’s how it came to prominence). It boils down to showing as an engineer your capable of being flexible and malleable your change and understanding. Some places definitely do this better than others, and I think it says a lot about company culture if they are Adversarial about it or not. In my experience rather unfortunately even good places to work can be adversarial about it.
The massive downside is and always will be it puts so much onerous on the candidate because you don’t really know what they are going to ask and freezing up or getting stumped is very frowned upon in these style interviews from what I experienced.
My tip to anyone though is just to practice, but I’ve yet to encounter places that don’t employ some technique to test algorithmic thinking and understanding of complex systems in some way.
It's a great showcase of how a flashy looking solution is the wrong approach. A good candidate will know it can be written in 2 lines recursively, but that the stack will explode with a fairly low term number, and that iterating with a for loop is more efficient.
The closed form solution is technically O(phi^N), so still exponential. It comes mostly from exponentiation not being constant time, see https://stackoverflow.com/questions/360748/computational-com.... It'll only be constant time if your values fit into a hardware register and you can leverage the exponentiation instructions of your CPU.
There is a O(log(N)) solution involving matrix exponentiation though, if you really need to get the big numbers.
Technically, Fib(n) at unbounded sizes is at least linear to compute. This is because the output of Fib(n) has O(n) bits in it. So even if the computation is free, it's still O(n) just to print the result.
That's not the type of thing I would ever expect a candidate to know in an interview, just something fun I've run across.
Of course, recursion vs iteration is mostly an implementation detail. Here's a recursive version (expressed in Python) that works better than your loop:
def fib(n):
if n =< 0:
return (0, 1)
else:
a, b = f(n-1)
return (b, a + b)
(I say it works better, because it has the same asymptotic runtime, but fails better: When numbers get large, your C version will run into undefined behaviour that can cause arbitrary problems. The Python version will just crash with a well-defined exception.
A better language than Python can run this recursive version for arbitrarily big numbers.)
If you have a decent language and a good compiler / interpreter, then the recursion with function calls will have no overhead over iteration. (Basically, in Haskell or Scheme your recursion will be compiled into the same machine language sequence of straight-line code plus conditional jump as the iterative loop.)
> If you have a decent language and a good compiler / interpreter, then the recursion with function calls will have no overhead over iteration.
The recursive Python version above didn't use tail calls. I don't think that a Haskell or Scheme compiler would compile the equivalent versions into a simple loop.
I just tried it out, I didn't manage to get GHC to compile the equivalent of the code I've given into something that runs in constant memory. (I did the calculations modulo some number, to keep the numbers themselves bounded.)
GHC is sometimes able to do some of those transformations.
> The recursive Python version above didn't use tail calls.
Just to be more pedantic: it did use tail calls, but the recursive calls weren't the tail calls.
> Just to be more pedantic: it did use tail calls, but the recursive calls weren't the tail calls.
I was talking about this code:
def fib(n):
if n =< 0:
return (0, 1)
else:
a, b = f(n-1)
return (b, a + b)
Not sure what you mean by tail calls here. I don't see Python-level tail calls. The interpreter will call C code for tuple packing, but those aren't in tail position with respect to the Python code either.
Because after tuple packing returns (a C return) you still need to perform a Python return. The C tuple packing function cannot return directly from the Python function.
Oh, your compiler doesn't have to be sufficiently smart. It merely has to avoid premature optimization: see this classic paper https://dspace.mit.edu/handle/1721.1/5753 by Guy Steele.
> I can't be sure without measuring, but I strongly suspect the overhead will be mostly in tuple packing/unpacking and GC.
I guess that's the same overhead as in this imperative version:
>(Basically, in Haskell or Scheme your recursion will be compiled into the same machine language sequence of straight-line code plus conditional jump as the iterative loop.)
This is not true. The recursive code will not compile with zero overhead even in haskell or lisp.
fib :: int -> int
fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
The code above will add layers to the call stack and has a speed complexity of O(N) and memory complexity of O(N).
To optimize in Haskell you need to deliberately restructure your code.
fib :: int -> int
fib n = let _fib 0 a b = a
_fib 1 a b = b
_fib n a b = fib (n - 1) b (a + b)
in _fib n 0 1
The above code will have O(N) speed complexity and constant memory in Haskell. In order for Haskell or any language with tail recursion optimization to work the recursive call must take up the entire return expression. In short the coder must deliberately make optimizations and write recursion in a way similar to the original iterative syntax in order for such tricks to work.
Though GHC is sometimes able to do some simple transformations on its own. But not in this case.
For anyone trying this at home: I suggest calculating your additions modulo some constant, so that the numbers involved stay within a fixed size. (Otherwise, you either hit the limits of Int and weird things can happen, or when calculating with the arbitrary precision type Integer, your numbers themselves will grow linearly in space.)
Though if we allow programs like the C example that give wrong answers or have undefined behaviour, I can write an even faster version that takes no time at all.
For the code above memory complexity is still O(N) even in a language that optimizes for tail calls. This occurs because you have an additional expression that occurs AFTER your recursive call that means the system must hold everything on the call stack for it to work.
For Fibonacci, recursion is not the best or most efficient way to approach the problem, but I like using it as a recursion problem (artificially constrain the candidate to using recursion) because Fibonacci is so simple that you get to spend most of your time talking about recursion itself rather than talking about Fibonacci as a problem.
At least for this part of the interview, I'm not worried about your problem solving skills I'm worried about your programming fundamentals. We'll test problem solving in a different session.
I, for one, prefer recursion to explicit iteration in most cases. Anyway, if you were going to write the answer in Haskell, it's a three-liner and it's recursive.
While your formula is correct, it is not an actual implementation. How many digits of the square root do you need to compute exactly for being sure that the value of the power does not change?
Whether this is "fast" or not depends a lot on the concrete implementation of your arbitrary-precision real numbers.
As a nice thing, the second term (after the first minus sign) is smaller than 1, so you can omit it by rounding the result to the nearest integer; all the game happens in the first term.
You can implement the matrix exponentiation via repeated squaring recursively even in a language like Python that doesn't do tail call optimization, and it will still be fast: your recursion only goes to a logarithmic depth.
In any case, recursion vs iteration is an implementation detail. Especially if your language supports tail call optimization. Have a look at this example:
f(0) := (0, 1)
f(n) := let (a, b) = f(n-1) in (b, a + b)
f is recursive function over tuples of integers. And f is basically equivalent to the typically iterative algorithm for computing Fibonacci numbers.
We've learnt on "discrete math" course at university how to derive closed form solutions to any similar recursive sequences using algebra and eigenvectors.
I remember that it's possible but I forgot all the required math :) Now that I googled it it's not THAT bad
In my decades of programming I've never had to seriously consider these issues. I have used recursion and have written some pretty deep stuff like cryptography and writing my own interpreter (for a business - not a school project). I've even implemented recursion in a language that didn't support it. I have read about tail recursion several times. I still barely remember what it is. But I know a few books to reach for if I had to use recursion again. This is why the interview process is broken. I've written lots of production code and end up being seen as a lead programmer within weeks of a new job. And your questions would make me look like I don't know what I'm talking about.
I’ve worked with some interviewers who are out to prove they are smarter than the candidate because they remember a bit of something that the candidate does not.
Only when the interviewer finds someone “smarter” than himself does he approve of hiring the candidate.
Serious request, as a developer who would probably code a naive Fibonacci that doesn't meet your standard: Could you provide a code sample that does meet your standard? This looks like an important learning opportunity for me. Thanks.
True, but then the "worker" fib() method should be called fib_calculate() and should be wrapped by fib() which then returns a single integer. I believe that breaks the spirit of the question.
There should be a fourth level where they use the closed form solution to get to the solution they want without any recursion or looping for reasonable values of N. Maybe even a fifth level using the O(log(N)) matrix exponentiation method.
I’m a bit puzzled at the idea of using recursion for an infinite sequence (did OP mean factorial?). Give me a LazyList / generator / IEnumerable instead any day for Fib.
I think someone's ability to understand and explain recursion like am a child is very undervalued. It's not about testing whether you know the base case or the fact that you write less lines of code in recursion but the fact that there is a built-in stack for you to use without creating one.
What are the practical applications of recursion though ? Other than sorting and DFS ( well even DFS can be done iteratively with stacks ). I'll be curious to know.
I find testing for HashTable/HashMap knowledge to be far more practical than testing for LinkedLists simply because you can't escape HashTables in today's world.
> What are the practical applications of recursion though ?
Traversing and transforming nested data structures.
Just last month I had to write code that maps flat data from one system into a nested structure required by another system.
We wrote mappings as map literals and the code traverses them creating a new instance of the map filling the leaves with data from the input row and running some business logic on it.
Seems over-complicated, e.g. I probably wouldn't go for recursion for Fibbonacci, so I'd miss your expectations completely. Why not just ask a direct question on things that you're looking for? If you care about recursion, ask them to implement simple recursive tree walker or something. Equally linked lists are something that in modern languages almost no one will have to manage by hand. If you care about understanding the concept of pointers/refs, why just not asking directly about that.
Have you tried just having a conversation about pointers and recursion? Does that not work as well (or better)?
Kudos for letting candidates know what’s going to happen, it’s just that when I see problems that are clearly just a stand in for “do you know X?” I always wonder why interviewers don’t cut to the chase and just ask directly. “Are you comfortable with recursion? Can you describe it? When does it tend to be applicable?”
Some people (myself included) can bullshit through such questions pretty well even when we don't know the answers. It's a skill, a combination of reading body language for clues, being confidently vague in the right places and turning attention away from dangerous questions with charisma.
You learn it quickly when teachers do oral exams at university :)
Code doesn't lie, so I understand why people like to check candidates that way instead of relying on talk alone. I would just prefer if it wasn't a hit-or-miss test on what algorithms you memorized.
I think that your test if fairly easy and since it requires very little time before that, I dont understand the opposition of other people.
But, you are not seeing how people think about code. You are seeing presentation prepared before hand. That whole part abour seeing how people think, as much as it is repeated, is nonsense, so maybe it is not much of loss.
Making people write code on paper is just ridiculous - way outside of testing and checking reality - and your reasoning of
>"because it shows that they know how to think about code"
means nothing at worst, and at best indicates you'll only be happy to work with people who are replicas of yourself.
Take home is the way to go, unless the position is some sort of public exhibitionist analogue developer position.
The least I think you can do is move from paper to machine, and inform them they should bring their own machine, or offer them use of one with many envs preconfigured.
The problem with take home interviews is that it could take one candidate an hour, and another every evening for a week.
Ideally the interviewer shouldn't be concerned about absolute code correctness, such as syntax or argument position, and should be interested more in how you're able to solve the problem, which should be a novel, yet simple task that doesn't require studying up on 200 level algorithms.
You want to hire developers (for permanent full time roles, at least) who have a good conceptual grasp of programming and logic, rather than their particular knowledge of a language or framework, or their ability to search on stackoverflow and run their code through a linter.
The worst interview problem I've been given was to write an AngularJS directive, I think literally to simply take an attribute and display it. I can't remember at the best of times the syntactical oddities of AngularJS, let alone when writing with pen and paper in an interview with no resources.
One of the better problems I was given was around parsing XML, from memory validating that opening tags matched closing tags, while allowing for self-closing tagsI remember the problem specifically didn't include any more complex facets of XML. Another was to reverse a string in-place ("hello world" -> "dlrow olleh"), and then to modify the algorithm to reverse the words but keep them in place ("hello world" -> "olleh dlrow"). Obviously in the real world you'd just use built in methods, but it's a problem that should be solvable without digging up your old lecture notes.
I've always felt comfortable writing code (or at least psuedocode) with a pen, but I think it's unfair to require a candidate to solve the problem on paper or whiteboard if they feel more comfortable typing on a computer instead, all that achieves is disadvantaging otherwise capable candidates who for one reason or another can't write code with a pen and paper. As long as they aren't googling "how to reverse a string in place", it immaterial what writing tool they use. If they feel more comfortable using a brush and papyrus, or carving a runestone, then that should be perfectly acceptable too (provided they bring their own writing material).
This varies a lot. I had a take-home for a data engineer role which just asked to get and parse an xml and post a cleaned, limited json of the data. Took ~1hr. Perfect for an initial threshold.
Are you hiring for first year beginners? Or is this also a test for your senior software engineers?
Your question topics are completely useless to normal software engineering work. And this proves how immature your company is, in understanding the nature of the work.
Perhaps you should consider asking them instead, what their technique is to ensure reliability, throughout, and redundancy in their code? Can they make their code self-heal itself? Or to make some minor decisions to restart itself, if optimal conditions are not met.
What's wrong with a memoized recursive solution? Or a DP tail recursive solution? Tail recursive solutions are less buggy, easier to code, and easier to write than iterative ones. And they're much easier to prove the correctness of as well.
The memoized recursive solution is a good demonstration of how to use memoization to improve recursive function execution time. But it also seriously increases the memory requirements for many algorithms. If the question is "generate the first N numbers in the Fibonacci series", then memoization is a reasonable answer (though still not the fastest) since you actually need to generate and store every value anyways. If the question, instead, is "generate the Nth number in the series", then memoization will require an array of N values, when only 2 (at a time) are needed (which can still be generated recursively, but efficiently):
(defun fib (n &optional (a 0) (b 1))
(cond ((zerop n) a)
(t (fib (1- n) b (+ a b)))))
With tail recursion, that should be as fast as the iterative solution and uses as much memory to store the intermediate values.
Of course, the Fibonacci series also grows incredibly fast, so practically speaking, unless your language supports arbitrarily large integers, you'll never generate even 100 elements of the series.
If the question is "generate the Nth number in the series", I would be inclined to suggest a closed-form solution that returns in O(1) time (assuming regular size integers), no iteration required.
Completely agree. The only thing that's important is knowing what to google for. i.e. being able to map from a real world problem to one or several algorithm/structure classes.
It does not matter how us think, I believe these detail-oriented algorithm interviews are intentionally designed for younger coders who can still do them out of memory, though in practice they're not very meaningful and if you really need them sometime you can always dive-in and get what you need.
I'm doing leetcode now, as a senior engineer there is no way to get a decent job without being tested like a college fresh-out as far as programmer positions are concerned, no complains, I will do them, it is the market picks me, not the other way around.
To me even though this is painful, but at least it is "merit-based", what I dislike the most is that you got a job based on other factors instead of how able you are.
Just using a graph was the highlight of that month for me. (The data wasn't already in a graph.) Reading the wiki, it may have been Dijkstra that I used under the hood. (I just wanted the sum of simple paths for all leaves to the root, for each leaf.)
IMHO all you need to know is to recognize a certain category of problems and remember that there is an appropriate algorithm for it - and if can you recall the name even better, will save you some time googling, but it's not that important. After consulting the documentation and if you previously learned it in a school/course, you'll be able to implement it in pretty much the same time as someone who knows how to draw it on a whiteboard from the top of their head.
As an engineer who works on security software, here's what I've empirically used on the job:
1. Tree/graph traversal (certificate validation and a couple other random places)
2. Using, not implementing, hash tables
3. Generators/iterators/streams: minimizing the number of unnecessary list traversals or allocations made when you have to shovel data around
4. Circular buffers: specifically in low latency, high throughput applications
5. Some exotic string search algorithms in a very specific, highly performance sensitive inner loop
6. Database query performance tuning
7. Every now and then something vaguely reminiscent of dynamic programming comes up, but it's never an actual dynamic programming problem, it's just a "cache results of expensive operations" problem.
For my job you need something exotic once in a blue moon, and when that happens you Google for someone else's research. You're not making up algorithms on your own. If you want to test that someone can handle algorithm-heavy situations like case #5, you should be testing their paper reading and ability to implement that paper, not their ability to solve an algorithms puzzle.
Also relevant to my job: if you find yourself implementing cryptographic algorithms, you're almost certainly doing it wrong. You shouldn't be implementing cryptographic algorithms. When I need them, my job is to vet and correctly use an expert implementation.
The interview process is totally broken, as it tests mainly how much someone is willing to prepare for the interview, which might actually show more how little they focus on doing more productive things in their current job, at university or by starting interesting projects. It also scares away people who might actually be better at the job but not as good or interested in interviews - at least this was my experience at Google compared to the usually more interesting people I worked with at university.
It’s just more difficult to test beforehand how someone might actually solve a problem in a good way as you describe. If applicable it’s possible to look at prior work, if you have any other good ways I’d be very interested.
Edit: this is actually a good thread to get some ideas on improving interviews.
I still do algorithms interviews, sort of. The one-hour interview format is an external constraint, so within that constraint I will do ~40 minutes of coding and ~15 minutes of discussing past projects. I ask a question where the algorithm itself is at most some list iterations or tree traversals, but the real difficulty is thinking through the data and figuring out the right generalizations and transformations to apply.
It seems to control decently well for people who have practiced for interviews, because they do the usual dance of asking some clarification questions, mocking the functions, and narrating their code, but many of them hit a wall five minutes in. It's not because their algorithm doesn't work. They're using the right algorithm. The problem is that they haven't thought through "ok what do you do with the data now that you've traversed the tree?" In my experience, for my job, that's usually the actual hard question. For example, if you're checking a JWT, are you validating it in a way that is hard to subvert? Are you taking any time to think about pathological data inputs?
The counterpoint would be "what about a candidate who has solid coding skills but stumbles on the problem space because they're unfamiliar with it?" In my sample size of approximately n=10 since I started interviewing candidates this way (admittedly a small sample, but it's the sample I have), I have yet to see someone who writes code well who neglects thinking through the characteristics of the data up front. That said, it's a real issue. Data is usually contextual, so you're at an advantage if you have experience in the corresponding problem domain, which is not something I'm measuring for in the coding exercise. While I try to pick topics that should be universal, I inevitably get surprised, so I offer three different topics based on the candidate's resume, and I give the candidate a choice.
The biggest weakness I've seen in my interview process (within the scope of what you can do with only one hour) is that it doesn't control for nervousness or people who just don't operate well under time pressure. Unfortunately that's an unavoidable consequence of the mandated form factor, so I have to try my best to help relax the candidate and then rely on my gut for how much nervousness or pressure affected the interviewee.
I think the key element is how you calibrate towards the candidate, bringing common sense into the process. This is something Google tried to cancel out to increase fairness, which failed in my experience.
Maybe another issue is setting the bar too high during the interview to improve the metric on retention, sometimes it might just not be the match that the interview appeared to have.
I usually try to work with people on something small to get a feeling for how well we work together before committing to larger projects, but at some point I’ll need to start hiring, so I’m very interested in this topic.
I'm a very "generic" programmer that dabbles in an incredible variety of problems, from Windows GUIs to health monitor probes running on a BSD network appliance. You just summed up pretty much everything I've ever needed to know as well.
IMHO the #1 thing that most developers are missing is database query writing skills. There is a shocking amount of terribly inefficient SQL out there that is wasting everyone's time and money.
We often see the "don't roll your own crypto", and of course, in a production setting that's obligatory advice. I think that it's a valuable exercise for anyone to implement some of the algorithms and protocols, just to understand the complexity within. I did that for a minimal TLS1.2 implementation, just because, and it was a valuable exercise. Do you see any value in changing the slant you put on "don't try this at home"?
I think there has always been an implied exception for doing things for their pedagogical value. In the case of my previous comment, I think it’s pretty clear that I’m talking about production code.
As far as rolling your own crypto goes, I think the advice should be “only try it at home and don’t ever use it in production even for yourself”.
A few years ago I spend lots of time and effort at Goldman Sachs solving a performance problem in a major part of their internal cloud infrastructure.
The programme in question was running into performance problems, and a few smart people had already banged their head against a wall solving them.
After lots of experiments and different approaches, my solution was to remove most of the advanced data structures that were in the code.
In theory, they should have given us logarithmic runtime on some common operations, but the constant factors were too large. I proved (in the mathematical and the practical sense) that a brute force scheme combined with a careful randomization would dramatically improve real world performance with a fraction of the previous line count.
Despite me removing those interesting data structures, I still count it as a great application of my algorithms-and-data-structures knowledge: a big part of expertise is to be able to spot opportunities for simplification.
This was the focus of my advanced algorithms course at Georgia Tech in my senior year. We had basically a full semester on random algorithms, and I remember walking out each day feeling like the fancy algorithms I'd memorized the previous year were a bit less glamorous.
The number of algorithms that removed multiple complicated stateful steps with 'and we randomly select an element from the array' was mindblowing. As I work on more and more distributed systems I keep seeing opportunities for simplifications with randomness (with obvious drawbacks on occasion).
You can sometimes put all the randomness in one part of the algorithm, even. Like shuffling before a naive quicksort.
In practice that's often even easier to understand (and debug!) than algorithms that keep making random choices as they run.
Shuffling and sorting are two humble but powerful building blocks of many algorithms. Both distributed and sequential.
In the example of what I did at Goldman, the core of the problem was essentially a souped up multi-dimensional bin packing problem. The big insight was that the typical distribution of our input data, random assignments had a high enough chance of being good, so we didn't need to keep track of everything in k-d-trees.
(k-d-trees are also awesome. And I even implemented randomized k-d-treaps at first, before I hit on an even simpler solution.)
You can find a lot of good material just via Google, actually.
If you read the likes of The Art of Computer Programming for breakfast, you might like 'The Discrepancy Method - Randomness and Complexity' available at https://www.cs.princeton.edu/~chazelle/pubs/book.pdf But it's not for the faint of heart.
I'm surprised and delighted to see someone recommend The Discrepancy Method by Chazelle. I love this book, but even beyond it requiring a lot of mathematical prerequisites, I'm not sure of the use to most software engineers. I think only the chapters on sampling, geometric algorithms, minimum spanning trees, and maybe linear programming would be useful references on algorithm design for most software engineers.
I second the recommendation of Probability and Computing by Mitzenmacher and Upfal. In addition to being much more mathematically self-contained, there is more focus on models and techniques that I imagine software engineers might actually use, e.g. hashing, load balancing.
In addition, Randomized Algorithms by Motwani and Raghavan is a fantastic book, and should be doable after completing Mitzenmacher and Upfal. It goes into further depth on techinques for designing randomized algorithms.
A bit orthogonal but still related to the idea of "what should a software engineer read for interesting algorithm ideas", I really like Approximation Algorithms by Shmoys and Williamson. There is some intersection with randomized algorithms there too.
Chazelle also came up with the ingenious soft heaps.
I was just giving the recommendations in the context of 'Do you know any good books or resources to read up more on random algorithms?'. Not with any regard to practicality.
I have to admit, I only managed to work through some of the chapters in the books I recommended. And for example, the main reason I know of Chazelle's book it's because it is available for free online and stumbled across it a while ago.
Btw, you seem knowledgeable. I have an algorithmic puzzle that has plagued me for some years now:
Starting with an empty heap, and a sequence of inserts and min-pops, can you compute what elements will be left in the heap at the end in linear (expected) time?
Obviously, you can't just run the instructions, that would take O(n log n) time.
I have an algorithm to verify a proposed solution in linear time. But I don't have anything solid for finding one in linear time. I have a hunch that soft-heaps might be useful. And there's probably an even simpler probabilistic approach.
Ideally, I'd like the solution in the comparison model, but if you have something that works on numbers only, that's also fine.
> I was just giving the recommendations in the context of 'Do you know any good books or resources to read up more on random algorithms?'. Not with any regard to practicality.
Fair enough! I still think it's a good recommendation, I was also adding on some thoughts on things that might be easier to digest :-)
> Chazelle also came up with the ingenious soft heaps.
Yes, soft heaps are very cool!
> I have an algorithmic puzzle..
Cool puzzle! Hmm, the solutions depend on exactly what you're asking.
The puzzle is substantially easier if the min-pop operation is not required to return anything. In this case, you are solving the much easier problem "return the top k elements of an array in unsorted order". You can insert into an unordered list and increment a counter every time min-pop is called. Then the last step can be done with a basic quickselect. See https://www.cs.cmu.edu/~avrim/451f11/lectures/lect0908.pdf page 21, the "QuickSelect" algorithm. You need to do some small modifications to give you the "top k" elements rather than just the "kth" element. This gives expected linear time, and the note describes a deterministic algorithm that makes this worst-case linear time.
You can implement deterministic quick select using soft heaps, or instead you could also do a radix sort and then slice out the popped elements.
If the min-pop operation is required to return the popped element, then I believe you run into the sorting linear bound that prevents a deterministic O(n) solution. (Surprisingly, this indicates the hardness of the problem is not really in the last step, it's in implementing constant-time insert and pop). I can't think of an immediate solution off the top of my head, but I don't think a soft-heap provides the right guarantees here. I also don't know of a probabilistic data structure that provides both insert and min-pop in expected amortized constant time, and it seems that this could be an area of research. There are some better, but not quite linear results outside the comparison-based model (https://cs.stackexchange.com/questions/6455/an-efficient-dat...)
The min-pop is not supposed to return anything, yes. We are only interested in the final contents of the heap. So no sorting required. You can eg give the results of the whole operation as a bitmap over the inserts, so you need to return a linear number of bits.
Min-pops and inserts will in generally be interleaved. The prototypical example has blocks of 2 inserts and 1 pop repeated n times. (All other interleaving patterns can be reduced to this one in linear time.)
QuickSelect doesn't work for this.
QuickSelect or Median-of-Medians approaches work if you only have a small constant number of interleaved blocks (of any arbitrary internal length). Like eg all the inserts first then all the min-pops is equivalent to finding the k smallest elements.
The other points he mentions, beyond constant factors, are that algorithms with great theoretical characteristics tend to interact really poorly with gross real-world considerations like the memory hierarchy, and that worst-case performance is not average-case performance.
Exactly this. While the underlying theory is excellent on many of these theoretical algorithms, they typically don't perform as expected when taking into account the infinite complexities of the real-world.
But being able to understand the core value of the algorithm enables you to adapt or modify slightly in order to get it to work as needed in the real world.
In general just knowing that there are specialized algorithms for certain classes of problems is 80% of the expertise you gain over years of experience. Knowing that things like Bloom filters exist when you hit a problem that could be solved by this class of algorithm gets you much further than expertly memorizing any specific implementation of the algorithm. There are a variety of them depending on the actual use case you are looking to solve for.
> The other points he mentions, beyond constant factors, are that algorithms with great theoretical characteristics tend to interact really poorly with gross real-world considerations like the memory hierarchy, and that worst-case performance is not average-case performance.
I'd say _some_ algorithms and data structures with great theoretical characteristics tend that way. Just as many other work great in practice as well. You have to measure and benchmark.
I think one of the main takeaways of his post is that anything is survivable when n is small, and that the overhead required to spool up more robust data structures just isn't worth it for small n.
It's actually a bit ironic, because I consider Ferrari to build elegant cars while my old V8 Dodge is a triumph of brute force and ignorance. They're both great cars at opposite ends of the spectrum :-)
A variation on the sentiment I heard in a movie: "turbochargers are for wussies, real cars have cubic inches!"
The problem in the previous solution was that it took a while to keep the fancy datastructures updated. (It's a globally replicated distributed system..)
Due to the physical architecture of CPUs/etc., data structures that have "worse" asymptotic performance are often quite a bit faster than those with "better" performance. For example, iterating through a small array to find an item and test for existence is often quite a bit faster than using a hash set for the same operation.
In the same vein, pre-processing your data via sorting on some carefully chosen keys can sometimes alleviate the need for purpose built data structures.
And because of caches, sorting can sometimes beat hashtables.
Algorithms are all about eliminating waste effort. Not using programs invented by others to manipulate data structures. Those just happen to be solutions to some problem patterns.
A person good at algorithms is some one who can make things happen with least effort possible. Not some one who can invert trees, even more so when there is not need to invert a tree.
You can see how good some one is at algorithm stuff to see how much drudgery exists in the way they do work themselves.
I've learned approaches like this when I took a Operations Research class. I found it all exciting. We've also learned techniques to better choose between meta-heuristics like CGRASP, or flat algos, or integer programming, and so on. Now I'm seeing if I can think of some cool pet project where I can apply this stuff.
Oh, I also applied lots of linear and integer programming.
The main benefit of something like integer programming is that you get a clear separation of the specification of your solution and the algorithm that computes it.
When even smart people naively attack any kind of optimization (or selection) problem, the resulting approach often mixes the business logic for specifying the optimum solution and the code for finding that optimum.
That makes any change in business requirements very hard to implement.
I'm increasingly convinced that Algorithms-and-Data-Structure interviews are essentially being used as a proxy for:
- General IQ. Can this person understand and apply complex ideas
- Grit. Is this person hard-working enough to learn things that take time and effort
It's the software equivalent of the NFL scouting combine. The goal is not to create a test that is similar to the day-to-day job. But rather, create a test that isolates and evaluates a specific set of skills, which you think are important to the organization.
Unfortunately, those kinds of interviews also select for some other things that they shouldn't.
* Youth. People who have very recently studied these things in school, and use the same languages as the interviewers, have an advantage.
* Free time. People who have families (for example) might have less free time to study "Cracking the Code Interview" and such.
* Absence of anxiety. This disadvantages women, minorities, and people with psychological conditions that should be covered by ADA. Also, people whose financial situation is precarious will be more anxious than those who don't need the job, independent of which is actually a better candidate.
* Conformity. People who can recognize the flaws in a measurement technique, and who have the strength of character to push back against its application - both good qualities for a candidate - will self select out.
There's a lot of overlap among these, of course. There are better ways to measure "general IQ" and "grit" (which are both questionable concepts anyway). I've passed every such interview I've ever taken, but I refuse to administer them (despite the fact that my refusal has carried a quite tangible cost) because whatever benefit they provide is outweighed by their many flaws.
> Resistance to anxiety. This disadvantages women, minorities, and people with psychological conditions that should be covered by ADA.
I resemble some of those categories, and I don't know if I would feel comfortable making the leap to correlate them to a some inherent reduced level of resistance to anxiety. That seems like a generalization which I feel that, on an aggregate level, seems unsupportable by data.
I think that determination should be on a case-by-case basis, as is currently done at universities.
Allow me to elaborate, then. There's an inherent power dynamic in interviews, which creates stress in the interviewees. That effect is magnified for anyone who is unlike their interviewers, who still tend to be white and male. It's magnified still further when the power dynamic within the interview reflect the one that - very unfortunately - still persists in society at large. Lastly, the funny thing about stress/anxiety is that it tends to be additive. Having experienced high levels recently (including in other interviews) makes one more susceptible to new triggers. Thus, anyone who is the least bit "outside" in any way will feel more anxious.
Is any of that even controversial enough to require citation? How many Psychology or Sociology 101 textbooks should I cite? It's easy enough for those who don't feel this kind of anxiety themselves to brush it off, but for those who are less fortunate all those magnifiers can create an anxiety level that's quite debilitating.
I can see what you're saying (in good faith). I do think interview anxiety is a collocation of multiple factors. I don't think the correlation of anxiety to the listed categories are easily deconvolved from other factors -- it might seem like a common-sense correlation, especially if you start from certain priors, but it's a big assumption to make on average.
(Only this past week I had experiences that challenged my assumptions about certain demographics (seniors) and how I would expect they would behave, and how they actually behaved. The lesson I learned was -- don't assume, always collect real data)
The white-male interviewer power dynamic has some basis in reality (I've experienced it occasionally, not all the time), but its effect on my interview performance may be less than 10%? (to throw out a number). I find I'm much more affected -- maybe 90% -- about (1) my competence in the subject matter and (2) how well practiced I am (for instance, I know the theory for a great many subjects but am unpracticed at some of them, so I tend to stumble and lack ease when it comes to demonstrating my subject matter knowledge in real time).
For different people, those percentages shift, and I believe in a way that is not obviously or necessarily correlated with their demographic (psychological conditions, yes, but also depends on which ones -- some don't affect anxiety). But all I have is anecdata so I'm not able to provide strong evidence one way or another so this is just my two cents worth -- and I do mean this in good faith.
I appreciate your willingness to continue this conversation in a constructive way. So let me ask you a question. You say the white-male interviewer power dynamic might affect your interview performance by 10% or less. (Personally I'd pick an even lower number, but then I'm a white male myself and also old enough that I've been senior to most of my interviewers for a while now.) Would a 10% difference in interview performance be enough, on average, to affect who gets offers or what those offers are?
My basic point here is that even 1% would be too much. If an interview process creates any inherent disadvantage for some groups, I'd say it deserves serious scrutiny. BTW, by "inherent" I mean beyond what can be addressed by bias training and such. That can enable interviewers to conduct any type of interview in as fair and kind a way as possible, but not to change the interview structure itself. If the structure is the problem, training isn't the solution. I think the in-person white-board algorithm interview is unavoidably weighted toward factors that have nothing to do with likely on-the-job performance, and thus should be avoided.
I'm probably not the best person to gauge that in general, but I think the "inherent" part is where we differ.
Going back to whiteboarding: I don't like whiteboarding myself, but to be fair it does measure certain dimensions quickness-on-feet, memorization abilities, ability to exude presence, fluency in language, etc. While these are laudable abilities on their own, I agree they might not correlate with overall on-the-job performance (but it depends on the job).
I guess "job performance" is this amorphous latent variable y that is correlated with a bunch of direct predictors x which we can measure, u which we can't measure, so we use proxy variables z to stand-in for them: y = f(x, u, z).
The worry is that some candidates, who may be bad for the job, but just happen to be good at these proxy dimensions (or train for them) might get the job; on the flip side, we may exclude certain candidates who are potentially good for the job but perform badly at the proxy dimensions. Whiteboarding measures the proxy dimension z.
Edit: oh look, an article on HN's front page on this very issue:
>Is any of that even controversial enough to require citation?
I'm sorry, excuse me? Are you saying that non-minority, non-women don't suffer anxiety? Your parent comment certainly seems to suggest that. Which, at a minimum, is flat out wrong. Educate yourself[0]. And then zoom out and ask yourself why it's not only permissible, but often lauded, to so flippantly say what you just said.
> I'm sorry, excuse me? Are you saying that non-minority, non-women don't suffer anxiety?
To be fair, OP did say "That effect is magnified for anyone who is unlike their interviewers"
But, I do agree some evidence from OP would help their claims.
I wouldn't be surprised if minorities experience more anxiety, on average, in situations like an interview, though. I think it's established that imposter syndrome is more frequently encountered for example but it's too late here to go digging for evidence :)
Stop dehumanizing an entire group of people. All humans feel anxiety and that's a fact. Excluding one group of people that is equally likely to experience it because it's currently in vogue is still discriminatory.
Yeah I’ve never heard of women and minorities having less resistance to anxiety as a group. I’m curious where that’s coming from. Certain psychological conditions I could see, but that’s such a broad category that I think that’s also an over generalization.
I don’t know about “resistance to anxiety”, but it can certainly be anxiety-inducing to be the only member of a given minority in the interviewing room (or entire floor, as is sometimes the case in tech).
What if qualities you might judge in an interview other than “general IQ” and “grit” are even more bias-prone, and using those other qualities is actually worse than measuring “general IQ” and “grit” and applying a corrective factor?
In other words, I’d rather work with a disadvantaged person who may appear rough around the edges but made it this far and has the “general IQ” and “grit” to do well on the programming problem, than the preppy white kid who has a lifetime of experience preparing for the task of exuding status and competency when answering behavioral questions or engineering case studies, but lacks the “general IQ” and “grit” to solve the programming problem.
Just curious, what are some examples of better ways to measure general IQ and grit? You said they are questionable concepts, so how do _you_ interview people?
I don't, any more. I'm at a company that enforces a very rigid structure that I don't agree with, so I simply opt out. I pay for it every review cycle. Ironically, the rigidity of that structure is explicitly intended to reduce personal bias, which is a laudable goal, and I believe it succeeds. Unfortunately, I think it just replaces personal bias with systemic bias.
When I did interview, which was a lot at times when I was in a leadership role at a couple of startups, my favorite interview technique was to let the candidate lead and I'd follow. If I wanted to ask about algorithms, I'd ask about one they'd used in a project they'd worked on. How did it work? What were its strengths and pitfalls? What others were considered? What bugs were found in its implementation, or caused by its use? Besides flipping the control dynamic of the interview, it often led to more interesting conversations. Highly recommend.
> what are some examples of better ways to measure general IQ and grit
IQ has been under a shadow since _The Bell Curve_ and I'm not keen on letting it back out. ;) If one must measure it, I'd say measure it directly with simple challenges (e.g. memory or pattern completion) or puzzles ... but even those are apparently fraught with cultural baggage and of questionable relevance to a knowledge-heavy domain like programming.
As for grit, it's often readily apparent from someone's resume. Were they self-taught, worked through college, or took a free ride? Did they stay with companies and projects through hard times and get promoted "in the field" or were they always the first rat to abandon ship? It usually only takes a few questions to figure out whether someone's a coaster or a fighter. Funnily enough, the people with the most actual evidence of grit are the ones least likely to have spent their time studying specifically for the interview. They were busy actually doing stuff.
Algorithms and Data Structures don't measure either of those things. General IQ is not measured by very specific technical problems. Nor is learning something specific an indication of "grit".
IQ is a measure of mental flexibility independent of context. Being able to solve tricky algorithm problems is a measure of mental flexibility in the context of programming. The two are strongly correlated. Of course, the test is confounded by a baseline of programming and CS knowledge.
This is absolutely not true. I have seen amazing scientists and engineers get turned down by FAANG companies because they did not happen to study particular algorithms that were featured in that day's set of questions, and mediocre engineers fly through because they put in more time studying, or perhaps got lucky with the subset of technical questions that were asked.
I agree with the comment you were replying to. There will always be outliers, but testing prowess in technical problem solving and grit correlates well enough with the job of a software engineer.
The "amazing scientist" maybe was not a good culture fit, or, yes, the interview was botched.
Good candidates are so good that they often enough compensate for bad interviews. Sure it means we sometimes don't hire the best, but that's better IME than sometimes hiring a not so good candiate.
Yes, such tests are subject to a certain amount of gaming and prior knowledge. But that doesn't invalidate the fact that they are correlated with raw intelligence.
> General IQ is not measured by very specific technical problems.
I do not see data and algorithm interviews as very specific technical problems.
I do not have a computer science background, and have been able to bring myself up to speed to the general level expected without too much hassle.
I don't think I'm particularly special. I just searched and spent some time learning this stuff over a few weekends. If you are serious about a career, I don't really think that this is too much of an ask.
From my experience, when you have a big pool of candidates, the ones that pass not necessarily super stars, but they tend to perform at a relative stable level.
No, it is black and white. Just because you have lots of candidates doesn't mean you need to pick sub-par questions.
Interview for the skills you actually need. If the person isn't implementing algorithms and data structures from scratch, it's a shit question. Why would you ask questions that don't match the actual work they'll be doing?
If they will be doing this work, then obviously it's a fair question.
I disagree with that comment, based on my experience.
> Why would you ask questions that don't match the actual work they'll be doing?
As an interviewer, and likely peer or manager of the potential new hire, I want to understand growth potentials as well, so I want to challenge you during the interview. In my particular situation, there are so many candidates, and so many mediocre ones, we needed to raise the bar, and it served us well.
What? I'd go so far as to say this is universally incorrect. Having interviewed hundreds of people at multiple companies, at every level (intern to director), I have never been told what technical questions to ask....
> because if everyone is asking whatever they want there is no way to compare one candidate to another.
That's obviously not true....
> Most companies require interviewers to pick a question from their internal 'question bank'
Again, having worked at some fairly big and respected companies, this has never been the case.
I'm not interviewing for rote candidates. Everyone is different. Ergo, the questions are different. I could never imagine hiring senior developers and security engineers with questions from a "question bank".
If you're just doing boilerplate, you're probably getting very sub-par employees.
Please take a look at these. I recently interviewed at FB and I got 2 questions in phone screen that were from leetcode with FB tag.
> Everyone is different. Ergo, the questions are different.
Facebook is running interview factory, they just don't have time to customize interview for each candidate. Their own recruiter told me to practise questions from leetcode tagged with facebook.
I agree with you re your reasons for not using a 'question bank' but thats just not the realty.
Answering data structure/algorithm questions is absolutely meant as a measure of grit. It takes perhaps hundreds of hours of leetcode grinding to be able to quickly answer any problem which might come up in an interview. The point is to find out how committed applicants are.
I hear this so often that I wonder if people actually believe it. If you do, keep in mind that it would require a fairly large conspiracy within tech circles to maintain. A more likely explanation is that it's less effort to come up with and apply a leetcode-style question in an interview scenario.
Never attribute to malice that which is adequately explained by laziness and cargo-culting.
I'll disagree with this one. I'd actually be inclined to job-hop more frequently if I have the skill to pass hard interviews at any tier 1 company, thus maximizing my earnings.
If I don't, I just stay put knowing I lucked out at a great company, knowing it would be hard to get lucky again.
I had the opposite experience, once you grind problems on leetcode and figure them out yourself, you somehow never forget them, esp under pressure in an interview. The problems aren't exactly the same of course but like Polya's book "how to solve it" describes solving a problem by considering something similar you solved, when presented with some interview problem to work through the first things that came to my mind each time were previous silly leetcode solutions I came up with that bought me some time instead of blanking out.
If you're working on a large scale project you wouldn't be implementing a specific algorithm by yourself anyway. You'd be discussing a specific problem and then discussing the pros and cons of different algorithms that you want to implement and implementing POCs in different algorithms. The interview is just to see if you can think and discuss in terms of algorithms and data structures.
Technical interviews problems do sometimes actually resemble some discussions that happen in the real world however there are two major problems that I see in the interview space that don't have clear solutions:
1) one or two people in the discussion (interviewers) already know the perfect solution to the problem and are contributing as little as possible to the discussion.
2) the actual amount of allotted time to brainstorm a solution to the problem is realistically only ~10 minutes not the ~45 minutes you are allotted because of the time it takes to implement the solution with real code.
It would be nice if no one in the interview knew the answer to the problem before starting the discussion and this discussion would be pretty realistic aside from the lack of help from the interviewers. However, you cannot easily/fairly compare candidates with so many different questions.
Technical interviews would also be far more realistic if they allotted more time for problem solving but I imagine if the standard 45 minutes was bumped to over an hour, the only outcome is that more candidates would perform very well and that's not an outcome companies actually want unfortunately.
I'm completely in favor of randomized interview questions. My personal favorite approach is a two-way interview. You get to ask a technical interview question of the person you're interviewing with. If they ask you a ridiculous question, they get hit with a ridiculous question also. As an employer you could monitor this and see if you're employees are giving unfair questions to candidates they can't answer themselves. It would also be a good idea for HR to record all of these interviews so they can have someone knowledgeable judge the interview process and track the performance of new hires versus the questions they are asking. If the interviewer starts having problems answering their own difficulty level in questions then maybe they should be looking for a new job also. I was once asked a ridiculous question and threw an interviewer off by asking them how many times they had actually implemented something like they were asking, they stopped talking immediately.
My personal opinion is that all of this should be scrapped in favor of seeing what the person has produced and having them partially implement a solution of something they have written in the past. It is a virtual impossibility that anyone could work on a project of any sort without being able to sit down for an 8 hour interview where they are responsible for partially re-creating something they have worked on in the past. To this day I still remember large parts of source code I've worked on 10 years in the past.
Pick up a neuroscience book and you're going to quickly find out why your statement isn't possible. Have you ever had to conduct tech interviews or spoken to people who have? Tech interviews are the biggest crapshoot you'll ever see, for every 100 interviews you'll be lucky to find a single person who can code fizz buzz on the fly, introduce a small variation in fizz buzz that requires them to be able to read their own code and they can't modify their own code. The number of people who have a long enough short term memory and can concentrate on a single thing for three hours straight is exceedingly small.
Even the very best tech companies are constantly filtering through thousands of people who claim to have worked on extremely complicated development projects but can't code extremely simple things.
Yeah larger desirable companies already have no shortage of well performing candidates to choose from so why make the interview more fair in any way? That would just make selection more difficult for them. Smaller companies might not have this issue but will probably follow the practices of larger, more successful companies anyway.
I'll get myself some down voting here... I kind of like asking questions about data structures and algorithms. I don't see them as simple black and white questions though. I see several values: 1) If you're a "computer science" degreed person, I expect basic understanding of basic algorithms and data structures. As for your basic job stuff, things like Java have multiple implementations of maps or hash tables you should have some idea when to pick one vs the other. I don't think that's off limits. 2) I like to ask a couple challenges or questions that sort of make the interviewee a little uncomfortable, not to get the answer but to work with them on it and see how they work through that situation. I intentionally try not to be cruel but I want them to think, I want to communicate with them as they sort through it, I want to see how that stuff goes. I've had 60+ minute conversations about engineering a professional grade hash table and the different things you have to consider, that's good stuff. The 3rd thing, and this is maybe more subtle, there is a gigantic difference between implementing quick sort and qsort in glibc, the same can be said about most algorithms and data structures and I think at least a cursory knowledge of that is an indication of some wisdom. Should you be asked to implement data structure x or classical algorithm y, understanding the mechanics beyond simply copying it out of a text book indicates some wisdom.
After a grueling interview process at Goldman Sachs, with 7+ technical interviews that required me to solve very specific questions on college-level Maths, Stats and Computer Science (admittedly, I was applying for a quant job position), I was eventually asked to interview candidates myself. While I did not feel entitled to change the current interviewing culture at the company by asking questions of a completely different nature from what I got asked in the first place, I conducted my interviews in a very similar way to what you described. By no means did I expect applicants to reach a definitive answer, but I instead worked on the problems with them to see how far their intelligence, creativity, curiosity and, most importantly, their ability to well communicate their thought process would take them.
Such interviews used to take a while hour of my time (which is a lot to afford when you work in a bank), but by the end of each I believed to confidently ascertain the candidate’s ability to thrive on our team. In retrospect, it has served me really well.
All in all, the problems posed (and the solutions given to them) might not carry as much weight in the final decision as the discussion held with the applicants. As long as the questions asked give them some material to work on, and DS and algorithms usually serve this purpose very well for us engineers and developers in general, one should be able to effectively select candidates given some time investment.
The problem for me is do I want to spend my time and effort learning solutions to leetcode problems or do I want to spend time and effort learning actual development skills? Which would be more valuable in the long run? Every hour you have to spend on leetcode just to be able to pass some arbitrary measure of your leetcode ability is one less hour you can spend on learning something else.
I suspect there are better IQ tests than random algorithms questions.
Isn’t the nfl scouting combine bullshit though? The players who tend to be most favoured are those who did well at playing football in the previous season, rather than those who scored well on the IQ or creative writing or jumping tests
This is correct. It's unfortunate, but unless you can mandate Google to change their entire interviewing regime, you have to simply understand that this is the perspective, and move forward demonstrating yourself against this criteria, whatever else you may think.
remember, players opt out of the combine. and a good portion do, if they have a dope highlight reel. though they will conduct interviews with the gm for personality what we call in the tech field: "cultural fit"
There's a huge distinction between "used" and "implemented myself".
I've used quite a lot of features from RDBMs, as well as topological sorting, LRU for caches, Unicode normalization, graph traversal, bloom filters, hash maps and so on.
I'm not payed to implement algorithms or data structures, but to solve problems. So for anything non-trivial I tend to use ready-made libraries.
I only implement stuff myself when it's faster and simpler to implement AND TEST it than to draw in another dependency, or if there isn't a well-made off-the-shelf component.
So what I've implemented myself at $work is pretty limited:
* depth-first tree traversal
* graph traversal
* parsers for various non-standard file formats
* maybe a topological sort once, not sure
Finally, many classical algorithms have lesser-known variants that optimize for some practical advantages (reduced memory usage, memory cache friendliness, sequential disk reads/writes etc.). So if I were to implement, say, a substring search, it might not be a by-the-book Boyer-Moore algorithm, but some subsequent paper that builds on it to add a few percent practical performance improvement.
You still have to understand how things are implemented by others (even at a high level view: ex: what is a RDBMS index) to be aware of their advantages and drawbacks to make the best use of algorithms available to achieve your goals (ex: performance of the solution, ease of evolution of the solution).
I agree. It's good to know a name of an algorithm/data structure, and rough characteristics (like bloom filter: O(1) lookup, super memory compact, statistical, can have false positives, no false negatives; perfect for caching lookups in "forbidden" lists).
There's not much point though in knowning the minutiae to the level that you can code one on the whiteboard without prior preparation -- which is probably the main point that the article relates to.
And this is the measure of a good engineer -- recognizing that it's most likely that battle tested libraries will have superior implementations of algorithms than whatever one can draw up oneself.
I use the STL daily. I know fairly well the complexity guarantees behind each data structure. That's one of the things I like about it versus other collections libraries. It forces you to be somewhat literate on data structures in order to make the right choices.
But no, I could not write you up a red-black tree from scratch without going away for a few days with my Knuth books and a few pots of coffee. Sorry.
It's like in any competitive exam where there are too many candidates and not enough positions. If you ever look at the type of math and science problems on Chinese university exams they are not necessarily advance in terms of the topic but they are extremely tricky. A electromagnetism question testing your knowledge of Gauss' law usually in a regular setting would use a charged sphere or some other object with geometric symmetry you can take advantage of. I have seen one question where it involved Gauss' law around the corner of a pipe (the elbow part).
It's just an exercise to see "how badly does this guy want it? how much did you cram?" Like hazing.
As an anecdotal story, I once interviewed at a well known HFT in Manhattan, after jumping through the phone screen and timed coding interview (involving four questions), you were invited on site. The first thing you do on-site (10 am in the morning) is take a 2 hour multiple choice exam consisting of 100 questions and get this - it was literally on scantron card, so they can score it right away (exactly how I used to multiple choice exams in high school).
If they didn't like your score, you were sent packing right away, otherwise the real interviews would begin with actual people throughout the afternoon. Allegedly, the way you knew this was, if you they asked you what you wanted to lunch, that meant you passed and could go to the one-on-one interviews.
I didn't get the job in the end, but I did get a ham sandwich and soda out of the deal.
> too many candidates and not enough positions.
so sad, some of these smart and talented engineers will take the failure personally. The system needs to change, the only way we can progress is to not waste talent like this. We cannot rely on a small set of institutions (Harvard, Oxford, IIT etc) to output a small group of "elite" engineers, surely the world would be better if everybody that wanted to become an engineer had access to "elite" level education. Top companies have one major complaint: not enough engineers.
Bootcamps don't help either, what you want is that "elite" education with a bootcamp price, possibly many bootcamps over time, as skill sets need to adapt and grow.
This article is hurting its credibility right from the get-go by un-critically reproducing yet again this tired saw from Max Howell:
> Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.
First, it's not remotely true that 90% of Google engineers use Homebrew, seeing as how almost all development is done on Linux (Max Howell is unjustifiably full of himself here). And secondly, he doesn't know why he wasn't hired, but it may well be because of the entitled attitude on display here rather than any coding shortcomings. No one wants to work with pompous rockstars. They may be fine for developing one-person projects out in the wild but they don't work well on team projects at large companies.
If you go into an interview with the attitude that the problems you're being asked to solve are beneath you and that you just flat-out deserve the job without having to prove yourself, your success rate is gonna be poor. To a big corporation, almost no one is as big of a deal as they might think they are, unless they hold a Turing Award or similar.
Most Googler SWEs have Mac laptops, not linux or windows laptops. But only a fraction of them use brew to install additional software.
I'd love to interview the creator of homebrew. There are so many dependency and reliabiltiy questions that it's clear brew doesn't handle well (same criticism of CPAN, and pip to some degree) in terms of performance or correctness that you could just talk for an hour about graph problems... who knows, something like... inverting a binary tree?
Someone told me they did all their development in the cloud and you aren't allowed to check out software locally? Does that mean they just use their macs as thin terminals? But what's running in the cloud for development then? Linux X desktops, or do you edit in a browser, or do you develop entirely in a console over SSH?
Nobody seems to talk about the developer experience at Google that I've seen, despite how much they talk about how they do operations and site reliability.
Many googlers work on the centralized google3 source tree where the source lives in the cloud and your workstation is mostly a frontend for editing a FUSE view (citc): https://cacm.acm.org/magazines/2016/7/204032-why-google-stor... among other documentation gives some details on the process.
Typically that work will be done on a workstation at your desktop. But if you want to work remotely, and you can't access citc from your laptop. So, you'd ssh into your workstation, or use Chrome Remote Desktop (personally, I ssh from a ChromeOS laptop to a glinux workstation with tmux). Others use CRD for a full remote desktop. At that point the dev experience is mostly what like other people experience, except that the source and build and test environments are in the cloud, rather than on your local machine.
That just describes one common case- devs and researchers writing stuff that runs on Google's internal resource management system, borg. There are many other teams, who have their own standards and approaches, which don't use the technology I described abvove. I'm sure there are plenty of devs at Google who actually build directly on their laptop, and commit code to open source repos without ever touching citc, or google3.
For me at least, the dev experience at Google feels like every other dev job I've had: ssh to a LINUX machine, write code, compile it, run tests, send it for review, submit. A lot of people who are C++ server developers and python client developers could drop into the Google environment and quickly be productive.
A lot of this is documented in external talks but it takes a ton of work to assemble all of it.
Googlers tend to use their Mac laptops as glorified remote desktop terminals, because they aren't allowed to so much as check out code to portable computers that can leave the office.
It's a running joke that $2k top-of-the-line Apple laptops are being used as remote desktop terminals when much cheaper hardware would be perfectly sufficient.
I replaced my MacBook Pro with a Google Pixelbook since indeed my work is all remote and I don't really like MacBooks. I've previously tried high end Dell laptop (the most amazing laptop I've ever used, it had a high end nvidia GPU and you could train models on an airplane) and ended up with this device.
I wish it was slightly larger with better specs and more ports, only because I spend a lot of time in video chat and there isn't enough CPU oomph to do video chat and Google docs on an external display.
I get what you mean, but I think this can be looked at in a more neutral way, especially if we distance ourselves from the exact Homebrew example.
The expectation of a large engineering company is to hire someone who fits well into their way of doing things. Typically they want smart, humble team-players with predictable skills (AKA solid educational background and possibly industry experience).
However an open source tool author has completely different self-imposed requirements and capabilities. If successful, they have proven that they can ship reliable software, basically on their own, which people want to use. Which is great, exceptional even. But typically not in terms of the metrics of a large engineering company, except they actually do use the tool/library, deem it important and the role of the programmer would involve developing/supporting it.
This also poses the question of: "Why would open source author want to get hired by big company in the first place?"
Wouldn't this mismatch of expectations and skill-sets be a hindrance/waste?
Aren't there much better places for this exceptional open source author? Startups, other open source projects, self-employment/freelancing, SMEs etc.
Thought experiment: If one were to make a very simple yet popular program, for what reason would that entitle them to a job somewhere? I'm having trouble thinking of one.
I think people forget how incredibly high the Google hiring bar is. Tons of people have written extremely successful software, but I think you really need to be at the very top of your field to even be considering going to Google. You can be absolutely excellent... and still not be good enough for Google, and it's fine to admit that.
I've known too many people who work at Google to agree with this. They've hired some people who were just plain incompetent, some who were great, but mostly in the middle, much like every other company.
TBF, they do seem to have more than their share of great, but, not by a lot...
I recently had an A-ha moment when I realized that the problem I was trying to solve admitted a simple solution with dynamic programming, something I had never used outside programming competitions.
The problem was to divide a text into a number of tweets to make it a thread, with the obvious constraint that no tweet should have more than 280 characters, but you still wanted to minimize some cost based on how far your tweets were from 280 chars and where you divided them (e.g., dividing after a full stop is better than after a comma, which is better than between two works, which is way better than midword).
With a reasonable cost function, this really seems a textbook dynamic programming example (possibly much more credible than the entering-a-treasure-cave-with-a-rucksack story).
Yes, dynamic programming is how I implemented line wrapping for (the help text in) SingStar PS3 also.
Good spotting BTW, the line wrapping algorithm (where each tweet is a "line") is a perfect match for the post you are responding to.
When doing programming competitions, you're often trying to figure out what standard algorithm is similar to the problem and how you need to tweak it to match.
(Apologies to people on mobile for the following...)
One of the things I miss about Usenet was that
nearly everyone read it with a fixed with font
so that if you choose your phrasing well so as
to make your text come out naturally perfectly
justified, it would come out that way for them
too.
English has so many synonyms and near-synonyms
for every word, and so much flexibility in the
ordering of words that you can write like this
in near real time.
You get to the end of a line, find that you're
just a little long or short, and you backtrack
just a couple words or so most of the time and
you can usually find a way that works. In this
paragraph, for instance, I was one too long in
the first line, but contracting "you are" down
to "you're" fixed it. I was short in that last
sentence, but inserting "down" fixed it.
Perfect justification by inserting extra space
is for amateurs.
Now we've got all fancy and use variable width
fonts and automatic wrapping and posting isn't
quite as fun anymore.
Give it a try. Use an editor with a fixed font
to compose your next post and try to get it to
come out perfectly justified without having to
insert extra spaces. When you paste it into HN
that will get lost, but the composing can be a
fun little English puzzle.
I read at one point that the typesetters at the New Yorker would work with the copy editors to fix cases of bad justification (huge word space, awkward hyphen). It's rare to see that kind of care, but automatic algorithms are getting better.
On topic to the original post, I implemented Knuth-style line breaking in the Android text stack (working with Anish Athalye who was an intern at the time and did the first prototype). There were a bunch of nicely tuned implementations of advanced data structures and algorithms in there.
I still say it is a bad interview question, but there were lots of interesting examples I learned about.
- GCC splitting IA-64 instructions
- Trellis quantization in lossy video encoding
- Knuth-Plass line breaking algorithm (mentioned here too)
- Some algorithms I knew about, but which can be considered dynamic programming (I'm not sure how interesting this is): A* search, Dijikstra's shortest path, Myers common subsequence algorithm, transitive closure algorithm
I would say the GCC one is most interesting because there's a link to the actual code and comments by the developer.
CPUs have some number of individual units that do different things. You'll have a few ALUs that can do stuff like adding, subtracting, xor, and, etc. You'll have some number of units that do floating point math. You'll have a shift unit to do bitshifts. In ye olden days, the CPU would only do one thing at a time, while the rest of the CPU sat idle.
x86-64 (and most other architectures) can use multiple units at the same time using what's called a superscalar architecture. There's a hardware unit that figures out what units are in use and what instruction just arrived, and can either send the instruction to ALU0 if it's unused, or ALU1 if ALU0 is in use, etc.
But this hardware unit that does scheduling is complex, it takes up space that could be used by other stuff. IA64 aka Itanium, not to be confused with x86-64, is a VLIW (very long instruction word) architecture. The underlying assumption is that the compiler knows in advance what operations it's already emitted, and what operations are coming next, and the compiler can be considerably more complex than the hardware scheduler does. So a VLIW instruction isn't just "add eax,ebx" like x86, it's more like "ALU0: add r12,r48; ALU1: add r93,r42; SHIFT: r60,12; MEM: load r17,r32". (Itanium had 128 registers) The compiler had to do a bunch of stuff that modern CPUs do in hardware. I think it even had to deconflict instructions; like the compiler had to know that an addition takes 3 clock cycles or whatever, so if you used ALU0 on cycle 123772 and then tried to use ALU0 again on 123774 something bad would happen, but don't quote me on that.
So at some point the compiler is going to have a DAG of operations that need to get run in a block, and it needs to bundle up those individual operations into bundles of (I think) 4. Sounds dynamic programmy to me. At least I think that's what's going on.
It turns out that most code is pretty branchy, which means many lines of code will have multiple entry points. This invalidates the assumption that the compiler knows what operation it just executed. So in practice, VLIW architectures aren't able to achieve their theoretical performance, and superscalar architectures are better.
Sorry I don't have the full context. It seems like some kind of pattern matching over instructions to put them in bundles.
I think it could be one of those cases where if you had a more obvious representation you wouldn't need a clever algorithm, but there is probably some other reason (good or not) that instructions are represented that way
I don't think the issue is DS&A or even leetcode problems in general.
I think the problem is being expected to regurgitate* 1-2 hyperoptimal leetcode solutions in 45 minutes while suffering from heavy interview pressure.
*by regurgitate, you can't simply implement the optimal solution either even if you know it. You have to put on a show where it seems like you're arriving at and iterating towards the optimal solution, "explaining your thought processes". But you can't waste time iterating and going down suboptimal paths either because you only have 45 minutes or less. Hence why ideally you know the exact optimal solution beforehand, or at least know the tricks and patterns to quickly get to the optimal solution for the type of problem you are tackling.
Recruiters and official interview guides say that your "thought processes" matter a lot, but reports from in the field tend to imply that the #1 most important factor is that you get the optimal solution. If you can't, your "thought processes" are worth little, barring exceptional circumstances.
"These two guys spent 6 months thinking about this problem to come up with this algorithm. Now pretend like you can independently come up with an identical algorithm in 45 minutes."
Here's an algorithm some elite CS PhD took a year to research and solve. You haven't seen it before? Too bad, better come up with the solution on the spot. If you can't I'll have to write another blog post about how no one I interview can program anymore?!?
> Recruiters and official interview guides say that your "thought processes" matter a lot, but reports from in the field tend to imply that the #1 most important factor is that you get the optimal solution. If you can't, your "thought processes" are worth little, barring exceptional circumstances
Agree. Also "there is no hard requirement in completing both part of the exercise" is another lie.
It’s an interesting question why we focus so much on algorithms that are mostly not used on a day to day basis, but the topic of persistence that’s everywhere and which is often only partially understood is far from being this prominent.
I remember a stint in research, about data analytic non the less, where rarely anyone had a good grasp of SQL or any other way to persist data for that matter. It really puzzles me to this day.
Might be me finding most ORMs to be harmful if used without understanding of the underlying technologies.
Let's say someone can solve the algo problem, what's that show?
Mostly that they prepared for an algorithms question.
It may be a good filter for 3rd-wave do-as-you're told programmers who stay in their lanes, produce by the book expected code, and just consistently obediently build things.
They wan better cogs for the corporate software machine.
If people are asking me algo questions, the job probably isn't right for me because my answer is "it depends". Last time I took one I was thinking "there's like 4 answer to this, what the fuck do you want?" it might as well have been "I'm thinking of a color" ... they have something written down and called it the "right" answer.
I gave a parallelizable answer, they wanted single threaded. I gave a single threaded one, they wanted 2 passes. I gave them a 2 pass version, they wanted one that didn't use collections.deque, I mean it was nonsense. "Guess what's on my piece of paper!" Cool beans bro.
Some people would have given them that answer the first time, I'm sure of it. Not me though. Not during the interview, not during the day-to-day.
I don't know how. I really don't. I don't know the right answers, all I see are a bunch of possibilities. That's why I'm first-wave.
The writer of homebrew isn't what Google is looking for anymore. His time to get hired there closed around 15 years ago. After the revolutionaries comes the administrators, a far less interesting but necessary entourage.
The people like me have all already quit. I've actually got nothing to offer them.
Not at all. it's a different kind of job for a different kind of person.
Fabrice Bellard, Ted Nelson, Theo de Raadt, Patrick Volkerding, Richard Stallman, Larry Wall, these people aren't off working at stable ibm-like firms. It's a different kind of thing. Look at Nelson's fiery career crash when he worked at Autodesk. Look at Woz and Paul Allen walking away or Bushnell getting rid of Atari. This isn't the grab-and-dash modern unicorn stuff, these people saw it wasn't right for them. The company outgrew them.
They couldn't do the job. That's not where they fit.
Chefs make terrible bus boys and bus boys make terrible chefs.
That's the big important lesson: The Chef is incapable of being a bus boy.
It's not "too easy for her" and she's not "too smart for it". The chef can't consistently, reliably, and efficiently do the tasks. The hierarchy is illusory, it's all about fit.
Drucker explains this better than I ever could. He's a good read
If so, they're pushing "conformity" and "being a good cog in the machine" well past the point of cargo cult programming. That's what this algorithm-based interviewing is all about: a textbook cargo cult. And people wonder why they aren't seeing quality.
I'm not so sure. Maintaining and building an empire are dramatically different.
Companies that could build and not maintain: Lotus, Digital Research, Palm, Netscape, MySpace, Digg, Blackberry, Ashton Tate, it's a different set of skills. Heck, you can even toss the French Jacobins in there
They all shot themselves in the foot, I know, that's the point. Not having their eye on the ball and instead looking over the horizon is what built the empire, but then the ball hit their nose
Some people can do both (gates, zuck, bezos), but once you're at the Apple/Microsoft stage, you need the second group.
Whenever I interview engineers, my main priority, beyond grasping whether they understand the stack they’ll be working with, is gauging how well they can work in an organization of fellow engineers, designers, and product folks to deliver a product and support the larger engineering team.
If they can pass that hurdle, you can almost be certain they know how and when crack open an algorithms textbook or use Google-fu to apply the right algorithm to solve a given problem.
(Knowing which data structures to reach for is far more applicable than being able to apply algorithms from memory. The article is good evidence of that.)
I internally have something I call the "scramble score". If I hire someone to say, do some python backend and then a few weeks in I'm like "oh shit, actually this big deal we're doing needs us to get an iphone app together" and I can be like "hey, can you go from python backend to do an iphone app?" and a week or so later I'd have a basic app.
Those people do exist. Really, they think it's a thrilling joyride. Hard to find, but they're real. I look for those and run the team tight and small.
What does this have to do with the bulk of the article (which is about algorithms the author used at his jobs, and only tangentially (IMO) about the use of algorithmic questions in interviews)?
It has to do with the rest of the comments in this thread
at the time I posted it ... I was replying to that sentiment.
The vast majority of algorithms I use are for parallelizing complex workloads, failure detection, and scoring systems. I usually DIY after I find the OTS ones unsatisfactory.
I'm not "smarter", they're general solutions but all I seem to have in life are specific problems so specific solutions perform better.
This article is an excellent example of why most companies should never ask about algorithms in an interview. The author has worked for elite companies and yet even there he rarely had to reach something advanced. I've worked on some cool and really hard stuff in my career including cryptography and a popular Facebook app where my team used a graphdb, etc, etc, etc. And I would fail at most of today's interviews. Fortunately I'm often the one doing the interviews so I rarely have to endure this nonsense. If you ask me algorithm questions on an interview and you're not the equivalent of Google or Facebook in their early years then I'll find a way to end the interview early and you just lost the opportunity to work with a talented dev. Get some training in interviewing. Do the research on best practice. Create the type of interview that gets people talking enough about past work that you learn what they are actually good at. It's not really that hard to figure out how to create an effective interviewing process for the types of problems your company is solving. It's surprising at just how many otherwise smart people fail at creating that.
I call this distinction red flag versus green flag interviews. The typical hiring process is looking to quickly disqualify all but 1 person in the hundreds of resumes submitted to any open software engineering position. The hiring process you are proposing is looking to methodically search for all of the useful qualities in the candidate pool and determine how they can best be applied at the company.
I think we can all agree someone can be a poor software engineer and not have any red flags.
That's a useful mental model. It took me a while to reply because I was trying to get enough clarity on why my process works to put it into words. I use red flags in my hiring process. There are many when it comes to whether or not someone is a good engineer. Inability to do algorithms on a whiteboard is not one of them. I do try to prove my red flags wrong which is what sometimes reveals a diamond in the rough.
> The hiring process you are proposing is looking to methodically search for all of the useful qualities in the candidate pool and determine how they can best be applied at the company.
That's not necessarily what I'm proposing. I often need find the first qualified candidate who can start contributing. Don't let perfect be the enemy of good.
One of the ways I accomplish cost effective hiring is to go through applications in the order they arrive and the first candidate who passes the interview gets the job. If I get 200 applications and I find a suitable candidate in the 1st interview, why would I waste my time and money doing the other 199 interviews?
I sometimes even use recruiters when my time is at a premium. And that raises another interesting question: how is it that so many recruiters who can't code have been able to send me top quality candidates so consistently? Which leads me right back to my first point in this thread: this article is an excellent example of why most companies should never ask about algorithms in an interview.
> I think we can all agree someone can be a poor software engineer and not have any red flags.
This has been something I find myself musing over every now and then for a couple years now. As we begin to relax barriers of entry, how do we maintain that some people fail/lose?
I'm curious what makes you think we are relaxing barriers to entry? The senior engineers I've hired are highly productive. And diverse. My process does not have a low barrier to entry. The goal is to use more accurate signals. Instead of hiring people who are good at talking about algorithms at a white board I want to hire good software engineers.
> some people fail / lose
This comes off as a condescending way of thinking about the hiring process. Even if the candidate is not qualified for the position I want to leave them feeling like I helped them a little in their career or at the very least in their interviewing skills and confidence. You can find a good fit for a role without leaving the other candidates feeling like they failed. And I think that starts to get to the crux of the problem at some companies : the process is meant to boost the ego of the interviewer. Almost every senior dev has a few stories about how the interviewer just wanted to feel superior. We can do far better than that.
In a business, you are either don't hire them in the beginning or fire them in the end. Not everyone should be a software engineer (where would the users come from?). A large labor market organizes people into better jobs when they are passed over for or fired from a position.
I had interviewers grill me about the time complexity of dictionary implementations in python while making assumptions about their behaviour from Java.
I was impressed by the fact that nobody ever tried to argue with them before.
Basically they were hiring for a Python position and I know that part of the test is the same for everyone. Yet they didn’t know about open addressing.
Thank you. I've been poking around the job market again after 10 years not searching, and it's disheartening. I have 20 years software development experience, I work at Google, I'm no spring chicken. I'm not the best engineer in the world, I'm sure, but I am a good programmer. I think I'd be an asset in many jobs. But I just turned down proceeding with interviews at a certain payment processing company because in part they wanted to give this kind of whiteboard coding interview. Our industry needs to give its head a shake.
When everyone else has gone through the pain of such an interview process, they are emotionally and ego-wise invested in believing in its efficacy. They have to apply it consistently, and they mostly have to believe it proves something about the intelligence of the successful applicant.
Last I looked we are still in a market where there is supposedly more open positions than there are engineers to fill them.
So why are firms that are hiring so obsessed with producing more and more arcane barriers to entry?
As I always comment when this topic comes up: this process makes some sense at Google (where I work) where the sheer number of applicants is massive and false-negatives are perfectly fine because the potential applicant pool is so large. But at smaller companies, who can't pay Google compensation and feed you gourmet food, blah blah blah? And where your job will be mainly writing some JavaScript to drive web pages? Really?
I work around embedded stuff and spend a lot of time in low-level code, and I _still_ don't get to spend a lot of time writing algorithm and data structure heavy code. I actually really enjoy doing that kind of work, but on my own time, at my desk, with my headphones on, and some books and resources to reference as I'm doing it. This is how engineering / authoring / writing is classically done, by the way. Calmly, often solitary, and with space to gather thoughts and do trial and error.
Why should I be selected or deselected based on my ability to perform this activity in front of people in a high pressure situation? Often someone 15 years younger than me, fresh out of a CS program, and with a pile of hubris that goes with that?
For what it's worth I'm self-educated, not a CS grad, but got into this because it's what I like to do and spent many years privately studying on my own to get here.
FWIW I just this morning turned down a potential job opportunity because this is the interview process they wanted.
Take an interviewer who has the benefit of having worked through a problem literally a hundred times, further aided by internal training that represents thousands of iterations. Have them judge someone who hasn't had to solve that particular problem more than once or twice, twenty years ago in a different language (and certainly not on a whiteboard). That interviewer will form an inaccurate opinion of the interviewee's relative ability. Not maybe, and not by a little. Any interview process that does nothing to correct for that is broken.
As an average/below average engineer with 15 yoe who wouldn't pass SV-style interviews no matter how many leetcode problems I solve, I've only had to use algorithms a handful of times in my career.
One of the most memorable was when I had to build a graph from sql statements, parse the sql statements, determine the dependencies between the sql statements by traversing the syntax tree and ordering the graph based on the dependencies so sql statements on each level could be evaluated in parallel.
It was one of the most fun and interesting projects I've ever worked on, it took me a few days to come up with a Java implementation and after a few bugs I rewrote it in Scala. I think I ended up with some kind of DFS algorithm if I recall, I might give it a shot at implementing it from memory and putting it on github.
I once coded a function to calculate edit distance. It was the algorithmic highlight of my career :)
But the general understanding of algorithms and complexity did help even in CRUD apps. It gives the bricks to form mental model of the underlying system. I don't need to code a b-tree but I may need to tweak its params.
I had a similar problem once and being an atypical programmer and did not know the term edit distance.
Some research gave me Levenshtein distance and from there I first used a naive perl implementation before finding that you could extend MySQL and found an example and implemented that.
Took me 1/2 a day to go from zero to working prototype
I think they're useful to know. I don't mind algorithms and data structure questions in interviews. I use them a fair bit even in some of my most benign, enterprise JSON-schlepping tasks.
Indexes come up a bit. I've seen many junior engineers struggle when performance problems crop up over time. If they don't have a familiarity with data structures and algorithms their "fixes" never seem to work and they get frustrated. I enjoy taking the time to show them how indexes can speed up search and when they don't give you much benefit. At small companies getting off the ground I think it's less important to hire people for their algorithms/data-structures knowledge.
At companies where the teams are working on high-performance or large scale problems it's quite essential. Being able to shave down build times, as in the article, is a big deal. Knowing how to scale a large problem is a big deal when the quality of the service depends on it.
There are also some problems that require it. I'm building a key-value data store as one of my side projects and it definitely requires knowledge of data structures and algorithms. You can't even implement one efficiently without such knowledge!
So I guess it depends on how much your team actually works with these concepts. If your hiring process is keeping the bar high but all you do is schlep JSON from one bucket to another you're missing out on a lot of good candidates for no good reason. If you're building networking products or databases then yeah, keep the bar high.
But within reason. I agree with the OP -- the need for exotic structures and algorithms is so rare that it's not a terribly good indicator of anything to use them in an interview unless you're looking for researchers.
I don't like algorithms as an interview structure but I do think they have one property that people way underestimate. Algorithms test your ability to manipulate a complex problem in your head without being able to break it down.
Most coding problems can be broken apart and the individual components tackled one by one. But that has two problems. One, it doesn't stress-test the programmer. Two, the most beneficial changes to a codebase come from a high-level understanding of the system. Implementation might be segmented, but the more of the system you can simultaneously understand & manipulate in your head, the better placed you are to manipulate the architecture.
Complex algo questions force you to manipulate a fundamentally complex problem. You can break it apart in some ways, but in general you have to be able to think about the entire basic algorithm in your head. Reversing a binary tree? You have to be able to visualise the datastructure you're manipulating and figure out what changes you need to make before you start writing. It's a stress test, it tests horsepower.
Granted, you can game that system by doing practice questions which undermines it to an enormous degree but I'm not sure what else you can do to test that.
The problem I have with algorithms is I can get good at them if I practice them all the time - basically like I did at university 20 years ago. I have barely used them in real jobs since, so while I write far better (more readable maintainable, performant) code now, I am far worse at answering this stuff in an interview.
Also a number of times I haven't got an answer in an interview only for something to pop into my head ten minutes out of the door (or a far more elegant solution came to me). You might as well toss a coin and save me the hassle.
When I was at Microsoft, we used data structures quite often in our service that powered Azure Frontdoor / Azure CDN.
Some of the stuff I personally worked on was tries and nested tries for routing/cache purge, LRU & variants for the caching algorithm on a cache node, and I implemented consistent hashing for the distributed cache.
There were some algorithms stuff for load balancing, but I didn't work on that.
I know there was a few other things, but I can't remember them right now.
Working primarily on autonomous systems from robotics to avionics I have needed to use quite a few data structures and algorithms including:
- Space partitioning such as octrees
- Finite-state machines
- Behaviour trees (I much prefer to state machines)
- Too many machine learning and deep learning algorithms to list
I have also had to come up with boutique solutions to a number of problems. Even though I have never failed to deliver a solution in the real world I doubt I would pass any sort of algorithm interview without significant study. I don't rote memorize things and only (quickly) learn what is relevant when it is required to solve a problem. Unfortunately I also do not know of any quick way to test for that sort of ability that would be suitable for an interview.
A good wood worker tends to know the tools of the trades and more importantly know when to not use a tool and when to invent a new one.. That said not every cabinet is a work of art some are just there to be functional for long enough to justify their creation.
I feel system interviews that dive deep about decisions and insights are far more useful than hitting a leetcode jackpot. Though it puts a high bar on the interviewer as well.
In the sense of going from rocks to iron to steel to finished tool, no, but otherwise, yes. Making specialised saws, scrapers, chisels, spokeshaves, planes and so forth are part of the luthier's, cabinetmaker's, and shipwright's existence. And that's just the tools, leaving workholding aside. Add in jigs and fixtures and there's a whole lot more. Not everything you need to do the job can be had off the shelf.
I have been tracking luthiers and it is fascinating how detailed and varied each builder is.. the likelihood that the instrument will sound good is well correlated to how much time the luthier puts into refining his process.
I don’t understand the rational for not wanting to learn DS/Algos this is just one part of it, there is also the whole business/customer side of writing code. There is a difference between never getting a demanding customer who understands the difference between a good instrument and something glued together and not wanting to know how to do something more than glueing it together is appalling. As a coder if you want to learn DS/Algos and you do not find a job the values that maybe there is more to learn so that find a job that values it. It will be competitive and you can fail but it is not wasted.
It leaves out framing carpenters, basically. I could have added patternmakers, timber fitters and so on, but there comes a time when adding to the list just for the sake of adding to the list becomes tedious. I, personally, have never been more than a hobbyist, but I've made my own tools both for woodworking and metalworking. This whole "get it at the store" thing is pretty new, and has mostly to do with building out of nothing but sheet goods using only power tools.
One algorithm I keep coming back to is Aho-Corasick, which locates all occurrences of a set of keywords in a string of text in linear time. (https://github.com/ahnick/ahocorasick) It's been useful anytime I needed to locate patterns in a group and I didn't want to be looping back over the group repeatedly.
What is annoying about these interviews is that you are expected to have memoized all of the algorithms be able to implement them while someone is watching, on a whiteboard, in a very short amount of time.
In my experience at Amazon and Google we all referred to books and colleagues when working through algorithms.
The grading rubrics for interviewers usually gives the candidate points for even mentioning particular algorithms, and I would hope that any decent interviewer would help you walk through trying to recall something. It's meant to be a design/application test, not a memory test
That was my experience. One interview question I was asked at Google boiled down to pathfinding on a graph. I suggested using A* and said "but I doubt I can write that on a whiteboard". The interviewer was fine with that, I got hired.
I did many SWE interviews at Google. I came up with my own question that obviously required using data structures and algorithms, but probably not something the candidate had ever thought about. Most people had a good thought process which was 90% of the question; some people arrived at the answer I thought was correct. Sadly, nobody ever came up with a better answer than what I decided was best. I was kind of hoping they would ;)
The problem with Google's interview system is that everyone gets to come up with their own questions. Some are bad! Some interviewers are bad! It takes the Hiring Committee a few candidates to recognize this and give the interviewer feedback about what's bad. But, that's why the HC exists and that's why you have 4 or more in-person interviews. The uncalibrated first-time interviewer does not have full veto power over hiring you. It can make for an uncomfortable experience (when is meeting new people and writing code on a whiteboard ever comfortable?), but overall the process does find good engineers.
The end result of the process, which I really liked, was that people on the team you're joining assume competency and don't explain simple things to you that you already know. I remember a few discussions in my first weeks at Google that blew my mind; we were talking about idempotency, and nobody needed to explain what it was. Every time I've ever used that word it derailed the meeting completely, requiring a remedial CS 101 course to bring everyone else on the team up to speed about that concept. Everyone at Google knows what that is, so you don't have explain it. It was nice. (This came up again when there was a discussion about state machines. Again, everyone knew what a state machine was, and used them somewhat regularly, so what was in my past life a discussion-derailing tangent was just a thing everyone knew.)
I'm not sure how people in the comments are saying that the "advanced stuff is never used", when the author used the A* search algorithm at work! I'm especially fond of this passage:
> You should also know about basic data structures that are pretty common, like hashtables, queues, or stacks. But specific algorithms like Dijkstra or A* are not ones you'd need to memorize: you'll have a reference for this, just like I had when implementing crypto.
Everyone complains about the lack of applications for these interviews, but there's not really an expectation to go beyond the fundamentals.
I've used many many many algorithms in my job creating search for video. I had no formal IT training though and I just learned them on the spot. I was trained as a researcher (computational neuroscience). When I need one I just read all I can about it and then build it.
I think having a rough understanding of what's out there does help though. Just reading some books about them, kinda scanning over them thinking hmm that's interesting. And then when you need one you'll remember "wait I think some sort of x algorithm I read about might be able to solve this".
> come up with simple ones on your own, like a greedy one.
Greedy alogrithms are simple to come up with in an interview, Yes. But they are often wrong and even if they are right there is no way to know that, unless you construct a mathematical proof.
I would highly advice not using greedy in an interview since coming up with a solid proof in 15 mins is not really possible in all but simple cases.
I once thought it would be difficult for big tech company recruiting processes to tell the difference between:
a) A really good problem solver
b) Someone who has ran through all the example interview problems on leetcode or something similar
Then I thought that this might be similar to the Turing test. Once you’re that good at faking it that you can convince someone else - maybe the difference doesn’t matter at that point.
For interviewing, I find it most useful if we ask a question that is an algorithmic problem to solve (but we don't tell them it is a graph problem and obviously it's not something as classic as Dijkstra). Then we observe if the candidate can formulate it as such, or can formulate it as anything useful (often there are several options, e.g. some find the problem to be dynamic programming). This gives much more information about the analytical skills of the candidate than about their algorithms knowledge. In terms of knowledge, what I find useful is just to ask what is a hashtable and how it works.
Of course, there are positions where this kind of skill is unnecessary and I cannot know everything about the false negatives. But failure in these areas also correlate with poor coding skills, at least in my experience of a free hundred interviews.
False negatives is right. You're skipping over a lot of good engineers with this approach and you'd have to interview fewer people if you could avoid that. How many times even without the pressure of an interview have I been stuck on what seems like a hard problem and then I go for a walk and end up running home because the lightbulb goes off and I can't believe how "stupid" I was and how simple the problem was.
Being able to use algorithms and data structures, which what this article mostly talks about, is rather a different thing from knowing how to implement them, which is what interviews go after.
That said, the only algorithm that I'm convinced that every single programmer needs to know by heart is state machines. Because using them can often save you a lot of code and complexity. And because you really have to know them well to recognize spots where they would be useful. And because using an off-the-shelf library to implement them is, for most use cases, more complicated, more time-consuming to implement, and less readable than a little light hard-coding.
In this case, this was implementing the AES standard.
Sounds like a terrible case of NIH. Why (re)implement AES when you've got battle tested implementations from OpenSSL, NaCL and practically any OS provided crypto APIs?
Is there any resource, either online, print of any other form, that lists many data structures in a ordered, searchable manner?
Something close to a dictionary or compendium that you could, for example, search what data structures had better performance for the search of an element, or insertion/deletion of an element, stuff like that.
I learned the basics ones in uni, but I still find many new (new to me anyway) ones, mostly at random, I wish I knew.
Most books on the matter that I read don't go much beyond the basic set of most common ones either.
> When we built Skype of Xbox One, we worked on a barebones Xbox OS, that was missing key libraries. We were building one of the first full-fledged applications on the platform. We needed a navigation solution that we could hook up both to touch gestures and to voice commands.
That makes sense. I would expect one to implement data structures and algorithms in a new operating system / kernel without the presence of any libraries available, except for libc, so that they can be reused or abstracted elsewhere in the kernel, drivers etc.
> There were cases where we had to build our own encryption / decryption implementations, formally verifying and auditing them, in the absence of the framework supporting it, or audited libraries being available.
I would leave implementing cryptographic protocols to the professional cryptographers.
But overall, I agree with the author to ask about data structures and algorithms that are actually used in the company if I were interviewing a candidate. It gives an honest account of the engineering decisions and reasons made in the team as to how implementing this DS & A helped them solved their problem and to test if the candidate understands these concepts.
However, after asking the candidate to implement a DS or A, if the candidate questions the technical interviewer if they use it in the company / teams and the answer is no, then it seems rather than a dishonest ego trip on the interviewer's side to test the candidate if they know the secret konami code.
> The most frequent data structure I've used regularly was hashtables and the hashing function. It's such a handy tool from counting, to detecting duplications, to caching, all the way to distributed systems use cases like sharding. After arrays, it's easily the most common data structure I've used on countless occasions. Almost all languages come with this data structure, and it's simple to implement if you'd need it.
I'm surprised this wasn't listed first. I always ask a question or two related to hash tables when I interview candidates and I'm continuously shocked that a good chunk of candidates don't know the basics of hash tables. I expect you to know that looking up whether an item exists in a hash table is _generally_ fast in practice, even if you don't know the specifics of O(1) best case, O(n) worst case. I expect you to know that it doesn't allow duplicate keys. I don't expect you to implement a hash data structure from scratch, but I do expect you to know which data structure implements a hash table in your language of choice (e.g. Object, Dictionary, Map, etc.).
It's the one slightly more complex "data structure" that I use all the time, so it's surprising to me when people don't know the basics.
Working on compilers, graph algorithms of various kinds tend to come up rather frequently. The only one that I recall having to implement myself was enumerating elementary cycles in a graph. That said, you often have to do a modified standard tree or graph traversal, so some variant of BFS or DFS is pretty common.
The only other exotic data structure I've had to use is the union-find data structure. It's a pretty slick data structure, both because it's so easy that you could probably come up with the optimal one just by thinking about it for a few hours, but also because its runtime is O(n * inverse Ackermann(n)), the latter function grows so slowly that it is less than 4 for the number of atoms in the universe. Although, unfortunately, the data structure doesn't do a good job of telling you which union call is the one that merged two sets that should be separate together.
> The Algorithm Design Manual and Algorithms: Fourth Edition are both books I picked up back in the day to refresh some of the my university algorithm class studies. I gave up midway, and found them pretty dry, and not applicable to my day-to-day work.
These are both good books that I actually like! They aren't quite as massive or comprehensive as CLRS but are easier to read as a textbook. I also like Steven Skiena's course videos. But I agree completely that they are unlikely to be something you'll use day-to-day unless you work as an algorithms specialist.
> Grokking Algorithms by Aditya Bhargava... I am convinced that you don't need to know more about algorithms than this book covers.
This is a nice and compact book, and I think he's right for most jobs that involve writing software. Won't be enough to get you past the idiotic algorithm puzzle interviews though. ;-(
Many software engineers do indeed go for long periods without using anything but the most rudimentary algorithms. Needing to know or at least be familiar with many complex algorithms is more of a broad specialty now, and you get shunted into different sorts of work depending on your knowledge of algorithms.
I've done an awful lot of investment in booktime to learn various algos, simple to obscure, and frankly never used any of them. I do find that depressing.
What people seem to want is big-data or various tech stacks. I look forward to the time I can put even a bloom filter to work.
I implemented a bloom filter for the KeePass plugin [1] I wrote, using the data from HIBP. It was pretty fun and there were some challenges that you won't typically encounter in online guides.
Still, that was a hobby project, I've never had to implement anything similar at my regular job.
It's interesting to see someone else's list. If I were to make a similar list, I think I'd have very little overlap with this one. And the overlap that is there, like using hashtables and hashing, I'm not sure passes out of the realm of triviality: while I've built hashtables and written hash functions myself, I don't recall any job where I was required to do that, rather than just using something off-the-shelf.
It's probable that I've done some of the other stuff -- graph traversal comes to mind as feeling like something I've done professionally -- I feel like I've done stuff like that maybe once or twice in ~20 years. While it was useful to have that knowledge, probably, it wasn't even remotely representative of regular work on those jobs.
But that raises another question: is it still worthwhile to test for something you'll use 0.1% of the time on the job? Like, say I didn't know anything about graph traversal, and came across a problem that (even though I didn't know it) was perfectly suited to a solution involving a well-known algorithm. I might search around a bit, but ultimately my solution will probably be pretty non-optimal, might involve brute-forcing, and might be difficult to understand and read since I had no idea what I was doing.
On one hand you could say yes, that's important: even if you will barely use this information, it will be absolutely critical that you have it already and understand it when you do run into a problem that needs it, to the point that we don't want to hire you if you don't have it. On the other hand, you could say that picking it up as you go along is fine, or even writing a bad, brute-forced solution is fine, and the likelihood is that someone else on the team would notice during design or review and suggest the correct approach. You could even say that even if that doesn't happen, a bad implementation of part of your stack isn't even that big a deal; we all write so much technical debt for various reasons, this is just another thing that someone might have to revisit and improve later.
I've used Sort method several types both in Java and JavaScript but they way it's used it as a library function, I don't need to write my own sorting algorithm. Same for Data Structure commons ones I've used are found in Java Collections - ArrayList, LinkedList, HashMap, Set etc. For Deep Learning have used several algorithms that are best practices and common data structures like Tensors and Vectors. I realize the value of knowing the theoretical underpinning but practically speaking these are only ever written one by library creators, no idea why companies insist everyone to know these and implement by heart, they can ask much more interesting practical problems.
The point is, they should not actually require candidates to recall these things from memory. But there is certainly value in the non-memorization part of this knowledge and the ability to solve this kind of problems distinguish people who can think from those naive jobsworths. If nothing, they are better than back-of-the-newspaper if-you-have-seen-the-answer-you-know-the-answer kind of trick questions.
Java is an interesting one; while you don't write the sorting algorithm, you do write the sorting conditions, a function that returns a number depending on the compared values. Likewise there's hash functions, although in practice those will be generated by your IDE or Lombok. (I haven't been into Java for a while so there may be better alternatives, iirc Scala and / or Kotlin solve it as well)
Quote: "... but I have come across everyday use cases of data structures and algorithms when working at Skype/Microsoft, Skyscanner and Uber"
Considering Skype is at best laughable compared to other IM applications, I'd not boast about working on it. I used Skype over 10 years and after it got bought by Microsoft it gradually started to be worse and worse, to the point I had to look at other IM in order to communicate with my clients.
I have a question, why is that Whatsapp and FB messenger can and will deliver notifications when you receive a message every single time, while for Skype this seems to be an unachievable feature?
I don't think there is a right or wrong answer. My experience tells me that everyone is different when implementing solutions. I'm working with a new grad, with MS in CS from a top school. He is great theoretically, but this project requires learning and implementing new tech very fast. thinking outside the box and prototyping a lot unfortunately he is overthinking and delaying the project. On the other side I have seen people that doesn't excel in algos and create great products. My take is that the take home assignment provides a better perspective on candidates than just algos and ds
Where things get interesting is the mismatch between Big-O data structure complexity analysis (as typically discussed in interviews) and actually knowing about the hardware, the operating system, the memory hierarchy and things like cost of context switches and cache misses.
Some real-life practical examples: knowing when a simple O(n) linear search beats O(log n) binary search, or knowing when a multiple substring search algorithm based on a simple Rabin-Karp and L1 cached hash table lookup will outperform the theoretically more optimal Aho-Corasick.
But as a senior developer, I daily have to understand the graph of code submitted for review to propose a simplified one to increase readability and ease future maintenance.
I use a lot of algorithms through libraries but rarely implement one. I think people get tired of the typical algorithm interviews because they often focus on implementation and not use.
Algorithms come up all the time. Sometimes standard algorithms to use, sometimes to implement or modify slightly, sometimes as something completely custom where some inspiration is drawn from the classics.
But does this mean you need to learn them by rote or be able to figure them out on a whiteboard? No. And although they appear regularly, I don‘t spend enough time on them that this would meaningfully affect my performance. So the time you spend thinking doesn‘t matter, very unlike a whiteboard situation.
I'm surprised that you didn't recommend Knuth as the best reference for algorithms.
Technical interviewing for long term employees based on exam essay like questions is rarely productive. My first objective is determining the applicant's honesty on their prior experience. It is amazing that the vast majority of applicants will out right lie on their resumes and to your face when questioned.
Past success in solving/implementing difficult projects is the best indicator of future success.
I sometimes look at the hiring experiences of other kinds of engineers longingly. Electrical Engineer? Asked to design a circuit. Chemical Engineer? Asked to synthesize a chemical. Mechanical Engineer? Asked to design a car. Software Engineer? 50 million different processes based on the whims of "senior engineer"s with 4 years out of college, mostly trivia questions out of a book that only 1% of software developers actually use in everyday work
I think it's nice knowing about analogous problems. If you know what you're trying to do is similar to NPC, one can quickly either dismiss the feature/problem, convert it to a problem with an existing solver, or maybe know that in general it's hard to solve but a relaxed variant is good enough.
I'd wish more of those problems showed up in my daily work, though.
Btw, a cool popsci book about algorithms occuring in day to day life is "Algorithms to live by".
In my first year at Facebook, I saw an opportunity to use a priority queue to improve a service my team supported. It ended up saving something like 30 machines.
The main problem, I believe, is the time constraint and the interview environment, both add a LOT of stress and will reduce our ability to come up with an answer. I think most people can come up with a good algorithmic solution given the proper time to do so.
IMHO take home tests with a following discussion of the solution is the best way to go. Interviewers can judge the code quality as well as critical thinking with the follow up discussions.
Can anyone recommend a good resource for learning about Dynamic Programming? Not from a FAANG interview perspective, it's something that I didn't really wrap my brain around in the algorithms courses in University. Five years into my career I still haven't ever had to use it. It's something I feel mildly guilty about.
I like his point at the end, that the interviewing process is the most pragmatic one, not the best. It reminds me of boarding airplanes, where we've chosen pragmatic boarding strategies, but not the most efficient.
Remember people processes need to be the least bad, not the best. Most of the best are either unworkable or tyrannical.
I have used graph algorithms a little bit at work. For example if you are generating code for a language like C where order of declaration matters, you can use a directed graph to represent dependencies between data types and then use a topological sort to order how you write structs to the header file.
I wrote a typed visitor pattern for validating and rewriting objects with an audit log, it became necessary for an integration where an error response would need to return a modified input if the original could not be processed but he modified one could be resubmitted successfully.
Algorithms and data structures are very useful and a general knowledge is certainly required. However, when you're facing a problem, do you have to come up with an optimal solution, on a whiteboard, in 45 minutes, and with someone looking over your shoulder?
Would love to hear a take on this from a game programmer. They might be a bit more specialized these days, but I'm sure in the late 90's, earl 2000's if you were working on a game, or game engine (and their tools) you used numerous algorithms.
Thanks for this insightful look into software engineering in tech companies, as a more DevOps person this is very useful to know about, i.e. there are just too many things outside of programming that are interesting so developing full time is not an option.
The problem with interviews is not whether those companies are actually using algos in practice. The problem is that they ask the data structures and algorithms as ruthless puzzless to detect a candidate's level. That's a very wrong approach.
I like algorithms and coding competitions, but in my 22 year career in software engineering I have never had to code any algorithm myself, except in numerous job interviews.
As for data structures, the only one I occasionally need to code myself is a simple tree.
algo questions come in many forms. it is a problem space that devs can focus on when preparing for interviews. it side-steps integration issues that occur in real world problems like "implement an HTTP server" or "implement a multi-host parallelization framework".
even though real world problems are better interview questions, they suffer from requiring more candidate/interviewer prep. they can also stall out due to integration/machine/etc issues
Uber rolled their own crypto? Do they still? I thought you could always import some C library on iOS or Android (or use bouncycastle, unless that wasn't around then)
Given that the publisher, Springer, is giving it away for free during the pandemic, you should grab the PDF of Steven Skiena's The Algorithm Design Manual[0] (direct PDF link[1]) -- it's a book that has often been mentioned favorably here on HN.
(And you can pick up another book of his, The Data Science Design Manual[2] (direct PDF link[3]), which is similar in its conversational style, but about a different aspect of CS)
I sometimes suspect that everything is really just a sorting problem.
For example, here is a shell script that takes an input file consisting of lines of the form
X Y
where X and Y are integers representing the X and Y coordinates of live cells in a Conway's Life grid, and outputs the next generation in the same format. It runs in O(n log n) where n is the number of live cells, and it is really just sorting.
For me, I have spent many years, writing code that presents UI, or controls devices.
That has some aspects of software development that I rarely hear discussed, like testing, usability, accessibility, aesthetics, graphic design, error handling and recovery, documentation, support, configuration management, and lots of system framework knowledge.
If I am supposed to be writing apps for iOS devices, then I’d think knowledge of UIKit would be a heck of a lot more important than balancing a binary tree. I can tell you, from personal experience, that it takes a long time to learn, and is very important, if you want actual, shipping apps.
Even so, I have often encountered obsession with “büzzwürd du jour,” and people get hung up on things like MVVM/MVP, VIPER, etc.
I remember once, getting a “take home” test that asked me to implement an iOS app that employed MapBox, which is an excellent library, but, at the time, I had never used. I was instructed to use MVVM. I have no idea why.
In four hours, I had a completely functional, localizable, well-code-documented, nearly ship-ready (including a custom app icon and splash screen), high-quality app that implemented MapBox (again, I had never even looked at MapBox before this test), using Dependency Injection (basically, the “D” in “SOLID”). If I incorporate dependencies, I always encapsulate the dependency, and DI is an excellent way to do that.
Oh, also, while I was working on the app, we had a household emergency that required urgent attention. The app would have taken less time to write, otherwise.
It was not received well. To this day, I have never learned why. I suspect that I was supposed to spend a couple of days, creating some kind of chimera that illustrated every buzzword on Earth. No matter. I wasn’t what they wanted, and, after that experience, I realized I would probably not enjoy working with them; which was a bit disappointing, as I liked their product. I felt that I could have had a fairly significant impact on their Apple software.
In my experience, I have found it’s always best to use the development model a framework is designed to support; even if it isn’t particularly “buzzwordy.” If we use UIKit, then MVC is the most practical and simplest approach, as that is how the SDK was designed. If we use SwiftUI, then we have a great deal more flexibility with our models, but very few companies are willing to ship SwiftUI apps (yet).
Shipping is all about practical approach. Ship software should be done quickly, as simply as possible, and needs to be robust, well-documented, organized, testable, Extensible, and maintainable. If we are talking Apple apps, then they should also be performant, responsive, secure, highly usable, intuitive, aesthetically pleasing, accessible, and that employ familiar (to the user) idioms. They also need to pass App Store Review muster, so that means being careful about how we incorporate dependencies and frameworks, as well as not using private APIs.
Since I’ve had over twenty apps in the App Store that I’ve written from scratch (but I'm down to seven, right now: https://littlegreenviper.com/AppDocs/), this is something I do know a bit about.
That usually requires a great deal of frugality, practicality, user empathy, experience, and self-discipline. It’s difficult to figure that out with “Draw Spunky” binary tree tests.
I'm not at all opposed to companies like Google, Facebook, etc asking Algorithms, Data Structure and Big O related questions. Why? It's very applicable to problems at their scale. That being said, not all engineers there work on such problems.
If I'm asked to do a BFS/DFS, Tree traversal, etc for a small company.. I tend to share high level how I'll solve it then basically not actually code it up and say something like "This is pretty tricky...". Why? It's my way to exit the interview quickly because I question the ability of the company to hire talented engineers. Especially when I test your product out and see all sorts of inconsistencies.
Okay, so when do Data Structures matter to a company?
Are you building a product that needs to perform very efficiently at scale and the system is doing something outside the "norms" of what a data store can provide. Examples: Facebook's TAO system and their type ahead search.
Read the design paper for TAO and you'll see how they use very primitive data structured related to Graphs. Their typeahead system also makes use of some very basic data structures and some probabilistic data structures as well.
When do Algorithms matter to a company?
For most traditional companies, you're not going to do a BFS/DFS search, traverse a tree or a Dynamic Programming solution like Levenshtein distance. So unless these algorithms have a practical use case in your company, you're just creating a sort of monoculture.
Once again, Google and Facebook do apply these algorithms so I respect their interview process.
Big O has its place in such large companies. I think most people fail to understand the purpose of Big O; identify upfront if a solution will be sufficient from a time or space perspective as the data grows. Most people speak about Big O on interviews AFTER they code up the solution. You should do that before you code it up.
e.g, So the data for this problem is <100 items then this quadratic solution would work, but if we scale the data set up to say 10,000 items then it won't work. Then you can look at data structures or sorting algorithms for instance that'll help you get it down to say O(n) or O(n log n) etc
Look, I get the frustration a lot of people feel about this sort of interviewing process. I have a very non-traditional background and it could be very scary when you first start learning about this. My advice? Learn it for your own good. It'll make your a better programmer and it'll help you become more aware of so many things you weren't aware of before!
The moment when you realize why using an array for a Min Heap or why a Min Heap must be a complete tree... you'll step back and go "Now that's sexy!" Or when you realize even stupid stuff like "A balanced binary Tree has this weird reality that the leaf nodes account for 50% of all nodes in the tree" It's just fun if you see it in a positive way.
Let's call technical interviews that ask such questions when it doesn't represent the company "interviewer imposter syndrome". When a company tries to act and look like Google early on.. Google has a million+ candidates a year interviewing with them. They MUST allow good candidates slip through their process.
I remember, when starting university, with no real programming knowledge, making a little game in my spare time (a clone of Pang if you know it) but it was before I knew what a linked list is. I implemented things like the balls which bounce around the level in an array, and just gave that array a max size. I was very unsatisfied by this, and then later finding out about linked lists was an ah-hah moment, very satisfying.
Next project was making a "Countdown" game, where you are given 9 pseudo random letters and have to make the longest word you can. I found a dictionary as a text file, so could see if the word you entered existed. The game was on Gameboy Advance, so not a huge amount of space or very fast CPU. As you can imagine, walking the entire dictionary file from start to end looking for a word was far too slow. So there was another ah-hah moment when binary search was introduced.
Next I worked on a rendering engine for this device called GP32, you basically got a pointer to the screen buffer and could put what you liked in it, so I learned how to write polygon fill routines, back face call, etc but didn't know what perspective projection was or how to find out about it. I finally found a book, Game Programmers Black Book or something like that, which explained perspective projection, at least to some extent, another ah-hah moment (previously I was dividing my XY by Z as I knew I wanted things smaller in the distance but this doesn't give a nice result by itself).
These are just very early examples when I first started programming, when information was harder to find, and when a lot of games development involved DIY, if you want a polygon you need to pixel fill a polygon! Even when PS2 came out you still had to write ASM render programs to take an array of vertices and transform them, their UVs, etc and send them to the Graphics Interface.
But I haven't found later tech developments have stopped me finding and needing to use other algorithms and structures. Just last week I had to diagnose a crash which resulted with the target device and debugger showing a nonsensical callstack, so I enabled the profile options in GCC/Clang so I had an epilogue / prologue for every function that is called, so I could store my own call graph history, and then, on crash, display it nicely, with indentation etc. This allowed me to see what happened just before the crash (turned out to be a system UTF16 conversation routine stomping over a pointers boundaries as the NULL termination of the string was incorrectly done as if the string was a normal char*, effectively NULL terminating half of a UTF16 pair, which wasn't treated as a terminate, so the actual bug was bad string termination done by the off the shelf engine we use). As the profile code ran twice for every single function that was run, it had to be pretty efficient, using appropriate data structures, etc.
So I guess the point of this post is to say I believe having a good knowledge of algorithms and data structures always seems beneficial to me. The extent which some companies push them is too much for me, but I don't think this should lead to us thinking it is all pointless. There is a nice balance out there.
This is kind of dumb because most of the examples just involve built-in language implementations or libraries that implement the stated algorithm.
For example if you use dict a lot in Python, that’s not at all the same as writing your own hash table with a custom chaining or probing algorithm for collision resolution.
The original quote from the whole homebrew saga is talking about needing to seriously implement these algorithms entirely yourself for a task. It was not talking about casually knowing a few fundamentals you loosely keep in your mind while using built in libraries.
Whiteboard hazing trivia interviews are also all about obscure implementation specifics, and they are not at all about knowing the coarse fundamentals. That was the entire point of criticizing Google’s parochial barrier to entry hazing crap.
While this author’s stated experience is cool, I think they entirely missed the point of what they are responding to.
99% of the time, the "right" data structure is either an array of records or a hash table, or a tree that you traverse depth-first.
However, you should be able to implement some of these more rarely used data structures, given a description. You shouldn't know how to do it ahead of time, however, because your job is to solve problems that aren't solved yet.
What you get with these interview questions is that some applicants prepare for how to solve some of these commonly posed problems specifically. So you have to implement a bug-free linked list, on a whiteboard, in ten minutes, to be competitive. It's doable if you are prepared, but that defeats the purpose.
I've used loads of algorithms to solve problems during work and memorised the mechanics of none of them. It seems memorising this stuff is the opposite of how to work effectively with computers.
How long did DFS take? In my experience, with Spark it's like factor of 100 slower than what one would expect on a single machine and a sizable dataset.
nice thread. sorry for the noisy comment, but most threads similar to this end up with folks griping that the interviewer asked them to invert a binary tree or other such super basic stuff that -- no, you do not do every day or even ever at all, but -- is 101 level stuff that you better be able do in a few minutes from first principles. sticking with that theme, even AVL or red/black you better be able to describe it off the top of your head although asking to implement a working solution covering all edge cases in the span of an interview session is nonsense.
no, in this thread people are describing actually hard, complex algorithms and ridiculous interviews. so sad to see that these questions are still being asked today.
this is the best thread on this subject that i have ever seen on HN.
Would you rather be interviewed on algorithm questions or Ravens progressive matrices? They both test the same thing, but at least one you can study for, is somewhat relevant to the job (and is legal).
Only if you remember all the permutations. But I think Ravens progressive matrices are only good for finding people who have good visual acuity, not people who think deep.
I did not get the job at Google.
I do make sure as a more senior engineer at my current company I use what leverage I have to make sure other interviewers don't ask pointless questions like this.