Evaluating HackerRank for Tech Hiring
We were looking at HackerRank to see if it could help us alleviate some of the interview and review load on our senior developers.
Some observations:
- I feel this is a more “sophisticated” FizzBuzz for filtering candidates who say they can program but in reality cannot.
- The exercise by its nature focuses on results, not on some of the more (in my opinion) important metrics of code quality such as maintainability, readability, discipline, testability, etc.
- The time limit practically forces the applicant to cowboy code instead of practicing their code discipline. I don’t really want to get cowboy coders on my team.
- (Note: I experienced this with Codility and not with HackerRank directly, but since they are in a similar niche, I feel I can extrapolate from there.) The harder algorithm problems test whether you know a particular algorithm or not (like splitting binary trees). Although such knowledge is great if you’re making the next high-performance NoSQL database server or a natural language processing library, it’s less useful for web developer applicants. The danger is assuming that someone good at these kinds of “puzzles” would also be good at solving business problems; I feel it’s just not a good predictor.
- Following on the previous point, there is a danger that the hiring manager, having all these crisp numbers, would use them exclusively as a predictor of skill or aptitude; they’re not. These methods produce a high number of false positives (up to a certain number of applications), so I feel it’s better to invest in a more involved programming challenge (like what we do at Mindvalley). If we were getting hundreds of applications with a wide range of skill levels every week, then I think it would be worth filtering with these challenges since the time savings would outweigh the risk of false positives. Right now, Mindvalley receives a trickle of really high-quality applicants, so there’s no need to test them at a FizzBuzz level.
I tried the questions for myself, with the time limit and all, to find out what kind of experience potential applicants would have. I was not able to finish all four questions within 30 minutes as I was doing TDD, and had to figure out that I needed to send my output to STDOUT for the checker to confirm my answers. I did eventually find out that the last two questions were actually SQL questions, which would probably have taken me around 10 to 15 minutes tops.
I’m not allowed to reproduce the questions, so I’m just pasting here my answers :P
def lastLetter(word)
word = word.strip
last_two_letters = get_last_two_letters(word)
reversed = last_two_letters.reverse
result = reversed.split("").join(" ")
puts result
result
end
def get_last_two_letters(word)
word[word.length - 2, word.length]
end
# require "rspec"
# require "rspec-given"
# describe "lastLetter" do
# Given(:word) { "APPLE" }
# context "getting the last two letters" do
# When(:last_two_letters) { get_last_two_letters(word) }
# Then { last_two_letters == "LE" }
# end
# context "getting the result" do
# When(:result) { lastLetter(word) }
# Then { result == "E L"}
# end
# context "edge cases" do
# context "1 character long" do
# Given(:word) { "a" }
# When(:result) { lastLetter(word) }
# Then { result == "a"}
# end
# context "last character is a space" do
# Given(:word) { "a " }
# When(:result) { lastLetter(word) }
# Then { result == "a"}
# end
# end
# end
def solvePuzzle(num)
num = num.to_s
result = num.split("").reduce(0) { |sum, num| sum + get_num_holes(num.to_i) }
puts result
result
end
def get_num_holes(num)
return 0 if [1, 2, 3, 5, 7].include?(num)
return 1 if [0, 4, 6, 9].include?(num)
return 2 if [8].include?(num)
end
# require "rspec"
# require "rspec-given"
# describe "number of holes" do
# context "solution" do
# Given(:num) { "9899" }
# When(:result) { solvePuzzle(num) }
# Then { result == 5 }
# end
# context "zero hole" do
# context do
# Given(:number) { 1 }
# When(:num_holes) { get_num_holes(number) }
# Then { num_holes == 0 }
# end
# context do
# Given(:number) { 2 }
# When(:num_holes) { get_num_holes(number) }
# Then { num_holes == 0 }
# end
# end
# context "one hole" do
# context do
# Given(:number) { 0 }
# When(:num_holes) { get_num_holes(number) }
# Then { num_holes == 1 }
# end
# context do
# Given(:number) { 4 }
# When(:num_holes) { get_num_holes(number) }
# Then { num_holes == 1 }
# end
# end
# end