天天看點

2016屆360公司PHP服務端開發筆試和面試之所得所感

        這是一篇叙述自己在360公司參加筆試和面試的過程,可能面試的職位并不是你所學的方向,但是如果你能從中學到些什麼或者吸取我的教訓,那麼作者就非常知足了。本着"學習别人是怎麼失敗的,活着出來的人才能成功"的目标,我從三個方面進行叙述:

        第一部分:360公司筆試題

        第二部分:面試過程

        第三部分:注意事項及心得體會

        同時,真心感謝360公司,我非常向往的一個公司。也非常感謝給我面試的那位大哥,讓我真的學到了很多東西。所有題目版權歸360所有,如果有不适的地方請告知我删除或修改。總之我認為:有的時候了解别人失敗的案例比你總看别人成功的例子對你的幫助更大。看了下面我的大學畢設,你就會知道為什麼我這麼推崇這個公司了。

2016屆360公司PHP服務端開發筆試和面試之所得所感

面試時間:2015年9月16日

        面試崗位:PHP服務端開發工程師

        職位要求:精通PHP/Python語言文法、掌握MySQL,基本了解Redis和MongoDB等各種DB、掌握HTML/CSS等。

        題目難度:較難,選擇題考得比較廣,程式設計題一道極為簡單一道比較複雜。

        PS:因為當時題目都是一邊做一邊在草稿紙上抄的,可能有遺漏的地方,請海涵~

(一) 單選題:

1.MySQL存儲過程的優點:

某選項可以多次調用、修改,網絡負載降低

2.找出/etc/my.conf檔案屬于哪個包(package),執行:

       A.rpm -qf /etc/my.conf                B.rpm -q /etc/my.conf

       C.rpm -q | grep /etc/my.conf       D.rpm -requires etc/my.conf

題解: 該題考察linux,答案是A。其中-f Query package owning FILE,賽馬網:

       -ivh:安裝顯示安裝進度--install--verbose--hash 

        -Uvh:更新軟體包--Update; 

        -qpl:列出RPM軟體包内的檔案資訊[Query Package list]; 

        -qpi:列出RPM軟體包的描述資訊[Query Package install package(s)]; 

        -qf:查找指定檔案屬于哪個RPM軟體包[Query File]; 

        -Va:校驗所有的RPM軟體包,查找丢失的檔案[View Lost]; 

        -e:删除包

3.下面代碼的運作結果:

        A.1                    B.警告,沒定義a::$myvar

        C.2                    D.一個錯誤,沒定義a::$myvar

4.以下代碼能正确顯示圖檔的是:

PS: 由于4段代碼,僅僅手抄了B答案,僅供參考

5.下面的腳本輸出值為多少:

       A.5       B.2      C.10       D.NULL

         $b=$a的指派,僅僅是建立一個連結,指派後對$b的修改會影響$a。

6.Person類執行個體化(new)一個對象$p,那使用對象$p調用Person類中getInfo方法:

        A.$p->getInfo()                B.this->getInfo()

        C.$p::getInfo()                   D.$p=>getInfo()

題解:A,常用的考察PHP類定義調用方法的問題。

7.下列關于工廠方法factory叙述正确的是那個:

8.R=(A,B,C)與SQL語句select distinct A from R where B=17等價關系代數表達式:

         A.πA(σB=17(R))           B.σB=17(πA(R))

         C.σB=17(πA,C(R))     D.πA,C(σB=17(R))

題解:其中select語句對應σB=17(R),而Select distinct A為消除重複,答案為A.

        投影操作π是一個關系操作,所謂的出現重複行是指多個記錄在投影屬性上具有相同的取值,例如參考百度百科:

                      學号    姓名    性别    年齡

                       01       艾倫    男        17

                       02      三笠     女        17

                       03      阿明     男        17

        在性别和年齡兩個屬性上投影後資料集隻保留這兩個屬性列,結果如下:

                      性别    年齡

                       男        17

                       女        17

        其中第一行和第三行就是重複行,雖然來自不同記錄,但是這兩個屬性上的内容相同。需要消除相同的行(SQL語句預設不消除重複),最後結果就是:

9.計算機cache,一主存層次采用相聯映射方式,塊大小為128位元組,cache容量64塊,按4塊分組,主存容量為4096塊,主存位址共需______位。

題解:由于主存容量為4096塊,而每塊為128個字,主存的總容量為512K字,故主存位址應為19位。主存位址應分為區号、組号、組内塊号、塊内位址号。可以看到,塊内位址号應為7位,用以表示128個字。一組為4塊,則組内塊号用2位表示。Cache容量為64塊共分16組,故組号需要用4位位址表示。剩餘的即為區号,主存區号應為6位。|

10.下列代碼的運算結果為多少:

        var a = new Array(2,3,4,5,6);

        var sum=0;

        for(i=1;i<a.length;i++)

        sum+=a[i];

        document.write(sum)

題解:計算3+4+5+6=18

11.document對象的是:

       A.form      B.link       C.三項都是      D.anchor

答案:C

12.mysql資料庫還原指令是:

題解:恢複、備份資料庫備份資料庫shell

> mysqldump -h host -u root -p

13.求下列代碼的時間複雜度,more than one answer is correct, choose the smallest one (     ).

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

             for(j=1; j<=m; j*=2)

                  for(z=j/2; z<j; z++)

其中某項答案:O(n*log(m)*m)

14.HTML5庫抛棄了:

        A.form     B.applet     C.frame      D.center

題解:html5不再使用fram,答案C。不再用frame、noframes和frameset,這些标簽對可用性産生負面影響。HTML5中不支援frame架構,隻支援iframe架構,或者用伺服器方建立的由多個頁面組成的符合頁面的形式,删除以上這三個标簽。

15.HTML5中,input元素type屬性預設值為:

        A.search    B.hidden     C.text        D.form

題解:預設應該是text

16.下列代碼的輸出結果是:

         A.24     B.17      C.72      D.36

題解:感覺lambda表達式替換 2*2=4 4*3=12 12*2=24,應該輸出A。Right?

17.不是動态規劃算法基本要素的是:

        A.馬爾可夫性     B.建表填       C.運用子項疊代    D.最優子結構

答案:A

18.不要求最優子結構的是:

        A.分治法      B.貪心         C.動态規劃        D.回溯

答案:D

19.下列叙述正确的是:

PS:太長記不下來了

20.設有N堆沙子排成一排,其編号為1,2,3,…,N(N<=100)。每堆沙子有一定的數量。現要将N堆沙子并成為一堆。歸并的過程隻能每次将相鄰的兩堆沙子堆成一堆,這樣經過N-1次歸并後成為一堆。找出一種合理的歸并方法,使總的代價最小:

PS:答案沒記錄下來,但是這是典型的動态規劃問題。

21.下列不是分治法所能解決的問題特征是:

        A.子問題的解無後效性

題解:隻能懷疑答案是A,因為其它選項忘了,請見諒!分治法通常分為"分解-解決-合并"三個步驟,其中若幹小規模的問題是可以解決的子問題,即具有最優子結構性質;最後将各個子問題的解合并為原問題的解。

22.<div><a href="http://www.360.com">360</a></div>紅色連結不正确的是:

        A.a:link{color:red}

題解:該題考察網頁基礎知識,包括CSS定義超連結顔色等。A答案肯定正确,比較考察實際應用。

23.下列不屬于結構性僞類的是:

        A.E:root       B.E:enabled      C.E:first-child     D.E:empty

24.TCP連接配接,socket調用recv函數傳回值為0表示:

        A.對端發送了一段長度為0的資料

        B.對端關閉了連接配接

        C.還沒有收到對端資料

        D.連接配接發生錯誤

題解:答案B。如果recv函數在等待協定接收資料時網絡中斷了,那麼它傳回0。預設 socket 是阻塞的。阻塞與非阻塞recv傳回值沒有區分,都是:

           <0 出錯 =0 連接配接關閉 >0 接收到資料大小。

25.需對檔案進行随機存取,下列哪種檔案實體結構不适合上述應用場景?

        A.順序檔案      B.索引檔案      C.連結檔案      D.Hash檔案

題解:答案C。鍊式存儲結構的存儲位址不一定連續,無法通過計算位址實作随機通路,隻能順序通路。如果要随機通路的話隻能順序查找,效率低下。

26.關于int *const ptr叙述正确的是:

        A.ptr不可修改,*ptr可修改

        B.ptr可以修改,*ptr可修改

        C.ptr可以修改,*ptr不可修改

        D.ptr不以修改,*ptr不可修改

          對于 int *const ptr 沒有const關鍵字時為int* ptr,此時ptr是指向int的指針。加上const後,const修飾并封鎖ptr ,即ptr的指向不可改變。

          同理 int const* ptr(等同 const int *ptr)  。const修飾 *  解引用,即指針指向的内容不可改變。

27.下列錯誤的用法是:

PS:其中某個答案為 D.typedef void (*FUN)()

28.下面代碼fun(21)輸出值多少:

      int fun(int a) {

           a^=(1<<5)-1;

           return a;

      }

題解:首先(1<<5)表示左移5位,相當于1乘以2的5次方,即100000=32。

          然後是異或運算:

          21=010101   ^     31=011111     =》    001010=10,結果為10。

29.sort的template正确的寫法是:

        A.void sort(class A first,class A last,class B pred)

        B.void template(class A,class B)sort(A first,A last,B pred)

        C.template<class A><class B> void sort(A first,A last,B pred)

        D.template<class A,class B> void sort(A first,A last,B pred)

         函數模闆的聲明

         模闆函數格式是先聲明模闆類型,然後才能使用。 函數模闆可以用來建立一個通用的函數,以支援多種不同的形參,避免重載函數的函數體重複設計。它的最大特點是把函數使用的資料類型作為參數。

         函數模闆的聲明形式為:

         template<typename 資料類型參數辨別符>

        <傳回類型><函數名>(參數表)

        {

            函數體

        }

        格式 template<class T1, class T2, ...> 傳回值 函數名(參數清單){//函數體}

30.16位機器,浪費多少空間?

        struct {

            char a;

            int b;

        A.8           B.4          C.6         D.2

題解:答案D。16位機器,char型占1位元組,int型占2個位元組。資料自動對齊,實際結構體:1(char)+1(補齊)+2(int)+1(char)+1(補齊)=6位元組,浪費2個位元組空間。

31.一道關于A[m][n]數組處理的題目:

PS:答案好像有644、676、696等。

32.關于C/C++宏定義錯誤的叙述是:

        A.宏定義不檢查參數正确性,會有安全隐患

        B.宏定義的常量更容易了解,如果可以使用宏定義常量的話,要避免使用const常量

        C.宏的嵌套定義過多會影響程式的可讀性,而且很容易出錯

        D.相對于函數調用,宏定義可以提高程式的運作效率

         使用const比使用define有一下幾種好處:

        (1)const會進行資料類型檢查,而define不會

        (2)const存儲在符号表\常量區,表示值不能修改

33.下列值為多少:1^2^....^100

題解:答案100,python代碼如下圖所示:

2016屆360公司PHP服務端開發筆試和面試之所得所感

34.下列關于繼承錯誤的是:

        A.隻能公有繼承,不能私有繼承

        B.派生類可以通路基類protect成員

        C.一個基類可以繼承多個派生類,一個派生類可繼承多個基類

        D.基類中至少有一個虛函數可構成多态

35.下列代碼的輸出值為多少:

        int main(int argc, char **argv)

               int a[4] = {1, 2, 3, 4};

               int *ptr = (int *)(&a + 1);

               printf("%d", *(ptr - 1));

        A.3        B.1        C.2        D.4

          考察對于數組和指針的認識,指針加一的能力由類型決定。int*ptr=(int*)(&a+1);  &a 和a 都指的是數組首元素的位址。不同的是a就是a+0 ,*(a+0)就是a[0],而&a+1相當于a[]數組類型的指針加1,此時指針加到數組的末尾。ptr接受後,由于Ptr的類型是int* 是以ptr-1即回退4位元組。即指到最後一個元素。

2016屆360公司PHP服務端開發筆試和面試之所得所感

36.下列可作為對象繼承之間的轉換的是:

        A.static_cast

        B.dynamic_cast

        C.const_cast

        D.reinterpret_cast

題解:答案B。

          dynamic_cast:在基類和派生類之間的轉換,繼承體系安全向下轉型或跨系轉型,找出某對象占用記憶體的起始點。static_cast:同舊式C轉型,如int 到double。const_cast:常用于去除某個對象的常量性。reinterpret_cast

不具備移植性,常見用途是轉化函數指針類型。

37.下列是獲得執行個體化對象所屬類名字的函數是:

        A.get_class_methods()

        B.get_class()

        C.get_classname()

        D.get_object_vars()

題解:答案B。PHP中沒有get_classname()函數,其他如下:

        get_class — Returns the name of the class of an object

        get_object_vars — Gets the properties of the given object

        get_class_methods — Gets the class methods' names

(二) 程式設計題:

1.電腦的新功能

可視化程式設計一個新功能的電腦,輸入一個數時,能将這個數分解為一個或多個素因子乘積的形式,并按素因子的大小排列顯示出來,0-9這十個數字表示如下:每個數字占5*3大小的字元區域。

輸入:多組測試數n(n<=1,000,000)

輸出:每個數分成若幹個素數乘積形式,從小到大輸出。素因子之間用"*"形式連接配接。

例:

輸入:

       10

       2

輸出:

首先需要計算素數組成,然後難點是怎樣将數字一次性從上往下顯示出來。

2.研究所學生考試

政治100分,英語100分,數學150分,專業課150分。政治、英語要求單科不低于60分,數學、專業課要求單科不低于90分,總分不低于310分。總分350以上(含350)為公費,310-349分為自費。

請程式設計判斷考生情況。

輸入:正整數N,表示N組測試資料。每組4個正整數分:政治、英語、數學、專業

輸出:Fail/Zifei/Gongfei

3

61 62 100 120

80 80 120 100

55 90 130 130

Zifei

Gongfei

Fail

PS:該題目比較簡單,基本為送分題。同時希望該部分題目對你有所幫助!再次聲明,此部分為我一邊做題一邊抄在紙上,是以有些遺漏的地方,請原諒~

        面試時間:2015年10月9日

        面試部門:伺服器端開發

        面試地點:360大廈

        面試時長:100多分鐘

        PS:過程中可能存在一些遺漏的地方,但是還是非常感謝那個面試的哥哥,今天都還覺得給人很舒服的感覺。同時因為間隔時間太長,最近也太忙,不準備采用對話方式進行,而是分幾個步驟進行簡單叙述。

        第一部分 自我介紹

        1.首先簡單問候面試官并遞上自己的履歷,然後做個自我介紹;

        2.面試官通過我的履歷,讓我介紹自己最拿得出手的項目,我介紹的是知識圖譜相關的項目,包括:傳統搜尋引擎的工作原理、知識圖譜概念(舉例姚明身高、梁啟超關系查詢)、實體消歧與實體對齊、采用的VSM向量模型及聚類算法;

        3.面試官問我該階段主要熟悉什麼語言?我說現在做得最多的是Python,以前是C/C++,當然Java、C#、PHP都做過,畢竟語言都有通性,但是想精通還是難。

        4.他說PHP比較簡單,他們是做底層伺服器方向的,今天的面試主要是問Unix相關知識;我也贊同這個觀點,因為PHP可以通過一些開源架構實作,同時也問了些自己做的WAMP網站。

        第二部分 Unix為主

        1.面試官首先問我是否做過Unix相關的東西?我說自己就簡單做過Linux下的Python爬蟲、腳本等。

2.然後問了Unix下的網絡程式設計會不會?我簡單介紹了Python的網絡程式設計TCP\UDP的過程,主要的三次過程如下,同時Socket其他語言過程基本類似。

        伺服器:

             ss = socket()                # 建立伺服器套接字

        ss.bind()                   # 位址綁定到套接字上

        ss.listen()                      # 監聽連接配接

             inf_loop:                       # 伺服器無限循環

                  cs = ss.accept()       # 接受用戶端連接配接 阻塞式:程式連接配接之前處于挂起狀态

             comm_loop:                 # 通信循環

                  cs.recv()/cs.send()   # 對話 接受與發送資料

             cs.close()                      # 關閉用戶端套接字 

             ss.close()                      # 關閉伺服器套接字 (可選)

        用戶端:

        cs = socket()                 #

建立用戶端套接字

             cs.connect()                  #

嘗試連接配接伺服器

             comm_loop:                 # 通訊循環

                  cs.send()/cs.recv()    # 對話 發送接受資料

             cs.close()                       #

關閉用戶端套接字

         3.然後他又問如果用戶端出現異常,伺服器怎樣捕獲這個異常呢?我當時想了下,提出了伺服器可以設定一個時間點(心跳),當某段時間沒有接受到該用戶端的封包,則表示斷開連接配接或異常錯誤。他又問我能不能把這段recv()函數寫出來。我說不太會。

         PS:回來後想了想,當時是不是在考察recv()函數的傳回值: >0獲得封包長度, =0用戶端斷開連接配接,<0連接配接發生異常錯誤。但确實自己也不會Unix下的網絡程式設計。

         4.面試官又問了些Unix下的fork相關的知識,我說沒有接觸過。還有些英文不知道是什麼,自己英語太差了~

        第三部分 算法和資料結構

        1.面試官說:“你資料結構和算法應該很熟悉了吧!”我說:“還行,但是也忘記很多了。”自己确實很多基礎知識都忘了很多,擔心回答不上來。

        2.面試官給我一張紙,有兩段很長的代碼(C語言),讓我尋找兩代碼的差別。

        這兩段代碼的主要差別就是參數一個是int,一個是double,當然前面還定義了些結構,代碼裡面的内容基本類似,相當于一個int型排序,一個double型排序。

        他問我平時肯定會遇到這種情況,寫兩個函數代碼過于備援,怎樣提煉成實作兩種不同的類型排序,而且類型可以是float、結構體等等。

        我說這有點類似于C++的模闆啊!如果是C++就簡單了,但是C語言主要是怎樣判斷這個類型呢?

        PS:後來回來想了想,感覺類似于qsort快速排序的那種寫法,通過const void *a實作,不知道是不是。但有同學懷疑是不是考察##的連接配接用法。

        int型快排

        int cmp1(const void *a, const void *b)  

        {  

               return *(int*)a - *(int*)b;  

        } 

        qsort(num, len, sizeof(int), cmp1);

        double型快排

        int cmp(const void *a, const void *b)  

            return *(double*)a > *(double*)b ? 1 : -1;  

        }  

        qsort(num, sum, sizeof(double), cmp); 

        char型快排

        int cmp(const void *a, const void *b)  

             return *(char*)a - *(char*)b;  

        }   

        qsort(str, sum, sizeof(char)*10, cmp);

        3.上面代碼沒有寫出來,那麼你就做個最簡單的吧!二叉樹中序周遊非遞歸實作。

        他又問我以前是怎麼做的?我說通常都是三句話遞歸,這個題主要是考察通過棧模拟二叉樹周遊遞歸的過程,然後寫代碼中。我失誤了,棧寫成隊列了,然後隊列是先進先出,又通過兩個隊列(一個輸入隊列、一個輸出隊列)模拟了一個棧實作了非遞歸周遊。

        遞歸代碼

        非遞歸周遊

        根據中序周遊的順序,對于任一結點,優先通路其左孩子,而左孩子結點又可以看做一根結點,然後繼續通路其左孩子結點,直到遇到左孩子結點為空的結點才進行通路,然後按相同的規則通路其右子樹。是以其處理過程如下:

        對于任一結點P,

        1)若其左孩子不為空,則将P入棧并将P的左孩子置為目前的P,然後對目前結點P再進行相同的處理;

        2)若其左孩子為空,則取棧頂元素并進行出棧操作,通路該棧頂結點,然後将目前的P置為棧頂結點的右孩子;

        3)直到P為NULL并且棧為空則周遊結束

        如下圖所示:

2016屆360公司PHP服務端開發筆試和面試之所得所感

        第四部分 結束面試

        1.面試官問我最近在看什麼書?我說《Python核心程式設計》和《Web資料挖掘》,然後問我有沒有看過Unix的書籍,我說看過《Unix程式設計藝術》前兩章。他就給我推薦了三本書,希望我回去看這三本,其他可以放一邊了,那些都是小兒科了。

       《Unix進階環境程式設計》《TCP\IP協定》《Unix網絡程式設計》

        PS:這三本數都是Unxi傳奇W.Richard Stevens的作品,當時以為推薦書,有面試了100分鐘以為有戲。可惜了,哈哈~

        2.然後又問我有什麼問題,我說想自己實作個小的搜尋引擎系統;他給我分析了硬體裝置、分詞、索引、倒排序、Rank、推薦系統等等知識。

        3.最後讓我出去等了大概15分鐘左右,好像他們那天也比較忙,最後還是方向不太對口被拒了。但我自己已經非常知足了,一方面從他那學到了很多,另一方面也深深認識到了自己的不足,當初随便報了個PHP方向居然能面試,我也不知道報了這個方向。

         在最後總結之間,說點題外話。在回學校之前,因為360公司就在798藝術工廠的旁邊,我去到那裡逛了3個多小時。寫下這樣一段話:

       “今天早上來360面試,估計已跪,但仍不虛此行。會不會程式設計我不知道,但去了它旁邊的798,發現自己還是有藝術細菌的。

        好喜歡這種什麼也不想,什麼也不做,就靜靜地坐在角落,看着川流不息的人行的感覺。是那樣的踏實惬意,那樣的無憂無慮~

        因為不喜旅遊,否則再忙也要出去看看這大千世界。但有時候又覺得做個井底之蛙也沒有什麼不好的,至少還可以每天看月亮。”

                                                                                           ——Eastmount

2016屆360公司PHP服務端開發筆試和面試之所得所感
2016屆360公司PHP服務端開發筆試和面試之所得所感

最後簡單總結下:

         面試中經常考察的問題包括:

         1.Socket套接字通信,TCP\UDP、同步異步解決方法;

         2.基本算法和資料結構題目,包括二叉樹周遊(含非遞歸)、快速排序(手寫代碼)、連結清單翻轉等;

         3.程序與線程的差別,是否寫過線程相關的,如何解決同步、互斥等問題;

         4.設計模式,如代理模式(圖檔浏覽縮略圖)、工廠模式、觀察者模型等;

         5.Cookie和Session的差別,緩存内容等,Android、前端開發常問;

         6.後端開發常常會問Unix\Linux+C語言+網絡通信的知識;

         7.Python還會問爬蟲、正則表達、開源架構Spider、docker、線程通信等;

         8.自然語言處理會問分詞、分類聚類、搜尋引擎、推薦系統等;

         提供幾點建議:

         1.申請職位一定要慎重考慮,一定是自己熟悉的東西,而不是各種職位都申請;

         2.履歷上的項目自己一定要熟悉,能說出項目的内容;

         3.如果現在距離找工作早,建議嘗試學習Linux、Unix下程式設計;

         4.網絡通信常常會問,簡單的是TCP\UDP\Socket程式設計問題,三次握手等,如果深入就需要Unix相關知識;

         5.算法很重要,如果有時間,一定要去做LeetCode題目,因為真的很多很多公司筆試面試題目都來自這裡,比如連結清單翻轉、字元串相似判斷、二叉樹周遊非遞歸等等;

         6.如果有可能,盡量做些有深度的項目,履歷中寫"熟悉XXX語言、熟悉HTML或MySQL資料庫",顯然不如"對Linux下網絡程式設計比較熟悉,通過Spider或XX架構進行過分布式爬取"。盡量讓自己的履歷更加專業、有水準。

          7.如果有開源項目或者研究過源碼、驅動這些最好不過,但顯然很少人做到。

        最後希望文章對你有所幫助,如果有不足或錯誤的地方,還請海涵~希望大家都找到自己心儀的工作。

        作者寫這篇文章也不容易,最近真心太忙了,明天還有好幾個筆試面試,自己也報了幾個貴州的大學,還是想回去任教啊!一生的夢想,不知在何方;但是不論深處何地,做什麼工作,都需要不斷地學習,保持一顆平常心和健康的身體去生活。哈哈,加油~

       (By:Eastmount