You just landed an interview for a new position. Congratulations! Perhaps you recently graduated from a program like Berkeley’s Master of Information and Data Science. Perhaps you are finding remote jobs posted that used to be Bay Area positions. Perhaps you are ready for something new.
Now you have to take a code challenge. Say what you like about interview questions, but online coding challenges are increasingly common, they are harder than they used to be, and they matter more. No matter what anyone says about looking at the whole application, to fail a coding challenge is a speed bump your application doesn’t need. Think of it this way: Suppose you are hiring for an open position on your team, and you received a hundred applications per day (a common occurrence). How many applications would you pursue that scored below the 50th percentile on a code challenge?
Just like the SAT or ACT, coding challenges are standardized tests, and one of the only ways we can directly compare applicants. You have no excuse not to be prepared—after all, coding is one of your core career talents!
In short, treat this like any other test: Prepare! Practice!
Here, then, are my suggestions:
- Practice, using a throwaway account, on the site you will use for your official code challenge. Every site I’ve seen that contracts with companies to offer official interview code challenges also has a public-facing version with sample challenges. Take a couple of those sample challenge tests. You want to be familiar with the site, so that you avoid accidentally submitting—or deleting—your work. The editor will have quirks. The site will expect you to format your output in specific ways. Like with any standardized test, you should be entirely familiar with the instructions before you go in.
- Confirm what languages your particular test will allow you to submit a solution in! Carefully note whether your preferred language is in the list!
- First, make sure the site you’re using supports that language.
- Second, ask your interviewer to confirm what languages will be available for your test. (Most sites tell you what languages are available for your test, a click or two before you begin, but you might accidentally start the test, which would be a disaster.)
- Mentally choose one of the available languages, and code all of your practice exams in that language.
- Take several practice challenges, with a wide range of difficulty. You should consistently earn a perfect score on easy challenges, and get a fair start on the hardest challenges. Very hard challenges make poor test questions, so you are likely to get an easy or moderate challenge for your interview. Even in the event that you are unable to solve your challenge entirely, you can still do well on on much of it.
- A good exam has multiple questions. If possible, read the entire exam first. If possible, start with the easiest question for you to solve, even if it’s not the first question. Regardless, avoid getting stuck on one of question for some weird reason and then never getting to later questions. Submitting nothing would be a disaster!
- When you are taking a code challenge, your goal is to maximize your score. Five or ten years ago, scores were often boolean: Did the person find a solution, yes or no? Today, code challenges test a wide variety of skills:
- Fluency. While most of the compiler’s annoyances will be hidden, you will still have to load modules and write code.
- Edge cases. Quality assurance demands that edge cases be checked, and good programming requires that they be handled correctly.
- Complexity of the solution. It’s easy for websites to empirically check the time and memory complexity of your solution. If your solution is too slow, it won’t receive a perfect score. A good rule of thumb is: Do better than O(n^2). If, for every element, you have to search through all remaining elements, your solution is too slow. If you can avoid doing that, your solution will probably be O(n log n), which is probably fine. An O(n) solution is unlikely, unless it’s a trivial problem. (See below for tricks to speed up your solution!)
- Overall programming prowess. The raw code you submit will be sent to your interviewer.
- When you read the problem statement, take careful note of the tasks’s requirements. Enumerate each requirement into a personal checklist. Checklists are wildly valuable! Deliberately confirm each entry on your checklist before submitting.
- Keep an up-to-date local copy of your code as you work. The internet may go down, or your browser may choke. Back up your work! Keep a few versions in case you break something and have to go back to an earlier solution.
- Avoid clever syntax. A timed test is not appropriate for taking risks. The fastest code developer gets it right the first time.
- Use accepted idioms for the programming language and use them consistently.
- At a minimum, make sure your solution solves the examples correctly. The answer is right there! Your general solution should handle them correctly.
- If output is limited (eg: “Return -1 if the answer is greater than 1,000,000,000”), make sure your code respects the limit. A limit like that is for overflow protection. In any case, that’s a specific requirement that should be on your checklist.
- While coding and testing, add assertion-style checks. (eg: your lists are sorted the way you think, elements are positive, etc.) This will help you with debugging, and you can comment them out later, if speed is a question. Especially since you will be editing code while you design your solution, every moment spent not realizing you’ve violated an assumption made by some other line of code is a wasted moment.
- Use lots of print statements. Print the new value after setting each variable. You can take it out later, and it will save you debugging time.
- Check that your solution respects symmetry in the problem. (eg: “Find the longest word in this sentence.” Reversed input should give the same result.)
- They can see your code. Don’t curse or use dumb variable names.
- Short-circuit degenerate and trivial cases. (eg: empty input, or input with one value.) This will allow your general case to make important assumptions like “the input array exists and has at least one element.”
- Short-circuit ALL easy cases, especially for large input! If your main solution is too slow, you will fail most large input cases, even if your solution is correct. Some of the large input cases will be special cases you can short-circuit. (eg: “Minimize
|a+b|
over a list of integers.” If zero is in the list, zero is the answer; return it immediately. If all inputs are positive or all negative, the answer is2*min|a|
. That case is O(n) complexity, and you probably already computemin|a|
somewhere in your solution.) - Familiarize yourself with common topics.
- Stacks and queues. (eg: Is this string of random “()[]{}” characters balanced? Using a stack is O(n) (good). Repeatedly removing balanced pairs of brackets is O(n^2) (bad).)
- Searching for patterns in strings or lists. (eg: “Find a maximum length sublist B of elements of a list A, such that B is strictly increasing. Return the number of unique such sublists B.”)
- Trees and graphs. (egs: “Compute the diameter of this tree.” “Find the number of cycles in this graph.”)
- Caching and memoization. If you compute something you may need again, keep track of it! (eg: “Compute the n-th prime number for this list of values of n.”)
- Database queries. For many data science jobs, you will need to be familiar with databases, either manually or through a web interface. (eg: “Find all customers who have made a payment in the past 30 days, but have not logged in for more than 60 days.” You will probably need to join tables.)
- Consider whether your edge cases will generalize. Test them.
- Think of a wide variety of inputs. (eg: repeated input, reversed input, long input, trivial input.)
- Discover common cases used by the site. (eg: trivial cases, minimal cases, short nontrivial cases, repetitions, simple long cases, symmetric cases, random large input.)
- Familiarize yourself with common mistakes you make, and that are made with your chosen language.
Perl:- Sort is lexicographic by default even on integers!
It’ssort {$a<=>$b} @integers
, notsort @integers
. use strict
- Making a class from scratch is annoying. Try to use STL classes. Confirm that your testing site contains those classes!
- Don’t mess up your indentation.
- Keep the order of your calls correct:
str.join(MyStrings).trim(' ')
is different fromstr.trim(' ').join(MyStrings)
. - Avoid Obi-wan errors (aka “off by one” errors) in loops. The range
[1:11]
will give output for values from 1 to 10.
- Sort is lexicographic by default even on integers!
- Remember the things you should do for any important event.
- Clear your schedule. Remove all distractions from well before you plan to start, until well after.
- Set up a comfortable workspace.
- Have resources like a bathroom available.
- Have a plan in case the internet goes out.
- Be well-rested.
- (Optional) Have caffeine nearby.
Finally, right before you hit submit, copy/paste your code into a local file. After you see your score—or perhaps when your head hits the pillow that night—you’ll suddenly think of a way you could have made your solution better! This is also true during practice. During practice, if you’re not satisfied with your score, go back and try again.
Again, congratulations on making steps toward your career goals. This is what we at the School of Information are here for!
Great list and great tips! I didn’t know about the Perl sort thing and wouldn’t have thought of 80% of this list. Thank you!