「收藏」2019阿里巴巴面試題集錦(含答案)
【新智元導讀】本文是阿里巴巴 2019 面試題集錦(含答案),是阿里巴巴自身技術專家們結合多年的工作、面試經驗總結提煉而成的面試真題。通過這些面試題,還可以間接地了解技術大牛們出題思路與考察要點。
想要入職大廠可謂是千軍萬馬過獨木橋。要通過層層考驗,刷題肯定是必不可少的。
為幫助開發者們提升面試技能、有機會入職阿里,雲棲社區特別製作了這個專輯——阿里巴巴資深技術專家們結合多年的工作、面試經驗總結提煉而成的面試真題這一次整體放出。
這一次,不僅是知識的收穫,還將間接地與技術大牛們做了直觀的溝通,了解他們的出題思路與考察要點,並加以消化吸收,這對自己技術能力本身就是一種極大的提升。走上編程之路,不斷豐富自己方能與世接軌,努力做最優秀的自己。
面試題001:如何實現一個高效的單向鏈表逆序輸出?
——阿里巴巴出題專家:昀龍/阿里雲彈性人工智慧負責人
參考答案
下面是其中一種寫法,也可以有不同的寫法,比如遞歸等。供參考。
typedefstructnode
{
intdata;
structnode*next;
node(intd):data(d),next(NULL){}
}node;
voidreverse(node*head)
{
if(NULL==head||NULL==head->next)
{
return;
}
node*prev=NULL;
node*pcur=head->next;
node*next;
while(pcur!=NULL)
{
if(pcur->next==NULL)
{
pcur->next=prev;
break;
}
next=pcur->next;
pcur->next=prev;
prev=pcur;
pcur=next;
}
head->next=pcur;
node*tmp=head->next;
while(tmp!=NULL)
{
cout<<tmp->data<<" ";
tmp=tmp->next;
}
}
面試題002:已知sqrt (2)約等於1.414,要求不用數學庫,求sqrt (2)精確到小數點後10位。
——阿里巴巴出題專家:文景/阿里雲CDN資深技術專家
考察點
- 基礎演算法的靈活應用能力(二分法學過數據結構的同學都知道,但不一定往這個方向考慮;如果學過數值計算的同學,應該還要能想到牛頓迭代法並解釋清楚)。
- 退出條件設計。
參考答案
1. 已知sqrt(2)約等於1.414,那麼就可以在(1.4, 1.5)區間做二分查找,如:
- high=>1.5
- low=>1.4
- mid => (high+low)/2=1.45
- 1.45*1.45>2 ? high=>1.45 : low => 1.45
- 循環到c)
2. 退出條件
前後兩次的差值的絕對值<=0.0000000001, 則可退出。
代碼示例:
const double EPSINON = 0.0000000001;
double sqrt2( )
{
double low = 1.4, high = 1.5;
double mid = (low + high) / 2;
while (high – low > EPSINON)
{
if (mid*mid < 2)
{
high = mid;
}
else
{
low = mid;
}
mid = (high + low) / 2;
}
return mid;
}
面試題003:給定一個二叉搜索樹(BST),找到樹中第K小的節點。
——阿里巴巴出題專家:文景/阿里雲CDN資深技術專家
考察點
1. 基礎數據結構的理解和編碼能力
2. 遞歸使用
示例:
如下圖,輸入K=3, 輸出節點值3
說明:保證輸入的K滿足1<=K<=(節點數目)
參考答案
樹相關的題目,第一眼就想到遞歸求解,左右子樹分別遍歷。聯想到二叉搜索樹的性質,root大於左子樹,小於右子樹,如果左子樹的節點數目等於K-1,那麼root就是結果,否則如果左子樹節點數目小於K-1,那麼結果必然在右子樹,否則就在左子樹。因此在搜索的時候同時返回節點數目,跟K做對比,就能得出結果了。
代碼示例:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/class Solution {
private class ResultType {
// 是否找到
boolean found;
// 節點數目
int val;
ResultType(boolean found, int val) {
this.found = found;
this.val = val;
}
}
public int kthSmallest(TreeNode root, int k) {
return kthSmallestHelper(root, k).val;
}
private ResultType kthSmallestHelper(TreeNode root, int k) {
if (root == null) {
return new ResultType(false, 0);
}
ResultType left = kthSmallestHelper(root.left, k);
// 左子樹找到,直接返回
if (left.found) {
return new ResultType(true, left.val);
}
// 左子樹的節點數目 = K-1,結果為root的值
if (k - left.val == 1) {
return new ResultType(true, root.val);
}
// 右子樹尋找
ResultType right = kthSmallestHelper(root.right, k - left.val - 1);
if (right.found) {
return new ResultType(true, right.val);
}
// 沒找到,返回節點總數
return new ResultType(false, left.val + 1 + right.val);
}
}
複雜度分析:
時間複雜度: O(N),節點最多遍歷一遍
空間複雜度:O(1),(如果算上遞歸深度可以當做O(logN))
面試題004:LRU緩存機制。
——阿里巴巴出題專家:文景/阿里雲CDN資深技術專家
設計和實現一個LRU(最近最少使用)緩存數據結構,使它應該支持一下操作:get和put。
get(key) - 如果key存在於緩存中,則獲取key的value(總是正數),否則返回 -1。
put(key,value) - 如果key不存在,請設置或插入value。當緩存達到其容量時,它應該在插入新項目之前使最近最少使用的項目作廢。
參考答案
代碼示例:
《 Python版本 》
class LRUCache(object):
def __init__(self, capacity):
"""
:type capacity: int
"""
self.cache = {}
self.keys = []
self.capacity = capacity
def visit_key(self, key):
if key in self.keys:
self.keys.remove(key)
self.keys.append(key)
def elim_key(self):
key = self.keys[0]
self.keys = self.keys[1:]
del self.cache[key]
def get(self, key):
"""
:type key: int
:rtype: int
"""
if not key in self.cache:
return -1
self.visit_key(key)
return self.cache[key]
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: void
"""
if not key in self.cache:
if len(self.keys) == self.capacity:
self.elim_key()
self.cache[key] = value
self.visit_key(key)
def main():
s = [["put","put","get","put","get","put","get","get","get"],[[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]]]
obj = LRUCache(2)
l=[]
for i,c in enumerate(s[0]):
if(c == "get"):
l.append(obj.get(s[1][i][0]))
else:
obj.put(s[1][i][0], s[1][i][1])
print(l)
if __name__ == "__main__":
main()
《 C++版本 》
class LRUCache{
public:
LRUCache(int capacity) {
cap = capacity;
}
int get(int key) {
auto it = m.find(key);
if (it == m.end()) return -1;
l.splice(l.begin(), l, it->second);
return it->second->second;
}
void set(int key, int value) {
auto it = m.find(key);
if (it != m.end()) l.erase(it->second);
l.push_front(make_pair(key, value));
m[key] = l.begin();
if (m.size() > cap) {
int k = l.rbegin()->first;
l.pop_back();
m.erase(k);
}
面試題005:關於epoll和select的區別,哪些說法是正確的?(多選)
——阿里巴巴出題專家:寈峰/阿里技術專家
A. epoll和select都是I/O多路復用的技術,都可以實現同時監聽多個I/O事件的狀態。
B. epoll相比select效率更高,主要是基於其操作系統支持的I/O事件通知機制,而select是基於輪詢機制。
C. epoll支持水平觸發和邊沿觸發兩種模式。
D. select能並行支持I/O比較小,且無法修改。
參考答案 A . B . C
面試題006:從innodb的索引結構分析,為什麼索引的key長度不能太長?
——阿里巴巴出題專家:近秋/阿里雲資料庫產品技術部技術專家
參考答案
key太長會導致一個頁當中能夠存放的key的數目變少,間接導致索引樹的頁數目變多,索引層次增加,從而影響整體查詢變更的效率。
面試題007:MySQL的數據如何恢復到任意時間點?
——阿里巴巴出題專家:近秋/阿里雲資料庫產品技術部技術專家
參考答案
恢復到任意時間點以定時的做全量備份,以及備份增量的binlog日誌為前提。恢復到任意時間點首先將全量備份恢復之後,再此基礎上回放增加的binlog直至指定的時間點。
面試題008:NFS和SMB是最常見的兩種NAS(Network Attached Storage)協議,當把一個文件系統同時通過NFS和SMB協議共享給多個主機訪問時,以下哪些說法是錯誤的:(多選)
——阿里巴巴出題專家:起影/阿里雲文件存儲高級技術專家
A. 不可能有這樣的操作,即把一個文件系統同時通過NFS和SMB協議共享給多個主機訪問。
B. 主機a的用戶通過NFS協議創建的文件或者目錄,另一個主機b的用戶不能通過SMB協議將其刪除。
C. 在同一個目錄下,主機a通過NFS協議看到文件file.txt,主機b通過SMB協議也看到文件file.txt,那麼它們是同一個文件。
D. 主機a通過NFS協議,以及主機b通過SMB協議,都可以通過主機端的數據緩存,提升文件訪問性能。
參考答案 A . B . C
面試題009:輸入ping IP後敲回車,發包前會發生什麼?
——阿里巴巴出題專家:懷虎/阿里云云效平台負責人
參考答案
首先根據目的IP和路由表決定走哪個網卡,再根據網卡的子網掩碼地址判斷目的IP是否在子網內。如果不在則會通過arp緩存查詢IP的網卡地址,不存在的話會通過廣播詢問目的IP的mac地址,得到後就開始發包了,同時mac地址也會被arp緩存起來。
面試題010:請解釋下為什麼鹿晗發布戀情的時候,微博系統會崩潰,如何解決?
——阿里巴巴出題專家:江嵐/阿里巴巴數據技術高級技術專家
參考答案 《 參考思路 》
A. 獲取微博通過pull方式還是push方式
B. 發布微博的頻率要遠小於閱讀微博
C. 流量明星的發微博,和普通博主要區分對待,比如在sharding的時候,也要考慮這個因素
面試題011:現有一批郵件需要發送給訂閱顧客,且有一個集群(集群的節點數不定,會動態擴容縮容)來負責具體的郵件發送任務,如何讓系統儘快地完成發送?請詳述技術方案!
——阿里巴巴出題專家:江嵐/阿里巴巴數據技術高級技術專家
參考答案
A. 藉助消息中間件,通過發布者訂閱者模式來進行任務分配
B. master-slave部署,由master來分配任務
C. 不藉助任何中間件,且所有節點均等。通過資料庫的update returning,從而實現節點之間任務的互斥
面試題012:有一批氣象觀測站,現需要獲取這些站點的觀測數據,並存儲到Hive中。但是氣象局只提供了api查詢,每次只能查詢單個觀測點。那麼如果能夠方便快速地獲取到所有的觀測點的數據?
——阿里巴巴出題專家:江嵐/阿里巴巴數據技術高級技術專家
參考答案
A. 通過shell或python等調用api,結果先暫存本地,最後將本地文件上傳到Hive中。
B. 通過datax的httpReader和hdfsWriter插件,從而獲取所需的數據。
C. 比較理想的回答,是在計算引擎的UDF中調用查詢api,執行UDF的查詢結果存儲到對應的表中。一方面,不需要同步任務的導出導入;另一方面,計算引擎的分散式框架天生提供了分散式、容錯、並發等特性。
面試題013 如何實現兩金額數據相加(最多小數點兩位)?
——阿里巴巴出題專家:御術/螞蟻金服數據可視化高級技術專家
參考答案
其實問題並不難,就是考察候選人對 JavaScript 數據運算上的認知以及考慮問題的縝密程度,有很多坑,可以用在筆試題,如果用在面試,回答過程中還可以隨機加入有很多計算機基礎的延伸。
回到這個問題,由於直接浮點相 yu 加會失精,所以要轉整數;(可以插入問遇到過嗎?是否可以舉個例子?)。
轉整數是第一個坑,雖然只有兩位可以通過乘以100轉整數,但由於乘以一百和除以一百都會出現浮點數的運算,所以也會失精,還是要通過字元串來轉;(可以插入問字元串轉整數有幾種方式?)
字元串轉整是第二個坑,因為最後要對齊計算,如果沒考慮周全先 toFixed(2),對於只有一位小數點數據進入計算就會錯誤;轉整數後的計算是個加分點,很多同學往往就是直接算了,如果可以考慮大數計算的場景,恭喜同學進入隱藏關卡,這就會涉及如何有效循環、遍歷、演算法複雜度的問題。
面試題014:關於並行計算的一些基礎開放問題。
——阿里巴巴出題專家:何萬青/阿里雲高性能計算資深技術專家
? 如何定義並計算,請分別闡述分散式內存到共享內存模式行編程的區別和實現(例子代碼)?
? 請使用MPI和OpenMP分別實現N個處理器對M個變數的求和?
? 請說明SIMD指令在循環中使用的許可權?向量化優化有哪些手段?
? 請用Amdahl定律說明什麼是並行效率以及並行演算法的擴展性?並說明擴展性的性能指標和限制因素,最後請說明在共享內存計算機中,共享內存的限制?OpenMP是怎樣實現共享內存編程環境的?MPI阻塞和非阻塞讀寫的區別?
參考答案
(簡要答案,但必須觸及,可以展開)
? 同時執行多個/演算法/邏輯操作/內存訪問/IO,相互獨立同時運行,分三個層次:進程級,多個節點分散式內存通過MPI通信並行;線程級,共享內存的多路機器,通過OpenMP實現多線程並行;指令集:通過SIMD指令實現單指令多數據。。。。舉例吧啦吧啦。
? MPI代碼,,,OpenMP代碼,分別寫出來 M個元素,N個處理器的累加,後者注意private 參數。
SIMD在循環中的應用,限制在於 SIMD指令處理的每一個數組的長度,cache line利用,內部循環間的依賴和條件調用等。
? 向量化,主要看SSE和AVX指令佔比率,通過編譯器優化。。。。在loop代碼中使用,
? 性能和計算規模隨處理器增加的變化曲線,實測HPL和峰值HPL比率,能用用Amdahl定律表達 Tpar(N) = (an + (1-a)n/N )t + C (n,N), 能夠講明白串列部分對整個並行的天花板效應,擴展性能夠解釋清楚演算法的擴展性=並行效率隨處理器數目的變化關係,畫出來。
? 共享內存計算機OpenMP對變數的限制描述,EREW,CREW,ERCW,CRCW等區別,NUMA概念,如何保持coherent等。
? 寫出OpenMP和MPI的核心函數,回答問題即可。
面試題015:請計算XILINX公司VU9P晶元的算力相當於多少TOPS,給出計算過程與公式。
——阿里巴巴出題專家:隱達/阿里雲異構計算資深專家
參考答案
基於不同的演算法,這個值在十幾到幾百之間。但是,如果只是單純比算力,FPGA和ASIC、GPU相比並無太大優勢,甚至大多時候有較大劣勢。FPGA的優勢在於高度的靈活性和演算法的針對性。
面試題016:一顆現代處理器,每秒大概可以執行多少條簡單的MOV指令,有哪些主要的影響因素?
——阿里巴巴出題專家:子團/創新產品虛擬化&穩定性資深技術專家
參考答案
及格:
每執行一條mov指令需要消耗1個時鐘周期,所以每秒執行的mov指令和CPU主頻相關。
加分:
在CPU微架構上,要考慮數據預取,亂序執行,多發射,內存stall (前端stall和後端stall)等諸多因素,因此除了cpu主頻外,還和流水線上的效率(IPC)強相關,比較複雜的一個問題。
面試題017:請分析MaxCompute產品與分散式技術的關係、當前大數據計算平台類產品的市場現狀和發展趨勢。
——阿里巴巴出題專家:雲郎/阿里MaxCompute高級產品專家
參考答案
開放性問題,無標準答案。
面試題018:對大數據平台中的元數據管理是怎麼理解的,元數據收集管理體系是怎麼樣的,會對大數據應用有什麼樣的影響。
——阿里巴巴出題專家:映泉/阿里巴巴高級技術專家
參考答案
開放性問題,無標準答案。
面試題019:你理解常見如阿里,和友商大數據平台的技術體系差異以及發展趨勢和技術瓶頸,在存儲和計算兩個方面進行概述。
——阿里巴巴出題專家:映泉/阿里巴巴高級技術專家
參考答案
開放性問題,無標準答案。
面試題020:在雲計算大數據處理場景中,每天運行著成千上萬的任務,每個任務都要進行IO讀寫。存儲系統為了更好的服務,經常會保證高優先順序的任務優先執行。當多個作業或用戶訪問存儲系統時,如何保證優先順序和公平性。
——阿里巴巴出題專家:田磊磊/阿里雲文件存儲高級技術專家
參考答案
開放性問題,無標準答案。
面試題 021:最大頻率棧。
——阿里巴巴出題專家:屹平/阿里雲視頻雲邊緣計算高級技術專家
實現 FreqStack,模擬類似棧的數據結構的操作的一個類。FreqStack 有兩個函數: push(int x),將整數 x 推入棧中。pop(),它移除並返回棧中出現最頻繁的元素。如果最頻繁的元素不只一個,則移除並返回最接近棧頂的元素。
示例:
push [5,7,5,7,4,5]
pop() -> 返回 5,因為 5 是出現頻率最高的。 棧變成 [5,7,5,7,4]。
pop() -> 返回 7,因為 5 和 7 都是頻率最高的,但 7 最接近棧頂。 棧變成 [5,7,5,4]。
pop() -> 返回 5 。 棧變成 [5,7,4]。
pop() -> 返回 4 。 棧變成 [5,7]。
參考答案
令 freq 作為x的出現次數的映射 Map。
此外maxfreq,即棧中任意元素的當前最大頻率,因為我們必須彈出頻率最高的元素。
當前主要的問題就變成了:在具有相同的(最大)頻率的元素中,怎麼判斷那個元素是最新的?我們可以使用棧來查詢這一信息:靠近棧頂的元素總是相對更新一些。
為此,我們令 group 作為從頻率到具有該頻率的元素的映射。到目前,我們已經實現了 FreqStack 的所有必要的組件。
演算法:
實際上,作為實現層面上的一點細節,如果 x 的頻率為 f,那麼我們將獲取在所有 group[i] (i <= f) 中的 x,而不僅僅是棧頂的那個。這是因為每個 group[i] 都會存儲與第 i 個 x 副本相關的信息。
最後,我們僅僅需要如上所述維持 freq,group,以及 maxfreq。
代碼示例:
class FreqStack {
Map<Integer, Integer> freq;
Map<Integer, Stack<Integer>> group;
int maxfreq;
public FreqStack() {
freq = new HashMap();
group = new HashMap();
maxfreq = 0;
}
public void push(int x) {
int f = freq.getOrDefault(x, 0) + 1;
freq.put(x, f);
if (f > maxfreq)
maxfreq = f;
group.computeIfAbsent(f, z-> new Stack()).push(x);
}
public int pop() {
int x = group.get(maxfreq).pop();
freq.put(x, freq.get(x) - 1);
if (group.get(maxfreq).size() == 0)
maxfreq--;
return x;
}
}
複雜度分析:
時間複雜度:對於 push 和 pop 操作, O(1)。
空間複雜度: O(N),其中 N 為 FreqStack 中元素的數目。
面試題022:給定一個鏈表,刪除鏈表的倒數第N個節點,並且返回鏈表的頭結點。
——阿里巴巴出題專家:屹平/阿里雲視頻雲邊緣計算高級技術專家
? 示例:
給定一個鏈表: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,鏈表變為 1->2->3->5.
說明:
給定的 n 保證是有效的。
要求:
只允許對鏈表進行一次遍歷。
參考答案
我們可以使用兩個指針而不是一個指針。第一個指針從列表的開頭向前移動 n+1n+1 步,而第二個指針將從列表的開頭出發。現在,這兩個指針被 nn 個結點分開。我們通過同時移動兩個指針向前來保持這個恆定的間隔,直到第一個指針到達最後一個結點。此時第二個指針將指向從最後一個結點數起的第 nn 個結點。我們重新鏈接第二個指針所引用的結點的 next 指針指向該結點的下下個結點。
代碼示例:
public ListNode removeNthFromEnd(ListNode head, int n)
{
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode first = dummy;
ListNode second = dummy;
// Advances first pointer so that the gap between first and second is n nodes apart
for (int i = 1; i <= n + 1; i++) {
first = first.next;
}
// Move first to the end, maintaining the gap
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummy.next;
}
複雜度分析:
*時間複雜度:O(L),該演算法對含有 L 個結點的列表進行了一次遍歷。因此時間複雜度為 O(L)。
*空間複雜度:O(1),我們只用了常量級的額外空間。
面試題023:如果讓你設計一個通用的、支持各種資料庫秒級備份和恢復的系統,你會如何設計?
——阿里巴巴出題專家:千震/阿里雲資料庫高級技術專家
參考答案
開放性問題,無標準答案。
面試題024:如果讓你來設計一個支持資料庫、NOSQL和大數據之間數據實時流動的數據流及處理的系統,你會考慮哪些問題?如何設計?
——阿里巴巴出題專家:千震/阿里雲資料庫高級技術專家
參考答案
開放性問題,無標準答案。
面試題025:給定一個整數數組和一個整數,返回兩個數組的索引,這兩個索引指向的數字的加和等於指定的整數。需要最優的演算法,分析演算法的空間和時間複雜度。
——阿里巴巴出題專家:龍欣/異構計算資深技術專家
參考答案
開放性問題,無標準答案。
面試題026:假如給你一個新產品,你將從哪些方面來保障它的質量?
——阿里巴巴出題專家:晨暉 /阿里雲中間件技術部測試開發專家
參考答案
可以從代碼開發、測試保障、線上質量三個方面來保障。
在代碼開發階段,有單元測試、代碼Review、靜態代碼掃描等;測試保障階段,有功能測試、性能測試、高可用測試、穩定性測試、兼容性測試等;在線上質量方面,有灰度發布、緊急回滾、故障演練、線上監控和巡檢等。
面試題027:如何用socket編程實現ftp協議?
——阿里巴巴出題專家:吳明/阿里雲彈性計算資深技術專家
參考答案
https://www.jianshu.com/p/e9a2e0755496
面試題028:請評估一下程序的執行結果?
——阿里巴巴出題專家:桃谷/阿里雲中間件技術專家
public class SynchronousQueueQuiz { public static void main(String[] args) throws Exception {
BlockingQueue<Integer> queue = new SynchronousQueue<>(); System.out.print(queue.offer(1) + " "); System.out.print(queue.offer(2) + " "); System.out.print(queue.offer(3) + " "); System.out.print(queue.take() + " "); System.out.println(queue.size()); } }
A. true true true 1 3
B. true true true (阻塞)
C. false false false null 0
D. false false false (阻塞)
參考答案 D
原文鏈接:
https://yq.aliyun.com/download/3587?utm_content=m_1000061168&do=login
※CVPR主席朱松純等聯名聲明挺華為:IEEE限制評審參會,我們不!
※AMD宣布不再對中國合資公司授權x86 IP,自主才是硬道理
TAG:新智元 |