干貨 | 美團推薦算法工程師崗8道面試題分享!

問題1:各種優(yōu)化器使用的經驗
梯度下降:在一個方向上更新和調整模型的參數,來最小化損失函數。
隨機梯度下降(Stochastic gradient descent,SGD)對每個訓練樣本進行參數更新,每次執(zhí)行都進行一次更新,且執(zhí)行速度更快。
為了避免SGD和標準梯度下降中存在的問題,一個改進方法為小批量梯度下降(Mini Batch Gradient Descent),因為對每個批次中的n個訓練樣本,這種方法只執(zhí)行一次更新。
使用小批量梯度下降的優(yōu)點是:
1) 可以減少參數更新的波動,最終得到效果更好和更穩(wěn)定的收斂。
2) 還可以使用最新的深層學習庫中通用的矩陣優(yōu)化方法,使計算小批量數據的梯度更加高效。
3) 通常來說,小批量樣本的大小范圍是從50到256,可以根據實際問題而有所不同。
4) 在訓練神經網絡時,通常都會選擇小批量梯度下降算法。
SGD方法中的高方差振蕩使得網絡很難穩(wěn)定收斂,所以有研究者提出了一種稱為動量(Momentum)的技術,通過優(yōu)化相關方向的訓練和弱化無關方向的振蕩,來加速SGD訓練。
Nesterov梯度加速法,通過使網絡更新與誤差函數的斜率相適應,并依次加速SGD,也可根據每個參數的重要性來調整和更新對應參數,以執(zhí)行更大或更小的更新幅度。
AdaDelta方法是AdaGrad的延伸方法,它傾向于解決其學習率衰減的問題。Adadelta不是累積所有之前的平方梯度,而是將累積之前梯度的窗口限制到某個固定大小w。
Adam算法即自適應時刻估計方法(Adaptive Moment Estimation),能計算每個參數的自適應學習率。
這個方法不僅存儲了AdaDelta先前平方梯度的指數衰減平均值,而且保持了先前梯度M(t)的指數衰減平均值,這一點與動量類似。
Adagrad方法是通過參數來調整合適的學習率η,對稀疏參數進行大幅更新和對頻繁參數進行小幅更新。因此,Adagrad方法非常適合處理稀疏數據。

?
問題2:python 垃圾處理機制
在Python中,主要通過引用計數進行垃圾回收;
通過 “標記-清除” 解決容器對象可能產生的循環(huán)引用問題;
通過 “分代回收” 以空間換時間的方法提高垃圾回收效率。
也就是說,python采用的是引用計數機制為主,標記-清除和分代收集(隔代回收)兩種機制為輔的策略。

?
問題3:yield 關鍵字作用
yield是一個類似 return 的關鍵字,只是這個函數返回的是個生成器,可以節(jié)省巨大的時間、空間開銷。

?
問題4:python 多繼承,兩個父類有同名方法怎么辦?
super(Classname,self).methodname()或super(Classname, cls).methodname() 調用"下一個"父類中的方法
1、假設類A繼承B, C, D: class A(B, C, D), B/C/D都有一個show()方法
a.調用B的show()方法:
super().show()
super(A, self).show()
b.調用C的show()方法:
super(B,self).show()
c.調用D的show()方法:
super(C,self).show()
2.如果在B類中需要調用C類中的show()方法, 也是一樣的
class B:
def show(self):
super(B, self).show()
?
問題5:python 多線程/多進程/協(xié)程


?
問題6:樂觀鎖/悲觀鎖?
參考:https://zhuanlan.zhihu.com/p/82745364
悲觀鎖
總是假設最壞的情況,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖
樂觀鎖
總是假設最好的情況,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號機制和CAS算法實現(xiàn)。
?
兩種鎖的使用場景
樂觀鎖適用于寫比較少的情況下(多讀場景),即沖突真的很少發(fā)生的時候,這樣可以省去了鎖的開銷,加大了系統(tǒng)的整個吞吐量。
悲觀鎖一般適用于多寫的場景下。
?
兩種鎖的實現(xiàn)方式
樂觀鎖常見的兩種實現(xiàn)方式
樂觀鎖一般會使用版本號機制或CAS算法實現(xiàn)。
悲觀鎖的實現(xiàn)方式是加鎖,加鎖既可以是對代碼塊加鎖(如Java的synchronized關鍵字),也可以是對數據加鎖(如MySQL中的排它鎖)。

?
問題7:coding: 合并兩個有序鏈表
方法一:遞歸
分兩種情況:空鏈表和非空鏈表
當其中一個為空鏈表時,可以直接返回另一個鏈表
當兩個鏈表都為非空鏈表時,可以使用下面方法進行遞歸
?
代碼如下:

時間復雜度:O(m+n)
空間復雜度:O(m+n)
方法二:迭代
?
首先要設定一個哨兵節(jié)點,可以在最后比較容易地返回合并后的鏈表。
維護一個 pre 指針,根據 l1和 l2 的大小不斷更新 prev 的next 指針。
?
代碼如下:

時間復雜度:O(m+n)
空間復雜度:O(1)

?
問題8:講下CNN發(fā)展史
1、LeNet:
廣為流傳LeNet誕生于1998年,網絡結構比較完整,包括卷積層、pooling層、全連接層,這些都是現(xiàn)代CNN網絡的基本組件。被認為是CNN的開端。
?
2、AlexNet:
2012年Geoffrey和他學生Alex在ImageNet的競賽中,刷新了image classification的記錄,一舉奠定了deep learning 在計算機視覺中的地位。這次競賽中Alex所用的結構就被稱為作為AlexNet。
對比LeNet,AlexNet加入了:
(1)非線性激活函數:ReLU;
(2)防止過擬合的方法:Dropout,Data augmentation。同時,使用多個GPU,LRN歸一化層。其主要的優(yōu)勢有:網絡擴大(5個卷積層+3個全連接層+1個softmax層);解決過擬合問題(dropout,data augmentation,LRN);多GPU加速計算。
?
3 VGG-Net:
VGG-Net來自 Andrew Zisserman 教授的組 (Oxford),在2014年的 ILSVRC localization and classification 兩個問題上分別取得了第一名和第二名,其不同于AlexNet的地方是:VGG-Net使用更多的層,通常有16-19層,而AlexNet只有8層。同時,VGG-Net的所有 convolutional layer 使用同樣大小的 convolutional filter,大小為 3 x 3。
?
4 GoogLeNet:
提出的Inception結構是主要的創(chuàng)新點,這是(Network In Network)的結構,即原來的結點也是一個網絡。其使用使得之后整個網絡結構的寬度和深度都可擴大,能夠帶來2-3倍的性能提升。
?
5 Resnet
ResNet提出了一種減輕網絡訓練負擔的殘差學習框架,這種網絡比以前使用過的網絡本質上層次更深。其明確地將這層作為輸入層相關的學習殘差函數,而不是學習未知的函數。
在ImageNet數據集用152 層(據說層數已經超過1000==)——比VGG網絡深8倍的深度來評估殘差網絡,但它仍具有較低的復雜度。在2015年大規(guī)模視覺識別挑戰(zhàn)賽分類任務中贏得了第一。
— 推薦閱讀 — 最新大廠面試題
學員最新面經分享
七月內推崗位
AI開源項目論文
NLP ( 自然語言處理 )
CV(計算機視覺)
推薦

