華為C++面試題
suningin華為招聘--前人經驗(1)
這篇文章是寫給2007屆的畢業生的,我想我這些日子的經歷應該能給2007屆的師弟和師妹們將來的校園招聘提供點幫助。
一、準備階段:
在華為面試之前,我把《軟體設計師教程》大概的複習了一遍,時間實在太緊迫了,有些概念我也只是很粗糙地掠過去。10號下午還到圖書館借了一本《程式設計師面試攻略》,11號下午就差不多把那本書大概地啃完。
二、筆試:
11號,收到簡訊通知當晚7:00在E棟筆試(只要是註冊了電子簡歷的同學都有資格),考試種類分兩種:硬體和軟體,共四類題:填空,選擇,改錯,程式設計。基本上都是一些C/C++語言題,資料結構的樹的前序、中序及後序排列,計算機網路裡的IP報文中的TTL(Time to live),資料庫的操作等等;程式題有兩道,一道題是關於資料結構的,另外有一道是“字串A插入字串B中”。
三、面試:
第二天就有人接到通知去面試了,我們班一位同學去了,他很牛B,從第一輪到第四輪一
直很順利。我是第三天才和我們寢室另外的一位同學才接到面試通知的(不過我聽說我們這一批接到通知的筆試分數普遍都很高),當然在前三天的等待時間裡,我心情很鬱悶,我還以為我沒有慧通的面試資格了,所以一直在玩,希望有時真的是期而不遇,遇而不期阿。(其實筆試這一輪刷的人不多,大家以後沒必要像我這樣子提前就爆棄了)
我下午4:00準時到凱萊大酒店,一進去就感覺一股熱氣,大廳裡也許是因為太熱或者太緊張的緣故,每個人的臉都很紅,很紅。大概等了半個小時,我的心也跳得好厲害,我就到門口舒緩下情緒,很快一位帥哥就領我去第一輪面試了,他問我會什麼,**,這問題該怎麼答阿,然後我說我是電子科學與技術專業的,計算機基本上是靠自學的,大概他體會到自學的不易,他給我出了5道程式設計題,雖然很多,但基本上都不很難。(我一同專業的哥們雖然只有一道題,但卻是用C語言編桌球的運動軌跡,媽啊,對於C語言的影象功能我都沒接觸到過阿),我的題目是:
1、1到100之間的所有素數之和;
2、佇列的實現;
3、選首領(有一群人圍在一圈,從第一個人開始數1、2、3,數到3者退出,用迴圈連結串列實現)
4、字串匹配問題(int countABC(* s) 輸入任何一串字串,計算機其中有連續ABC子字串的個數 )
5、用陣列儲存超大數的問題。
6、詢問我作業系統的程序和執行緒的區別
幸好這些題目在筆試前我就都已經見過了,雖然第四個題目,面試老師說我執行效率不高,但可以過得去了。哈哈,他直接通知我去進行第二輪面試了。
第二輪是資格面試,沒多大問題,就聊聊家鄉,聊聊自己的情況,這一關只要說話有分寸,一般都可以通過。第二輪面試完,就快到了晚飯的時間了,晚飯當然是慧通免費提供的,晚飯一過後,我就被一被稱作是部長的面試官叫了進去,這一關一進去他直接拿了我《軟體設計書》提問我:
1、ping命令使用的是哪種報文?
2、OSI分哪幾個層,IP是在哪個層?
3、雜湊表的問題
4、為什麼要採取二叉樹這種資料結構?(折半查詢)
5、兩臺計算機中的程序怎麼互相通訊,我說通過IP唄,他說除了IP呢?我卡住了,他說你聽說過五元組嗎?我只好老老實實的回答說不知道,然後他在那裡給我解釋一通,但我還是沒搞明白,回來翻潘愛民老師的《計算機網路書》
也沒有。這一輪雖然第5個問題我有點卡殼,但老師說我畢竟是自學,還表揚了我,說我已經很不錯了。面試完已經好晚了,華為的MM通知我第二天繼續去進行第四輪的面試。
第二天,我按時到了考試地點,這一天,明顯感覺氣氛沒有第一天的好,垂頭喪氣的好多。很快就通知我去面試了,這一輪面試的老師明顯態度比前幾輪差多了,問的問題都有點讓我透不過氣來,但終於挺了過去,最後他直接點到桌子上
的一個題目:
void main()
{
char *p;
*p=-130;
printf("%d",*p);
}
正確的答案是126,原因:-130在計算機裡面儲存形式是11111111-01111110(取反碼的形式),因為C裡面的CHAR是8位的,所以,最高位1去掉,剩下01111110。
四、些許體會
面試,就是面試,不是學習,考試。你現在會多少東西固然重要,但更重要的是你得
讓面試官知道,所以面試時把你的知識表達出來是最重要的。切記!面試表達是關鍵,你
可以先把自己熟悉的整理一下,不至於面試的時候磕磕碰碰的。面試,好比下棋。把握局
面,掌握主動權是關鍵。一旦你把面試官成功引入你的領地,讓他把注意力關注在你熟悉
的領域,無暇自顧,那就盡情發揮吧,已經成功了一大半。所以從面試官拿到你的簡歷起
,就主動出擊,別給他機會.另外,在大肆開學初,一定要把各位的專業課翻出來看看,考軟體的特別要多多看看基礎的C語言,想找到好工作一定要從骨子裡面重視起來。
1、1到100之間的所有素數之和;
int i = 1;
int j = 0;
bool change= 1;
int sum = 0;
for (i=1; i<100; i++)
{ for (j=2; j<i; j++)
{ if(i%j= =0)
{ change = 0;
break; 跳出J迴圈,I+1繼續判斷
}
}
if(change= =1)
sum +=i;
change = 1;
}
printf("%d\n",sum);
2、佇列的實現;(用陣列或者連結串列,定義好輸入和輸出即可)
3、選首領(有一群人圍在一圈,從第一個人開始數1、2、3,數到3者退出,用迴圈連結串列實現)
n個人圍成一圈,從第一個人開始依次從1到m迴圈報數,當報到m的時候此人出圈,直到圈 中只剩一人為止.求最後一個人的原始編號。
int yuesefu(int n, int m)
{ int i,r=0;
for (i=2;i<=n;i++) r=(r+m)%i;
return r+1;
}
//上面看不懂,程心建註釋
4、字串匹配問題(int countABC(* s) 輸入任何一串字串,計算機其中有連續ABC子字元 串的個數 )
int countABC(* s)
{
int i = 0;
int j = 0;
int num = 0;
scanf("%s",s);
int len = strlen(s);
for (i=0; i<len-3; i++)
{
j = strcmp(s+i,"ABC");
if(j= =0)
num++;
}
}
5、用陣列儲存超大數的問題。
這是陣列得一個應用,思想是我們定義一個數組,讓每一個元素得值都是從後到前以十 進製得方式存貯得,如過到了9下一位就要讓前一個元素進位為1,9變為0同時。
下面這個例子是要求一個40位的 n!的值
int data[40];//儲存40位書的整數陣列
int digit;//資料位數變數
int i,j,r,k;
int n;//使用者輸入值
for(i=1; i<40+1; i++)
data[i]=0;
data[0]=data[1]=1;
digit=1;
printf("enter a number :");
scanf("%d",&n);
for(i=1; i<n+1; i++)
{
for(j=1; j<digit+1; j++)
data[j]*=i;
for(j=1; j<digit+1; j++)
{
if(data[j]>10)
{
for(r=1; r<digit+1; r++)
{
if(data[digit]>10)//大於10時候位數加1
digit++;
data[r+1]+=data[r]/10;//進位增加
data[r]=data[r]%10;//去掉進位後得值
}
}
}
printf("%d! = ",i);
for(k =digit; k>0; k--)
printf("%d",data[k]);
printf("\n");
}
6、詢問我作業系統的程序和執行緒的區別
程序和執行緒都是由作業系統所體會的程式執行的基本單元,系統利用該基本單元 實現系統對應用的併發性。程序和執行緒的區別,簡而言之:一個程式至少有一個程序,一個程序至少有一個執行緒. 執行緒的劃分尺度小於程序,使得多執行緒程式的併發性高。 另外,程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大 地提高了程式的執行效率。
1、ping命令使用的是哪種報文?
PING命令使用ICMP的哪種code型別:Echo reply(回顯請求報文)
2、OSI分哪幾個層,IP是在哪個層?
osi:物理層、鏈路層、網路層、傳輸層、會話層、管理層、應用層。
tcp/ip:主機網路層、互聯層、傳輸層、應用層。ip是在互聯層
3、雜湊表的問題
主要用於快速查詢檢索方面
4、為什麼要採取二叉樹這種資料結構?
他折半查詢,可以減少查詢比較次數
5、五元組
二元組的定義:<K,R>
三元組的定義:<D,F,A>
五元組的定義:<V,O,G,M,S>
V是值的集合,O是操作的集合,G是構成名字的文法,M是儲存的集合,S是從G能構成的名字 幾個到M的對映.
iP報文中的五元組(即源IP地址,源埠號,目的IP地址,目的埠,協議)。
半相關
綜上所述,網路中用一個三元組可以在全域性唯一標誌一個程序:
(協議,本地地址,本地埠號)
這樣一個三元組,叫做一個半相關(half-association),它指定連線的每半部分。
全相關
一個完整的網間程序通訊需要由兩個程序組成,並且只能使用同一種高層協議。也就是 說,不可能通訊的一端用TCP協議,而另一端用UDP協議。因此一個完整的網間通訊需要 一個五元組來標識:
(協議,本地地址,本地埠號,遠地地址,遠地埠號)
這樣一個五元組,叫做一個相關(association),即兩個協議相同的半相關才能組合 成一個合適的相關,或完全指定組成一連線。
suningin詳解華為面試試題(1)
(if (a>-1e-6)&&a<1e-6) 判斷= =0 if(x < -0.000001 && x > 0.000001)判斷!=0 sizeof(a)=800 sizeof(a[2])=8 這裡要注意如果陣列名作為函式的形參後,它就是一個普通的指標了這時sizeof (a)=4指標佔4位(後面有) 32位系統中,字元型佔1位元組,整型佔4位元組,短整型佔2位元組,浮點型佔4位元組,雙精度佔8位元組。 (靜態儲存區中) |
共有四輪面試:
問題一:兩膝上型電腦連起來後拼不通,你覺得可能有哪些問題?
問題二:我們在南京,和深圳的網路是通的,但和北京的網路不通, 你以怎樣的順序檢查問題?
問題三:解釋什麼叫"透明"?什麼叫"網格"?
問題四:交換和路由的區別?VLAN的特點?
問題五:畫一個積分電路和一個微分電路。
問題六:知道現在的路由器是第幾代了嗎?
問題一:兩膝上型電腦連起來後ping不通,你覺得可能有哪些問題可能的原因大體有以下幾個:
1、網線不通;
2、某檯筆記本上的tcp/ip協議安裝的不完整;
3、ip地址配置有問題(不在一個網段上);
4、某檯筆記本上有防火牆,把icmp埠給遮蔽了(埠號:139)。
這個題的我是從osi模型上入手,從物理層往上一層層排除。
問題二:我們在南京,和深圳的網路是通的,但和北京的網路不通,你以怎樣的順序檢查問題?
我設想的順序是按照由近及遠的順序進行測試,如果是有vpn的話,只要確定兩端和本 地網路提供支援的公司之間的網路是連通的,其他的就交個那個公司來做了,如果是自 己維護的基於ddn一類的點對點網路,那麼找到路由表,從最近的路由器開始ping吧。
問題三:解釋什麼叫“透明”?什麼叫“網格”?
關於透明,我的理解就是一種開放的通訊,意味著應用程式可以與網路上它所知道地址的其它任何應用程式連線並會話,而在這個網路上的所有中間裝置不會干擾應用程式之間的資訊交換。
關於網格,就是把網路上所有的計算機進行整合使其成一臺超級計算 機,實現計算能力、儲存容量、資料和資訊資源等全方位的共享。 網格作為一種能帶來巨大處理、儲存能力和其他IT資源的新型網路,可以應付臨時之用。網格計算通過共享網路將不同地點的大量計算機相聯,從而形成虛擬的超級計算機,將各處計算機的多餘處理器能力合在一起,可為研究和其他資料集中應用提供巨大的處理能力。有了網格計算,那些沒有能力購買價值數百萬美元的超級計算機的機構,也能利用其巨大的計算能力。
問題四:交換和路由的區別?VLAN的特點?
交換技術和路由技術的最大區別在於他們定址的方式以及報文的轉發方式上,交換技術是發生在2層也就是資料鏈路層上,是直接利用mac地址建立會話;路由技術發生在網路層,需要通過ip地址建立路由表,然後進行資料通訊。在報文的轉發方式上,交換技術 是使用先收再轉,路由技術是採用邊收邊轉。
vlan(虛擬區域網)的主要特點就是安全,資訊只到達應該到達的地點。因此,防止了大部分基於網路監聽的入侵手段。通過虛擬網設定的訪問控制,使在虛擬網外的網路節點不能直接訪問虛擬網內節點。
問題五:畫一個積分電路和一個微分電路。
這個題目這裡不好給出圖片,呵呵,我還不會弄圖片,大家可以檢視電子書就好了,相信電子通訊的朋友都知道的。
問題六:知道現在的路由器是第幾代了嗎?
第幾代是華為公司提出的概念
第三代是基於分散式處理系統,軟體轉發,如華為的NE16E/08E/05,CISCO 7200/7500。
第四代是基於分散式處理系統,ASIC硬體轉發,如CISCO 12000
第五代是基於分散式處理系統,NP硬體轉發,如華為的NE80。
第六代是基於集群系統,啥轉發的不知道,例子也不知道。
還有一種回答,大家也參考一下:
從體系結構上看,路由器可以分為
第一代單匯流排單CPU結構路由器
第二代單匯流排主從CPU結構路由器
第三代單匯流排對稱式多CPU結構路由器
第四代多匯流排多CPU結構路由器
第五代共享記憶體式結構路由器
第六代交叉開關體系結構路由器和基於機群系統的路由器等多類。
suningin詳解華為面試試題(2)(本科生)華為面試題
1:OSI七層網路結構:物理層、資料鏈路層、網路層、傳輸層、會話層、表示層、應用層。
TCP/IP五層結構:物理層、資料鏈路層、互聯層、傳輸層、應用層。
四層 :主機-網路層、互聯層、傳輸層、應用層。
2:TCP/IP是一個協議集,對英特網中主機的定址方式,主機的命名機制,資訊的傳輸規則,以及各種服務功能作了約定.
IP協議是英特網中的交通規則,連入英特網中的每臺計算機及處於十字路口的路由器都必須熟知和遵守該交通規則。IP運行於互聯層。遮蔽各個物理網路的細節和差異。
TCP:傳輸控制協議,運行於傳輸層。利用IP層提供的服務,提供端到端的可靠的(TCP)服務.
UDP:使用者資料報協議,運行於傳輸層。利用IP層提供的服務,提供端到端的不可靠的(UDP)服務。
3:一般意義上說交換機是工作在資料鏈路層。但隨著科技的發展,現在有了三層交換機,三層交換機已經擴充套件到了網路層。也就是說:它等於“資料鏈路層 + 部分網路層”。交換機中傳的是幀。通過儲存轉發來實現的。
路由器是工作在網路層。路由器中傳的是IP資料報。主要是選址和路由。
交換機屬於OSI第二層即資料鏈路層裝置。它根據MAC地址定址,通過站表選擇路由,站表的建立和維護由交換機自動進行。
路由器屬於OSI第三層即網路層裝置,它根據IP地址進行定址,通過路由表路由協議產生。
交換機最大的好處是快速,路由器最大的好處是控制能力強。
4.比較“C++的類”和“C的struct”的區別沒什麼意思,他們的區別太大了,至少C的struct不能有成員函式。
比較“C++的類”和“C++的struct”還有點意思。主要體現在:
(1)class的預設成員訪問許可權是private,而struct是public;
(2)從class的的預設繼承是private繼承,從struct的預設繼承是public繼承。(Union是protected繼承)。
5.置於“~”是解構函式;解構函式因使用"~"符號(邏輯非運算子),表示它為逆建構函式,加上類名稱來定義;解構函式也是特殊的類成員函式,它沒有返回型別,沒有引數,不能隨意呼叫,也沒有過載,只有在類物件的生命期結束的時候,由系統自動呼叫。 有適放記憶體空間的做用!
虛擬函式是C++多型的一種表現
例如:子類繼承了父類的一個函式(方法),而我們把父類的指標指向子類,則必須把父類的該函式(方法)設為virtual(虛擬函式)。
使用虛擬函式,我們可以靈活的進行動態繫結,當然是以一定的開銷為代價。
如果父類的函式(方法)根本沒有必要或者無法實現,完全要依賴子類去實現的話,可以把此函式(方法)設為virtual 函式名=0 ;我們把這樣的函式(方法)稱為純虛擬函式。如果一個類包含了純虛擬函式,稱此類為抽象類
6.全域性變數是整個程式都可訪問的變數,誰都可以訪問,生存期在整個程式從執行到結束(在程式結束時所佔記憶體釋放),而區域性變數存在於模組(子程式,函式)中,只有所在模組可以訪問,其他模組不可直接訪問,模組結束(函式呼叫完畢),區域性變數就消失,所佔據的記憶體釋放。
作業系統和編譯器,可能是通過記憶體分配的位置來知道的,全域性變數分配在全域性資料段並且在程式開始執行的時候被載入。區域性變數則分配在堆疊裡面 。
8.8086的機器字長是16位,8086使用40個引腳的16個做地址/資料複用引腿來傳輸資料,一次讀寫過程由一個基本匯流排週期完成,它由4個時鐘(CLK)週期組成,按時間順序定義為T1、T2、T3、T4。在T1期間8086發出訪問目的地的地址訊號和地址鎖存選通訊號ALE;T2期間發出讀寫命令訊號RD、WR及其它相關訊號;T3期間完成資料的訪問;T4結束該匯流排週期。可見,地址與資料訊號不會同時出現在一個時鐘(CLK)週期,二者可以分時複用同一組引線。
suningin詳解華為筆試題(1)
suningin解答的華為筆試題
1.寫出判斷ABCD四個表示式的是否正確, 若正確, 寫出經過表示式中 a的值(3分)
int a = 4;
(A) a += (a++); (B) a += (++a) ; (C) (a++) += a; (D) (++a) += (a++);
a = ?
答:C錯誤,左側不是一個有效變數,不能賦值,可改為(++a) += a;改後答案依次為9,10,10,11
a++是先運算完了 A再加1;++a是先加1在運算,二者好像都不能單獨作為左值
2.某32位系統下, C++程式,請計算sizeof 的值(5分).
char str[] = “www.ibegroup.com”
char *p = str ;
int n = 10;
請計算
sizeof (str ) = ?(1)
sizeof ( p ) = ?(2)
sizeof ( n ) = ?(3)
void Foo ( char str[100]){
請計算 sizeof( str ) = ?(4)
void *p = malloc( 100 );
請計算 sizeof ( p ) = ?(5)
答:(1)17 (2)4 (3) 4 (4)4 (5)4
字串結束標誌符為\0,一般不寫,系統預設佔1位,32位系統中,字元型佔1位元組,整型佔4位元組,短整型佔2位元組,浮點型佔4位元組,雙精度佔8位元組,指標佔4位;這裡要注意如果陣列名作為函式的形參後,它就是一個普通的指標了這時sizeof(a)=4,
3. 回答下面的問題. (4分)
(1).標頭檔案中的 ifndef/define/endif 幹什麼用?預處理
答:防止標頭檔案被重複引用
(2). #include 《filename.h》和 #include “filename.h” 有什麼區別?
答:前者用來包含開發環境提供的庫標頭檔案,後者用來包含自己編寫的標頭檔案。查詢的
(3).在C++ 程式中呼叫被C 編譯器編譯後的函式,為什麼要加 extern “C”宣告?
答:函式和變數被C++編譯後在符號庫中的名字與C語言的不同,被extern "C"修飾的變數和函式是按照C語言方式編譯和連線的。由於編譯後的名字不同,C++程式不能直接呼叫C 函式。C++提供了一個C 連線交換指定符號extern“C”來解決這個問題。
(4). switch()中不允許的資料型別是?
答:實型
4. 回答下面的問題(6分)
(1).Void GetMemory(char **p, int num)
{ *p = (char *)malloc(num);}
void Test(void)
{ char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");由後面的串複製得前面的串
printf(str);
}
請問執行Test 函式會有什麼樣的結果?
答:輸出“hello”
(2). void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str); free掉的只是記憶體,並非指標本身,指標要在賦值為空在真正不存在
if(str != NULL)
{ strcpy(str, “world”);
printf(str);
}
}
請問執行Test 函式會有什麼樣的結果?
答:輸出“world”
正確,str經過Free後必須手工賦值為NULL,記憶體已經釋放了,str現在是一個野指標,所以,要養成釋放後,指標賦零的習慣,使用前變數初始化;free是釋放申請的記憶體空間,釋放了之後該變數的值是一個隨機值,因而需要自己賦NULL;就象某個人死了,但是沒有去派出所去登出戶口, 結果你去查,發現他還"活著"~~~~~~~~~`於是你想給他打電話,就見鬼了啊--------程式死了
(3). char *GetMemory(void)
{ char p[] = "hello world";
return p;
}
void Test(void)
{ char *str = NULL;
str = GetMemory();
printf(str);
}
請問執行Test 函式會有什麼樣的結果?
答:無效的指標,輸出不確定
char p[] = "hello world";
return p;的p[]陣列為函式內的區域性自動變數,在函式返回後,記憶體已經被釋放。這是許多程式設計師常犯的錯誤,其根源在於不理解變數的生存期。
void GetMemory( char *p )
{
p = (char *) malloc( 100 );
}
void Test( void )
{
char *str = NULL;
GetMemory( str );
strcpy( str, "hello world" );
printf( str );
}
請問執行Test 函式會有什麼樣的結果?
程心建註釋//不能通過編譯,編譯報錯是某些記憶體區的內容不確定。
傳入中GetMemory( char *p )函式的形參為字串指標,在函式內部修改形參並不能真正的改變傳入形參的值,執行完char *str = NULL;GetMemory( str );後的str仍然為NULL;
再看看下面的一段程式有什麼錯誤
swap( int* p1,int* p2 )
{
int *p;
*p = *p1;
*p1 = *p2;
*p2 = *p;
}
在swap函式中,p是一個“野”指標,有可能指向系統區,導致程式執行的崩潰。在VC++中DEBUG執行時提示錯誤“Access Violation”。該程式應該改為:
swap( int* p1,int* p2 )
{
int p;
p = *p1;
*p1 = *p2;
*p2 = p;
}
5.編寫strcat函式(6分)
已知strcat函式的原型是char *strcat (char *strDest, const char *strSrc);
其中strDest 是目的字串,strSrc 是源字串。
(1)不呼叫C++/C 的字串庫函式,請編寫函式 strcat
答:
VC原始碼:
char * __cdecl strcat (char * dst, const char * src)
{
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while( *cp++ = *src++ ) ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
(2)strcat能把strSrc 的內容連線到strDest,為什麼還要char * 型別的返回值?
答:方便賦值給其他變數
6.MFC中CString是型別安全類麼?
答:不是,其它資料型別轉換到CString可以使用CString的成員函式Format來轉換
7.C++中為什麼用模板類。
答:(1)可用來建立動態增長和減小的資料結構
(2)它是型別無關的,因此具有很高的可複用性。
(3)它在編譯時而不是執行時檢查資料型別,保證了型別安全
(4)它是平臺無關的,可移植性
(5)可用於基本資料型別
8.CSingleLock是幹什麼的。
答:同步多個執行緒對一個數據類的同時訪問
9.NEWTEXTMETRIC 是什麼。Newtextmetric
答:物理字型結構,用來設定字型的高寬大小
10.程式什麼時候應該使用執行緒,什麼時候單執行緒效率高。
答:1.耗時的操作使用執行緒,提高應用程式響應
2.並行操作時使用執行緒,如C/S架構的伺服器端併發執行緒響應使用者的請求。
3.多CPU系統中,使用執行緒提高CPU利用率
4.改善程式結構。一個既長又複雜的程序可以考慮分為多個執行緒,成為幾個獨立或半獨立的執行部分,這樣的程式會利於理解和修改。
其他情況都使用單執行緒。
11.Windows是核心級執行緒麼。
答:見下一題
12.Linux有核心級執行緒麼。
答:執行緒通常被定義為一個程序中程式碼的不同執行路線。從實現方式上劃分,執行緒有兩種型別:“使用者級執行緒”和“核心級執行緒”。 使用者執行緒指不需要核心支援而在使用者程式中實現的執行緒,其不依賴於作業系統核心,應用程序利用執行緒庫提供建立、同步、排程和管理執行緒的函式來控制使用者執行緒。這種執行緒甚至在象 DOS 這樣的作業系統中也可實現,但執行緒的排程需要使用者程式完成,這有些類似 Windows 3.x 的協作式多工。另外一種則需要核心的參與,由核心完成執行緒的排程。其依賴於作業系統核心,由核心的內部需求進行建立和撤銷,這兩種模型各有其好處和缺點。使用者執行緒不需要額外的核心開支,並且使用者態執行緒的實現方式可以被定製或修改以適應特殊應用的要求,但是當一個執行緒因 I/O 而處於等待狀態時,整個程序就會被排程程式切換為等待狀態,其他執行緒得不到執行的機會;而核心執行緒則沒有各個限制,有利於發揮多處理器的併發優勢,但卻佔用了更多的系統開支。
Windows NT和OS/2支援核心執行緒。Linux 支援核心級的多執行緒
13.C++中什麼資料分配在棧或堆中,New分配資料是在近堆還是遠堆中?
答:棧: 存放區域性變數,函式呼叫引數,函式返回值,函式返回地址。由系統管理
堆: 程式執行時動態申請,new 和malloc申請的記憶體就在堆上
14.使用執行緒是如何防止出現大的波峰。
答:意思是如何防止同時產生大量的執行緒,方法是使用執行緒池,執行緒池具有可以同時提高排程效率和限制資源使用的好處,執行緒池中的執行緒達到最大數時,其他執行緒就會排隊等候。
15函式模板與類模板有什麼區別?
答:函式模板的例項化是由編譯程式在處理函式呼叫時自動完成的,而類模板的例項化必須由程式設計師在程式中顯式地指定。
16一般資料庫若出現日誌滿了,會出現什麼情況,是否還能使用?
答:只能執行查詢等讀操作,不能執行更改,備份等寫操作,原因是任何寫操作都要記錄日誌。也就是說基本上處於不能使用的狀態。
17 SQL Server是否支援行級鎖,有什麼好處?
答:支援,設立封鎖機制主要是為了對併發操作進行控制,對干擾進行封鎖,保證資料的一致性和準確性,行級封鎖確保在使用者取得被更新的行到該行進行更新這段時間內不被其它使用者所修改。因而行級鎖即可保證資料的一致性又能提高資料操作的迸發性。
19 關於記憶體對齊的問題以及sizeof()的輸出
答:編譯器自動對齊的原因:為了提高程式的效能,資料結構(尤其是棧)應該儘可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;然而,對齊的記憶體訪問僅需要一次訪問。
20 int i=10, j=10, k=3; k*=i+j; k最後的值是?
答:60,此題考察優先順序,實際寫成: k*=(i+j);,賦值運算子優先順序最低
21.對資料庫的一張表進行操作,同時要對另一張表進行操作,如何實現?
答:將操作多個表的操作放入到事務中進行處理
22.TCP/IP 建立連線的過程?(3-way shake)
答:在TCP/IP協議中,TCP協議提供可靠的連線服務,採用三次握手建立一個連線。
第一次握手:建立連線時,客戶端傳送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認;
第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也傳送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;
第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=k+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。
23.ICMP是什麼協議,處於哪一層?
答:Internet控制報文協議,處於網路層(IP層)
24.觸發器怎麼工作的?
答:觸發器主要是通過事件進行觸發而被執行的,當對某一表進行諸如UPDATE、 INSERT、 DELETE 這些操作時,資料庫就會自動執行觸發器所定義的SQL 語句,從而確保對資料的處理必須符合由這些SQL 語句所定義的規則。
25.winsock建立連線的主要實現步驟?
答:伺服器端:socker()建立套接字,繫結(bind)並監聽(listen),用accept()等待客戶端連線。
客戶端:socker()建立套接字,連線(connect)伺服器,連線上後使用send()和recv(),在套接字上寫讀資料,直至資料交換完畢,closesocket()關閉套接字。
伺服器端:accept()發現有客戶端連線,建立一個新的套接字,自身重新開始等待連線。該新產生的套接字使用send()和recv()寫讀資料,直至資料交換完畢,closesocket()關閉套接字。
26.動態連線庫的兩種方式?
答:呼叫一個DLL中的函式有兩種方法:
1.載入時動態連結(load-time dynamic linking),模組非常明確呼叫某個匯出函式,使得他們就像本地函式一樣。這需要連結時連結那些函式所在DLL的匯入庫,匯入庫向系統提供了載入DLL時所需的資訊及DLL函式定位。
2.執行時動態連結(run-time dynamic linking),執行時可以通過LoadLibrary或LoadLibraryEx函式載入DLL。DLL載入後,模組可以通過呼叫GetProcAddress獲取DLL函式的出口地址,然後就可以通過返回的函式指標呼叫DLL函數了。如此即可避免匯入庫檔案了。
27.IP組播有那些好處?
答:Internet上產生的許多新的應用,特別是高頻寬的多媒體應用,帶來了頻寬的急劇消耗和網路擁擠問題。組播是一種允許一個或多個傳送者(組播源)傳送單一的資料包到多個接收者(一次的,同時的)的網路技術。組播可以大大的節省網路頻寬,因為無論有多少個目標地址,在整個網路的任何一條鏈路上只傳送單一的資料包。所以說組播技術的核心就是針對如何節約網路資源的前提下保證服務質量。
1、填空選擇
1.1 二分法的時間複雜度.(答:log(N))
1.2 堆疊的工作方式. (答:先進後出表FILO(first in last out )佇列為先進先出FIFO)
1.3 迴圈連結串列的概念(答:連結串列的最後一個節點指向第一個節點)
1.4 圖的遍歷方式. (答:深度優先搜尋和廣度優先搜尋)
1.10 80x86的加減操作最後對標誌位的影響 (溢位標誌位)
1.12 private, protected, public型別的區別
2、 下列兩個程式設計題任選其一,如果都答去分最低的。(40分)
2.1 對於非負整數0,1,2,....,如果該整數左右對稱,我們稱該數為迴文數,如11, 121, 1331 等,請編一段C程式,查詢0到N內所有滿足(m, m*m, m*m*m)同時都是迴文數的m.
#include "stdio.h"
#include "stdlib.h"
int panduan(int numputin)//判斷是不是對稱數
{ int digit[10];//用於存放每個輸入數字的每位位數
int temp = numputin;
for(int digitstop=0; digitstop<10; digitstop++)//初始化
{ digit[digitstop] = 0;}
digitstop=0;
while(temp)//取出每位的數值
{ digit[digitstop] = temp%10;
digitstop++;
temp = temp/10 ;}
for(int i=0; i<digitstop/2; i++)//比較看看是不是對稱
{
if(digit[i]!=digit[digitstop-i-1])
{ numputin = 0;
break;
}
}
return numputin;
}
int main(int argc, char* argv[])
{
int numtop ;
int cishu = 0;//第一輸入數字相乘次數 如m,m*m,m*m*m
printf("putin top number more than 10: ");
scanf("%d",&numtop);
int *num = (int*)malloc(sizeof(int)*numtop);//開闢一段空間用於儲存要尋找的陣列
int temp = 0;
for(int i=10; i<numtop; i++)//個位數字我們這裡不考慮
{
num[i] = i;
num[i] = panduan(num[i]);//做判斷如果是不變,如果不是清零
cishu = 0;
temp = num[i];
while(num[i]!=0&&cishu<2)//cishu<2題目是要相乘兩次m,m*m,m*m*m
{
temp *= num[i];
temp = panduan(temp);
if(temp!=0)
cishu++;
else break;
}
if(cishu==2)//輸出結果
printf("\n%d is right\n",num[i]);
else
printf("no num!");
}
free(num);
return 0;
}
2.2 對於非負整數0,1,2,....n-1,隨機放入一個大小為n的一維陣列中,請用時間複雜度為O(n)的演算法,把他們調整為0,1,2,3,....n-1的順序,輔助空間為O(1),只允許用交換操作,一次只能交換兩個元素位置。
int main()
{
int a[] = {10,6,9,5,2,8,4,7,1,3};
int len = sizeof(a) / sizeof(int);
int temp;
for(int i = 0; i < len; )
{
temp = a[a[i] - 1];
a[a[i] - 1] = a[i];
a[i] = temp;
if ( a[i] == i + 1)
i++;
}
for (int j = 0; j < len; j++)
cout<<a[j]<<",";
return 0;
}
suningin詳解華為筆試題(3)
一、判斷題(對的寫T,錯的寫F並說明原因,每小題4分,共20分)
1、有陣列定義int a[2][2]={{1},{2,3}};則a[0][1]的值為0。(答:正確 )
2、int (*ptr) (),則ptr是一維陣列的名字。(答:錯誤 int (*ptr) ();定義一個指向函式的指標變數)
3、指標在任何情況下都可進行>,<,>=,<=,==運算。(答:錯誤 )
4、switch(c) 語句中c可以是int ,long,char ,float ,unsigned int 型別。(答:錯,不能用實型)
二、填空題(共30分)
1、在windows下,寫出執行結果,每空2分,共10分。
char str[ ]= "Hello";
char *p=str;
int n=10;
sizeof(str)=( ? );
sizeof(p)=( ? );
sizeof(n)=( ? );
void func(char str[100]){ 。。。};
sizeof(str)=( ? );
答案:6,4,4,4,
3、設int arr[]={6,7,8,9,10};
int *ptr=arr;指標指向陣列的第一個元素
*(ptr++)+=123; ptr++並不是元素加1,而是指標加1,相當於往後挪一個
printf("%d,%d",*ptr,*(++ptr));
結果是什麼?( ? )10分
答案:8,8。這道題目的意義不大,因為在不同的編譯器裡printf的引數的方向是不一樣的,在vc6.0下是從有到左,這裡先*(++ptr) 後*pt,於是結果為8,8
C中printf計算引數時是從右往左壓棧的
二、程式設計題(第一小題20,第二小題30分)
1、不使用庫函式,編寫函式int strcmp(char *source, char *dest),若相等則返回0,不等返回-1;
答案:一、
int strcmp(char * source, char * dest)
{
assert((source!=NULL)&&(dest!=NULL));
int i,j;
for(i=0; source[i]= =dest[i]; i++)
{
if(source[i]= ='\0' && dest[i]= ='\0')
return 0;
else
return -1;
}
}
答案:二、
int strcmp(char * source, char * dest)
{
while ( (*source != '\0') && (*source = = *dest))
{
source++;
dest++;
}
return ( (*source) - (*dest) ) ? -1 : 0;
}
2、寫一函式int fun(char *p)判斷一字串是否為迴文,是返回1,不是返回0,出錯返回-1
答案:一、
int fun(char *p)
{
if(p==NULL)
return -1;
else
{
int length = 0;
int i = 0;
int judge = 1;
length = strlen(p);
for(i=0; i<length/2; i++)
{
if(p[i]!=p[length-1-i])
judge = 0;
break;
}
if(judge == 0)
return 0;
else
return 1;
}
}
答案:二、
int fun(char *p)
{
int len = strlen(p) - 1;
char *q = p + len;
if (!p)
return -1;
while (p < q)
{
if ((*p++) != (*q--))
return 0;
}
return 1;
}
選擇題
1.在OSI 7 層模型中,網路層的功能有( )
A.確保資料的傳送正確無誤 B.確定資料包如何轉發與路由C.在通道上傳送位元流 D.糾錯與流控
2.FDDI 使用的是___區域網技術。( )A.乙太網; B.快速乙太網; C.令牌環; D.令牌匯流排。3.下面那種LAN 是應用CSMA/CD協議的 ()A.令牌環 B.FDDI C.ETHERNET D.NOVELL
4.TCP 和UDP 協議的相似之處是 ( )A.面向連線的協議 B.面向非連線的協議 C.傳輸層協議 D.以上均不對
5.應用程式PING 發出的是___報文.( )A.TCP 請求報文。 B.TCP 應答報文。 C.ICMP 請求報文。 D.ICMP 應答報文。
6.以下說法錯誤的是(多) ( )A.中繼器是工作在物理層的裝置 B.集線器和乙太網交換機工作在資料連路層C.路由器是工作在網路層的裝置 D.橋能隔離網路層廣播
7.當橋接收的分組的目的MAC地址在橋的對映表中沒有對應的表項時,採取的策略是( )A.丟掉該分組 B.將該分組分片 C.向其他埠廣播該分組 D.以上答案均不對8.LAN Switch 在網路層次模型中的地位( )A.物理層 B.鏈路層 C.網路層 D.以上都不是
9.小於___的TCP/UDP埠號已保留與現有服務一一對應,此數字以上的埠號可自由分配。( )A.199 B.100 C.1024 D.2048
10.當一臺主機從一個網路移到另一個網路時,以下說法正確的是 ( )A.必須改變它的IP 地址和MAC 地址 B.必須改變它的IP 地址,但不需改動MAC 地址 C.必須改變它的MAC 地址,但不需改動IP 地址 D.MAC 地址.IP 地址都不需改動
找錯
void test1()
{
char string[10];
char* str1="0123456789";
strcpy(string, str1);
}
答:表面上並且編譯都不會錯誤。但如果string陣列原意表示的是字串的話,那這個賦值就沒有達到意圖。最好定義為char string[11],這樣最後一個元素可以儲存字串結尾符'\0';
void test2()
{
char string[10], str1[10];
for(int i=0; i<10;i++)
{
str1[i] ='a';
}
strcpy(string, str1);
}
答:strcpy使用錯誤,strcpy只有遇到字串末尾的'\0'才會結束,而str1並沒有結尾標誌,導致strcpy函式越界訪問,不妨讓str1[9]='\0',這樣就正常了。
void test3(char* str1)
{
char string[10];
if(strlen(str1)<=10)
{
strcpy(string, str1);
}
}
答:這又會出現第一道改錯題的錯誤了。strlen(str1)算出來的值是不包含結尾符'\0'的,如果str1剛好為10個字元+1結尾符,string就得不到結尾符了。可將strlen(str1)<=10改為strlen(str1)<10。
2. 找錯
#define MAX_SRM 256
DSN get_SRM_no( )
{
static int SRM_no;
int i;
for(i=0;I(i)<MAX_SRM;i++,SRM_no++)
{
SRM_no %= MAX_SRM;
if(MY_SRM.state= =IDLE)
{
break;
}
}
if(i>=MAX_SRM)
return (NULL_SRM);
else
return SRM_no;
}
答:我不知道這段程式碼的具體功能,但明顯有兩個錯誤
1,SRM_no沒有賦初值
2,由於static的宣告,使該函式成為不可重入(即不可預測結果)函式,因為SRM_no變數放在程式的全域性儲存區中,每次呼叫的時候還可以保持原來的賦值。這裡應該去掉static宣告。
3. 寫出程式執行結果
int sum(int a)
{
auto int c=0; 全域性變數
static int b=3;靜態變數
c+=1;
b+=2;
return(a+b+c);
}
void main()
{
int i;
int a=2;
for(i=0;i<5;i++)
{
printf("%d,", sum(a));
}
}
答:8,10,12,14,16(貌似是錯的!!!!)
該題比較簡單。只要注意b宣告為static靜態全域性變數,其值在下次呼叫時是可以保持住原來的賦值的就可以。
4. int func(int a)
{
int b;
switch(a)
{
case 1: b=30;
case 2: b=20;
case 3: b=16;
default: b=0;
}
return b;
}
問題:則func(1)=?
答:func(1)=0,因為沒有break語句,switch中會一直計算到b=0。這是提醒我們不要忘了break。呵呵。
5: int a[3];
a[0]=0; a[1]=1; a[2]=2;
int *p, *q;
p=a;
q=&a[2];
問題:則a[q-p]=?
答:a[q-p]=a[2]=2;這題是要告訴我們指標的運算特點
6. 定義 int **a[3][4], 則變數佔有的記憶體空間為:_____
答:此處定義的是指向指標的指標陣列,對於32位系統,指標佔記憶體空間4位元組,因此總空間為3×4×4=48。
7.編寫一個函式,要求輸入年月日時分秒,輸出該年月日時分秒的下一秒。如輸入2004年12月31日23時59分59秒,則輸出2005年1月1日0時0分0秒。
答:/*輸入年月日時分秒,輸出年月日時分秒的下一秒,輸出仍然在原記憶體空間*/
void NextMinute(int *nYear,int *nMonth,int *nDate,int *nHour,int *nMinute,int *nSecond)
{
int nDays;
(*nSecond)++; // 秒加1
if(*nSecond>=60) // 秒滿60,做出特殊處理,下面時,日,月等類同
{
*nSecond=0;
(*nMinute)++;
if(*nMinute>=60)
{
*nMinute=0;
(*nHour)++;
if(*nHour>=24)
{
*nHour=0;
(*nDate)++;
switch(*nMonth)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
nDays=31;
break;
case 2:// 判斷閏年
if(*nYear%400==0||*nYear%100!=0&&*nYear%4==0)
{
nDays=29;
}
else
{
nDays=28;
}
break;
default:
nDays=30;
break;
}
if(*nDate>nDays)
{
*nDate=1;
(*nMonth)++;
if(*nMonth>12)
{
*nMonth=1;
(*nYear)++;
}
}
}
}
}
}
/*示例可執行程式碼*/
void main()
{
int nYear=2004,nMonth=12,nDate=31,nHour=59,nMinute=59,nSecond=59;
NextMinute(&nYear,&nMonth,&nDate,&nHour,&nMinute,&nSecond);
printf("The result:%d-%d-%d %d:%d:%d",nYear,nMonth,nDate,nHour,nMinute,nSecond);
} //cxj註釋,編寫程式碼的人C語言很強
已知:無序陣列,折半查詢,各元素值唯一。
函式原型是:Binary_Seach(int array[], int iValue, int iCount)
array是陣列,在裡面用折半查詢的方法找等於iValue的值,找到返回1,否則0,iCount是元素個數,如何做呢?
把插入排序和折半查詢一起做:
int Binary_Seach(int array[], int iValue, int iCount)
{
int i,low,high,tmp,m,j;
for(i=2;i<=iCount;++i)
{
tmp=array[i];
low=1; high=i-1;
while(low<=high)
{
m=(low+high)/2;
if(array[m]==iValue)
return 1;
if(tmp>=array[m])
{ low=m+1;}
else
{ high=m-1;}
}
for(j=i-1;j>=high+1;--j)
array[j+1]=array[j];
array[high+1]=tmp;
}
return 0;
}
//cxj註釋,沒有看懂,能看懂折半查詢。
寫一個程式, 要求功能:求出用1,2,5這三個數不同個數組合的和為100的組合個數。
如:100個1是一個組合,5個1加19個5是一個組合。。。。 請用C++語言寫。
答案:最容易想到的演算法是:
設x是1的個數,y是2的個數,z是5的個數,number是組合數
注意到0<=x<=100,0<=y<=50,0<=z=20,所以可以程式設計為:
number=0;
for (x=0; x<=100; x++)
for (y=0; y<=50; y++)
for (z=0; z<=20; z++)
if ((x+2*y+5*z)==100)
number++;
cout<<number<<endl;
上面這個程式一共要迴圈100*50*20次,效率實在是太低了
事實上,這個題目是一道明顯的數學問題,而不是單純的程式設計問題。我的解法如下:
因為x+2y+5z=100
所以x+2y=100-5z,且z<=20 x<=100 y<=50
所以(x+2y)<=100,且(x+5z)是偶數
對z作迴圈,求x的可能值如下:
z=0, x=100, 98, 96, ... 0
z=1, x=95, 93, ..., 1
z=2, x=90, 88, ..., 0
z=3, x=85, 83, ..., 1
z=4, x=80, 78, ..., 0
......
z=19, x=5, 3, 1
z=20, x=0
因此,組合總數為100以內的偶數+95以內的奇數+90以內的偶數+...+5以內的奇數+1,
即為:
(51+48)+(46+43)+(41+38)+(36+33)+(31+28)+(26+23)+(21+18)+(16+13)+(11+8)+(6+3)+1
某個偶數m以內的偶數個數(包括0)可以表示為m/2+1=(m+2)/2
某個奇數m以內的奇數個數也可以表示為(m+2)/2
所以,求總的組合次數可以程式設計為:
number=0;
for (int m=0;m<=100;m+=5)
{
number+=(m+2)/2;
}
cout<<number<<endl;
這個程式,只需要迴圈21次, 兩個變數,就可以得到答案,比上面的那個程式高效了許多倍----只是因為作了一些簡單的數學分析
這再一次證明了:計算機程式=資料結構+演算法,而且演算法是程式的靈魂,對任何工程問題,當用軟體來實現時,必須選取滿足當前的資源限制,使用者需求限制,開發時間限制等種種限制條件下的最優演算法。而絕不能一拿到手,就立刻用最容易想到的演算法編出一個程式了事——這不是一個專業的研發人員的行為。
那麼,那種最容易想到的演算法就完全沒有用嗎?不,這種演算法正好可以用來驗證新演算法的正確性,在除錯階段,這非常有用。在很多大公司,例如微軟,都採用了這種方法:在除錯階段,對一些重要的需要好的演算法來實現的程式,而這種好的演算法又比較複雜時,同時用容易想到的演算法來驗證這段程式,如果兩種演算法得出的結果不一致(而最容易想到的演算法保證是正確的),那麼說明優化的演算法出了問題,需要修改。
可以舉例表示為:
#ifdef DEBUG
int simple();
#end if
int optimize();
......
in a function:
{
result=optimize();
ASSERT(result==simple());
}
這樣,在除錯階段,如果簡單演算法和優化演算法的結果不一致,就會打出斷言。同時,在程
序的釋出版本,卻不會包含笨重的simple()函式。——任何大型工程軟體都需要預先設計良
好的除錯手段,而這裡提到的就是一種有用的方法。
一個學生的資訊是:姓名,學號,性別,年齡等資訊,用一個連結串列,把這些學生資訊連在一起, 給出一個age, 在些連結串列中刪除學生年齡等於age的學生資訊。
#include "stdio.h"
#include "conio.h" % Console Input/Output(控制檯輸入輸出)
struct stu{
char name[20];
char sex;
int no;
int age;
struct stu * next;
}*linklist;
struct stu *creatlist(int n)
{
int i;
//h為頭結點,p為前一結點,s為當前結點
struct stu *h,*p,*s;
h = (struct stu *)malloc(sizeof(struct stu));
h->next = NULL;
p=h;
for(i=0;i<n;i++)
{
s = (struct stu *)malloc(sizeof(struct stu));
p->next = s;
printf("Please input the information of the student: name sex no age \n");
scanf("%s %c %d %d",s->name,&s->sex,&s->no,&s->age);
s->next = NULL;
p = s;
}
printf("Create successful!");
return(h);
}
void deletelist(struct stu *s,int a)
{
struct stu *p;
while(s->age!=a)
{
p = s;
s = s->next;
}
if(s==NULL)
printf("The record is not exist.");
else
{
p->next = s->next;
printf("Delete successful!");
}
}
void display(struct stu *s)
{
s = s->next;
while(s!=NULL)
{
printf("%s %c %d %d\n",s->name,s->sex,s->no,s->age);
s = s->next;
}
}
int main()
{
struct stu *s;
int n,age;
printf("Please input the length of seqlist:\n");
scanf("%d",&n);
s = creatlist(n);
display(s);
printf("Please input the age:\n");
scanf("%d",&age);
deletelist(s,age);
display(s);
return 0;
}
2、實現一個函式,把一個字串中的字元從小寫轉為大寫。
#include "stdio.h"
#include "conio.h"
void uppers(char *s,char *us)
{
for(;*s!='\0';s++,us++)
{
if(*s>='a'&&*s<='z')
*us = *s-32;
else
*us = *s;
}
*us = '\0';
}
int main()
{
char *s,*us;
char ss[20];
printf("Please input a string:\n");
scanf("%s",ss);
s = ss;
uppers(s,us);
printf("The result is:\n%s\n",us);
getch();
}
隨機輸入一個數,判斷它是不是對稱數(迴文數)(如3,121,12321,45254)。不能用字串庫函式
/***************************************************************
1.
函式名稱:Symmetry
功能: 判斷一個數時候為迴文數(121,35653)
輸入: 長整型的數
輸出: 若為迴文數返回值為1 esle 0
******************************************************************/
unsigned char Symmetry (long n)
{
long i,temp;
i=n; temp=0;
while(i) //不用出現長度問題,將數按高低位掉換
{
temp=temp*10+i%10;
i/=10;
}
return(temp==n);
}
方法一
/* ---------------------------------------------------------------------------
功能:
判斷字串是否為迴文數字
實現:
先將字串轉換為正整數,再將正整數逆序組合為新的正整數,兩數相同則為迴文數字
輸入:
char *s:待判斷的字串
輸出:
無
返回:
0:正確;1:待判斷的字串為空;2:待判斷的字串不為數字;
3:字串不為迴文數字;4:待判斷的字串溢位
---------------------------------------------------------------------------- */
unsigned IsSymmetry(char *s)
{
char *p = s;
long nNumber = 0;
long n = 0;
long nTemp = 0;
/*判斷輸入是否為空*/
if (*s == \'\\0\')
return 1;
/*將字串轉換為正整數*/
while (*p != \'\\0\')
{
/*判斷字元是否為數字*/
if (*p<\'0\' || *p>\'9\')
return 2;
/*判斷正整數是否溢位*/
if ((*p-\'0\') > (4294967295-(nNumber*10)))
return 4;
nNumber = (*p-\'0\') + (nNumber * 10);
p++;
}
/*將數字逆序組合,直接抄樓上高手的程式碼,莫怪,呵呵*/
n = nNumber;
while(n)
{
/*判斷正整數是否溢位*/
if ((n%10) > (4294967295-(nTemp*10)))
return 3;
nTemp = nTemp*10 + n%10;
n /= 10;
}
/*比較逆序數和原序數是否相等*/
if (nNumber != nTemp)
return 3;
return 0;
}
方法二
/* ---------------------------------------------------------------------------
功能:
判斷字串是否為迴文數字
實現:
先得到字串的長度,再依次比較字串的對應位字元是否相同
輸入:
char *s:待判斷的字串
輸出:
無
返回:
0:正確;1:待判斷的字串為空;2:待判斷的字串不為數字;
3:字串不為迴文數字
---------------------------------------------------------------------------- */
unsigned IsSymmetry_2(char *s)
{
char *p = s;
int nLen = 0;
int i = 0;
/*判斷輸入是否為空*/
if (*s == \'\\0\')
return 1;
/*得到字串長度*/
while (*p != \'\\0\')
{
/*判斷字元是否為數字*/
if (*p<\'0\' || *p>\'9\')
return 2;
nLen++;
p++;
}
/*長度不為奇數,不為迴文數字*/
if (nLen%2 == 0)
return 4;
/*長度為1,即為迴文數字*/
if (nLen == 1)
return 0;
/*依次比較對應字元是否相同*/
p = s;
i = nLen/2 - 1;
while (i)
{
if (*(p+i) != *(p+nLen-i-1))
return 3;
i--;
}
return 0;
}
求2~2000的所有素數.有足夠的記憶體,要求儘量快
答案:
int findvalue[2000]={2};
static int find=1;
bool adjust(int value)
{
assert(value>=2);
if(value==2) return true;
for(int i=0;i<=find;i++)
{
if(value%findvalue[i]==0)
return false;
}
findvalue[find++];
return true;
}
suningin華為招聘--前人經驗(3)
發了一篇華為面試歸來,然後有好多人問我相關的情況,大家找工作的心情都是一樣的,所以我乾脆把自己的經歷說詳細一點,希望能對要面試的同學有點幫助。
我面試的時間比較早,去了以後先是填表,跟簡歷上的內容差不多,只是更詳細了一些,等填完以後有一個漂亮的姐姐領著你去面試官那,我們當時面試的時候是所有面試官都在大廳裡,一個人面試一個同學,第三輪的面試官就是北研所的總監和另外一個,想來也應該是個小頭目,他們兩個在裡間的小房間裡。然後給我面試的哥哥先看我的簡歷,然後問偶做過
<