6.2 筆試真題 & 詳解
真題 1:
1,ISR,APC,DPC 的定義。
2,Windows/ Linux 下系統(tǒng)創(chuàng)建進(jìn)程的步驟。
3,xtoa 函數(shù),輸入是兩個整數(shù),原數(shù)字,數(shù)制,輸出是字符串。
4,實現(xiàn)內(nèi)存拷貝的 C 函數(shù)。
5,比較兩個二叉樹結(jié)構(gòu)是否一樣。
6,C++中 volatile 關(guān)鍵字的作用。
7,一個程序找錯誤。
8,根據(jù)上述錯誤給程序員發(fā)郵件提出改進(jìn)意見。
9,最喜歡的一首唐詩,原因。
10,當(dāng)代最崇拜的人,原因。
真題 2:
1、選擇下面哪一個是時序電路。四個選項分別是 ADD XOR Latch D-Flop。
2、問系統(tǒng)工作的最大時鐘頻率是否跟 Hold time 有關(guān),并說明理由。
3、畫出下面兩個代碼綜合出來的電路圖,并說明原因。 a:if(aflag)
begin opt1 <= a; opt2 <= b; end esle begin opt1 <= c; opt2 <= d; end
always@(posedge clk)
out_data <= opt1 +opt2; b: if(aflag)
out_data <= a+b; else
out_data <= c+d;
4、用圖表說明下列腳本命令。
a: set_multicycle_path 4 -setup -from dffa/cp -to dffb/d b: set_multicycle_path 4 -setup -from dffa/cp -to dffb/d set_multicycle_path 4 -hold -from dffa/cp -to dffb/d
//這三個命令不一定完全正確,憑記憶大概是這個樣子的
5、5 分頻,用 Verilog HDL/VHDL 實現(xiàn)。
6、timescale 1ns/1ps 與`timescale 1ns/50ps 分別代表的意義以及區(qū)別。
7.分別用 shell 以及 perl(或任一你熟知的腳本語言)將當(dāng)前目錄下所有".c"文件后綴改 成".cc"。
真題 3:
1:windows API 里面用于線程同步的有哪些?
答案:共有 12 個 API
1)、臨界區(qū)共有五個 API。
(1)InitializeCriticalSection
此函數(shù)用于設(shè)臵臨界區(qū)對象, 即對臨界區(qū)對象初始化。該函數(shù)必須在執(zhí)行 EnterCriticalSection 前調(diào)用。單個進(jìn)程的線程可以為互斥同步使用臨界區(qū)對象。進(jìn)程負(fù) 責(zé)分配臨界區(qū)對象使用的內(nèi)存,可以通過對 CRITICAL_SECTION 類型變量的定義和使用 來實現(xiàn)。
(2)EnterCriticalSection
此函數(shù)用于等待指定的臨界區(qū)對象的所有權(quán)。授予調(diào)用線程所有權(quán)后,該函數(shù)返回, 臨界區(qū)對象在單個進(jìn)程的各線程內(nèi)強(qiáng)制互斥同步。在線程擁有臨界區(qū)對象以后,對同一 個臨界區(qū)對象應(yīng)調(diào)用
nterCriticalSection 函數(shù),防止發(fā)生死鎖。在退出臨界區(qū)后用 LeaveCriticalSection 函數(shù)使其他線程可以進(jìn)入臨界區(qū)。
(3)TryEnterCriticalSection
此函數(shù)用沒有阻塞的方式試圖進(jìn)入一個臨界區(qū)。若函數(shù)調(diào)用成功,則進(jìn)行調(diào)用的線 程擁有對臨界區(qū)的所有權(quán),否則立即返回。
(4)LeaveCriticalSection
此函數(shù)用于釋放對臨 界區(qū)對象的所有權(quán)。 每次線程對同一個對象執(zhí)行 EnterCriticalSection 或 TryEnterCriticalSection 都必須調(diào)用 LeaveCriticalSection 函數(shù)。
(5)DeleteCriticalSection 此函數(shù)用于刪除一個臨界區(qū)對象,釋放所有與不再為自己所控制的臨界區(qū)對象有關(guān)的資源。一個臨界區(qū)對象被刪除, 就不能再對其調(diào)用函數(shù) EnterCriticalSection ,函數(shù)TryEnterCriticalSection 和函數(shù) LeaveCriticalSection 了。
2)、互斥和信號量共有 7 個 API。
(1)CreateMutex
此函數(shù)用于創(chuàng)建命名或未命名的互斥對象。這些互斥對象用于進(jìn)程同步,當(dāng)互斥對 象不為任何線程擁有時才處于信號態(tài),否則將處于非信號態(tài)。若要線程釋放其所有權(quán), 則線程在每次互斥對象處于非信號態(tài)時都調(diào)用函數(shù) ReleaseMutex。當(dāng)不再需要互斥對象 時可以使用函數(shù) CloseHandle 來關(guān)閉互斥對象。當(dāng)所有互斥對象的打開句柄都關(guān)閉時, 就刪除互斥對象。
(2)OpenMutex
用于返回存在的已命名互斥對象的句柄。該函數(shù)允許多個進(jìn)程打開同一個互斥對象 的句柄。該函數(shù)的調(diào)用一定要在函數(shù) CreateMutex 創(chuàng)建互斥對象之后,當(dāng)不需要句柄時 可以調(diào)用 CloseHandle 函數(shù)。
(3)ReleaseMutex
此函數(shù)用于釋放互斥對象。若函數(shù)調(diào)用成功,互斥對象處于信號態(tài)。 (4)CreateSemaphore 此函數(shù)用于創(chuàng)建已命名或未命名的信號量對象,信號量用計數(shù)器實現(xiàn)同步。每次取信號量時(可利用函數(shù)WaitForSingleObject 來。盘柫坑嫈(shù)器遞減;每次ReleaseSemaphore 釋放信號量值時,信號量計數(shù)器遞增。計數(shù)永遠(yuǎn)不會小于 0 或大 于在 lSemMaxCount 參數(shù)中定義的值。
(5)OpenSemaphore
用于打開一個已經(jīng)存在的命名的信號量對象。該信號量必須是 CreateSemaphore 創(chuàng) 建的。如果不再需要時,可以用函數(shù) CloseHandle 關(guān)閉返回的句柄。
(6)WaitForSingleObject
此函數(shù)僅當(dāng)在參數(shù)列表中指定的對象處于信號態(tài)或超過了超時間隔時,該函數(shù)才返 回。
(7)ReleaseSemaphore
用來遞增信號量的計數(shù)。對于 CreateSemaphore 函數(shù)創(chuàng)建的對象使用,計數(shù)可以達(dá) 到設(shè)定的最大計數(shù)值。
2: windows 內(nèi)核內(nèi)存分為 paged memory 和 nonpaged memory,請問有什么區(qū)別? 答案:paged memory:是指可以分頁的內(nèi)存,可以交換到硬盤文件上。Nonpaged memory:不可分頁,也就是不能交換到硬盤文件上。有些內(nèi)存,比如驅(qū)動程序,內(nèi)核代碼是不允許交換出去的,應(yīng)該常駐內(nèi)存,就使用 nonpaged memory。
3:請問什么情況下,cache 中只放指令(數(shù)據(jù)直接從存儲器存。┍ cache 中放數(shù)據(jù)和指令的效率高?
答案:計算密集型 cache 中只放指令(數(shù)據(jù)直接從存儲器存。┍ cache 中放數(shù)據(jù) 和指令的效率高,可以充分利用指令的局部原理。
4:RISC 和 CISC 等其他指令集相比有哪些優(yōu)點,請至少舉出 5 個。
答案:(1)尋址方式少且簡單,一般為 2—3 種,最多不超過 4 種,絕不出現(xiàn)存儲器間接尋址方式。
(2)指令集中的指令數(shù)目一般少于 100 種,指令格式一般少于 4 種。
(3)指令功能簡單,控制器多采用硬布線方式,以期更快的執(zhí)行速度。
(4)平均而言,所有指令的執(zhí)行時間為一個處理時鐘周期。
(5)指令格式中用于指派整數(shù)寄存器的個數(shù)不少于 32 個,用于指派浮點數(shù)寄存器的個數(shù)不少于 16 個。
(6)強(qiáng)調(diào)通用寄存器資源的優(yōu)化使用。
(7)支持指令流水并強(qiáng)調(diào)指令流水的優(yōu)化使用。
5:選擇題:
如果兩個節(jié)點 x,y,preorder 遍歷,x 在 y 之前,postorder 遍歷,x 在y 之后,請問 x,y 的關(guān)系為:
A.x 是 y 的左兄弟。
B x 是 y 的右兄弟。
C.x 是 y 的祖先。 D x 是 y 的后裔。 答案:C。
6:請問下面程序如果運行會出現(xiàn)什么結(jié)果?如果有錯誤請指出并改正。
include <stdlib.h> include <string.h> class mystring{ public: mystring(){ m_str=NULL;
}
mystring(mystring& str){ if(m_str!=NULL){
delete []m_str;
}
m_str=new char[strlen(str.m_str)]; strcpy(m_str,str.m_str);
}
mystring & operator=(const char *str){ if(m_str!=NULL){
delete []m_str;
}
m_str=new char[strlen(str)+1]; strcpy(m_str,str);
}
~mystring(){ if(m_str!=NULL){ delete m_str;
}
}
private:
char *m_str;
};
int main(){ mystring str1; str1="hello world"; mystring str2; str2=str1;
mystring str3=str2;
return 0;
}
答案:程序運行會出現(xiàn)內(nèi)存釋放錯誤,錯誤共有四處,分別在下面改正的代碼中標(biāo)出。
include <stdlib.h> include <string.h>
class mystring{ public: mystring(){ m_str=NULL; } mystring(mystring& str){
/*if(m_str!=NULL){ delete []m_str; }*/
//錯誤 1,因為 m_str 沒有被初始化,所以此處可能為 NULL,也可能不為 NULL, 如 果 不 為 null , 則 會 出 錯 , 因 為 m_str 是 一 個 隨 機(jī) 的 值 。 m_str=new
char[strlen(str.m_str)+1];
//錯誤 2:長度應(yīng)該+1 strcpy(m_str,str.m_str); }
mystring & operator=(mystring& str){
//錯誤 3 : 缺少賦值重載函數(shù) if(m_str!=NULL){ delete []m_str; } m_str=new
har[strlen(str.m_str)+1];
//錯誤 2:長度應(yīng)該+1 strcpy(m_str,str.m_str); } mystring & operator=(const char
*str){ if(m_str!=NULL){ delete []m_str; } m_str=new char[strlen(str)+1]; strcpy(m_str,str); }
~mystring(){ if(m_str!=NULL){ delete []m_str;
//錯誤 4:析構(gòu)函數(shù)中,應(yīng)該析構(gòu)數(shù)組 } } private: char *m_str; }; int main(){ mystring str1;
str1="hello world"; mystring str2; str2=str1; mystring str3=str2; return 0; }。
7:100 個乒乓球取勝之道,A,B兩個人輪流拿,A先拿,一次只能拿[1,5]個, 獲勝者為拿到最后一個球的人。請問 A 第一次該拿幾個?以后又該怎么拿,才能夠確 保獲勝?
答案:A 先拿 4 個,然后 B 拿,設(shè) B 拿 x 個,則每次 A 拿 6-x 個即可。
8:有編號 1-50 的人,依次排列,然后單號出列,然后剩下的人重新編號,單號 出列,依次類推,最后剩下一個人,請問這個人原來編號是多少號?如果是每一次雙號 出列,請問這個人原來編號是多少?
答案:單號出列:32 號,雙號出列:1 號。