`
CharlesCui
  • 浏览: 416384 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

笔试题目草稿-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部分分组.

举例:zheng.cuizh@gmail.com

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

如果地址中有非法字符,则不继续匹配.

 

match中的参数是答案

 

>> mail="zheng.cuizh@gmail.com"

=> "zheng.cuizh@gmail.com"

 

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

=> #<MatchData "zheng.cuizh@gmail.com" 1:"zheng.cuizh" 2:"gmail.com">

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

=> #<MatchData "zheng.cuizh@gmail.com" 1:"zheng.cuizh" 2:"gmail.com">

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

=> #<MatchData "zheng.cuizh@gmail.com" 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)}

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics