前些日子在網上偶然間看到了一波阿里的技術筆面試題,自己自信地嘗試做了一波,但結果很可惜,在不上網搜參考的情況下,20道題我只做出來8個…真尷尬,

題目水平高低起伏,這里我先把所有題目給大家看一遍,大多數題目后面都有參考答案,個別的確實沒找著答案,大家可以現在這里看一遍題目去思考一下你自己的答案,看你在不看答案的情況下能做出幾個來,
一、題目預覽
1.如何實作兩金額資料相加(最多小數點兩位)?
.
2.有一批氣象觀測站,現需要獲取這些站點的觀測資料,并存盤到 Hive 中,但是氣象局只提供了 api 查詢,每次只能查詢單個觀測點,那么如果能夠方便快速地獲取到所有的觀測點的資料?
.
3.請計算XILINX公司VU9P芯片的算力相當于多少TOPS,給出計算程序與公式,
.
4.給定一個整數陣列和一個整數,回傳兩個陣列的索引,這兩個索引指向的數字的加和等于指定的整數,需要最優的演算法,分析演算法的空間和時間復雜度,
.
5.MySQL 的資料如何恢復到任意時間點?
.
6.給定一個二叉搜索樹(BST),找到樹中第 K 小的節點,
.
7.一顆現代處理器,每秒大概可以執行多少條簡單的MOV指令,有哪些主要的影響因素?
.
8. 在云計算大資料處理場景中,每天運行著成千上萬的任務,每個任務都要進行 IO 讀寫,存盤系統為了更好的服務,經常會保證高優先級的任務優先執行,當多個作業或用戶訪問存盤系統時,如何保證優先級和公平性?
.
9.如何實作一個高效的單向鏈表逆序輸出?
.
10. 你理解常見如阿里,和友商大資料平臺的技術體系差異以及發展趨勢和技術瓶頸,在存盤和計算兩個方面進行概述,
.
11.如果讓你來設計一個支持資料庫、NOSQL 和大資料之間資料實時流動的資料流及處理的系統,你會考慮哪些問題?如何設計?
.
12.假如給你一個新產品,你將從哪些方面來保障它的質量?
.
13.已知 sqrt (2)約等于 1.414,要求不用數學庫,求 sqrt (2)精確到小數點后 10 位,
.
14.LRU 快取機制,設計和實作一個 LRU(最近最少使用)快取資料結構,使它應該支持一下操作:get 和 put, get(key) - 如果 key 存在于快取中,則獲取 key 的 value(總是正數),否則回傳 -1, put(key,value) - 如果 key 不存在,請設定或插入 value,當快取達到其容量時,它應該在插入新專案之前使最近最少使用的專案作廢,
.
15.給定一個鏈表,洗掉鏈表的倒數第 N 個節點,并且回傳鏈表的頭結點,
.
16.輸入 ping IP 后敲回車,發包前會發生什么?
.
17.請解釋下為什么鹿晗發布戀情的時候,微博系統會崩潰,如何解決?
.
18. 關于并行計算的一些基礎開放問題,
.
19.請評估一下程式的執行結果?
.
20.現有一批郵件需要發送給訂閱顧客,且有一個集群(集群的節點數不定,會動態擴容縮容)來負責具體的郵件發送任務,如何讓系統盡快地完成發送?請詳述技術方案!
阿里的筆面試題和答案我已整理成檔案,如果你文章看不習慣文章的話,可以找我要檔案去看的,
二、參考答案
以下只是網上的一些大神以及小哥自己做出的一些參考答案,并非出自阿里內部的答案,大家沒有頭緒的情況下可以參考參考,
1.如何實作兩金額資料相加(最多小數點兩位)?
出題人:阿里巴巴出題專家:御術/螞蟻金服資料可視化高級技術專家
參考答案:
其實問題并不難,就是考察候選人對 JavaScript 資料運算上的認知以及考慮問題的縝密程度,有很多坑,可以用在筆試題,如果用在面試,回答程序中還可以隨機加入有很多計算機基礎的延伸,
回到這個問題,由于直接浮點相與加會失精,所以要轉整數;(可以插入問遇到過嗎?是否可以舉個例子?),
轉整數是第一個坑,雖然只有兩位可以通過乘以100轉整數,但由于乘以一百和除以一百都會出現浮點數的運算,所以也會失精,還是要通過字串來轉;(可以插入問字串轉整數有幾種方式?)字串轉整是第二個坑,因為最后要對齊計算,如果沒考慮周全先toFixed(2),對于只有一位小數點資料進入計算就會錯誤;轉整數后的計算是個加分點,很多同學往往就是直接算了,如果可以考慮大數計算的場景,恭喜同學進入隱藏關卡,這就會涉及如何有效回圈、遍歷、演算法復雜度的問題,
2.有一批氣象觀測站,現需要獲取這些站點的觀測資料,并存盤到 Hive 中,但是氣象局只提供了 api 查詢,每次只能查詢單個觀測點,那么如果能夠方便快速地獲取到所有的觀測點的資料?
出題人:阿里巴巴出題專家:江嵐/阿里巴巴資料技術高級技術專家
參考答案:
A. 通過 shell 或 python 等呼叫 api,結果先暫存本地,最后將本地檔案上傳到 Hive 中,
B. 通過 datax 的 httpReader 和 hdfsWriter 插件,從而獲取所需的資料,
C. 比較理想的回答,是在計算引擎的 UDF 中呼叫查詢 api,執行UDF 的查詢結果存盤到對應的表中,一方面,不需要同步任務的匯出匯入;另一方面,計算引擎的分布式框架天生提供了分布式、容錯、并發等特性,
3.請計算XILINX公司VU9P芯片的算力相當于多少TOPS,給出計算程序與公式,
出題人: 阿里巴巴出題專家:隱達/阿里云異構計算資深專家
參考答案:基于不同的演算法,這個值在十幾到幾百之間,但是,如果只是單純比算力,FPGA和ASIC、GPU相比并無太大優勢,甚至大多時候有較大劣勢,FPGA的優勢在于高度的靈活性和演算法的針對性,

4.給定一個整數陣列和一個整數,回傳兩個陣列的索引,這兩個索引指向的數字的加和等于指定的整數,需要最優的演算法,分析演算法的空間和時間復雜度
參考答案:
Ha
public int[] twoSum(int[] nums, int target) {
if(nums==null || nums.length<2)
return new int[]{0,0};
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i=0; i<nums.length; i++){
if(map.containsKey(nums[i])){
return new int[]{map.get(nums[i]), i};
}else{
map.put(target-nums[i], i);
}
}
return new int[]{0,0};
}
分析:空間復雜度和時間復雜度均為 O(n)

5.MySQL 的資料如何恢復到任意時間點?
出題人:阿里巴巴出題專家:近秋/阿里云資料庫產品技術部技術專家參考答案
參考答案:恢復到任意時間點以定時的做全量備份,以及備份增量的 binlog 日志為前提,恢復到任意時間點首先將全量備份恢復之后,再此基礎上回放增加的 binlog 直至指定的時間點,
6.給定一個二叉搜索樹(BST),找到樹中第 K 小的節點,
出題人:阿里巴巴出題專家:文景/阿里云 CDN 資深技術專家
參考答案:
- 考察點
基礎資料結構的理解和編碼能力
遞回使用 - 示例
5
/ \
3 6
/ \
2 4
/
1
說明:保證輸入的 K 滿足 1<=K<=(節點數目)
解法1:
樹相關的題目,第一眼就想到遞回求解,左右子樹分別遍歷,聯想到二叉搜索樹的性質,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);
}
}
解法2:
基于二叉搜索樹的特性,在中序遍歷的結果中,第k個元素就是本題的解, 最差的情況是k節點是bst的最右葉子節點,不過每個節點的遍歷次數最多是1次, 遍歷并不是需要全部做完,使用計數的方式,找到第k個元素就可以退出, 下面是go的一個簡單實作,
// BST is binary search tree
type BST struct {
key, value int
left, right *BST
}
func (bst *BST) setLeft(b *BST) {
bst.left = b
}
func (bst *BST) setRight(b *BST) {
bst.right = b
}
// count 查找bst第k個節點的值,未找到就回傳0
func count(bst *BST, k int) int {
if k < 1 {
return 0
}
c := 0
ok, value := countRecursive(bst, &c, k)
if ok {
return value
}
return 0
}
// countRecurisive 對bst使用中序遍歷
// 用計數方式控制退出遍歷,引數c就是已遍歷節點數
func countRecursive(bst *BST, c *int, k int) (bool, int) {
if bst.left != nil {
ok, value := countRecursive(bst.left, c, k)
if ok {
return ok, value
}
}
if *c == k-1 {
return true, bst.value
}
*c++
if bst.right != nil {
ok, value := countRecursive(bst.right, c, k)
if ok {
return ok, value
}
}
return false, 0
}
// 下面是測驗代碼,覆寫了退化的情況和普通bst
func createBST1() *BST {
b1 := &BST{key: 1, value: 10}
b2 := &BST{key: 2, value: 20}
b3 := &BST{key: 3, value: 30}
b4 := &BST{key: 4, value: 40}
b5 := &BST{key: 5, value: 50}
b6 := &BST{key: 6, value: 60}
b7 := &BST{key: 7, value: 70}
b8 := &BST{key: 8, value: 80}
b9 := &BST{key: 9, value: 90}
b9.setLeft(b8)
b8.setLeft(b7)
b7.setLeft(b6)
b6.setLeft(b5)
b5.setLeft(b4)
b4.setLeft(b3)
b3.setLeft(b2)
b2.setLeft(b1)
return b9
}
func createBST2() *BST {
b1 := &BST{key: 1, value: 10}
b2 := &BST{key: 2, value: 20}
b3 := &BST{key: 3, value: 30}
b4 := &BST{key: 4, value: 40}
b5 := &BST{key: 5, value: 50}
b6 := &BST{key: 6, value: 60}
b7 := &BST{key: 7, value: 70}
b8 := &BST{key: 8, value: 80}
b9 := &BST{key: 9, value: 90}
b1.setRight(b2)
b2.setRight(b3)
b3.setRight(b4)
b4.setRight(b5)
b5.setRight(b6)
b6.setRight(b7)
b7.setRight(b8)
b8.setRight(b9)
return b1
}
func createBST3() *BST {
b1 := &BST{key: 1, value: 10}
b2 := &BST{key: 2, value: 20}
b3 := &BST{key: 3, value: 30}
b4 := &BST{key: 4, value: 40}
b5 := &BST{key: 5, value: 50}
b6 := &BST{key: 6, value: 60}
b7 := &BST{key: 7, value: 70}
b8 := &BST{key: 8, value: 80}
b9 := &BST{key: 9, value: 90}
b5.setLeft(b3)
b5.setRight(b7)
b3.setLeft(b2)
b3.setRight(b4)
b2.setLeft(b1)
b7.setLeft(b6)
b7.setRight(b8)
b8.setRight(b9)
return b5
}
func createBST4() *BST {
b := &BST{key: 1, value: 10}
last := b
for i := 2; i < 100000; i++ {
n := &BST{key: i, value: i * 10}
last.setRight(n)
last = n
}
return b
}
func createBST5() *BST {
b := &BST{key: 99999, value: 999990}
last := b
for i := 99998; i > 0; i-- {
n := &BST{key: i, value: i * 10}
last.setLeft(n)
last = n
}
return b
}
func createBST6() *BST {
b := &BST{key: 50000, value: 500000}
last := b
for i := 49999; i > 0; i-- {
n := &BST{key: i, value: i * 10}
last.setLeft(n)
last = n
}
last = b
for i := 50001; i < 100000; i++ {
n := &BST{key: i, value: i * 10}
last.setRight(n)
last = n
}
return b
}
func TestK(t *testing.T) {
bst1 := createBST1()
bst2 := createBST2()
bst3 := createBST3()
bst4 := createBST4()
check(t, bst1, 1, 10)
check(t, bst1, 2, 20)
check(t, bst1, 3, 30)
check(t, bst1, 4, 40)
check(t, bst1, 5, 50)
check(t, bst1, 6, 60)
check(t, bst1, 7, 70)
check(t, bst1, 8, 80)
check(t, bst1, 9, 90)
check(t, bst2, 1, 10)
check(t, bst2, 2, 20)
check(t, bst2, 3, 30)
check(t, bst2, 4, 40)
check(t, bst2, 5, 50)
check(t, bst2, 6, 60)
check(t, bst2, 7, 70)
check(t, bst2, 8, 80)
check(t, bst2, 9, 90)
check(t, bst3, 1, 10)
check(t, bst3, 2, 20)
check(t, bst3, 3, 30)
check(t, bst3, 4, 40)
check(t, bst3, 5, 50)
check(t, bst3, 6, 60)
check(t, bst3, 7, 70)
check(t, bst3, 8, 80)
check(t, bst3, 9, 90)
check(t, bst4, 1, 10)
check(t, bst4, 2, 20)
check(t, bst4, 3, 30)
check(t, bst4, 4, 40)
check(t, bst4, 5, 50)
check(t, bst4, 6, 60)
check(t, bst4, 7, 70)
check(t, bst4, 8, 80)
check(t, bst4, 9, 90)
check(t, bst4, 99991, 999910)
check(t, bst4, 99992, 999920)
check(t, bst4, 99993, 999930)
check(t, bst4, 99994, 999940)
check(t, bst4, 99995, 999950)
check(t, bst4, 99996, 999960)
check(t, bst4, 99997, 999970)
check(t, bst4, 99998, 999980)
check(t, bst4, 99999, 999990)
}
func check(t *testing.T, b *BST, k, value int) {
t.Helper()
checkCall(t, b, k, value, count)
// 此處可添加其他解法的實作
}
func checkCall(t *testing.T, b *BST, k, value int, find func(bst *BST, kth int) int) {
t.Helper()
got := find(b, k)
if got != value {
t.Fatalf("want:%d, got:%d", value, got)
}
}
7.一顆現代處理器,每秒大概可以執行多少條簡單的MOV指令,有哪些主要的影響因素?
出題人:阿里巴巴出題專家:子團/創新產品虛擬化&穩定性資深技術專家
參考答案:
及格: 每執行一條mov指令需要消耗1個時鐘周期,所以每秒執行的mov指令和CPU主頻相關,
加分: 在CPU微架構上,要考慮資料預取,亂序執行,多發射,記憶體stall(前端stall和后端stall)等諸多因素,因此除了cpu主頻外,還和流水線上的效率(IPC)強相關,比較復雜的一個問題,

8. 在云計算大資料處理場景中,每天運行著成千上萬的任務,每個任務都要進行 IO 讀寫,存盤系統為了更好的服務,經常會保證高優先級的任務優先執行,當多個作業或用戶訪問存盤系統時,如何保證優先級和公平性?
暫時沒有答案,
9.如何實作一個高效的單向鏈表逆序輸出?
出題人:阿里巴巴出題專家:昀龍/阿里云彈性人工智能負責人
參考答案:下面是其中一種寫法,也可以有不同的寫法,比如遞回等,供參考,
typedef struct node{
int data;
struct node* next;
node(int d):data(d), next(NULL){}
}node;
void reverse(node* head)
{
if(head == NULL){
return;
}
node* pleft = NULL;
node* pcurrent = head;
node* pright = head->next;
while(pright){
pcurrent->next = pleft;
node *ptemp = pright->next;
pright->next = pcurrent;
pleft = pcurrent;
pcurrent = pright;
pright = ptemp;
}
while(pcurrent != NULL){
cout<< pcurrent->data << "\t";
pcurrent = pcurrent->next;
}
}
class Solution<T> {
public void reverse(ListNode<T> head) {
if (head == null || head.next == null) {
return ;
}
ListNode<T> currentNode = head;
Stack<ListNode<T>> stack = new Stack<>();
while (currentNode != null) {
stack.push(currentNode);
ListNode<T> tempNode = currentNode.next;
currentNode.next = null; // 斷開連接
currentNode = tempNode;
}
head = stack.pop();
currentNode = head;
while (!stack.isEmpty()) {
currentNode.next = stack.pop();
currentNode = currentNode.next;
}
}
}
class ListNode<T>{
T val;
public ListNode(T val) {
this.val = val;
}
ListNode<T> next;
}
10. 你理解常見如阿里,和友商大資料平臺的技術體系差異以及發展趨勢和技術瓶頸,在存盤和計算兩個方面進行概述,
出題人: 阿里巴巴出題專家:映泉/阿里巴巴高級技術專家
參考答案:開放性問題,無標準答案,
11.如果讓你來設計一個支持資料庫、NOSQL 和大資料之間資料實時流動的資料流及處理的系統,你會考慮哪些問題?如何設計?
出題人:阿里巴巴出題專家:千震/阿里云資料庫高級技術專家
參考答案:開放性問題,無標準答案,

12.假如給你一個新產品,你將從哪些方面來保障它的質量?
出題人:阿里巴巴出題專家:晨暉 /阿里云中間件技術部測驗開發專家
參考答案:
可以從代碼開發、測驗保障、線上質量三個方面來保障,
在代碼開發階段,有單元測驗、代碼Review、靜態代碼掃描等;
測驗保障階段,有功能測驗、性能測驗、高可用測驗、穩定性測驗、兼容性測驗等;
在線上質量方面,有灰度發布、緊急回滾、故障演練、線上監控和巡檢等,
13.已知 sqrt (2)約等于 1.414,要求不用數學庫,求 sqrt (2)精確到小數點后 10 位,
出題人:——阿里巴巴出題專家:文景/阿里云 CDN 資深技術專家
參考答案:
- 考察點
1)基礎演算法的靈活應用能力(二分法學過資料結構的同學都知道,但不一定往這個方向考慮;如果學過數值計算的同學,應該還要能想到牛頓迭代法并解釋清楚)
2)退出條件設計
二分法
-
已知 sqrt(2)約等于 1.414,那么就可以在(1.4, 1.5)區間做二分
查找,如: a) high=>1.5 b) low=>1.4 c) mid => (high+low)/2=1.45 d) 1.45*1.45>2 ? high=>1.45 : low => 1.45 e) 回圈到 c) -
退出條件
a) 前后兩次的差值的絕對值<=0.0000000001, 則可退出
const double EPSILON = 0.0000000001;
double sqrt2() {
double low = 1.4, high = 1.5;
double mid = (low + high) / 2;
while (high - low > EPSILON) {
if (mid * mid > 2) {
high = mid;
} else {
low = mid;
}
mid = (high + low) / 2;
}
return mid;
}
牛頓迭代法
1.牛頓迭代法的公式為:
xn+1 = xn-f(xn)/f’(xn)
對于本題,需要求解的問題為:f(x)=x2-2 的零點
EPSILON = 0.1 ** 10
def newton(x):
if abs(x ** 2 - 2) > EPSILON:
return newton(x - (x ** 2 - 2) / (2 * x))
else:
return x

14.LRU 快取機制,設計和實作一個 LRU(最近最少使用)快取資料結構,使它應該支持一下操作:get 和 put, get(key) - 如果 key 存在于快取中,則獲取 key 的 value(總是正數),否則回傳 -1, put(key,value) - 如果 key 不存在,請設定或插入 value,當快取達到其容量時,它應該在插入新專案之前使最近最少使用的專案作廢,
出題人:文景/阿里云 CDN 資深技術專家
參考答案:
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);
}
}
}
15.給定一個鏈表,洗掉鏈表的倒數第 N 個節點,并且回傳鏈表的頭結點,
? 示例: 給定一個鏈表: 1->2->3->4->5, 和 n = 2. 當洗掉了倒數第二個節點后,鏈表變為 1->2->3->5. 說明: 給定的 n 保證是有效的, 要求: 只允許對鏈表進行一次遍歷,
出題人:阿里巴巴出題專家:屹平/阿里云視頻云邊緣計算高級技術專家
參考答案:
我們可以使用兩個指標而不是一個指標,第一個指標從串列的開頭向前移動 n+1 步,而第二個指標將從串列的開頭出發,現在,這兩個指標被 n 個結點分開,我們通過同時移動兩個指標向前來保持這個恒定的間隔,直到第一個指標到達最后一個結點,此時第二個指標將指向從最后一個結點數起的第 n 個結點,我們重新鏈接第二個指標所參考的結點的 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),我們只用了常量級的額外空間,

16.輸入 ping IP 后敲回車,發包前會發生什么?
出題人:阿里巴巴出題專家:懷虎/阿里云云效平臺負責人
參考答案:
ping目標ip時,先查路由表,確定出介面
如果落在直連介面子網內,此時若為以太網等 多路訪問網路 則先查詢arp快取,命中則直接發出,否則在該介面上發arp詢問目標ip的mac地址,取得后發出,若為ppp等 點對點網路 ,則直接可以發出;
如果查表落在預設路由上,此時若為以太網等 多路訪問網路 則先查詢網關arp快取,命中則直接發出,否則在該介面上發arp詢問網關的mac地址,取得后發出,若為ppp等 點對點網路 ,則直接可以發出;
若查表未命中,則回傳不可達,
17.請解釋下為什么鹿晗發布戀情的時候,微博系統會崩潰,如何解決?
出題人:阿里巴巴出題專家:江嵐/阿里巴巴資料技術高級技術專家
參考答案:
A. 獲取微博通過 pull 方式還是 push 方式
B. 發布微博的頻率要遠小于閱讀微博
C. 流量明星的發微博,和普通博主要區分對待,比如在 sharding的時候,也要考慮這個因素

18. 關于并行計算的一些基礎開放問題,
? 如何定義并計算,請分別闡述分布式記憶體到共享記憶體模式行編程的區別和實作(例子代碼)?
? 請使用 MPI 和 OpenMP 分別實作 N 個處理器對 M 個變數的求和?
? 請說明 SIMD 指令在回圈中使用的權限?向量化優化有哪些手段?
? 請用 Amdahl定律說明什么是并行效率以及并行演算法的擴展性?并說明擴展性的性能指標和限制因素,最后請說明在共享記憶體計算機中,共享記憶體的限制?OpenMP是怎樣實作共享記憶體編程環境的?MPI 阻塞和非阻塞讀寫的區別?
出題人:阿里巴巴出題專家:何萬青/阿里云高性能計算資深技術專家
參考答案:
(簡要答案,但必須觸及,可以展開)
?同時執行多個/演算法/邏輯操作/記憶體訪問/IO,相互獨立同時運行,分三個層次:行程級,多個節點分布式記憶體通過MPI通信并行;執行緒級,共享記憶體的多路機器,通過OpenMP實作多執行緒并行;指令集:通過SIM指令實作單指令多資料,,,,舉例吧啦吧啦,
? 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的核心函式,回答問題即可,
19.請評估一下程式的執行結果?
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
20.現有一批郵件需要發送給訂閱顧客,且有一個集群(集群的節點數不定,會動態擴容縮容)來負責具體的郵件發送任務,如何讓系統盡快地完成發送?請詳述技術方案!
出題人:阿里巴巴出題專家:江嵐/阿里巴巴資料技術高級技術專家
參考答案:
A. 借助訊息中間件,通過發布者訂閱者模式來進行任務分配
B. master-slave 部署,由 master 來分配任務
C. 不借助任何中間件,且所有節點均等,通過資料庫的 update-returning,從而實作節點之間任務的互斥
今天的分享就到這里了,我是最近沒有換崗的打算所以沒刷題,但凡是再給我點時間,這種題目我也能做出來個七八成,所有題目我已經整成檔案,要的話找我就行,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/290654.html
標籤:其他
下一篇:作業系統-2.4-死鎖
