ruby 问题总结

  1. ruby 的命名规则
    局部变量:以英文字母或者_开头,如:

    1
    name = "this is a local variable"

    全局变量:以 $ 开头,如:

    1
    $name = "this is a global variable"

    实例变量:以@开头,如:

    1
    @name = 'lily'

    类变量:以@@开头,如:

    1
    @@name = 'lily'

    常量:全大写字母,如:

    1
    NAME

    类名和模块名:以首字母大写,驼峰命名法。如:

    1
    HelloWorld

    方法名:小写用_隔开,如:

    1
    sort_by_name
  2. ruby 中 singleton class 和 singleton method 分别是什么

    Singleton method

    A method which belongs to a single object rather than to an entire class and other objects.
    一个方法只属于一个对象,而不是整个类和其他实例化对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    firstObj = ClassMethods.new
    secondObj = ClassMethods.new
    def firstObj.singletonMethod
    "Hi am a singlton method available only for firstObj"
    end
    firstObj.singletonMethod # "Hi am a singlton method available only for firstObj"
    secondObj.singletonMethod #undefined method `singletonMethod' for #<ClassMethods:0x32754d8> (NoMethodError)

    So this “singletonMethod” belongs only to the firstObj object and won’t be available for other objects of this class.
    If you try to make the secondObj.singletonMethod Ruby will inform you that singletonMethod is an undefined method.

    所以,singletonMethod 只属于 firstObj,不能被这个类的其他实例化对象所调用。如果你想用 secondObj.singletonMethod 调用这个单例方法,ruby 会告诉你 singletonMethod 没有定义

    If you like to find all the singleton methods for a specific object, you can say objectname.singleton_methods
    In our case
    如果你想找到一个特定对象的所有单例方法,你可以用 objectname.singleton_methods 。在我们的例子里面就是:

    1
    2
    firstObj.singleton_methods => ["singletonMethod"]
    secondObj.singleton_methods => []

    To avoid throwing undefined method error when you try to access a singleton method with some other object

    避免调用单例方法**抛出方法未定义的异常:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    if secondObj.singleton_methods.include?("singletonMethod")
    secondObj.singletonMethod
    end
    # 或
    if secondObj.singleton_methods.include?( :singletonMethod )
    secondObj.singletonMethod
    end

    Singleton classes
    单例类

    A singleton class is a class which defines a single object.
    单例类就是只有一个实例对象的类。

    In our above example we have two objects firstObj and secondObj.
    We can create a separate class for the secondObj instance and that is called as a singleton class.
    So as per the definition we created a class for a single object.

    在我们上面的例子里面,我们有两个对象,firstObj 和 secondObj。我们给 secondObj 实例 创建一个单独的类,这就叫做单例类。
    所以按照定义为一个单独的对象我们创建了一个类。

    1
    2
    3
    4
    5
    class << secondObj
    def method4
    p "Hi am a singlton method available only for secondObj"
    end
    end

    When you see a class definition with the class keyword followed by two less than symbols that is a Singleton class opened for the object.
    In our ClassMethods class we had something like class << self which is also a singleton class. In Ruby a class itself is an instance of the Ruby class Let’s try something like this

    当你看到定义一个类后面跟着 << 的时候,这就是打开这个对象的单例类。
    在我们的 ClassMethods 这个类中,我们有 class << self ,所以这也是一个单例类。在 ruby 里,一个类本身也是一个 ruby 的类。让我们试试

    1
    ClassMethods.class # Class
  3. 怎么写一个 module,可以让包含这个 module 的 class 既能使用这个 module 的类方法又能使用这个 module 的实例方法
    参考 http://motion-express.com/blog/include-instance-&-class-methods-from-a-module

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    module Foo
    def self.included(m)
    def m.show1
    p "hi"
    end
    end
    def show2
    p "hello"
    end
    end
    class Bar
    include Foo
    end
    Bar.new.show2 #=> "hello"
    Bar.show1 #=> "hi"
    Bar.show2 #=> NoMethodError: undefined method `show2' for Bar:Class
    Bar.new.show1 #=> NoMethodError: undefined method `show1' for #<Bar:0x007fa1fb8c2ce8>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    module A
    def b
    puts "method b from module A"
    end
    def c
    puts "method c from module A"
    end
    end
    class B
    include A
    extend A
    end
    B.new.b # => "method b from module A"
    B.b # => "method b from module A"
    B.new.c # => "method c from module A"
    B.c # => "method c from module A"
  4. require load auto_load 以及 require_dependency 的区别
    require,load用于文件,如.rb等等结尾的文件。
    include则用于包含一个文件(.rb等结尾的文件)中的模块。
    require一般情况下用于加载库文件,而load则用于加载配置文件。
    require加载一次,load可加载多次。

    详细参考: 浅谈Ruby中的类加载机制

    Require/load/autoload的区别和用法

    ActiveSupport::Autoload 学习

    Here are the differences between Require, Load, Include and

  1. 描述 object, class, module 的关系是什么,并画图表示。
    从继承关系来说,是Class –> Module –> Object,即Object是继承树的顶层,紧接着是Module,然后是Class。
    Modules, Classes, and Objects

    1
    2
    3
    4
    Object -> Module -> Class -> MyClass
    另外:
    Object.class = Class
    Class.superclass = Module
  2. 为什么在 model 中可以调用 validates,自己怎么实现 model 中的 validates,试着实现一下?

    validations

  3. ruby 中 ? 或者 ! 作为后缀的方法有什么不同?
    It’s “just sugarcoating” for readability, but they do have common meanings:

    Methods ending in ! perform some permanent or potentially dangerous change; for example:
    Enumerable#sort returns a sorted version of the object while Enumerable#sort! sorts it in place.
    In Rails, ActiveRecord::Base#save returns false if saving failed, while ActiveRecord::Base#save! raises an exception.
    Kernel::exit causes a script to exit, while Kernel::exit! does so immediately, bypassing any exit handlers.
    Methods ending in ? return a boolean, which makes the code flow even more intuitively like a sentence — if number.zero? reads like “if the number is zero”, but if number.zero just looks weird.

    在Ruby中,以问号(?)结尾,被用于标示谓词,即返回Boolean值的方法,如Array.empty?(判断数组中元素是否为空)。

    在Ruby中,以问号(?)结尾,出现在方法名词尾部,表示使用该yyifc是需要多加小心的。
    而通常情况下,不带感叹号的方法不带感叹号的方法返调用该方法的一个拷贝,二带感叹号的方法则是一个可变方法,该方法会修改原来的对象,如Array类中的sort和sort!

  4. 有没有读过 rails 源码?
    只瞅过几眼
  5. rails 本身是由什么组成的?
    Rails组成和项目结构
  6. 有没有读过 《ruby 元编程》?
    没有呢(心里想,回去赶紧买一本拜读一下)
  7. 工作中遇到过哪些挑战和困难,怎么解决的?
  8. 不使用 ActiveJob,sidekiq 单独使用可以不?
    Active Job 和 Sidekiq 简介
    Active Job
    Rails: 使用Active Job来处理异步任务
  9. bundler 和 gem 的关系?bundler 是 gem 么?
    bundler
    Rvm 与 Bundler 的爱恨情仇
    RVM,RubyGems和Bundler的日常使用

  10. passenger, nginx, 还有一个是什么,忘记了,这三个各自干什么的,怎么结合起来一起工作,缺一可以不
    Ruby 服务器对比

  11. each 和 map 的区别
    each: 顺序返回各个元素
    collect: 把原数组的各个元素顺序返回,并组装新的数组
    map: 与 collect一样,会创建一个新的数组
    select: 与collect一样,会创建一个新的数组

    Ruby: 聊一聊关于集合遍历的各种方法
    Pluck vs. map and select

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ a = [1,2,3,4]
    => [1, 2, 3, 4]
    $ a.each {|n| n*2}
    => [1, 2, 3, 4]
    $ a
    => [1, 2, 3, 4]
    $ a.map {|n| n*2}
    => [2, 4, 6, 8]
    $ a
    => [1, 2, 3, 4]
    $ a.collect {|n| n*2}
    => [2, 4, 6, 8]
    $ a
    => [1, 2, 3, 4]
  12. find 和 find_by 的区别
    rails中find/find_by/where的区别

  13. 解决 N+1 Query 的方法有哪些
    浅谈 ActiveRecord 的 N + 1 查询问题
    Rails使用include和join避免N+1 queries
    面试官说了片段缓存,也可以解决查询问题

  14. 单表继承
    Rails 之单表继承 (Single Table Inheritance)
    Inheritance 单表继承
    ActiveRecord-连接多张表之单表继承
  15. rack 是什么
    Rails on Rack

  16. 安全问题。怎么破 XSS 和 CSRF攻击
    解法:
    对于XSS:首先说说什么是XSS(Cross-site scripting),跨站脚本攻击,攻击者在客户端注入可执行代码。
    对策:
    过滤恶意输入非常重要,但是转义 Web 应用的输出同样也很重要。
    过滤恶意输入白名单比黑名单要有效,特别是在需要显示未经过滤的用户输入时(例如前面提到的的搜索表单的例子)。使用 escapeHTML() 方法(或其别名 h() 方法),把 HTML 中的字符 &、”、< 和 > 替换为对应的转义字符 &、”、< 和 >。

    对于CSRF:Cross Site Request Forgery,跨站请求伪造。通俗理解:攻击者盗用当前用户身份,发请当前用户的恶意请求:如邮件,银行转账等。

    对策:首先,根据 W3C 的要求,应该适当地使用 GET 和 POST HTTP 方法。其次,在非 GET 请求中使用安全令牌(security token)可以防止应用受到 CSRF 攻击。

  17. ActiveSupport::Concern 的工作原理
    参考 ActiveSupport::Concern
    [ActiveSupport::Concern 的工作原理](http://xiewenwei.github.io/blog/2014/01/13/how-activesupport-corncern-work/)
    
  18. Rails: pluck与select的区别
  19. yield self 的用法,写个例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Builder
    def initialize arguments
    # do somthing by init arguments
    end
    # you can use Builder's method in block
    def build
    yield self if block_given?
    end
    end
  20. scope 的实现原理
    核心是延迟计算,将where、order、limit子句变为Relation对象,然后在最终调用each/to_a时组装sql