15 Questions to Ask During a Ruby Interview
June 17th, 2008 by RyanWhen hiring Ruby on Rails programmers, knowing the right questions to ask during an interview was a real challenge for me at first. In 30 minutes or less, it’s difficult to get a solid read on a candidate’s skill set without looking at code they’ve previously written. And in the corporate/enterprise world, I often don’t have access to their previous work.
To ensure we hired competent ruby developers at my last job, I created a list of 15 ruby questions — a ruby measuring stick if you will — to select the cream of the crop that walked through our doors.
What to expect
Candidates will typically give you a range of responses based on their experience and personality. So it’s up to you to decide the correctness of their answer.
There are many solutions to most of these questions — some aren’t listed here. Candidates get my respect for knowing esoteric solutions, but I’m looking for developers with similar practices to my own.
Make no mistake, this list is not complete, by any means. But it does provide a useful tool to put a candidate’s reaction to the same series of questions in perspective. Especially during an interview, when your mouth goes dry and and your hands get all sweaty.
Begin!
Senior programmers won’t have a problem with these, while junior programmers will usually give only half-answers.
What is a class?
A text-book answer: classes are a blue-print for constructing computer models for real or virtual objects… boring.
In reality: classes hold data, have methods that interact with that data, and are used to instantiate objects.
Like this.
class WhatAreClasses
def initialize
@data = "I'm instance data of this object. Hello."
end
def method
puts @data.gsub("instance", "altered")
end
end
object = WhatAreClasses.new
object.method
#=> I'm altered data of this object. Hello.
What is an object?
An instance of a class.
To some, it’s also the root class in ruby (Object).
Classes themselves descend from the Object root class. (Kudos to Ezra)
What is a module? Can you tell me the difference between classes and modules?
Modules serve as a mechanism for namespaces.
module ANamespace
class AClass
def initialize
puts "Another object, coming right up!"
end
end
end
ANamespace::AClass.new
#=> Another object, coming right up!
Also, modules provide as a mechanism for multiple inheritance via mix-ins and cannot be instantiated like classes can.
module AMixIn
def who_am_i?
puts "An existentialist, that's who."
end
end
# String is already the parent class
class DeepString < String
# extend adds instance methods from AMixIn as class methods
extend AMixIn
end
DeepString.who_am_i?
#=> An existentialist, that's who.
AMixIn.new
#=> NoMethodError: undefined method ‘new’ for AMixIn:Module
Can you tell me the three levels of method access control for classes and modules? What do they imply about the method?
All methods, no matter the access control, can be accessed within the class. But what about outside callers?
Public methods enforce no access control — they can be called in any scope.
Protected methods are only accessible to other objects of the same class.
Private methods are only accessible within the context of the current object.
class AccessLevel
def something_interesting
another = AccessLevel.new
another.public_method
another.protected_method
another.private_method
end
def public_method
puts "Public method. Nice to meet you."
end
protected
def protected_method
puts "Protected method. Sweet!"
end
private
def private_method
puts "Incoming exception!"
end
end
AccessLevel.new.something_interesting
#=> Public method. Nice to meet you.
#=> Protected method. Sweet!
#=> NoMethodError: private method ‘private_method’ called for
#=> #<AccessLevel:0x898c8>
There are three ways to invoke a method in ruby. Can you give me at least two?
Here, I’m looking for the dot operator (or period operator), the Object#send method, or method(:foo).call
object = Object.new puts object.object_id #=> 282660 puts object.send(:object_id) #=> 282660 puts object.method(:object_id).call # (Kudos to Ezra) #=> 282660
Separating the professional from the hobbyist
Senior programmers should be able to give competent answers for all questions. Junior programmers should answer some correct, but usually won’t know them all.
Explain this ruby idiom: a ||= b
A common idiom that strong ruby developers use all the time.
# a = b when a == false # otherwise a remains unchanged a || a = b # (Kudos to Markus Prinz)
a = 1 b = 2 a ||= b #=> a = 1
a = nil b = 2 a ||= b #=> a = 2
a = false b = 2 a ||= b #=> a = 2
What does self mean?
self always refers to the current object. But this question is more difficult than it seems because Classes are also objects in ruby. (Kudos to Stephen)
class WhatIsSelf
def test
puts "At the instance level, self is #{self}"
end
def self.test
puts "At the class level, self is #{self}"
end
end
WhatIsSelf.test
#=> At the class level, self is WhatIsSelf
WhatIsSelf.new.test
#=> At the instance level, self is #<WhatIsSelf:0x28190>
This short snippet indicates two things:
- at the class level, self is the class, in this case WhatIsSelf.
- at the instance level, self is the instance in context, in this case the instance of WhatIsSelf at memory location 0×28190.
What is a Proc?
Everyone usually confuses procs with blocks, but the strongest rubyist can grok the true meaning of the question.
Essentially, Procs are anonymous methods (or nameless functions) containing code. They can be placed inside a variable and passed around like any other object or scalar value. They are created by Proc.new, lambda, and blocks (invoked by the yield keyword).
Note: Procs and lambdas do have subtle, but important, differences in ruby v1.8.6. However, I wouldn’t expect a candidate talk about these nitty-gritty details during an interview. (Kudos to Noah Thorp)
# wants a proc, a lambda, AND a block
def three_ways(proc, lambda, &block)
proc.call
lambda.call
yield # like block.call
puts "#{proc.inspect} #{lambda.inspect} #{block.inspect}"
end
anonymous = Proc.new { puts "I'm a Proc for sure." }
nameless = lambda { puts "But what about me?" }
three_ways(anonymous, nameless) do
puts "I'm a block, but could it be???"
end
#=> I'm a Proc for sure.
#=> But what about me?
#=> I'm a block, but could it be???
#=> #<Proc:0x00089d64> #<Proc:0x00089c74> #<Proc:0x00089b34>
What is unit testing (in classical terms)? What is the primary technique when writing a test?
The strongest candidates should be quite comfortable with test or behavior driven development.
Unit testing, simply put, is testing methods — the smallest unit in object-oriented programming. Strong candidates will argue that it allows a developer to flesh out their API before it’s consumed by other systems in the application.
The primary way to achieve this is to assert that the actual result of the method matches an expected result.
require "test/unit"
class Brokened
def uh_oh
"I needs fixing"
end
end
class BrokenedTest < Test::Unit::TestCase
def test_uh_oh
actual = Brokened.new
assert_equal("I'm all better!", actual.uh_oh)
end
end
#=> Started
#=> F
#=> Finished in 0.663831 seconds.
#=>
#=> 1) Failure:
#=> test_uh_oh:11
#=> <"I'm all better!"> expected but was
#=> <"I needs fixing">.
#=>
#=> 1 tests, 1 assertions, 1 failures, 0 errors
Show me the money!
Variable typing is one of those topics that everyone sort of understands it, but is hard to put it into words. I’ve iterated and improved the next series of questions to really test a senior level candidate’s knowledge of static and dynamic typing. This is my best attempt so far.
What is the primary difference in these two code snippets?
// Java
public boolean isEmpty(String s) {
return s.length() == 0;
}
# ruby
def empty?(s)
return s.size == 0
end
The Java method only accepts Strings as arguments and only returns a boolean while…
The ruby method accepts any Object and could return anything, but in this case will return a boolean if executed without exceptions.
What does this say about the advantages of ruby’s dynamic (duck) typed system?
That ruby program use less code and are more flexible.
What are some disadvantages (real and potential)?
Developers cannot be 100% certain that all arguments sent this empty? method will have a size method that is publicly accessible. Also, ruby is an interpreted language and it may take longer to run than compiled programs, such as Java, that are programmed similarly.
What could a developer do to address these disadvantages?
She could write unit tests or specs to ensure her application behaves as intended. She could also profile her application with tools like the unix time command, the ruby Benchmark class, and the ruby library called ruby-prof.
A cunning programmer would also argue that these two techniques ought to be used for both static and dynamic languages when developing complex systems.
Wrapping things up
To finish up with, I like to lob in some easy ones again. Plus I’m like to scratch my own curiosity about a candidates relationship with the ruby community.
What are rubygems? Any favorites not including rails? Any that you’ve worked on personally?
rubygems is package manager software for ruby libraries (i.e. gems). The package manager has basic CRUD operations, dependency trees, and supports asynchronous communication between multiple gem servers.
What is your favorite api resource for ruby?
I really like gotAPI — auto-complete searching for both ruby and rails together!
Your Own Questions?
I really want to know how you interview candidates for your ruby positions! Ruby is being used heavily at many companies all over the world for external and internal use alike. Please share your ideas with the rest of us!
June 18th, 2008 at 8:50 am
[...] read more | digg story [...]
June 18th, 2008 at 9:23 am
Do you have an equivalent set of questions for Rails ?
June 18th, 2008 at 9:25 am
Look for my rails questions in a follow up article.
June 18th, 2008 at 10:33 am
Great article.
One thing about lambdas and procs. Even though they appear to be the same class they do not behave completely the same. From running my_lambda.inspect and seeing the Proc instance you would never guess it but they are different.
Essentially lambda and Proc.new handle arguments and the “return” statement differently. Also the “proc” method returns a lambda not a Proc.
Here’s some code to prove the point. The argument handling is the easiest to demo:
my_proc = Proc.new {|x,y| print x,y} my_lambda = lambda {|x,y| print x,y} my_other_proc = proc {|x,y| print x,y}pass in one variable instead of 2
my_proc.call(1) #this doesn’t throw an error and sets y to nil my_lambda.call(1) #this throws an error my_other_proc.call(1) #this throws an error like a lambda because it actually is a lambda not a proc in ruby 1.8.6
Also in Ruby 1.9 I think that the “proc” method (as seen in line three) will actually return a Proc and not a lambda as it does here. Ruby 1.9 will also add a “lambda?” method for you to clarify the difference between a Proc and a lambda. As a general practice it’s best to use Proc.new or lambda but not the “proc” method because of the upcoming change in Ruby 1.9.
O’Reilly’s book “The Ruby Programming Language” by Matz (Yukihiro Matsumoto) and David Flanagen has a great chapter on this.
Noah Thorp Rixiform.com / Aquabu.com
http://www.aquabu.com/2008/6/18/proc-new-lambda-and-proc
June 18th, 2008 at 10:45 am
I can digg it! Very informative and to the point, a good read.
June 18th, 2008 at 11:01 am
Noah - I’m glad you brought this up. Procs and lambdas are not 100% equal, but similar enough in the context of the question. Fortunately, some of those differences will be ironed out for ruby 1.9.
I’ve updated the article to reflect this and provided a link to wikipedia for a more detailed explanation with code samples.
June 18th, 2008 at 8:54 pm
and also, I should add the difference between lambda and Proc as by Sam: http://samdanielson.com/2007/3/19/proc-new-vs-lambda-in-ruby
June 18th, 2008 at 9:18 pm
If you could only ask one question, what would it be? i might ask:
what does this code do, and how would you use it?
module Enumerable def injecting(s) inject(s) do |k, i| yield(k, i); k end end endhits the highpoints :)
June 18th, 2008 at 10:56 pm
Nice article. Learned something about the technical definition of a module!
June 19th, 2008 at 11:05 am
i dont think your questions are hard enough to weed out the newbies. i started using ruby two weeks ago and i was able to answer all of them. throw in some stuff about meta programming, missing methods and so on to see the diffrance between seniors and beginners
June 19th, 2008 at 11:41 am
cyrik - It would be awesome to only hire meta-programming whizz-kids. But in reality, meta-programming is only one small aspect of the programmer field at large. Typically, this isn’t a requirement for our positions, but an advantage none-the-less.
June 19th, 2008 at 8:41 pm
[...] the companies hiring developers with the knowledge of Ruby, Ritirisi blog posts some valuable Ruby interview questions to ask. Note that those are mostly Ruby questions - not Ruby on Rails [...]
June 20th, 2008 at 8:56 am
class Surprise def size return self end def ==(o) return "Lord Byron Farthammer. Bet you didn't see that one coming." end end s = Surprise.new empty?(s)June 20th, 2008 at 9:10 am
Bob - Lord Byron Farthammer fears nothing and is surprised by less. Nice use of self and == method overloading.
June 21st, 2008 at 9:17 pm
Nice post.
Explain what this code does: (To get their understanding of meta hooking modules)
module something self.included(base) def do_this ... end end endand perhaps some questions explaining what things like: things.collect(&name)
June 25th, 2008 at 8:51 am
The best way to recruit amazing talent is to approach people that you already know are at the top of their game. At this point, the most important question becomes whether their personality is a good fit for the existing team.
Really, if an awesome person who is clearly smart doesn’t know the answer to one of these questions, they can learn it quickly with a little direction. That’s the advantage of having a team - you help each other move forward.
We’re so connected as a community now that the idea of waiting for talented people to beg you for interviews seems regressive and baroque.
June 25th, 2008 at 8:51 am
Your explanation of “a ||= b” is actually not quite right.
“a ||= b” actually expands to “a or a = b”. In most cases this is the same as “a = a || b”, but there are some edge cases, usually when working with (Hash) defaults, according to David A. Black: http://dablog.rubypal.com/2008/3/25/a-short-circuit-edge-case
The example he gives looks like this:
h = Hash.new(1) => {} h[:x] => 1 h => {} h[:x] ||= 2 => 1 h => {} # still empty! h[:x] = h[:x] || 2 # Manually expand it => 1 h => {:x=>1} # no longer empty. Why? h[:y] or h[:y] = 2 # What ||= actually expands to => 1 h => {:x=>1} # Hash hasn’t changedJune 25th, 2008 at 9:13 am
Pete - I couldn’t agree with you more. I wish every company had the confidence to recruit great talent away from dead-end jobs. Unfortunately, most companies don’t invest that much time or effort into recruiting the RIGHT kind of help like they probably should.
June 25th, 2008 at 9:20 am
Markus - You’ve got to love edge cases — David’s explanation is superb. The article has been properly corrected.
June 26th, 2008 at 11:25 am
Great article Ryan. Now I am well prepared to come interview with you for a job as a Ruby programmer!
June 27th, 2008 at 2:47 pm
[...] (and it got a crazy number of comments), but now Ryan Ritirisi has put together a great list of 15 Questions to Ask During a Ruby Interview. They include questioning developers in a way that can separate professional Ruby developers from [...]
June 27th, 2008 at 3:09 pm
A few things. In ruby classes are objects too, there is no distinction. Also there are more then 2 ways to call a method. you can also do method(:foo).call.
June 27th, 2008 at 4:00 pm
Ezra - Duly noted and corrected. Thank you!
June 28th, 2008 at 5:17 am
maybe a few more things:
besides that it’s pretty complete and I’m surprised that I know 95% :-)
June 28th, 2008 at 9:00 am
Hey, even for someone learning, this is really helpful to see what I need a better understanding in. Thanks!
June 28th, 2008 at 10:31 am
There actually aren’t two meanings for self; Ezra’s point that classes are objects too means that self always refers to the current object — it’s just that when you’re defining a class, the current object is the class.
June 28th, 2008 at 11:33 am
Stephen - That is a clear and simple explanation. I’ve updated the article.
June 28th, 2008 at 6:16 pm
I never used Ruby before but I could answer a lot of the questions. Excepted “a ||= b” and the last two one on the ecosystem.
I think that your questions could apply to any dynamically typed OO.
I always wonder what is the relative value of knowing concept versus being an expert in a particular language ?
June 29th, 2008 at 1:54 pm
For the ‘What is the primary difference in these two code snippets?’ question:
I’d probably write the Java snippet as: ’s.length == 0′. A few reasons:
For ‘What does this say about the advantages of ruby’s dynamic (duck) typed system?’, I would really expect something more detailed than ‘less code and more dynamic’. I’d expect things like mentioning implicitly returned values, that length/size are actually methods, that you can omit parentheses for method calls in most cases. They might also point out that Ruby’s String already has an ‘empty?’ method, and if it didn’t, you could easily reopen String to add it.
June 30th, 2008 at 8:57 am
Antoine - I should mention that we encouraged non-ruby developers to apply with us as well. It’s clear that we choose to take a fundamentals approach to hiring rather than the expert approach. Your mileage may vary.
July 1st, 2008 at 12:42 am
Ryan, the list seems good but there seems to be more to ask when you really wanna diff hobbyist from expert. I have been preparing for a few interviews lately and i found these list of questions from Steve (http://www.oreillynet.com/ruby/blog/2006/03/interviewing_ruby_programmers.html) were helpful. They helped me prepare better and some were definitely “asked”.
July 1st, 2008 at 8:51 am
[...] 15 questions to ask during a Ruby inteview On the other hand, I aced this test, so I’m feeling a little bit better about my meager skills. [...]
July 5th, 2008 at 12:09 pm
In my hiring experience, these basic knowledge questions will only be useful in weeding out the most inexperienced developers. It’s very easy to find the minimally competent. It’s far more important to find the cream of the crop. To that end, I find it far more interesting and valuable to ask questions that let you get a glimpse into the thought processes and working habits of the potential hire.
When you ask a question like “What is a Proc?” you will learn one thing: whether or not they know what a Proc is. This won’t tell you if they actually understand its use. This question could be better phrased as “When might you use a proc in Ruby?”
Also, ask open-ended questions like what considerations they would make when designing and coding a specific system that solves a real business need. Ask them to review a section of your existing codebase that you’ve flagged as needing attention (refactoring or otherwise) and suggest improvements
Ask questions that allow them to show you their consideration of an area that is important. For instance, “Do you prefer a specific style of testing (for instance, TDD or BDD)? What is your testing framework of choice and why?” The answers to this sort of question will prove far more valuable than to questions like “What is the classical definition of Unit Testing?”
July 7th, 2008 at 1:32 am
Kind of nitpicky - okay, very nitpicky - have you hacked Kernel#puts in your IRb to prepend “#=>”? I prepend that to Wirble return-value output, yes, but… it seems like bad form to mess with Kernel#puts unless I’m missing something. I was a little confused reading through the examples d-:
Awesome article, though. I knew pretty much everything you listed, which makes me feel good about myself, but some of the terminology worries me - I’m new to the programming community, do you know if it’s common for prospective employers to worry about the terminology? I could easily explain anything listed here, but I’d probably never come across phrases like “anonymous methods”, “scalar value”, or “method access control” (probably because I taught myself everything I know by listening in on the community or just coding and using the API - no formal classes). I’m just curious if y’all think that’d be a sticking point with a quality employer. >,>
August 24th, 2008 at 9:27 am
Hi, It really great article about the classes in the ruby I am totally new in Ruby but After reading I got info classes in a ruby thanks for such nice article and keep it up . Some of more Ruby FAQs You can also these its really help other people
thanks
December 2nd, 2008 at 8:15 am
Great Article, will be very handy in th e
My 2 cents would be:
What would be a potential danger of opening ruby classes ( like Object,Array e.t.c)
What would be the difference between class method and instance method
What is the difference between include and extend
In the general area questions I would ask: What was the biggest problem you had to solve/implement. Why did you find it hard? What was the solution?
I was asked this question on my last interview, and found it to be more interesting and compelling to talk about rather then to repeat ri Array#sort description.
P.S.
module Kernel;def puts(val);$stdout.puts “#=> #{val}” ;end;end
December 7th, 2008 at 4:02 am
[...] em suas experiências, o Ryan elaborou 15 questões gerais, sobre a linguagem Ruby, para serem usadas numa entrevista e possibilitar analisar o conhecimento do candidato sobre a [...]