Algorithms

Summarized using AI

Implementing the LHC on a Whiteboard

James Edward Gray II • May 24, 2016 • Kansas City, MO

In the talk titled "Implementing the LHC on a Whiteboard," speaker James Edward Gray II discusses strategies to excel in coding interviews, addressing commonly used interview formats and offering practical advice based on his own experiences.

Key Points:\n- Interview Formats: Gray identifies different types of coding interviews including take-home tasks, technical interviews with live pairing, whiteboard interviews, and audition-style tasks where candidates work on a company’s application. He emphasizes that the methods used can feel disconnected from real-world programming.

- Preparation Strategies: Gray stresses the importance of familiarizing oneself with commonly asked coding problems and algorithm concepts, particularly Big O notation, which helps in analyzing the efficiency of algorithms. He suggests developing a strong understanding of algorithms and problem-solving techniques.

- Common Mistakes to Avoid: He highlights the importance of understanding the problem statement before diving into coding. He recounts a personal anecdote where miscommunication led to a misunderstanding during an interview.

- Demonstrating Thought Process: Gray encourages candidates to articulate their thought process during interviews, using phrases like "My first thought is..." to maintain communication. He regards humbly admitting gaps in knowledge as a strength.

- Focus on Core Challenges: Candidates should prioritize solving the main problem rather than getting sidetracked with bonus challenges or excessive setup work. Writing tests alongside coding is also encouraged to enhance clarity and presentation of solutions.

- Professionalism and Presentation: Appropriate behavior in interviews is essential; candidates are reminded to maintain professionalism and avoid distractions that could signal unfit behavior.

- Use of Tools and Techniques: Gray recommends practicing coding with resources like Exorcism.io and contributing to open-source projects to build a professional portfolio.

In conclusion, Gray emphasizes that while there is no guaranteed way to ace coding interviews, focusing on preparation, clear communication, and a sound understanding of algorithms can significantly increase chances of success. His advice serves as a roadmap for aspiring developers to navigate the often stressful interview process effectively.

Implementing the LHC on a Whiteboard
James Edward Gray II • May 24, 2016 • Kansas City, MO

If you apply for a programming job, you may be asked to complete a take home code challenge, "pair program" with another developer, and/or sketch out some code on a whiteboard. A lot has been said of the validity and fairness of these tactics, but, company ethics aside, what if you just need a job? In this talk, I'll show you a series of mistakes I have seen in these interview challenges and give you strategies for avoiding them. I'll give recommendations for how you can impress the programmers grading your work and I'll tell you which rules you should bend in your solutions.

RailsConf 2016

00:00:11.300 Alright, I think it's time we get started. I have to tell you something funny before we get into this talk. I decided it would be cool to have my five-year-old daughter do the illustrations and pictures for this talk. About halfway through, I realized I was giving her all these weird requirements and making her do all these things to fit my talk. I think I have actually become that interviewer that we all hate, which might be a problem. So, take the rest of this talk with an appropriate grain of salt. Today, we're going to talk about coding interviews and how to pass them. The reason I wanted to do this talk is basically inspired by a tweet I saw.
00:00:49.230 It's true, and sadly, I feel like there is a disconnect between what we do in interviews and what we do in our day jobs. We don't spend enough time discussing the interviewing side, so let's focus on that. These are the coding interviews I'm familiar with that are commonly practiced: you can have take-home problems where they give you some challenge to work on, with or without a time limit; technical interviews where you work with one of their employees, often involving pairing, but mostly it’s them watching you struggle to solve some problem; the whiteboard interview, where you program on a whiteboard or in a Google Doc; and auditions where you do some real work on their application, either on your own or with help, and then they judge you based on that.
00:01:30.329 I work at No Red Ink, and as part of my job, I conduct high-grade take-homes and technical interviews. I've seen a lot of what doesn't work, and I think I have some tips that can help you get past those problems. It's been my interest to do so. For example, if our director of engineering comes to me and says we need to hire eight new people this year, if I can find some great programmers by May, then I could take a few months off from interviewing! This talk does come with caveats, however.
00:02:07.380 First of all, there are no guarantees. I'm going to tell you the major mistakes to avoid, and I hope to raise your chances in interviews. But it’s well known that the mood of your interviewer and their level of training—these are all things that are beyond our control. So, it is definitely a numbers game. I'm also not going to judge the various interviewing practices. I think there are things our industry does well and things it does not do well, and that’s a great conversation to have, but it’s not this conversation. There was a really good talk yesterday called 'Hiring People with Science'; if you missed it, I highly recommend catching the video, as it gets into some of this.
00:04:09.000 Also, I am not familiar with every kind of interview out there. For example, I've never taken a whiteboard interview or been given one, so I won't have much to offer regarding that, aside from general tips. Finally, if you do everything I suggest in this talk, it will take a lot of time, and your spouse and family might not be happy with you, so it's up to you to apply the appropriate filter of how much you should do, based on your needs. Now, let's talk about what you can do to prepare.
00:05:03.840 The worst thing you could do is show up to an interview and start trying to pass it. You need to do some things to get ready to help swing the odds in your favor. The first step is to study interview questions that are pulled from a well-known subset of computer problems. If you are more familiar with those kinds of things, you'll do better in the interview, even if it's not stuff you're using every day in your job. It’s really important to load this back into your brain.
00:05:40.240 Here are some concepts that I believe are the most useful, based on my cross-checking with a few different sources that all agree closely. I've arranged them so that the most important stuff is at the top and to the left. If you work your way down this list, I think it's probably the most helpful. It's not that I think you'll be asked to implement a binary search directly, but sometimes just being familiar with these concepts can help you in an interview.
00:06:36.660 First, let's talk about Big O notation, which I stuck in the upper left corner. It might seem a little surprising, but I think it's more important than people give it credit. It’s a tool for understanding how long your code is going to run or how much memory it will consume. Understanding the different complexities of algorithms can be very powerful. For instance, being on the green line that slowly climbs means a very different experience than being on the orange curve, which shoots up almost straight to the top. Recognizing these differences can be incredibly beneficial in solving problems.
00:07:23.890 Let’s take a quick Big O notation quiz to see what you remember. Think in your head about the complexity of this code I'm about to show you and then I’ll give you the answer. This one is Big O of n; it’s a linear algorithm. The two important bits are right here: we scanned over the entire data set twice, summing once and multiplying the second time, resulting in 2n. However, in Big O notation, we drop constants and non-dominant terms, which leaves us with linear complexity.
00:07:57.510 Now, how about the classic recursive algorithm for the Fibonacci sequence? Give yourself a moment to think. This one is Big O of 2 to the power of n. I wanted to show this one because, when running recursive algorithms, there is a formula you can use to figure out the complexity. It's determined by how many branches there are raised to the power of the depth you have to go down. In this case, we're making two recursive calls, one with i minus 2 and one with i minus 1, and we go down however many steps based on the parameters provided. So that's a formula for figuring out recursive algorithms.
00:09:00.660 Next, here's a more complicated one. Bonus points if you know it. Anyone want to guess? This one is n log n; that's part of it. This particular algorithm is Big O of B log B plus A log B, which may seem horribly complicated, but it's not as challenging as it looks if you take the time to break it down. This is the sort, and Ruby uses a hybrid sort that is typically B log B or n log n.
00:09:49.780 The second term of our complexity arises from scanning over array A and for each element in A, performing a binary search on array B. Since there’s dependent work, you multiply the two together, and that’s where the A log B term comes from, while the sort is independent. Don’t feel bad if you don’t know these or didn’t get them right; I had my own struggles. The point is that studying them will give you advantages. Now let's tackle a classic interview problem I pulled from a list of interview questions.
00:10:49.460 The problem states: given two sorted arrays, find the elements in common. Each array is the same length and contains all distinct elements. The most obvious solution is to scan over one of the sets and check whether each item exists in the other set. That approach has a complexity of O(n²) since for every item, you could potentially have to run over the entire set. However, knowing that the sets are sorted and distinct, I suspect there's a linear solution; I can scan through one array once to identify shared items.
00:12:10.360 This could look something like keeping a pointer in one array and incrementing it whenever I pass a certain size, eliminating unnecessary checks. While I think it's linear, I'm not entirely sure, and it’s complicated. However, if you’re familiar with concepts like Big O notation and complexity measurements, there might be simpler ways to reach similar conclusions. Here’s another alternative: run through one array, load the elements into a hash, and then check the other array against that hash. This requires only two linear passes, resulting in a linear solution overall.
00:12:58.690 The hash lookup is faster than the original algorithm; therefore, this method is much easier and enables faster solutions. You can use Ruby to play around with performance; MiniTest allows you to provide assertions that give inputs and measure the time your code takes to execute, ultimately fitting it into a specific curve. Here's a small note: the recursive Fibonacci algorithm we discussed earlier is similar, except it's inside a Ruby hash, which enables memoization. In memoization, once a value has been calculated and stored in the hash, it is preserved for future reference.
00:14:23.400 Dynamic programming works differently, approaching the problem from the bottom up instead of top-down like memoization. Both methods achieve the same outcome. Using MiniTest Benchmark, you can also set up assertions to test your algorithm's complexity. Expect it to be exponential; however, be mindful that if your algorithm overwhelms Ruby quickly, it’s probably not a great algorithm. Something to keep in mind that can serve as a guideline.
00:15:03.400 Now let's switch gears and consider a coding challenge: you have nine balls, with one heavier ball among them. Use a balance to identify the heavier one in just two uses. After a moment, you can figure it out by putting three balls on each side of the scale. If one side is heavier, the heavier ball is among those three; if they're balanced out, it's on the table. This approach narrows the field significantly.
00:15:58.700 This problem illustrates one significant point: being familiar with problem-solving techniques—like binary search or merge sort—can lead you to answer interview questions more quickly. Overall, you need to practice problems just like this. Unfortunately, there isn't a better way, and I highly recommend using Exorcism.io, which has good-sized problems and ensures a consistent experience, along with opportunities for feedback on your solutions.
00:17:01.820 You should aim to solve Exorcism-style problems in under an hour because if you're facing a technical interview that possibly lasts an hour and a half, you won't be coding the entire time. You can also check out my older site, RubyQuiz.com, which has numerous problems but with slightly less consistency. To prepare yourself further, consider a book with over 600 pages of programming interview questions, explanations, and recommendations. Diving deep into these problems will get you familiar with what to expect during interviews.
00:18:06.410 Moreover, consider contributing to open-source projects; it’s beneficial to have code you can share when applying for jobs. Even a small gem can provide insight into your capabilities. I prefer simple code that doesn’t require sifting through thousands of lines to figure out its functionality. Including a straightforward readme, clean methods, and documentation can display the type of work you do daily, which the interviewer may find valuable.
00:19:12.760 Now that we’ve covered preparing for the interview, let’s focus on what you should do while taking the challenge. Your primary goal is to avoid being seen as a bad hire. Research indicates that while good hires contribute positively, bad hires can significantly diminish overall performance. Companies are focused on avoiding poor hiring decisions, so if you can steer clear of major mistakes, you’ll likely fare better than others.
00:20:02.650 My advice is to read the problem carefully; understanding what you're trying to solve is crucial. If questions are posed verbally, ensure you're asking clarifying questions until you thoroughly grasp the assignment. There are two key reasons for this: one, you have to know the problem to solve it correctly, and two, you need to get your interviewer on your side through clear communication.
00:20:52.330 It's a common mistake. When I interviewed at No Red Ink, a nice guy named Michael Glass asked me to reimplement the 'setTimeout' function in Ruby. I confidently opened a text editor thinking I knew the task, but he corrected me, explaining that JavaScript has no threads, just a single-threaded execution context. This is an important reminder: understanding the problem is essential to following directions. You’ll want to make a plan before you start coding; this strategy allows better time management.
00:22:34.690 Speaking out loud during the interview is also vital; this can be challenging for some candidates. If you struggle with verbalizing your thoughts, practice in front of a mirror or with friends. When I interview candidates, I often see them stop talking as they hesitate in their thought process. It’s essential they externalize their internal dialogues, so I might prompt them to articulate their considerations.
00:23:38.890 You should use phrases like 'My first thought is...' or 'I'm considering the trade-offs...'. Acknowledging the thought process behind your decisions shows that you're weighing options meaningfully. Similarly, admit when you don't know something. Saying 'I don't know' in an interview isn't a weakness; it's a sign of honesty, and it's better than pretending to know something when you don't. Interviewers appreciate this humility.
00:24:36.460 Moreover, maintain professionalism. During one interview, a candidate made inappropriate comments about a model on a website. Don’t do that; it’s essential to remember that humor should remain respectful. Being personable is great, but it should always be appropriate. When presented with an interview problem, start with the core components, especially the algorithm. Don't get sidetracked with excessive setup work, which can cost you valuable time.
00:26:37.890 Work on the interesting part first. If time runs out, you want to ensure you tackled the core challenge. You can add setup work or data imports later. On the same note, while developing your code, create test cases alongside it. Writing test cases while coding takes no extra time and can significantly enhance your presentation.
00:27:31.760 Avoid unnecessary dependencies unless stated otherwise in the problem. Interview problems usually revolve around simplicity, so refrain from over-complicating your solution. Additionally, minimize your code volume; avoid creating unnecessarily complex solutions. Remember not to gold-plate solutions; keep them concise and functional.
00:28:54.420 Ignore bonus challenges unless they’re specifically integrated into the main problem. Engagement with a bonus challenge often leads to extra work without sufficient time. Rather than attempting a challenging bonus feature, focus on the core task, effectively demonstrating your skills. Lastly, if you are physically present during the interview, brush up on your text editing skills. Being proficient with shortcuts can project familiarity and comfort with coding.
00:30:35.120 Finally, understand that interviewing can be hard for everyone. It's not just about the problems; you're competing against other candidates, so avoid major missteps. Incorporating these tips into your preparation can significantly improve your chances. Thanks for your time, and good luck with your future interviews!
Explore all talks recorded at RailsConf 2016
+106