- 相关推荐
三道Ruby面试试题
一、Ruby如何进行文件操作
Ruby使用File类来操作文件,可以通过File.new来创建一个File类的实例并打开这个文件。
file = File.new(“testfile”, “r”)
# … process the file
file.close
testfile是想要操作的文件名,”r”说明了文件的操作模式为读取。可以使用”w”表示写入,”rw”表示读写。
最后要记得关闭打开的文件,确保所有被缓冲的数据被写入文件,所有相关的资源被释放。
也可以使用File.open来打开文件,open和new的不同是open可以使用其后的代码块而new方法则返回一个File类的实例。
File.open(“testfile”, “r”) do |file|
# … process the file
end
open操作的另一个优点是处理了异常,如果处理一个文件发生错误抛出了
异常的话,那么open操作会自动关闭这个文件,下面是open操作的大致实现:
class File
def File.open(*args)
result = f = File.new(*args)
if block_given?
begin
result = yield f
ensure
f.close
end
end
return result
end
end
对于文件的路径,Ruby会在不同的操作系统间作转换。例如,在Windows下,/ruby/sample/test.rb会被转化为\ruby\sample\test.rb。当你使用字符串表示一个Windows下的文件时,请记住使用反斜线先转义:
“c:\\ruby\\sample\\test.rb”
也可以使用File::SEPARATOR表示不同系操作统的路径分割符。
二、Ruby如何创建一个线程
可以使用Thread.new方法去创建一个线程,可以随后代码块中列出线程执行的代码:
x = Thread.new { sleep 0.1; print “x”; print “y”; print “z” }
a = Thread.new { print “a”; print “b”; sleep 0.2; print “c” }
执行结果为:
ab
上面的示例程序中使用Thread.new创建了二个线程,线程随即开始运行。但是运行结果很奇怪,为什么程序运行结果是“ab”呢?我们预期的执行结果应该是 “abxyzc”。
当Ruby程序执行完毕的时候,他会杀掉所有的线程,不管其它的线程的运行状态如何。如果没有使用join方法,那么主程序执行完毕后会把所有没有执行完毕的线程杀掉。
上面的实例程序中,当主程序运行完毕时,两个线程都没有运行结束就被中止掉了。我们可以使用join方法来让主程序等待某个特定线程结束,对每一个线程使用join方法,可以确保在程序结束前所有的线程可以运行完毕。
x = Thread.new { sleep 0.1; print “x”; print “y”; print “z” }
a = Thread.new { print “a”; print “b”; sleep 0.2; print “c” }
x.join
a.join
我们使用Thread.new方法创建两个新的线程并开始运行, 然后使用join方法等待线程结束。执行结果为:
abxyzc
可以看到通过使用join方法等待线程结束,程序运行结果和我们预期结果相符。
另一个例子:
x = Thread.new { sleep 0.1; print “x”; print “y”; print “z” }
a = Thread.new { sleep 0.1; print “a”; print “b”; sleep 0.2; print “c” }
执行没有任何输出,因为主程序执行完毕杀死两个线程的时候这两个线程没有运行到输出语句。
也可以给join方法添加时间用来指明最大等待时间。如果超时join返回nil。
x = Thread.new { sleep 0.1; print “x”; print “y”; print “z” }
a = Thread.new { sleep 0.1; print “a”; print “b”; sleep 10; print “c” }
x.join(5)
a.join(5)
执行结果为:
abxyz
上面的例子中对于每一个线程的最大等待时间是5秒,由于a线程需要执行10秒以上,所以a线程没有运行完毕程序就将返回。
三、ruby如何进行集成操作?Ruby能进行多重继承吗?
Ruby继承的语法很简单,使用 < 即可。
Ruby语言只支持单继承,每一个类都只能有一个直接父类。这样避免了多继承的复杂度。但同时,Ruby提供了mixin的机制可以用来实现多继承。
可以使用super关键字调用对象父类的方法,当super省略参数时,将使用当前方法的参数来进行调用。