分享 面试中的基础题小结

wwwicbd · 2018年04月27日 · 最后由 wwwicbd 回复于 2018年05月03日 · 2669 次阅读

完成跟之前老板的深情告白之后, 终于能重新出发 来写可爱的 Ruby 啦 🎉

这个脚本是我准备面试前写的, 罗列了一些可能会考的基础问题. (押题命中率还挺高的, 示例代码不是对问题的直接回答, 仅用于启发思路.) 还在求职的小伙伴可以参考一下, 是不是每个问题都心中有数了.

这周已经收到理想的 offer, 希望这个小结能对其他小伙伴也有帮助 :)

puts "----------"
puts "Enumerable 的遍历"
=begin
each 和 map 有什么区别?
带!和不带!的方法有什么约定?
使用 {} 和 do end 有什么区别?
=end

fruits = ["apple", "banana", "pear"]

puts "each: 循环遍历, 返回原数组"
p fruits.each { |f| f.upcase }

puts "map: 循环遍历, 将处理结果打包新数组返回"
p fruits.map { |f| f.upcase }
p fruits.map(&:upcase)

puts "select: 返回数组, 筛选所有满足length>4的值"
p fruits.select { |f| f.length>4 }

puts "reject: 返回数组, 筛选所有不满足length>4的值"
p fruits.reject { |f| f.length>4 }

puts "partition: 返回一个数组, 满足条件的包装起来放0位, 不满足的包装起来放1位"
p fruits.partition { |f| f.length>4 }

puts "find: 返回第一个满足条件的元素"
p fruits.find { |f| f.length>4 }

puts "all?: 集合每个元素是否全都满足条件"
p fruits.all? { |f| f.length>4 }

puts "any?: 集合中是否存在一个满足条件的元素"
p fruits.any? { |f| f.length>4 }

puts "origin array:"
p fruits




puts "-----------"
puts "Proc 与 lambda"
=begin
Proc 和 lambda 分别是什么? 使用时有什么区别?
Proc 的 lambda 的return怎么用? next怎么用?
yield 怎么用?
self 怎么用?
& 符号在形参和实参中分别代表什么意义?
=end

def total1(from, to)
  sum = 0
  (from..to).each do |num|
    if block_given?
      sum += yield(num)
    else
      sum += num
    end
  end

  sum
end

def total2(from, to, &block)
  sum = 0
  (from..to).each do |num|
    if block
      sum += block.call(num)
    else
      sum += num
    end
  end

  sum
end

puts "---"
p total1(1, 10) { |n| n*(-1) }

puts "---"
p total2(1, 10) { |n| n*(-1) }

puts "---"
proc = Proc.new do |n|
  n * (-1)
end
p proc.class
p total2(1, 10, &proc)

puts "---"
lambd = lambda do |n|
  n*(-1)
end
p lambd.class
p total2(1, 10, &lambd)




puts "----------"
puts "alias 与 alias_method"
=begin
他们分别是什么? 使用时有什么区别?
https://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html
=end

class Hello
  def say
    p "say Hello"
  end

  alias say_alias say
  alias_method :say_alias_method, :say
end

Hello.new.say
Hello.new.say_alias
Hello.new.say_alias_method

class Hi
  def say
    p "Say Hi."
  end

  def self.generate_alias
    alias say_alias say
  end

  def self.generate_alias_method
    alias_method :say_alias_method, :say
  end
end

class Hi2 < Hi
  def say
    p "Say Hi !!!!!!!!!!!!!!!!!!"
  end

  generate_alias
  generate_alias_method
end

puts '----'
Hi2.new.say
Hi2.new.say_alias
Hi2.new.say_alias_method




puts "-----------"
puts "算法基础"
=begin
手工实现各种简单排序: 冒泡/插入/选择/归并/快排
分析各个实现的算法的时间复杂度和空间复杂度
在有先验条件的情况下该选哪种算法
=end


class Array

  # 冒泡排序 O(n^2)
  def bubble_sort!
    (self.length - 1).times do |time|
      last_index = self.length - 1 - time
      bubble_once!(0, last_index)
    end
  end

  # [i,j] 执行一次冒泡
  def bubble_once!(i, j)
    time = j-i
    time.times do
      if self[i] > self[i+1]
        self[i], self[i+1] = self[i+1], self[i]
      end

      i+=1
    end
  end

  private :bubble_once!


  # 选择排序 O(n^2)
  def select_sort!
    (self.length-1).times do |time|
      last_index = self.length - 1 - time
      max, max_index = max_of_array(0, last_index)

      self[max_index], self[last_index] = self[last_index], self[max_index]
    end
  end

  # [i,j] 最大的元素
  def max_of_array(i, j)
    max = self[j]
    max_index = j
    (i...j).each do |index|
      if self[index] > max
        max = self[index]
        max_index = index
      end
    end

    [max, max_index]
  end

  private :max_of_array


  # 插入排序 O(n^2)
  def insert_sort!
    (self.length - 1).times do |time|
      insert_once!(0, time + 1)
    end
  end

  # 对于 [i,j] 将 self[j] 插入到合适的位置
  def insert_once!(i, j)
    number = self[j]
    cursor = j
    while cursor>i
      if self[cursor] < self[cursor-1]
        self[cursor], self[cursor-1] = self[cursor-1], self[cursor]
      end
      cursor -= 1
    end
  end

  private :insert_once!


  # 归并排序 O(nlogn)
  def merge_sort
    return self if size == 1
    left = self[0, size/2]
    right = self[size/2, size - size/2]
    Array.merge(left.merge_sort, right.merge_sort)
  end

  def self.merge(left, right)
    ans = []
    until left.empty? or right.empty?
      smaller = left.first < right.first ? left.shift : right.shift
      ans.push(smaller)
    end

    ans + left + right
  end


  # 快排 O(nlogn)
  def quick_sort
    return [] if self.empty?

    center, *rest = self
    left, right = rest.partition { |ele| ele < center }
    left.quick_sort + [center] + right.quick_sort
  end
end



puts "----------"
puts "基本设计模式"
=begin
常用设计模式举例, 分别有什么典型应用?
=end

# 工厂模式

class CashBase
  def total
    raise "need implement"
  end
end

class Cash < CashBase
  def total(n)
    p n
  end
end

class CashVip < CashBase
  def initialize(rebate)
    @rebate = rebate
  end

  def total(n)
    p n*@rebate
  end
end

class CashFactory
  def self.generate(type)
    case type
      when "cash"
        Cash.new()
      when "vip1"
        CashVip.new(0.9)
      when "vip2"
        CashVip.new(0.7)
      else
        Cash.new()
    end
  end
end

CashFactory::generate('cash').total(100)
CashFactory::generate('vip1').total(100)
CashFactory::generate('vip2').total(100)

# 原型模式
class WorkEx
  attr_accessor :time_area, :company

  def print
    puts "time_area:#{time_area}\tcompany:#{company}"
  end
end

class Resume
  attr_accessor :name, :sex, :age, :workex

  def initialize(name)
    @name = name
    @workex = WorkEx.new
  end

  def set_person_info(sex, age)
    @sex = sex
    @age = age
  end

  def set_workex(time_area, company)
    @workex.time_area = time_area
    @workex.company = company
  end

  def print
    puts "name: #{name}\tage:#{age}\tsex:#{sex}"
    @workex.print
    puts
  end

  def self_clone
    # deep clone
    Marshal.load(Marshal.dump(self))
  end
end

no1 = Resume.new("XiaoMing")
no1.set_person_info("man", 25)
no1.set_workex("2017", "Google")

no2 = no1.self_clone
no2.set_workex('2018', "facebook")

no1.print
no2.print


# Singleton
require 'singleton'
class Logge
  include Singleton

  def msg(msg)
    puts msg
  end
end

logger = Logge.instance
logger.msg("hhh")



puts "----------"
puts "元编程"
=begin
Ruby 对象和类的关系, 画图解释一下?
继承和mixin的理解?
反射的使用?
打开类的使用?
=end

这可能是你第一个 Ruby offer,也可能是最后一个 Ruby offer

zhaoyshine 回复

为啥你对 ruby 这么悲观?受到过什么伤害吗?😂

LZ 在哪个城市呀

jakit 回复

上海

wwwicbd 回复

真幸福

lengcb 回复

我只是看不惯那些人,嘴里说自己是最早一批做 ruby 的人,我们都还在坚持,为什么你们坚持不下去了?他们一直都在写鸡汤,讲优雅,说别的语言丑,我王境泽就算饿死,也不写 java,这些人除了口上功夫了得,每天都在说 ruby 多好多好,沉迷 ruby 的美无法自拔,但其实根本没有给 ruby 写过一两个带劲的轮子

zhaoyshine 回复

希望自己能快快成长,能造轮子😁

zhaoyshine 回复

大家都是成年人, 有自己的判断和选择.

可以讨论问题, 不要 judge 别人, 谢谢.

wwwicbd 关闭了讨论 05月03日 09:44
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册