1. 程式人生 > >網易、百度等公司面試題整理

網易、百度等公司面試題整理

1、n是一個奇數,求證n(n^2-1)能被24整除(網易)

n=2*k+1;那麼n(n^2-1)=4*k(k+1)*(2k+1)=4*6*(1^2+...+k^2),顯然能被24整除。

2、do...while和while...do有什麼區別(華為)

前者先執行一遍迴圈體,在進行條件判斷;後者先進性判斷,然後根據判斷結果來決定是否執行;所以前者的迴圈體至少執行一次。

3、兩個整數集合A和B,求其交集(騰訊)

構造一個map,遍歷A中的元素,插入到map中;然後遍歷B中的元素,看是否在map中出現。

4、如何引用一個已經定義過的全域性變數(華為)

可以引用標頭檔案的方式,也可以使用extern關鍵字;兩者的區別在於,如果變量出錯了,那麼前者將會在編譯期間報錯,而後者則會等到連線期間報錯

5、甲乙丙丁4個人輪流順序抽籤(共4張籤)。任何第一個抽中“請客”的人即請大家吃飯。假設:
A) 4張籤中共有1張請客的籤;
B) 4張籤中共有2張請客的籤;
C) 4張籤中共有3張請客的籤;
請問A)、B)、C)三種情況下甲乙丙丁每個人請大家吃飯的概率分別有多大?(迅雷)

A) 第一個人請客的概率 1/4;第二個人請客的概率是 3/4 * 1/3 = 1/4;第三個人請客的概率是 3/4 * 2/3 * 1/2 = 1/4;第四個人請客的概率是 3/4 * 2/3 * 1/2 * 1 = 1/4。
B) 第一個人請客的概率是 2/4 = 1/2;第二個人請客的概率是 2/4 * 2/3 = 1/3;第三個人請客的概率是 2/4 * 1/3 = 1/6;第四個人請客的概率是 0。
C) 第一個人請客的概率是 3/4;第二個人請客的概率是 1/4;第三四個人請客的概率是0。(跟自己想的出入挺大,自己少考慮了比較多的情況)


6、n個空間(其中n<1M),存放a到a+n-1的數,位置隨機且數字不重複,a為正且未知。現在第一個空間的數被誤設定為-1。已經知道被修改的數不是最小的。請找出被修改的數字是多少。
例如:n=6,a=2,原始的串為5, 3, 7, 6, 2, 4。現在被別人修改為-1, 3, 7, 6, 2, 4。現在希望找到5。(百度)

這個題如果能弄懂題目意圖的話,貌似沒什麼難得;答案奉上:

由於修改的數不是最小的,所以遍歷第二個空間到最後一個空間可以得到a的值。
a 到 a+n-1這 n個數的和是 total = na + (n - 1)n/2。
將第二個至最後一個空間的數累加獲得 sub_total。
那麼被修改的數就是 total - sub_total。(或許應該考慮相加溢位的情況,故應該採用邊加邊減的方式,或者整體減去a的值,在進行後續計算)

7、兄弟該如何分錢:

媽媽有2000元,要分給她的2個孩子。由哥哥先提出分錢的方式,如果弟弟同意,那麼就這麼分。但如果弟弟不同意,媽媽會沒收1000元,由弟弟提出剩下 1000元的分錢方式,這時如果哥哥同意了,就分掉這剩下的1000元。但如果哥哥也不同意,媽媽會把剩下的1000元也拿走,然後分別只給他們每人100元。問:如果你是哥哥,你會提出什麼樣的分錢方式,使你有可能得到最多的錢?(最小單位1元)(IBM)

只要模仿海盜分金問題,採用從後往前推的思路就可以了,比較簡單。

哥哥提出分配方案時,弟弟是否同意取決於拒絕後是否可以獲得更多利益。弟弟分配時,哥哥是否同意也取決於拒絕後是否可以獲得更多好處。所以採取由後向前推導的方法。如果在兩次分配中弟弟和哥哥都不同意,則弟弟和哥哥各獲得100元。弟弟分錢時,為保證哥哥同意,會提出哥哥101元,弟弟899元的分配方法。因為哥哥獲得了比拒絕後的更多利益,所以必然會同意。哥哥分錢時,為保證弟弟同意,會提出哥哥1100元,弟弟900元的分配方法。因為弟弟獲得了比拒絕後的更多利益,所以必然會同意。也就是說,最終哥哥會提出哥哥1100元,弟弟900元的分配方法。

8、在一個重男輕女的國家裡,每個家庭都想生男孩,如果他們生的孩子是女孩,就再生一個,直到生下的是男孩為止。這樣的國家,男女比例會是多少?(Google)

我的答案是1:1,或者說接近於1:1,;可以考慮採用數學的方法,對與一個家庭,如果說有N個小孩,則會出現如下情況:

1/2 N=1:1個男孩

1/4 N=2:1個男孩,1個女孩

1/2^n N=n:1個男孩,(n-1)個女孩

我們統計Boy(n)近似為1,Girl(n)=1-(n-1)/2^n,數學上來說當n比較大時,接近於1:1;但是現實生活中n都不是太大,並且人為流產(人工干預)等因素,造成生男生女的概率不相等,所以也就出現了性別失調。

9、隨機洗牌問題;給出一種模擬方法,使得洗牌的結果比較隨機;(微軟)

1. for i:=1 to n do swap(a[i], a[random(1,n)]); // 湊合,但不是真正隨機
2. for i:=1 to n do swap(a[i], a[random(i,n)]); // 真正的隨機演算法
其中,random(a,b)函式用於返回一個從a到b(包括a和b)的隨機整數。
2)的時間複雜度O(n), 空間複雜度O(1);

10、在100w個數中找最大的前100個數(百度)

應該使用某種資料結構儲存迄今最大的100個數。每讀到一個新數時,將新數和儲存的100個數中的最小一個相比較,如果新數更大些,則替換。這樣掃描一遍100w個數也就獲得了最大的100個數。
對於儲存的100個數的資料結構,應該在最小複雜度的條件下滿足
1)可以獲得最小的數;
2)將最小數替換為另一個數後可以重新調整,使其可以滿足條件1。
可見小根堆可以滿足這些條件。
所以應該採用小根堆+掃描的方法。

11、正向最大匹配分詞,怎麼做最快?(百度)

Trie樹(有待進一步研究)

12、session和cache的區別是什麼?(百度)

session是針對單個連線(會話)來使用的,主要儲存和連線相關的上下文資訊,比如登入資訊等等。
cache是應用程式級的,主要用來快取計算結果,減輕伺服器負擔,並加快響應速度。

13、session和cookie的區別?

由於http是無狀態的協議,所以我們需要使用cookie和session來維護伺服器和客戶端互動過程中的上下文資訊。
cookie是儲存在客戶端的資料。伺服器通過在http響應頭,或者通過網頁中的指令碼在客戶端中生成cookie。當客戶端訪問某個頁面時,會把符合條件的cookie一併傳送給伺服器。這樣伺服器就可以獲得以前記錄的狀態了。
session是儲存在伺服器端以sessionid作為key資料。伺服器通過cookie(或者在url加入sessionid資訊)將sessionid傳給客戶端,當客戶端再次請求時,服務端就可以識別這個sessionid,並獲得相應的上下文資訊了

cookie 和session 的區別:
1、cookie資料存放在客戶的瀏覽器上,session資料放在伺服器上。
2、cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙
考慮到安全應當使用session
3、session會在一定時間內儲存在伺服器上。當訪問增多,會比較佔用你伺服器的效能
考慮到減輕伺服器效能方面,應當使用COOKIE
4、單個cookie在客戶端的限制是3K,就是說一個站點在客戶端存放的COOKIE不能3K

14、瘋子坐飛機問題

飛機上有100個座位,按順序從1到100編號。有100個乘客,他們分別拿到了從1號到100號的座位,他們按號碼順序登機並應當對號入座,如果 他們發現對應號座位被別人坐了,他會在剩下空的座位隨便挑一個坐。現在假如1號乘客瘋了 -_-! (其他人沒瘋),他會在100個座位中隨機坐一個座位。那麼第100人正確坐自己座位的概率是多少? 注意登機是從1到100按順序的。

假設飛機上只有兩個座位,那麼顯然第二個人有50%的概率坐在自己的座位上。
假設飛機上只有三個座位,如果1號坐了自己的座位,則3號會坐在自己的座位上;如果1號坐了3號的座位,則3號不能坐到自己的座位上;如果1號坐了2號的座位,則對於3號來說,效果和2號應該坐到1號座位上,但他會隨機坐相同,也就是等價於1號沒瘋,2號瘋了,根據上面只有兩個座位時的情況,知道這種情況下3號有50%的概率坐到自己的座位上。所以總體來說3號有50%的概率坐到自己的座位上。
.....
以此類推,可以知道當有100個座位時,100號坐到自己座位上的概率為50%

15、誰能先說出總和為100的數(迅雷)

甲乙兩人,玩一個遊戲。每人輪流說出1-10的一個數字,從甲開始。輪到某個人,使得所有說出的數字的總和等於100,就算誰贏。
請問甲或乙誰有必勝的把握,為什麼?

先假設X必勝,Y必輸。
那麼不論Y最後說出的數字是1還是10,X都能說出一個數使得總數為100。可以推出Y最後一次說之前的總和為89。
同理可以推出Y倒數第二次說之前總和為78。
依次類推,可以知道Y說之前的數字分別為1,12,23 ... 78, 89。
可以看出X就是甲。他的策略就是,先說出1,然後乙說出數字n,甲就說11-n

16、將query按照出現的頻度排序(10個1G大小的檔案)(百度)
有10個檔案,每個檔案1G,每個檔案的每一行都存放的是使用者的query,每個檔案的query都可能重複。如何按照query的頻度排序?

1)讀取10個檔案,按照hash(query)%10的結果將query寫到對應的檔案中。
這樣我們就有了10個大小約為1G的檔案。任意一個query只會出現在某個檔案中。
2)對於1)中獲得的10個檔案,分別進行如下操作
- 利用hash_map(query,query_count)來統計每個query出現的次數。
- 利用堆排序演算法對query按照出現次數進行排序。
- 將排序好的query輸出的檔案中。
這樣我們就獲得了10個檔案,每個檔案中都是按頻率排序好的query。
3)對2)中獲得的10個檔案進行歸併排序,並將最終結果輸出到檔案中。
注:如果記憶體比較小,在第1)步中可以增加檔案數。

17、有1到10w這10w個數,去除2個並打亂次序,如何找出那兩個數?(騰訊)

申請10w個bit的空間,每個bit代表一個數字是否出現過。
開始時將這10w個bit都初始化為0,表示所有數字都沒有出現過。
然後依次讀入已經打亂循序的數字,並將對應的bit設為1。
當處理完所有數字後,根據為0的bit得出沒有出現的數字。

18、在1億條使用者記錄裡,如何快速查詢統計出看了5個電影以上的使用者?(迅雷)

構建一個hash map,key為使用者名稱,value為已經看過的電影數量。
遍歷所有使用者記錄,然後根據使用者名稱和已經看過電影數量的情況進行處理:
- 如果使用者名稱不在hash map中,則新增對應使用者名稱,並將值設為1。
- 如果使用者名稱對應的值小於5,則將值加1。如果加1後值為5,則輸出此使用者名稱。
- 如果使用者名稱對應的值等於5,則不進行任何操作。

19、如果在高速公路上30分鐘內看到一輛車開過的機率是0.95,那麼在10分鐘內看到一輛車開過的機率是多少?(假設為常概率條件下)(Google)

假設10分鐘內看到一輛車開過的概率是x,那麼沒有看到車開過的概率就是1-x,30分鐘沒有看到車開過的概率是(1-x)^3,也就是0.05。所以得到方程
(1-x)^3 = 0.05 解方程得到x大約是0.63

20、有25匹馬,每次比賽只能有5匹馬參加,問最少進行幾次比賽才可以得到25匹馬中跑得最快的前3名?(Google)

最少需要7次。
首先將馬分成a,b,c,d,e 5個組,每組5匹,每組單獨比賽。然後將每組的第一名放在一起比賽。假設結果如下
a0,a1,a2,a3,a4
b0,b1,b2,b3,b4
c0,c1,c2,c3,c4
d0,d1,d2,d3,d4
e0,e1,e2,e3,e4
其中a, b,c,d,e小組都是按照名次排列(速度a0>a1>a2>a3>a4, b0>b1....)。並第6次比賽的結果為a0>b0>c0>d0>e0。
那麼第6次比賽結束後,我們知道最快的一匹為a0。
我們知道第2名的馬一定是a1或者b0,所以在接下來的比賽中要包含這兩匹馬。如果a1快,那麼第3名是a2或者b0,如果b0快,那麼第3名是a1,b1或者c0。也就是說第2名和第3名一定在a1,a2,b0,b1和c0當中,所以在第7場比賽中包括這5匹馬就可以得到第2名和第3名。
所以7次比賽就可以獲得前3名的馬。

21、根據上排給出十個數,在其下排填出對應的十個數, 要求下排每個數都是上排對應位置的數在下排出現的次數。上排的數:0,1,2,3,4,5,6,7,8,9。(騰訊)

0,1,2,3,4,5,6,7,8,9
6,2,1,0,0,0,1,0,0,0

22、ibm面試題:只有三隻酒杯,如何將酒平均分給4個人喝?(IBM)

總共16兩酒,4個人喝,平均每人喝4兩。
假設下面的三個數是8兩,8兩和4兩酒杯中的酒。
8 8 0
8 5 3
第一個人先喝3兩,變成
8 5 0
8 2 3
第二個人先喝2兩,變成
8 0 3
8 3 0
5 3 3
5 6 0
2 6 3
2 8 1
第一個人再喝1兩,就剛剛喝了4兩,變成
2 8 0
0 8 2
0 7 3
3 7 0
3 4 3
6 4 0
6 1 3
第三個人先喝1兩,變成
6 0 3
8 0 1
第四個人先喝1兩,變成
8 0 0
5 0 3
第三個人再喝3兩,就剛剛喝了4兩,變成
5 0 0
2 0 3
第二個人再喝2兩,就剛剛喝了4兩,變成
0 0 3
第四個人再喝3兩,就剛剛喝了4兩

23、16個硬幣,A和B輪流拿走一些,每次拿走的個數只能是1,2,4中的一個數。誰最後拿硬幣誰輸。
問:A或B有無策略保證自己贏?

B可以保證自己贏。
如果A拿1個,則B拿2個;如果A拿2個,則B拿1個;如果A拿4個,則B拿2個。這樣每次AB加起來都是3或者6,所以最後會剩下1個或4個。如果是1個則A直接輸了;如果剩下4個,A全拿則輸了,如果不全拿,B繼續採取上面的策略,最後還是剩下1個,還是A輸。

24、網易面試題:警長,逃犯和黑白帽的問題

有一位警長,抓了三個逃犯。現警長決定給他們一次機會。他拿出3頂黑帽子,兩頂白帽子,然後往這三個逃犯頭上每人戴了一頂帽子,每個逃犯只能看到另外兩個逃犯帽子的顏色,不能看到自己帽子的顏色,而且不能進行通訊,不能進行討論,只能靠自己的推理推出來,如果猜出來了,放一條生路,否則處死。
警長先問第一逃犯,結果第一逃犯猜錯了,被殺掉了。
警長問第二個逃犯,結果還是猜錯了,同樣被殺掉了。
警長再問第三個逃犯,結果第三個逃犯猜對了。
說明一下,每個逃犯在回答問題時,其他逃犯是聽不到的。
為什麼第三個一定能猜中,請你給出解釋。

如果第二個和第三個人都是白帽子,則第一個人肯定可以知道自己是黑帽子。第一個人沒有猜對,說明第二和第三個人中肯定有黑帽子。
如果第三個人是白帽子,由於第二和第三個中肯定有黑帽子,那麼第二個人肯定是黑帽子。第二個人沒有猜對,說明第三個人不是白帽子。
所以第三個人知道自己肯定是黑帽子。

25、海量日誌資料,提取出某日訪問百度次數最多的那個IP。

IP地址最多有2^32=4G種取值可能,所以不能完全載入到記憶體中。
可以考慮分而治之的策略,按照IP地址的hash(IP)%1024值,將海量日誌儲存到1024個小檔案中。每個小檔案最多包含4M個IP地址。
對於每個小檔案,可以構建一個IP作為key,出現次數作為value的hash_map,並記錄當前出現次數最多的1個IP地址。
有了1024個小檔案中的出現次數最多的IP,我們就可以輕鬆得到總體上出現次數最多的IP。

26、給40億個不重複的unsigned int的整數,沒排過序的,然後再給幾個數,如何快速判斷這幾個數是否在那40億個數當中?

unsigned int 的取值範圍是0到2^32-1。我們可以申請連續的2^32/8=512M的記憶體,用每一個bit對應一個unsigned int數字。首先將512M記憶體都初始化為0,然後每處理一個數字就將其對應的bit設定為1。當需要查詢時,直接找到對應bit,看其值是0還是1即可。

27、排序陣列中,找出給定數字的出現次數;(微軟)

使用二分查詢的方法分別找出給定數字的開始和結束位置,最壞情況下時間複雜度為O(logn)。
方法比較直接,不過程式碼寫起來還有些難度。有興趣的xdjm可以練習一下 :-)

28、給定字串,刪除開始和結尾處的空格,並將中間的多個連續的空格合併成一個。
比如 “ I like http://hi.baidu.com/mianshiti ” 會變成 "I like http://hi.baidu.com/mianshiti"。

void RemoveExtraSpace(char* str) {
bool keep_space = false;
int new_str_end = 0;

for (int i = 0; str[i]; ++i) {
if (str[i] != " ") {
str[new_str_end++] = str[i];
keep_space = true;
} else if (keep_space) {
str[new_str_end++] = str[i];
keep_space = false;
}
}

if (new_str_end > 0 && str[new_str_end - 1] == " ") {
str[new_str_end - 1] = '\0';
} else {
str[new_str_end] = '\0';
}
}
29、微軟面試題:正則表示式提取連結地址
寫出正則表示式,從一個字串中提取連結地址。比如下面字串中
"IT面試題部落格中包含很多 <a href=http://hi.baidu.com/mianshiti/blog/category/微軟面試題> 微軟面試題 </a> "
則需要提取的地址為 " http://hi.baidu.com/mianshiti/blog/category/微軟面試題 "
在python中:

import re
p = re.compile('<a(?: [^>]*)+href=([^ >]*)(?: [^>]*)*>')
content = "IT面試題部落格中包含很多 <a href=http://hi.baidu.com/mianshiti/blog/category/微軟面試題> 微軟面試題 </a> "
p.search(content).groups()

這段程式碼對於給出的例子是足夠了,但實際情況中還需要考慮連結地址兩邊的單引號或者雙引號,href的大小寫,情況會稍微複雜些。

另外,如果面試者對正則表示式完全沒有概念,可以和麵試官申請換一道題,一般不會有太大影響。

參考資料:
http://wiki.ubuntu.org.cn/Python正則表示式操作指南

30、從輸入URL到顯示網頁,後臺發生了什麼?

作為一個軟體開發者,你一定會對網路應用如何工作有一個完整的層次化的認知,同樣這裡也包括這些應用所用到的技術:像瀏覽器,HTTP,HTML,網路伺服器,需求處理等等。

本文將更深入的研究當你輸入一個網址的時候,後臺到底發生了一件件什麼樣的事~

1. 首先嘛,你得在瀏覽器裡輸入要網址:

image

2. 瀏覽器查詢域名的IP地址

image

導航的第一步是通過訪問的域名找出其IP地址。DNS查詢過程如下:

  • 瀏覽器快取 – 瀏覽器會快取DNS記錄一段時間。 有趣的是,作業系統沒有告訴瀏覽器儲存DNS記錄的時間,這樣不同瀏覽器會儲存個自固定的一個時間(2分鐘到30分鐘不等)。
  • 系統快取 – 如果在瀏覽器快取裡沒有找到需要的記錄,瀏覽器會做一個系統呼叫(windows裡是gethostbyname)。這樣便可獲得系統快取中的記錄。
  • 路由器快取 – 接著,前面的查詢請求發向路由器,它一般會有自己的DNS快取。
  • ISP DNS 快取 – 接下來要check的就是ISP快取DNS的伺服器。在這一般都能找到相應的快取記錄。
  • 遞迴搜尋 – 你的ISP的DNS伺服器從跟域名伺服器開始進行遞迴搜尋,從.com頂級域名伺服器到Facebook的域名伺服器。一般DNS伺服器的快取中會有.com域名伺服器中的域名,所以到頂級伺服器的匹配過程不是那麼必要了。

DNS遞迴查詢如下圖所示:

500px-An_example_of_theoretical_DNS_recursion_svg

DNS有一點令人擔憂,這就是像wikipedia.org 或者 facebook.com這樣的整個域名看上去只是對應一個單獨的IP地址。還好,有幾種方法可以消除這個瓶頸:

  • 迴圈 DNS 是DNS查詢時返回多個IP時的解決方案。舉例來說,Facebook.com實際上就對應了四個IP地址。
  • 負載平衡器 是以一個特定IP地址進行偵聽並將網路請求轉發到叢集伺服器上的硬體裝置。 一些大型的站點一般都會使用這種昂貴的高效能負載平衡器。
  • 地理 DNS 根據使用者所處的地理位置,通過把域名對映到多個不同的IP地址提高可擴充套件性。這樣不同的伺服器不能夠更新同步狀態,但對映靜態內容的話非常好。
  • Anycast 是一個IP地址對映多個物理主機的路由技術。 美中不足,Anycast與TCP協議適應的不是很好,所以很少應用在那些方案中。

大多數DNS伺服器使用Anycast來獲得高效低延遲的DNS查詢。

3. 瀏覽器給web伺服器傳送一個HTTP請求

image

因為像Facebook主頁這樣的動態頁面,開啟後在瀏覽器快取中很快甚至馬上就會過期,毫無疑問他們不能從中讀取。

所以,瀏覽器將把一下請求傳送到Facebook所在的伺服器:

GET http://facebook.com/ HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, [...]
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; [...]
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: facebook.com
Cookie: datr=1265876274-[...]; locale=en_US; lsd=WW[...]; c_user=2101[...]

GET 這個請求定義了要讀取的URL: “http://facebook.com/”。 瀏覽器自身定義 (User-Agent 頭), 和它希望接受什麼型別的相應 (Accept and Accept-Encoding 頭). Connection頭要求伺服器為了後邊的請求不要關閉TCP連線。

請求中也包含瀏覽器儲存的該域名的cookies。可能你已經知道,在不同頁面請求當中,cookies是與跟蹤一個網站狀態相匹配的鍵值。這樣cookies會儲存登入使用者名稱,伺服器分配的密碼和一些使用者設定等。Cookies會以文字文件形式儲存在客戶機裡,每次請求時傳送給伺服器。

用來看原始HTTP請求及其相應的工具很多。作者比較喜歡使用fiddler,當然也有像FireBug這樣其他的工具。這些軟體在網站優化時會幫上很大忙。

除了獲取請求,還有一種是傳送請求,它常在提交表單用到。傳送請求通過URL傳遞其引數(e.g.: http://robozzle.com/puzzle.aspx?id=85)。傳送請求在請求正文頭之後傳送其引數。

像“http://facebook.com/”中的斜槓是至關重要的。這種情況下,瀏覽器能安全的新增斜槓。而像“http: //example.com/folderOrFile”這樣的地址,因為瀏覽器不清楚folderOrFile到底是資料夾還是檔案,所以不能自動新增 斜槓。這時,瀏覽器就不加斜槓直接訪問地址,伺服器會響應一個重定向,結果造成一次不必要的握手。 

4. facebook服務的永久重定向響應

image

圖中所示為Facebook伺服器發回給瀏覽器的響應:

HTTP/1.1 301 Moved Permanently
Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0,
pre-check=0
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Location: http://www.facebook.com/
P3P: CP="DSP LAW"
Pragma: no-cache
Set-Cookie: made_write_conn=deleted; expires=Thu, 12-Feb-2009 05:09:50 GMT;
path=/; domain=.facebook.com; httponly
Content-Type: text/html; charset=utf-8
X-Cnection: close
Date: Fri, 12 Feb 2010 05:09:51 GMT
Content-Length: 0

伺服器給瀏覽器響應一個301永久重定向響應,這樣瀏覽器就會訪問“http://www.facebook.com/” 而非“http://facebook.com/”。

為什麼伺服器一定要重定向而不是直接發會使用者想看的網頁內容呢?這個問題有好多有意思的答案。

其中一個原因跟搜尋引擎排名有 關。你看,如果一個頁面有兩個地址,就像http://www.igoro.com/ 和http://igoro.com/,搜尋引擎會認為它們是兩個網站,結果造成每一個的搜尋連結都減少從而降低排名。而搜尋引擎知道301永久重定向是 什麼意思,這樣就會把訪問帶www的和不帶www的地址歸到同一個網站排名下。

還有一個是用不同的地址會造成快取友好性變差。當一個頁面有好幾個名字時,它可能會在快取裡出現好幾次。

5. 瀏覽器跟蹤重定向地址

image

現在,瀏覽器知道了“http://www.facebook.com/”才是要訪問的正確地址,所以它會發送另一個獲取請求:

GET http://www.facebook.com/ HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, [...]
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; [...]
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Cookie: lsd=XW[...]; c_user=21[...]; x-referer=[...]
Host: www.facebook.com

頭資訊以之前請求中的意義相同。

6. 伺服器“處理”請求

image

伺服器接收到獲取請求,然後處理並返回一個響應。

這表面上看起來是一個順向的任務,但其實這中間發生了很多有意思的東西- 就像作者部落格這樣簡單的網站,何況像facebook那樣訪問量大的網站呢!

  • Web 伺服器軟體
    web伺服器軟體(像IIS和阿帕奇)接收到HTTP請求,然後確定執行什麼請求處理來處理它。請求處理就是一個能夠讀懂請求並且能生成HTML來進行響應的程式(像ASP.NET,PHP,RUBY...)。

    舉 個最簡單的例子,需求處理可以以對映網站地址結構的檔案層次儲存。像http://example.com/folder1/page1.aspx這個地 址會對映/httpdocs/folder1/page1.aspx這個檔案。web伺服器軟體可以設定成為地址人工的對應請求處理,這樣 page1.aspx的釋出地址就可以是http://example.com/folder1/page1。

  • 請求處理
    請求處理閱讀請求及它的引數和cookies。它會讀取也可能更新一些資料,並講資料儲存在伺服器上。然後,需求處理會生成一個HTML響應。

所 有動態網站都面臨一個有意思的難點 -如何儲存資料。小網站一半都會有一個SQL資料庫來儲存資料,儲存大量資料和/或訪問量大的網站不得不找一些辦法把資料庫分配到多臺機器上。解決方案 有:sharding (基於主鍵值講資料表分散到多個數據庫中),複製,利用弱語義一致性的簡化資料庫。

委 託工作給批處理是一個廉價保持資料更新的技術。舉例來講,Fackbook得及時更新新聞feed,但資料支援下的“你可能認識的人”功能只需要每晚更新 (作者猜測是這樣的,改功能如何完善不得而知)。批處理作業更新會導致一些不太重要的資料陳舊,但能使資料更新耕作更快更簡潔。

7. 伺服器發回一個HTML響應

image

圖中為伺服器生成並返回的響應:

HTTP/1.1 200 OK
Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0,
pre-check=0
Expires: Sat, 01 Jan 2000 00:00:00 GMT
P3P: CP="DSP LAW"
Pragma: no-cache
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
X-Cnection: close
Transfer-Encoding: chunked
Date: Fri, 12 Feb 2010 09:05:55 GMT

[email protected][...]

整個響應大小為35kB,其中大部分在整理後以blob型別傳輸。

內容編碼頭告訴瀏覽器整個響應體用gzip演算法進行壓縮。解壓blob塊後,你可以看到如下期望的HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"    
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
lang="en" id="facebook" class=" no_js">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-language" content="en" />
...

關於壓縮,頭資訊說明了是否快取這個頁面,如果快取的話如何去做,有什麼cookies要去設定(前面這個響應裡沒有這點)和隱私資訊等等。

請注意報頭中把Content-type設定為“text/html”。報頭讓瀏覽器將該響應內容以HTML形式呈現,而不是以檔案形式下載它。瀏覽器會根據報頭資訊決定如何解釋該響應,不過同時也會考慮像URL擴充套件內容等其他因素。

8. 瀏覽器開始顯示HTML

在瀏覽器沒有完整接受全部HTML文件時,它就已經開始顯示這個頁面了:

image

9. 瀏覽器傳送獲取嵌入在HTML中的物件

image

在瀏覽器顯示HTML時,它會注意到需要獲取其他地址內容的標籤。這時,瀏覽器會發送一個獲取請求來重新獲得這些檔案。

下面是幾個我們訪問facebook.com時需要重獲取的幾個URL:

  • 圖片
    http://static.ak.fbcdn.net/rsrc.php/z12E0/hash/8q2anwu7.gif
    http://static.ak.fbcdn.net/rsrc.php/zBS5C/hash/7hwy7at6.gif
  • CSS 式樣表
    http://static.ak.fbcdn.net/rsrc.php/z448Z/hash/2plh8s4n.css
    http://static.ak.fbcdn.net/rsrc.php/zANE1/hash/cvtutcee.css
  • JavaScript 檔案
    http://static.ak.fbcdn.net/rsrc.php/zEMOA/hash/c8yzb6ub.js
    http://static.ak.fbcdn.net/rsrc.php/z6R9L/hash/cq2lgbs8.js

這些地址都要經歷一個和HTML讀取類似的過程。所以瀏覽器會在DNS中查詢這些域名,傳送請求,重定向等等...

但 不像動態頁面那樣,靜態檔案會允許瀏覽器對其進行快取。有的檔案可能會不需要與伺服器通訊,而從快取中直接讀取。伺服器的響應中包含了靜態檔案儲存的期限 資訊,所以瀏覽器知道要把它們快取多長時間。還有,每個響應都可能包含像版本號一樣工作的ETag頭(被請求變數的實體值),如果瀏覽器觀察到檔案的版本 ETag資訊已經存在,就馬上停止這個檔案的傳輸。

試著猜猜看“fbcdn.net”在地址中代表什麼?聰明的答案是"Facebook內容分發網路"。Facebook利用內容分發網路(CDN)分發像圖片,CSS表和JavaScript檔案這些靜態檔案。所以,這些檔案會在全球很多CDN的資料中心中留下備份。

靜態內容往往代表站點的頻寬大小,也能通過CDN輕鬆的複製。通常網站會使用第三方的CDN。例如,Facebook的靜態檔案由最大的CDN提供商Akamai來託管。

舉例來講,當你試著ping static.ak.fbcdn.net的時候,可能會從某個akamai.net伺服器上獲得響應。有意思的是,當你同樣再ping一次的時候,響應的伺服器可能就不一樣,這說明幕後的負載平衡開始起作用了。

10. 瀏覽器傳送非同步(AJAX)請求

image

在Web 2.0偉大精神的指引下,頁面顯示完成後客戶端仍與伺服器端保持著聯絡。

以 Facebook聊天功能為例,它會持續與伺服器保持聯絡來及時更新你那些亮亮灰灰的好友狀態。為了更新這些頭像亮著的好友狀態,在瀏覽器中執行的 JavaScript程式碼會給伺服器傳送非同步請求。這個非同步請求傳送給特定的地址,它是一個按照程式構造的獲取或傳送請求。還是在Facebook這個例 子中,客戶端傳送給http://www.facebook.com/ajax/chat/buddy_list.php一個釋出請求來獲取你好友裡哪個 線上的狀態資訊。

提起這個模式,就必須要講講"AJAX"-- “非同步JavaScript 和 XML”,雖然伺服器為什麼用XML格式來進行響應也沒有個一清二白的原因。再舉個例子吧,對於非同步請求,Facebook會返回一些JavaScript的程式碼片段。

除了其他,fiddler這個工具能夠讓你看到瀏覽器傳送的非同步請求。事實上,你不僅可以被動的做為這些請求的看客,還能主動出擊修改和重新發送它們。AJAX請求這麼容易被蒙,可著實讓那些計分的線上遊戲開發者們鬱悶的了。(當然,可別那樣騙人家~)

Facebook聊天功能提供了關於AJAX一個有意思的問題案例:把資料從伺服器端推送到客戶端。因為HTTP是一個請求-響應協議,所以聊天伺服器不能把新訊息發給客戶。取而代之的是客戶端不得不隔幾秒就輪詢下伺服器端看自己有沒有新訊息。

這些情況發生時長輪詢是個減輕伺服器負載挺有趣的技術。如果當被輪詢時伺服器沒有新訊息,它就不理這個客戶端。而當尚未超時的情況下收到了該客戶的新訊息,伺服器就會找到未完成的請求,把新訊息做為響應返回給客戶端。

http://igoro.com/archive/what-really-happens-when-you-navigate-to-a-url/ 

31、給定能隨機生成整數1到5的函式,寫出能隨機生成整數1到7的函式。

產生K個數(k>1) 假定產生的數分別為n1,n2,n3,n4...
那麼定義產生的數為n1-1+(n2-2)*5+(n3-1)*5^2+(n4-1)*5^3........
於是產生的數位於區間(0,5^k-1)
然後把5^k分成k等分,產生的數位於哪個等分就是那個產生的隨機數(0~6),然後+1即可
如果位於k等分的餘數範圍,則重新執行一次上述過程
不用擔心餘數問題,當k取3時落到餘數範圍的概率就已經降低為6/125
32、程式設計實現兩個正整數的除法,當然不能用除法操作符。
// return x/y.
int div(const int x, const int y) {
....
}

// return x/y

int div(const int x, const int y) {
int left_num = x;
int result = 0;
while (left_num >= y) {
int multi = 1;
while (y * multi <= (left_num >> 1)) {
multi = multi << 1;
}
result += multi;
left_num -= y * multi;
}
return result;
}

擴充套件問題:
如果需要測試上面這個函式,需要哪些測試用例?

33、微軟面試題:利用天平砝碼,三次將140克的鹽 分成50、90克兩份?有一個天平,2克和7克砝碼各一個。如何利用天平砝碼在三次內將140克鹽分成50,90克兩份。

第一種方法:
第一次:先稱 7+2克鹽 (相當於有三個法碼2,7,9)
第二次:稱2+7+9=18克鹽 (相當於有2,7,9,18四個法碼)
第三次:稱7+18=x+2,得出x是23,23+9+18=50克鹽.
剩下就是90克了.

第二種方法:
1.先把140克鹽分為兩份,每份70克
2.在把70克分為兩份,每份35克
3.然後把兩個砝碼放在天平兩邊,把35克麵粉分成兩份也放在兩邊(15+7=20+2)
現在有四堆麵粉70,35,15,20,分別組合得到
70+20=90
35+15=50

34、微軟面試題:地球上有多少個滿足這樣條件的點
站在地球上的某一點,向南走一公里,然後向東走一公里,最後向北走一公里,回到了原點。地球上有多少個滿足這樣條件的點?

北極點滿足這個條件。
距離南極點很近的一個圈上也滿足這個條件。在這個圓圈上,向南走一公里,然後向東走一公里恰好繞南極點一圈,向北走一公里回到原點。所以地球上總共有無數點滿足這個條件。事實上距離南極弧長滿足1+1/(2*k*pi)維度上的點都滿足

35、谷歌面試題:如何隨機選取1000個關鍵字;給定一個數據流,其中包含無窮盡的搜尋關鍵字(比如,人們在谷歌搜尋時不斷輸入的關鍵字)。如何才能從這個無窮盡的流中隨機的選取1000個關鍵字?

定義長度為1000的陣列。
對於資料流中的前1000個關鍵字,顯然都要放到陣列中。
對於資料流中的的第n(n>1000)個關鍵字,我們知道這個關鍵字被隨機選中的概率為 1000/n。所以我們以 1000/n 的概率用這個關鍵字去替換陣列中的隨機一個。這樣就可以保證所有關鍵字都以 1000/n的概率被選中。
對於後面的關鍵字都進行這樣的處理,這樣我們就可以保證陣列中總是儲存著1000個隨機關鍵字。

#include <iostream>
#include <time.h>
using namespace std;
#define MAX_SIZE 10
static void resample(int data, int *sample_list, int n)
{
int idx;
if(n<MAX_SIZE)
sample_list[n]=data;
else
{
srand(time(NULL));
idx=rand()%n;
if(idx<MAX_SIZE)
{
sample_list[idx]=data;

}
}
}
int main()
{
int sample_list[MAX_SIZE];
int count=0,num;
cin>>num;
while(num!=0)
{
resample(num, sample_list,count);
count++;
cin>>num;
}
for(int i=0;i<MAX_SIZE;i++)
cout<<sample_list[i]<<endl;
system("pause");
return 0;
}

36、谷歌面試題:判斷一個自然數是否是某個數的平方;判斷一個自然數是否是某個數的平方。當然不能使用開方運算。

方法1:
遍歷從1到N的數字,求取平方並和N進行比較。
如果平方小於N,則繼續遍歷;如果等於N,則成功退出;如果大於N,則失敗退出。
複雜度為O(n^0.5)。

方法2:
使用二分查詢法,對1到N之間的數字進行判斷。
複雜度為O(log n)。

方法3:
由於
(n+1)^2
=n^2 + 2n + 1,
= ...
= 1 + (2*1 + 1) + (2*2 + 1) + ... + (2*n + 1)
注意到這些項構成了等差數列(每項之間相差2)。
所以我們可以比較 N-1, N - 1 - 3, N - 1 - 3 - 5 ... 和0的關係。
如果大於0,則繼續減;如果等於0,則成功退出;如果小於 0,則失敗退出。
複雜度為O(n^0.5)。不過方法3中利用加減法替換掉了方法1中的乘法,所以速度會更快些。

37、微軟面試題:正確標註水果籃
有三個水果籃。其中一個裡面只有蘋果,一個裡面只有橘子,另外一個既有蘋果又有橘子。每個水果籃上都有標籤,但標籤都是錯的。如何檢查某個水果籃中的一個水果,然後正確標註每個水果籃?

從標註成既有蘋果也有橘子的水果籃中選取一個進行檢查。
如果是橘子,則此籃中只有橘子;標有橘子的水果籃中只有蘋果;標有蘋果的水果籃中既有蘋果也有橘子。
如果是蘋果,則此籃中只有蘋果;標有蘋果的水果籃中只有橘子;標有橘子的水果籃中既有蘋果也有橘子。

38、IBM面試題:為什麼小和尚會在同一時間出現在同一地點
有一座山,山上有座廟,只有一條路可以從山上的廟到山腳,每週一早上8點,有一個聰明的小和尚去山下化緣,週二早上8點從山腳回山上的廟裡,小和尚的上下山的速度是任意的,在每個往返中,他總是能在週一和週二的同一鐘點到達山路上的同一點。例如,有一次他發現星期一的8點30和星期二的8點30他都到了山路靠山腳的3/4的地方,問這是為什麼?

可以用畫圖法來解釋:
在一個平面上,x 軸代表從8點開始的時間,y 軸代表距廟的距離。那麼從廟到山腳就是一條從左下到右上的一條曲線,從山腳到廟就是一條從左上到右下的一條曲線。考慮到兩條曲線的起始點和終點,兩線必定交於一點。

39、微軟面試題:不利用浮點運算,畫一個圓
不利用浮點運算,在螢幕上畫一個圓 (x**2 + y**2 = r**2,其中 r 為正整數)。

考慮到圓的對稱性,我們只需考慮第一象限即可。
等價於找到一條連線點(0,r)到點(r,0)的一條曲線,曲線上的點距圓心(0,0)的距離最接近 r。
我們可以從點(0,r)開始,搜尋右(1,r),下(0,r-1),右下(1,r-1)三個點到圓心的距離,選擇距圓心距離最接近 r 的點作為下一個點。反覆進行這種運算,直至到達點(r,0)。
由於不能利用浮點運算,所以距離的比較只能在距離平方的基礎上進行。也就是比較 x**2 + y**2 和 r**2之間的差值。

40、微軟面試題:快速求取一個整數的7倍
給出一種快速求一個整數7倍的方法。

乘法相對比較慢,所以快速的方法就是將這個乘法轉換成加減法和移位操作。
可以將此整數先左移三位(×8)然後再減去原值:X << 3 - X。

41、微軟面試題:三隻螞蟻不相撞的概率是多少
在三角形的三個頂點上各有一隻螞蟻,它們向另一個頂點運動,目標隨機(可能為另外兩個頂點的任意一個)。問三隻螞蟻不相撞的概率是多少?
如果螞蟻順時針爬行記為0,逆時針爬行記為1。那麼三隻螞蟻的狀態可能為000,001,...,110,111中的任意一個,且為每種狀態的概率相等。在這8種狀態中,只有000和111可以避免相撞,所以螞蟻不相撞的概率是1/4。

題目的一些擴充套件:
1. 如果將三角形變成正方形,並且有四隻螞蟻,那麼不相撞的概率是多少?
2. 如果將正方形的對角線相連,螞蟻也可以在對角線上爬行,那麼不相撞的概率是多少?(假設對角線相交處有立交橋)

方法1.
對陣列進行排序(快速,堆),然後比較相鄰的元素是否相同。
時間複雜度為O(nlogn),空間複雜度為O(1)。
42、判斷陣列中是否包含重複數字
給定一個長度為N的陣列,其中每個元素的取值範圍都是1到N。判斷陣列中是否有重複的數字。(原陣列不必保留)
方法2.
使用bitmap方法。
定義長度為N/8的char陣列,每個bit表示對應數字是否出現過。遍歷陣列,使用 bitmap對數字是否出現進行統計。
時間複雜度為O(n),空間複雜度為O(n)。

方法3.
遍歷陣列,假設第 i 個位置的數字為 j ,則通過交換將 j 換到下標為 j 的位置上。直到所有數字都出現在自己對應的下標處,或發生了衝突。
時間複雜度為O(n),空間複雜度為O(1)。

43、谷歌面試題:在半徑為1的圓中隨機選取一點
在半徑為1的圓中隨機選取一點。

假設圓心所在位置為座標元點(0, 0)。

方法1.
在x軸[-1, 1],y軸[-1, 1]的正方形內隨機選取一點。然後判斷此點是否在圓內(通過計算此點到圓心的距離)。如果在圓內,則此點即為所求;如果不在,則重新選取直到找到為止。
正方形的面積為4,圓的面積為pi,所以正方形內的隨機點在圓內的概率是 pi / 4。

方法2.
從[0, 2*pi)中隨機選一個角度,對應於圓中的一條半徑,然後在此半徑上選一個點。但半徑上的點不能均勻選取,選取的概率應該和距圓心的長度成正比,這樣才能保證隨機點在圓內是均勻分佈的。

44、谷歌面試題:給定一個未知長度的整數流,如何隨機選取一個數
給定一個未知長度的整數流,如何隨機選取一個數?

方法1.
將整個整數流儲存到一個數組中,然後再隨機選取。
如果整數流很長,無法儲存下來,則此方法不能使用。

方法2.
如果整數流在第一個數後結束,則我們必定會選第一個數作為隨機數。
如果整數流在第二個數後結束,我們選第二個數的概率為1/2。我們以1/2的概率用第2個數替換前面選的隨機數,得到滿足條件的新隨機數。
....
如果整數流在第n個數後結束,我們選第n個數的概率為1/n。我們以1/n的概率用第n個數替換前面選的隨機數,得到滿足條件的新隨機數。
....
利用這種方法,我們只需儲存一個隨機數,和迄今整數流的長度即可。所以可以處理任意長的整數流。

45、谷歌面試題:設計方便提取中數的資料結構
設計一個數據結構,其中包含兩個函式,1.插入一個數字,2.獲得中數。並估計時間複雜度。

1. 使用陣列儲存。
插入數字時,在O(1)時間內將該數字插入到陣列最後。
獲取中數時,在O(n)時間內找到中數。(選陣列的第一個數和其它數比較,並根據比較結果的大小分成兩組,那麼我們可以確定中數在哪組中。然後對那一組按照同樣的方法進一步細分,直到找到中數。)

2. 使用排序陣列儲存。
插入數字時,在O(logn)時間內找到要插入的位置,在O(n)時間裡移動元素並將新數字插入到合適的位置。
獲得中數時,在O(1)複雜度內找到中數。

3. 使用大根堆和小根堆儲存。
使用大根堆儲存較小的一半數字,使用小根堆儲存較大的一半數字。
插入數字時,在O(logn)時間內將該數字插入到對應的堆當中,並適當移動根節點以保持兩個堆數字相等(或相差1)。
獲取中數時,在O(1)時間內找到中數。

46、谷歌面試題:在一個特殊陣列中進行查詢
給定一個固定長度的陣列,將遞增整數序列寫入這個陣列。當寫到陣列尾部時,返回陣列開始重新寫,並覆蓋先前寫過的數。
請在這個特殊陣列中找出給定的整數。

假設陣列為a[0, 1, ..., N-1]。
我們可以採用類似二分查詢的策略。
首先比較a[0]和a[N/2],如果a[0] < a[N/2],則說明a[0,1,...,N/2]為遞增子序列,否則另一部分是遞增子序列。
然後判斷要找的整數是否在遞增子序列範圍內。如果在,則使用普通的二分查詢方法繼續查詢;如果不在,則重複上面的查詢過程,直到找到或者失敗為止。

47、谷歌面試題:給定一個排序陣列,如何構造一個二叉排序樹?
給定一個排序陣列,如何構造一個二叉排序樹?

採用遞迴演算法。
選取陣列中間的一個元素作為根節點,左邊的元素構造左子樹,右邊的節點構造有子樹。

48、雅虎面試題:HTTP中Get和Post的區別
解釋HTTP中Get和Post。它們有什麼區別,哪個使用時更加安全?

Get和Post都是瀏覽器向網頁伺服器提交資料的方法。

Get把要提交的資料編碼在url中,比如 http://hi.baidu.com/mianshiti?key1=value1&key2=value2 中就編碼了鍵值對 key1,value1 和key2,value2。受限於url的長度限制,Get方法能傳輸的資料有限(不同瀏覽器對url長度限制不同,比如微軟IE設為2048)。
Post把要提交的資料放在請求的body中,而不會顯示在url中,因此,也沒有資料大小的限制。

由於Get把資料編碼在URL中,所以這些變數顯示在瀏覽器的位址列,也會被記錄在伺服器端的日誌中。所以Post方法更加安全。

49、雅虎面試題:燈炮能亮的概率是多少?
一個開關接一個燈炮,開關一年內壞掉的概率為10%,燈炮一年內壞掉的概率為20%,問一年後開啟開關,燈炮能亮的概率是多少?(假定其他裝置都不損壞)
開關好的概率是90%,燈泡好的概率是80%,
所以兩個都好的概率是90%*80%=72%。

50、華為面試題:IP,TCP和UDP協議的定義和主要作用
IP,TCP和UDP協議的定義和主要作用?

IP協議是網路層的協議。IP協議規定每個網際網路網上的電腦都有一個唯一的IP地址,這樣資料包就可以通過路由器的轉發到達指定的電腦。但IP協議並不保證資料傳輸的可靠性。
TCP協議是傳輸層的協議。它向下遮蔽了IP協議不能可靠傳輸的缺點,向上提供面向連線的可靠的資料傳輸。
UDP協議也是傳輸層的協議。它提供無連線的不可靠傳輸。

51、華為面試題:全域性變數和區域性變數有什麼區別?
全域性變數和區域性變數有什麼區別?怎麼實現的?作業系統和編譯器是怎麼知道的?

全域性變數是整個程式都可訪問的變數,生存期從程式開始到程式結束;區域性變數存在於模組中(比如某個函式),只有在模組中才可以訪問,生存期從模組開始到模組結束。
全域性變數分配在全域性資料段,在程式開始執行的時候被載入。區域性變數則分配在程式的堆疊中。因此,作業系統和編譯器可以通過記憶體分配的位置來知道來區分全域性變數和區域性變數。

52、華為面試題:6個整數,每個數中都包含'6',和為100可能嗎?
6個整數,每個數中都包含'6'(在個位或十位上),6個數的和為100可能嗎?

可能,這六個數的取值為:60,16,6,6,6,6

首先,6不可能都在個位數上出現,否則6個數的和個位也是會是6。
其次,最多有一個數在十位上出現6,否則6個數的和會大於100。
這六個數為 6?,?6,?6,?6,?6,?6。不考慮?部分,總和等於90。所以最終的結果60,16,6,6,6,6。

53、完美時空面試題:memcpy 和 memmove 有什麼區別?

memcpy和memmove都是將源地址的若干個字元拷貝到目標地址。
如果源地址和目標地址有重疊,則memcpy不能保證拷貝正確,但memmove可以保證拷貝正確。

例如:
char src[20];
// set src
char* dst = src + 5;
此時如果要從src拷貝10個字元到dst,則麼memcpy不能保證拷貝正確,但是memmove可以保證。

54、騰訊面試題:const的含義及實現機制

const用來說明所定義的變數是隻讀的。