筆試題目草稿-C語言基礎及算法

 

#include <stdlib.h>

 

typedef struct foo

{

    int x;

    int y;

    unsigned long ptr;

    char* buffer;

}foo_t;

 

代碼一:

考察考生對可執行文件空間結構的認識.堆,棧,初始化空間及未初始化空間的作用.

 

foo_t* factory(int x,int y) 

{

    foo_t fp;

// foo_t* fp = (foo_t*)malloc(sizeof(foo_t));

    if(x>0 && x < 1024)

        fp.x = x;

//fp->x = x;

    if(y>0 && y < 768)

        fp.y = y;

//fp->y = y;

 

    return &fp;

//return fp;

}

 

 

代碼二:

考察考生對變量及變量指針聲明時是否分配可用空間的理解.

int add_buffer() 

{

    foo_t* fp;

    /*

 need malloc before use a pointer.

 */

    //fp = (foo_t*)malloc(sizeof(foo_t));

    fp->buffer = "hello alibaba";

 

    printf("BUFFER => %s\n",fp->buffer);

    /*

 need free the malloced pointer.

 */

    //free(fp);

    return 0;

}

 

代碼三:

考察考生是否對細節足夠仔細.

該段代碼是RSHASH算法的變形,要對輸入的字符串逐個作HASH運算,但while循環中條件寫錯,導致死循環.

unsigned int Hash(char *str)

{

unsigned int b = 378551;

unsigned int a = 63689;

unsigned int hash = 0;

    /*

 str need ++

 */

while (*str)

{

hash = hash * a + (*str);

a *= b;

}

return hash;

}

 

代碼四:

考察考生對多線程操作的理解,本題目的陷阱在於對一個多線程共享的全局變量做自加操作時,是否需要加鎖.

這個題目代碼較多,但結構很清晰,如果考生不能正確閱讀多線程調度的代碼,則不能準確定位到問題.

 

一個函數dobench用作併發調度,其中關鍵結構體如下:

 

typedef struct bench

{       

void* func;//業務函數

void* param;//業務參數

long n;//每個線程要執行的次數

long count;//併發計數器

long num;//併發的線程總數

pthread_cond_t cond;

pthread_mutex_t mutex;

}bench_t;

 

 

該函數的調用方式如下:

 

pthread_t tid;

for(i = 0; i < p->num; ++i)

{

/* 通過多線程併發執行 */

if (pthread_create(&tid,NULL,dobench,p) < 0) {

syslog(LOG_ERR, "Create thread failed. - %m\n");

}

syslog(LOG_NOTICE, "Created a thread.\n");

}

 

b的類型爲bench_t.

 

dobench的原型如下:

 

void dobench(void* param)

{

int i;

void(* func)(void* param);

struct bench * p = (struct bench *) param;

struct timeval tvStart,tvEnd;

func = p->func;

syslog(LOG_NOTICE, "Thread[%lld] dobench variables inited.\n",pthread_self());

//起始時間

gettimeofday(&tvStart,NULL);

if (p->n > 0) {

for (i=0; i < p->n; i++) {

func((void*)p->param);

}

}

else {

syslog(LOG_NOTICE, "struct bench * p->n should graet than 0\n");

}

//終止時間

gettimeofday(&tvEnd,NULL);

double dif;

dif = 1000000*(tvEnd.tv_sec-tvStart.tv_sec) + (tvEnd.tv_usec-tvStart.tv_usec);

syslog(LOG_NOTICE,"Thread[%lld] Cost => %f\n",pthread_self(),dif);

/*

 加鎖->計數器加一->條件變量觸發->解鎖

 每當一個線程迭代完成指定的任務時,都要通過條件變量通知主線程.

 */

//pthread_mutex_lock(&p->mutex);

p->count++;

pthread_cond_signal(&p->cond);

//pthread_mutex_unlock(&p->mutex);

return;

}

傳遞給dobench的參數param是個全局變量, param->num是要啓動工作的線程總數.

主線程通過param->count這個計數器來判斷當前已執行完的線程數,是否等於param->num,如果等於,則表示所有的線程已經工作完成,主線程可以退出.

請排查該原型代碼中的錯誤.

 

 

代碼五:

考察考生對正則表達式的理解和運用.

 

正則表達式:

郵件地址:name@domain,其中name和domain部分,只能出現大小寫字母,點(.)以及下劃線(_),

請寫出一個正則表達式能夠取出name部分和domain部分分組.

舉例:[email protected]

能夠取到zheng.cuizh以及gmail.com

如果地址中有非法字符,則不繼續匹配.

 

match中的參數是答案

 

>> mail="[email protected]"

=> "[email protected]"

 

>> mail.match(/^([a-zA-Z0-9\.\_]*)?\@([a-zA-Z0-9\.\_]*\.[a-zA-Z0-9\.\_]*)$/)

=> #<MatchData "[email protected]" 1:"zheng.cuizh" 2:"gmail.com">

>> mail.match(/^([a-zA-Z0-9\.\_]*)?@([a-zA-Z0-9\.\_]*\.[a-zA-Z0-9\.\_]*)$/)

=> #<MatchData "[email protected]" 1:"zheng.cuizh" 2:"gmail.com">

>> mail.match(/^([a-zA-Z0-9\.\_]*)@([a-zA-Z0-9\.\_]*\.[a-zA-Z0-9\.\_]*)$/)

=> #<MatchData "[email protected]" 1:"zheng.cuizh" 2:"gmail.com">

 

代碼六:

這段代碼考察考生在做字符串操作的時候是否考慮越界.

 

這段代碼是測試rpc_call方法在執行若干次後是否出錯的代碼,rpc_call這個函數需要在每次調用的時候使用一個唯一的id,這個id我們通過uuid方法獲得.但該段代碼存在一個錯誤,請找出.

 

int rpc_call(char *);

char* uuid();

 

int caller()

{

    char name[32];

    int i = 100;

 

    while(i--)

    {

        //sprintf(name,"%s",uuid);

        //or

        //memset(name,0,16);

        strcat(name,uuid());

syslog(LOG_ERR,"current name is => %s",name);

        rpc_call(name);

    }

 

}

 

 

 

代碼七:

下面這段代碼考察考生對位運算的理解.

 

long generate();

 

unsigned long l = generate();

 

下面這個運算起到什麼作用?

l<<1;

l>>1;

 

下面這個運算起到什麼作用?

l&=0xfffffffe

 

 

代碼八:

下面這個題目考察考生對異常處理底層實現的理解.

 

請使用setjmp.h中的方法實現C的異常處理.

 

#include <setjmp.h>

jmp_buf jb;

int ret = setjmp(jb);

switch(ret)

{

case 0:/*ok*/;break;

case 1:exc1_handler();break;

case 2:exc2_handler();break;

default:default_handler();

}

 

if(a==b){/*do ok*/}

else{/*raise exception*/longjmp(jb,1)}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章