PPS2013校园招聘笔试题
生活随笔
收集整理的這篇文章主要介紹了
PPS2013校园招聘笔试题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載請標明出處,原文地址:http://blog.csdn.net/hackbuteer1/article/details/11473405
一、簡答題
(1)一位老師有2個推理能力很強的學生,他告訴學生他手里有以下的牌:
黑桃:2 , 5 , 7 , 9 , J , K
紅心:3 , 4 , 9 , J , K
梅花:5 , 8 , 9 , Q
方塊:2 , 7 , 8
然后從中拿出一張牌,告訴A這張牌的大小,告訴了B這張牌的花色;
A:我不知道這張是什么牌
B:我就知道你肯定不知道這張是什么牌
A:現在我知道
B:現在我也知道了
請問這張是什么牌?
答:方塊8
(2)有11個乒乓球,其中有一個球是偽劣產品并存在質量較輕的問題,現有一個沒有砝碼的天平,只能稱3次把那個假貨給稱出來。
答:
第一次,天平兩端各放5個乒乓球,如果天平平衡,那么剩下的那個就是偽劣產品。
如果不平衡,則將天平較輕那端的5個乒乓球選出來,然后在天平兩端各放2個乒乓球,如果天平平衡,那么剩下的那個就是偽劣產品。否則,將天平較輕那端的2個乒乓球選出來,放在天平上重新測量,天平較輕端的那個乒乓球就是偽劣產品。
(3)說明指針與引用的區別。
答:●指針是一個實體,而引用僅是個別名;
●引用只能在定義時被初始化一次,之后不可變;指針可變;引用“從一而終”,指針可以“見異思遷”;
●引用沒有const,指針有const,const的指針不可變;
●引用不能為空,指針可以為空;
●“sizeof 引用”得到的是所指向的變量(對象)的大小,而“sizeof 指針”得到的是指針本身的大小;
●指針和引用的自增(++)運算意義不一樣;
●引用是類型安全的,而指針不是 (引用比指針多了類型檢查
從內存分配上看:程序為指針變量分配內存區域,而引用不分配內存區域。指針:指向另一個內存空間的變量,我們可以通過它來索引另一個內存空間的內容,本身有自己的內存空間。?
(4)列出C++類型轉換操作符,并分別舉例。
dynamic_cast: 在多態類型轉換時使用,用來執行繼承體系中"安全的向下轉型或跨系轉型動作",就是子類對象指針轉化為父類對象指針。實現在運行時,并進行運行時檢測,如果轉換失敗,返回值是NULL。
static_cast:與dynamic_cast相反,static_cast是在編譯時轉換類型的,故稱為static_cast,它可以用在值類型轉換中
const_cast:一般用于去除const, volatile等修飾屬性上.
reinterpret_cast:特意用于底層的強制轉型,這個操作符能夠在非相關的類型之間轉換。操作結果只是簡單的從一個指針到別的指針的值的二進制拷貝。在類型之間指向的內容不做任何類型的檢查和轉換。
(5)寫個簡單的函數,用于判斷CPU的字節序(little endian/big endian)
//若處理器是Big_endian的,則返回0;若是Little_endian的,則返回1。 int checkCPU(void) {union{int a;char b;}c;c.a = 1;return (c.b == 1); } (6)實現一個128位整數的類,并且完成后面的函數,測試一個數是否為素數。
class int128
{
};
bool isPrime(int128 & number)
{
...
}
答:
#include<bitset> #include<algorithm> #include<iostream> #include<string> #include<deque> using namespace std;class int128;void shift(int128 & in,deque<bool> & de);template<size_t N> bool operator<(bitset<N> const& b1,bitset<N> const& b2) {int i=N;while( i-- && b1[i]==b2[i] ) { }return ((-1 == i) ? false : (b1[i]<b2[i])); }class int128 {bitset<128> number; public:explicit int128(string str):number(str){}int128(bitset<128>const& b):number(b){}int128(int a = 0 , int b = 0 , int c = 0 , int d = 0){bitset<32> b1(a),b2(b),b3(c),b4(d);int i, k = 128;for(i = 32 ; i ; number[--k] = b1[--i]) { }for(i = 32 ; i ; number[--k] = b2[--i]) { }for(i = 32 ; i ; number[--k] = b3[--i]) { }for(i = 32 ; i ; number[--k] = b4[--i]) { }}bool operator[](size_t i)const{return number[i];}bitset<128>::reference operator[](size_t i){return number[i];}friend bool operator<(int128 const& i1,int128 const& i2){return i1.number < i2.number;}friend int128 operator+(int128 const& i1,int128 const& i2){if(i1 == 0)return i2;if(i2 == 0)return i1;int128 result;bitset<2> sum;for(int i = 0 ; i < 128 ; ++i){sum=i1[i]+i2[i]+sum.to_ulong();result[i]=sum[0];sum>>=1;}return result;}friend int128 operator-(int128 const& i1,int128 const& i2){if(i2==0)return i1;int128 result=i1;for(int i = 0 ; i < 128 ; ++i){if(i2[i] == 0) {}else{if(result[i] == 1)result[i] = 0;else{int k = i;while(k < 128 && result[k] == 0){result[k] = 1;++k;}if(k != 128)result[k] = 0;}}}return result;}friend int128 operator*(int128 const& i1,int128 const& i2){if(i1==0 || i2==0)return int128();if(i1==1)return i2;if(i2==1)return i1;int128 acc=int128();for(int i=0;i<128;++i){if(i2[i]==1){acc=acc+(i1<<i);}}return acc;}friend int128 operator/(int128 const& i1,int128 const& i2){if(i1 < i2)return int128();deque<bool> de;bool flag = 0;for(int i = 127 ; i >= 0 ; --i){if(flag == 0 && i1[i] == 0) {}else{flag = 1;de.push_back(i1[i]);}}int128 div = int128();int128 result = int128();while(!de.empty()){shift(div,de);if(div < i2){result = result<<1;}else{result = (result<<1) + int128(0,0,0,1);div = div - i2;}}return result;}friend int128 operator%(int128 const& i1,int128 const& i2){if(i1 < i2)return i1;deque<bool> de;bool flag = 0;for(int i = 127 ; i >= 0 ; --i){if(flag == 0 && i1[i] == 0) {}else{flag = 1;de.push_back(i1[i]);}}int128 div = int128();int128 result = int128();while(!de.empty()){shift(div,de);if(div < i2){result = result<<1;}else{result = (result<<1) + int128(0,0,0,1);div = div - i2;}}return div;}friend bool operator==(int128 const& i,int const k){bitset<32> bb(k);for(int g = 0 ; g < 32 ; ++g){if(i[g] != bb[g])return 0;}return 1;}void operator=(bitset<128>const& b){number = b;}friend ostream& operator<<(ostream& o,int128 const& i){o<<i.number;return o;}int128 operator<<(size_t step)const{return int128(number<<step);}unsigned long to_ulong()const{return *((unsigned long*)&number);}public:bool ToDecimalStr(std::string &str){str.clear();char buf[128] = {0};int128 Radix(0, 0, 0, 10);for(int128 num = number; !(num == 0); num = num/Radix){if( sprintf_s(buf, 64, "%d", ((int)(num%Radix).to_ulong())) < 0 ){return false;}str = buf + str;}return true;}static void Print(int128 & data, bool bEndl = true){string str;if( data.ToDecimalStr(str) ){printf("%s%s", str.c_str(), (bEndl?"\n":""));}} };static int128 const one = int128(0,0,0,1);template<size_t N> void add_one(bitset<N>& b) {int i = 0;while(i < N && b[i] == 1){b[i] = 0;++i;}if(i == N)return;b[i] = 1; }void add_one(int128& k) {int i = 0;while(i < 128 && k[i] == 1){k[i] = 0;++i;}if(i == 128)return;k[i] = 1; }void shift(int128 & in,deque<bool> & de) {if(de.front()==1){de.pop_front();in=(in<<1)+one;}else{de.pop_front();in=in<<1;} }bool IsPrime(int128 const& number) {for(int128 i = int128(0,0,0,2) ; i < number ; add_one(i)){if(number%i == 0)return 0;}return 1; }(7)對 二叉樹進行排序,排序后的結果為二叉排序樹。
二叉排序樹又稱二叉查找樹,它或者是一棵空樹,或者是具有下列性質的二叉樹:(1)若左子樹不空,則左子樹上所有結點的值均小于它的根結點的值;(2)若右子樹不空,則右子樹上所有結點的值均大于它的根結點的值;(3)左、右子樹也分別為二叉排序樹;
struct STreeNode
{
int key;
STreeNode* left_child;
STreeNode* right_child;
};
//返回值為排序后的根節點
STreeNode* bt2bst(STreeNode* root_node)
{
}
struct STreeNode {int key;STreeNode* left_child;STreeNode* right_child; };void InsertBST(STreeNode* t , int key) {if(NULL == t){t = new STreeNode; t->left_child = t->right_child = NULL;t->key = key;return; }if(key < t->key) InsertBST(t->left_child , key);elseInsertBST(t->right_child , key ); }//先序遍歷樹并插入建立排序樹 void PreOrder(STreeNode* t , STreeNode* tBST) {if(NULL != t){InsertBST(tBST , t->key);PreOrder(t->left_child , tBST);PreOrder(t->right_child , tBST);} }//目標函數 STreeNode* bt2bst(STreeNode* root_node) {STreeNode* bstTreeRoot = NULL;PreOrder(root_node , bstTreeRoot);return bstTreeRoot; } 二、擴展題
(1)列出幾種你了解的IPC機制。
答:共享內存:是一片指定的物理內存區域,這個區域通常是在存放正常程序數據區域的外面, 它允許兩個或多個進程共享一給定的存儲區,是針對其他通信機制運行效率較低而設計的。使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。往往與其它通信機制,如信號量結合使用,來達到進程間的同步及互斥。
信號量(semaphore):主要作為進程間以及同一進程不同線程之間的同步手段。
套接口(Socket):更為一般的進程間通信機制,可用于不同機器之間的進程間通信。起初是由Unix系統的BSD分支開發出來的,但現在一般可以移植到其它類Unix系統上。
消息隊列(MessageQueue)是一個結構化的排序內存段表,這個隊列是進程存放或檢索數據的地方,是一個消息的鏈表,可以被多個進程所共享。
(2)列舉一種死鎖發生的場景,并給出解決方案。
答:最經典的場景就是生產者/消費者,生產者線程生產物品,然后將物品放置在一個空緩沖區中供消費者線程消費。消費者線程從緩沖區中獲得物品,然后釋放緩沖區。由于生產者/消費者都在操作緩沖區,容易導致死鎖的發生。
可以通過添加鎖的保護來對緩沖區進行互斥的訪問,保證某一時刻只有一個線程對緩沖區進行操作,當緩沖區滿的時候,生產者線程就會掛起,同時通知消費者線程。而緩沖區空的時候,消費者線程就會掛起,同時通知生產者線程。
(3)列舉編寫一個TCP的服務器端程序可能需要用到的socket API,如果這些API的調用有先后關系,請按先后關系列出。
(4)舉例說明什么是MVC。
答:MVC是一個設計模式,它強制性的使應用程序的輸入、處理和輸出分開。使用MVC應用程序被分成三個核心部件:模型、視圖、控制器。它們各自處理自己的任務。
視圖是用戶看到并與之交互的界面。對老式的Web應用程序來說,視圖就是由HTML元素組成的界面,在新式的Web應用程序中,HTML依舊在視圖中扮演著重要的角色,作為視圖來講,它只是作為一種輸出數據并允許用戶操縱的方式。
模型表示企業數據和業務規則。在MVC的三個部件中,模型擁有最多的處理任務。由于應用于模型的代碼只需寫一次就可以被多個視圖重用,所以減少了代碼的重復性。
控制器接受用戶的輸入并調用模型和視圖去完成用戶的需求。所以當單擊Web頁面中的超鏈接和發送HTML表單時,控制器本身不輸出任何東西和做任何處理。它只是接收請求并決定調用哪個模型構件去處理請求,然后用確定用哪個視圖來顯示模型處理返回的數據。
轉載請標明出處,原文地址:http://blog.csdn.net/hackbuteer1/article/details/11473405
一、簡答題
(1)一位老師有2個推理能力很強的學生,他告訴學生他手里有以下的牌:
黑桃:2 , 5 , 7 , 9 , J , K
紅心:3 , 4 , 9 , J , K
梅花:5 , 8 , 9 , Q
方塊:2 , 7 , 8
然后從中拿出一張牌,告訴A這張牌的大小,告訴了B這張牌的花色;
A:我不知道這張是什么牌
B:我就知道你肯定不知道這張是什么牌
A:現在我知道
B:現在我也知道了
請問這張是什么牌?
答:方塊8
(2)有11個乒乓球,其中有一個球是偽劣產品并存在質量較輕的問題,現有一個沒有砝碼的天平,只能稱3次把那個假貨給稱出來。
答:
第一次,天平兩端各放5個乒乓球,如果天平平衡,那么剩下的那個就是偽劣產品。
如果不平衡,則將天平較輕那端的5個乒乓球選出來,然后在天平兩端各放2個乒乓球,如果天平平衡,那么剩下的那個就是偽劣產品。否則,將天平較輕那端的2個乒乓球選出來,放在天平上重新測量,天平較輕端的那個乒乓球就是偽劣產品。
(3)說明指針與引用的區別。
答:●指針是一個實體,而引用僅是個別名;
●引用只能在定義時被初始化一次,之后不可變;指針可變;引用“從一而終”,指針可以“見異思遷”;
●引用沒有const,指針有const,const的指針不可變;
●引用不能為空,指針可以為空;
●“sizeof 引用”得到的是所指向的變量(對象)的大小,而“sizeof 指針”得到的是指針本身的大小;
●指針和引用的自增(++)運算意義不一樣;
●引用是類型安全的,而指針不是 (引用比指針多了類型檢查
從內存分配上看:程序為指針變量分配內存區域,而引用不分配內存區域。指針:指向另一個內存空間的變量,我們可以通過它來索引另一個內存空間的內容,本身有自己的內存空間。?
(4)列出C++類型轉換操作符,并分別舉例。
dynamic_cast: 在多態類型轉換時使用,用來執行繼承體系中"安全的向下轉型或跨系轉型動作",就是子類對象指針轉化為父類對象指針。實現在運行時,并進行運行時檢測,如果轉換失敗,返回值是NULL。
static_cast:與dynamic_cast相反,static_cast是在編譯時轉換類型的,故稱為static_cast,它可以用在值類型轉換中
const_cast:一般用于去除const, volatile等修飾屬性上.
reinterpret_cast:特意用于底層的強制轉型,這個操作符能夠在非相關的類型之間轉換。操作結果只是簡單的從一個指針到別的指針的值的二進制拷貝。在類型之間指向的內容不做任何類型的檢查和轉換。
(5)寫個簡單的函數,用于判斷CPU的字節序(little endian/big endian)
//若處理器是Big_endian的,則返回0;若是Little_endian的,則返回1。 int checkCPU(void) {union{int a;char b;}c;c.a = 1;return (c.b == 1); } (6)實現一個128位整數的類,并且完成后面的函數,測試一個數是否為素數。
class int128
{
};
bool isPrime(int128 & number)
{
...
}
答:
#include<bitset> #include<algorithm> #include<iostream> #include<string> #include<deque> using namespace std;class int128;void shift(int128 & in,deque<bool> & de);template<size_t N> bool operator<(bitset<N> const& b1,bitset<N> const& b2) {int i=N;while( i-- && b1[i]==b2[i] ) { }return ((-1 == i) ? false : (b1[i]<b2[i])); }class int128 {bitset<128> number; public:explicit int128(string str):number(str){}int128(bitset<128>const& b):number(b){}int128(int a = 0 , int b = 0 , int c = 0 , int d = 0){bitset<32> b1(a),b2(b),b3(c),b4(d);int i, k = 128;for(i = 32 ; i ; number[--k] = b1[--i]) { }for(i = 32 ; i ; number[--k] = b2[--i]) { }for(i = 32 ; i ; number[--k] = b3[--i]) { }for(i = 32 ; i ; number[--k] = b4[--i]) { }}bool operator[](size_t i)const{return number[i];}bitset<128>::reference operator[](size_t i){return number[i];}friend bool operator<(int128 const& i1,int128 const& i2){return i1.number < i2.number;}friend int128 operator+(int128 const& i1,int128 const& i2){if(i1 == 0)return i2;if(i2 == 0)return i1;int128 result;bitset<2> sum;for(int i = 0 ; i < 128 ; ++i){sum=i1[i]+i2[i]+sum.to_ulong();result[i]=sum[0];sum>>=1;}return result;}friend int128 operator-(int128 const& i1,int128 const& i2){if(i2==0)return i1;int128 result=i1;for(int i = 0 ; i < 128 ; ++i){if(i2[i] == 0) {}else{if(result[i] == 1)result[i] = 0;else{int k = i;while(k < 128 && result[k] == 0){result[k] = 1;++k;}if(k != 128)result[k] = 0;}}}return result;}friend int128 operator*(int128 const& i1,int128 const& i2){if(i1==0 || i2==0)return int128();if(i1==1)return i2;if(i2==1)return i1;int128 acc=int128();for(int i=0;i<128;++i){if(i2[i]==1){acc=acc+(i1<<i);}}return acc;}friend int128 operator/(int128 const& i1,int128 const& i2){if(i1 < i2)return int128();deque<bool> de;bool flag = 0;for(int i = 127 ; i >= 0 ; --i){if(flag == 0 && i1[i] == 0) {}else{flag = 1;de.push_back(i1[i]);}}int128 div = int128();int128 result = int128();while(!de.empty()){shift(div,de);if(div < i2){result = result<<1;}else{result = (result<<1) + int128(0,0,0,1);div = div - i2;}}return result;}friend int128 operator%(int128 const& i1,int128 const& i2){if(i1 < i2)return i1;deque<bool> de;bool flag = 0;for(int i = 127 ; i >= 0 ; --i){if(flag == 0 && i1[i] == 0) {}else{flag = 1;de.push_back(i1[i]);}}int128 div = int128();int128 result = int128();while(!de.empty()){shift(div,de);if(div < i2){result = result<<1;}else{result = (result<<1) + int128(0,0,0,1);div = div - i2;}}return div;}friend bool operator==(int128 const& i,int const k){bitset<32> bb(k);for(int g = 0 ; g < 32 ; ++g){if(i[g] != bb[g])return 0;}return 1;}void operator=(bitset<128>const& b){number = b;}friend ostream& operator<<(ostream& o,int128 const& i){o<<i.number;return o;}int128 operator<<(size_t step)const{return int128(number<<step);}unsigned long to_ulong()const{return *((unsigned long*)&number);}public:bool ToDecimalStr(std::string &str){str.clear();char buf[128] = {0};int128 Radix(0, 0, 0, 10);for(int128 num = number; !(num == 0); num = num/Radix){if( sprintf_s(buf, 64, "%d", ((int)(num%Radix).to_ulong())) < 0 ){return false;}str = buf + str;}return true;}static void Print(int128 & data, bool bEndl = true){string str;if( data.ToDecimalStr(str) ){printf("%s%s", str.c_str(), (bEndl?"\n":""));}} };static int128 const one = int128(0,0,0,1);template<size_t N> void add_one(bitset<N>& b) {int i = 0;while(i < N && b[i] == 1){b[i] = 0;++i;}if(i == N)return;b[i] = 1; }void add_one(int128& k) {int i = 0;while(i < 128 && k[i] == 1){k[i] = 0;++i;}if(i == 128)return;k[i] = 1; }void shift(int128 & in,deque<bool> & de) {if(de.front()==1){de.pop_front();in=(in<<1)+one;}else{de.pop_front();in=in<<1;} }bool IsPrime(int128 const& number) {for(int128 i = int128(0,0,0,2) ; i < number ; add_one(i)){if(number%i == 0)return 0;}return 1; }(7)對 二叉樹進行排序,排序后的結果為二叉排序樹。
二叉排序樹又稱二叉查找樹,它或者是一棵空樹,或者是具有下列性質的二叉樹:(1)若左子樹不空,則左子樹上所有結點的值均小于它的根結點的值;(2)若右子樹不空,則右子樹上所有結點的值均大于它的根結點的值;(3)左、右子樹也分別為二叉排序樹;
struct STreeNode
{
int key;
STreeNode* left_child;
STreeNode* right_child;
};
//返回值為排序后的根節點
STreeNode* bt2bst(STreeNode* root_node)
{
}
struct STreeNode {int key;STreeNode* left_child;STreeNode* right_child; };void InsertBST(STreeNode* t , int key) {if(NULL == t){t = new STreeNode; t->left_child = t->right_child = NULL;t->key = key;return; }if(key < t->key) InsertBST(t->left_child , key);elseInsertBST(t->right_child , key ); }//先序遍歷樹并插入建立排序樹 void PreOrder(STreeNode* t , STreeNode* tBST) {if(NULL != t){InsertBST(tBST , t->key);PreOrder(t->left_child , tBST);PreOrder(t->right_child , tBST);} }//目標函數 STreeNode* bt2bst(STreeNode* root_node) {STreeNode* bstTreeRoot = NULL;PreOrder(root_node , bstTreeRoot);return bstTreeRoot; } 二、擴展題
(1)列出幾種你了解的IPC機制。
答:共享內存:是一片指定的物理內存區域,這個區域通常是在存放正常程序數據區域的外面, 它允許兩個或多個進程共享一給定的存儲區,是針對其他通信機制運行效率較低而設計的。使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。往往與其它通信機制,如信號量結合使用,來達到進程間的同步及互斥。
信號量(semaphore):主要作為進程間以及同一進程不同線程之間的同步手段。
套接口(Socket):更為一般的進程間通信機制,可用于不同機器之間的進程間通信。起初是由Unix系統的BSD分支開發出來的,但現在一般可以移植到其它類Unix系統上。
消息隊列(MessageQueue)是一個結構化的排序內存段表,這個隊列是進程存放或檢索數據的地方,是一個消息的鏈表,可以被多個進程所共享。
(2)列舉一種死鎖發生的場景,并給出解決方案。
答:最經典的場景就是生產者/消費者,生產者線程生產物品,然后將物品放置在一個空緩沖區中供消費者線程消費。消費者線程從緩沖區中獲得物品,然后釋放緩沖區。由于生產者/消費者都在操作緩沖區,容易導致死鎖的發生。
可以通過添加鎖的保護來對緩沖區進行互斥的訪問,保證某一時刻只有一個線程對緩沖區進行操作,當緩沖區滿的時候,生產者線程就會掛起,同時通知消費者線程。而緩沖區空的時候,消費者線程就會掛起,同時通知生產者線程。
(3)列舉編寫一個TCP的服務器端程序可能需要用到的socket API,如果這些API的調用有先后關系,請按先后關系列出。
(4)舉例說明什么是MVC。
答:MVC是一個設計模式,它強制性的使應用程序的輸入、處理和輸出分開。使用MVC應用程序被分成三個核心部件:模型、視圖、控制器。它們各自處理自己的任務。
視圖是用戶看到并與之交互的界面。對老式的Web應用程序來說,視圖就是由HTML元素組成的界面,在新式的Web應用程序中,HTML依舊在視圖中扮演著重要的角色,作為視圖來講,它只是作為一種輸出數據并允許用戶操縱的方式。
模型表示企業數據和業務規則。在MVC的三個部件中,模型擁有最多的處理任務。由于應用于模型的代碼只需寫一次就可以被多個視圖重用,所以減少了代碼的重復性。
控制器接受用戶的輸入并調用模型和視圖去完成用戶的需求。所以當單擊Web頁面中的超鏈接和發送HTML表單時,控制器本身不輸出任何東西和做任何處理。它只是接收請求并決定調用哪個模型構件去處理請求,然后用確定用哪個視圖來顯示模型處理返回的數據。
轉載請標明出處,原文地址:http://blog.csdn.net/hackbuteer1/article/details/11473405
總結
以上是生活随笔為你收集整理的PPS2013校园招聘笔试题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2013豆瓣校园招聘研发类笔试题
- 下一篇: 迅雷2014校园招聘笔试题