第一篇:嵌入式程序員C語言筆試經(jīng)典題
新一篇: 存儲過程,無限級分類 | 舊一篇: 類繼承中構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用
這個(gè)測試適于不同水平的應(yīng)試者,大多數(shù)初級水平的應(yīng)試者的成績會很差,經(jīng)驗(yàn)豐富的程序員應(yīng)該有很好的成績。為了讓你能自己決定某些問題的偏好,每個(gè)問題沒有分配分?jǐn)?shù),如果選擇這些考題為你所用,請自行按你的意思分配分?jǐn)?shù)。
預(yù)處理器(Preprocessor).用預(yù)處理指令#define 聲明一個(gè)常數(shù),用以表明1年中有多少秒(忽略閏年問題)#define SECONDS_PER_YEAR(60 * 60 * 24 * 365)UL 我在這想看到幾件事情:
1)#define 語法的基本知識(例如:不能以分號結(jié)束,括號的使用,等等)
2)懂得預(yù)處理器將為你計(jì)算常數(shù)表達(dá)式的值,因此,直接寫出你是如何計(jì)算一年中有多少秒而不是計(jì)算出實(shí)際的值,是更清晰而沒有代價(jià)的。
3)意識到這個(gè)表達(dá)式將使一個(gè)16位機(jī)的整型數(shù)溢出-因此要用到長整型符號L,告訴編譯器這個(gè)常數(shù)是的長整型數(shù)。
4)如果你在你的表達(dá)式中用到UL(表示無符號長整型),那么你有了一個(gè)好的起點(diǎn)。記住,第一印象很重要。.寫一個(gè)“標(biāo)準(zhǔn)”宏MIN,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)。#define MIN(A,B)((A)<=(B)?(A):(B))這個(gè)測試是為下面的目的而設(shè)的:
1)標(biāo)識#define在宏中應(yīng)用的基本知識。這是很重要的。因?yàn)樵谇度?inline)操作符 變?yōu)闃?biāo)準(zhǔn)C的一部分之前,宏是方便產(chǎn)生嵌入代碼的唯一方法,對于嵌入式系統(tǒng)來說,為了能達(dá)到要求的性能,嵌入代碼經(jīng)常是必須的方法。
2)三重條件操作符的知識。這個(gè)操作符存在C語言中的原因是它使得編譯器能產(chǎn)生比if-then-else更優(yōu)化的代碼,了解這個(gè)用法是很重要的。3)懂得在宏中小心地把參數(shù)用括號括起來
4)我也用這個(gè)問題開始討論宏的副作用,例如:當(dāng)你寫下面的代碼時(shí)會發(fā)生什么事? least = MIN(*p++, b);
3.預(yù)處理器標(biāo)識#error的目的是什么?
如果你不知道答案,請看參考文獻(xiàn)1。這問題對區(qū)分一個(gè)正常的伙計(jì)和一個(gè)書呆子是很有用的。只有書呆子才會讀C語言課本的附錄去找出象這種問題的答案。當(dāng)然如果你不是在找一個(gè)書呆子,那么應(yīng)試者最好希望自己不要知道答案。指令 用途
# 空指令,無任何效果
#include 包含一個(gè)源代碼文件
#define 定義宏
#undef 取消已定義的宏
#if 如果給定條件為真,則編譯下面代碼
#ifdef 如果宏已經(jīng)定義,則編譯下面代碼
#ifndef 如果宏沒有定義,則編譯下面代碼
#elif 如果前面的#if給定條件不為真,當(dāng)前條件為真,則編譯下面代碼 #endif 結(jié)束一個(gè)#if……#else條件編譯塊
#error 停止編譯并顯示錯誤信息
死循環(huán)(Infinite loops)
4.嵌入式系統(tǒng)中經(jīng)常要用到無限循環(huán),你怎么樣用C編寫死循環(huán)呢? 這個(gè)問題用幾個(gè)解決方案。我首選的方案是:
while(1){ }
一些程序員更喜歡如下方案:
for(;;){ }
這個(gè)實(shí)現(xiàn)方式讓我為難,因?yàn)檫@個(gè)語法沒有確切表達(dá)到底怎么回事。如果一個(gè)應(yīng)試者給出這個(gè)作為方案,我將用這個(gè)作為一個(gè)機(jī)會去探究他們這樣做的基本原理。如果他們的基本答案是:“我被教著這樣做,但從沒有想到過為什么?!边@會給我留下一個(gè)壞印象。
第三個(gè)方案是用 goto Loop:...goto Loop;應(yīng)試者如給出上面的方案,這說明或者他是一個(gè)匯編語言程序員(這也許是好事)或者他是一個(gè)想進(jìn)入新領(lǐng)域的BASIC/FORTRAN程序員。
數(shù)據(jù)聲明(Data declarations)
5.用變量a給出下面的定義 a)一個(gè)整型數(shù)(An integer)
//int a me b)一個(gè)指向整型數(shù)的指針(A pointer to an integer)
//int *a me c)一個(gè)指向指針的的指針,它指向的指針是指向一個(gè)整型數(shù)(A pointer to a pointer to an intege)r
//int ** a me
d)一個(gè)有10個(gè)整型數(shù)的數(shù)組(An array of 10 integers)//int a[10] me e)一個(gè)有10個(gè)指針的數(shù)組,該指針是指向一個(gè)整型數(shù)的。(An array of 10 pointers to integers)
// int * a[10] me f)一個(gè)指向有10個(gè)整型數(shù)數(shù)組的指針(A pointer to an array of 10 integers)
//in t(*a)[10] me g)一個(gè)指向函數(shù)的指針,該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(A pointer to a function that takes an integer as an argument and returns an integer)
int(*fun)(int)
h)一個(gè)有10個(gè)指針的數(shù)組,該指針指向一個(gè)函數(shù),該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(An array of ten pointers to functions that take an integer argument and return an integer)
//int(*fun[10])(int)答案是:
a)int a;// An integer b)int *a;// A pointer to an integer c)int **a;// A pointer to a pointer to an integer d)int a[10];// An array of 10 integers e)int *a[10];// An array of 10 pointers to integers f)int(*a)[10];// A pointer to an array of 10 integers g)int(*a)(int);// A pointer to a function a that takes an integer argument and returns an integer h)int(*a[10])(int);// An array of 10 pointers to functions that take an integer argument and return an integer
人們經(jīng)常聲稱這里有幾個(gè)問題是那種要翻一下書才能回答的問題,我同意這種說法。當(dāng)我寫這篇文章時(shí),為了確定語法的正確性,我的確查了一下書。但是當(dāng)我被面試的時(shí)候,我期望被問到這個(gè)問題(或者相近的問題)。因?yàn)樵诒幻嬖嚨倪@段時(shí)間里,我確定我知道這個(gè)問題的答案。應(yīng)試者如果不知道所有的答案(或至少大部分答案),那么也就沒有為這次面試做準(zhǔn)備,如果該面試者沒有為這次面試做準(zhǔn)備,那么他又能為什么出準(zhǔn)備呢?
Static
6.關(guān)鍵字static的作用是什么?
這個(gè)簡單的問題很少有人能回答完全。在C語言中,關(guān)鍵字static有三個(gè)明顯的作用: 1)在函數(shù)體,一個(gè)被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過程中維持其值不變。
2)在模塊內(nèi)(但在函數(shù)體外),一個(gè)被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問。它是一個(gè)本地的全局變量。
3)在模塊內(nèi),一個(gè)被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用。那就是,這個(gè)函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用。
大多數(shù)應(yīng)試者能正確回答第一部分,一部分能正確回答第二部分,同是很少的人能懂得第三部分。這是一個(gè)應(yīng)試者的嚴(yán)重的缺點(diǎn),因?yàn)樗@然不懂得本地化數(shù)據(jù)和代碼范圍的好處和重要性。
Const
7.關(guān)鍵字const有什么含意?
我只要一聽到被面試者說:“const意味著常數(shù)”,我就知道我正在和一個(gè)業(yè)余者打交道。去年Dan Saks已經(jīng)在他的文章里完全概括了const的所有用法,因此ESP(譯者:Embedded Systems Programming)的每一位讀者應(yīng)該非常熟悉const能做什么和不能做什么.如果你從沒有讀到那篇文章,只要能說出const意味著“只讀”就可以了。盡管這個(gè)答案不是完全的答案,但我接受它作為一個(gè)正確的答案。(如果你想知道更詳細(xì)的答案,仔細(xì)讀一下Saks的文章吧。)
如果應(yīng)試者能正確回答這個(gè)問題,我將問他一個(gè)附加的問題: 下面的聲明都是什么意思?
const int a;int const a;const int *a;int * const a;int const * a const;
/******/ 前兩個(gè)的作用是一樣,a是一個(gè)常整型數(shù)。第三個(gè)意味著a是一個(gè)指向常整型數(shù)的指針(也就是,整型數(shù)是不可修改的,但指針可以)。第四個(gè)意識a是一個(gè)指向整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是可以修改的,但指針是不可修改的)。最后一個(gè)意味著a是一個(gè)指向常整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是不可修改的,同時(shí)指針也是不可修改的)。如果應(yīng)試者能正確回答這些問題,那么他就給我留下了一個(gè)好印象。順帶提一句,也許你可能會問,即使不用關(guān)鍵字 const,也還是能很容易寫出功能正確的程序,那么我為什么還要如此看重關(guān)鍵字const呢?我也如下的幾下理由:
1)關(guān)鍵字const的作用是為給讀你代碼的人傳達(dá)非常有用的信息,實(shí)際上,聲明一個(gè)參數(shù)為常量是為了告訴了用戶這個(gè)參數(shù)的應(yīng)用目的。如果你曾花很多時(shí)間清理其它人留下的垃圾,你就會很快學(xué)會感謝這點(diǎn)多余的信息。(當(dāng)然,懂得用const的程序員很少會留下的垃圾讓別人來清理的。)2)通過給優(yōu)化器一些附加的信息,使用關(guān)鍵字const也許能產(chǎn)生更緊湊的代碼。
3)合理地使用關(guān)鍵字const可以使編譯器很自然地保護(hù)那些不希望被改變的參數(shù),防止其被無意的代碼修改。簡而言之,這樣可以減少bug的出現(xiàn)。
Volatile
8.關(guān)鍵字volatile有什么含意?并給出三個(gè)不同的例子。
一個(gè)定義為volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設(shè)這個(gè)變量的值了。精確地說就是,優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心地重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個(gè)例子: 1)并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器)
2)一個(gè)中斷服務(wù)子程序中會訪問到的非自動變量(Non-automatic variables)3)多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量
回答不出這個(gè)問題的人是不會被雇傭的。我認(rèn)為這是區(qū)分C程序員和嵌入式系統(tǒng)程序員的最基本的問題。搞嵌入式的家伙們經(jīng)常同硬件、中斷、RTOS等等打交道,所有這些都要求用到volatile變量。不懂得volatile的內(nèi)容將會帶來災(zāi)難。
假設(shè)被面試者正確地回答了這是問題(嗯,懷疑是否會是這樣),我將稍微深究一下,看一下這家伙是不是直正懂得volatile完全的重要性。
1)一個(gè)參數(shù)既可以是const還可以是volatile嗎?解釋為什么。2);一個(gè)指針可以是volatile 嗎?解釋為什么。3);下面的函數(shù)有什么錯誤:
int square(volatile int *ptr){ return *ptr * *ptr;}
下面是答案:
1)是的。一個(gè)例子是只讀的狀態(tài)寄存器。它是volatile因?yàn)樗赡鼙灰庀氩坏降馗淖?。它是const因?yàn)槌绦虿粦?yīng)該試圖去修改它。
2);是的。盡管這并不很常見。一個(gè)例子是當(dāng)一個(gè)中服務(wù)子程序修該一個(gè)指向一個(gè)buffer的指針時(shí)。3)這段代碼有點(diǎn)變態(tài)。這段代碼的目的是用來返指針*ptr指向值的平方,但是,由于*ptr指向一個(gè)volatile型參數(shù),編譯器將產(chǎn)生類似下面的代碼:
int square(volatile int *ptr){ int a,b;a = *ptr;b = *ptr;return a * b;}
由于*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結(jié)果,這段代碼可能返不是你所期望的平方值!正確的代碼如下:
long square(volatile int *ptr){ int a;a = *ptr;return a * a;}
位操作(Bit manipulation)
9.嵌入式系統(tǒng)總是要用戶對變量或寄存器進(jìn)行位操作。給定一個(gè)整型變量a,寫兩段代碼,第一個(gè)設(shè)置a的bit 3,第二個(gè)清除a 的bit 3。在以上兩個(gè)操作中,要保持其它位不變。對這個(gè)問題有三種基本的反應(yīng)
1)不知道如何下手。該被面者從沒做過任何嵌入式系統(tǒng)的工作。
2)用bit fields。Bit fields是被扔到C語言死角的東西,它保證你的代碼在不同編譯器之間是不可移植的,同時(shí)也保證了的你的代碼是不可重用的。我最近不幸看到 Infineon為其較復(fù)雜的通信芯片寫的驅(qū)動程序,它用到了bit fields因此完全對我無用,因?yàn)槲业木幾g器用其它的方式來實(shí)現(xiàn)bit fields的。從道德講:永遠(yuǎn)不要讓一個(gè)非嵌入式的家伙粘實(shí)際硬件的邊。
3)用 #defines 和 bit masks 操作。這是一個(gè)有極高可移植性的方法,是應(yīng)該被用到的方法。最佳的解決方案如下:
#define BIT3(0x1 << 3)static int a;
void set_bit3(void){ a |= BIT3;} void clear_bit3(void){ a &= ~BIT3;}
一些人喜歡為設(shè)置和清除值而定義一個(gè)掩碼同時(shí)定義一些說明常數(shù),這也是可以接受的。我希望看到幾個(gè)要點(diǎn):說明常數(shù)、|=和&=~操作。
訪問固定的內(nèi)存位置(Accessing fixed memory locations)
10.嵌入式系統(tǒng)經(jīng)常具有要求程序員去訪問某特定的內(nèi)存位置的特點(diǎn)。在某工程中,要求設(shè)置一絕對地址為0x67a9的整型變量的值為0xaa66。編譯器是一個(gè)純粹的ANSI編譯器。寫代碼去完成這一任務(wù)。這一問題測試你是否知道為了訪問一絕對地址把一個(gè)整型數(shù)強(qiáng)制轉(zhuǎn)換(typecast)為一指針是合法的。這一問題的實(shí)現(xiàn)方式隨著個(gè)人風(fēng)格不同而不同。典型的類似代碼如下: int *ptr;ptr =(int *)0x67a9;*ptr = 0xaa55;
A more obscure approach is: 一個(gè)較晦澀的方法是:
*(int * const)(0x67a9)= 0xaa55;
即使你的品味更接近第二種方案,但我建議你在面試時(shí)使用第一種方案。
中斷(Interrupts)
11.中斷是嵌入式系統(tǒng)中重要的組成部分,這導(dǎo)致了很多編譯開發(fā)商提供一種擴(kuò)展—讓標(biāo)準(zhǔn)C支持中斷。具代表事實(shí)是,產(chǎn)生了一個(gè)新的關(guān)鍵字 __interrupt。下面的代碼就使用了__interrupt關(guān)鍵字去定義了一個(gè)中斷服務(wù)子程序(ISR),請?jiān)u論一下這段代碼的。
__interrupt double compute_area(double radius){ double area = PI * radius * radius;printf(“nArea = %f”, area);return area;}
這個(gè)函數(shù)有太多的錯誤了,以至讓人不知從何說起了:
1)ISR 不能返回一個(gè)值。如果你不懂這個(gè),那么你不會被雇用的。
2)ISR 不能傳遞參數(shù)。如果你沒有看到這一點(diǎn),你被雇用的機(jī)會等同第一項(xiàng)。
3)在許多的處理器/編譯器中,浮點(diǎn)一般都是不可重入的。有些處理器/編譯器需要讓額處的寄存器入棧,有些處理器/編譯器就是不允許在ISR中做浮點(diǎn)運(yùn)算。此外,ISR應(yīng)該是短而有效率的,在ISR中做浮點(diǎn)運(yùn)算是不明智的。
4)與第三點(diǎn)一脈相承,printf()經(jīng)常有重入和性能上的問題。如果你丟掉了第三和第四點(diǎn),我不會太為難你的。不用說,如果你能得到后兩點(diǎn),那么你的被雇用前景越來越光明了。
代碼例子(Code examples).下面的代碼輸出是什么,為什么?
void foo(void){ unsigned int a = 6;int b =-20;(a+b > 6)? puts(“> 6”): puts(“<= 6”);} 這個(gè)問題測試你是否懂得C語言中的整數(shù)自動轉(zhuǎn)換原則,我發(fā)現(xiàn)有些開發(fā)者懂得極少這些東西。不管如何,這無符號整型問題的答案是輸出是 “>6”。原因是當(dāng)表達(dá)式中存在有符號類型和無符號類型時(shí)所有的操作數(shù)都自動轉(zhuǎn)換為無符號類型。因此-20變成了一個(gè)非常大的正整數(shù),所以該表達(dá)式計(jì)算出的結(jié)果大于6。這一點(diǎn)對于應(yīng)當(dāng)頻繁用到無符號數(shù)據(jù)類型的嵌入式系統(tǒng)來說是豐常重要的。如果你答錯了這個(gè)問題,你也就到了得不到這份工作的邊緣。
13.評價(jià)下面的代碼片斷:
unsigned int zero = 0;unsigned int compzero = 0xFFFF;/*1's complement of zero */
對于一個(gè)int型不是16位的處理器為說,上面的代碼是不正確的。應(yīng)編寫如下:
unsigned int compzero = ~0;這一問題真正能揭露出應(yīng)試者是否懂得處理器字長的重要性。在我的經(jīng)驗(yàn)里,好的嵌入式程序員非常準(zhǔn)確地明白硬件的細(xì)節(jié)和它的局限,然而PC機(jī)程序往往把硬件作為一個(gè)無法避免的煩惱。
到了這個(gè)階段,應(yīng)試者或者完全垂頭喪氣了或者信心滿滿志在必得。如果顯然應(yīng)試者不是很好,那么這個(gè)測試就在這里結(jié)束了。但如果顯然應(yīng)試者做得不錯,那么我就扔出下面的追加問題,這些問題是比較難的,我想僅僅非常優(yōu)秀的應(yīng)試者能做得不錯。提出這些問題,我希望更多看到應(yīng)試者應(yīng)付問題的方法,而不是答案。不管如何,你就當(dāng)是這個(gè)娛樂吧...動態(tài)內(nèi)存分配(Dynamic memory allocation)
14.盡管不像非嵌入式計(jì)算機(jī)那么常見,嵌入式系統(tǒng)還是有從堆(heap)中動態(tài)分配內(nèi)存的過程的。那么嵌入式系統(tǒng)中,動態(tài)分配內(nèi)存可能發(fā)生的問題是什么?
這里,我期望應(yīng)試者能提到內(nèi)存碎片,碎片收集的問題,變量的持行時(shí)間等等。這個(gè)主題已經(jīng)在ESP雜志中被廣泛地討論過了(主要是 P.J.Plauger, 他的解釋遠(yuǎn)遠(yuǎn)超過我這里能提到的任何解釋),所有回過頭看一下這些雜志吧!讓應(yīng)試者進(jìn)入一種虛假的安全感覺后,我拿出這么一個(gè)小節(jié)目: 下面的代碼片段的輸出是什么,為什么?
char *ptr;if((ptr =(char *)malloc(0))== NULL)puts(“Got a null pointer”);else puts(“Got a valid pointer”);
這是一個(gè)有趣的問題。最近在我的一個(gè)同事不經(jīng)意把0值傳給了函數(shù)malloc,得到了一個(gè)合法的指針之后,我才想到這個(gè)問題。這就是上面的代碼,該代碼的輸出是“Got a valid pointer”。我用這個(gè)來開始討論這樣的一問題,看看被面試者是否想到庫例程這樣做是正確。得到正確的答案固然重要,但解決問題的方法和你做決定的基本原理更重要些。
Typedef Typedef 在C語言中頻繁用以聲明一個(gè)已經(jīng)存在的數(shù)據(jù)類型的同義字。也可以用預(yù)處理器做類似的事。例如,思考一下下面的例子:
#define dPS struct s * typedef struct s * tPS;
以上兩種情況的意圖都是要定義dPS 和 tPS 作為一個(gè)指向結(jié)構(gòu)s指針。哪種方法更好呢?(如果有的話)為什么?
這是一個(gè)非常微妙的問題,任何人答對這個(gè)問題(正當(dāng)?shù)脑颍┦菓?yīng)當(dāng)被恭喜的。答案是:typedef更好。思考下面的例子:
dPS p1,p2;tPS p3,p4;第一個(gè)擴(kuò)展為
struct s * p1, p2;.上面的代碼定義p1為一個(gè)指向結(jié)構(gòu)的指,p2為一個(gè)實(shí)際的結(jié)構(gòu),這也許不是你想要的。第二個(gè)例子正確地定義了p3 和p4 兩個(gè)指針。
晦澀的語法.C語言同意一些令人震驚的結(jié)構(gòu),下面的結(jié)構(gòu)是合法的嗎,如果是它做些什么?
int a = 5, b = 7, c;c = a+++b;
這個(gè)問題將做為這個(gè)測驗(yàn)的一個(gè)愉快的結(jié)尾。不管你相不相信,上面的例子是完全合乎語法的。問題是編譯器如何處理它?水平不高的編譯作者實(shí)際上會爭論這個(gè)問題,根據(jù)最處理原則,編譯器應(yīng)當(dāng)能處理盡可能所有合法的用法。因此,上面的代碼被處理成:
c = a++ + b;
因此, 這段代碼持行后a = 6, b = 7, c = 12。
如果你知道答案,或猜出正確答案,做得好。如果你不知道答案,我也不把這個(gè)當(dāng)作問題。我發(fā)現(xiàn)這個(gè)問題的最大好處是這是一個(gè)關(guān)于代碼編寫風(fēng)格,代碼的可讀性,代碼的可修改性的好的話題。
第二篇:嵌入式程序員C語言筆試題目
華碩_嵌入式程序員C語言筆試題目
預(yù)處理器(Preprocessor).用預(yù)處理指令#define 聲明一個(gè)常數(shù),用以表明1年中有多少秒(忽略閏年問題)
#define SECONDS_PER_YEAR(60 * 60 * 24 * 365)UL
我在這想看到幾件事情:
1)#define 語法的基本知識(例如:不能以分號結(jié)束,括號的使用,等等)
2)懂得預(yù)處理器將為你計(jì)算常數(shù)表達(dá)式的值,因此,直接寫出你是如何計(jì)算一年中有多少秒而不是計(jì)算出實(shí)際的值,是更清晰而沒有代價(jià)的。
3)意識到這個(gè)表達(dá)式將使一個(gè)16位機(jī)的整型數(shù)溢出-因此要用到長整型符號L,告訴編譯器這個(gè)常數(shù)是的長整型數(shù)。
4)如果你在你的表達(dá)式中用到UL(表示無符號長整型),那么你有了一個(gè)好的起點(diǎn)。記住,第一印象很重要。.寫一個(gè)“標(biāo)準(zhǔn)”宏MIN,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)。
#define MIN(A,B)((A)<=(B)?(A):(B))
這個(gè)測試是為下面的目的而設(shè)的:
1)標(biāo)識#define在宏中應(yīng)用的基本知識。這是很重要的。因?yàn)樵?嵌入(inline)操作符 變?yōu)闃?biāo)準(zhǔn)C的一部分之前,宏是方便產(chǎn)生嵌入代碼的唯一方法,對于嵌入式系統(tǒng)來說,為了能達(dá)到要求的性能,嵌入代碼經(jīng)常是必須的方法。
2)三重條件操作符的知識。這個(gè)操作符存在C語言中的原因是它使得編譯器能產(chǎn)生比if-then-else更優(yōu)化的代碼,了解這個(gè)用法是很重要的。
3)懂得在宏中小心地把參數(shù)用括號括起來
4)我也用這個(gè)問題開始討論宏的副作用,例如:當(dāng)你寫下面的代碼時(shí)會發(fā)生什么事?
least = MIN(*p++, b);
3.預(yù)處理器標(biāo)識#error的目的是什么?
Error directives produce compiler-time error messages.死循環(huán)(Infinite loops)
4.嵌入式系統(tǒng)中經(jīng)常要用到無限循環(huán),你怎么樣用C編寫死循環(huán)呢?
這個(gè)問題用幾個(gè)解決方案。我首選的方案是:
while(1){ }
一些程序員更喜歡如下方案:
for(;;){ }
這個(gè)實(shí)現(xiàn)方式讓我為難,因?yàn)檫@個(gè)語法沒有確切表達(dá)到底怎么回事。如果一個(gè)應(yīng)試者給出這個(gè)作為方案,我將用這個(gè)作為一個(gè)機(jī)會去探究他們這樣做的基本原理。如果他們的基本答案是:“我被教著這樣做,但從沒有想到過為什么。”這會給我留下一個(gè)壞印象。
第三個(gè)方案是用 goto Loop:...goto Loop;
應(yīng)試者如給出上面的方案,這說明或者他是一個(gè)匯編語言程序員(這也許是好事)或者他是一個(gè)想進(jìn)入新領(lǐng)域的BASIC/FORTRAN程序員。
數(shù)據(jù)聲明(Data declarations)
5.用變量a給出下面的定義
a)一個(gè)整型數(shù)(An integer)
b)一個(gè)指向整型數(shù)的指針(A pointer to an integer)c)一個(gè)指向指針的的指針,它指向的指針是指向一個(gè)整型數(shù)(A pointer to a pointer to an intege)r
d)一個(gè)有10個(gè)整型數(shù)的數(shù)組(An array of 10 integers)e)一個(gè)有10個(gè)指針的數(shù)組,該指針是指向一個(gè)整型數(shù)的。(An array of 10 pointers to integers)
f)一個(gè)指向有10個(gè)整型數(shù)數(shù)組的指針(A pointer to an array of 10 integers)
g)一個(gè)指向函數(shù)的指針,該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(A pointer to a function that takes an integer as an argument and returns an integer)
h)一個(gè)有10個(gè)指針的數(shù)組,該指針指向一個(gè)函數(shù),該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(An array of ten pointers to functions that take an integer argument and return an integer)
答案是:
a)int a;// An integer
b)int *a;// A pointer to an integer
c)int **a;// A pointer to a pointer to an integer
d)int a[10];// An array of 10 integers
e)int *a[10];// An array of 10 pointers to integers
f)int(*a)[10];// A pointer to an array of 10 integers
g)int(*a)(int);// A pointer to a function a that takes an integer argument and returns an integer
h)int(*a[10])(int);// An array of 10 pointers to functions that take an integer argument and return an integer
人們經(jīng)常聲稱這里有幾個(gè)問題是那種要翻一下書才能回答的問題,我同意這種說法。當(dāng)我寫這篇文章時(shí),為了確定語法的正確性,我的確查了一下書。但是當(dāng)我被面試的時(shí)候,我期望被問到這個(gè)問題(或者相近的問題)。因?yàn)樵诒幻嬖嚨倪@段時(shí)間里,我確定我知道這個(gè)問題的答案。應(yīng)試者如果不知道所有的答案(或至少大部分答案),那么也就沒有為這次面試做準(zhǔn)備,如果該面試者沒有為這次面試做準(zhǔn)備,那么他又能為什么出準(zhǔn)備呢? Static
6.關(guān)鍵字static的作用是什么?
這個(gè)簡單的問題很少有人能回答完全。在C語言中,關(guān)鍵字static有三個(gè)明顯的作用:
1)在函數(shù)體,一個(gè)被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過程中維持其值不變。
2)在模塊內(nèi)(但在函數(shù)體外),一個(gè)被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問。它是一個(gè)本地的全局變量。
3)在模塊內(nèi),一個(gè)被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用。那就是,這個(gè)函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用。
大多數(shù)應(yīng)試者能正確回答第一部分,一部分能正確回答第二部分,同是很少的人能懂得第三部分。這是一個(gè)應(yīng)試者的嚴(yán)重的缺點(diǎn),因?yàn)樗@然不懂得本地化數(shù)據(jù)和代碼范圍的好處和重要性。
Const
7.關(guān)鍵字const有什么含意?
我只要一聽到被面試者說:“const意味著常數(shù)”,我就知道我正在和一個(gè)業(yè)余者打交道。去年Dan Saks已經(jīng)在他的文章里完全概括了const的所有用法,因此ESP(譯者:Embedded Systems Programming)的每一位讀者應(yīng)該非常熟悉const能做什么和不能做什么.如果你從沒有讀到那篇文章,只要能說出const意味著“只讀”就可以了。盡管這個(gè)答案不是完全的答案,但我接受它作為一個(gè)正確的答案。(如果你想知道更詳細(xì)的答案,仔細(xì)讀一下Saks的文章吧。)
如果應(yīng)試者能正確回答這個(gè)問題,我將問他一個(gè)附加的問題:
下面的聲明都是什么意思?
const int a;
int const a;
const int *a;
int * const a;
int const * const a=new int(1);
/******/
前兩個(gè)的作用是一樣,a是一個(gè)常整型數(shù)。第三個(gè)意味著a是一個(gè)指向常整型數(shù)的指針(也就是,整型數(shù)是不可修改的,但指針可以)。第四個(gè)意識a是一個(gè)指向整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是可以修改的,但指針是不可修改的)。最后一個(gè)意味著a是一個(gè)指向常整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是不可修改的,同時(shí)指針也是不可修改的)。如果應(yīng)試者能正確回答這些問題,那么他就給我留下了一個(gè)好印象。順帶提一句,也許你可能會問,即使不用關(guān)鍵字 const,也還是能很容易寫出功能正確的程序,那么我為什么還要如此看重關(guān)鍵字const呢?我也如下的幾下理由:
1)關(guān)鍵字const的作用是為給讀你代碼的人傳達(dá)非常有用的信息,實(shí)際上,聲明一個(gè)參數(shù)為常量是為了告訴了用戶這個(gè)參數(shù)的應(yīng)用目的。如果你曾花很多時(shí)間清理其它人留下的垃圾,你就會很快學(xué)會感謝這點(diǎn)多余的信息。(當(dāng)然,懂得用const的程序員很少會留下的垃圾讓別人來清理的。)
第三篇:2012年最新C和C++程序員筆試題
以下是整理自8月下旬至10月份內(nèi)的各大公司的筆試面試三十題(注:所有題目基本上全部為軟件開發(fā)方向,題目來源:網(wǎng)絡(luò)收集),相信一定能給正在參加各種校招的諸多朋友多少幫助,學(xué)習(xí)參考或借鑒
九月十月百度人搜,阿里巴巴,騰訊華為小米搜狗筆/面試五十題
9月11日,京東:
談?wù)勀銓γ嫦驅(qū)ο缶幊痰恼J(rèn)識
? 8月20日,金山面試,題目如下:
數(shù)據(jù)庫1中存放著a類數(shù)據(jù),數(shù)據(jù)庫2中存放著以天為單位劃分的表30張(比如table_20110909,table_20110910,table_20110911),總共是一個(gè)月的數(shù)據(jù)。表1中的a類數(shù)據(jù)中有一個(gè)字段userid來唯一判別用戶身份,表2中的30張表(每張表結(jié)構(gòu)相同)也有一個(gè)字段userid來唯一識別用戶身份。如何判定a類數(shù)據(jù)庫的多少用戶在數(shù)據(jù)庫2中出現(xiàn)過? 百度實(shí)習(xí)筆試題(2012.5.6)
簡答題1
一個(gè)單詞單詞字母交換,可得另一個(gè)單詞,如army->mary,成為兄弟單詞。提供一個(gè)單詞,在字典中找到它的兄弟。描述數(shù)據(jù)結(jié)構(gòu)和查詢過程。評點(diǎn):同去年9月份的一道題,見此文第3題:簡答題2 線程和進(jìn)程區(qū)別和聯(lián)系。什么是“線程安全”
簡答題3
C和C++怎樣分配和釋放內(nèi)存,區(qū)別是什么
算法題1
一個(gè)url指向的頁面里面有另一個(gè)url,最終有一個(gè)url指向之前出現(xiàn)過的url或空,這兩種情形都定義為null。這樣構(gòu)成一個(gè)單鏈表。給兩條這樣單鏈表,判斷里面是否存在同樣的url。url以億級計(jì),資源不足以hash。
算法題2
數(shù)組al[0,mid-1] 和 al[mid,num-1],都分別有序。將其merge成有序數(shù)組al[0,num-1],要求空間復(fù)雜度O(1)系統(tǒng)設(shè)計(jì)題
百度搜索框的suggestion,比如輸入北京,搜索框下面會以北京為前綴,展示“北京愛情故事”、“北京公交”、“北京醫(yī)院”等等搜索詞。
如何設(shè)計(jì)使得空間和時(shí)間復(fù)雜度盡量低。評點(diǎn):老題,直接上Trie樹+Hash,Trie樹的介紹見:從Trie樹(字典樹)談到后綴樹。
? ? 人搜筆試
1.快排每次以第一個(gè)作為主元,問時(shí)間復(fù)雜度是多少?(O(N*logN))
2.T(N)= N + T(N/2)+T(2N), 問T(N)的時(shí)間復(fù)雜度是多少? 點(diǎn)評:O(N*logN)or O(N)? 3.從(0,1)中平均隨機(jī)出幾次才能使得和超過1?(e)4.編程題:
一棵樹的節(jié)點(diǎn)定義格式如下: struct Node{ Node* parent;Node* firstChild;// 孩子節(jié)點(diǎn) Node* sibling;// 兄弟節(jié)點(diǎn) } 要求非遞歸遍歷該樹。
思路:采用隊(duì)列存儲,來遍歷節(jié)點(diǎn)。5.算法題:
有N個(gè)節(jié)點(diǎn),每兩個(gè)節(jié)點(diǎn)相鄰,每個(gè)節(jié)點(diǎn)只與2個(gè)節(jié)點(diǎn)相鄰,因此,N個(gè)頂點(diǎn)有N-1條邊。每一條邊上都有權(quán)值wi,定義節(jié)點(diǎn)i到節(jié)點(diǎn)i+1的邊為wi。求:不相鄰的權(quán)值和最大的邊的集合。? 人搜面試,所投職位:搜索研發(fā)工程師:面試題回憶
1、刪除字符串開始及末尾的空白符,并且把數(shù)組中間的多個(gè)空格(如果有)符轉(zhuǎn)化為1個(gè)。
2、求數(shù)組(元素可為正數(shù)、負(fù)數(shù)、0)的最大子序列和。
3、鏈表相鄰元素翻轉(zhuǎn),如a->b->c->d->e->f-g,翻轉(zhuǎn)后變?yōu)椋篵->a->d->c->f->e->g
4、鏈表克隆。鏈表的結(jié)構(gòu)為: typedef struct list { int data;//數(shù)據(jù)字段
list *middle;//指向鏈表中某任意位置元素(可指向自己)的指針 list *next;//指向鏈表下一元素 } list;5、100萬條數(shù)據(jù)的數(shù)據(jù)庫查詢速度優(yōu)化問題,解決關(guān)鍵點(diǎn)是:根據(jù)主表元素特點(diǎn),把主表拆分并新建副表,并且利用存儲過程保證主副表的數(shù)據(jù)一致性。(不用寫代碼)
6、求正整數(shù)n所有可能的和式的組合(如;4=1+1+1+1、1+1+2、1+3、2+1+1、2+2)。?
7、求旋轉(zhuǎn)數(shù)組的最小元素(把一個(gè)數(shù)組最開始的若干個(gè)元素搬到數(shù)組的末尾,我們稱之為數(shù)組的旋轉(zhuǎn)。輸入一個(gè)排好序的數(shù)組的一個(gè)旋轉(zhuǎn),輸出旋轉(zhuǎn)數(shù)組的最小元素。例如數(shù)組{3, 4, 5, 1, 2}為{1, 2, 3, 4, 5}的一個(gè)旋轉(zhuǎn),該數(shù)組的最小值為1)
8、找出兩個(gè)單鏈表里交叉的第一個(gè)元素
9、字符串移動(字符串為*號和26個(gè)字母的任意組合,把*號都移動到最左側(cè),把字母移到最右側(cè)并保持相對順序不變),要求時(shí)間和空間復(fù)雜度最小
10、時(shí)間復(fù)雜度為O(1),怎么找出一個(gè)棧里的最大元素
11、線程、進(jìn)程區(qū)別
12、static在C和C++里各代表什么含義
13、const在C/C++里什么意思
14、常用linux命令
15、解釋Select/Poll模型 ? 網(wǎng)易有道二面:
判斷一個(gè)數(shù)字序列是BST后序遍歷的結(jié)果,現(xiàn)場寫代碼。
? 8月30日,網(wǎng)易有道面試題
var tt = 'aa';function test(){ alert(tt);var tt = 'dd';alert(tt);} test();? ? 8月31日,百度面試題:不使用隨機(jī)數(shù)的洗牌算法,9月6日,阿里筆試題:平面上有很多點(diǎn),點(diǎn)與點(diǎn)之間有可能有連線,求這個(gè)圖里環(huán)的數(shù)目。
?? 9月7日,一道華為上機(jī)題:
題目描述: 選秀節(jié)目打分,分為專家評委和大眾評委,score[] 數(shù)組里面存儲每個(gè)評委打的分?jǐn)?shù),judge_type[] 里存儲與 score[] 數(shù)組對應(yīng)的評委類別,judge_type == 1,表示專家評委,judge_type == 2,表示大眾評委,n表示評委總數(shù)。打分規(guī)則如下:專家評委和大眾評委的分?jǐn)?shù)先分別取一個(gè)平均分(平均分取整),然后,總分 = 專家評委平均分 * 0.6 + 大眾評委 * 0.4,總分取整。如果沒有大眾評委,則 總分 = 專家評委平均分,總分取整。函數(shù)最終返回選手得分。
函數(shù)接口 int cal_score(int score[], int judge_type[], int n)
上機(jī)題目需要將函數(shù)驗(yàn)證,但是題目中默認(rèn)專家評委的個(gè)數(shù)不能為零,但是如何將這種專家數(shù)目為0的情形排除出去。
9月8日,騰訊面試題:
假設(shè)兩個(gè)字符串中所含有的字符和個(gè)數(shù)都相同我們就叫這兩個(gè)字符串匹配,比如:abcda和adabc,由于出現(xiàn)的字符個(gè)數(shù)都是相同,只是順序不同,所以這兩個(gè)字符串是匹配的。要求高效!
又是跟上述第3題中簡單題一的兄弟節(jié)點(diǎn)類似的一道題,我想,你們能想到的,?? 阿里云,搜索引擎中5億個(gè)url怎么高效存儲;
?? 一道C++筆試題,求矩形交集的面積:
在一個(gè)平面坐標(biāo)系上,有兩個(gè)矩形,它們的邊分別平行于X和Y軸。
其中,矩形A已知,ax1(左邊), ax2(右邊), ay1(top的縱坐標(biāo)), ay2(bottom縱坐標(biāo)).矩形B,類似,就是 bx1, bx2, by1, by2。這些值都是整數(shù)就OK了。要求是,如果矩形沒有交集,返回-1,有交集,返回交集的面積。int area(rect const& a, rect const& b){...} 點(diǎn)評: healer_kx:
補(bǔ)齊代碼,最好是簡潔的,別用庫。你可以寫你的輔助函數(shù),宏定義,代碼風(fēng)格也很重要。ri_aje:struct rect ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? {
// axis alignment assumed // bottom left is(x[0],y[0]), top right is(x[1],y[1])double x [2];double y [2];};
template
// return type changed to handle non-integer rects double area(rect const& a, rect const& b){
// perfectly adjacent rects are considered having an intersection of 0 area double const dx = min(a.x[1],b.x[1])max(a.y[0],b.y[0]);return dx>=0&&dy>=0 ? dx*dy :-1;?? } ?? 下面是一個(gè)簡短的證明。
對于平行于坐標(biāo)軸的矩形 r,假設(shè)其左下角點(diǎn)坐標(biāo)為(rx0,ry0),右上角點(diǎn)坐標(biāo)為(rx1,ry1),那么由 r 定義的無限有界點(diǎn)集為:{(x,y)|x in [rx0,rx1] && y in [ry0,ry1]}。
根據(jù)交集的定義,則任意二維點(diǎn)(x,y)在矩形 a,b 的交集內(nèi)等價(jià)于 {(x,y)|(x,y)in a 并且(x,y)in b} <==>
{(x,y)|x in [ax0,ax1] && x in [bx0,bx1] 并且 y in [ay0,ay1] && y in [by0,by1]} <==> {(x,y)|x in [max(ax0,bx0),min(ax1,bx1)] 并且 y in [max(ay0,by0),min(ay1,by1)]}
因此,交集矩形的邊長分別為 min(ax1,bx1)-max(ax0,bx0)和 min(ay1,by1)-max(ay0,by0)。注意當(dāng)交集為空時(shí)(a,b 不相交),則經(jīng)此法計(jì)算出來的交集邊長為負(fù)值,此事實(shí)可用于驗(yàn)證 a,b 的相交性。
鑒于笛卡爾積各個(gè)維度上的不相關(guān)性,此方法可擴(kuò)展到任意有限維線性空間,比如,三維空間中平行于坐標(biāo)軸的長方體的交集體積可以用類似的方法計(jì)算。
?? 2012年創(chuàng)新工場校園招聘最后一道筆試題:工場很忙
創(chuàng)新工場每年會組織同學(xué)與項(xiàng)目的雙選會,假設(shè)現(xiàn)在有M個(gè)項(xiàng)目,編號從1到M,另有N名同學(xué),編號從1到N,每名同學(xué)能選擇最多三個(gè)、最少一個(gè)感興趣的項(xiàng)目。選定之后,HR會安排項(xiàng)目負(fù)責(zé)人和相應(yīng)感興趣的同學(xué)一對一面談,每次面談持續(xù)半小時(shí)。由于大家平時(shí)都很忙,所以咱們要盡量節(jié)約時(shí)間,請你按照以下的條件設(shè)計(jì)算法,幫助HR安排面試。
1)同學(xué)很忙。項(xiàng)目負(fù)責(zé)人一次只能與一名同學(xué)面談,而同學(xué)會在自己第一個(gè)面試開始時(shí)達(dá)到工場,最后一個(gè)面試結(jié)束后離開工場,如果參加一個(gè)項(xiàng)目組的面試后不能立即參加下一個(gè)項(xiàng)目組的面試,就必須在工場等待。所以請盡可能讓同學(xué)的面試集中在某一時(shí)間段,減少同學(xué)在工場等待的時(shí)間。
2)項(xiàng)目負(fù)責(zé)人很忙。眾所周知,創(chuàng)業(yè)團(tuán)隊(duì)的負(fù)責(zé)人會有很多事情要做,所以他們希望能夠?qū)⒆约簠⑴c的面試集中在某一段時(shí)間內(nèi),請?jiān)诒WC1)的情況下,使得項(xiàng)目負(fù)責(zé)人等待的時(shí)間最少。
3)HR很忙。從第一輪面試開始以后,所有HR都必須等到最后一輪面試結(jié)束,所以需要在保證1)和2)的同時(shí),也能盡快解放掉所有的HR,即讓第一輪面試到最后一輪面試之間持續(xù)的時(shí)間最短。
輸入(以文件方式輸入,文件名為iw,例如iw.in):
第1行...第n行:同學(xué)的編號 項(xiàng)目的編號
樣例(數(shù)據(jù)間用空格隔開,兩個(gè)0表示輸入結(jié)束):
112
0 0
表示M=3,N=3,編號為1的同學(xué)選擇了項(xiàng)目1,2和3,編號為2的同學(xué)選擇了項(xiàng)目1,編號為3的同學(xué)選了項(xiàng)目1和2
輸出(以文件方式輸出,文件名為iw,例如iw.out):
第1行:編號為1的項(xiàng)目依次面試新同學(xué)的編號序列
第2行:編號為2的項(xiàng)目依次面試新同學(xué)的編號序列...第n行:編號為n的項(xiàng)目依次面試新同學(xué)的編號序列
樣例(數(shù)據(jù)間用空格隔開,0表示沒有面試):3 21 0 0 0 1
表示編號為1的項(xiàng)目在第一輪面試編號為1的同學(xué),第二輪面試編號為3的同學(xué),第三輪面試編號為2的同學(xué)
編號為2的項(xiàng)目在第一輪面試編號為3的同學(xué),第二輪面試編號為1的同學(xué),第二輪不用面試
編號為3的項(xiàng)目在第一輪和第二輪都不用面試,第三輪面試編號為1的同學(xué)
4**9 的筆試題,比較簡單: 1.求鏈表的倒數(shù)第二個(gè)節(jié)點(diǎn)
2.有一個(gè)整數(shù)數(shù)組,求數(shù)組中第二大的數(shù) 阿里巴巴二道題 第一道:
對于給定的整數(shù)集合S,求出最大的d,使得a+b+c=d。a,b,c,d互不相同,且都屬于S。集合的元素個(gè)數(shù)小于等于2000個(gè),元素的取值范圍在[-2^28,2^281)^2)。最后我給出了一個(gè)巧妙的證明。然后發(fā)現(xiàn)如果是m*n的矩陣也是類似的答案,不局限于方陣。此外,題目具體描述可以看看這里:
?? 9月27日,小米兩面:
一面:
除了聊研究,就一道題
數(shù)組里找到和最接近于0的兩個(gè)值。二面:
行列有序的矩陣查找一個(gè)數(shù)
直方圖最大矩形。點(diǎn)評:這里有此題的具體表述及一份答案: 3 next_permutation 字符串匹配 含有* ?(寫代碼)
實(shí)現(xiàn)strcpy memmove(必須寫代碼)//void * memmove(void * destination, const void * source, size_t num);)?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? //是
//最簡單的方法是直接復(fù)制,但是由于它們可能存在內(nèi)存的重疊區(qū),因此可能覆蓋了原有數(shù)據(jù)。//比如當(dāng)source+count>=dest&&source //解決辦法是從后往前拷貝。//對于其它情況,則從前往后拷貝。 void* memmove(void* dest, void* source, size_t count){ void* ret = dest; if(dest <= source || dest >=(source + count)){ //正向拷貝 //copy from lower addresses to higher addresses while(count--)*dest++ = *source++;} else { //反向拷貝 //copy from higher addresses to lower addresses dest += count1;?? ?? ?? ?? ?? while(count--)*dest--= *source--;} return ret;} ?? 6 讀數(shù)(千萬億,百萬億??)變?yōu)閿?shù)字(說思路即可,字符串查找,填寫各個(gè)權(quán)值的字段,然后判斷是否合法,讀前面那些×權(quán)值,累加)。?? 9月27日,Hulu 2013北京地區(qū)校招筆試題 填空題: 1、中序遍歷二叉樹,結(jié)果為ABCDEFGH,后序遍歷結(jié)果為ABEDCHGF,那么前序遍歷結(jié)果為? 2、對字符串HELL0_HULU中的字符進(jìn)行二進(jìn)制編碼,使得字符串的編碼長度盡可能短,最短長度為? 3、對長度12的有序數(shù)組進(jìn)行二分查找,目標(biāo)等概率出現(xiàn)在數(shù)組的每個(gè)位置上,則平均比較次數(shù)為? 4、一副撲克(去王),每個(gè)人隨機(jī)的摸兩張,則至少需要多少人摸牌,才能保證有兩個(gè)人抽到同樣的花色。 5、x個(gè)小球中有唯一一個(gè)球較輕,用天平秤最少稱量y次能找出這個(gè)較輕的球,寫出y和x的函數(shù)表達(dá)式y(tǒng)=f(x)6、3的方冪及不相等的3的方冪的和排列成遞增序列1,3,4,9,10,12,13??,寫出數(shù)列第300項(xiàng) 7、無向圖G有20條邊,有4個(gè)度為4的頂點(diǎn),6個(gè)度為3的頂點(diǎn),其余頂點(diǎn)度小于3,則G有多少個(gè)頂點(diǎn) 8、桶中有M個(gè)白球,小明每分鐘從桶中隨機(jī)取出一個(gè)球,涂成紅色(無論白或紅都涂紅)再放回,問小明將桶中球全部涂紅的期望時(shí)間是? 9、煤礦有3000噸煤要拿到市場上賣,有一輛火車可以用來運(yùn)煤,火車最多能裝1000噸煤,且火車本身需要燒煤做動力,每走1公里消耗1噸煤,如何運(yùn)煤才能使得運(yùn)到市場的煤最多,最多是多少? 10、1,2,3,4?..n,n個(gè)數(shù)進(jìn)棧,有多少種出棧順序,寫出遞推公式(寫出通項(xiàng)公式不得分) 11、宇宙飛船有100,000位的存儲空間,其中有一位有故障,現(xiàn)有一種Agent可以用來檢測故障,每個(gè)Agent可以同時(shí)測試任意個(gè)位數(shù),若都沒有故障,則返回OK,若有一位有故障,則失去響應(yīng)。如果有無限多個(gè)Agent可供使用,每個(gè)Agent進(jìn)行一次檢測需要耗費(fèi)1小時(shí),現(xiàn)在有2個(gè)小時(shí)時(shí)間去找出故障位,問最少使用多少個(gè)Agent就能找出故障。 (總共12道填空題,還有一道太復(fù)雜,題目很長,還有示意圖,這里沒有記錄下來)大題: 1、n個(gè)數(shù),找出其中最小的k個(gè)數(shù),寫出代碼,要求最壞情況下的時(shí)間復(fù)雜度不能高于O(n logk) 2、寫程序輸出8皇后問題的所有排列,要求使用非遞歸的深度優(yōu)先遍歷 3、有n個(gè)作業(yè),a1,a2?..an,作業(yè)aj的處理時(shí)間為tj,產(chǎn)生的效益為pj,最后完成期限為dj,作業(yè)一旦被調(diào)度則不能中斷,如果作業(yè)aj在dj前完成,則獲得效益pj,否則無效益。給出最大化效益的作業(yè)調(diào)度算法。?? 有道的一個(gè)筆試題,1-9,9個(gè)數(shù)組成三個(gè)三位數(shù),且都是完全平方數(shù)(三個(gè)三位數(shù) 占據(jù) 9個(gè)數(shù))求解法。?? 點(diǎn)評@林晚?xiàng)?歸云見鴻:(a*10+b)(a*10+b)100a^2+20ab+b^2 a 屬于 [1,2,3] a=3,b=1 31 961, a=2,b=3 23 529 400+40b+b^2 25 625 27 729 28 784 29 841 a=1,b=3 13 169 100+20b+b^2 14 196 16 256 17 289 18 324 19 361 =>最終唯一解 529 784 361 具體代碼如下(3個(gè)for循環(huán),然后hash): ?? 9月28日,大眾點(diǎn)評北京筆試題目: 1.一個(gè)是跳臺階問題,可以1次一級,1次兩級,1次三級,求N級的跳法一共多少種? 點(diǎn)評:老題,?? 2.一個(gè)文件有N個(gè)單詞,每行一個(gè),其中一個(gè)單詞出現(xiàn)的次數(shù)大于N/2,怎么樣才能快速找出這個(gè)單詞? 點(diǎn)評:還是老題,?? 大眾點(diǎn)評前面還有30道邏輯題,15道文字推理,15道數(shù)學(xué)推理,一共只給20min。?? 9月28日,網(wǎng)易筆試題: 1、英雄升級,從0級升到1級,概率100%。 從1級升到2級,有1/3的可能成功;1/3的可能停留原級;1/3的可能下降到0級; 從2級升到3級,有1/9的可能成功;4/9的可能停留原級;4/9的可能下降到1級。每次升級要花費(fèi)一個(gè)寶石,不管成功還是停留還是降級。求英雄從0級升到3級平均花費(fèi)的寶石數(shù)目。 點(diǎn)評:題目的意思是,從第n級升級到第n+1級成功的概率是(1/3)^n(指數(shù)),停留原級和降級的概率一樣,都為[1-(1/3)^n]/2)。 2、將一個(gè)很長的字符串,分割成一段一段的子字符串,子字符串都是回文字符串。有回文字符串就輸出最長的,沒有回文就輸出一個(gè)一個(gè)的字符。例如: habbafgh 輸出h,abba,f,g,h。 點(diǎn)評:一般的人會想到用后綴數(shù)組來解決這個(gè)問題,?? 10月9日,騰訊一面試題: 有一個(gè)log文件,里面記錄的格式為: QQ號: 時(shí)間: flag: 如123456 14:00:00 0 123457 14:00:01 1 其中flag=0表示登錄 flag=1表示退出 問:統(tǒng)計(jì)一天平均在線的QQ數(shù)。 點(diǎn)評:第8題后的騰訊面試題,讀者可以參看之。 ?? 10月9日,騰訊面試題: 1.有一億個(gè)數(shù),輸入一個(gè)數(shù),找出與它編輯距離在3以內(nèi)的書,比如輸入6(0110),找出0010等數(shù),數(shù)是32位的。2.每個(gè)城市的IP段是固定的,新來一個(gè)IP,找出它是哪個(gè)城市的,設(shè)計(jì)一個(gè)后臺系統(tǒng)。?? 10月9日,YY筆試題: 輸出一個(gè)字符串中沒有重復(fù)的字符。如“baaca”輸出“bac”。對于一個(gè)多叉樹,設(shè)計(jì)TreeNode節(jié)點(diǎn)和函數(shù),返回先序遍歷情況下的下一個(gè)節(jié)點(diǎn)。函數(shù)定義為TreeNode* NextNode(TreeNode* node)3 分割字符串。 對于一個(gè)字符串,根據(jù)分隔符seperator,把字符串分割,如果存在多個(gè)分隔符連在一起,則當(dāng)做一個(gè)分隔符。如果分隔符出現(xiàn)在“ ”符號之間,則不需要分割“ ”之間的字符。比如a++abc,分隔符為+,輸出a abc a+“hu+” 輸出a hu+ a++“HU+JI 輸出a ”HU JI。 請根據(jù)上述需求完成函數(shù):void spiltString(string aString,char aSeperator)。?? 10月9日,趕集網(wǎng)筆試 ?? 10月9日,阿里巴巴2013校園招聘全套筆試題(注:下圖中所標(biāo)答案不代表標(biāo)準(zhǔn)答案,有問題,歡迎留言評論) 上述第15題,填空:lower+(upper-lower)/2 lower mid upper 0 6 12 7 9 12 7 7 8 8 8 8 比較4次 上述第16題,解答如下圖所示: 上述第17題,解答如下圖所示: 18、甲包8個(gè)紅球 2個(gè)藍(lán)球,乙包2個(gè)紅球 8個(gè)藍(lán)球。拋硬幣決定從哪個(gè)包取球,取了11次,7紅4藍(lán)。注,每次取后還放進(jìn)去,只拋一次硬幣。問選的是甲包的概率? 點(diǎn)評: 貝葉斯公式 + 全概率公式作答(參看鏈接:http://)。具體解答如下圖所示: 注:上述第15~18的解答全部來自讀者Lei Lei來信給出的解答,特此感謝。有任何問題,歡迎隨時(shí)討論&指正,同時(shí),更歡迎其他朋友也一起來做這些題目(你的答案一經(jīng)選用,我可以根據(jù)你的要求,貼出你的個(gè)人主頁或微博地址或博客地址)。 19、已知一個(gè)n個(gè)元素的數(shù)組,第i個(gè)元素在排序后的位置在[i-k,i+k]區(qū)間,k< 10月10日,暴風(fēng)影音筆試: 都是非常基礎(chǔ)的題目,這是其中一道:一個(gè)整數(shù)轉(zhuǎn)換成二進(jìn)制后,問里面有多少個(gè)1。10月10日人人網(wǎng)面試題 第一面: 1、(1)++i 和 i++,那個(gè)效率高? (2)++++i,i++++,哪個(gè)是合法的? (3)實(shí)現(xiàn)int型的++i 和 i++操作。 2、一段程序,求輸出。(考察靜態(tài)變量和模版類) ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? int g = 0;template int main(){ ?? ?? ?? ?? ?? ?? ?? cout << B 3、(1)實(shí)現(xiàn)二進(jìn)制轉(zhuǎn)十進(jìn)制。 (2)如果有下面這種能直接求二進(jìn)制轉(zhuǎn)十進(jìn)制的代碼,是怎么實(shí)現(xiàn)的? binary<1>::value;// 結(jié)果為1 binary<11>::value;// 結(jié)果為3 4、volatile、explicit、mutable表示的含義。 5、求整形數(shù)組的一個(gè)子數(shù)組,使得該子數(shù)組所有元素的和的絕對值最大。 6、(1)寫求單鏈表是否有環(huán)的算法。(2)如果有環(huán),如何找出環(huán)的第一個(gè)結(jié)點(diǎn)。 7、實(shí)現(xiàn)單例模式。二面: 1、一個(gè)文本,一萬行,每行一個(gè)詞,統(tǒng)計(jì)出現(xiàn)頻率最高的前10個(gè)詞(詞的平均長度為Len)。并分析時(shí)間復(fù)雜度。 2、求數(shù)組中最長遞增子序列。 ?? 10月10日,網(wǎng)易2013校園招聘全套筆試題: ?? 10月10日,網(wǎng)易,數(shù)據(jù)挖掘工程師: 1,簡述你對數(shù)據(jù)與處理的認(rèn)識; 2,簡述你對中文分詞的理解,說明主要難點(diǎn)和常用算法; 3,常見的分類算法有哪些; 4,簡述K-MEANS算法; 5,設(shè)計(jì)一個(gè)智能的商品推薦系統(tǒng); 6,簡述你對觀點(diǎn)挖掘的認(rèn)識。其它題目同 點(diǎn)評:其它題目與上述第56題第一部分所述相同。 一、選擇題(1)~(10)每小題2分,(11)~(50)每小題1分,共60分) 下列各題A)、B)、C)、D)四個(gè)選項(xiàng)中,只有一個(gè)選項(xiàng)是正確的,請將正確的選項(xiàng)涂寫在答題卡相應(yīng)位置上,答在試卷上不得分。 (1)在數(shù)據(jù)結(jié)構(gòu)中,從邏輯上可以把數(shù)據(jù)結(jié)構(gòu)分為_______。 A)動態(tài)結(jié)構(gòu)和靜態(tài)結(jié)構(gòu) B)緊湊結(jié)構(gòu)和非緊湊結(jié)構(gòu) C)線性結(jié)構(gòu)和非線性結(jié)構(gòu) D)內(nèi)部結(jié)構(gòu)和外部結(jié)構(gòu) 答案:C 評析:邏輯結(jié)構(gòu)反映數(shù)據(jù)元素之間的邏輯關(guān)系,線性結(jié)構(gòu)表示數(shù)據(jù)元素之間一對一的關(guān)系,非線性結(jié)構(gòu)表示數(shù)據(jù)元素之間一對多或多對一的關(guān)系。 (2)若進(jìn)棧序列為l,2,3,4,進(jìn)棧過程中可以出棧,則下列不可能的一個(gè)出棧序列是_______。 A)1,4,3,2 B)2,3,4,l C)3,1,4,2 D)3,4, 2,1 答案:C 評析:棧是一種后進(jìn)先出表,選項(xiàng)c中,先出棧的是3,說明此時(shí)棧內(nèi)必然有1,2,由于l先于2進(jìn)棧,所以l不可能在2之前出棧,故選項(xiàng)C這種出棧序列是不可能的。 (3)排序方法中,將整個(gè)無序序列分割成若干小的子序列并分別進(jìn)行插入排序的方法,稱為_______。 A)希爾排序 B)冒泡排序 C)插入排序 D)選擇排序 答案:A 評析:希爾排序法的基本思想是:將整個(gè)無序序列分割成若干小的子序列分別進(jìn)行插入排序。 (4)在順序表(3,6,8,10,12,15,16,18,21,25,30)中,用二分法查找關(guān)鍵碼值11,所需的關(guān)鍵碼比較次數(shù)為_______。 A)2 B)3 C)4 D)5 答案:C 評析:二分法查找是用關(guān)鍵碼與線性表的中間元素比較,然后根據(jù)比較結(jié)果來判斷是結(jié)束查找,還是在左邊或者右邊子表按相同的方法繼續(xù)查找。本題中,與ll比較的關(guān)鍵碼分別為15,8,10,12四個(gè)。 (5)對于n個(gè)結(jié)點(diǎn)的單向鏈表(無表頭結(jié)點(diǎn)),需要指針單元的個(gè)數(shù)至少為_______。 A)n-1 B)n C)n+l D)2n 答案:C 評析:在n個(gè)結(jié)點(diǎn)的單向鏈表(無表頭結(jié)點(diǎn))中,每個(gè)結(jié)點(diǎn)都有一個(gè)指針單元(即指針域),加上頭指針,至少需要n+1個(gè)指針單元。 (6)在軟件開發(fā)過程中,軟件結(jié)構(gòu)設(shè)計(jì)是描述_______。 A)數(shù)據(jù)存儲結(jié)構(gòu) B)軟件體系結(jié)構(gòu) C)軟件結(jié)構(gòu)測試 D)軟件控制過程 答案:B 評析:從工程管理角度來看,軟件設(shè)計(jì)分兩步完成:概要設(shè)計(jì)和詳細(xì)設(shè)計(jì)。概要設(shè)計(jì)(又稱結(jié)構(gòu)設(shè)計(jì))將軟件需求轉(zhuǎn)化為軟件體系結(jié)構(gòu)、確定系統(tǒng)級接口、全局?jǐn)?shù)據(jù)結(jié)構(gòu)或數(shù)據(jù)庫模式。 (7)模塊本身的內(nèi)聚是模塊獨(dú)立性的重要性度量因素之一。在7類內(nèi)聚中,具有最強(qiáng)內(nèi)聚 的一類是_______。 A)順序性內(nèi)聚 B)過程性內(nèi)聚 C)邏輯性內(nèi)聚 D)功能性內(nèi)聚 答案:D 評析:內(nèi)聚性是一個(gè)模塊內(nèi)部各元素間彼此結(jié)合的緊密程度的度量。內(nèi)聚共有7類,它們之間的內(nèi)聚性由弱到強(qiáng)排列順序?yàn)椋号既粌?nèi)聚、邏輯內(nèi)聚、時(shí)間內(nèi)聚、過程內(nèi)聚、通信內(nèi)聚、順序內(nèi)聚和功能內(nèi)聚。 (8)數(shù)據(jù)存儲和數(shù)據(jù)流都是_______,僅僅是所處的狀態(tài)不同。 A)分析結(jié)果 B)事件 C)動作 D)數(shù)據(jù) 答案:D 評析:數(shù)據(jù)流圖有4種成分:源點(diǎn)或終點(diǎn)、處理、數(shù)據(jù)存儲和數(shù)據(jù)流。數(shù)據(jù)存儲是處于靜止?fàn)顟B(tài)的數(shù)據(jù),數(shù)據(jù)流是處于運(yùn)動中的數(shù)據(jù)。 (9)數(shù)據(jù)的完整性是指數(shù)據(jù)的正確性、有效性和_______。 A)可維護(hù)性 B)獨(dú)立性 C)安全性 D)相容性 答案:D 評析:數(shù)據(jù)模型的完整性規(guī)則是給定的數(shù)據(jù)模型中數(shù)據(jù)及其聯(lián)系所具有的制約和依存規(guī)則,用以限定符合數(shù)據(jù)模型的數(shù)據(jù)庫狀態(tài)及其狀態(tài)的變化,以保證數(shù)據(jù)的正確性、有效性和相容性。 (10)關(guān)系代數(shù)運(yùn)算是以_______為基礎(chǔ)的運(yùn)算。 A)關(guān)系運(yùn)算 B)謂詞運(yùn)算 C)集合運(yùn)算 D)代數(shù)運(yùn)算 答案:C 評析:關(guān)系代數(shù)運(yùn)算是以關(guān)系代數(shù)作為運(yùn)算對象的一組高級運(yùn)算的集合。它的基本操作是并、交、差、笛卡爾積,另外還包垂直分割(投影)、水平分割(選擇)、關(guān)系的結(jié)合(連接)等。 (11)能將高級語言程序轉(zhuǎn)換成目標(biāo)語言程序的是_______。 A)調(diào)試程序 B)解釋程序 C)編譯程序 D)編輯程序 答案:C 評析:用高級語言編寫的程序稱為“源程序”,而計(jì)算機(jī)只能識別和執(zhí)行由0和l組成的二進(jìn)制指令,所以高級語言必須先用一種稱為“編譯程序”的軟件,把源程序翻譯成二進(jìn)制形式的“目標(biāo)程序”。 (12)_______是構(gòu)成c語言程序的基本單位。 A)函數(shù) B)過程 C)子程序 D)子例程 答案:A 評析:c程序是由函數(shù)構(gòu)成的。一個(gè)c源程序至少包含一個(gè)main函數(shù),也可以包含一個(gè)main函數(shù)和若干個(gè)其他函數(shù),因此,函數(shù)是c程序的基本單位。 (13)可以在C語言中用做用戶標(biāo)識符的是_______。 A)void B)as_b3 C)for D)2c define _123-abc Do WORD If cas SIG 答案:B 評析:c語言規(guī)定,標(biāo)識符只能由字母、數(shù)字和下劃線三種符號組成,而且第一個(gè)字符必須是字母或下劃線。另外還需要注意的是關(guān)鍵字不能作標(biāo)識符。選項(xiàng)A中void,C中for都為關(guān)鍵字,D中2c以字母開頭。 (14)若有以下類型說明語句: char w;int x;float y,z; 則表達(dá)式w*x+z-y的結(jié)果為________類型。 A)float B)char C)int D)double 答案:A 評析:在進(jìn)行運(yùn)算時(shí),不同類型的數(shù)據(jù)參加運(yùn)算,需要先將其轉(zhuǎn)換成同一類型的數(shù)據(jù),然后再進(jìn)行運(yùn)算。轉(zhuǎn)換的順序由低到高為:char,short→int→unsigned→long→double→float,故結(jié)果為float型。 (15)main(() { float x=123A56; printf(“%-5.2fn”,x); } 以上程序輸出的結(jié)果是________。 A)123.4 B)123.5 C)123.45 D)123.46 答案:D 評析:f格式符,用來輸出實(shí)數(shù),以小數(shù)形式輸出?!埃?m.nf”的含義是:輸出數(shù)據(jù)共占m列,其中n位小數(shù),如果輸出位數(shù)小于m。則右端補(bǔ)空格。如果總長度大于列數(shù),則按實(shí)際情況四舍五入輸出。 (16)下面語句的輸出結(jié)果是________。 Printf(“%d\n”,strlen(“\t\”\065\xff\n”)); A)14 B)8 C)5 D)輸出項(xiàng)不合法,無正常輸出 答案:C 評析:在c語言中,以“\”開頭的字符均為轉(zhuǎn)義字符,其中“\”后可跟l~3位八進(jìn)制數(shù)或在“\”后跟字母x及l(fā)~2位十六進(jìn)制數(shù),以此來代表一個(gè)特定的字符。 (17)下列程序的輸出結(jié)果是________。 main() { int a=0,b=0,c=0; if(++a>0lI++b>0)++c; printf(“\na=%d,b=%d,c=%d”,a,b,C); } A)a=0,b=0,c=0 B)a=l,b=l,c=1 C)a=l,b=O, c=I D)a=0, b=1.c=1 答案:C 評析: “︱︱”是或運(yùn)算,它有個(gè)“短路”的特點(diǎn)需特別注意,當(dāng)“︱︱”運(yùn)算符左邊的表達(dá)式的值為真時(shí),則程序就不再對“︱︱”右邊的表達(dá)式的值進(jìn)行運(yùn)算,而是使得整個(gè)表達(dá)式的值直接為真。 (18)下列程序的輸出結(jié)果是_________。 Main() { int i; for(i=1;i+l;i++) { if(i>4){printlf(”%d”,i++);break;} } printf(“%d”,i++); } A)55 B)56 C)程序錯誤,沒有輸出 D)循環(huán)條件永遠(yuǎn)為真,死循環(huán) 答案:B 評析:本程序中有個(gè)for循環(huán),但注意到for循環(huán)的條件是“i+l”,也就是只要i+l的值為真(非零值均為真),就執(zhí)行循環(huán)。當(dāng)i=l的時(shí),i+l的值為真,判斷if條件不成立,執(zhí)行i++,輸出i的值為5。 (19)下列程序的輸出結(jié)果是_________。 #define A 100 main() { int i=O,sum=O; do{ if(I==(i/2)*2)continue; sum+=i;第四篇:c語言筆試題總結(jié)