完成跟之前老板的深情告白之后,终于能重新出发 来写可爱的 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