http://blog.csdn.net/anxiongshan/archive/2007/10/11/1819511.aspx
目錄
一、ANSI C/C++方面的知識
二、POSIX方面的知識
三、Linux編程基本使用知識
四、C++題目
五、QT編程
六、MiniGUI編程
七、Kernel & Driver
八、用中文Linux辦公
九、娛樂
一、ANSI C/C++方面的知識
(一.I).簡答題。下面的題目必須全部答對纔給分(20分):
1、 如何在C中初始化一個字符數組。
2、 如何在C中爲一個數組分配空間。
3、 如何初始化一個指針數組。
4、 如何定義一個有10個元素的整數型指針數組。
5、 s[10]的另外一種表達方式是什麼。
6、 GCC3.2.2版本中支持哪幾種編程語言。
7、 要使用CHAR_BIT需要包含哪個頭文件。
8、 對(-1.2345)取整是多少?
9、 如何讓局部變量具有全局生命期。
10、C中的常量字符串應在何時定義?
11、如何在兩個.c文件中引用對方的變量。
12、使用malloc之前需要做什麼準備工作。
13、realloc函數在使用上要注意什麼問題。
14、strtok函數在使用上要注意什麼問題。
15、gets函數在使用上要注意什麼問題。
16、C語言的詞法分析在長度規則方面採用的是什麼策略?
17、a+++++b所表示的是什麼意思?有什麼問題?
18、如何定義Bool變量的TRUE和FALSE的值。
19、C語言的const的含義是什麼。在定義常量時,爲什麼推薦使用const,而不是#define。
20、C語言的volatile的含義是什麼。使用時會對編譯器有什麼暗示。
(一.II).問答題。
1、-----------------------------------------------------------
"匈牙利命名法"有什麼優缺點?(2分)
2、-----------------------------------------------------------
下面x, y, *p的值是多少,有什麼問題?(2分)
int x, y, z = 2;
int *p=&z;
x=sizeof*p;
y=x/*p; /* x=?, *p=?, y=?, 有什麼問題?*/
3、-----------------------------------------------------------
下面的語句是什麼意思?如何聲明或定義才使它們更易懂?(10分)
int (*foo())();
int (*foo())[];
int (*foo[])();
(*(void(*)())0)();
void (*signal(int,void(*)(int)))(int);
4、-----------------------------------------------------------
本題(2分)。一般使用malloc時,需要進行強制類型轉換,如:
char *s; s = (char *)malloc(31);
下面中???該如何填寫,纔可以正確執行強制類型轉換?
int (*monthp)[31]; monthp = (???)malloc(31);
5、-----------------------------------------------------------
關於C語言運算符優先級的記憶技巧是什麼?(2分)
/* 下面r的值是多少 */
int hi, low, r;
hi=7;low=3;
r=hi<<4+low;
6、-----------------------------------------------------------
指針和數組的區別是什麼?用一個簡單的聲明把它們區分開。(2分)
指針和數組的聲明在什麼情況下是相同的?(2分)
7、-----------------------------------------------------------
C語言的左值(lvalue)和右值(rvalue)的含義是什麼?(2分)
8、-----------------------------------------------------------
爲什麼C語言可以實現printf(char *format, ...)這樣可變參數的調用形式?這樣有什
麼缺點?(2分)
9、-----------------------------------------------------------
說明C語言中術語"聲明""定義""原型"的含義?(2分)
10、-----------------------------------------------------------
舉一個例子,說明使用assert和防錯代碼的區別。(5分)
11、-----------------------------------------------------------
對語句 if else 與操作符 ? : 使用場合的比較。(2分)
12、-----------------------------------------------------------
編寫一個函數,輸入一個的整型數字,可以選擇按照8/10/16進制輸出字符串。
注意邊界值。(5分)
13、-----------------------------------------------------------
本題(2分)。下面是一個16x16的黑白圖標:
static unsigned short stopwatch[] = {
0x07c6,
0x1ff7,
0x383b,
0x600c,
0x600c,
0xc006,
0xc006,
0xdf06,
0xc106,
0xc106,
0x610c,
0x610c,
0x3838,
0x1ff0,
0x07c0,
0x0000,
};
如何修改聲明,可以使之在源代碼中形象地表現出圖形的模樣。
14、-----------------------------------------------------------
說出可以使用calendar[11][30]變量的四種類型定義。(5分)
如:int calendar[12][31]; /* 二維數組 */
15、-----------------------------------------------------------
使用strcmp,當字符串相同時會返回'/0'。但'/0'一般作爲邏輯假,
因此下面的語句不容易理解:
if (!strcmp(s, "string")) return EQUATION;
如何經過簡單修改,使之更易懂?(2分)
16、-----------------------------------------------------------
編寫一個自己的完全C語言版本的memset函數,並且評價這個實現的性能和可移植性。(5
分)
17、-----------------------------------------------------------
在樹和圖這些數據結構中,通常使用指針來組織數據。如果我們要把這些數據保存到文
件
中,指針是沒有意義的。我們該如何解決這個問題。(2分)
18、-----------------------------------------------------------
用2種不同的方法計算long變量的"1"bit的個數。(2分)
19、-----------------------------------------------------------
任意給出一個C的基本數據類型,如何編碼判斷這個數據類型是有符號還是無符號的?(2
分)
不得上機實驗,寫出下面代碼的輸出。解釋這個行爲是標準定義的,還是依賴實現的。(
2分)
int i;
for (i = 0; i < 10; i++) {
int j = i;
printf ("%d/n", j);
}
20、-----------------------------------------------------------
列出5種以上你所看過的C編程的書籍,並寫簡要書評。(5分)
對C的評價。如果要你改造一把菜刀,使之更加安全,你是否會使用這樣的菜刀,爲什麼?(5分)
(一.III)、分析題。
本題(各5分)。假設下面代碼中的變量都是合法變量,調用外部的函數都是正確的。回答幾個問題:
這些代碼意圖要幹什麼?
是否有問題?
如果有問題,該如何修改,或者如何避免類似錯誤發生?
如果沒有問題,如果代碼有輸出,輸出是什麼?
1、-----------------------------------------------------------
int isvowel (char c)
{
return c=='a'||c=='e'||c=='i'||c=='o'||c=='u';
}
2、-----------------------------------------------------------
while (c=='/t'||c=' '||c=='/n')
c=getc(f);
3、-----------------------------------------------------------
/* 當x=2, y=3, z=? */
if (x==0)
if (y==0)
z=-1;
else
z=x+y;
4、-----------------------------------------------------------
/* 處理網絡事件 */
void process_network_code(int x, int y)
{
/* 選擇modes_pointer資源 */
switch (line) {
case THING1:
/* 處理異常1#, 使用老的modes_pointer資源 */
doit1();
break;
case THING2:
/* 處理異常2#, 需要重新啓動服務 */
if (x == STUFF) {
/* 重新申請modes_pointer資源,沒有初始化 */
do_first_stuff();
/* 在這種條件下,有些資源不用重新申請 */
if (y == OTHER_STUFF)
break;
/* 申請剩下的資源,並初始化 */
do_later_stuff();
}
/* 初始化modes_pointer資源 */
initialize_modes_pointer();
break;
default:
/* 處理普通事件, 使用老的modes_pointer資源 */
processing();
}
/* 使用modes_pointer資源,處理事件 */
use_modes_pointer();
}
5、-----------------------------------------------------------
int is_gb2312_char(char c1, char c2)
{
if (c1 >= 0xa1 && c2 >= 0xa1)
return 1;
else
return 0;
}
6、-----------------------------------------------------------
下面x, y的值是多少,有什麼問題?
int x = 10, y = 3;
x ^= y;
y ^= x;
x ^= y;
/* x=?, y = ? */
7、-----------------------------------------------------------
int days[]={31,28,31,30,31,30,31,31,30,31,30,31,};
int calendar[12][31];
int (*monthp)[31];
int *dayp;
int i;
memset(calendar, 0, sizeof(calendar));
i = 0;
for (monthp = calendar; monthp < &calendar[12]; monthp++) {
for (dayp = *monthp; dayp < &(*monthp)[31]; dayp++) {
if (dayp - *monthp < days[calendar - monthp]) {
*dayp = i++ % 7 + 1;
}
}
}
8、-----------------------------------------------------------
void printnum(long n)
{
if (n < 0) {
putchar('-');
n = -n;
}
if (n >= 10) {
printnum(n/10);
}
putchar ("0123456789"[n%10]);
}
9、-----------------------------------------------------------
void * memchr(void *pv, unsigned char ch, size_t size)
{
unsigned char *pch = (unsigned char *) pv;
unsigned char *pchEnd = pch + size;
while (pch < pchEnd) {
if (*pch == ch)
return (pch);
pch++;
}
return NULL;
}
10、-----------------------------------------------------------
void * memchr(void *pv, unsigned char ch, size_t size)
{
unsigned char *pch = (unsigned char *) pv;
unsigned char *pchPlant = pch + size;
unsigned char chSave = *pchPlant;
*pchPlant = ch;
while (pch != ch) {
pch++;
}
*pchPlant = chSave;
return ((pch == pchPlant) ? NULL : pch);
}
11、-----------------------------------------------------------
void UnsToStr(unsigned short int u, char *str)
{
char *pch;
assert(u <= 65535);
pch = &str[5];
*pch = '/0';
do {
*--pch = u % 10 + '0';
} while ((u / 10) > 0);
strcpy(str, pch);
}
12、-----------------------------------------------------------
void *memmove(void *pvTo, void pvFrom, size_t size)
{
char *pbTo = (char *)pvTo;
char *pbFrom = (char *)pvFrom;
((pbTo < pbFrom) ? tailmove : headmove) (pbTo, pbFrom, size);
return (pvTo);
}
13、-----------------------------------------------------------
void *memcpy(void *pvTo, void pvFrom, size_t size)
{
char *pbTo = (char *)pvTo;
char *pbFrom = (char *)pvFrom;
while (size-- > 0);
*pbTo++ = *pbFrom++;
return (pvTo);
}
14、-----------------------------------------------------------
#include <stdio.h>
int main(int argc, char *argv[])
{
char s[]="0123456789";
int i = 0;
do {
printf ("%c", i++[s]);
} while(s?1:printf("/n")-1);
return 0;
}
15、-----------------------------------------------------------
int fibonacci(int x)
{
if (x == 1 || x == 2)
return 1;
return fibonacci(x - 2) + fibonacci(x - 1);
}
16、-----------------------------------------------------------
這裏有一個程序cdecl.c。寫出它的工作流程。寫出它的使用方法。
給出一個典型輸入用例,記錄下它的輸出。
(一.IV)、綜合編程題。
要求:
1、完成需求,程序運行正確。
2、工作原理文檔,使用文檔完整。
3、代碼規整優美。註釋得當。
4、運行速度足夠快。
5、用工具分析出是哪些代碼或函數造成速度瓶頸。
1、-----------------------------------------------------------
編寫一個排序程序。被排序的文件有8MB大小,一行一個隨機整數(ASCII格式)。要求對
這些整數進行
排序,並計算平均值,打印出排序所需的時間。(20分)
2、-----------------------------------------------------------
用dummy header技巧實現一個鏈表DEMO。要求具有create, insert, delete, search功
能。
編寫一個應用程序,使用上面的函數。使用dummy header技巧有什麼優點。(20分)
3、-----------------------------------------------------------
用heapsort算法實現優先隊列。要求具有create, insert, delete功能。
編寫一個應用程序,使用上面的函數。使用heapsort算法有什麼優點。(20分)
用trie(一種多叉樹)實現一個字典。要求具有create, insert, delete, search功能。
編寫一個應用程序,使用上面的函數。使用trie樹有什麼優點。(20分)
二、POSIX方面的知識。
(二.I)、簡答題。下面的題目必須全部答對纔給分:(5分)
1、在UNIX環境中,編譯流程是什麼?
2、ABI,ELF的英文全稱是什麼
3、一般UNIX的程序有多少段,舉一個實際的例子說明。
4、如何在kernel二進制代碼中找一個字符串。
5、段地址F000:FFF0轉換爲線形地址的值是多少(16進製表達)。
6、在一個UNIX文件系統中,文件的唯一性標誌是什麼?
(二.II)、問答題。
1、-----------------------------------------------------------
寫一些代碼。如何用文件實現信號燈?要求如果程序崩潰了,這個文件也將自動被刪除
。
爲什麼可以這樣實現信號燈?(5分)
傳統的signal函數信號處理爲什麼是不可靠的,信號和系統調用有何關係?(5分)
在圖形庫系統中往往提供timer的功能,除了使用ALARM信號外,你還可以使用什麼系統
調用來實現timer?(5分)
2、-----------------------------------------------------------
寫一些代碼,演示如何正確使用write系統調用。注意看好手冊再回答。(2分)
如果一個文件以rw模式打開,在進行read/write操作轉換時,需要進行什麼操作。(2分)
3、-----------------------------------------------------------
解釋終端結構termios.c_cc的MIN/TIME數值變化的帶來read/write的特性。(5分)
如何理解終端、控制終端、虛擬終端、控制檯、tty等類同的概念?(5分)
4、-----------------------------------------------------------
解釋計算機中Copy-On-Write的概念。(2分)
調用fork之後,子進程沒有繼承父進程的屬性有哪些?(5分)
解釋爲什麼每個程序在裝入執行之後,總是已經預先打開了stdout、stdin、stderr?(2分)
在fork之前,父進程打開了一個文件。在fork之後,如果子進程移動了文件指針,
父進程的文件指針有什麼變化;如果子進程關閉了文件,父進程有什麼變化?爲什麼會這樣?(5分)
標準輸入、輸出和錯誤輸出分別是什麼類型的緩衝,這些緩衝在用戶空間還是在覈心空間?
怎樣關閉他們的緩衝?如果父進程關閉了緩衝,在fork之後建立的子進程是否也關閉了緩衝?(5分)
vfork和fork相比,有什麼特色?(2分)
system函數是否等同於fork+exec?(2分)
wait系統調用有多少種條件可以退出?(2分)
5、-----------------------------------------------------------
系統調用和庫函數調用有什麼區別。(2分)
在linux2.4.x上的glibc和newlib(一種嵌入式C庫)的系統調用有什麼不同?(2分)
在linux2.4.x上,對系統調用execve如果調用成功,它返回的值是多少。(2分)
6、-----------------------------------------------------------
列出你所知道的2個內存跟蹤庫。(2分)
設計一個內存跟蹤方案,爲什麼選擇這個方案(5分)
(二.III)、綜合編程題。
要求:
1、完成需求,程序運行正確。
2、工作原理文檔,使用文檔完整。
3、代碼規整優美。註釋得當。
4、運行速度足夠快。
1、-----------------------------------------------------------
這裏有一個8MB的文件,編寫一個copy程序,拷貝這個文件,並計算所需時間。用工具分析
出是哪些代碼或函數造成速度瓶頸。
提示:如果只是使用read/write調用,不是一個好的實現。(20分)
2、-----------------------------------------------------------
Linux系統中,什麼時候會出現類似Y2K的問題。寫一個程序證明。(20分)
3、-----------------------------------------------------------
編寫一個程序,測試系統最小的睡眠時間間隔。(20分)
4、-----------------------------------------------------------
編寫一個pipe程序,測試有N個管道,size大小的buffer情況下,pipe的傳輸性能是多少?(20分)
5、-----------------------------------------------------------
在ext2文件系統上,單個文件最大可以達到多少?
寫一個程序獲得這方面的限制。(20分)
三、Linux編程基本使用知識。
(三.I).命令和shell
1)編寫一個腳本,統計一個目錄下面所有C代碼的行數。(2分)
2)編寫一個sed腳本,去除HTML文件中的HTML標記。(2分)
3)編寫一個腳本獲得當前系統eth0的IP地址。(2分)
4)編寫一個腳本以交互的方式,進行DNS的設定。(2分)
5)使用ls命令編寫一個腳本,實現ls -R,遞歸列出當前目錄下的所有目錄、文件。(2分)
6)-----------------------------------------------------------
在一個目錄下,找soft-link files,用下面的命令,原理是可行的,但無法操作,
該如何解決?要2種方法。(2分)
ls -l | grep ->
7)-----------------------------------------------------------
如何把標準錯誤輸出,重定向到標準輸出上。(2分)
8)-----------------------------------------------------------
我們的系統中的軟件包是使用RPM管理的。要求下面的問題寫出shell命令和運行結果。(
5分)
如何知道系統中安裝了幾個軟件包。
如何知道系統中安裝了哪幾類(group)軟件包。
如何知道kernel軟件包的簡述。
如何知道kernel軟件包的Changelog。
如何知道kernel軟件包有幾個文件。
如何知道kernel軟件包安裝後有多大。
(三.II)、編輯工具的使用。(各2分)
1)如何使用vi進行塊拷貝、粘貼、刪除的操作
2)如何設置Tab的長度,以及自動縮進的長度
3)如何使用tag進行代碼閱讀
4)如何在1~10行,有確認的進把所有的RedHat改爲RedFlag
5)在SourceNavigator中,如何跳到一個變量的聲明處?如何得知光標當前的位置在那個函數體內?
(三.III)、編譯器與調試器。(各2分)
1)如何使用gcc得到宏展開的中間代碼
2)如何通過gcc在命令行中傳入宏定義
3)在那一級優化的情況下,內聯函數才真正的內聯到代碼中
4)gdb的watch命令如何使用,有何缺點
5)gdb中使用什麼命令可以顯式調用的棧幀,如何查看某個棧幀上的局部變量
6)如何使用gdb調試多進程
7)如何使能/禁止core dump?
(三.IV)、庫。(各2分)
1)如何知道XSetIMValues這個符號在那個X的庫文件中
2)如何讀取C++的符號名,更具可讀性
3)請解釋動態庫的soname概念
4)解釋在鏈接時rpath選項的含義
(三.V)、Makefile。(10分)
如果有一個簡單的Test項目目錄如下:
# tree Test
Test
|-- common.h
|-- main.cpp
|-- test.cpp
`-- test.h
1)使用wildcard、patsubst函數編寫一個C++項目的Makefile文件
2)使用automake、autoconfig編寫一個支持configure選項的configure.in腳本
(三.VI)、CVS。(10分)
1)如果一個CVS項目中,甲添加了一個子目錄模塊,那麼乙在update時是否會自動檢
出這個新添加的子模塊?如果不能,那麼你有什麼好的解決方案?
2)如何在一個CVS項目中添加一個二進制文件,這個二進制文件可以進行增量的版本管理嗎?
3)如何檢出標記(tag)爲milestone-1的版本,如何創建以milestone-1爲基礎的分支
milestone-1-b1,並如何把分支的修改合併到milestone-1的主分支上
(三.VII)、Linux/GNU編程基本知識
1、-----------------------------------------------------------
Linux2.4.x有多少種類型的設備文件?分別寫出來。(2分)
2、-----------------------------------------------------------
glibc動態庫的搜尋次序是什麼?(2分)
glibc 2.1.x 與 2.2.x的動態庫的搜尋次序有什麼不同?爲什麼會採用現在的方案?(2分)
3、綜合編程題。
要求:
1、完成需求,程序運行正確。
2、工作原理文檔,使用文檔完整。
3、代碼規整優美。註釋得當。
4、運行速度足夠快。
1、-----------------------------------------------------------
本題(20分)。寫一個程序,有三個功能:
a)取得CMOS中的當前時間,按照YY:MMD:HH:MM:SS格式輸出。
b)取得物理內存的大小,格式化輸出。
c)取得從物理段地址F000:FFF0起,16個字節的值,每字節按照16進制格式輸出。
2、-----------------------------------------------------------
本題(20分)。對串口編程,編寫一對類似ping的程序,作用在串口上,瞭解serial的聯
通情況。
定義協議
要求:
定義一個聯通和響應協議。至少具有:發送、回覆、超時三種狀態。除超時狀態外,所有
狀態的數據必須經過校驗纔可使用。
ping_serial_client
要求:
1,發送數據包;
2,等待回覆數據包,直到超時;
3,如果有回覆數據包,對數據包進行校驗;
4,計算校驗通過的數據包之間的時間差;
5,重複直到用戶退出;
6,統計丟包率,時間。
界面:
bash# ping_serial_client /dev/ttyS0 baud_value
??bytes from ttyS0, time=??ms
......
^C
--- ttyS0 ping statistics ---
?? packets transmitted, ?? received, ??% loss
time ??ms, min/avg/max = ??/??/?? ms
ping_serial_server
要求:
1,等待對方的發送數據包;
2,對發送數據包進行校驗;
3,校驗通過則回覆數據包;
4,重複直到用戶退出;
界面:
bash# ping_serial_server /dev/ttyS0 baud_value
3、-----------------------------------------------------------
編寫一對socket程序,要求類似於network echo procotol。
Client每隔1秒把自己的IP地址輪流循環發送給一個Server.
Server接到IP後,在屏幕上打印對方IP;然後把自己的IP發送回去。
Client收到回覆後,在屏幕上打印對方IP。
程序一直運行,直到用戶退出。各自分類統計接收到的各IP的數據包的個數。
注意:Client可以向多個Server發送請求,Server也可以接收多個Client請求。
注意:輸出信息的美觀,和對錯誤的處理。
-----------------------------------------------------------
四、C++題目。
-----------------------------------------------------------
1。給定下面的代碼:
class Graph{
public:
Graph() { s_gCount++; }
virtual ~Graph() { s_gCount--;}
virtual int drawOut() = 0;
static int getTotalCount() { return s_gCount; }
protected:
int m_x;
int m_y;
static int s_gCount;
};
回答下列問題:(各5分)
1)這個類能否生成實例,爲什麼?
2)上述代碼中有什麼錯誤?
3)如果有一個Rectangle類公共繼承該類,那麼s_gCount對Rectangle的成員屬性是什麼
?
4)對Graph及其子類的計數是否有效,如果無效應該採取什麼措施?
5)請畫出該類的內存佈局結構示意圖
-----------------------------------------------------------
2。給定下面的代碼:
class A
{
int a;
};
class AA : public A
{
int aa;
};
class X : public virtual A
{
int x;
};
class Y : public virtual A
{
int y;
};
class Z : public X, public Y {
int z;
};
回答下列問題:(各5分)
1)請畫出上述5個類的UML類圖
2)請畫出A、AA、X、Z的內存佈局結構示意圖
-----------------------------------------------------------
3。給定下面代碼:
#include <stdio.h>
#include <stdlib.h>
typedef struct _AAA
{
int a;
}AAA, *PAAA;
class CAAA
{
public:
CAAA() { m_a.a = 0; }
CAAA(CAAA& in) { printf("CAAA(CAAA& in)/n"); }
CAAA(AAA in) { printf("CAAA(AAA in)/n"); }
CAAA(int in) { printf("CAAA(int in)/n"); }
private:
AAA m_a;
public:
operator PAAA ()
{
return &m_a;
}
};
void test0(PAAA pa)
{
printf("test0/n");
}
void test1(CAAA ca)
{
printf("test1/n");
}
void test2(CAAA ca)
{
printf ("test2/n");
}
void main(void)
{
CAAA a;
test0 (a);
AAA b;
test1 (b);
int i=0;
test2 (i);
}
請回答下列問題:(各5分)
1)找出程序中的錯誤
2)test0函數聲明傳入的參數爲PAAA類型,而在main函數中,實際傳入的是CAAA類型,
這是否是一個錯誤?如果不是,請解釋原因。
4。回答下列問題:
1)C++中的struct和class類型有什麼區別?(2分)
2)假定一個class名爲Test,具有構造函數、拷貝構造函數、operator =,那麼
Test a;
Test b=a;
分別執行的是哪一個函數?(2分)
3)C++程序進行鏈接時是否必須鏈接stdc++函數庫,如果不必須情況下不需要,什麼情
況下需要?(2分)
4)你所熟悉的關於C++的中英文經典書籍都有哪些,它們分別都側重於什麼方面?(5分)
五、QT編程。任選2題完成。(各20分)
要求:按照綜合編程題目的要求編寫代碼和文檔。
1.編寫一個簡單的clock控件, 要求從QWidget繼承, 有一個指針和錶盤,指針每12秒轉一
圈,
並且可以用鼠標左鍵,起動和停止指針的轉動.
2.給定一個designer生成的UI文件, 讀取指定名字控件的幾何信息,計算出該控件的面積
大小.
(用Dom和SAX都可)
3.設計一個程序, 建立個人信息庫,包括:姓名,年齡,性別,住址.建立完之後可以查處特
定人
的信息,用designer設計你的界面, 不要求把信息庫存在硬盤上.
4.把第三題變成國際化程序, 要求兩種語言中文和英文.需要用qt-linquist等工具.
5. 用QSocket實現兩臺不同機器間的收發, 收發要求用戶動態輸入.
提示:以上各題需在qt3.0以上實現,推薦用qt-3.1.1,不限止qt-embedded或qt-desktop.
六、MiniGUI編程
要求:按照綜合編程題目的要求編寫代碼和文檔。
1.裁剪MiniGUI字體庫,使它僅支持英文和繁體中文。(10分)
2.描述MiniGUI/MPP的消息機制(20分)
3.使用MPP和MySql,編寫一使用在商場POS機上的應用,要求如下:(50分)
1)收銀員帳戶管理:每臺POS機供若干個收銀員和一個系統管理員使用.收銀員憑密碼
登錄POS機,密碼可修改.收銀員只能查看自己的銷售數據,
但不能刪除.系統管理員可以增加刪減收銀員帳戶,查詢銷售記錄.
2)收款管理:計算顧客購買商品總金額;計算找零
3)顧客會員管理:根據顧客ID,判斷會員等級及相應打折級別.
4)屏幕鎖定功能:特定按健觸發屏幕鎖定,輸入密碼後解鎖
七、Kernel & Driver
內核基礎試題
1. 簡答題。(各10分)
1.1 Spin Lock 相對於信號量的特點;在UP/MP/SMP這些不同環境下,Spin Lock的不同實現方法。
1.2 簡要說明e2compr壓縮文件系統的壓縮策略;經其處理後,上層文件系統(EXT2/3等)是否會受到影響。
1.3 比較linux操作系統內核態和用戶態的搶佔性,及兩者之間存在差異的原因。
1.4 linux2.2支持的最大進程數是多少,演進至2.4後,這一制約是如何克服的。
1.5 列舉中斷屏蔽的類型,並簡單比較。
1.6 列舉linux所要處理的定時/計數器(實際的外圍硬件設備,不是指軟件定時器),及其用途。
2. 問答題。(各20分)
2.1 窮舉在用戶態空間,內核消息的獲取方式、差異、以及差異的原因。
2.2 解釋linux進程調度中的epoch概念,該機制的目的。
2.3 描述一個硬件中斷信號發生,到爲其註冊的中斷服務例程開始執行,之間所經過的內核處理過程。並進一步分析,制約linux
中斷響應時間的因素存在於哪些方面。
2.4 比較底半機制(BH)和Tasklet的特點,及運行方面的差異。
2.5 說明引導過程中initrd.img和linuxrc作用,給出製作initrd.img的僞代碼形式的流程。
2.6 在VFS層中如何區分設備文件和正規文件?
2.7 內核有幾種方式訪問硬件設備?
2.8 內核如何訪問iomem?請舉例說明。
3. 分析題。
3.1 系統時間設置問題。(10分)
同樣採用date命令,目的在於修改系統時間,在不同的系統上卻有不同的現象:
假定初始時間(T1)爲 03月01日16:00 2003年,期望的修改後時間(T2)爲 12月31日00:00 2002年,
<1> 在EDK系統中,執行命令 #date 123100002002,系統時間立即會變爲T2;
但系統重新啓動之後,系統時間仍恢復爲T1的時間區間: 03月01日16:02
2003年,修改並未保留下來。
<2> 在RedHat7.2/8.0中,重複上述設置,系統重新啓動之後,時間設置得到了保
留,系統運行於T2的時間區間:12月31日00:02 2002年。
請分析<1> 中所表現出的現象是由於什麼原因造成的;
3.2 在大家相關於串口的工作中,可能會遇到這樣的問題:(20分)
串口在發送數據時,不是連續且迅速地發送,而是以一個固定的節拍(10秒),且
每次只發送等長度的一段數據,請列舉可能造成這一問題的所有原因;
3.3 Oops分析。(50分)
以下是一段經過符號解析過的Oops信息,我們知道造成這個Oops的直接原因在於對
於
內核函數__wake_up的調用過程之中出現了問題;基於上述判斷,請基於已經給出
的__wake_up相關源碼和反彙編碼,大致分析問題出現在哪個源碼行,並給出分析結論;
-----------------------------------------------------------
ksymoops信息:
ksymoops 2.4.4 on i686 2.2.19-rthal3. Options used
-v /usr/src/linux-2.2.19/vmlinux (specified)
-k /proc/ksyms (specified)
-l /proc/modules (specified)
-o /lib/modules/2.2.19-rthal3/ (default)
-m /usr/src/linux-2.2.19/System.map (specified)
current->tss.cr3 = 07d29000, %cr3 = 07d29000
*pde = 00000000
Oops: 0000
CPU: 0
EIP: 0010:[<C01110C1>]
Using defaults from ksymoops -t elf32-i386 -a i386
eax: 00000014 ebx: c0eabf74 ecx: 00000013 edx: 00000021
esi: 00000000 edi: 00000020 ebp: c0eabf6c esp: c0eabf60
ds: 0018 es: 0018 ss: 0018
Process in.identd (pid: 828, process nr: 6, stackpage=c0eab000)
Stack: 00000000 c807ca04 00000021 c0eabf74 c807be21 c0eabfb0 c807bf74
c807c940
00000000 00000000 00000000 c803fb60 c807e000 00000e20 2b124c28
0000027c
0010a000 c807c900 00000000 0000f944 bffff944 c803d2ec 00000000
00000000
Call Trace: [<c807ca04>] [<c807be21>] [<c807bf74>] [<c807c940>]
[<c803fb60>] [<c807e000>]
[<c807c900>] [<c803d2ec>] [<c803c0a0>]
Code: 8b 02 85 45 fc 74 1b 85 ff 74 10 83 7a 44 00 74 0a 85 f6 75
>>EIP; c01110c1 <__wake_up+2d/6c> <=====
Trace; c807ca04 <[rt_das]timeout+c4/c8>
Trace; c807be21 <[rt_das]read_timeout+25/28>
Trace; c807bf74 <[rt_das]pulse_isr+150/19c>
Trace; c807c940 <[rt_das]timeout+0/c8>
Trace; c803fb60 <[rtai]global_irq_handler+0/80>
Trace; c807e000 <.bss.end+14a1/????>
Trace; c807c900 <[rt_das]board+0/28>
Trace; c803d2ec <[rtai]dispatch_global_irq+28/90>
Trace; c803c0a0 <[rtai]GLOBAL0_interrupt+18/34>
Code; c01110c1 <__wake_up+2d/6c>
00000000 <_EIP>:
Code; c01110c1 <__wake_up+2d/6c> <=====
0: 8b 02 movl (%edx),%eax <=====
Code; c01110c3 <__wake_up+2f/6c>
2: 85 45 fc testl %eax,0xfffffffc(%ebp)
Code; c01110c6 <__wake_up+32/6c>
5: 74 1b je 22 <_EIP+0x22> c01110e3
<__wake_up+4f/6c>
Code; c01110c8 <__wake_up+34/6c>
7: 85 ff testl %edi,%edi
Code; c01110ca <__wake_up+36/6c>
9: 74 10 je 1b <_EIP+0x1b> c01110dc
<__wake_up+48/6c>
Code; c01110cc <__wake_up+38/6c>
b: 83 7a 44 00 cmpl $0x0,0x44(%edx)
Code; c01110d0 <__wake_up+3c/6c>
f: 74 0a je 1b <_EIP+0x1b> c01110dc
<__wake_up+48/6c>
Code; c01110d2 <__wake_up+3e/6c>
11: 85 f6 testl %esi,%esi
Code; c01110d4 <__wake_up+40/6c>
13: 75 00 jne 15 <_EIP+0x15> c01110d6
<__wake_up+42/6c>
Unable to handle kernel paging request at virtual address 66fe4603
current->tss.cr3 = 00e94000, %cr3 = 00e94000
*pde = 00000000
Oops: 0000
CPU: 0
EIP: 0010:[<c01113e6>]
EFLAGS: 00010a83
Warning (Oops_read): Code line not seen, dumping what data is available
>>EIP; c01113e6 <interruptible_sleep_on+5a/78> <=====
1 warning issued. Results may not be reliable.
<附錄>
1. __wake_up的源碼:
void __wake_up(struct wait_queue **q, unsigned int mode)
{
struct task_struct *p, *best_exclusive;
struct wait_queue *head, *next;
unsigned int do_exclusive;
if (!q)
goto out;
/*
* this is safe to be done before the check because it
* means no deference, just pointer operations.
*/
head = WAIT_QUEUE_HEAD(q);
read_lock(&waitqueue_lock);
next = *q;
if (!next)
goto out_unlock;
best_exclusive = 0;
do_exclusive = mode & TASK_EXCLUSIVE;
while (next != head) {
p = next->task;
next = next->next;
if (p->state & mode) {
if (do_exclusive && p->task_exclusive) {
if (best_exclusive == NULL)
best_exclusive = p;
}
else {
wake_up_process(p);
}
}
}
if (best_exclusive)
wake_up_process(best_exclusive);
out_unlock:
read_unlock(&waitqueue_lock);
out:
return;
}
2. __wake_up的反彙編碼:
c0111094 <__wake_up>:
c0111094: 55 pushl %ebp
c0111095: 89 e5 movl %esp,%ebp
c0111097: 83 ec 08 subl $0x8,%esp
c011109a: 57 pushl %edi
c011109b: 56 pushl %esi
c011109c: 53 pushl %ebx
c011109d: 89 55 fc movl %edx,0xfffffffc(%ebp)
c01110a0: 85 c0 testl %eax,%eax
c01110a2: 74 50 je c01110f4 <__wake_up+0x60>
c01110a4: 8d 48 fc leal 0xfffffffc(%eax),%ecx
c01110a7: 89 4d f8 movl %ecx,0xfffffff8(%ebp)
c01110aa: 8b 18 movl (%eax),%ebx
c01110ac: 85 db testl %ebx,%ebx
c01110ae: 74 44 je c01110f4 <__wake_up+0x60>
c01110b0: 31 f6 xorl %esi,%esi
c01110b2: 89 d7 movl %edx,%edi
c01110b4: 83 e7 20 andl $0x20,%edi
c01110b7: 39 cb cmpl %ecx,%ebx
c01110b9: 74 2d je c01110e8 <__wake_up+0x54>
c01110bb: 90 nop
c01110bc: 8b 13 movl (%ebx),%edx
c01110be: 8b 5b 04 movl 0x4(%ebx),%ebx
c01110c1: 8b 02 movl (%edx),%eax
c01110c3: 85 45 fc testl %eax,0xfffffffc(%ebp)
c01110c6: 74 1b je c01110e3 <__wake_up+0x4f>
c01110c8: 85 ff testl %edi,%edi
c01110ca: 74 10 je c01110dc <__wake_up+0x48>
c01110cc: 83 7a 44 00 cmpl $0x0,0x44(%edx)
c01110d0: 74 0a je c01110dc <__wake_up+0x48>
c01110d2: 85 f6 testl %esi,%esi
c01110d4: 75 0d jne c01110e3 <__wake_up+0x4f>
c01110d6: 89 d6 movl %edx,%esi
c01110d8: eb 09 jmp c01110e3 <__wake_up+0x4f>
c01110da: 89 f6 movl %esi,%esi
c01110dc: 89 d0 movl %edx,%eax
c01110de: e8 2d f9 ff ff call c0110a10 <wake_up_process>
c01110e3: 3b 5d f8 cmpl 0xfffffff8(%ebp),%ebx
c01110e6: 75 d4 jne c01110bc <__wake_up+0x28>
c01110e8: 85 f6 testl %esi,%esi
c01110ea: 74 08 je c01110f4 <__wake_up+0x60>
c01110ec: 89 f0 movl %esi,%eax
c01110ee: e8 1d f9 ff ff call c0110a10 <wake_up_process>
c01110f3: 90 nop
c01110f4: 8d 65 ec leal 0xffffffec(%ebp),%esp
c01110f7: 5b popl %ebx
c01110f8: 5e popl %esi
c01110f9: 5f popl %edi
c01110fa: 89 ec movl %ebp,%esp
c01110fc: 5d popl %ebp
c01110fd: c3 ret
c01110fe: 89 f6 movl %esi,%esi
-----------------------------------------------------------
內核驅動題
以下設計應該包括設計文檔,實現策略說明,代碼包,測試用例,使用說明.
要求:按照綜合編程題目的要求編寫代碼和文檔。
參考資料: <Linux設備驅動程序>第二版.
1.設計並實現一個軟件watchdog設備,以監視系統運行情況.(50分)
說明:watchdog設備用於監測系統運行狀態,正常運行的系統定期寫watchdog以使其
不會超時,一旦超時,意味系統已掛起;watchdog應該重啓系統. 現在的軟件watchdog
不重啓系統,只用於監視應用程序的運行.
2.設計並實現一個簡化的、容量可以變化的內存FIFO設備.(50分)
八、用中文Linux辦公。
要求本考卷完全在Linux完成,並要求進行版面的格式化或美化。如果只提交TEXT版本,
本題不得分。(各10分)
本題要求是:
1、提交進行版面的格式化或美化的PDF版本。爲方便修改和評分,還須提交一個lyx或te
x版本。
2、PDF內嵌的中文字體使用的是紅旗桌面版4.0所攜帶的新版宋體。
九、娛樂。(沒有分數)
不會娛樂的程序員不是好的程序員。本部分沒有分數,但是聰明的人在這裏是不會留下空白的。
1、運行RedHat 7.3上面的推箱子游戲。用方向-數字的方式(如左3,右4)記錄下通過第一關
的過程,同時記錄下過關的時間。看誰的步數少,時間短。
2、運行emacs + doctor遊戲。摘錄下10句以上的對話,看誰的對話最精彩,同時也看誰的心理最變態。
************************************
答案
************************************
這部分是ANSI C的一些問題,題目的前提是必須都答對,看似很變態,但是細想一下,這些都是最基礎的,雖然我們在使用他們的
時候會犯這樣那樣的錯誤,但是最終目的是不犯錯誤,不是麼,那麼好,從最基礎的開始。
1、 如何在C中初始化一個字符數組。
這個問題看似很簡單,但是我們要將最簡單的問題用最嚴謹的態度來對待。關鍵的地方:初始化、字符型、數組。最簡單的方法是
char array[];。這個問題看似解決了,但是在初始化上好像還欠缺點什麼,個人認爲:char array[5]={'1','2','3','4','5'};
或者char array[5]={"12345"};或者char array[2][10]={"China","Beijing"};也許更符合“初始化”的意思。
2、 如何在C中爲一個數組分配空間。
最簡單的方法是:char array[5];意思是分配給數組array一個5個字節的空間。但是我們要知道在C中數組其實就是一個名字,其
實質含義就是指針,比如char array[];是到底分配的多少空間?所以我們要將其分成爲兩種不同的形式給出答案:
一種是棧的形式:char array[5];
一種是堆的形式:char *array; array=(char *)malloc(5);//C++: array=new char[5];
堆和棧的含義其實我也沒弄太透徹,改天明白了再發一篇。
我們要明白的是,第一種形式空間分配的大小可能會受操作系統的限制,比如windows會限制在2M;第二種形式成空間分配很靈活,
想分配多少分配多少,只要RAM夠大。
3、 如何初始化一個指針數組。
首先明確一個概念,就是指向數組的指針,和存放指針的數組。
指向數組的指針:char (*array)[5];含義是一個指向存放5個字符的數組的指針。
存放指針的數組:char *array[5];含義是一個數組中存放了5個指向字符型數據的指針。
按照題意,我理解爲初始化一個存放指針的數組,char *array[2]={"China","Beijing"};其含義是初始化了一個有兩個指向字符
型數據的指針的數組,這兩個指針分別指向字符串"China"和"Beijing"。
4、如何定義一個有10個元素的整數型指針數組。
既然只是定義而不是初始化,那就很簡單且沒有爭議了:int *array[10];。
5、 s[10]的另外一種表達方式是什麼。
前面說過了,數組和指針其實是數據存在形態的兩種表現形式,如果說對於數組s[],我們知道*s=s[0],那麼s[10]的另一種表達
方式就是:*(s+10)。
6、 GCC3.2.2版本中支持哪幾種編程語言。
這個問題實在變態,就像問你#error的作用是什麼一樣。不可否認,gcc是linux下一個亮點,是一個備受無數程序員推崇的編譯器
,其優點省略1000字,有興趣可以自己查,我翻了翻書,書上曰:支持C,C++,Java,Obj-C,Ada,Fortran,Pascal,Modula-3等語言,
這個“等”比較要命,不過我認爲已經很全了,如果認爲還是不全,乾脆把ASM也加上算了,不過那已經不算是編譯了。
7、 要使用CHAR_BIT需要包含哪個頭文件。
如果結合上面的問題,答題的人估計會認爲自己撞鬼了,這個問題實在是……搜索了一下,應該是limits.h。
8、 對(-1.2345)取整是多少?
其實不同的取整函數可能有不同的結果,不過這個數沒有太大的爭議,答案是-1。
9、 如何讓局部變量具有全局生命期。
具體的生命期的概念我覺得我還要好好深入的學習一下,但是這個題目還算比較簡單,即用static修飾就可以了,但是隻是生命期
延長,範圍並沒有擴大,除非把這個變量定義在函數體外的靜態區,不過那樣就變成全局變量了,彷彿不符合題目要求。
10、C中的常量字符串應在何時定義?
這個問題說實話不是很理解題乾的意思,據我理解,有兩種情況,一種是預處理階段,用#define定義;還有就是使用const修飾詞
,不過const修飾的是一個變量,其含義是“只讀”,稱之爲常量並不準確,但是確實可以用操作變量的方法當常量用。所以還是
第一種比較靠譜。
11、如何在兩個.c文件中引用對方的變量。
這個問題也問的挺含糊的,怎麼說呢,最簡單最直接的方法是爲變量添加extern修飾詞,當然,這個變量必須是全局變量。還有一
種就是利用函數調用來進行變量的間接引用,比如這個C文件中的一個函數引用另外一個C中的函數,將變量通過實參的形式傳遞過
去。不過題目既然說是引用,那麼還是用第一個答案好了。
12、使用malloc之前需要做什麼準備工作。
其實準備工作很多啊,比如你需要一臺計算機之類的。玩笑話,我們首先要知道malloc的用途,簡單的說就是動態的分配一段空間
,返回這段空間的頭指針。實際的準備工作可以這麼分:需要這段空間的指針是否存在,若不存在,則定義一個指針用來被賦值,
還要清楚要返回一個什麼類型的指針,分配的空間是否合理;如果指針已經存在,那麼在重新將新的空間頭地址賦值給這個指針之
前,要先判斷指針是否爲NULL,如果不是要free一下,否則原來的空間就會被浪費,或者出錯,free之後就按照前一種情形考慮就
可以了。
13、realloc函數在使用上要注意什麼問題。
這個函數我也才知道的,汗一個。據我的初步理解,這個函數的作用是重新分配空間大小,返回的頭指針不變,只是改變空間大小
。既然是改變,就有變大、變小和爲什麼改變的問題。變大,要注意不能大到內存溢出;變小,那變小的那部分空間會被徵用,原
有數據不再存在;爲什麼改變,如果是想重新挪作他用,還是先free了吧。
14、strtok函數在使用上要注意什麼問題。
這個問題我不知道能不能回答全面,因爲實在是用的很少。這個函數的作用是分割字符串,但是要分割的字符串不能是常量,這是
要注意的。比如先定義一個字符串:char array[]="part1,part2";,strtok的原形是char *strtok(char *string, char
*delim);,我們將","作爲分隔符,先用pt=strtok(array,",");,得到的結果print出來就是"part1",那後面的呢,要寫成
pt=strtok(NULL,",");,注意,要用NULL,如果被分割的字符串會被分成N段,那從第二次開始就一直要用NULL。總結起來,需要
注意的是:被分割的字符串和分隔符都要使用變量;除第一次使用指向字符串的指針外,之後的都要使用NULL;注意使用這個函數
的時候千萬別把指針跟丟了,不然就全亂了。
15、gets函數在使用上要注意什麼問題。
這是一個鍵盤輸入函數,將輸入字符串的頭地址返回。說到要注意的問題,我還是先查了一下網上的一些情況,需要注意的就是
gets以輸入回車結束,這個地球人都知道,但是很多人不知道的是,當你輸入完一個字符串後,這個字符串可能依然存在於這個標
準輸入流之中,當再次使用gets的時候,也許會把上次輸入的東西讀出來,所以應該在使用之後用fflush(stdin);處理一下,將輸
入流清空。最後也還是要注意溢出的問題。關於這個答案我比較含糊,不知道有沒有高人高見?
16、C語言的詞法分析在長度規則方面採用的是什麼策略?
我無語……聞所未聞啊……還是搜索了一下,有一篇文章,地址是:
http://202.117.80.9/jp2005/20/kcwz/wlkc/wlkc/03/3_5_2.htm,是關於詞法分析器的。其中提到了兩點策略: (1) 按最長匹配
原則確定被選的詞型;(2) 如果一個字符串能爲若干個詞型匹配,則排列在最前面的詞型被選中。不知道是不是題乾的要求,還是
其他什麼。我乃一介草民,望達人指點迷津!
17、a+++++b所表示的是什麼意思?有什麼問題?
這個東西(稱之爲東西一點都不過分)其實並沒有語法錯誤,按照C對運算符等級的劃分,++的優先級大於+,那麼這句話會被編譯
器看做:(a++)+(++b),這回明白了吧。有什麼問題,語法上沒有問題,有的是道德上的問題!作爲一個優秀的程序員,我們要力
求語句的合法性和可讀性,如果寫這句的人是在一個team裏,那麼他基本會被打的半死……最後討論一下結果:假設a之前的值是3
,b是4,那麼運行完這個變態語句後,a的值是4,b是5,語句的結果是8。
18、如何定義Bool變量的TRUE和FALSE的值。
不知道這個題有什麼陷阱,寫到現在神經已經大了,一般來說先要把TURE和FALSE給定義了,使用#define就可以:
#define TURE 1
#define FALSE 0
如果有一個變量需要定義成bool型的,舉個例子:bool a=TURE;就可以了。
19、C語言的const的含義是什麼。在定義常量時,爲什麼推薦使用const,而不是#define。
首先,這個題幹抽了10題回答的一個大嘴巴。關於常量的概念看來我要好好看看書了……我說過了,const修飾詞可以將一個變量
修飾爲“只讀”,這個就能稱爲常量麼?姑且認爲可以。回到題目中,const是隻讀的意思,它限定一個變量不允許被改變,誰都
不能改!既然是修飾變量,那麼變量的類型就可以豐富多彩,int啊,char啊,只要C認識的都可以;但是#define就不可以了,在
預處理階段缺乏類型檢測機制,有可能會出錯。還有就是變量可以extern,但是#define就不可以。貌似const還可以節省RAM,這
個我倒是沒有考證過。至於const的用法和作用,有很多,我會總結後發上來。
20、C語言的volatile的含義是什麼。使用時會對編譯器有什麼暗示。
終於最後一題了,容易麼……如果這個測試是一個關於嵌入式的,那麼這道題非常重要!!從詞面上講,volatile的意思是易變的
,也就是說,在程序運行過程中,有一些變量可能會被莫名其妙的改變,而優化器爲了節約時間,有時候不會重讀這個變量的真實
值,而是去讀在寄存器的備份,這樣的話,這個變量的真實值反而被優化器給“優化”掉了,用時髦的詞說就是被“和諧”了。如
果使用了這個修飾詞,就是通知編譯器別犯懶,老老實實去重新讀一遍!可能我說的太“通俗”了,那麼我引用一下“大師”的標
準解釋:
volatile的本意是“易變的” 。
由於訪問寄存器的速度要快過RAM,所以編譯器一般都會作減少存取外部RAM的優化,但有可能會讀髒數據。當要求使用volatile 聲
明的變量的值的時候,系統總是重新從它所在的內存讀取數據,即使它前面的指令剛剛從該處讀取過數據。而且讀取的數據立刻被
保存。
精確地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器裏的備份。
下面是volatile變量的幾個例子:
1). 並行設備的硬件寄存器(如:狀態寄存器)
2). 一箇中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)
3). 多線程應用中被幾個任務共享的變量
嵌入式系統程序員經常同硬件、中斷、RTOS等等打交道,所用這些都要求volatile變量。不懂得volatile內容將會帶來災難。
....