Slide 1

Slide 1 text

Art and photos by Summer Gray Implementing the LHC on a Whiteboard How to survive coding interviews of all shapes and sizes

Slide 2

Slide 2 text

Why Coding Interviews?

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

What Is a Coding Interview? ❖ Take homes ❖ With or without time limits ❖ Technical interviews ❖ “Pairing” ❖ The dreaded whiteboard ❖ Auditions

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

What This Talk Is Not? ❖ Guaranteed ❖ A moral judgement ❖ All-knowing ❖ Respectful of your time

Slide 9

Slide 9 text

How Can You Prepare?

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

http://bigocheatsheet.com/

Slide 14

Slide 14 text

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!

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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)

Slide 20

Slide 20 text

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)

Slide 21

Slide 21 text

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] )

Slide 22

Slide 22 text

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)

Slide 23

Slide 23 text

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)

Slide 24

Slide 24 text

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)

Slide 25

Slide 25 text

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.

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

Ruby Can Sometimes Help ❖ Minitest::Benchmark supports: ❖ assert_performance_constant() ❖ assert_performance_exponential() ❖ assert_performance_linear() ❖ assert_performance_logarithmic() ❖ assert_performance_power()

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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.

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

Practice ❖ Work code challenges ❖ http://exercism.io/ ❖ http://rubyquiz.com/ ❖ You need to be able to consistently solve Exercism size problems in one hour

Slide 50

Slide 50 text

More Study and Practice

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

What To Do While Coding?

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

Tip #1 Read Carefully And/or ask as many clarifying questions as needed

Slide 55

Slide 55 text

Tip #2 Follow Directions Many candidates do not do this

Slide 56

Slide 56 text

Tip #3 Stop and Think You don’t have time not to do this

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

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.”

Slide 59

Slide 59 text

Tip #5 Don’t Make Offensive Comments Show that you have personality and a little bit of humor, but keep it appropriate

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

Tip #7 Test the Core Pretty much no one tests anything, so just a little, at the key place, is a win

Slide 62

Slide 62 text

Tip #8 Avoid Dependencies And don’t recreate them manually

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

Tip #11 Consider Time Limits Soft Submit on time, but resubmit later if needed

Slide 66

Slide 66 text

Tip #12 Show Off Your Text Editing Skills • Know five editing shortcuts • Make one multiple cursors or macros

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

Thanks and I hope you ace your interviews!