Implementing the LHC on a Whiteboard

259f23c3b129f07b0c496b9f0495f07e?s=47 jeg2
May 05, 2016

Implementing the LHC on a Whiteboard

A survival guide for passing coding interviews.

259f23c3b129f07b0c496b9f0495f07e?s=128

jeg2

May 05, 2016
Tweet

Transcript

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

    a Whiteboard How to survive coding interviews of all shapes and sizes
  2. Why Coding Interviews?

  3. None
  4. 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 fixable
  5. What Is a Coding Interview? ❖ Take homes ❖ With

    or without time limits ❖ Technical interviews ❖ “Pairing” ❖ The dreaded whiteboard ❖ Auditions
  6. What Do I Know About This? ❖ I work for

    NoRedInk ❖ We get a lot of applicants ❖ Roughly 75% of the candidates fail our “take home” ❖ Around 30% of the rest fail their first technical interview ❖ I see a lot of what doesn’t work
  7. 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
  8. What This Talk Is Not? ❖ Guaranteed ❖ A moral

    judgement ❖ All-knowing ❖ Respectful of your time
  9. How Can You Prepare?

  10. 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
  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
  12. 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. http://bigocheatsheet.com/

  14. Big O Notation ❖ A metric used to describe an

    upper bound on algorithm efficiency ❖ 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!
  15. def sum_and_product(nums) { sum: nums.inject(0, :+), product: nums.inject(1, :*) }

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

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

    end p sum_and_product(1..10) O(n)
  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)
  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(2n)
  20. 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)
  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] )
  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. 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)
  25. A: 13, 27, 35, 40, 49, 55, 59 B: 17,

    35, 39, 40, 55, 58, 60 Given two sorted arrays, find the elements in common. The arrays are the same length and each has all distinct elements.
  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. 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
  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. 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
  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. 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
  33. Ruby Can Sometimes Help ❖ Minitest::Benchmark supports: ❖ assert_performance_constant() ❖

    assert_performance_exponential() ❖ assert_performance_linear() ❖ assert_performance_logarithmic() ❖ assert_performance_power()
  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. 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
  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. 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
  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. 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
  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 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
  46. 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.
  47. None
  48. None
  49. Practice ❖ Work code challenges ❖ http://exercism.io/ ❖ http://rubyquiz.com/ ❖

    You need to be able to consistently solve Exercism size problems in one hour
  50. More Study and Practice

  51. 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 fine
  52. What To Do While Coding?

  53. 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
  54. Tip #1 Read Carefully And/or ask as many clarifying questions

    as needed
  55. Tip #2 Follow Directions Many candidates do not do this

  56. Tip #3 Stop and Think You don’t have time not

    to do this
  57. None
  58. Tip #4 Think Out Loud Magic words: • “My first

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

    personality and a little bit of humor, but keep it appropriate
  60. 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
  61. Tip #7 Test the Core Pretty much no one tests

    anything, so just a little, at the key place, is a win
  62. Tip #8 Avoid Dependencies And don’t recreate them manually

  63. Tip #9 Write Less Code Don’t “gold plate”

  64. Tip #10 Ignore “Bonus” Challenges Seriously, it’s just not worth

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

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

    five editing shortcuts • Make one multiple cursors or macros
  67. Maximizing for Success ❖ You probably won’t nail all of

    my tips every time ❖ That’s fine ❖ 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
  68. Thanks and I hope you ace your interviews!