jeg2
May 05, 2016
680

# Implementing the LHC on a Whiteboard

A survival guide for passing coding interviews.

May 05, 2016

## Transcript

1. ### Art and photos by Summer Gray Implementing the LHC on

a Whiteboard How to survive coding interviews of all shapes and sizes

3. ### This Mismatch… ❖ Is keeping programmers from getting jobs ❖

Is likely due to a lack of interview training (especially compared to the other training we do in our industry) ❖ Is ﬁxable
4. ### What Is a Coding Interview? ❖ Take homes ❖ With

or without time limits ❖ Technical interviews ❖ “Pairing” ❖ The dreaded whiteboard ❖ Auditions

NoRedInk ❖ We get a lot of applicants ❖ Roughly 75% of the candidates fail our “take home” ❖ Around 30% of the rest fail their ﬁrst technical interview ❖ I see a lot of what doesn’t work
6. ### We’re hiring It’s In My Interest To Improve How You

Do The better candidates do, the faster we hire and the less I interview
7. ### What This Talk Is Not? ❖ Guaranteed ❖ A moral

judgement ❖ All-knowing ❖ Respectful of your time

9. ### Study ❖ Interviews commonly focus on a certain subset of

programming knowledge ❖ This probably isn’t knowledge that you use daily ❖ Ensuring it’s fresh in your brain can help
10. ### Concepts Data Structures Algorithms Big O Notation Hash Tables Binary

Search Dynamic Programming/ Memoization Trees/Tries/Graphs Bread-First Search/ Depth-First Search Recursion Linked Lists Merge Sort/ Quicksort Bit Manipulation Heaps Stacks and Queues
11. ### Concepts Data Structures Algorithms Big O Notation Hash Tables Binary

Search Dynamic Programming/ Memoization Trees/Tries/Graphs Bread-First Search/ Depth-First Search Recursion Linked Lists Merge Sort/ Quicksort Bit Manipulation Heaps Stacks and Queues

13. ### Big O Notation ❖ A metric used to describe an

upper bound on algorithm efﬁciency ❖ Can be used for time or space ❖ Drops constants and non-dominant terms ❖ Adds independent work; multiplies dependent work ❖ Not just an academic curiosity! It can help you solve problems faster and easier!
14. ### def sum_and_product(nums) { sum: nums.inject(0, :+), product: nums.inject(1, :*) }

end p sum_and_product(1..10)
15. ### def sum_and_product(nums) { sum: nums.inject(0, :+), product: nums.inject(1, :*) }

end p sum_and_product(1..10) O(n)
16. ### def sum_and_product(nums) { sum: nums.inject(0, :+), product: nums.inject(1, :*) }

end p sum_and_product(1..10) O(n)
17. ### module Fib module_function def recursive(i) return i if i <

2 recursive(i - 2) + recursive(i - 1) end end p Fib.recursive(10)
18. ### module Fib module_function def recursive(i) return i if i <

2 recursive(i - 2) + recursive(i - 1) end end p Fib.recursive(10) O(2n)
19. ### module Fib module_function def recursive(i) return i if i <

2 recursive(i - 2) + recursive(i - 1) end end p Fib.recursive(10) O(branchesdepth) O(2n)
20. ### def shared_count(a, b) sorted = b.sort a.count { |i| sorted.bsearch

{ |j| j >= i } == i } end p shared_count( [35, 55, 13, 49, 40, 59, 27], [39, 40, 60, 17, 55, 58, 35] )
21. ### def shared_count(a, b) sorted = b.sort a.count { |i| sorted.bsearch

{ |j| j >= i } == i } end p shared_count( [35, 55, 13, 49, 40, 59, 27], [39, 40, 60, 17, 55, 58, 35] ) O(b log b + a log b)
22. ### def shared_count(a, b) sorted = b.sort a.count { |i| sorted.bsearch

{ |j| j >= i } == i } end p shared_count( [35, 55, 13, 49, 40, 59, 27], [39, 40, 60, 17, 55, 58, 35] ) O(b log b + a log b)
23. ### def shared_count(a, b) sorted = b.sort a.count { |i| sorted.bsearch

{ |j| j >= i } == i } end p shared_count( [35, 55, 13, 49, 40, 59, 27], [39, 40, 60, 17, 55, 58, 35] ) O(b log b + a log b)
24. ### A: 13, 27, 35, 40, 49, 55, 59 B: 17,

35, 39, 40, 55, 58, 60 Given two sorted arrays, ﬁnd the elements in common. The arrays are the same length and each has all distinct elements.
25. ### A Brute Force Solution a = [13, 27, 35, 40,

49, 55, 59] b = [17, 35, 39, 40, 55, 58, 60] shared = a.select { |n| b.include?(n) } p shared
26. ### A Brute Force Solution a = [13, 27, 35, 40,

49, 55, 59] b = [17, 35, 39, 40, 55, 58, 60] shared = a.select { |n| b.include?(n) } p shared
27. ### Bungling Towards Ideal a = [13, 27, 35, 40, 49,

55, 59] b = [17, 35, 39, 40, 55, 58, 60] i = 0 shared = b.each_with_object([ ]) do |n, array| while i < a.size && a[i] < n i += 1 end array << n if a[i] == n end p shared
28. ### Bungling Towards Ideal a = [13, 27, 35, 40, 49,

55, 59] b = [17, 35, 39, 40, 55, 58, 60] i = 0 shared = b.each_with_object([ ]) do |n, array| while i < a.size && a[i] < n i += 1 end array << n if a[i] == n end p shared
29. ### Bungling Towards Ideal a = [13, 27, 35, 40, 49,

55, 59] b = [17, 35, 39, 40, 55, 58, 60] i = 0 shared = b.each_with_object([ ]) do |n, array| while i < a.size && a[i] < n i += 1 end array << n if a[i] == n end p shared
30. ### Straightforward Linear a = [13, 27, 35, 40, 49, 55,

59] b = [17, 35, 39, 40, 55, 58, 60] c = b.each_with_object({ }) do |n, hash| hash[n] = true end shared = a.select { |n| c.include?(n) } p shared
31. ### Straightforward Linear a = [13, 27, 35, 40, 49, 55,

59] b = [17, 35, 39, 40, 55, 58, 60] c = b.each_with_object({ }) do |n, hash| hash[n] = true end shared = a.select { |n| c.include?(n) } p shared
32. ### Ruby Can Sometimes Help ❖ Minitest::Benchmark supports: ❖ assert_performance_constant() ❖

assert_performance_exponential() ❖ assert_performance_linear() ❖ assert_performance_logarithmic() ❖ assert_performance_power()
33. ### Analyzing Algorithms module Fib module_function def recursive(i) return i if

i < 2 recursive(i - 2) + recursive(i - 1) end def memoized(i) cache = Hash.new { |hash, n| hash[n] = n < 2 ? n : hash[n - 2] + hash[n - 1] } cache[i] end def dynamic(i) return i if i < 2 a, b = 0, 1 (i - 2).times do a, b = b, a + b end a + b end end
34. ### Analyzing Algorithms module Fib module_function def recursive(i) return i if

i < 2 recursive(i - 2) + recursive(i - 1) end def memoized(i) cache = Hash.new { |hash, n| hash[n] = n < 2 ? n : hash[n - 2] + hash[n - 1] } cache[i] end def dynamic(i) return i if i < 2 a, b = 0, 1 (i - 2).times do a, b = b, a + b end a + b end end
35. ### Analyzing Algorithms module Fib module_function def recursive(i) return i if

i < 2 recursive(i - 2) + recursive(i - 1) end def memoized(i) cache = Hash.new { |hash, n| hash[n] = n < 2 ? n : hash[n - 2] + hash[n - 1] } cache[i] end def dynamic(i) return i if i < 2 a, b = 0, 1 (i - 2).times do a, b = b, a + b end a + b end end
36. ### Analyzing Algorithms module Fib module_function def recursive(i) return i if

i < 2 recursive(i - 2) + recursive(i - 1) end def memoized(i) cache = Hash.new { |hash, n| hash[n] = n < 2 ? n : hash[n - 2] + hash[n - 1] } cache[i] end def dynamic(i) return i if i < 2 a, b = 0, 1 (i - 2).times do a, b = b, a + b end a + b end end
37. ### Almost Helpful require "minitest/autorun" require "minitest/benchmark" require_relative "fib" class FibRecursiveBench

< Minitest::Benchmark def self.bench_range [1, 3, 30] end def bench_recursive_fib assert_performance_exponential do |n| Fib.recursive(n) end end end
38. ### Almost Helpful require "minitest/autorun" require "minitest/benchmark" require_relative "fib" class FibRecursiveBench

< Minitest::Benchmark def self.bench_range [1, 3, 30] end def bench_recursive_fib assert_performance_exponential do |n| Fib.recursive(n) end end end
39. ### Almost Helpful require "minitest/autorun" require "minitest/benchmark" require_relative "fib" class FibRecursiveBench

< Minitest::Benchmark def self.bench_range [1, 3, 30] end def bench_recursive_fib assert_performance_exponential do |n| Fib.recursive(n) end end end
40. ### More Helpful require "minitest/autorun" require "minitest/benchmark" require_relative "fib" class FibMemoizedBench

< Minitest::Benchmark def self.bench_range bench_exp(1, 1_000) end def bench_memoized_fib assert_performance_linear do |n| Fib.memoized(n) end end end
41. ### More Helpful require "minitest/autorun" require "minitest/benchmark" require_relative "fib" class FibMemoizedBench

< Minitest::Benchmark def self.bench_range bench_exp(1, 1_000) end def bench_memoized_fib assert_performance_linear do |n| Fib.memoized(n) end end end
42. ### More Helpful require "minitest/autorun" require "minitest/benchmark" require_relative "fib" class FibMemoizedBench

< Minitest::Benchmark def self.bench_range bench_exp(1, 1_000) end def bench_memoized_fib assert_performance_linear do |n| Fib.memoized(n) end end end
43. ### The Most Helpful require "minitest/autorun" require "minitest/benchmark" require_relative "fib" class

FibDynamicBench < Minitest::Benchmark def bench_dynamic_fib assert_performance_linear do |n| Fib.dynamic(n) end end end
44. ### The Most Helpful require "minitest/autorun" require "minitest/benchmark" require_relative "fib" class

FibDynamicBench < Minitest::Benchmark def bench_dynamic_fib assert_performance_linear do |n| Fib.dynamic(n) end end end
45. ### The classic “Nine Balls” interview brainteaser You have nine balls.

Eight are the same weight and one is heavier. You are given a balance which tells you only wether the left side or right side is heavier. Find the heavy ball in just two uses of the scale.
46. ### Practice ❖ Work code challenges ❖ http://exercism.io/ ❖ http://rubyquiz.com/ ❖

You need to be able to consistently solve Exercism size problems in one hour

48. ### Have Some Open Source ❖ Be able to point to

a published gem ❖ It barely matters what it does ❖ The most important details are a strong README, clean code, tests, and documentation ❖ A small gem is ﬁne

50. ### Goals ❖ Not the same as normal on the job

programming ❖ You need to avoid being seen as a bad hire ❖ If you can avoid major mistakes, you’re ahead

as needed

to do this
54. ### Tip #4 Think Out Loud Magic words: • “My ﬁrst

thought is…” • “I’m considering the tradeoffs…” • “I might circle back to this…” • “I don’t know.”
55. ### Tip #5 Don’t Make Offensive Comments Show that you have

personality and a little bit of humor, but keep it appropriate
56. ### Tip #6 Start at the Hard Part • Don’t begin

by designing objects • Jump straight to the interesting bit • Fake input as needed • Ignore UI completely
57. ### Tip #7 Test the Core Pretty much no one tests

anything, so just a little, at the key place, is a win

it
61. ### Tip #11 Consider Time Limits Soft Submit on time, but

resubmit later if needed
62. ### Tip #12 Show Off Your Text Editing Skills • Know

ﬁve editing shortcuts • Make one multiple cursors or macros
63. ### Maximizing for Success ❖ You probably won’t nail all of

my tips every time ❖ That’s ﬁne ❖ Interviews are hard for everyone and everyone makes mistakes ❖ Hit as many of the points we’ve discussed as you can ❖ Those you get will help