從朋友那得到了一份求職的考題,範圍是網頁開發的後端操作:
OOP的三大特性是什麼?
Object-oriented programming是一種programming paradigm(其餘還有procedural programming、functional programming等),以生活中所見的「物件」(object)作為核心,並套用在程式碼之中。物件包含了 屬性(attributes) 與 方法(method) ,所謂屬性就是該物件的特徵、資料,而方法是該物件的行為;若以人作為一個物件,屬性則包含性別、身高、名字,而方法則會有走路、跑步、吃飯等等。
OOP的三大特性
封裝(Encapsulation)
封裝的目的,是讓其他人可以使用物件,但不需要知道物件內部的邏輯。
操作電腦時,不需要知道電腦內部是如何運作的,也能透過鍵盤、滑鼠來輸入文字或完成指令。在OOP中,同樣也只需要知道物件有哪些屬性、哪些方法,即可對物件進行操作,而不需要知道物件的方法是如何定義的。
繼承(Inheritance)
Don’t Repeat Yourself
就像是親代與子代的關係,子代除了擁有自己的性格以外,也會繼承親代的某些特性。OOP內,subclass可以繼承superclass所有的屬性與方法(也能透過寫新的程式碼來覆蓋掉sperclass的),如此一來將能重複利用同樣的程式碼。
多型(Polymorphism)
即使物品不同,也能根據情境透過同樣的方法來執行對的行為。
由於慣例,讓每個人不用重新學一套開車的方式:無輪是哪個廠牌的汽車,坐進去後都能透過踩油門使汽車加速。多型的概念即是如此,不同型態或不同的實體,都擁有同樣名稱的屬性或方法;假設A和B都有x方法,那麼就能在呼叫x方法時自由抽換A角色或B角色,而不用寫死「A的x方法」與「B的x方法」。
Ruby:class與module的區別?(至少包含用途、差了哪些method)
Module是Class的superclass
Class除了繼承Module的method外,還多出了[:new, :allocate, :superclass]三個instance methods[1]。由此可以得知Module的instance並沒有辦法建立新的instance以及繼承別的module。
所以若是在多個Class中都會用到的功能,會比較適合用Module來寫,等需要時再include module_name就可以了。
註:至於allocate方法,他與new都是Class創建新instance的方法,但allocate並不會調用initialize,也就是說 new其實就是allocate後再initialize 而已。若我們想建立一個沒有初始化的instance,就能考慮使用allocate。[2]
Ruby:為什麼(幾乎)所有東西都是物件?
“I wanted a scripting language that was more powerful than Perl, and more object-oriented than Python.”
– by Ruby發明人 Matz [3]
這問題其實蠻弔詭的,我不明白出題人想問什麼。從Matz說的話可知道,Ruby在一開始被設計時就定位成一個「萬物即物件」的程式語言。因此如果想問的是「為什麼要把所有東西都變成物件」的話,可能問Matz本人會比較清楚;又如果是想問「把所有東西都變成物件有什麼好處」,又可以拿上面的OOP三大特性來回答。不過還是把Ruby萬物即物件這一點看到的資料做一些整理。
萬物即物件
在大部分的程式語言裡,許多primitive value都不是物件,他們都是被定義好的、不能改變的資料型態,像是string、數字、boolean等等。但在Ruby裡,這些資料型態都可以被當作物件來使用。以5.times來說,就把數字當成物件,並且可以呼叫其方法。
所以我說…有什麼不是物件?
以Stack Overflow上的回答來看[5],包含block、運算元、loop、條件式等等都不是物件。在為你自己學Ruby on Rails中[6]也有提到,block並沒有辦法單獨存在,也無法assign給某個變數。如果要把block掛在方法上使用,可以在方法內寫上yield來將想傳遞的訊息傳給block執行;而也可以利用Proc將block物件化,像是:
1
2greeting = Proc.new { |name| puts "Hello, #{name}!"}
greeting.call("Hung") # => Hello, Hung!
列出七個你最常用的git指令,並簡述使用時機。
什麼是Monkey patching?這種做法好嗎?
Python:求下列程式碼的輸出值。
1 | def f(x, l=[]): |
- 第一個參數x是必需要手動帶入的;而第二個參數l是個list,若沒有手動帶入則以預設的空list
[]進行 - range(x)表示
[0, 1, ..., x-1]的list - append是list的一種方法,可以將參數放到list的最後一項
答案:
[0, 1][3, 2, 1, 0, 1, 4][0, 1, 0, 1, 4](註: l會繼續存在在方法內,所以當執行完f(2)時,l就變成了[0, 1])