1. 程式人生 > >百度內容質量部測試開發面試題

百度內容質量部測試開發面試題

目錄

Chap1 測試基礎 2

Chap2 測試設計 4

Chap3 演算法 12

Chap4 設計題 19

Chap5 邏輯題 21

Chap6程式設計及程式碼題 26

Chap7 計算機基礎 38

1. C/C++ 38

2. JAVA 39

3. 多執行緒: 40

4. 網路程式設計 41

5. Linux 43

Chap 8 專案和背景 47

Chap9 外部工具 48

1. Selenium 48

2. Ruby-Watir 49

3. QTP: 50

4. LoadRunner 51

Chap1 測試基礎

附件1的19-21頁是一個模擬的面試場景,其中有不少經典題型和問題。不過已經在網上廣為流傳,建議瞭解其中面試思路為主,題目不要照搬太多。

  1. 黑盒測試和白盒測試常用的測試方法有哪些?舉例說明。

答:白盒測試:邏輯覆蓋法,主要包括語句覆蓋,判斷覆蓋,條件覆蓋,判斷條件覆蓋,條件組合覆蓋、路徑覆蓋。

黑盒測試:等價劃分類,邊界值分析,錯誤推測法等

  1. 靜態測試和動態測試的概念。

答:靜態方法是指不執行被測程式本身,僅通過分析或檢查源程式的語法、結構、過程、介面等來檢查程式的正確性。對需求規格說明書、軟體設計說明書、源程式做結構分析、流程圖分析、符號執行來找錯。靜態方法通過程式靜態特性的分析,找出欠缺和可疑之處,例如不匹配的引數、不適當的迴圈巢狀和分支巢狀、不允許的遞迴、未使用過的變數、空指標的引用和可疑的計算等。靜態測試結果可用於進一步的查錯,併為測試用例選取提供指導。

動態方法是指通過執行被測程式,檢查執行結果與預期結果的差異,並分析執行效率和健壯性等效能,這種方法由三部分組成:構造測試例項、執行程式、分析程式的輸出結果。所謂軟體的動態測試,就是通過執行軟體來檢驗軟體的動態行為和執行結果的正確性。目前,動態測試也是公司的測試工作的主要方式。根據動態測試在軟體開發過程中所處的階段和作用,動態測試可分為如下幾個步驟:1、單元測試 2、整合測試 3、系統測試 4、驗收測試 5、迴歸測試。

  1. 等價類有幾種,含義分別是什麼?

答:等價類分為以下幾類:

  • 有效等價類和無效等價類
  • 有效等價類就是對程式的規格說明有意義的,合理的輸入資料所構成的集合,利用有效等價類可驗證程式是否實現了規格說明中的功能和效能。
  • 無效等價類是那些對程式的規格說明不合理或者無意義的資料所構成的,為了驗證程式做其不應作的事情。
  1. 等價類劃分的優缺點。(答出一些使用過程中的體會即可)

答:優點:考慮了單個數據域的各類情況,避免盲目或隨機的選取輸入資料的不完整性和不穩定性,同時可有效控制測試設計的數量。

缺點:對組合情況考慮不足,同時等價類劃分基於等價類中的輸入都能產生相同的效果,在很多情況下用例選擇不當會產生問題(如邊界)。

  1. 邊界值測試方法的優缺點。

答:長期的測試工作經驗告訴我們,大量的錯誤是發生在輸入或輸出範圍的邊界上,而不是發生在輸入輸出範圍的內部。因此針對各種邊界情況設計測試用例,可以查出更多的錯誤。

不過邊界值分析法與等價類劃分法一樣,沒有考慮輸入之間的組合情況,因此需要進一步結合其他測試用例設計方法。

  1. 等價類劃分的原則(瞭解大概即可,關鍵看是否會使用)

答:等價類劃分的原則如下:

  • 在輸入條件規定了取值範圍或值的個數的情況下,則可以確立一個有效等價類和兩個無效等價類.
  • 在輸入條件規定了輸入值的集合或者規定了“必須如何”的條件的情況下,可確立一個有效等價類和一個無效等價類.
  • 在輸入條件是一個布林量的情況下,可確定一個有效等價類和一個無效等價類.
  • 在規定了輸入資料的一組值(假定n個),並且程式要對每一個輸入值分別處理的情況下,可確立n個有效等價類和一個無效等價類.
  • 在規定了輸入資料必須遵守的規則的情況下,可確立一個有效等價類(符合規則)和若干個無效等價類(從不同角度違反規則).
  • 在確知已劃分的等價類中各元素在程式處理中的方式不同的情況下,則應再將該等價類進一步的劃分為更小的等價類.
  1. 效能測試:如何評價系統的極限效能?

答: 基本點:併發度、響應時間、單位時間吞吐量、系統穩定性、多場景。

加分點:新舊版本對比,效能瓶頸分析方法(雪崩、線性拐點等)。

  1. 判斷測試活動中止的條件

答:從以下幾個角度分析,包括:無新發生bug且嚴重性高的老bug已修復;bug收斂;某一級別bug低於一定比例;時間耗盡;滿足特定覆蓋率。另外,可以說說在以前的專案測試是如何結束的。

  1. 常見測試模型?

答:常見的軟體測試模型包括V模型、W模型、H模型、X模型和前置模型。([注]:具體解釋太長了,見附件1的前幾頁。)

Chap2 測試設計

  1. 配置檔案測試設計

題目:一個程式需要根據配置檔案,將本地的多個檔案(model.0, model.1, model.2…)分發到不同機房的不同機器上去。其中,配置檔案格式如下:

#機房數量

SITE_NUM : 5

#第0個機房機器數量

SITE_0_HOST_NUM : 10

#該機房第n個機器的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

。。。

#檔案數量

MODEL_NUM : 5

#第n個檔案在第m個機房需要的備份數

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

分發要求:一臺機器上不能佈置多份相同的檔案

每臺機器上要求分發的檔案數量儘量均勻

問題:請設計測試用例。

答:各種邊界值;不同機器的IP重複;在某機房的需要的備份數超過了機器數;

  1. 杯子的測試(校招)

答:冒煙測試:速度裝一杯水,是否漏水

功能測試:漏水測試,透明度測試,衛生情況測試,杯口平滑測試,重量測試,均勻度測試

壓力測試:抗摔測試,抗高溫測試

歡迎新增

  1. 描述bs這類模組的功能,設計測試用例【標記】
  2. strstr測試(可以擴充套件到其他函式測試,主要考察邊界,基本情況,魯棒性,效能等方面是否考慮全面,實習生2面)

答:基本情況;邊界值;魯棒性;效能以及其演算法優化;

  1. 請使用等價類劃分的測試方法完成用例設計。

題目: 設有一個檔案管理系統,要求使用者輸入以年月表示的日期。假設日期限定在1990年1月~2049年12月,並規定日期由6位數字字元組成,前4位表示年,後2位表示月。

問題:現用等價類劃分法設計測試用例,來測試程式的"日期檢查功能"。

答:

  • 劃分等價類並編號,下表等價類劃分的結果

輸入等價類

有效等價類

無效等價類

日期的型別及長度

6位數字字元

有非數字字元

少於6位數字字元

多於6位數字字元

年份範圍

在1990~2049之間

小於1990

大於2049

月份範圍

在01~12之間

等於00

大於12

  • 設計測試用例,以便覆蓋所有的有效等價類在表中列出了3個有效等價類,編號分別為①、⑤、⑧,設計的測試用例如下:

測試資料    期望結果      覆蓋的有效等價類

200211      輸入有效      ①、⑤、⑧

為每一個無效等價類設計一個測試用例,設計結果如下:

測試資料   期望結果     覆蓋的無效等價類

95June     無效輸入          ②

20036      無效輸入          ③

2001006    無效輸入          ④

198912     無效輸入          ⑥

200401     無效輸入          ⑦

200100     無效輸入          ⑨

200113     無效輸入          ⑩

  1. CP 命令設計測試用例(5分鐘)

答:主要從異常、功能和效能三方面考慮:

  • 異常

引數異常:源和目標引數異常:包含特殊字元;引數超長;指定的位置實際不存在

拷貝物件異常:非法的執行許可權;儲存介質有損壞;非法的檔案格式和內容

執行過程異常:拷貝到一半斷電;拷貝過程中硬碟滿;拷貝過程中源或目的被刪除

  • 功能
    • 檔案

不同檔案大小:0,1k,10k。。。

不同的檔案型別:文字,二進位制,裝置檔案。。。

  • 目錄

包含各種檔案型別

包含子目錄,目錄深度

目錄檔案數量很多

針對檔案和目錄分別驗證拷貝的準確性,完整性。

  • 效能
    • 場景:

拷貝大檔案

拷貝目錄中存在大量小檔案

跨檔案系統間拷貝

跨儲存介質間拷貝(硬碟到U盤。。。)

構造源的各種磁碟分佈(磁碟扇區分佈。。。)

併發執行拷貝

  • 關注的效能點:拷貝時間, CPU,記憶體,磁碟IO
  1. 如何測試模板(10分鐘)

題目:百度首頁是由模板展現,請問如何對它進行測試;

要求:不需要考慮效能相關因素。建議多從使用者行為和使用環境角度進行測試

(考察點:測試能力+思維繫統性+思維發散性)

答:

展現檢查:文字圖片內容,連結,一致性

資料傳遞:字串長短與截斷;特殊字元;中英文;空格;下拉條提示

相容性檢查:不同瀏覽器,不同作業系統,不同解析度

使用者行為:視窗拉大,放小;字號大小;編碼格式;重新整理;前進後退

  1. 白盒測試對子程式進行測試(15分鐘)

題目:本流程圖描述了某子程式的處理流程,現要求用白盒測試法對子程式進行測試。

要求:根據白盒測試常用的以下幾種方式:語句覆蓋、判定覆蓋、條件覆蓋、判定/條件覆蓋、多重條件覆蓋(條件組合覆蓋)、路徑覆蓋六種覆蓋標準,從供選擇的答案中分別找出滿足相應覆蓋標準的最小的測試資料組並簡述各種測試方法。

供選擇的答案

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:語句覆蓋是指選擇足夠的測試用例,使得執行這些測試用例時,被測程式的每個語句至少被執行一次,語句覆蓋是一種比較弱的覆蓋標準
  • 判定覆蓋A:也稱分支覆蓋,是指選擇足夠的測試用例,使得執行這些測試用例時,被測程式的每個判定的所有可能結果至少出現一次
  • 條件覆蓋B:是指選擇足夠的測試用例,使得執行這些測試用例時,判定中的每個條件的所有可能結果至少出現一次
  • 判定/條件覆蓋F:是指選擇足夠的測試用例,使得執行這些測試用例時,判定中每個條件的所有可能結果至出現一次,並且每個判定本身的所有可能結果也至少出現一次
  • 多重條件覆蓋D:是指選擇足夠的測試用例,使得執行這些測試用例時,每個判定中條件結果的所有可能組合至少出現一次
  • 路徑覆蓋C:是指選擇足夠的測試用例,使得執行這些測試用例時,程式的每條可能執行到的路徑都至少經過一次
  1. Baidu hi 聊天訊息收發的測試思路(10分鐘)

問題:請給出BAIDU hi聊天訊息收發的測試思路?(10分鐘)

(考察點:基本測試思路)

參考答案:主要從以下幾個方面來考察:正常測試、異常測試、不同的訊息型別、組合測試、長度極值、是否延遲、是否丟失、是否被篡改、安全性

  1. 登入介面測試(10分鐘)

參考答案:希望可以對測試點做分類劃分,如功能、UI、效能、安全

  1. 測試自動販賣機 (20分鐘)

題目: 測試自動販賣機,場景:販賣機將用在露天的繁華的大街上

(考察點: 主要考察邏輯思維、思維的發散性)

參考答案: 

大概可以從以下幾個方面來考慮:

  • 考慮到管理員的功能:如新增貨物功能、定價等功能
  • 考慮到介面外觀、使用者說明的
  • 容錯考慮比較多的
  1. 三角形測試(20分鐘)

題目:一個程式,從輸入框中讀取三個整數值,這三個數值代表了三角形三邊的長度。程式顯示提示資訊,指出該三角形究竟是不規則三角形、等腰三角形還是等邊三角形。(注:不規則三角形指三角形中任意兩邊不相等,等腰三角形指有兩條邊相等,等邊三角形指三條邊相等)

要求:假設你將作為一名測試工程師對該程式進行測試,你會採用什麼方法進行測試用例設計?請寫出你採用的方法、測試用例設計的過程以及最後的測試用例。(30分鐘)

(考查點:考察測試思維的嚴謹性,答全難)

參考答案:可以採用等價類劃分的方法進行測試用例的設計。

  • 等價類表:

輸入條件

有效等價類

無效等價類

是否三角形的三條邊

⑴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]

    不能構成三角形

    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]

    ⑶⑷⑸⑹⒀⒇

    1. 較複雜功能程式設計用例(30分鐘)

    程式從標準輸入中讀取,判斷輸入字元是固定電話號碼或者手機號碼

             a) 手機號碼:以13開頭,長度為11的連續數字

             b) 固定電話號碼:固定電話號碼包括區號和號碼兩部分,其中號碼為長度為7或8,並且不以0開頭的連續數字。區號可有可不有。區號和號碼間可有“-”,也可以沒有。

             c) 當用戶輸入完畢後,系統返回的答案包括: 手機號碼 固定號碼 無正確電話號碼

             d) 一次輸入中如果有多個正確號碼(空格為分割符),以最後一個正確號碼的型別為準

    對實現上述功能的程式設計測試用例。(40分鐘)

    區號範圍(x表示任意數字):

    3位區號

    4位區號

    10

    03××

    20

    04××

    21

    05××

    22

    06××

    23

    07××

    24

    08××

    25

    09××

    27

    28

    29

    參考答案: 以下是測試設計的參考思路:

    有空格

    空格在兩頭

    中間有正確電話號碼

    中間無正確電話號碼

    中間無字元

    空格在中間

    一個空格

    最後一個為錯誤手機號

    全部為錯誤手機號

    最後一個為正確手機號

    多個空格

    最後一個為正確手機號

    第一個為正確手機號

    全部為錯誤手機號

    超長字元含空格

     無空格

    只含數字

    以0開頭

    前三位是區號

    區號識別

    前三位非區號

    前四位為區號

    區號識別

    前四位非區號

    非0開頭

    13開頭

    長度為11

    長度非11

    座機號碼

    非座機號碼

    非13開頭

    座機號碼識別

    含數字和-

    一個-

    -前是區號

    -後為座機

    -後非座機

    -前非區號

    -後為座機

    多個-

    含其他字元

    超長字元不含空格

    空輸入

    座機識別

    首位為0

    長度為6

    所有數字均能被識別??

    長度為7

    長度為5

    長度為8

    首位非0

    區號識別

    三位長度

    010開頭

    02開頭

    026開頭

    非026

    非010、02開頭

    011開頭

    030開頭

    四位長度

    03-09開頭

    01

    02

    Chap3 演算法

    1. 請列舉的常用排序演算法,並說明其時間複雜度,並說明排序思想。

    答:

    • 氣泡排序:兩兩比較待排序資料元素的大小,發現兩個資料元素的次序相反時即進行交換,直到沒有反序的資料元素為止。演算法時間複雜度是O(n^2)。
    • 選擇排序:每一趟從待排序的資料元素中選出最小(或最大)的一個元素,順序放在已排好序的數列的最後,直到全部待排序的資料元素排完,演算法複雜度是O(n^2)。
    • 插入排序:每次將一個待排序的資料元素,插入到前面已經排好序的數列中的適當位置,使數列依然有序;直到待排序資料元素全部插入完為止。演算法時間複雜度是O(n^2)
    • 快速排序:在當前無序區R[1..H]中任取一個數據元素作為比較的"基準"(不妨記為X),用此基準將當前無序區劃分為左右兩個較小的無序區:R[1..I-1]和R[I+1..H],且左邊的無序子區中資料元素均小於等於基準元素,右邊的無序子區中資料元素均大於等於基準元素,而基準X則位於最終排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),當R[1..I-1]和R[I+1..H]均非空時,分別對它們進行上述的劃分過程,直至所有無序子區中的資料元素均已排序為止。不穩定,最理想情況演算法時間複雜度O(nlog2n),最壞O(n^2)。
    • 堆排序:堆排序是一樹形選擇排序,在排序過程中,將R[1..N]看成是一顆完全二叉樹的順序儲存結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關係來選擇最小的元素。演算法時間複雜度O(nlogn)。
    • 希爾排序:其實就是用步長控制的插入排序,希爾排序通過加大插入排序中元素之間的間隔,並在這些有間隔的元素中進行插入排序,從而讓資料項可以大幅度移動,這樣的方式可以使每次移動之後的資料離他們在最終序列中的位置相差不大,保證資料的基本有序,大大提升了排序速度,運算時間複雜度N*logN。
    • 歸併排序:

    Divide: 把長度為n的輸入序列分成兩個長度為n/2的子序列。

    Conquer: 對這兩個子序列分別採用歸併排序。

    Combine: 將兩個排序好的子序列合併成一個最終的排序序列。

    時間複雜度是O(nlog2n)。

    1. 快速排序的平均時間複雜度是多少?最壞時間複雜度是多少?在哪些情況下會遇到最壞的時間複雜度。

    答:

    快速排序的平均時間複雜度O(nlog2n),最壞時間複雜度O(n^2)。

    最壞情況:當每次pivot選擇恰好都把列表元素分成了(1,n-1)

    採取措施:pivot的選取是通過random來進行

    1. 各個排序演算法的穩定性,並給出理由。

    答:

    選擇排序、快速排序、希爾排序、堆排序不是穩定的排序演算法,而氣泡排序、插入排序、歸併排序和基數排序是穩定的排序演算法。

    1. 兩個單項鍊表求交點。

    單向連結串列有交點意思是交點後的節點都是一樣的;因此,如果兩個單向連結串列相交,是成Y字形的。

    思路:求出第一個連結串列長m,第二個長n。假設m>=n,那麼就去掉第一個連結串列的前m-n個元素,使之等長,然後依次比較第一個、第二個、第三個元素,直到找到或者結束。

    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;        //如果尾節點不同,直接返回 NULL

        }

        else                   //否則尋找第一個相同的節點

        {

            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;

            }

        }

    }

    1. 遞增數列中每一項都可以表示為3^i*5^j*7^k(0<=i,j,k),即1,3,5,7,9,15,21,25,27…,實現演算法,求出該數列中的第n項

    答:

    先放置幾個佇列:

    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放入三個佇列的首位。準備一個新佇列L(目前為空)。

    Step2: 比較三個佇列的頭,找出最小的那個。把這個元素從隊列出隊,並加到L的尾部。

    Step3:

    如果Step2中的元素是從L1中獲取的,假設是3^m,則在L1的尾部加入3^(m+1),L2的尾部加入3^m*5,L3的尾部加入3^m*7。

    如果Step2中的元素是從L2中獲取的,假設是3^m * 5^n,則在L2的尾部加入3^m * 5^(n+1),L3的尾部加入3^m * 5^n *7。

    如果Step3中的元素是從L3中獲取的,假設是3^m * 5^n * 7^p,則在L3的尾部加入3^m * 5^n * 7^(p+1)。

    Step4: L的長度到達N了嗎?如果沒到達,重複L2-L4。如果到達,則進行L5。

    Step5: 取得L的末尾元素,即為所求。

    1. 為二叉樹中每一個節點建立他的右鄰居節點(可以不屬於同一個父節點),要求遞迴與非遞迴都實現,如

                    A

                  /   \

              B  -----> C

            /           /  \

          E-----> F -> G

    答:

    • 遞迴:

    buildRightSibling(Linkedlist list)

    {

      Linkedlist nextlevel = new Linkedlist();

      把list中的每個元素的子節點,放入nextlevel中。

      //list中每個元素,設定右鄰結點,指向list中的下一個元素

      //這一步可以在連結串列中就實現掉。

      If(nextlevel == null || nextlevel.length() ==0)

        Return;

      Else

    buildRightSibling(nextlevel);

    }

    //啟動函式

    buildRightSibling(new Linkedlist(root));

    • 非遞迴

    層序遍歷每一層,對每一個元素都打上標記。比如(1,1)代表第1層第1個元素。

    所有元素都打上標記以後,對每個元素(m,n)都尋找(m,n+1)元素

    1. 走臺階問題,一次可以走1,2,3級,都N級臺階的方法數。

    答:

    初始:f(0) = 0;  f(1) =1;  f(2) = 1 + 1 = 2;

    遞推公式:f(n) = f(n - 1) + f(n-2) + f(n - 3)

    1. 10進位制數轉2進位制數,

    題目:2進位制除了0,1,還可以用2表示。例如:

    1-> 1

    2-> 10 or 02

    3->11

    4 ->100 or 020 or 012

    問題:這樣一個十進位制數轉為二進位制數,就不是唯一的了。現求十進位制數N轉換為這種二進位制數的所有表示方法數。

    答:

    f(0)=1, f(1)=1, f(2)=2,

    f(n) = f( (n-1)/2) 當n為奇數

           = f(n/2)+f((n-2)/2 )當n為偶數

    1. 一個環狀連結串列(收尾相連),兩個指標head1head2從同一個節點出發,head1每次走一步,head2每次走兩步,請證明,兩個指標第一次相遇於出發的節點

    答:

    設兩個指標走的次數為x,使用簡單的數學公式即可證明。難度1面。考察基本的數學 知識。

    設連結串列有m個元素,head1在第一次相遇時走了n步,c為head1和head2第一次相遇的節點距離出發節點的距離。

    則: head1走過的路程為 c = n;

    head2走過的路程為 c + k *m = 2n; (k為整數)

    因此,c = k*m,即c恰好是連結串列長度的整數倍,即兩個指標第一次相遇一定是在出發的節點。

    1. 一個連結串列中含有環。請找出環的起始節點

    答:

    方法1: 使用標記法,走過的節點標記1。使用這種方法,需要時間/空間複雜度O(n)

    方法2: 使用第6題的思路,設兩個指標走的次數為x即可得到,時間複雜度不變,但空間 複雜度為O(1)。難度1面,考察能否使用已經掌握的知識(第一題)來求解。

    讓兩個指標head1和head2從同一個節點出發,head1每次走一步,head2每次走兩步,當二者重合時,讓head2回到連結串列的頭部,以每次一步的步長走,當head1和head2再次相遇時,就是環路的起始節點了。

    1. 給定N個數,其中有一個數的出現次數超過N/2,請找出這個數,O(n)演算法

    (考察點:該數出現次數超過其他所有數出現次數總和,使用計數方式解答。難度:2面)

    答:

    解法1: 開一個新的列

    比較第1,2個數字。如果相同,則放入新的列中 如果不同,則兩個都丟棄

    然後比較第3,4個數字,5,6個數字

    這個時候 新的列 最長為n/2 (實際上會遠遠更短)

    然後對新的列 如法炮製 再次縮短一半

    當某個時刻 列的長度是1或者列突然消失時候 結束

    長度為1 說明這個就是的。消失,說明不存在大於n/2的個數的數

    解法2:

    構造一個hashtable,其中key是這個N個數的值,而value則是他們出現的次數;

    最後遍歷這個hashtable,找出最大的即可。[ZhaiYao: 這個方法應該不好。不應該使用hashtable]

    1. 最長連續子序列之和(和最接近0的子序列),環形陣列的最大子序列和。

    答:

    環形的拼成2n的陣列後求解。

    最長連續子序列之和:掃描陣列,從左到右記錄當前子序列的和ThisSum,若這個和不斷增加,那麼最大子序列的和MaxSum也不斷增加(不斷更新MaxSum)。如果往前掃描中遇到負數,那麼當前子序列的和將會減小。此時ThisSum 將會小於MaxSum,當然MaxSum也就不更新。如果ThisSum降到0時,說明前面已經掃描的那一段就可以拋棄了,這時將ThisSum置為0。然後,ThisSum將從後面開始將這個子段進行分析,若有比當前MaxSum大的子段,繼續更新MaxSum。這樣一趟掃描結果也就出來了。

    和最接近0的子序列:【標記】

    環形陣列的最大子序列之和:將環形陣列首尾拼接成一個2n的線型陣列(如環形陣列 0 1 2, 可以拼接成 0 1 2 0 1 2),按1)的方法可以找到最大連續子序列之和

    1. 字串按字母a-z排序

             題目要求:

              (1)不是用排序庫函式;

              (2)程式碼實現;

              (3)演算法複雜度估算;

              (4)測試自己的程式碼;

              (5)能否用另一種排序方式,比較優缺點;(plus)

    答:

    1char *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. 演算法複雜度:輸入為一個n個字元的字串,則複雜度為O()

    3. 另一種排序演算法:快排,複雜度O(nlgn) [ZHAIYAO:可不可以用另一種方式?開一個26長的陣列,記錄每個字母出現的次數。然後根據這個記錄,重新列印(構造)出來排序後的字串]

    1. 已知一個亂序的整數陣列,求該陣列排序相鄰兩數的最大間隔,要求時間複雜度為O(n)

    例如:給定陣列為10 23 7 1 35 27 50 41

    排序後的結果為:1 7 10 23 27 35 41 50

    相鄰兩數的最大間隔為13(10-23)。

    遍歷找到數列找到最大最小值(max,min),則所求的gap>=(max-min)/n,以(max-min)/n為步長建立k個桶,每個桶記錄落入桶內的最大最小值,順序比較各個桶之間的最大gap。

    答:

    用基於桶排序的方式,具體如下:

    先找到最小和最大,分別記為min和max,並設avg=(max-min)/n

    按照avg的大小將[min,max]分配(N-1)個桶

    將陣列中的數存入桶中

    然後按順序對每個相鄰桶(跳過沒有數的桶)進行比較,如相鄰桶(a, b)(c, d)的距離D=c-b

    最終比較D的最大值,則為所求

    1. 求兩個相同大小已排序陣列的中位數

    題目:設a[0..n-1]和b[0..n-1]是兩個已經排好序的陣列,設計一個演算法,找出a和b的2n個數的中位數。要求給出演算法複雜度(O(lgn))。

    答:

    設a[0..n-1]的中位數是m1,b[0..n-1]的中位數為m2

    如果m1=m2,則m1則為2n個數的中位數

    如果m1>m2,則2n個數的中位數一定在a[0..2/n]和b[n/2..n],在求這兩個子陣列的中位數

    如果 m1<m2,則2n個數的中位數一定在a[n/2..n]和b[0..2/n],在求這兩個子陣列的中位數

    1. 已知一個數組a1, a2, ..., an, b1, b2, ..., bn,設計一個演算法把陣列變成a1, b1, a2, b2, ..., an, bn。

    答:

    如果 n = 2k,   則 C(k) =

    如果 n = 2k+1, 則 C(k) =

    ZhaiYao: 綜合考慮時間和空間。時間O(n)應該沒辦法降低了,覺得空間可以達到是O(1)。但是沒想出來演算法,【標記】

    1. 全排序演算法

    全排序演算法就是列舉一些字元的所有排列順序。

    void Perm(char list[], int k, int m)

    { //生成list [km ]的所有排列方式

      int i;

      if (k == m) {//輸出一個排列方式

        for (i = 0; i <= m; i++)

          putchar(list[i]);

        putchar('\n');

      }

      else // list[km ]有多個排列方式

        // 遞迴地產生這些排列方式

        for (i=k; i <= m; i++) {

          Swap (&list[k], &list[i]);

          Perm (list, k+1, m);

          Swap (&list [k], &list [i]);

        }

    }

    Chap4 設計題[標記]

    1. 多執行緒鎖機制設計

    在多執行緒程式設計中,對臨界資源,經常需要lock(),unlock()這樣的操作,但是經常在lock之後忘記unlock,造成多執行緒問題。現在用C++類的思想實現一個scopelock類(校招)

    例如:

    {

    lock()

    ……

    unlock()

    }

    這種使用模式變成

    {

    Scopelock()

    }

    (在建構函式和虛構函式中實現lock和unlock)

    1. 設計Spider

    題目:Spider抓取能力一天10w個url,網際網路每天新增1000w個url  (社招)

    這1000w個都是新增的url,spider怎麼選取10w個進行抓取,選優的準則

    這1000w個有些是抓取過的,存在歷史抓取資訊,spider怎麼選取10w個進行抓取,選優的準則。

    1. 海量url除重(spilt&merge的思想,主要看候選人的思路,2面)

    答:

    在獲取URL的時候按照一定數量分組,然後分別在每組用URL的sign作為key,用awk以key為標來構造陣列;最後把每組過濾過的結果在merge起來過濾。

    1. 給定一個file,包含各類url,統計出現次數topN的url

    答: sort|uniq -c|sort -nr|head

    1. 多路陣列交集

    題目:有十路陣列,陣列元素組成為:{int id, unsigned int weight},每路陣列內id、weight均為無序

     要求:如何求出這十路陣列的交集(交集:id相同),並將交集內的元素按照weight排序?給出思路和複雜度;如果原始的十路陣列中的id均為有序的,又該如何做?給出思路和複雜度;

    1. 兄弟單詞索引

    題目:dog和god這類字母出現的次數和種類都完全一樣的字串稱為兄弟單詞,現在有海量的字串,設計檢索系統,支援查詢使用者輸入字串的所有兄弟單詞。

    1. 死鏈監測設計

    題目:網際網路上每天有大量的網頁成為死鏈,如何用最小的代價降低搜尋引擎的死鏈率。

    (考察其工程思維能力,包括相關死鏈反饋、使用者點選檢查、利用外掛資料、站點穩定性等等)

    1. 使用者經常會輸錯query,如何糾錯

    參考答案:發散問題,常見輸入法錯誤、缺字多字編輯距離判斷,使用者session挖掘等等

    Chap5 邏輯題

    1. 一天,harlan的店裡來了一位顧客,挑了25元的貨,顧客拿出100元,harlan沒零錢找不開,就到隔壁飛白的店裡把這100元換成零錢,回來給 顧客找了75元零錢。過一會,飛白來找harlan,說剛才的是假錢,harlan馬上給飛白換了張真錢,問harlan賠了多少錢(低)?

    答:

    方法A:

    • 列出每筆交易的收入和支出,給分
    • 答出結果,陪100元,給分

    方法B:

    • 直接從結果出發,如果沒有假錢,不賺不虧,給分
    • 由於收入100假錢,賠100,給分
    1. 5只貓5分鐘捉5只老鼠的速度計算,要在100分鐘內捉100只老鼠,需要多少隻貓(低)

    答:5只貓

    方法A:

    • 算出每隻貓每分鐘的捉鼠能力,給分
    • 算出答案,給分

    方法B:

    • 把5只貓看為整體,整體每分鐘的捉鼠能力,給分
    • 算出答案,給分
    1. 一副撲克牌54張,紅黑各一半,從裡面任意翻兩張,一紅一黑的可能性是多少(低)

    答:27/53

    1. 一隻手錶100元買進,110元賣出;120元又買進,130元再賣出,問共賺了多少錢(低)

    答:賺20元

    1. 有一牧場,已知養牛27頭,6天把草吃盡;養牛23頭,9天把草吃盡。如果養牛21頭,那麼幾天能把牧場上的草吃盡呢?並且牧場上的草是不斷生長的(中)

    答:12天

    1. 列出2個已知方程和一個求解方程,給分

    2. 算出答案,給分 假設牧場的草為1單位,每天生長x單位,每個牛每天吃y單位

    27y*6-6x=1

    23y*9-9x=1

    解得:y=1/72, x=15/72 [得一半分]

    21頭牛,就是1/(21y-x)=12天 [得滿分]

    1. 4個人進入餐廳前都把自己的帽子交給寄存部的小姐儲存。當他們一起離開時粗心的小姐把那4頂帽子隨便的戴在每個人的頭上。發完帽子以後大家發現沒有一個人 戴的是自己的帽子。請問這種情況發生的概率是多少?如果是n個人呢(n>1) (中)

    答:

    【4人時候,答案是9/24。9種可能分別是2143,4123,3142,3412,4312,2413,4321,3421,2341)】

    【n人時候,解法如下】

    解法1:

    n人時候,運用容斥原理的高階形式求解。【想到容斥原理就給出一半分數】

    zhaiyao:本科的離散數學課程,本帽子題目是一個例題。我做助教的時候背熟了。。。

    設人站成一排,第1個的帽子設為帽子1,第i的人的帽子設為帽子i。

    設帽子i戴在人i的頭上(其他人無所謂)的情況數為Ai

    那麼很明顯有|Ai| =(n-1)! ;

    i和j同時帶對(不考慮其他人對不對)情況是 |Ai ∩Aj| = (n-2)! ;

    i和j,k同時帶對(不考慮其他人對不對)|Ai ∩Aj ∩Ak | = (n-3)!

    問題問沒有一個人帶對帽子,問題的反面就是問“存在至少一個人戴對帽子”

    “存在至少一個人戴對帽子”的情況數為:|A1∪A2∪...∪An|

    根據容斥原理,

    |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! 【得到答案得到全部分數】

    形象點就是:

    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的情況。然後進行數列規律解析,猜測出來最終表示式1/2!-...+(-1)^(n-1)*1/n!。

    【如果只能列出n=2,3,4等情況,建議不給分,因為這個思路很容易想。

    但是能夠找到規律並猜測出表示式,建議給三分之二或者四分之三的分數。因為這個數列規律很不好找。但是這種思路一定不給滿分,因為沒有嚴格的推理過程】

    1. 甲、乙、丙每人出兩元共六元買了一個收音機,然後就一起離開了商店,和他們一起去的丁因有事沒有離開,這時售貨員發現收音機的售價應該是五元,就把那一元 錢退給了丁,丁回去時坐車花了4角,然後把剩下的6角分給了甲、乙、丙三人各2角,這時算帳甲、乙、丙每人花了1.8元,加上丁坐車花的4角,是5.8元,那剩下的兩角錢哪兒去了(中)

    答:

    甲乙丙每人花了1.8元,但丁坐車沒有花4角(丁自己沒有錢),甲乙丙花的錢裡面,已經包含了丁的錢

    這題無法根據中間過程給分,不推薦

    【ZhaiYao:這題有點混淆概念,可以看出來一個人在混亂時候腦子能不能反應過來,分析清楚各種關係。解釋