面试题答案
一键面试1. 延迟加载概念
延迟加载(Lazy Loading)是指在需要时才加载对象或数据,而不是在程序启动时就全部加载,以此来优化启动时间和内存占用。
2. Ruby 实现延迟加载的方式 - 模块的延迟加载
假设我们有一个大型项目,其中有一个 BigModule
模块,里面包含很多功能,但启动时不需要立即加载。
# 定义一个延迟加载的模块
module BigModule
def self.loaded?
@loaded ||= false
end
def self.load!
return if loaded?
# 模拟大量代码加载
puts "Loading BigModule..."
@loaded = true
end
def self.method_1
load!
puts "Executing method_1 in BigModule"
end
def self.method_2
load!
puts "Executing method_2 in BigModule"
end
end
在上面代码中,BigModule
模块定义了 loaded?
方法来检查模块是否已加载,load!
方法用于实际加载模块(这里用 puts
模拟加载操作)。method_1
和 method_2
方法在执行前会先调用 load!
确保模块已加载。
3. Ruby 实现延迟加载的方式 - 对象的延迟加载
假设我们有一个数据量较大的类 BigDataObject
。
class BigDataObject
def initialize
@loaded = false
end
def load_data
return if @loaded
# 模拟加载大量数据
@data = (1..1000000).to_a
@loaded = true
end
def process_data
load_data
puts "Processing data: #{@data.first(10)}"
end
end
在这个 BigDataObject
类中,initialize
方法初始化加载状态为 false
。load_data
方法用于实际加载数据(这里用一个大数组模拟)。process_data
方法在处理数据前先调用 load_data
确保数据已加载。
4. 使用惰性求值实现延迟加载
Ruby 的 Enumerator
类可以用于惰性求值,从而实现延迟加载数据。
def big_data_generator
Enumerator.new do |y|
(1..1000000).each do |i|
y.yield i
end
end
end
big_data = big_data_generator
# 这里还未实际生成所有数据
first_10 = big_data.take(10)
# 只有在调用 take 方法时,才会生成部分数据
在上述代码中,big_data_generator
返回一个 Enumerator
,它不会立即生成所有数据。只有在调用 take
等方法时,才会按需生成数据,达到延迟加载数据的效果。