百度内容质量部测试开发面试题
目錄
Chap1 測試基礎(chǔ) 2
Chap2 測試設(shè)計 4
Chap3 算法 12
Chap4 設(shè)計題 19
Chap5 邏輯題 21
Chap6編程及代碼題 26
Chap7 計算機(jī)基礎(chǔ) 38
1. C/C++ 38
2. JAVA 39
3. 多線程: 40
4. 網(wǎng)絡(luò)編程 41
5. Linux: 43
Chap 8 項目和背景 47
Chap9 外部工具 48
1. Selenium 48
2. Ruby-Watir 49
3. QTP: 50
4. LoadRunner 51
?
Chap1 測試基礎(chǔ)
附件1的19-21頁是一個模擬的面試場景,其中有不少經(jīng)典題型和問題。不過已經(jīng)在網(wǎng)上廣為流傳,建議了解其中面試思路為主,題目不要照搬太多。
答:白盒測試:邏輯覆蓋法,主要包括語句覆蓋,判斷覆蓋,條件覆蓋,判斷條件覆蓋,條件組合覆蓋、路徑覆蓋。
黑盒測試:等價劃分類,邊界值分析,錯誤推測法等
答:靜態(tài)方法是指不運(yùn)行被測程序本身,僅通過分析或檢查源程序的語法、結(jié)構(gòu)、過程、接口等來檢查程序的正確性。對需求規(guī)格說明書、軟件設(shè)計說明書、源程序做結(jié)構(gòu)分析、流程圖分析、符號執(zhí)行來找錯。靜態(tài)方法通過程序靜態(tài)特性的分析,找出欠缺和可疑之處,例如不匹配的參數(shù)、不適當(dāng)?shù)难h(huán)嵌套和分支嵌套、不允許的遞歸、未使用過的變量、空指針的引用和可疑的計算等。靜態(tài)測試結(jié)果可用于進(jìn)一步的查錯,并為測試用例選取提供指導(dǎo)。
動態(tài)方法是指通過運(yùn)行被測程序,檢查運(yùn)行結(jié)果與預(yù)期結(jié)果的差異,并分析運(yùn)行效率和健壯性等性能,這種方法由三部分組成:構(gòu)造測試實例、執(zhí)行程序、分析程序的輸出結(jié)果。所謂軟件的動態(tài)測試,就是通過運(yùn)行軟件來檢驗軟件的動態(tài)行為和運(yùn)行結(jié)果的正確性。目前,動態(tài)測試也是公司的測試工作的主要方式。根據(jù)動態(tài)測試在軟件開發(fā)過程中所處的階段和作用,動態(tài)測試可分為如下幾個步驟:1、單元測試 2、集成測試 3、系統(tǒng)測試 4、驗收測試 5、回歸測試。
答:等價類分為以下幾類:
- 有效等價類和無效等價類
- 有效等價類就是對程序的規(guī)格說明有意義的,合理的輸入數(shù)據(jù)所構(gòu)成的集合,利用有效等價類可驗證程序是否實現(xiàn)了規(guī)格說明中的功能和性能。
- 無效等價類是那些對程序的規(guī)格說明不合理或者無意義的數(shù)據(jù)所構(gòu)成的,為了驗證程序做其不應(yīng)作的事情。
答:優(yōu)點:考慮了單個數(shù)據(jù)域的各類情況,避免盲目或隨機(jī)的選取輸入數(shù)據(jù)的不完整性和不穩(wěn)定性,同時可有效控制測試設(shè)計的數(shù)量。
缺點:對組合情況考慮不足,同時等價類劃分基于等價類中的輸入都能產(chǎn)生相同的效果,在很多情況下用例選擇不當(dāng)會產(chǎn)生問題(如邊界)。
答:長期的測試工作經(jīng)驗告訴我們,大量的錯誤是發(fā)生在輸入或輸出范圍的邊界上,而不是發(fā)生在輸入輸出范圍的內(nèi)部。因此針對各種邊界情況設(shè)計測試用例,可以查出更多的錯誤。
不過邊界值分析法與等價類劃分法一樣,沒有考慮輸入之間的組合情況,因此需要進(jìn)一步結(jié)合其他測試用例設(shè)計方法。
答:等價類劃分的原則如下:
- 在輸入條件規(guī)定了取值范圍或值的個數(shù)的情況下,則可以確立一個有效等價類和兩個無效等價類.
- 在輸入條件規(guī)定了輸入值的集合或者規(guī)定了“必須如何”的條件的情況下,可確立一個有效等價類和一個無效等價類.
- 在輸入條件是一個布爾量的情況下,可確定一個有效等價類和一個無效等價類.
- 在規(guī)定了輸入數(shù)據(jù)的一組值(假定n個),并且程序要對每一個輸入值分別處理的情況下,可確立n個有效等價類和一個無效等價類.
- 在規(guī)定了輸入數(shù)據(jù)必須遵守的規(guī)則的情況下,可確立一個有效等價類(符合規(guī)則)和若干個無效等價類(從不同角度違反規(guī)則).
- 在確知已劃分的等價類中各元素在程序處理中的方式不同的情況下,則應(yīng)再將該等價類進(jìn)一步的劃分為更小的等價類.
答: 基本點:并發(fā)度、響應(yīng)時間、單位時間吞吐量、系統(tǒng)穩(wěn)定性、多場景。
加分點:新舊版本對比,性能瓶頸分析方法(雪崩、線性拐點等)。
答:從以下幾個角度分析,包括:無新發(fā)生bug且嚴(yán)重性高的老bug已修復(fù);bug收斂;某一級別bug低于一定比例;時間耗盡;滿足特定覆蓋率。另外,可以說說在以前的項目測試是如何結(jié)束的。
答:常見的軟件測試模型包括V模型、W模型、H模型、X模型和前置模型。([注]:具體解釋太長了,見附件1的前幾頁。)
Chap2 測試設(shè)計
題目:一個程序需要根據(jù)配置文件,將本地的多個文件(model.0, model.1, model.2…)分發(fā)到不同機(jī)房的不同機(jī)器上去。其中,配置文件格式如下:
#機(jī)房數(shù)量
SITE_NUM : 5
#第0個機(jī)房機(jī)器數(shù)量
SITE_0_HOST_NUM : 10
#該機(jī)房第n個機(jī)器的ip
SITE_0_HOST_0 : 192.168.0.1
SITE_0_HOST_1 : 192.168.0.2
。。。
SITE_0_HOST_9 : 192.168.0.10
?
SITE_1_HOST_NUM : 10
SITE_1_HOST_0 : 192.168.1.1
SITE_1_HOST_1 : 192.168.1.2
。。。
?
#文件數(shù)量
MODEL_NUM : 5
#第n個文件在第m個機(jī)房需要的備份數(shù)
MODEL_0_REP_NUM : 0 : 3, 1 : 3,2:3, 3:3:4:3
MODEL_1_REP_NUM : 0 : 3, 1 : 3,2:3, 3:3:4:3
MODEL_2_REP_NUM : 0 : 3, 1 : 3,2:3, 3:3:4:3
MODEL_3_REP_NUM : 0 : 3, 1 : 3,2:3, 3:3:4:3
MODEL_4_REP_NUM : 0 : 3, 1 : 3,2:3, 3:3:4:3
?
分發(fā)要求:一臺機(jī)器上不能布置多份相同的文件
每臺機(jī)器上要求分發(fā)的文件數(shù)量盡量均勻
問題:請設(shè)計測試用例。
答:各種邊界值;不同機(jī)器的IP重復(fù);在某機(jī)房的需要的備份數(shù)超過了機(jī)器數(shù);
答:冒煙測試:速度裝一杯水,是否漏水
功能測試:漏水測試,透明度測試,衛(wèi)生情況測試,杯口平滑測試,重量測試,均勻度測試
壓力測試:抗摔測試,抗高溫測試
歡迎添加
答:基本情況;邊界值;魯棒性;性能以及其算法優(yōu)化;
題目: 設(shè)有一個檔案管理系統(tǒng),要求用戶輸入以年月表示的日期。假設(shè)日期限定在1990年1月~2049年12月,并規(guī)定日期由6位數(shù)字字符組成,前4位表示年,后2位表示月。
問題:現(xiàn)用等價類劃分法設(shè)計測試用例,來測試程序的"日期檢查功能"。
答:
- 劃分等價類并編號,下表等價類劃分的結(jié)果
| 輸入等價類 | 有效等價類 | 無效等價類 |
| 日期的類型及長度 | 6位數(shù)字字符 | 有非數(shù)字字符 |
| ? | ? | 少于6位數(shù)字字符 |
| ? | ? | 多于6位數(shù)字字符 |
| 年份范圍 | 在1990~2049之間 | 小于1990 |
| ? | ? | 大于2049 |
| 月份范圍 | 在01~12之間 | 等于00 |
| ? | ? | 大于12 |
- 設(shè)計測試用例,以便覆蓋所有的有效等價類在表中列出了3個有效等價類,編號分別為①、⑤、⑧,設(shè)計的測試用例如下:
測試數(shù)據(jù) ???期望結(jié)果 ?????覆蓋的有效等價類
200211 ?????輸入有效 ?????①、⑤、⑧
為每一個無效等價類設(shè)計一個測試用例,設(shè)計結(jié)果如下:
測試數(shù)據(jù) ??期望結(jié)果 ????覆蓋的無效等價類
95June ????無效輸入 ?????????②
20036 ?????無效輸入 ?????????③
2001006 ???無效輸入 ?????????④
198912 ????無效輸入 ?????????⑥
200401 ????無效輸入 ?????????⑦
200100 ????無效輸入 ?????????⑨
200113 ????無效輸入 ?????????⑩
答:主要從異常、功能和性能三方面考慮:
- 異常
參數(shù)異常:源和目標(biāo)參數(shù)異常:包含特殊字符;參數(shù)超長;指定的位置實際不存在
拷貝對象異常:非法的執(zhí)行權(quán)限;存儲介質(zhì)有損壞;非法的文件格式和內(nèi)容
執(zhí)行過程異常:拷貝到一半斷電;拷貝過程中硬盤滿;拷貝過程中源或目的被刪除
- 功能
- 文件
不同文件大小:0,1k,10k。。。
不同的文件類型:文本,二進(jìn)制,設(shè)備文件。。。
- 目錄
包含各種文件類型
包含子目錄,目錄深度
目錄文件數(shù)量很多
針對文件和目錄分別驗證拷貝的準(zhǔn)確性,完整性。
- 性能
- 場景:
拷貝大文件
拷貝目錄中存在大量小文件
跨文件系統(tǒng)間拷貝
跨存儲介質(zhì)間拷貝(硬盤到U盤。。。)
構(gòu)造源的各種磁盤分布(磁盤扇區(qū)分布。。。)
并發(fā)執(zhí)行拷貝
- 關(guān)注的性能點:拷貝時間, CPU,內(nèi)存,磁盤IO
題目:百度首頁是由模板展現(xiàn),請問如何對它進(jìn)行測試;
要求:不需要考慮性能相關(guān)因素。建議多從用戶行為和使用環(huán)境角度進(jìn)行測試
(考察點:測試能力+思維系統(tǒng)性+思維發(fā)散性)
答:
展現(xiàn)檢查:文字圖片內(nèi)容,鏈接,一致性
數(shù)據(jù)傳遞:字符串長短與截斷;特殊字符;中英文;空格;下拉條提示
兼容性檢查:不同瀏覽器,不同操作系統(tǒng),不同分辨率
用戶行為:窗口拉大,放小;字號大小;編碼格式;刷新;前進(jìn)后退
題目:本流程圖描述了某子程序的處理流程,現(xiàn)要求用白盒測試法對子程序進(jìn)行測試。
要求:根據(jù)白盒測試常用的以下幾種方式:語句覆蓋、判定覆蓋、條件覆蓋、判定/條件覆蓋、多重條件覆蓋(條件組合覆蓋)、路徑覆蓋六種覆蓋標(biāo)準(zhǔn),從供選擇的答案中分別找出滿足相應(yīng)覆蓋標(biāo)準(zhǔn)的最小的測試數(shù)據(jù)組并簡述各種測試方法。
?
?
供選擇的答案
x=3 y=3 z=0;x=1 y=2 z=1
x=1 y=2 z=0;x=2 y=1 z=1
x=4 y=2 z=0; x=3 y=3 z=0; x=2 y=1 z=0; x=1 y=1 z=1
x=4 y=2 z=0; x=1 y=2 z=1; x=2 y=1 z=0; x=1 y=1 z=1
x=4 y=2 z=0
x=4 y=2 z=0;x=1 y=1 z=1
參考答案:
- 語句覆蓋E:語句覆蓋是指選擇足夠的測試用例,使得運(yùn)行這些測試用例時,被測程序的每個語句至少被執(zhí)行一次,語句覆蓋是一種比較弱的覆蓋標(biāo)準(zhǔn)
- 判定覆蓋A:也稱分支覆蓋,是指選擇足夠的測試用例,使得運(yùn)行這些測試用例時,被測程序的每個判定的所有可能結(jié)果至少出現(xiàn)一次
- 條件覆蓋B:是指選擇足夠的測試用例,使得運(yùn)行這些測試用例時,判定中的每個條件的所有可能結(jié)果至少出現(xiàn)一次
- 判定/條件覆蓋F:是指選擇足夠的測試用例,使得運(yùn)行這些測試用例時,判定中每個條件的所有可能結(jié)果至出現(xiàn)一次,并且每個判定本身的所有可能結(jié)果也至少出現(xiàn)一次
- 多重條件覆蓋D:是指選擇足夠的測試用例,使得運(yùn)行這些測試用例時,每個判定中條件結(jié)果的所有可能組合至少出現(xiàn)一次
- 路徑覆蓋C:是指選擇足夠的測試用例,使得運(yùn)行這些測試用例時,程序的每條可能執(zhí)行到的路徑都至少經(jīng)過一次
問題:請給出BAIDU hi聊天消息收發(fā)的測試思路?(10分鐘)
(考察點:基本測試思路)
參考答案:主要從以下幾個方面來考察:正常測試、異常測試、不同的消息類型、組合測試、長度極值、是否延遲、是否丟失、是否被篡改、安全性
?
參考答案:希望可以對測試點做分類劃分,如功能、UI、性能、安全
題目:?測試自動販賣機(jī),場景:販賣機(jī)將用在露天的繁華的大街上
(考察點:?主要考察邏輯思維、思維的發(fā)散性)
參考答案:?
大概可以從以下幾個方面來考慮:
- 考慮到管理員的功能:如添加貨物功能、定價等功能
- 考慮到界面外觀、用戶說明的
- 容錯考慮比較多的
題目:一個程序,從輸入框中讀取三個整數(shù)值,這三個數(shù)值代表了三角形三邊的長度。程序顯示提示信息,指出該三角形究竟是不規(guī)則三角形、等腰三角形還是等邊三角形。(注:不規(guī)則三角形指三角形中任意兩邊不相等,等腰三角形指有兩條邊相等,等邊三角形指三條邊相等)
要求:假設(shè)你將作為一名測試工程師對該程序進(jìn)行測試,你會采用什么方法進(jìn)行測試用例設(shè)計?請寫出你采用的方法、測試用例設(shè)計的過程以及最后的測試用例。(30分鐘)
(考查點:考察測試思維的嚴(yán)謹(jǐn)性,答全難)
參考答案:可以采用等價類劃分的方法進(jìn)行測試用例的設(shè)計。
- 等價類表:
| 輸入條件 | 有效等價類 | 無效等價類 |
| 是否三角形的三條邊 | ⑴A>0 | ⑺A<=0 |
| ⑵B>0 | ⑻B<=0 | |
| ⑶C>0 | ⑼C<=0 | |
| ⑷A+B>C | ⑽A+B<=C | |
| ⑸B+C>A | ⑾B+C<=A | |
| ⑹A+C>B | ⑿A+C<=B | |
| 是否等腰三角形 | ⒀A=B | ⒃A!=B&&B!=C&&C!=A |
| ⒁B=C | ||
| ⒂C=A | ||
| 是否等邊三角形 | ⒄A=B&&B=C&&C=A | ⒅A!=B |
| ⒆B!=C | ||
| ⒇C!=A |
-
- 測試用例:
序號
[A,B,C]
覆蓋等價類
輸出
1
[3,4,5]
⑴⑵⑶⑷⑸⑹
一般三角形
2
[0,1,2]
⑺
不能構(gòu)成三角形
3
[1,0,2]
⑻
4
[1,2,0]
⑼
5
[1,2,3]
⑽
6
[1,3,2]
⑾
7
[3,1,2]
⑿
8
[3,3,4]
⑴⑵⑶⑷⑸⑹⒀
等腰三角形
9
[3,4,4]
⑴⑵⑶⑷⑸⑹⒁
10
[3,4,3]
⑴⑵⑶⑷⑸⑹⒂
11
[3,4,5]
⑴⑵⑶⑷⑸⑹⒃
非等腰三角形
12
[3,3,3]
⑴⑵⑶⑷⑸⑹⒄
等邊三角形
13
[3,4,4]
⑴⑵⑶⑷⑸⑹⒁⒅
非等邊三角形
14
[3,4,3]
⑴⑵⑶⑷⑸⑹⒂⒆
15
[3,3,4]
⑶⑷⑸⑹⒀⒇
?
- 較復(fù)雜功能程序設(shè)計用例(30分鐘)
- 請列舉的常用排序算法,并說明其時間復(fù)雜度,并說明排序思想。
- 冒泡排序:兩兩比較待排序數(shù)據(jù)元素的大小,發(fā)現(xiàn)兩個數(shù)據(jù)元素的次序相反時即進(jìn)行交換,直到?jīng)]有反序的數(shù)據(jù)元素為止。算法時間復(fù)雜度是O(n^2)。
- 選擇排序:每一趟從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個元素,順序放在已排好序的數(shù)列的最后,直到全部待排序的數(shù)據(jù)元素排完,算法復(fù)雜度是O(n^2)。
- 插入排序:每次將一個待排序的數(shù)據(jù)元素,插入到前面已經(jīng)排好序的數(shù)列中的適當(dāng)位置,使數(shù)列依然有序;直到待排序數(shù)據(jù)元素全部插入完為止。算法時間復(fù)雜度是O(n^2)
- 快速排序:在當(dāng)前無序區(qū)R[1..H]中任取一個數(shù)據(jù)元素作為比較的"基準(zhǔn)"(不妨記為X),用此基準(zhǔn)將當(dāng)前無序區(qū)劃分為左右兩個較小的無序區(qū):R[1..I-1]和R[I+1..H],且左邊的無序子區(qū)中數(shù)據(jù)元素均小于等于基準(zhǔn)元素,右邊的無序子區(qū)中數(shù)據(jù)元素均大于等于基準(zhǔn)元素,而基準(zhǔn)X則位于最終排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),當(dāng)R[1..I-1]和R[I+1..H]均非空時,分別對它們進(jìn)行上述的劃分過程,直至所有無序子區(qū)中的數(shù)據(jù)元素均已排序為止。不穩(wěn)定,最理想情況算法時間復(fù)雜度O(nlog2n),最壞O(n^2)。
- 堆排序:堆排序是一樹形選擇排序,在排序過程中,將R[1..N]看成是一顆完全二叉樹的順序存儲結(jié)構(gòu),利用完全二叉樹中雙親結(jié)點和孩子結(jié)點之間的內(nèi)在關(guān)系來選擇最小的元素。算法時間復(fù)雜度O(nlogn)。
- 希爾排序:其實就是用步長控制的插入排序,希爾排序通過加大插入排序中元素之間的間隔,并在這些有間隔的元素中進(jìn)行插入排序,從而讓數(shù)據(jù)項可以大幅度移動,這樣的方式可以使每次移動之后的數(shù)據(jù)離他們在最終序列中的位置相差不大,保證數(shù)據(jù)的基本有序,大大提升了排序速度,運(yùn)算時間復(fù)雜度N*logN。
- 歸并排序:
- 快速排序的平均時間復(fù)雜度是多少?最壞時間復(fù)雜度是多少?在哪些情況下會遇到最壞的時間復(fù)雜度。
- 各個排序算法的穩(wěn)定性,并給出理由。
- 兩個單項鏈表求交點。
- 遞增數(shù)列中每一項都可以表示為3^i*5^j*7^k(0<=i,j,k),即1,3,5,7,9,15,21,25,27…,實現(xiàn)算法,求出該數(shù)列中的第n項
- 為二叉樹中每一個節(jié)點建立他的右鄰居節(jié)點(可以不屬于同一個父節(jié)點),要求遞歸與非遞歸都實現(xiàn),如
- 遞歸:
- 非遞歸
- 走臺階問題,一次可以走1,2,3級,都N級臺階的方法數(shù)。
- 10進(jìn)制數(shù)轉(zhuǎn)2進(jìn)制數(shù),
- 一個環(huán)狀鏈表(收尾相連),兩個指針head1和head2從同一個節(jié)點出發(fā),head1每次走一步,head2每次走兩步,請證明,兩個指針第一次相遇于出發(fā)的節(jié)點
- 一個鏈表中含有環(huán)。請找出環(huán)的起始節(jié)點
- 給定N個數(shù),其中有一個數(shù)的出現(xiàn)次數(shù)超過N/2,請找出這個數(shù),O(n)算法
- 最長連續(xù)子序列之和(和最接近0的子序列),環(huán)形數(shù)組的最大子序列和。
- 字符串按字母a-z排序
- 已知一個亂序的整數(shù)數(shù)組,求該數(shù)組排序相鄰兩數(shù)的最大間隔,要求時間復(fù)雜度為O(n)。
- 求兩個相同大小已排序數(shù)組的中位數(shù)
- 已知一個數(shù)組a1, a2, ..., an, b1, b2, ..., bn,設(shè)計一個算法把數(shù)組變成a1, b1, a2, b2, ..., an, bn。
- 全排序算法
- 多線程鎖機(jī)制設(shè)計
- 設(shè)計Spider
- 海量url除重(spilt&merge的思想,主要看候選人的思路,2面)
- 給定一個file,包含各類url,統(tǒng)計出現(xiàn)次數(shù)topN的url
- 多路數(shù)組交集
- 兄弟單詞索引
- 死鏈監(jiān)測設(shè)計
- 用戶經(jīng)常會輸錯query,如何糾錯
- 一天,harlan的店里來了一位顧客,挑了25元的貨,顧客拿出100元,harlan沒零錢找不開,就到隔壁飛白的店里把這100元換成零錢,回來給 顧客找了75元零錢。過一會,飛白來找harlan,說剛才的是假錢,harlan馬上給飛白換了張真錢,問harlan賠了多少錢(低)?
- 列出每筆交易的收入和支出,給分
- 答出結(jié)果,陪100元,給分
- 直接從結(jié)果出發(fā),如果沒有假錢,不賺不虧,給分
- 由于收入100假錢,賠100,給分
- 以5只貓5分鐘捉5只老鼠的速度計算,要在100分鐘內(nèi)捉100只老鼠,需要多少只貓(低)
- 算出每只貓每分鐘的捉鼠能力,給分
- 算出答案,給分
- 把5只貓看為整體,整體每分鐘的捉鼠能力,給分
- 算出答案,給分
- 一副撲克牌54張,紅黑各一半,從里面任意翻兩張,一紅一黑的可能性是多少(低)
- 一只手表100元買進(jìn),110元賣出;120元又買進(jìn),130元再賣出,問共賺了多少錢(低)
- 有一牧場,已知養(yǎng)牛27頭,6天把草吃盡;養(yǎng)牛23頭,9天把草吃盡。如果養(yǎng)牛21頭,那么幾天能把牧場上的草吃盡呢?并且牧場上的草是不斷生長的(中)
- 4個人進(jìn)入餐廳前都把自己的帽子交給寄存部的小姐保存。當(dāng)他們一起離開時粗心的小姐把那4頂帽子隨便的戴在每個人的頭上。發(fā)完帽子以后大家發(fā)現(xiàn)沒有一個人 戴的是自己的帽子。請問這種情況發(fā)生的概率是多少?如果是n個人呢(n>1)?(中)
- 甲、乙、丙每人出兩元共六元買了一個收音機(jī),然后就一起離開了商店,和他們一起去的丁因有事沒有離開,這時售貨員發(fā)現(xiàn)收音機(jī)的售價應(yīng)該是五元,就把那一元 錢退給了丁,丁回去時坐車花了4角,然后把剩下的6角分給了甲、乙、丙三人各2角,這時算帳甲、乙、丙每人花了1.8元,加上丁坐車花的4角,是5.8元,那剩下的兩角錢哪兒去了(中)
- 長8高2的矩形中,填入后兩種圖形,一共有幾種填法(中)
- 村子里有50個人,每人有一條狗。在這50條狗中有病狗(這種病不會傳染)。于是人們就要找出病狗。每個人可以觀察其他的49條狗,以判斷它們是否生病, 只有自己的狗不能看。觀察后得到的結(jié)果不得交流,也不能通知病狗的主人。主人一旦推算出自己家的是病狗就要槍斃自己的狗,而且每個人只有權(quán)利槍斃自己的 狗,沒有權(quán)利打死其他人的狗。第一天,第二天都沒有槍響。到了第三天傳來一陣槍聲,問有幾條病狗,如何推算得出(中)
- 有5只猴子在海邊發(fā)現(xiàn)一堆桃子,決定第二天來平分。第二天清晨,第一只猴子最早來到,它左分右分分不開,就朝海里扔了一只,恰好可以分成5份,它拿上自己 的一份走了。第2,3,4,5只猴子也遇到同樣的問題,采用了同樣的方法,都是扔掉一只后,恰好可以分成5份。問這堆桃子至少有多少只
- 有三個人都不能說話,但都很聰明。他們每人戴一頂帽子,帽子不是黑色就是紅色。這三人都苦思苦想,希望知道自己帽子的顏色,但終始終無法得知。有一天,一個外地人見到這三人,隨口說了一句話:“你們?nèi)酥辽儆幸粋€是戴著紅帽子。”說完就走了。當(dāng)天三人聽完這句話,都紛紛回家苦思。第二 天中午,三人依舊一起在廣場見面,有兩人當(dāng)即宣布了自己帽子的顏色。隨后,第三個人也知道了自己帽子的顏色。請問:這三人的帽子分別為什么顏色
- A,B兩人射箭,命中率都是50%。兩人比賽射箭,各射50箭,射中靶子多的人獲勝。比賽中A耍賴,多射了1箭,問A有多大的可能性獲勝。
- 假設(shè)一個國家沒有離婚、死亡等情況出現(xiàn)。該國國王規(guī)定:一對夫妻的第一胎是男孩時候,不允許再生育;第一胎是女孩時候,夫妻可以選擇生第二胎,也可以不生;第二胎是女孩子的時候,還可以繼續(xù)生。但是一旦生育了一個男孩,那么就嚴(yán)禁再生育。當(dāng)這個政策運(yùn)行足夠久之后,該國的男女孩子的比例是多少?
- Strcpy函數(shù)的實現(xiàn)。(校招)
- Bigint乘法實現(xiàn)(bigint用數(shù)組存儲每一個位)?社招
- 實現(xiàn)char *strtok(char *s, const char *delim);
- struct { int a, char b, long c} 的sizeof結(jié)果是多少,32位機(jī)器和64位機(jī)器下
- int a = (int)(char)(byte)-1; a的值為? ?(位數(shù)補(bǔ)齊)
- aoti()的實現(xiàn):
- 不使用庫函數(shù),實現(xiàn)int atoi(char *s)函數(shù);
- 在此基礎(chǔ)上,實現(xiàn)自定義的atoi()升級版,要求:
- int atoi(char *s, unsigned int base)中,2<=base<=16,s是以進(jìn)制為base表示形式的字符串,比如:base=8時,”123”表示數(shù)字83。
- 對以上代碼進(jìn)行測試。
- 寫代碼能力,異常處理是否全面。
- 主要考慮點:
- NULL指針輸入;
- atoi()在檢測到錯誤時,無法return合適的值來表示這個錯誤;
- 輸入字符串前綴的合法性檢查,
- 字符串中的字符是否在當(dāng)前進(jìn)制能表示的范圍內(nèi),例如:字符’F’不在進(jìn)制為15的數(shù)字表示范圍內(nèi)。
- int atoi(char *s){
- result = 10 * result + ( *s - '0' );?替換為:result = base * result + (*s–?‘0’)即可
- strstr()的實現(xiàn);
- 給出單向鏈表的定義,并實現(xiàn)如下操作:
- add():在head增加一個節(jié)點;
- delete():刪除指定的節(jié)點
- retrieve():對所有節(jié)點進(jìn)行“指定的函數(shù)操作”,“指定的函數(shù)操作”由用戶輸入;
- 單向鏈表的定義;
- 功能代碼的實現(xiàn);函數(shù)指針的運(yùn)用(retrieve()中)。
- 請找出下面代碼中的所有錯誤
- 兩路歸并
- 以下代碼會是什么效果?
- 下列三個函數(shù)有沒有問題,如果有請指出:
- 說明以下函數(shù)所實現(xiàn)的功能以及可能存在的問題:
- 以下程序的輸出是怎樣的?請給出分析過程。
- 解釋以下代碼中函數(shù)function()的執(zhí)行過程,指出可能存在的問題:
- myclass c1=100; 調(diào)用constructor myclass(unsigned int k),其中伴隨automatic type conversion;為c1.content指針分配了內(nèi)存。
- myclass c2=c1; 調(diào)用默認(rèn)的copy constructor,采用member-wize的copy,導(dǎo)致c2的content指針指向c1. Content指向的區(qū)域;
- myclass c3; 這里需要調(diào)用default constructor,但是由于自己定義了其他類型的constructor,編譯器不會在自動幫助生成default constructor,編譯不通過;
- c4=c1; 調(diào)用copy assignment operator,實施member-wize的copy,導(dǎo)致c4的content指針也指向c1. Content指向的區(qū)域;構(gòu)造函數(shù)為c4分配的內(nèi)存成為孤立區(qū)域,導(dǎo)致內(nèi)存泄露。
- 函數(shù)退出,噩夢開始:不考慮c3的話,這里共調(diào)用constructor myclass(unsigned int k)兩次,但是卻要調(diào)用destructor三次。由于指針淺copy,三次destructor會對同一塊內(nèi)存free三次,這是個問題。
- 解釋以下代碼中函數(shù)function()的執(zhí)行過程,指出可能存在的問題:
- 請寫出以下程序的運(yùn)行結(jié)果,并解釋導(dǎo)致這樣運(yùn)行結(jié)果的關(guān)鍵性原因。
- C/C++[標(biāo)記]
- Inline函數(shù)、虛函數(shù)的概念;虛函數(shù)是否可以實現(xiàn)成inline
- 函數(shù)調(diào)用過程中,函數(shù)參數(shù)的入棧順序,why?
- extern的使用場合以及工作原理
- C++中?struct和class的區(qū)別
- OO語言中動態(tài)綁定的概念。參考答案網(wǎng)上都有考察精通c++/java的面試者對基本概念的了解
- C++中多態(tài)的概念及實現(xiàn)機(jī)制(答題點:虛函數(shù),虛表)
- JAVA
- 繼承和實現(xiàn)的區(qū)別。當(dāng)一個類已經(jīng)繼承了其他類,就不能繼承Thread,只能實現(xiàn)runnable。
- 每個JAVA對象都有一把所,當(dāng)有多個線程同時訪問共享資源的時候,需要Synchronize 來控制安全性,synchronize分synchronize 方法和synchronize塊,使用synchronize塊時, 一定要顯示的獲得該對象的鎖(如synchronize(object))而方法則不需要
- 在java多線程編程中,最被經(jīng)常用到的便是wait與notfiy方法,這兩個方法可以用來更加精確地控制被同步的代碼,從而使得被同步的代碼最小化,提高并發(fā)效率。當(dāng)某個類的某個方法被標(biāo)記為synchronized時,這個方法在同一時間只能被一個線程訪問。此時這個方法中的所有代碼都是被同步的,只有當(dāng)一個線程執(zhí)行完所有的代碼之后,下一個線程才能開始執(zhí)行。當(dāng)被同步的方法代碼量比較小,而且每一步執(zhí)行都非??斓臅r候僅僅使用synchronized關(guān)鍵字就夠了。
- 多線程:
- 管道(Pipe)及有名管道(named pipe):管道可用于具有親緣關(guān)系進(jìn)程間的通信,有名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關(guān)系進(jìn)程間的通信;
- 信號(Signal):信號是比較復(fù)雜的通信方式,用于通知接受進(jìn)程有某種事件發(fā)生,除了用于進(jìn)程間通信外,進(jìn)程還可以發(fā)送信號給進(jìn)程本身;Linux除了支持Unix早期信號語義函數(shù)sigal外,還支持語義符合Posix.1標(biāo)準(zhǔn)的信號函數(shù)sigaction(實際上,該函數(shù)是基于 BSD的,BSD為了實現(xiàn)可靠信號機(jī)制,又能夠統(tǒng)一對外接口,用sigaction函數(shù)重新實現(xiàn)了signal函數(shù));
- 報文(Message)隊列(消息隊列):消息隊列是消息的鏈接表,包括Posix消息隊列systemV消息隊列。有足夠權(quán)限的進(jìn)程可以向隊列中添加消息,被賦予讀權(quán)限的進(jìn)程則可以讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點。
- 共享內(nèi)存:使得多個進(jìn)程可以訪問同一塊內(nèi)存空間,是最快的可用IPC形式。是針對其他通信機(jī)制運(yùn)行效率較低而設(shè)計的。往往與其它通信機(jī)制,如信號量結(jié)合使用,來達(dá)到進(jìn)程間的同步及互斥。
- 信號量(semaphore):主要作為進(jìn)程間以及同一進(jìn)程不同線程之間的同步手段。
- 套接口(Socket):更為一般的進(jìn)程間通信機(jī)制,可用于不同機(jī)器之間的進(jìn)程間通信。起初是由Unix系統(tǒng)的BSD分支開發(fā)出來的,但現(xiàn)在一般可以移植到其它類Unix系統(tǒng)上:Linux和System V的變種都支持套接字。
- 網(wǎng)絡(luò)編程
- Linux
- cookie和session的概念;兩者的實現(xiàn)方式;兩者的應(yīng)用場景
- cookie機(jī)制和session機(jī)制的區(qū)別
- Cookies與Session的應(yīng)用場景:
- Selenium
- Ruby-Watir
- QTP:
- LoadRunner
程序從標(biāo)準(zhǔn)輸入中讀取,判斷輸入字符是固定電話號碼或者手機(jī)號碼
???????? a) 手機(jī)號碼:以13開頭,長度為11的連續(xù)數(shù)字
???????? b) 固定電話號碼:固定電話號碼包括區(qū)號和號碼兩部分,其中號碼為長度為7或8,并且不以0開頭的連續(xù)數(shù)字。區(qū)號可有可不有。區(qū)號和號碼間可有“-”,也可以沒有。
?????????c) 當(dāng)用戶輸入完畢后,系統(tǒng)返回的答案包括: 手機(jī)號碼 固定號碼 無正確電話號碼
?????????d) 一次輸入中如果有多個正確號碼(空格為分割符),以最后一個正確號碼的類型為準(zhǔn)
對實現(xiàn)上述功能的程序設(shè)計測試用例。(40分鐘)
區(qū)號范圍(x表示任意數(shù)字):
| 3位區(qū)號 | 4位區(qū)號 |
| 10 | 03×× |
| 20 | 04×× |
| 21 | 05×× |
| 22 | 06×× |
| 23 | 07×× |
| 24 | 08×× |
| 25 | 09×× |
| 27 | ? |
| 28 | ? |
| 29 | ? |
參考答案:?以下是測試設(shè)計的參考思路:
| 有空格 | 空格在兩頭 | 中間有正確電話號碼 |
| ? | ? | ||
| 中間無正確電話號碼 |
| ? | ? | ||||
| 中間無字符 | ? | ? | |||||
| 空格在中間 | 一個空格 | 最后一個為錯誤手機(jī)號 | ? | ? | |||
| 全部為錯誤手機(jī)號 | ? | ? | |||||
| 最后一個為正確手機(jī)號 | ? | ? | |||||
| 多個空格 | 最后一個為正確手機(jī)號 | ? | ? | ||||
| 第一個為正確手機(jī)號 | ? | ? | |||||
| 全部為錯誤手機(jī)號 | ? | ? | |||||
| 超長字符含空格 | ? | ? | |||||
| 無空格 | 只含數(shù)字 | 以0開頭 | 前三位是區(qū)號 | 區(qū)號識別 | |||
| 前三位非區(qū)號 | 前四位為區(qū)號 | 區(qū)號識別 | |||||
| 前四位非區(qū)號 |
| ||||||
| 非0開頭 | 13開頭 | 長度為11 | |||||
| 長度非11 | 座機(jī)號碼 | ||||||
| 非座機(jī)號碼 | |||||||
| 非13開頭 | 座機(jī)號碼識別 | ||||||
| 含數(shù)字和- | 一個- | -前是區(qū)號 | -后為座機(jī) | ||||
| -后非座機(jī) | |||||||
| -前非區(qū)號 | -后為座機(jī) | ||||||
| 多個- | |||||||
| 含其他字符 | |||||||
| 超長字符不含空格 | |||||||
| 空輸入 | |||||||
| ? | ? | ? | ? | ? | ? | ||
| 座機(jī)識別 | ? | ? | ? | ? | ? | ||
| 首位為0 | 長度為6 | 所有數(shù)字均能被識別?? | ? | ? | |||
| 長度為7 | ? | ? | ? | ? | |||
| 長度為5 | ? | ? | ? | ? | |||
| 長度為8 | ? | ? | ? | ? | |||
| 首位非0 | ? | ? | ? | ? | |||
| ? ? ? ? | ? | ? | ? | ? | ? | ||
| 區(qū)號識別 | ? | ? | ? | ? | ? | ||
| 三位長度 | 010開頭 | ? | ? | ? | |||
| 02開頭 | 026開頭 | ? | ? | ? | |||
| 非026 | ? | ? | ? | ||||
| 非010、02開頭 | 011開頭 | ? | ? | ? | |||
| 030開頭 | ? | ? | ? | ||||
| 四位長度 | 03-09開頭 | ? | ? | ? | |||
| 01 | ? | ? | ? | ||||
| 02 | ? | ? | ? | ||||
Chap3 算法
答:
Divide: 把長度為n的輸入序列分成兩個長度為n/2的子序列。
Conquer: 對這兩個子序列分別采用歸并排序。
Combine: 將兩個排序好的子序列合并成一個最終的排序序列。
時間復(fù)雜度是O(nlog2n)。
答:
快速排序的平均時間復(fù)雜度O(nlog2n),最壞時間復(fù)雜度O(n^2)。
最壞情況:當(dāng)每次pivot選擇恰好都把列表元素分成了(1,n-1)
采取措施:pivot的選取是通過random來進(jìn)行
答:
選擇排序、快速排序、希爾排序、堆排序不是穩(wěn)定的排序算法,而冒泡排序、插入排序、歸并排序和基數(shù)排序是穩(wěn)定的排序算法。
參考:http://hi.baidu.com/cuifenghui/blog/item/0587932b039557f9e7cd4051.html
單向鏈表有交點意思是交點后的節(jié)點都是一樣的;因此,如果兩個單向鏈表相交,是成Y字形的。
思路:求出第一個鏈表長m,第二個長n。假設(shè)m>=n,那么就去掉第一個鏈表的前m-n個元素,使之等長,然后依次比較第一個、第二個、第三個元素,直到找到或者結(jié)束。
| NODE* FindNode(NODE* pHead1, NODE* pHead2) { ????NODE* p1 = pHead1; ????NODE* p2 = pHead2; ????int i = 1, j = 1, k = 0, f = 0; ????if(pHead2 == NULL || pHead2 == NULL) ????{ ????????return NULL; ????} ????while(p1->next != NULL) ????{ ????????p1 = p1->next; ????????i++; ????} ????while(p2->next != NULL) ????{ ????????p2 = p2->next; ????????j++; ????} ????if(p1 != p2) ????{ ????????return NULL; ???????//如果尾節(jié)點不同,直接返回 NULL ????} ????else ??????????????????//否則尋找第一個相同的節(jié)點 ????{ ????????p1 = pHead1; ???????????????// 1 ????????p2 = pHead2; ???????????????// 2 ????????f = fabs(i, j); ??//計算兩條鏈表長度的差 ????????if(i > j) ????????//如果第一個鏈表比第二個長,第一個鏈表先向前移動f步 ????????{ ????????????for(k=0; k<f; k++) ????????????{ ???????????????p1 = p1->next; ????????????} ????????????while(p1 != p2) ????????????{ ????????????????p1 = p1->next; ????????????????p2 = p2->next; ????????????} ????????????return p1; ????????} ????????else ????????{ ????????????for(k=0; k<f; k++) ????????????{ ????????????????p2 = p2->next; ????????????} ????????????while(p1 != p2) ????????????{ ????????????????p1 = p1->next; ????????????????p2 = p2->next; ????????????} ????????????return p1; ????????} ????} } |
?
答:
先放置幾個隊列:
L1: 3^i?(i >=0)
L2: 3^i * 5^j ?(j >= 1)
L3: 3^i * 5^j?* 7^k (k >= 1)
Step1: 清空三個隊列、分別把3,5,7放入三個隊列的首位。準(zhǔn)備一個新隊列L(目前為空)。
Step2: 比較三個隊列的頭,找出最小的那個。把這個元素從隊列出隊,并加到L的尾部。
Step3:
如果Step2中的元素是從L1中獲取的,假設(shè)是3^m,則在L1的尾部加入3^(m+1),L2的尾部加入3^m*5,L3的尾部加入3^m*7。
如果Step2中的元素是從L2中獲取的,假設(shè)是3^m * 5^n,則在L2的尾部加入3^m * 5^(n+1),L3的尾部加入3^m * 5^n *7。
如果Step3中的元素是從L3中獲取的,假設(shè)是3^m * 5^n * 7^p,則在L3的尾部加入3^m * 5^n * 7^(p+1)。
Step4: L的長度到達(dá)N了嗎?如果沒到達(dá),重復(fù)L2-L4。如果到達(dá),則進(jìn)行L5。
Step5: 取得L的末尾元素,即為所求。
??????????????? A
????????????? /?? \
????????? B??-----> C
????? ??/?????????? /? \
??? ??E-----> F?-> G
答:
| buildRightSibling(Linkedlist list) { ??Linkedlist nextlevel = new Linkedlist(); ??把list中的每個元素的子節(jié)點,放入nextlevel中。 ??//對list中每個元素,設(shè)置右鄰結(jié)點,指向list中的下一個元素 ??//這一步可以在鏈表中就實現(xiàn)掉。 ??If(nextlevel == null || nextlevel.length() ==0) ????Return; ??Else buildRightSibling(nextlevel); } //啟動函數(shù) buildRightSibling(new Linkedlist(root)); ? 層序遍歷每一層,對每一個元素都打上標(biāo)記。比如(1,1)代表第1層第1個元素。 所有元素都打上標(biāo)記以后,對每個元素(m,n)都尋找(m,n+1)元素 |
答:
初始:f(0) = 0; ?f(1) =1; ?f(2) = 1 + 1 = 2;
遞推公式:f(n) = f(n - 1) + f(n-2) + f(n - 3)
題目:2進(jìn)制除了0,1,還可以用2表示。例如:
1-> 1
2-> 10 or 02
3->11
4 ->100 or 020 or 012
問題:這樣一個十進(jìn)制數(shù)轉(zhuǎn)為二進(jìn)制數(shù),就不是唯一的了?,F(xiàn)求十進(jìn)制數(shù)N轉(zhuǎn)換為這種二進(jìn)制數(shù)的所有表示方法數(shù)。
答:
f(0)=1, f(1)=1, f(2)=2,
f(n) = f( (n-1)/2) 當(dāng)n為奇數(shù)
?????? = f(n/2)+f((n-2)/2 )當(dāng)n為偶數(shù)
答:
設(shè)兩個指針走的次數(shù)為x,使用簡單的數(shù)學(xué)公式即可證明。難度1面??疾旎镜臄?shù)學(xué) 知識。
設(shè)鏈表有m個元素,head1在第一次相遇時走了n步,c為head1和head2第一次相遇的節(jié)點距離出發(fā)節(jié)點的距離。
則: head1走過的路程為 c = n;
head2走過的路程為 c + k *m = 2n; (k為整數(shù))
因此,c = k*m,即c恰好是鏈表長度的整數(shù)倍,即兩個指針第一次相遇一定是在出發(fā)的節(jié)點。
答:
方法1: 使用標(biāo)記法,走過的節(jié)點標(biāo)記1。使用這種方法,需要時間/空間復(fù)雜度O(n)
方法2: 使用第6題的思路,設(shè)兩個指針走的次數(shù)為x即可得到,時間復(fù)雜度不變,但空間 復(fù)雜度為O(1)。難度1面,考察能否使用已經(jīng)掌握的知識(第一題)來求解。
讓兩個指針head1和head2從同一個節(jié)點出發(fā),head1每次走一步,head2每次走兩步,當(dāng)二者重合時,讓head2回到鏈表的頭部,以每次一步的步長走,當(dāng)head1和head2再次相遇時,就是環(huán)路的起始節(jié)點了。
(考察點:該數(shù)出現(xiàn)次數(shù)超過其他所有數(shù)出現(xiàn)次數(shù)總和,使用計數(shù)方式解答。難度:2面)
答:
解法1: 開一個新的列
比較第1,2個數(shù)字。如果相同,則放入新的列中 如果不同,則兩個都丟棄
然后比較第3,4個數(shù)字,5,6個數(shù)字
這個時候 新的列 最長為n/2 (實際上會遠(yuǎn)遠(yuǎn)更短)
然后對新的列 如法炮制 再次縮短一半
當(dāng)某個時刻 列的長度是1或者列突然消失時候 結(jié)束
長度為1 說明這個就是的。消失,說明不存在大于n/2的個數(shù)的數(shù)
解法2:
構(gòu)造一個hashtable,其中key是這個N個數(shù)的值,而value則是他們出現(xiàn)的次數(shù);
最后遍歷這個hashtable,找出最大的即可。[ZhaiYao: 這個方法應(yīng)該不好。不應(yīng)該使用hashtable]
答:
環(huán)形的拼成2n的數(shù)組后求解。
最長連續(xù)子序列之和:掃描數(shù)組,從左到右記錄當(dāng)前子序列的和ThisSum,若這個和不斷增加,那么最大子序列的和MaxSum也不斷增加(不斷更新MaxSum)。如果往前掃描中遇到負(fù)數(shù),那么當(dāng)前子序列的和將會減小。此時ThisSum 將會小于MaxSum,當(dāng)然MaxSum也就不更新。如果ThisSum降到0時,說明前面已經(jīng)掃描的那一段就可以拋棄了,這時將ThisSum置為0。然后,ThisSum將從后面開始將這個子段進(jìn)行分析,若有比當(dāng)前MaxSum大的子段,繼續(xù)更新MaxSum。這樣一趟掃描結(jié)果也就出來了。
和最接近0的子序列:【標(biāo)記】
環(huán)形數(shù)組的最大子序列之和:將環(huán)形數(shù)組首尾拼接成一個2n的線型數(shù)組(如環(huán)形數(shù)組 0 1 2, 可以拼接成 0 1 2 0 1 2),按1)的方法可以找到最大連續(xù)子序列之和
???????? 題目要求:
????????? (1)不是用排序庫函數(shù);
????????? (2)代碼實現(xiàn);
????????? (3)算法復(fù)雜度估算;
????????? (4)測試自己的代碼;
??????????(5)能否用另一種排序方式,比較優(yōu)缺點;(plus)
答:
| 1. char *sort(char *a){ ????????int i, j; ????????char tmp; ????????for( i = 0; a[i] != '\0'; i++){ ????????????????for( j = i + 1; a[j] != '\0'; j++){ ????????????????????????if(a[i] > a[j]){ ????????????????????????????????tmp = a[i]; ????????????????????????????????a[i] = a[j]; ????????????????????????????????a[j] = tmp; ????????????????????????} ????????????????} ????????} 2. 算法復(fù)雜度:輸入為一個n個字符的字符串,則復(fù)雜度為O() 3. 另一種排序算法:快排,復(fù)雜度O(nlgn) [ZHAIYAO:可不可以用另一種方式?開一個26長的數(shù)組,記錄每個字母出現(xiàn)的次數(shù)。然后根據(jù)這個記錄,重新打印(構(gòu)造)出來排序后的字符串] |
例如:給定數(shù)組為10 23 7 1 35 27 50 41
排序后的結(jié)果為:1 7 10 23 27 35 41 50
相鄰兩數(shù)的最大間隔為13(10-23)。
遍歷找到數(shù)列找到最大最小值(max,min),則所求的gap>=(max-min)/n,以(max-min)/n為步長建立k個桶,每個桶記錄落入桶內(nèi)的最大最小值,順序比較各個桶之間的最大gap。
答:
用基于桶排序的方式,具體如下:
先找到最小和最大,分別記為min和max,并設(shè)avg=(max-min)/n
按照avg的大小將[min,max]分配(N-1)個桶
將數(shù)組中的數(shù)存入桶中
然后按順序?qū)γ總€相鄰?fù)?#xff08;跳過沒有數(shù)的桶)進(jìn)行比較,如相鄰?fù)?#xff08;a, b)(c, d)的距離D=c-b
最終比較D的最大值,則為所求
題目:設(shè)a[0..n-1]和b[0..n-1]是兩個已經(jīng)排好序的數(shù)組,設(shè)計一個算法,找出a和b的2n個數(shù)的中位數(shù)。要求給出算法復(fù)雜度(O(lgn))。
答:
設(shè)a[0..n-1]的中位數(shù)是m1,b[0..n-1]的中位數(shù)為m2
如果m1=m2,則m1則為2n個數(shù)的中位數(shù)
如果m1>m2,則2n個數(shù)的中位數(shù)一定在a[0..2/n]和b[n/2..n],在求這兩個子數(shù)組的中位數(shù)
如果 m1<m2,則2n個數(shù)的中位數(shù)一定在a[n/2..n]和b[0..2/n],在求這兩個子數(shù)組的中位數(shù)
答:
如果 n = 2k, ? 則 C(k) =
如果 n = 2k+1, 則 C(k) =
ZhaiYao: 綜合考慮時間和空間。時間O(n)應(yīng)該沒辦法降低了,覺得空間可以達(dá)到是O(1)。但是沒想出來算法,【標(biāo)記】
全排序算法就是列舉一些字符的所有排列順序。
| void Perm(char list[], int k, int m) { //生成list [k:m ]的所有排列方式 int i; if (k == m) {//輸出一個排列方式 for (i = 0; i <= m; i++) putchar(list[i]); putchar('\n'); } else // list[k:m ]有多個排列方式 // 遞歸地產(chǎn)生這些排列方式 for (i=k; i <= m; i++) { Swap (&list[k], &list[i]); Perm (list, k+1, m); Swap (&list [k], &list [i]); } } |
Chap4 設(shè)計題[標(biāo)記]
在多線程編程中,對臨界資源,經(jīng)常需要lock(),unlock()這樣的操作,但是經(jīng)常在lock之后忘記unlock,造成多線程問題?,F(xiàn)在用C++類的思想實現(xiàn)一個scopelock類(校招)
例如:
{
lock()
……
unlock()
}
這種使用模式變成
{
Scopelock()
…
}
(在構(gòu)造函數(shù)和虛構(gòu)函數(shù)中實現(xiàn)lock和unlock)
題目:Spider抓取能力一天10w個url,互聯(lián)網(wǎng)每天新增1000w個url ?(社招)
這1000w個都是新增的url,spider怎么選取10w個進(jìn)行抓取,選優(yōu)的準(zhǔn)則
這1000w個有些是抓取過的,存在歷史抓取信息,spider怎么選取10w個進(jìn)行抓取,選優(yōu)的準(zhǔn)則。
答:
在獲取URL的時候按照一定數(shù)量分組,然后分別在每組用URL的sign作為key,用awk以key為標(biāo)來構(gòu)造數(shù)組;最后把每組過濾過的結(jié)果在merge起來過濾。
答: sort|uniq -c|sort -nr|head
題目:有十路數(shù)組,數(shù)組元素組成為:{int id, unsigned int weight},每路數(shù)組內(nèi)id、weight均為無序
?要求:如何求出這十路數(shù)組的交集(交集:id相同),并將交集內(nèi)的元素按照weight排序?給出思路和復(fù)雜度;如果原始的十路數(shù)組中的id均為有序的,又該如何做?給出思路和復(fù)雜度;
題目:dog和god這類字母出現(xiàn)的次數(shù)和種類都完全一樣的字符串稱為兄弟單詞,現(xiàn)在有海量的字符串,設(shè)計檢索系統(tǒng),支持查找用戶輸入字符串的所有兄弟單詞。
題目:互聯(lián)網(wǎng)上每天有大量的網(wǎng)頁成為死鏈,如何用最小的代價降低搜索引擎的死鏈率。
(考察其工程思維能力,包括相關(guān)死鏈反饋、用戶點擊檢查、利用插件數(shù)據(jù)、站點穩(wěn)定性等等)
參考答案:發(fā)散問題,常見輸入法錯誤、缺字多字編輯距離判斷,用戶session挖掘等等
Chap5 邏輯題
答:
方法A:
方法B:
答:5只貓
方法A:
方法B:
答:27/53
答:賺20元
答:12天
1. 列出2個已知方程和一個求解方程,給分
2. 算出答案,給分 假設(shè)牧場的草為1單位,每天生長x單位,每個牛每天吃y單位
27y*6-6x=1
23y*9-9x=1
解得:y=1/72, x=15/72 [得一半分]
21頭牛,就是1/(21y-x)=12天 [得滿分]
答:
【4人時候,答案是9/24。9種可能分別是2143,4123,3142,3412,4312,2413,4321,3421,2341)】
【n人時候,解法如下】
?
解法1:
n人時候,運(yùn)用容斥原理的高級形式求解?!鞠氲饺莩庠砭徒o出一半分?jǐn)?shù)】
?
lixin:這是全錯位排列問題http://baike.baidu.com/view/1926671.htm?fr=ala0_1
zhaiyao:本科的離散數(shù)學(xué)課程,本帽子題目是一個例題。我做助教的時候背熟了。。。
?
設(shè)人站成一排,第1個的帽子設(shè)為帽子1,第i的人的帽子設(shè)為帽子i。
?
設(shè)帽子i戴在人i的頭上(其他人無所謂)的情況數(shù)為Ai
?
那么很明顯有|Ai| =(n-1)! ;
i和j同時帶對(不考慮其他人對不對)情況是?|Ai ∩Aj| = (n-2)! ;
i和j,k同時帶對(不考慮其他人對不對)|Ai ∩Aj ∩Ak | = (n-3)!
?
問題問沒有一個人帶對帽子,問題的反面就是問“存在至少一個人戴對帽子”
?
“存在至少一個人戴對帽子”的情況數(shù)為:|A1∪A2∪...∪An|
根據(jù)容斥原理,
|A1∪A2∪...∪An| =(|A1|+|A2|+…+|An|) - ( | A1 ∩A2| + | A1 ∩A3| ?) + (| A1 ∩A2 ∩A3| + ) ?- …. ?(參見容斥原理)
= n*(n-1)! - C(n,2)*(n-2)! + C(n,3)*(n-3)! - ... + (-1)^(n-1)*C(n,n)*0!
=n!(1/1!-1/2!+...+(-1)^(n-1)*1/n!)
?
所以都帶錯的情況是:
n!? -? n!(1/1!-1/2! + ...+(-1)^(n-1)*1/n!)
= n! *(1 - 1/1!+1/2!+...+(-1)^n* 1/n!)
?
概率是1 - 1/1!+1/2!-...+(-1)^(n-1)*1/n!
?= 1/2!-...+(-1)^(n-1)*1/n! 【得到答案得到全部分?jǐn)?shù)】
?
?
形象點就是:
2個人: 1/2!
3個人:1/2! – 1/3!
4個人: 1/2! – 1/3! + 1/4! ??(不是4/24,而是9/24。)
5個人: 1/2! – 1/3! + 1/4! – 1/5!
6個人: 1/2! – 1/3! + 1/4! – 1/5! + ?1/6!
?
。。。
解法2:
人肉寫出n=2,3,4的情況。然后進(jìn)行數(shù)列規(guī)律解析,猜測出來最終表達(dá)式1/2!-...+(-1)^(n-1)*1/n!。
【如果只能列出n=2,3,4等情況,建議不給分,因為這個思路很容易想。
但是能夠找到規(guī)律并猜測出表達(dá)式,建議給三分之二或者四分之三的分?jǐn)?shù)。因為這個數(shù)列規(guī)律很不好找。但是這種思路一定不給滿分,因為沒有嚴(yán)格的推理過程】
答:
甲乙丙每人花了1.8元,但丁坐車沒有花4角(丁自己沒有錢),甲乙丙花的錢里面,已經(jīng)包含了丁的錢
這題無法根據(jù)中間過程給分,不推薦
【ZhaiYao:這題有點混淆概念,可以看出來一個人在混亂時候腦子能不能反應(yīng)過來,分析清楚各種關(guān)系。解釋清楚就得滿分,否則不得分】
?
答:34
1. 根據(jù)第2塊圖形填入的個數(shù)分類討論(或其他方式分類討論),給分
2. 回答對答案,給分
[追問:對2*n的情況,有多少種?遞推關(guān)系:n=1或者2,有1種;否則,f(n)=f(n-1)+f(n-2),斐波拉契數(shù)列]
答:3條
1. 從1條病狗的情況開始分析,給三分之一的分
2. 推廣到3條病狗,給滿分(需要解釋,直接說3條,卻解釋不清楚的,不得分)
[追問:如果第x天傳來一陣槍聲,那么問一共有幾條病狗?這天響了多少槍?]
由于題目的知名度較高,如果面試者很快答對,考慮不予計分
答:3121
1. 從最后一只猴子開始考慮,給分
2. 設(shè)最后一只猴子來的時候,桃子的數(shù)量為5x+1;第4只就為(5x+1) * (5/4) + 1,給分
3. 依次類推,得到第一只猴子來的時候,桃子的數(shù)量,給分
4. 算出x的值,給分
[張一]: 用遞歸的方式來做,很巧妙!設(shè)f(n)為第n次每只猴子的份數(shù)。則4f(n) = 5f(n+1) + 1
1. 給出遞歸式,給分
2. 化為等比數(shù)列,給分 f(n)=a*(4/5)^n-1。
2. 算出答案,
F(5)有意義,a最少為5^5,所以f(1)=5^4 * 4 –?1 =624,總數(shù)為624*5+1=3121
給分
答:
1. 如果只有一頂紅帽子,則紅帽子的人當(dāng)場就知道了,排除。給分
2. 如果三頂都是紅帽子,則無人能知道自己的顏色,因為他看到的另兩頂都是紅帽子??梢耘懦?。給分
3. 只能是2頂紅帽子,1頂黑帽子。思路如下:A黒,BC紅。3人都無法確定,回家苦思。B想:如果自己頭上黒帽,則C立即知道頭上是紅帽,既然C不知道,則說明自己頭上也是紅帽。第二天猜出自己的帽子。C也是這樣。A根據(jù)BC的表現(xiàn),知道只有2頂紅帽,自己頭上是黒帽。給分。
面試者解釋比較繁瑣,不推薦。
【ZhaiYao: 該題目面試者有自信的說出答案就可以給分,不需要面試者詳細(xì)解釋】
答:
1. 將比賽結(jié)果分為勝、平、負(fù)三種。給分
2. 各射50箭時,三種結(jié)果的可能性為x, y, x;且x+y+x=100%。給分
3. A多射1箭,則原來獲勝時,現(xiàn)在還是獲勝;原來打平時,現(xiàn)在50%可能獲勝;原來輸時,現(xiàn)在不可能獲勝。因此獲勝的可能性為x+0.5y,正好等于50%。給分
注:如果面試者能以各射0箭,各射1箭等簡單情況,推算出結(jié)果和原本的箭數(shù)無關(guān),固定為50%,可以考慮給分。
答:
解法1:假設(shè)一共生育x孩子。那么每次生育并不被其他事件所影響,所以男女孩子各半。1:1
解法2:數(shù)學(xué)建模。
解法3:設(shè)想極端情況:(1)大家都堅持只生一胎;(2)大家都一直生育,直到得到男孩為止;結(jié)論均為50%。所以推出一般情況下,也為50%
注:如果面試者能以各射0箭,各射1箭等簡單情況,推算出結(jié)果和原本的箭數(shù)無關(guān),固定為50%,可以考慮給分。
Chap6編程及代碼題
答:
| 1.?char * strcpy(char * strDest,const char * strSrc){ if ((strDest==NULL)||(strSrc==NULL)) //[1] throw "Invalid argument(s)"; //[2] ?????????char * strDestCopy=strDest; ?//[3] while ((*strDest++=*strSrc++)!='\0'); //[4] return strDestCopy; ?????} 2. 為了實現(xiàn)鏈?zhǔn)椒祷?/span> |
題目:void multiple(int a[], int b[], int c[]); //a,b為兩個乘數(shù),c為輸出結(jié)果
考察點:就是編程實現(xiàn)一下小學(xué)的乘法運(yùn)算,關(guān)注a,b各位相乘結(jié)果寫入c時,對應(yīng)的下標(biāo)運(yùn)算,以及進(jìn)位的處理。
如果寫的比較快,再考察一下怎么測自己的代碼
答:
| void multiply(int a[], int b[], int c[])?{ int i, j, k; ? ??????int tmp; ? ??????for (i = 0; i < a.size(); ++i) { ? ?????????k = i; ? ?????????for (j = 0; j < b.size(); ++j) { ?????????????result[k++] += a[i] * b[j]; ? ?????????} ?????} ?????for (k = c.size() - 1; ?k >= 0; --k) { ? ?????????if (result[k] > 9) { ?????????????if (k != 0){ ?????????????????c[k-1] += c[k] / 10; ? ?????????????????c[k] %= 10; ? ?????????????}else{ ?????????????????tmp = result[k] / 10; ? ?????????????????result[k] %=10; ? ?????????????????result.insert(result.begin(), tmp); ? ?????????????} ?????????} ????} } |
題目:The strtok() function can be used to parse the string s into tokens. The first call to strtok() should ?have ?s ?as its first argument. Subsequent calls should have the first argument set to NULL. Each call returns a pointer to the next token, or NULL when no more tokens are found.
答:
| char *mystrtok(char *s,const char *delim) { ????static char *last; ????char *tok; ????char *ucdelim; ????char *spanp; ????int c,sc; ????/**//*s為空,并且上次剩余值也為空,則直接返回 NULL,否則s為last或當(dāng)前值中有值的一方*/ ????if (s == NULL && (s = last) == NULL) ????????return NULL; ???? ????int found = 0;//是否找到與delim匹配的字符 ???? ????//處理連續(xù)的待匹配的字符 ????cont: ????c=*s++; ????for (spanp = (char *)delim;(sc = *spanp++) != 0;) ????{ ????????if (c == sc) ????????????goto cont; ????} ????if (c == 0) ????{ ????????last = NULL; ????????return NULL; ????} ????tok = s-1; ????while (!found && *s != '\0') ????{ ????????ucdelim = (char *) delim; ????????while (*ucdelim) ????????{ ????????????if (*s == *ucdelim) ????????????{ ????????????????found = 1; ????????????????*s = '\0'; ????????????????last = s + 1; ????????????????break; ????????????} ????????????ucdelim++; ????????} ????????if (!found) ????????{ ????????????s++; ????????????if(*s=='\0') ????????????????last = NULL; ????????} ????} ????return tok; } |
答:32bit下12; 64bit下16
答:byte ó?unsigned char => a = -1;
要求:
考察點:
答:
| int c; // current char int result; int sign; // if '-', negative; otherwise positive; /*skip the whitespace*/ while( isspace(*s) ) ???????s++; sign = ( *s == '-' ) ? -1 : 1; if( *s == '+' || *s == '-' ) //skip the sign s++; result = 0; ??while(isdigit(*s)){ result = 10 * result + ( *s - '0' ); s++; } return sign * result; } |
| char *strstr(const char *s, const char *find){ ????????char *cp = s; ????????char *s1; ????????char *s2; ????????/*find="\0"*/ ????????if(!*find) ???????????????return s; ????????while(*cp){ ????????????????s1 = cp; ????????????????s2 = find; ????????????????while(*s1 && *s2 && !(*s1 - *s2)){ ????????????????????????s1++; ????????????????????????s2++; ????????????????} ????????????????if(!*s2) ????????????????????????return cp; ????????????????cp++; ????????} ????????return NULL; } |
考察點:
答:
單向鏈表(單鏈表)是鏈表的一種,其特點是鏈表的鏈接方向是單向的,對鏈表的訪問要通過順序讀取從頭部開始。
| 1.?Node定義: typedef?struct Node{ ??DataType data; ??struct node *next; }node; 2.?add():在head增加一個節(jié)點 int add(Node *head,?DataType DataX){ ?//返回參數(shù):0分配空間失敗,1成功 Node NodeAdd=new LinkList; if(!NodeAdd) return (0); NodeAdd->data=DataX; NodeAdd->Next=head->Next; head->Next=NodeAdd; return (1); } 3.?delete():刪除指定節(jié)點 int delete(Node *head, DataType DataX){ ???Node *p = head; ???Node *s = p->next; ???while(s != NULL){ ??????if(s->data != Datax){ ???????????p = p->next; ???????????s = s->next; ??????} ??????else{ ??????????p -> next = s -> next; ??????????free(s); ??????????return 1; ??????} ???} ??return 0; } 4.?retrieve():對所有節(jié)點進(jìn)行“指定的函數(shù)操作”,“指定的函數(shù)操作”由用戶輸入; void retrieve(Node *head, void (*visit)(data)){ Node *p = head; while(p != NULL){ ???(*visit)(p->data); ???p = p->next; } } |
?
| 說明:以下代碼是把一個字符串倒序,如“abcd”倒序后變?yōu)椤癲cba” 1、#include"string.h" 2、main() 3、{ 4、?char*src="hello,world"; 5、?char* dest=NULL; 6、?int len=strlen(src); 7、?dest=(char*)malloc(len);??// 分配len+1 8、?char* d=dest; 9、?char* s=src[len];???//len-1 10、?while(len--!=0) 11、?d++=s--; 12、?printf("%s",dest);??//尾部要加\0 13、?return 0;??//返回前要釋放malloc的內(nèi)存 14、} |
| void Merge(int *p1, unsigned uCount1, int *p2, unsigned uCount2) { ????if (p1 == NULL || p2 == NULL || uCount1 == 0 || uCount2 == 0) ????{ ????????return; ????} ????int i = 0; ????int j = 0; ????bool fSign = false; ? ????while ((i < uCount1) && (j < uCount2)) ????{ ????????if (p1[i] == p2[j]) ????????{ ????????????if (!fSign) ????????????{ ????????????????printf("%d\n", p1[i]); ????????????????fSign = true; ????????????} ????????????++i; ????????} ????????else if (p1[i] < p2[j]) ????????{ ????????????fSign = false; ????????????++i; ????????} ????????else ????????{ ????????????fSign = false; ????????????++j; ????????} ????} } |
?
| char str[]=”hello”; int *p=(int *)str; *p=0x00313200; printf("%s",str); |
//提示0x31對應(yīng)字符'1',0x32對應(yīng)字符'2'。
答:返回空?!盶0”
| void test1() { char string[10]; char* str1 = "0123456789"; strcpy( string, str1 ); } ? ? void test2() { char string[10], str1[10]; int i; for(i=0; i<10; i++) { str1[i] = 'a'; } strcpy( string, str1 ); } ? ? void test3(char* str1) { char string[10]; if( strlen( str1 ) <= 10 ) { strcpy( string, str1 ); } } ? |
答:
試題1字符串str1需要11個字節(jié)才能存放下(包括末尾的’\0’),而string只有10個字節(jié)的空間,strcpy會導(dǎo)致數(shù)組越界;
試題2,如果面試者指出字符數(shù)組str1不能在數(shù)組內(nèi)結(jié)束可以給3分;如果面試者指出strcpy(string, str1)調(diào)用使得從 str1內(nèi)存起復(fù)制到string內(nèi)存起所復(fù)制的字節(jié)數(shù)具有不確定性可以給7分,在此基礎(chǔ)上指出庫函數(shù)strcpy工作方式的給10分;
對試題3,if(strlen(str1) <= 10)應(yīng)改為if(strlen(str1) < 10),因為strlen的結(jié)果未統(tǒng)計’\0’所占用的1個字節(jié)。
| int function(char *s1, char *s2) { int i=0; while(s1[i]==s2[i] && s2[i]!=0 ) i++; return (s1[i]==0 && s2[i]==0); } |
答:
功能——判斷s2與s1是否內(nèi)容一致
問題——沒有判斷參數(shù)為NULL的情況;當(dāng)s1==s2的時候,函數(shù)應(yīng)該直接返回true,不需要一個個去比較下去;
| class myclass { ?public: ??//Constructor ??myclass( string s ):str(s) ??{ ???cout << "Constructing " << endl ; ??} ?? ??//Destructor ??~myclass() ??{ ???cout << "Destructing " << endl ; ??} ?? ??string getValue() ??{ ???return str ; ??} ? ?private: ??string str ; } ; ? void display( myclass t ) { ?cout << t.getValue() << endl ; } ? myclass getTest() { ?return myclass("Jun") ; } ? int main() { ?myclass te = myclass("chenjq") ; ?display(te) ; ?getTest() ; ?return 0; } |
答:
輸出:
Constructing
chenjq
Destructing
Constructing
Destructing
Destructing
重點:需要了解在按值傳向函數(shù),以及按值從函數(shù)返回的時候?qū)ο蟮臉?gòu)造、析構(gòu)過程:
(1) 將對象按值傳給函數(shù)的時候,首先會創(chuàng)建該對象的一個副本,將這個副本傳給函數(shù),但是在創(chuàng)建這個副本的時候,不會調(diào)用構(gòu)造函數(shù),而在這個函數(shù)返回的時候會調(diào)用析構(gòu)函數(shù)。
(2) 函數(shù)按值返回對象的時候,也會創(chuàng)建返回對象的一個副本,同樣的也不會調(diào)用構(gòu)造函數(shù),在返回后調(diào)用析構(gòu)函數(shù)銷毀該對象。
| class myclass{ public: ?myclass(unsigned int k):length(k){ content=(int *)malloc(sizeof(int)*k); } ? ~myclass(){ if(content)free(content); } private: ?unsigned int length; ?int *content; } ? void function() { myclass c1=100; myclass c2=c1; myclass c3; ? myclass c4=200; c4=c1; ? } |
答:
| class myclass{ public: myclass(unsigned int k):length(k){ content=(int *)malloc(sizeof(int)*k); ? } ? ~myclass(){ if(content)free(content); } private: unsigned int length; int *content; ? } ? void function() { void *p=new myclass(100); delete p; } |
答:
Delete操作,由于p是void *類型,在free對象本身所占的內(nèi)存空間之前,不會調(diào)用destructor,帶造成content指針指向的內(nèi)存區(qū)域的泄露。
| ?#include <iostream> using std::cout; class P { public: virtual void print() { cout << "P"; } }; class Q: public P { public: virtual void print() { cout << "Q"; } }; int main() { P * p = new P; Q * q = static_cast <Q *> (p); ? q->print(); delete p; cout << endl; ? q = new Q; p = q; q->print(); p->print(); cout << endl; ? p = new (q) P; q->print(); p->print(); cout << endl; ? p->~P(); delete q; return 0; } |
答:輸出為 —— P?QQ?PP
Chap7 計算機(jī)基礎(chǔ)
inline 函數(shù):
定義:
關(guān)鍵字用來定義一個類的內(nèi)聯(lián)函數(shù),函數(shù)的代碼被放入符號表中,在使用時直接進(jìn)行替換,(像宏一樣展開),沒有了調(diào)用的開銷,效率也很高。
用途:
引入它的主要原因是用它替代C中表達(dá)式形式的宏定義。
虛函數(shù):
定義:
在某基類中聲明為virtual并在一個或多個派生類中被重新定義的成員函數(shù)。
用途:
實現(xiàn)多態(tài)性,通過指向派生類的基類指針,訪問派生類中同名覆蓋成員函數(shù)。
虛函數(shù)是否可以實現(xiàn)成inline?
從狹義的角度來講是不能的,因為虛函數(shù)是在運(yùn)行期間決定如何調(diào)用,而inline函數(shù)實在編譯期間決定是否inline。從廣義的角度講是可以的。參見《More Exceptional C++》第8條款,《Exceptional C++ Style》第25條款。
函數(shù)調(diào)用過程中,第一個進(jìn)棧的是(主函數(shù)中的)調(diào)用處的下一條指令(即函數(shù)調(diào)用語句的下一條可執(zhí)行語句)的地址;然后是函數(shù)的各個參數(shù),而在大多數(shù)C/C++編譯器中,在函數(shù)調(diào)用的過程中,函數(shù)的參數(shù)是由右向左入棧的;然后是函數(shù)內(nèi)部的局部變量(注意static變量是不入棧的);在函數(shù)調(diào)用結(jié)束(函數(shù)運(yùn)行結(jié)束)后,局部變量最先出棧,然后是參數(shù),最后棧頂指針指向最開始存的指令地址,程序由該點繼續(xù)運(yùn)行。
函數(shù)調(diào)用方式?jīng)Q定了函數(shù)參數(shù)入棧的順序,是由調(diào)用者函數(shù)還是被調(diào)用函數(shù)負(fù)責(zé)清除棧中的參數(shù)等問題,而函數(shù)名修飾規(guī)則決定了編譯器使用何種名字修飾方式來區(qū)分不同的函數(shù),如果函數(shù)之間的調(diào)用約定不匹配或者名字修飾不匹配就會產(chǎn)生以上的問題。
參考:http://caifuchang.blog.163.com/blog/static/33912331201041611260151/
extern 可以用引用頭文件的方式,也可以用extern關(guān)鍵字,如果用引用頭文件方式來引用某個在頭文件中聲明的全局變理,假定你將那個編寫錯了,那么在編譯期間會報錯,如果你用extern方式引用時,假定你犯了同樣的錯誤,那么在編譯期間不會報錯,而在連接期間報錯。
C++語言支持函數(shù)重載,C 語言不支持函數(shù)重載。函數(shù)被C++編譯后在庫中的名字與C 語言的不同。假設(shè)某個函數(shù)的原型為:?void foo(int x, int y);該函數(shù)被C 編譯器編譯后在庫中的名字為_foo ,?而C++ 編譯器則會產(chǎn)生像_foo_int_int 之類的名字。C++提供了C 連接交換指定符號extern“C”來解決名字匹配問題。?
C++的class具有數(shù)據(jù)封裝功能,其包含屬性訪問級別可以為private,public和protect,還具有實現(xiàn)類接口功能和輔助功能的操作函數(shù),而struct屬性訪問權(quán)限只有public,沒有數(shù)據(jù)封裝功能,也就沒有實現(xiàn)信息隱藏這一面向?qū)ο蟮乃枷氲臋C(jī)制,struct本身不含有操作函數(shù),只有數(shù)據(jù)。
靜態(tài)綁定:編譯時綁定,通過對象調(diào)用
動態(tài)綁定:運(yùn)行時綁定,通過地址實現(xiàn)
只有采用“指針->函數(shù)()”或“引用變量.函數(shù)()”的方式調(diào)用C++類中的虛函數(shù)才會執(zhí)行動態(tài)綁定。對于C++中的非虛函數(shù),因為其不具備動態(tài)綁定的特征,所以不管采用什么樣的方式調(diào)用,都不會執(zhí)行動態(tài)綁定。
多態(tài)(Polymorphism)是面向?qū)ο蟮暮诵母拍?#xff0c; C++中多態(tài)可以分為基于繼承和虛函數(shù)的動態(tài)多態(tài)以及基于模板的靜態(tài)多態(tài),?
1)?描述以下表示形式的意義:Char *q[]={“xxx”, “yyy”, “zzz”};
Char (*p)[]=a;
答:
前者:指針數(shù)組,q[0],q[1],q[2]都為char *類型的指針;
后者:數(shù)組指針,p指向一個char數(shù)組。
2)?解釋以下表示形式的意義:
A)?"a" ???B)?'\\' ???C)?'W' ???D)?’abc’
3)?解釋以下表示形式的意義及其作用:typedef int (*PFUN)(int x,int y);
答案:函數(shù)指針;
4)?Call by value、call by reference和call by pointer的優(yōu)缺點,舉例說明各自的應(yīng)用形式。
?
5)?C++對象的copy constructor與copy assignment的區(qū)別與聯(lián)系,談?wù)勈褂脮r的注意事項,列舉它們應(yīng)用的場景及。
答:
copy constructor:從一個已有的對象來構(gòu)造另一個對象;包括:
用已有對象來初始化新聲明的對象;
將對象按值傳遞給函數(shù)作為參數(shù);
函數(shù)按值返回對象。
copy assignment:將已有的對象賦值個另一個已有的對象;
實例:
Person A(B); // copy constructor
Person C=B; //copy constructor
Function1(D); //copy constructor
B=?Function2(…); //copy constructor
Person D;
D=B; //copy assignment
注意事項:編譯器默認(rèn)的copy constructor和copy assignment操作,是按照member-wise copy的方式逐個copy每個member,這種淺拷貝操作在有些情況下可能造成資源泄漏/指向重疊。
如果的確需要deep copy,需要自定義相應(yīng)操作。這時需要清楚哪些地方用了copy constructor,哪些地方用了copy assignment,從而分別自定義copy constructor和copy assignment。一般來說,自定義的copy constructor、destructor和copy assignment操作常常同時出現(xiàn)。
區(qū)別與聯(lián)系:
copy constructor不用檢測是否是用一個對象來初始化它自己;
copy constructor不用對被構(gòu)造對象做資源清理操作,如delete操作;
6)?說明以下表達(dá)式的意義:TYPE *t = new(a) TYPETYPE;
答: Placement new操作:在a指向的內(nèi)存區(qū)域,調(diào)用default constructor構(gòu)造一個TYPE類型的對象,并返回該對象的指針。
7)?解釋以下表達(dá)式的區(qū)別:TYPE t 與 TYPE *PT=new TYPE;
答: TYPE t; 從static area或者stack上分配內(nèi)存,并調(diào)用default constructor;
TYPE *PT=new TYPE; 從堆上分配內(nèi)存,并調(diào)用default constructor;
1)?Java多線程編程機(jī)制,線程類,互斥機(jī)制(synchronize) Java線程類:Thread,Runnable接口 Java互斥:synchronize關(guān)鍵字 wait和notify方法
答:
但是,如果被同步的方法里面有一些代碼是可以被共享的,而且這些能夠被共享的代碼里面存在比較耗時的操作時,僅僅使用synchronized關(guān)鍵字就無法達(dá)到最高的效率,這個時候可以使用wait與notify方法來對并發(fā)訪問做更進(jìn)一步的控制。
wait()方法表示,放棄當(dāng)前對資源的占有權(quán),等啊等啊,一直等到有人通知我,我才會運(yùn)行后面的代碼。 notify()方法表示,當(dāng)前的線程已經(jīng)放棄對資源的占有,通知等待的線程來獲得對資源的占有權(quán),但是只有一個線程能夠從wait狀態(tài)中恢復(fù),然后繼續(xù)運(yùn)行wait()后面的語句;notifyAll()方法表示,當(dāng)前的線程已經(jīng)放棄對資源的占有,通知所有的等待線程從wait()方法后的語句開始運(yùn)行。
2)?引用傳遞 Java函數(shù)傳遞的是參數(shù)的引用 深度拷貝:重寫clone()
3)?接口和抽象類的作用有什么區(qū)別
答:
接口能夠多重繼承;抽象類只能繼承一個;
接口只能定義常量;抽象類能夠定義變量
接口的函數(shù)都是抽象的;抽象類的函數(shù)可以是非抽象的
接口implement,抽象extend
4)?重載和覆寫
答:
重載時function(int i), function(int i, int j)。相同的函數(shù)名,不同的簽名;重寫是函數(shù)簽名相同。但是子類的函數(shù)覆蓋了父類的同名(簽名)函數(shù)。
5)?容器類型選擇: ArrayList:隨機(jī)訪問好 LinkedList:元素添加和移出(中心位置) HashSet:普遍性能都比TreeSet好 TreeSet:保持內(nèi)部元素的排序狀態(tài) HashMap:Hashtable的替代品,一般性能都較好 TreeMap:保持內(nèi)部元素的排序狀態(tài)
6)?向上轉(zhuǎn)型和向下轉(zhuǎn)型 向上安全,向下執(zhí)行期檢查:ClassCastException
7)?多態(tài) 繼承,接口與多態(tài)的關(guān)系
1)?是否寫過多線程代碼
2)?線程間通信的方法
答:同一進(jìn)程的各線程可以直接讀寫進(jìn)程數(shù)據(jù)段進(jìn)行通信,同時需要同步和互斥手段的輔助。而不同進(jìn)程間的線程通信可以參考不同進(jìn)程間的通信。
3)?多線程同步方式(能答出幾個就可以)
答:事件Event, 臨界區(qū)域Critical Section, 互斥器Mutex, ?信號量Semaphore
詳細(xì)參考:http://baike.baidu.com/view/2808915.htm
4)?同步和異步的區(qū)別
答:同步是阻塞模式,即發(fā)送方發(fā)出數(shù)據(jù)后,等接收方發(fā)回響應(yīng)以后才發(fā)下一個數(shù)據(jù)包的通訊方式;而異步是非阻塞方式,發(fā)送方發(fā)出數(shù)據(jù)后,不等接收方發(fā)回響應(yīng),接著發(fā)送下個數(shù)據(jù)包的通訊方式。
例如:普通B/S模式(同步)AJAX技術(shù)(異步)
同步:提交請求->等待服務(wù)器處理->處理完畢返回 這個期間客戶端瀏覽器不能干任何事
異步: 請求通過事件觸發(fā)->服務(wù)器處理(這是瀏覽器仍然可以作其他事情)->處理完畢
5)?進(jìn)程和線程的概念
答:進(jìn)程是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ);是一個正在執(zhí)行的程序;計算機(jī)中正在運(yùn)行的程序?qū)嵗?#xff1b;可以分配給處理器并由處理器執(zhí)行的一個實體;由單一順序的執(zhí)行顯示,一個當(dāng)前狀態(tài)和一組相關(guān)的系統(tǒng)資源所描述的活動單元。
線程(thread),有時被稱為輕量級進(jìn)程(Lightweight Process,LWP),是程序執(zhí)行流的最小單元。一個標(biāo)準(zhǔn)的線程由線程ID,當(dāng)前指令指針(PC),寄存器集合和堆棧組成。另外,線程是進(jìn)程中的一個實體,是被系統(tǒng)獨(dú)立調(diào)度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有一點在運(yùn)行中必不可少的資源,但它可與同屬一個進(jìn)程的其它線程共享進(jìn)程所擁有的全部資源。一個線程可以創(chuàng)建和撤消另一個線程,同一進(jìn)程中的多個線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約,致使線程在運(yùn)行中呈現(xiàn)出間斷性。線程也有就緒、阻塞和運(yùn)行三種基本狀態(tài)。
二者區(qū)別:子進(jìn)程和父進(jìn)程有不同的代碼和數(shù)據(jù)空間,而多個線程則共享數(shù)據(jù)空間,每個線程有自己的執(zhí)行堆棧和程序計數(shù)器為其執(zhí)行上下文.多線程主要是為了節(jié)約CPU時間,發(fā)揮利用,根據(jù)具體情況而定. 線程的運(yùn)行中需要使用計算機(jī)的內(nèi)存資源和CPU。通常在一個進(jìn)程中可以包含若干個線程,它們可以利用進(jìn)程所擁有的資源。在引入線程的操作系統(tǒng)中,通常都是把進(jìn)程作為分配資源的基本單位,而把線程作為獨(dú)立運(yùn)行和獨(dú)立調(diào)度的基本單位。
6)?進(jìn)程的地址空間是怎么回事?虛擬內(nèi)存是如何實現(xiàn)的
答:虛擬內(nèi)存的存在使得CPU上的指令訪問的地址都是虛擬地址,而這些地址是需要在物理內(nèi)存中真實存在的,這里就需要在虛擬地址和物理地址直接建立一個映射關(guān)系(應(yīng)當(dāng)是多對一的關(guān)系),說白了就是一個整數(shù)集合到另一個整數(shù)集合的映射。然后在查找時,根據(jù)相應(yīng)的算法(如先進(jìn)先出,最多使用等)進(jìn)行調(diào)度。
7)?Linux進(jìn)程間通信有哪些方式,優(yōu)缺點如何
答: Linux下進(jìn)程間通信的幾種主要手段:
1)?Tcp/IP連接模型
答:TCP/IP 通訊協(xié)議采用了四層的層級模型結(jié)構(gòu),每一層都調(diào)用它的下一層所提供的網(wǎng)絡(luò)任務(wù)來完成自己的需求:
應(yīng)用層 (Application):應(yīng)用層是個很廣泛的概念,有一些基本相同的系統(tǒng)級 TCP/IP 應(yīng)用以及應(yīng)用協(xié)議,也有許多的企業(yè)商業(yè)應(yīng)用和互聯(lián)網(wǎng)應(yīng)用。
傳輸層 (Transport):傳輸層包括 UDP 和 TCP,UDP 幾乎不對報文進(jìn)行檢查,而 TCP 提供傳輸保證。
網(wǎng)絡(luò)層 (Network):網(wǎng)絡(luò)層協(xié)議由一系列協(xié)議組成,包括 ICMP、IGMP、RIP、OSPF、IP(v4,v6) 等。
鏈路層 (Link):又稱為物理數(shù)據(jù)網(wǎng)絡(luò)接口層,負(fù)責(zé)報文傳輸。
2)?Io復(fù)用,select和poll的區(qū)別
答:IO復(fù)用模型:調(diào)用select或poll,在這兩個系統(tǒng)調(diào)用中的某一個上阻塞,而不是阻塞于真正I/O系統(tǒng)調(diào)用。 阻塞于select調(diào)用,等待數(shù)據(jù)報套接口可讀。當(dāng)select返回套接口可讀條件時,調(diào)用recevfrom將數(shù)據(jù)報拷貝到應(yīng)用緩沖區(qū)中。
select和poll的區(qū)別:select()和poll()本質(zhì)上來講做的是同一件事,只是完成的方法不一樣。兩者都通過檢驗一組文件描述符來檢測是否有特定的時間將在上面發(fā)生并在一定的時間內(nèi)等待其發(fā)生。
select()函數(shù)的接口主要是建立在一種叫'fd_set'類型的基礎(chǔ)上。它('fd_set') 是一組文件描述符 (fd)的集合。
poll ()接受一個指向結(jié)構(gòu)'struct pollfd'列表的指針,其中包括了你想測試的文件描述符和事件。事件由一個在結(jié)構(gòu)中事件域的比特掩碼確定。當(dāng)前 的結(jié)構(gòu)在調(diào)用后將被填寫并在事件發(fā)生后返回。
3)?實現(xiàn)一個client/server的通信過程,寫一段偽代碼(重點寫出需要調(diào)用的各socket api)
答:
| Server端: socket addr_in svr_addr; socket addr_in client_addr; ServerSocket(addr_in_svr_addr); bind(); listen(); while(true){ ????client = accept(addr_in client_addr); ????if(!fork()){ read(); send(client); close(client); ?????} } |
| Client 端: ?socket(addr_in_client_addr); connect(server); data = recv(); close(); |
4)?TCP和UDP的區(qū)別,擁塞窗口的概念,如何建立一個TCP連接
答:TCP---傳輸控制協(xié)議,提供的是面向連接、可靠的字節(jié)流服務(wù)。當(dāng)客戶和服務(wù)器彼此交換數(shù)據(jù)前,必須先在雙方之間建立一個TCP連接,之后才能傳輸數(shù)據(jù)。TCP提供超時重發(fā),丟棄重復(fù)數(shù)據(jù),檢驗數(shù)據(jù),流量控制等功能,保證數(shù)據(jù)能從一端傳到另一端。
UDP---用戶數(shù)據(jù)報協(xié)議,是一個簡單的面向數(shù)據(jù)報的運(yùn)輸層協(xié)議。UDP不提供可靠性,它只是把應(yīng)用程序傳給IP層的數(shù)據(jù)報發(fā)送出去,但是并不能保證它們能到達(dá)目的地。由于UDP在傳輸數(shù)據(jù)報前不用在客戶和服務(wù)器之間建立一個連接,且沒有超時重發(fā)等機(jī)制,故而傳輸速度很快
擁塞窗口: 在TCP傳送中的擁塞控制中,發(fā)送端通過網(wǎng)絡(luò)的擁塞程度所給出的一個大小值,而這個值就是擁塞窗口。
建立TCP連接:TCP連接時通過三次握手建立的,詳細(xì)見下面所示。
5)?Tcp連接建立的三次握手是指什么
答:第一步是請求端(客戶端)發(fā)送一個包含SYN即同步(Synchronize)標(biāo)志的TCP報文,SYN同步報文會指明客戶端使用的端口以及TCP連接的初始序號;
第二步,服務(wù)器在收到客戶端的SYN報文后,將返回一個SYN+ACK的報文,表示客戶端的請求被接受,同時TCP序號被加一,ACK即確認(rèn)(Acknowledgement)。
第三步,客戶端也返回一個確認(rèn)報文ACK給服務(wù)器端,同樣TCP序列號被加一,到此一個TCP連接完成。然后才開始通信的第二步:數(shù)據(jù)處理。
| TCP Client | Flags | TCP Server |
| 1 Send SYN (seq=x) | ----SYN---> | SYN Received |
| 2 SYN/ACK Received | <---SYN/ACK---- | Send SYN (seq=y), ACK (x+1) |
| 3 Send ACK (y+1) | ----ACK---> | ACK Received, Connection?Established |
在TCP/IP協(xié)議中,TCP協(xié)議提供可靠的連接服務(wù),采用三次握手建立一個連接。
第一次握手:建立連接時,客戶端發(fā)送syn包(syn=j)到服務(wù)器,并進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器確認(rèn);
第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ack=j+1),同時自己也發(fā)送一個SYN包(syn=k),即SYN+ACK包,此時服務(wù)器進(jìn)入SYN_RECV狀態(tài);
第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài),完成三次握手。
完成三次握手,客戶端與服務(wù)器開始傳送數(shù)據(jù),
6)?tcp連接的time_wait是什么狀態(tài),描述其發(fā)生的場景,說明它存在的好處/壞處
答:TCP包括一種機(jī)制, 確認(rèn)與連接相關(guān)的包在網(wǎng)絡(luò)上延遲后不被同一對主機(jī)之間后來的連接所接受. 這種機(jī)制是由TCP 協(xié)議的T IM E_WA IT 狀態(tài)實現(xiàn)的. 當(dāng)一端點關(guān)閉一個TCP 連接時, 它保留與連接有關(guān)的狀態(tài)—— 通常是TCB(TCP protocol control block) 的復(fù)制——兩倍于最大段存活時間(maximum segment life time, 即MSL ). 處于此狀態(tài)的連接即處于TIME_WAIT 狀態(tài);
TIME_WAIT的優(yōu)點:可靠地實現(xiàn)TCP全雙工連接的終止;允許老的重復(fù)分節(jié)在網(wǎng)絡(luò)中消逝?。
TIME_WAIT的缺點:重負(fù)載服務(wù)器有可能保留有上千個TIME_WAIT TCB, 因而消耗了大量的內(nèi)存并能減慢活動的連接。
1)?Shell命令,sed,awk等。
參考問題及答案:
Shell:
用沒用過shell命令。如果用過,說下常用的shell命令。
問下cat chmod diff more/less, paste, head/tail, uniq, sort, who
Sed:
Sed簡介參看翟耀的分享: http://com.baidu.com/twiki/bin/view/Sdc/SedEditorShare
考察這幾個命令的理解:
(1) sed '/line/ p' list.txt
(2) sed -n '/line/ p' list.txt
(3) sed '3q' new
(4)
$ sed -n -f holdtest?list.txt
其中holdtest是個文本文件
$ cat holdtest
h
n
p
g
p
(***Only For面試官***
h #拿到一行l(wèi)ine1并且復(fù)制到hold區(qū)。目前p區(qū)[line1],h區(qū)[line1]
n #取下一行l(wèi)ine2放入p區(qū)。目前p區(qū)[line2],h區(qū)[line1]
p #打印p區(qū)內(nèi)容:line2
g #把h區(qū)內(nèi)容復(fù)制到p區(qū)。目前p區(qū)[line1],h區(qū)[line1]
p #打印p區(qū)內(nèi)容:line1。這樣就做到了每兩行互相替換。)
Awk:
Awk簡介參看翟耀的分享: http://com.baidu.com/twiki/bin/view/Sdc/GawkShare
可以考察如下題目:
gawk '/^f/' cars
gawk '$1 ~ /l/' cars
用gawk把所有行加上行長,并按照長度大小排序
gawk '{print length, $0}' cars | sort –n
2)?是否熟悉Linux下的C/C++開發(fā),gcc,gdb,makefile等一些編譯,調(diào)試工具,是否熟悉。
3)?文件系統(tǒng)的組織結(jié)構(gòu),文件重定向是如何實現(xiàn)的
參考答案:ls -la /
下面我們把Linux文件系統(tǒng)的樹形結(jié)構(gòu)的主要目錄列一下
/ Linux文件系統(tǒng)的入口,也是處于最高一級的目錄;
/bin 基礎(chǔ)系統(tǒng)所需要的那些命令位于此目錄,也是最小系統(tǒng)所需要的命令;比如 ls、cp、mkdir等命令;功能和/usr/bin類似,這個目錄中的文件都是可執(zhí)行的,普通用戶都可以使用的命令。做為基礎(chǔ)系統(tǒng)所需要的最基礎(chǔ)的命令就是放在這里。
/boot Linux文件系統(tǒng)的內(nèi)核及引導(dǎo)系統(tǒng)程序所需要的文件,比如 vmlinuz initrd.img 文件都位于這個目錄中。在一般情況下,GRUB或LILO系統(tǒng)引導(dǎo)管理器也位于這個目錄;
/dev 設(shè)備文件存儲目錄,比如聲卡、磁盤... ...
/etc 系統(tǒng)配置文件的所在地,一些服務(wù)器的配置文件也在這里;比如用戶帳號及密碼配置文件;
/home 普通用戶家目錄默認(rèn)存放目錄;
/lib 庫文件存放目錄
/mnt 這個目錄一般是用于存放掛載儲存設(shè)備的掛載目錄的,比如有cdrom 等目錄。
/root Linux文件系統(tǒng)超級權(quán)限用戶root的Home目錄;
?
考察管道,重定向等概念和使用。
重定向的分享見: http://com.baidu.com/twiki/bin/view/Sdc/OutputRedirection
重定向用著簡單,重要是思考重定向的實現(xiàn)方式。
可以考下 ./myprog 1>tmp 2>tmp是否正確?應(yīng)該怎么改?
答案:./myprog 1>tmp 2>&1
具體來說cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案,而session機(jī)制采用的是在服務(wù)器端保持狀態(tài)的方案。
同時我們也看到,由于才服務(wù)器端保持狀態(tài)的方案在客戶端也需要保存一個標(biāo)識,所以session
機(jī)制可能需要借助于cookie機(jī)制來達(dá)到保存標(biāo)識的目的。其實有其他辦法。
session機(jī)制是一種服務(wù)器端的機(jī)制,服務(wù)器使用一種類似于散列表的結(jié)構(gòu)(也可能就是使用散列表)來保存信息。但程序需要為某個客戶端的請求創(chuàng)建一個session的時候,服務(wù)器首先檢查這個客戶端的請求里是否包含了一個session標(biāo)識-稱為session id,如果已經(jīng)包含一個session id則說明以前已經(jīng)為此客戶創(chuàng)建過session,服務(wù)器就按照session id把這個session檢索出來使用(如果檢索不到,可能會新建一個,這種情況可能出現(xiàn)在服務(wù)端已經(jīng)刪除了該用戶對應(yīng)的session對象,但用戶人為地在請求的URL后面附加上一個JSESSION的參數(shù))。
如果客戶請求不包含session id,則為此客戶創(chuàng)建一個session并且生成一個與此session相關(guān)聯(lián)的session id,這個session id將在本次響應(yīng)中返回給客戶端保存。
cookie:將你的所有提供的這些信息和登陸信息,以文件的形式保存到你的計算機(jī)上,當(dāng)訪問其他文件的時候,首先把cookies提交給服務(wù)器,服務(wù)器判斷這里的信息,得知你是什么樣的一個用戶,然后給出你相應(yīng)的功能頁面.可以自行設(shè)置cookies的存在周期,除非設(shè)置了臨時cookies,否則關(guān)閉瀏覽器后cookies信息仍舊保存在主機(jī)的硬盤上。
session:將你所提供的信息,以犧牲服務(wù)器資源的方式記錄下來,當(dāng)你訪問其他頁面的時候,先判斷服務(wù)器上的關(guān)于你的信息,并提供給你相應(yīng)的功能頁面.變量保存在客戶端主機(jī)的內(nèi)存上,關(guān)閉瀏覽器或者session腳本過期后,即自動清除。
Cookies的安全性能一直是倍受爭議的。雖然Cookies是保存在本機(jī)上的,但是其信息的完全可見性且易于本地編輯性,往往可以引起很多的安全問題。所以Cookies到底該不該用,到底該怎樣用,就有了一個需要給定的底線。
先來看看,網(wǎng)站的敏感數(shù)據(jù)有哪些。
登陸驗證信息。一般采用Session("Logon")=true or false的形式。
用戶的各種私人信息,比如姓名等,某種情況下,需要保存在Session里
需要在頁面間傳遞的內(nèi)容信息,比如調(diào)查工作需要分好幾步。每一步的信息都保存在Session里,最后在統(tǒng)一更新到數(shù)據(jù)庫。
當(dāng)然還會有很多,這里列舉一些比較典型的
假如,一個人孤僻到不想碰Session,因為他認(rèn)為,如果用戶萬一不小心關(guān)閉了瀏覽器,那么之前保存的數(shù)據(jù)就全部丟失了。所以,他出于好意,決定把這些用Session的地方,都改成用Cookies來存儲,這完全是可行的,且基本操作和用Session一模一樣。那么,下面就針對以上的3個典型例子,做一個分析
很顯然,只要某個有意非法入侵者,知道該網(wǎng)站驗證登陸信息的Session變量是什么,那么他就可以事先編輯好該Cookies,放入到Cookies目錄中,這樣就可以順利通過驗證了。這是不是很可怕?
Cookies完全是可見的,即使程序員設(shè)定了Cookies的生存周期(比如只在用戶會話有效期內(nèi)有效),它也是不安全的。假設(shè),用戶忘了關(guān)瀏覽器 或者一個惡意者硬性把用戶給打暈,那用戶的損失將是巨大的。
這點如上點一樣,很容易被它人竊取重要的私人信息。但,其還有一個問題所在是,可能這些數(shù)據(jù)信息量太大,而使得Cookies的文件大小劇增。這可不是用戶希望所看到的。
顯然,Cookies并不是那么一塊好啃的小甜餅。但,Cookies的存在,當(dāng)然有其原因。它給予程序員更多發(fā)揮編程才能的空間。所以,使用Cookies改有個底線。這個底線一般來說,遵循以下原則。
不要保存私人信息。
任何重要數(shù)據(jù),最好通過加密形式來保存數(shù)據(jù)(最簡單的可以用URLEncode,當(dāng)然也可以用完善的可逆加密方式,遺憾的是,最好不要用md5來加密)。
是否保存登陸信息,需有用戶自行選擇。
長于10K的數(shù)據(jù),不要用到Cookies。
參考答案網(wǎng)上都有
考察項目多為前端開發(fā)/測試的面試者對基本概念的了解
Chap 8 項目和背景
結(jié)合項目詢問對測試了解的情況,談?wù)剬y試流程的理解:什么階段介入測試比較好;對Code?Review的看法,RD和QA各自的側(cè)重點;測試完成的衡量標(biāo)準(zhǔn),是否接觸過測試覆蓋率;自動化的實現(xiàn)方法,談一下測web常見的一些自動化思路。。。
Chap9 外部工具
1)?介紹一下selenium? Selenium有哪些特點?
答: Selenium是一個針對Web應(yīng)用的開源測試框架,它的測試用例可以用HTML table和HTML代碼或者一些非常流行的編程序言進(jìn)行開發(fā),而且它能在幾乎所有現(xiàn)在的瀏覽器上執(zhí)行。selenium可以被部署到Windows, Linux和Macintosh平臺上。它支持的語言有Java, Python, Ruby, .Net, Perl等等
主要的特點:
l?支持錄制和回放
l?能夠靈活的根據(jù)ID, Name或者XPath來進(jìn)行頁面元素的選取
l?能夠進(jìn)行Debug和設(shè)置斷點
l?能夠把測試腳本保存成HTML, Ruby或者其他語言
l?支持user-extensions.js形式的用戶擴(kuò)展
l?能夠自動進(jìn)行頁面的斷言
2)?Selenium分為哪幾部分?
Selenium IDE: 一個firefox插件,可以錄制、回放測試腳本。
Selenium RC:支持用程序語言編寫測試用例,比如Ruby、Java、C#等,這樣做的好處是,可以將Selenium和其他測試框架集成,比如.NET環(huán)境下,可以把 Selenium和NUnit集成,用Selenium來編寫測試用例,用NUnit來實現(xiàn)測試用例的自動化運(yùn)行。
Selenium Core:Selenium Core是Selenium的核心,是由Javascript和Html文件組成的,它是Selenium IDE和Selenium RC的核心引擎。
Selenium Grid:Selenium Grid是Selenium的一個擴(kuò)展,它可以將一批selenium腳本分配到不同的測試機(jī)上面同步運(yùn)行,從而節(jié)省執(zhí)行時間。
3)?Selenium中verifyTextPresent和assertTextPresent命令的區(qū)別?
答:verifyTestPresent和assertTextPresnt命令都用于判斷頁面上是否存在指定的文本,區(qū)別是verifyTestPresent結(jié)果是false時,剩余的步驟會繼續(xù)執(zhí)行。但assertTextPresent結(jié)果是false時直接終結(jié)該腳本剩余步驟的運(yùn)行。
4)?Selenium中click和clickAndWait的區(qū)別?
答:click命令模擬用戶點擊的動作。命令執(zhí)行完畢后立刻執(zhí)行下一條命令。ClickAndWait命令在點擊后有一個等待的過程,會等頁面重新加載完畢再執(zhí)行下一條命令。
5)?如果有一個按鈕,點擊該按鈕后會發(fā)出一個ajax call,然后得到返回結(jié)果后將該內(nèi)容顯示到新彈出的一個layer中。在寫腳本的時候,點擊按鈕這個動作是否可以用clickAndWait命令?如果不行,怎么解決?
答:不能使用clickAndWait。因為ajax call不會刷新頁面,clickandWait命令會因為等待頁面重新加載而出現(xiàn)Time out. 對這種情況應(yīng)該使用click命令結(jié)合pause命令。
6)?下面是某頁面中的一段html source,其中某a鏈接的地址中包含關(guān)鍵字test。用xpath定位該a元素。
<html>
......
<a href="http://www.baidu.com/s?wd=test">baidu</a>
......
</html>
答: //a[contains(@href,?‘test')]
7)?Selenium內(nèi)部運(yùn)行機(jī)制是這樣的?為什么Selenium腳本可以運(yùn)行在幾乎所有的主流瀏覽器上。
答:Selenium的核心是Javascript寫的,它通過javascript來 實現(xiàn)對Html頁面的操作的。它提供了豐富的指定Html頁 面元素和操作頁面元素的方法。Selenium打開瀏覽器時,把自己的JavaScript文 件嵌入網(wǎng)頁中。然后Selenium的網(wǎng)頁通過frame嵌入目標(biāo)網(wǎng)頁。這樣,就可以使用Selenium的JavaScript對象來控制目標(biāo)網(wǎng)頁。因為selenium是用javascript去操作頁面元素,所以支持幾乎所有主流的瀏覽器。
8)?Selenium用javascript去操作頁面元素會碰到什么問題? Selenium是如何解決這個問題的?
答:javascript受同源策略的限制。當(dāng)瀏覽器要運(yùn)行一個腳本時,便會進(jìn)行同源檢查,只有和被操控網(wǎng)頁同源的腳本才能被執(zhí)行。
Selenium通過采用代理模式來解決這個問題。測試腳本向Selenium Server發(fā)送Http請求,要求和Selenium Server建立連接。Selenium Server啟動瀏覽器,把Selenium Core加載入瀏覽器頁面當(dāng)中,并把瀏覽器的代理設(shè)置為Selenium Server的Http Proxy。測試腳本向Selenium Server發(fā)送Http請求,Selenium Server對請求進(jìn)行解析,然后通過Http Proxy發(fā)送JS命令通知Selenium Core執(zhí)行操作瀏覽器的動作。Selenium Core接收到指令后,執(zhí)行操作。Selenium Server接收到瀏覽器的發(fā)送的Http請求后,自己重組Http請求,獲取對應(yīng)的Web頁面。Selenium Server的Http Proxy把接收的Web頁面返回給瀏覽器。因為瀏覽器存在同源策略,所以Selenium RC中的Selenium Server需要以這種代理模式運(yùn)行
1)?對于Javascript生成的元素,Watir識別和操作該元素是如何做的?
答:實際上,Watir::IE封裝了一個當(dāng)前頁面的DOM tree,而不是html source。比如如果用javascrīpt動態(tài)產(chǎn)生一個元素,在這里仍然可以訪問。普通元素,按照Watir封裝的類就可以實現(xiàn)訪問和操作。Windows對象支持并不好。
詳細(xì)參考該篇文檔:http://www.51testing.com/?uid-84226-action-viewspace-itemid-147237
2)?對于多瀏覽器的web測試,Ruby-watir是如何支持的?
答:Watir,FireWatir,SafariWatir各自的類庫支持,然而對于多瀏覽器的web自動化case編寫,不建議直接使用各個類庫去編寫case。在支持各瀏覽器操作的類庫之上進(jìn)行一層封裝。在自動化case中不需要去關(guān)注各個瀏覽器的操作之間的區(qū)別,只需要通過封裝的類庫直接初始化相應(yīng)的瀏覽器實例即可。
3)?簡述ruby-watir中如何實現(xiàn)數(shù)據(jù)驅(qū)動。
答:將與邏輯無關(guān)的數(shù)據(jù)剝離開來,多組數(shù)據(jù)作為一組輸入,循環(huán)調(diào)用重復(fù)的用例接口。在ruby-watir中,支持讀取Excel等多種數(shù)據(jù)管理格式。
4)?Ruby-watir中對于正則的支持,正則表達(dá)式的考察。
答:在Ruby中,要建立一個正則表達(dá)式,只要把要匹配的模式放到兩個斜線中就行了(/pattern/),而且,在Ruby中,正則表達(dá)式也是對象,可以像對象一樣被操作。
例如,匹配Email地址的正則表達(dá)式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*等。
5)?watir不支持的windows控件,是如何解決的?
解答:采用第三方autoit技術(shù),來模擬鍵盤或鼠標(biāo)操作。參考
http://wiki.openqa.org/display/WTR/JavaScript+Pop+Ups
6)?簡述ruby元編程的概念,應(yīng)用場景,以及如何應(yīng)用。
答:通常元編程被認(rèn)為是通過程序來生成程序,在Ruby中,Ruby元編程的使用變得相當(dāng)?shù)暮唵魏腿菀讓崿F(xiàn),使用Ruby語言本身來產(chǎn)生Ruby代碼,不需要借助外部的工具,著名的RoR框架就是建立在Ruby元編程的基礎(chǔ)上的。
比如ROR框架中的
class Person ?
attr_reader :name ?
end
attr_reader的實現(xiàn)如下:
# def attr_reader(*syms) ?
# syms.each do |sym| ?
# class_eval %{def #{sym} ?
# @#{sym} ?
# end ?
# end ?
# end
#注:class_eval是為一個class增加method的??梢越觭tring和block為參數(shù)。
在ROR框架中已經(jīng)廣泛應(yīng)用了元編程,ActiveRecord在OR映射模型中,將關(guān)系數(shù)據(jù)庫中的關(guān)系表映射到對象模型時,將關(guān)系表的表名映射到類名,表中的每一個元組映射到對應(yīng)于這個類的一個對象,元組的一個字段對應(yīng)于對象的一個屬性。ActiveRecord在這里靈活應(yīng)用了ruby元編程的動態(tài)特性,實現(xiàn)了優(yōu)雅的解決方案。51Testing軟件測試網(wǎng)&S9ttat hFh}
1)?簡單介紹下QTP
答:QTP是個用于錄制和回放腳本的自動化測試工具。它可以用于web和客戶端程序的自動化測試。
2)?QTP中RO與TO的區(qū)別?
答:TO是Test Object的簡稱,RO是Runtime Object簡稱,既用來區(qū)分倉庫對象和實際對象,又用來區(qū)分對象的封裝接口和自身接口。
從實際作用上來看,應(yīng)該說TO就是是倉庫文件里定義的倉庫對象,RO是被測試軟件的實際對象。
為用戶提供了兩種操作對象的接口,一種就是對象的封裝接口,另一種是對象的自身接口。對象的自身接口是對象控件本身的接口,對象的封裝接口是QTP為對象封裝的另一層接口,它是QTP通過調(diào)用對象的自身接口來實現(xiàn)的。兩種接口的腳本書寫格式的差別在于:自身接口需要在對象名后面加object再加屬 性名或方法名,封裝接口就不用在對象名后面加object.
3)?QTP中OBJECT SPY的作用?
答:查看對象,在查看窗口里有列出這些接口,包括屬性和方法。
窗口中間有選擇欄讓你選擇Run-time Object或者Test Object,當(dāng)你選擇Runtime Object時,它顯示的就是對象的自身接口(自身的 屬性和方法).當(dāng)你選擇Test Object時,它顯示的就是對象的封裝接口(封裝的屬性和方法)
4)?如何激活一個窗口?
答:激活窗口使用的方法Window("").Activate
5)?編寫一個QTP腳本,實現(xiàn)向記事本中輸入“baidu”。?
答:SystemUtil.Run “C:\WINDOWS\system32\notepad.exe”
Window(”Notepad”).Activate
Window(”Notepad”).WinEditor(”Edit”).Type “baidu”
1)?什么是負(fù)載測試?什么是性能測試?
答:負(fù)載測試是通過改變系統(tǒng)負(fù)載方式、增加負(fù)載等來發(fā)現(xiàn)系統(tǒng)中所存在的性能問題。負(fù)載測試是一種測試方法,可以為性能測試、壓力測試所采用。負(fù)載測試的加載方 式也有很多種,可以根據(jù)測試需要來選擇。
性能測試是為獲取或驗證系統(tǒng)性能指標(biāo)而進(jìn)行測試。多數(shù)情況下,性能測試會在不同負(fù)載情況下進(jìn)行。
壓力測試通常是在高負(fù)載情況下來對系統(tǒng)的穩(wěn)定性進(jìn)行測試,更有效地發(fā)現(xiàn)系統(tǒng)穩(wěn)定性的隱患和系統(tǒng)在負(fù)載峰值的條件下功能隱患等。
2)?性能測試包含了哪些測試(至少舉出3種)
答:壓力測試、負(fù)載測試、并發(fā)測試、可靠測試、失效恢復(fù)測試。
3)?簡述使用Loadrunner的步驟
答:腳本錄制設(shè)置—錄制腳本—調(diào)試腳本—場景設(shè)置—結(jié)果分析
4)?LoadRunner由哪些部件組成?你使用LoadRunner的哪個部件來錄制腳本, 哪個部件可以模擬多用戶并發(fā)下回放腳本?
答:virtual user generator
controller
analysis
virtual user generator?來錄制腳本,controller來回放腳本
5)?什么是集合點?設(shè)置集合點有什么意義?Loadrunner中設(shè)置集合點的函數(shù)是哪個?
答:集合點:設(shè)置多個用戶到達(dá)某個用戶數(shù)量點集合,同時觸發(fā)一個事務(wù),以達(dá)到模擬真實環(huán)境下同時多個用戶操作,同時模擬負(fù)載,實現(xiàn)性能測試的最終目的
LR_rendezvous(“集合點名稱”)
6)?你在LR中如何編寫自定義函數(shù)?請給出一些你在以前進(jìn)行的項目中編寫的函數(shù)。
答:在創(chuàng)建用戶自定義函數(shù)前我們需要和創(chuàng)建DLL(external libary)。把庫放在VuGen bin 目錄下。一旦加了庫,把自定義函數(shù)分配做一個參數(shù)。該函數(shù)應(yīng)該具有一下格式:__declspec (dllexport) char* <function name>(char*, char*)。
7)?以線程方式運(yùn)行的虛擬用戶有哪些優(yōu)點?
答:VuGen提供了用多線程的便利。這使得在每個生成器上可以跑更多的虛擬用戶。如果是以進(jìn)程的方式跑虛擬用戶,為每個用戶加載相同的驅(qū)動程序到內(nèi)存中,因 此占用了大量的內(nèi)存。這就限制了在單個生成器上能跑的虛擬用戶數(shù)。如果按進(jìn)程運(yùn)行,給定的所有虛擬用戶數(shù)(比如100)只是加載一個驅(qū)動程序?qū)嵗絻?nèi)存 里。每個進(jìn)程共用父驅(qū)動程序的內(nèi)存,因此在每個生成器上可以跑更多的虛擬用戶。
總結(jié)
以上是生活随笔為你收集整理的百度内容质量部测试开发面试题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。