• 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
     #=>  #
    
    
  • 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 0x28190.

  • 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???
     #=> # # #
    
    
  • Difference between a proc and lambda

    Lambdas check the number of arguments, while procs do not

    lam = lambda { |x| puts x }    # creates a lambda that takes 1 argument
    lam.call(2)                    # prints out 2
    lam.call                       # ArgumentError: wrong number of arguments (0 for 1)
    lam.call(1,2,3)                # ArgumentError: wrong number of arguments (3 for 1)

    In contrast, procs don’t care if they are passed the wrong number of arguments.
    proc = Proc.new { |x| puts x } # creates a proc that takes 1 argument
    proc.call(2)                   # prints out 2
    proc.call                      # returns nil
    proc.call(1,2,3)               # prints out 1 and forgets about the extra arguments

    Lambdas and procs treat the ‘return’ keyword differently
    ‘return’ inside of a lambda triggers the code right outside of the lambda code

    def lambda_test
    lam = lambda { return }
    lam.call
    puts "Hello world"
    end
    lambda_test # calling lambda_test prints 'Hello World'


    `return` inside of a proc triggers the code outside of the method where the proc is being executed

    def proc_test
    proc = Proc.new { return }
    proc.call
    puts "Hello world"
    end
    
    proc_test # calling proc_test prints nothing

     

  • 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 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!

  • Difference between Preload, Include, Eager Load and Joins in Rails?


    Preload

     
    Preload loads the association data in a separate query.

    User.preload(:posts).to_a
    
    # =>
    SELECT "users".* FROM "users"
    SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1)


    This is how includes loads data in the default case.

    Since preload always generates two sql we can’t use posts table in where condition. Following query will result in an error.

    User.preload(:posts).where("posts.desc='ruby is awesome'")
    
    # =>
    SQLite3::SQLException: no such column: posts.desc:
    SELECT "users".* FROM "users" WHERE (posts.desc='ruby is awesome')
    

    With preload where clauses can be applied.

    User.preload(:posts).where("users.name='Neeraj'")
    
    # =>
    SELECT "users".* FROM "users" WHERE (users.name='Neeraj')
    SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (3)


    Includes

    Includes loads the association data in a separate query just like preload.

    However it is smarter than preload. Above we saw that preload failed for query:

    User.preload(:posts).where("posts.desc='ruby is awesome'")

    Let’s try same with includes.

    User.includes(:posts).where('posts.desc = "ruby is awesome"').to_a
    
    # =>
    SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, "posts"."id" AS t1_r0,
    "posts"."title" AS t1_r1,
    "posts"."user_id" AS t1_r2, "posts"."desc" AS t1_r3
    FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"
    WHERE (posts.desc = "ruby is awesome")


    As you can see includes switches from using two separate queries to creating a single LEFT OUTER JOIN to get the data. And it also applied the supplied condition.

    So includes changes from two queries to a single query in some cases. By default for a simple case it will use two queries. Let’s say that for some reason you want to force a simple includes case to use a single query instead of two. Use references to achieve that.

    User.includes(:posts).references(:posts).to_a
    
    # =>
    SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, "posts"."id" AS t1_r0,
    "posts"."title" AS t1_r1,
    "posts"."user_id" AS t1_r2, "posts"."desc" AS t1_r3
    FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"


    In the above case a single query was done.

    Eager load

    eager loading loads all association in a single query using LEFT OUTER JOIN.

    User.eager_load(:posts).to_a
    
    # =>
    SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, "posts"."id" AS t1_r0,
    "posts"."title" AS t1_r1, "posts"."user_id" AS t1_r2, "posts"."desc" AS t1_r3
    FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"


    This is exactly what includes does when it is forced to make a single query when where or order clause is using an attribute from posts table.

    Joins

    Joins brings association data using inner join.

    User.joins(:posts)
    
    # =>
    SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id"


    In the above case no posts data is selected. Above query can also produce duplicate result. To see it let’s create some sample data.

    def self.setup
    User.delete_all
    Post.delete_all
    
    u = User.create name: 'Neeraj'
    u.posts.create! title: 'ruby', desc: 'ruby is awesome'
    u.posts.create! title: 'rails', desc: 'rails is awesome'
    u.posts.create! title: 'JavaScript', desc: 'JavaScript is awesome'
    
    u = User.create name: 'Neil'
    u.posts.create! title: 'JavaScript', desc: 'Javascript is awesome'
    
    u = User.create name: 'Trisha'
    end


    With the above sample data if we execute User.joins(:posts) then this is the result we get

    #<User id: 9, name: "Neeraj">
    #<User id: 9, name: "Neeraj">
    #<User id: 9, name: "Neeraj">
    #<User id: 10, name: "Neil">


    We can avoid the duplication by using distinct .

    User.joins(:posts).select('distinct users.*').to_a


    Also if we want to make use of attributes from posts table then we need to select them.

    records = User.joins(:posts).select('distinct users.*, posts.title as posts_title').to_a
    records.each do |user|
    puts user.name
    puts user.posts_title
    end


    Note that using joins means if you use user.posts then another query will be performed.   

    Source: https://blog.bigbinary.com/2013/07/01/preload-vs-eager-load-vs-joins-vs-includes.html

     

source: https://gist.github.com/ryansobol/5252653