2012年面试题集
2012年5月份百度實習生招聘筆試題
1、C和C++動態內存分配與釋放的區別?
?
5月6號去百度暑期實習招聘現場打了滿滿一瓶醬油,盡管進行了網申,但是沒有收到百度的筆試通知,只好和幾名同時沒有收到通知的好友一同去復旦霸筆 了,復旦五角場校區算是一個故地,因為之前騰訊實習招聘筆試也是在這里進行的,幸運的是騰訊出的考題都比較基礎,有幸通過了筆試篩選進入了一輪面試,本人 水平有限也就這能止步一輪面了,已經很高興了,并不奢望收到騰訊或百度的橄欖枝,只是希望在參加這樣的筆試面試的過程中不斷查漏補缺,增加經驗,不斷提高 自己,希望正式找工作的時候能夠滿足名企的要求。
言歸正傳,回到百度筆試題目上面,百度筆試題目明顯和騰訊有著截然不同的風格,騰訊比較注重基礎能力,而百度更注重解決實際問題的能力,只給出六道 大題,基本上是與實際問題相結合的,很重視應試人對程序算法、數據結構的理解,這里不談那些發散性的問題,這里只談論基礎問題,因為我覺得一切偉大的建筑 都是基于牢固基石的,掌握好基礎才能掌握更高深的技術。
其中一道很基礎的問題是問C和C++在動態內存分配,釋放方面的區別。作為一個勵志成為C和C++軟件開發人員,居然連這個問題都解答的含糊不清,深感慚愧,這才認真總結一番。
一、先來談談在C語言下,動態內存分配和釋放的特點。
動態分配內存的定義是這樣的,指在程序運行過程中,要申請內存,系統會根據程序的實際情況來分配,分配空間的大小是由程序的需求來決定的。在C語言 下面,舉個例子,定義一個指針,int *p;此時指針i是一個野指針,是一個指向不確定位置的指針,對它進行操作是很危險的,此時我們需要動態分配內存空間,讓i指向它。而有一種形式是這樣 的,int *p=&b;這并非是一種動態內存分配方式,而是一種指針的初始化,把變量b的首地址給了指針p。在C語言下究竟如何實現動態內存分配的呢?這里 提供了幾個函數來實現,分別是malloc(),calloc(),realloc(),而釋放內存的函數為free(),分別探討他們的異同。
1.malloc函數
函數原型為void *malloc(unsigned int size);在內存的動態存儲區中分配一塊長度為"size" 字節的連續區域。函數的返回值為該區域的首地址。 “類型說明符”表示把該區域用于何種數據類型。(類型說明符*)表示把返回值強制轉換為該類型指針。“size”是一個無符號數。例如: pc=(char *) malloc (100); 表示分配100個字節的內存空間,并強制轉換為字符數組類型,函數的返回值為指向該字符數組的指針,把該指針賦予指針變量pc。若size超出可用空間, 則返回空指針值NULL。
2.calloc 函數
函數原型為void *calloc(unsigned int num, unsigned int size)
按所給數據個數和每個數據所占字節數開辟存儲空間。其中num為數據個數,size為每個數據所占字節數,故開辟的總字節數為 num*size。函數返回該存儲區的起始地址。calloc函數與malloc 函數的區別僅在于一次可以分配n塊區域。例如: ps=(struct stu*) calloc(2,sizeof (struct stu)); 其中的sizeof(struct stu)是求stu的結構長度。因此該語句的意思是:按stu的長度分配2塊連續區域,強制轉換為stu類型,并把其首地址賦予指針變量ps。
3. realloc函數:
函數原型為void *realloc(void *ptr, unsigned int size)
重新定義所開辟內存空間的大小。其中ptr所指的內存空間是用前述函數已開辟的,size為新的空間大小,其值可比原來大或小。函數返回新存儲區的 起始地址(該地址可能與以前的地址不同)。例如p1=(float *)realloc(p1,16);將原先開辟的8個字節調整為16個字節。
**動態申請的內存空間要進行手動用free()函數釋放
4. free函數:
函數原型為void free(void *ptr)
將以前開辟的某內存空間釋放。函數原型為 void free(void *ptr)其中ptr為存放待釋放空間起始地址的指針變量,函數無返回值。應注意:ptr所指向的空間必須是前述函數所開辟的。例如free((void *)p1);將上例開辟的16個字節釋放。可簡寫為free(p1);由系統自動進行類型轉換。
二、C++語言動態內存分配
C++語言中用new和delete來動態申請和釋放內存。
1. 申請單個對象
int *p;
p=new int;或者 p=new int(value);
2. 動態申請數組
int *p;
p=new int [100];
這樣可以申請長度為100的數組,但是不能進行初始化。
3. delete
int *p, *q;
p=new int;
q=new int[10];
delete p;
delete [ ]q;
分享來源:http://www.cnblogs.com/zhj202190/archive/2011/05/11/2043620.html
http://apps.hi.baidu.com/share/detail/57234849
2012年10月18號百度PC客戶端崗位一面電話面試面試題:
前奏:因為阿里巴巴的面 試不能由大連調北京,我就風塵撲撲的從北京回到大連去面阿里巴巴,盡管知道在就業形勢很不好的今年進阿里巴巴的機會很渺茫,但是還是想試一把,所以就回去 了,正好在回去的時候收到的百度的面試,由于不在北京,就電話面了,其實在會大連之前筆試百度過之后,就知道肯定會有面試
2012年10月22號百度客戶端二面面試題:
1、select函數的介紹
(1)一些小的知識點比如 select() 函數中第一個參數 int maxfdp 為什么要是最大的文件描述符的值 +1 ,當時臨陣磨槍的看了下select函數,細致的知識點答不上來,參考http://blog.csdn.net/leo115/article/details/8097143
2、C++中一個類的大小如何確定?
這個以前沒看過,就是分析了一下,結果露出了自己對虛函數理解的嚴重錯誤的馬腳,接下來分析一下C++中類的大小:
(1)在一個C++類中,如果什么都沒有,則這個類只占有1個字節;說明:如果一個類中沒有任何數據成員,則這個類實際上是不占用存儲空間的,size = 0;但是0不好在內存中定義一個地址,所以我們就人為的規定了大小為0的一個對象所占的存儲空間的大小為1。
(2)一旦這個類中有其他的一些數據成員,比如說一個 int data ;那么這個類的大小就為 4 個字節,而不是5個字節,上述的一個字節不計算在內;
(3)普通的成員函數是不占用空間的,所以一個只用普通函數的類的大小只占有 1 個字節。說明:普通成員函數是類的所有對象所通用的方法,不算做對象的成員,所以不能算在對象的存儲空間內。
(4)對于有虛函數的類,因為要存在一個虛函數表,需要4個字節,(是一個數組指針vptr,數組中存儲的是虛函數的函數指針的地址),這個指向虛函數表的指針占用4個字節的存儲空間。
(5)注意將數據對齊考慮進去,如一個類中含有 虛函數 和 ?一個char型數據,sizeof(class) = 8 ;默認對齊是 4字節對齊。
理解參考這個:http://blog.163.com/xping_lsr/blog/static/19654034520119804131721/
3、聊了一下虛函數機制,虛函數表這一塊理解的粗枝大葉,答得很狼狽:
(1)竟然理解成了 虛函數表中可以存儲普通函數的函數指針地址,參考http://blog.csdn.net/leo115/article/details/8035078
(2)這個虛函數表是所有的類的實例都共用這個虛函數表呢?還是每個實例都會有一個虛函數表的copy版本?
4、Linux下的一個文件 /proc 這個目錄是存放什么的?如何查看當前跑的進程的最大數量?如果查看當前所打開的文件的數量?如何查看當前所建立的連接?統計當前建立的連接的數量?
我在Linux環境下周游了一年多的時間,感覺對這個平臺還算很熟悉吧,但是對于面試 官提出的幾個命令,表示都沒有接觸過,再者就是忘了, 再者就是完全沒用到,對于第一個命令,這個目錄是是linux下的一個偽文件系統,里邊存儲一些與 進程相關的,系統相關的,以及系統子系統部分,可以直接通過cat / echo 直接輸出一些用戶需要的內核信息。平時在做多線程編程的時候更多的調用繼承開發環境自帶的庫函數,可能是自己所操作的線程比較少 或者是 平時做的項目的深度確實沒達到,都是一些淺層面的操作,導致自己根本沒有掌握這么多知識,只的表示不會。
5、進程和線程之間的區別?什么是“線程安全”?
簡單的介紹:進程是動態運行的程序的實例,是操作系統分配資源的基本單位,每一個進程都是一個實體,都有自己的地址空間,(包括:文本區域,數據區域,堆棧),進程是運行中的程序。線程是 進程中某單一順序的控制流,也被稱為輕量級進程,是運行中的程序的調度的基本單位,說明:單一順序的控制流,每個獨立的線程都有一個程序的入口、運行隊列和程序的出口。但是線程不能獨立的執行,必須存在應用程序中,由應用程序提供多個線程執行控制。
(0)一個程序至少擁有一個進程(通過fork創建進程),一個進程至少擁有一個線程(必有一個主線程)。
(1) 從調度方面考慮,線程是作為調度和分配的基本單位,進程是作為擁有資源的基本單位,線程是CPU和內存的真正的使用者
(2)并發性方面考慮:不僅相同進程中的線程可以并發,不同進程中線程之間也是可以并發的;同時進程與進程之間也是可以并發的
(3)擁有資源:進程擁有自己獨立的地址空間,而線程不擁有系統資源,但是可以訪問所在的進程的資源。
(4)系統開銷方面:在創建和撤銷進程時,由于系統都要為之分配和回收資源,導致系統的開銷明顯大于創建和撤銷線程時的開銷。
接著解釋第二個問題 什么是“線程安全”?
(1)如果程序代碼所在的進程中有多個線程在同時運行,這些線程可能會同時運行這段代碼,如果每次運行的結果和單線程運行的結果是一樣的,而且其他的變量的值也和預期的一樣,就是線程安全的。
(2)或者說:一個類或者程序所提供的接口對于線程來說是原子操作或者多個線程之間的切換不會導致該接口執行的結果產生二義性,也就是說我們不用考慮同步問題,這個時候線程是安全的。
(3)線程安全問題往往是由全局變量及靜態變量引起的。
(4)一般來說若每個線程中對全局變量、靜態變量只有讀操作,而無寫操作,一般來說,這個全局變量的線程是安全的;若有多個線程同時執行寫操作,一般要考慮線程同步問題,線程同步的解決辦法一般是:臨界區、信號量、互斥鎖等
6、最后問了一道算法題:
有兩個字符串數組: string src[] ?和 string des[] ,每個字符串數組的長度都是10W跳左右,每個字符的 size<1KB ,設計一個算法 查找 兩個字符串數組中想交的字符串。
解析方法:
分析 10W = 2^20 ?1KB*10W*2 = 2GB ,當今的內存中正好可以容下這么多數據,算法設計
(1)遍歷字符串數組src,構造一個 tire tree(字典數),然后遍歷字符串數組des遇到已經存儲過的相同的結構則輸出。
(2)設計一個hash,關鍵是哈希算法的設計,因為這是一個字符串數組,每個字符都 是有范圍的(0~25),我們可以字符串數組中的每個字符串看成一個26進制的數,將其轉化為10進制,這樣就可以得到一個唯一的key值,對于字符串太 長的情況下,我們可以將這個字符串對10萬取模,對10萬取模后,我們并不能保證這個key唯一,這樣我們就需要key值沖突處理,參考以下四種處理方 式:http://blog.csdn.net/leo115/article/details/8052353
11月3號青牛軟件面試
青牛軟件的一面就是聊項目,沒有做題,然后遇到下面的一個問題:
1、操作系統中 什么是臨界區?什么是臨界資源? 舉例說明!
答:操作系統中對臨界區的定義是這樣的:每個進程中訪問臨界資源的那段程序稱為臨界區。臨界資源的定義是:臨界資源可以由多個進程所共享,但是一次僅能由一個進程訪問的共享資源。 ?臨界區要求每次只準許一個進程進入臨界區,占時擁有臨界資源;
臨界資源的舉例:打印機,磁盤等, 一個全局變量可以允許多個進程訪問,所以全局變量不是臨界資源。
?
轉自:http://blog.csdn.net/leo115/article/details/8111926
轉載于:https://www.cnblogs.com/heyonggang/archive/2012/12/13/2817095.html
總結
- 上一篇: stack排序
- 下一篇: 地理空间数据库(Geodatabase)