僵尸国度多久更新一集:各公司面试题

来源:百度文库 编辑:偶看新闻 时间:2024/05/06 08:58:26

吉林大学牡丹园站 -- 文章阅读 [讨论区: CCST]


发信人: liujiannan (天天), 信区: CCST 标 题: 找到工作给即将找工作的师弟妹发些经验,没找到工作 发信站: 吉林大学牡丹园站 (Thu Apr 16 10:56:44 2009) 我前段时间在北京找工作,因为找到了并且学校有点事我就回学校了,还有几个公司给 我面试通知,我有这些公司的地址和电话,他们也招人,有些笔试题我做过了可以说下, 如果有去那边找工作的,我可以给大家这几个公司的电话和地址,大家可以事先联系然后 过去,毕竟让我去的应该也认咱们吉大的牌子,有很多公司我都没过笔试这关,也有和清 华北大硕士一起技术面的时候。 因为大家都是一个学校的,事先声明:这些工作的工资也就2500-3500之间,一般就300 0左右,我是本科生,也是说本科的待遇。我想这些也是机会,我也不知道他们还是否继续 招人,其实也挺难的。 因为我现在在选要工作还是调剂的事情很茫然,一会有事要出去一下,顺便向大家说下 在北京找工作的小小经验,大家不要笑话 大家千万不要去那种国展的社会招聘什么的(至少没有工作经验的本科生计算机软件是这 样的,不会要你还要你10元的票钱,划不来的)要时刻关注北京高校的就业网和BBS 北京有些不太好的学校像北工什么的都不让看,大家主要关注清华北大北邮北航的还有北 交的就好,我个人认为 交大的招聘会很好,清华北大的就业网好些,而BBS当属北邮的最 好了,其次是清华的北科的,像北里就不要登录了,什么用也没有。 其实网投很有技巧的,大家一定要写一段然后粘一遍再附件一个,名称么就写应聘职位 学校名称 姓名 ,一定要加个简介,说优点,但不要写人人都写的动手能力强,适应能力 强,分析能力强啊,举个小例子代表能力,不超过两句话的,然后写上谢谢您的阅读,下 面是我的简历: 最后再加上什么感谢和你的保证之类的话 并且网投的最好是在高校就业网发布的信息,或者是BBS上发布的,觉得适合的,否则白 投,就算让你去面试也会被刷,我java不太好,有一次应聘java结果去面试好多没答上, 应聘还是写擅长的,一般让我面试的公司都是C或C++ c#什么的 ,一定要多看面试题,我 有好多面试题,看了好多还是觉得自己基础不好 我和大家说几个找工作,email发简历,或去招聘会和宣讲会信息的几个非常好的网站, 这些很多大家都不知道,他们包括了各大 高校就业网的信息(因为很多学校的就业信息 都给屏蔽了,包括咱们吉大)还有BBS上的一些信息,我觉得很不错,大家可以常登登,即 将找工作的师弟师妹也可以试试-- 这个包括很多大学就业网的信息,绝对好网站http://www.121job.cn/article/list.asp?classid=42 这个是很多学校就业网和BBS上的信息,可能有些已经不更新了,但是还是有很多好信息http://www.maiwo.net/source/html/s.html?q=%C7%E5%BB%AA%B4%F3%D1%A7 hail求职http://hiall.com.cn/hiall_home/ 毕业生招聘网http://www.byszp.com/ 高校就业网汇总http://010.58.com/lvyou/zhongdiangaoxiao.shtml it英才网http://www.cnithr.com/这个不怎么好 大家可以注册中华英才网的简历,每天猛投他三四百份,还是有回复的(我同学有在上面 投得到回复的) 有我网 简历截止期(这个找一些招聘会和宣讲很好,网罗好多高校)http://www.unus.cn/career/job-deadline/ 还有应届生bbs 过来人 等等,想大家找工作这些基本的网站都应该有我就不说了,上面几个网站确实很好 大家多登,每天还有各个高校BBS和就业网(当然还是目标地区,目标单位,有些 针对,像我投了深圳和武汉的公司,就算对我进行邮件笔试,电话面试等等,要求我 再过去面试时我还是去不了,但是我这个人给机会就抓住,让我笔试我就去) 我是研究生成绩出来后才找的工作,分了两次3月1号到14号一个阶段,4月1到10号第二阶 段这两次都在北京,4月4到7号北京的公司还放了至少三天的大假,上火啊。我是7号才收 到0ffer,可能是上周幸运,去了好几家都要我,我认为应聘还是有技巧的,但是基础最 重要,有的公司上来就是6到编码题,不要算法,要代码。(基础很重要,我也有些笔试题 ,一会发上来吧),最近很愁,工作和读软件双证没决定,工作的话去哪个公司也没决定 。 我不太记得笔过面过多少家,对了,去外地求职还有骗子呢,我差点被骗 了。。。。。。。。幸运啊 简历书写问题,绝对缩成一页纸,少些格格框框。觉得自己学校特别好就价格校徽标志 啥的,要不然就算了,还是不要加。向我们计算机专业的就多写项目经验,没有的话可以 更改啊,英文简历弄一份也好,但是水平不够就不要上写英文简历了,否则事倍功半。 至于正装问题,好像我的同学都有,大家努力下争取都有吧,买个二手的更是既便宜又 实惠,还能转出手。 另外打算找工作,现在就得努力学些了,多做下我下面发的面试笔试题,对提高水平有帮 助 发一些面试题,大家做下看看自己的水平 这些题大家可能看过了,有些应该没看过,做下很好,我也是在网上搜的这些是我搜集的 题,很多我在面试中也遇到了,给没有找到工作的同学们和即将工作的师弟师妹们看下吧 C++笔试题(一) 二、简单编程题。根据程序要求,写出函数的完整定义。(共25分) 1.(本小题15分)写一个函数,找出给定字符串中数字字符(即’0’—‘9’这10个数字 )的个数(如字符串”olympic2000”中数字字符的个数为4个。函数的原型为: int CalcDigital(char *str); 函数参数:str为所要处理的字符串。 函数返回值:所给字符串中数字字符的个数。 int CalcDigital(char *str) { //在下面写出程序的实现 } 1. 程序为: int CalcDigital(char *str) { //判断字符指针是否为空 if(str==NULL) return 0; //记录数字字符个数的变量 int num_of_digital=0; //依次检查各个字符,如果是数字,则总数加1 for(int i=0;str[ i ]!=0x0;i++) if(str[ i ]<=’9’&&str[ i ]>=’0’) num_of_digital++; //返回数字字符个数 return num_of_digital; } 2.(本小题10分)用递归函数完成以下运算: sum(n)=12+22+…+n2 函数的原型如下: long sum(int n); 该函数完成12+22+…+n2的运算,并返回运算结果,其中n>0。 提示:你可以使用递归表达式:sum(n)=sum(n-1)+n2 long sum(int n) { } 2. 程序为: long sum(int n) { if(n==1) return 1; else return n*n+sum(n-1); } 三、 (本小题30分) 下面的文件queue.h是一个队列类模板Queue的完整实现。在这个文件中首先定义了一个 队列元素类模板QueueItem,然后在这个类的基础上定义了队列类模板Queue。在Queue中使 用链表存放队列的各个元素,front指针指向链表的第一个节点元素,back指针指向链表的 最后一个节点元素,成员函数add()将一个新节点元素加入到队列结尾,remove()从队列开 头删除一个节点元素。为方便起见,程序中加上了行号。阅读程序,根据程序后面的问题 作出相应解答。 /*****************文件queue.h**************************************/ /******************************************************************/ 1 template 2 class Queue; 3 /**********定义模板类QueueItem*******************************/ 4 template 5 class QueueItem 6 { 7 public: 8 QueueItem(const Type &elem):item(elem){} 9 QueueItem(){} 10 private: 11 Type item; 12 QueueItem *nextItem; 13 friend class Queue; 14 }; 15 /***************定义模板类Queue*****************************/ 16 template 17 class Queue{ 18 public: 19 Queue():front(NULL),_______(A)_______{} 20 ~Queue(); 21 Type remove(); 22 void add(const Type &); 23 bool is_empty()const {return ____(B)____;} 24 private: 25 QueueItem *front; 26 QueueItem *back; 27 }; 28 //模板类Queue的函数成员remove()的实现 29 //从队列头取出一个节点,并返回该节点的值 30 template 31 Type Queue::remove() 32 { 33 QueueItem *pFront; //指向头节点的临时指针 34 Type retVal; //返回值 35 ____(C)____; 36 retVal=front->item; 37 front=front->nextItem; 38 delete pFront; 39 return retVal; 40 } 41 //模板类Queue的函数成员add()的实现 42 template 43 void Queue::add(const Type& newItem) 44 { 45 QueueItem *pNew=new QueueItem; 46 pNew->item=newItem; 47 ____(D)____; 48 if(front==NULL) 49 front=back=pNew; 50 else 51 { 52 back->nextItem=pNew; 53 ____(E)____; 54 } 55 } 56 57 template 58 Queue::~Queue() 59 { 60 QueueItem *p=front, *q; 61 while(p!=NULL) 62 { 63 q=p->nextItem; 64 delete p; 65 p=q; 66 } 67 } 问题1:(每个填空3分,共15分)程序中有几处填空,将它们完成。 (A)______________________________________________ (B)______________________________________________ (C)______________________________________________ (D)______________________________________________ (E)______________________________________________ 问题2:(本小题3分)题中程序第1、2行为什么要说明一下类模板Queue?如果没有这两行 语句,程序还正确吗? 答: 问题3:(本小题4分)程序第22、23行各有一个const,它们各自表示什么含义? 答: 问题4:(本小题3分)程序中模板类Queue的析构函数主要做了什么事情?为什么要这么做 ? 答: 问题5:(本小题5分,每答对一个给1分)下面的程序使用了queue.h文件中定义的类模板 ,说明程序中哪些定义队列对象的语句是不正确的,哪些是正确的? #include “queue.h” void main() { Queue q1; //1 Queue q2; //2 Queue q3(100); //3 Queue q4[100]; //4 Queue q5=new Queue; //5 //… delete q5; } 答: 语句号 1 2 3 4 5 对/错 答案: 问题1:答案为: (A)back(NULL) (B)front == NULL 或 back == NULL (C)pFront = front (D)pNew->nextItem = NULL (E)back = pNew 问题2: 答:不正确。因为在类QueueItem模板类的定义中用到了模板类Queue,而此 时Queue还没有定义,所以要先声明一下,告诉编译程序Queue是一个模板类 ,它将在程序的其他地方定义。如果没有这个说明,编译程序就不知道标识 符Queue代表什么样的含义了。 问题3: 答:第22行的const修饰的是函数的参数,表示在这个函数体中不能改它所修 饰的参数所对应的实际参数的值。 第23行的const修饰的是模板类Queue的成员函数is_empty(),它表示在函数i s_empty()的函数体中不能改变任何数据成员的值。 问题4: 答:析构函数中主要是释放链表中存放的各个节点的空间。因为Queue对象在 其生存期间可能加入了很多节点,从堆中申请了一些内存空间,这些空间应 该随着对象的消亡而释放掉,所以需要在析构函数中来释放这些空间。 问题5: 语句号 1 2 3 4 5 对/错 错 对 错 对 对 四、 (本小题16分)阅读下面的程序,写出程序运行的结果。 /*************************************************************/ #include class A{ private: //…其它成员 public: virtual void func(int data){cout<<”class A:”<func(1); pA->func(“haha”); return 0; } /*******************************************************************/ 问题1:(本小题4分)在下面写出程序的运行结果: 问题2:(本小题2分)如下句所示,在函数main()中通过pA调用类B中定义的参数表为空的 函数func() : pA->func(); 是否正确? 答:(正确/不正确) 问题3:(本小题10分)如果要记录已尼创建的A类的实例(对象)的个数,我们可以借助 于类的静态成员。修改上面类A的定义,使得它包含一个私有的静态成员object_count,记 录属于该类的对象的个数,然后为类A增加必要的成员函数,使得下面的程序: void main() { A *pA=new A[3]; cout<<”There are ”<GetObjectCount()<<” objects”<>(istream &is, SmallInt &si); //重载算术运算符 SmallInt operator+(const SmallInt &si){return SmallInt(val+si.val);} SmallInt operator-(const SmallInt &si){return SmallInt(val-si.val);} SmallInt operator*(const SmallInt &si){return SmallInt(val*si.val);} SmallInt operator/(const SmallInt &si){return SmallInt(val/si.val);} //重载比较运算符 bool operator==(const SmallInt &si){return (val==si.val);} private: char val; }; SmallInt::SmallInt(int i) { while(i>127) i-=256; while(i<-128) i+=256; val=i; } ostream &operator<<(ostream &os,const SmallInt &si) { os<<(int)si.val; return os; } istream &operator>>(istream &is,SmallInt &si) { int tmp; is>>tmp; si=SmallInt(tmp); return is; } 问题1:(本小题4分)上面的类定义中,重载的插入运算符和抽取运算符被定义为类的友 元函数,能不能将这两个运算符定义为类的成员函数?如果能,写出函数原型,如果不能 ,说明理由。 答: 问题2:(本小题5分)为类SmallInt增加一个重载的运算符’+=’,函数原型: class SmallInt{ public: SmallInt &operator +=(const SmallInt &si); //其它函数…… private: char val; }; 该函数将返回对当前对象的引用。如: SmallInt si1(20),si2(13); 则表达式: si1+=si2 将返回对象si1的引用,并且si1中的的值是si1.val和si2.val的值之和(但必须正规化为 在-128至127之间)。 在下面写出重载的运算符+=的实现: 答案: 问题1: 答:不能将插入运算符和抽取运算符定义为类的成员函数。 因为这两个运算符对第一个运算数有特殊的要求,即必须分别是ostream和istream类的对 象,而不能是用户自己定义的其它类,而类的成员函数默认的第一个参数为指向该类对象 的指针类型,所以不符合插入和抽取运算符的要求。 问题2: 重载的运算符的实现如下: SmallInt &SmallInt::operator+=(const SmallInt &si) { SmallInt tmp(val+si.val); val=tmp.val; return *this; } 或 SmallInt &SmallInt::operator+=(const SmallInt &si) { val+=si.val; if(val>127) val-=256; if(val<-128 val=256; return *this; } C++笔试题(二) 1、请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句 2、如何输出源文件的标题和目前执行行的行数 3、两个数相乘,小数点后位数没有限制,请写一个高精度算法 4、写一个病毒 5、有A、B、C、D四个人,要在夜里过一座桥。他们通过这座桥分别需要耗时1、2、5、10 分钟,只有一支手电,并且同时最多只能两个人一起过桥。请问,如何安排,能够在17分 钟内这四个人都过桥? 2005年腾讯招聘 选择题(60) c/c++ os linux 方面的基础知识 c的Sizeof函数有好几个! 程序填空(40) 1.(20) 4空x5 不使用额外空间,将 A,B两链表的元素交叉归并 2.(20) 4空x5 MFC 将树序列化 转存在数组或 链表中! 1.请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句 // 这样转向定义应该不算违规吧!^_^ #include "stdafx.h" #include #include using namespace std; #define Cmp(x,y) compare(x,y) int compare(int a,int b) { a^=(1<<31); b^=(1<<31); int i=31; while((i^-1) && !((a&(1<>i)&1)?1:-1):0; } int _tmain() { int c; c = Cmp(5,4); cout<0:a>b 2.如何输出源文件的标题和目前执行行的行数 cout << "Filename " << __FILE__ << " Line " << __LINE__ << endl; 3.两个数相乘,小数点后位数没有限制,请写一个高精度算法 算法提示: 输入 string a, string b; 计算string c=a*b; 返回 c; 1, 纪录小数点在a,b中的位置l1,l2, 则需要小数点后移动位置数为l=length(a)+len gth(b)-l1-l2-2; 2, 去掉a,b中的小数点,(a,b小数点后移,使a,b变为整数) 3, 计算c=a*b; (同整数的大数相乘算法) 4, 输出c,(注意在输出倒数第l个数时,输出一个小数点。若是输出的数少于l个,就 补0) du51(郁郁思扬)的答案: 变为整数求就行了.输入的时候记一下,小数点位置..输出再做点文章就行了. 下面的是大整数的运算. #include using namespace std; #define MAX 10000 struct Node{ int data; Node *next; }; void output(Node *head) { if(!head->next&&!head->data)return; output(head->next); cout<data; } void Mul(char *a,char *b,int pos) { char *ap=a,*bp=b; Node *head=0; head=new Node;head->data=0,head->next=0; //头 Node *p,*q=head,*p1; int temp=0,temp1,bbit; while(*bp) //若乘数不为空 ,继续. { p=q->next;p1=q; bbit=*bp-48; //把当前位转为整型 while(*ap||temp) //若被乘数不空,继续 { if(!p) //若要操作的结点为空,申请之 { p=new Node; p->data=0; p->next=0; p1->next=p; } if(*ap==0)temp1=temp; else { temp1=(p1->data)+(*ap-48)*bbit+temp;ap++; } p1->data=temp1%10; //留当前位 temp=temp1/10; //进位以int的形式留下. p1=p;p=p->next; //被乘数到下一位 } ap=a;bp++;q=q->next; //q进下一位 } p=head; output(p); //显示 cout<next; delete head; head=p; } } int main() { cout<<"请输入两个数"< using namespace std; #define MAX 10000 struct Node{ int data; Node *next; }; void output(Node *head,int pos) { if(!head->next&&!head->data)return; output(head->next,pos-1); cout<data; if(!pos)cout<<"."; } void Mul(char *a,char *b,int pos) { char *ap=a,*bp=b; Node *head=0; head=new Node;head->data=0,head->next=0; //头 Node *p,*q=head,*p1; int temp=0,temp1,bbit; while(*bp) //若乘数不为空 ,继续. { p=q->next;p1=q; bbit=*bp-48; //把当前位转为整型 while(*ap||temp) //若被乘数不空,继续 { if(!p) //若要操作的结点为空,申请之 { p=new Node; p->data=0; p->next=0; p1->next=p; } if(*ap==0)temp1=temp; else { temp1=(p1->data)+(*ap-48)*bbit+temp;ap++; } p1->data=temp1%10; //留当前位 temp=temp1/10; //进位以int的形式留下. p1=p;p=p->next; //被乘数到下一位 } ap=a;bp++;q=q->next; //q进下一位 } p=head; output(p,pos); //显示 cout<next; delete head; head=p; } } int main() { cout<<"请输入两个数"< #include #define Max 100000000 int a[Max+10]; int cmp(const void *a, const void *b) { int *x = (int *) a; int *y = (int *) b; return *x-*y; } int main() { int n=0; while(scanf("%d",&a[n])==1) n++; qsort(a,n,4,cmp); for(int i=0;i<3;i++) printf("%d",a[ i ]); return 1; } 5、有A、B、C、D四个人,要在夜里过一座桥。他们通过这座桥分别需要耗时1、2、5、10 分钟,只有一支手电,并且同时最多只能两个人一起过桥。请问,如何安排,能够在17分 钟内这四个人都过桥? Solution:关键是时间最长的两个人必须同时过桥 The First Time: A(1)和B(2)过桥,A(1)返回 Cost:1+2 The Second Time: C(5)和D(10)过桥,B(2)返回 Cost:10+2 The Third Time A(1)和B(2)过桥 Cost:2 Total Time Cost: (1+2)+(10+2)+2=17 minutes 转载整理出自:http://lhxxy.spaces.live.com/PersonalSpace.aspx?_c11_BlogPart_n=1&_c11_BlogPar t_handle=cns!1C2BAD78035C0FC0!125&_c11_BlogPart_FullView=1&_c=BlogParthttp://topic.csdn.net/t/20050620/22/4095256.htmlhttp://www.bczs.net/xml/2006/3/30/4651575.xml C++笔试题(三) 普天是南京一家通信公司,全称为:南京普天通信股份有限公司,公司网址为:http://w ww.postel.com.cn 网上流传一套普天C++笔试题,我将我做的答案公布与此,仅供参考。 1.实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数; 答: //假设线性表的双向链表存储结构 typedef struct DulNode{ struct DulNode *prior; //前驱指针 ElemType data; //数据 struct DulNode *next; //后继指针 }DulNode,*DuLinkList; //删除操作 Status ListDelete_DuL(DuLinkList &L,int i,ElemType &e) { if(!(p=GetElemP_DuL(L,i))) //此处得到i位置的节点指针,如果有需要也得写出具体 函数实现 return ERROR; e=p->data; p->prior->next=p->next; p->next->prior=p->pror; free(p); return OK; } //插入操作 Status ListInsert_DuL(DuLinkList &L,int i,ElemType &e) { if(!(p=GetElemP_DuL(L,i))) return ERROR; if(!(s=(DuLinkList)malloc(sizeof(DuLNode)))) return ERROR; s->data=e; s->prior=p->prior; p->prior->next=s; s->next=p; p->prior=s; return OK; } 2.写一个函数,将其中的\t都转换成4个空格。 答: 该函数命名为convert,参数的意义为: *strDest目的字符串,*strSrc源字符串,length源字符串的长度 函数实现为: char* convert(char *strDest, const char *strSrc,int length) { char * cp = strDest; int i=0; while(*strSrc && inext; while (p->next!=link) // 链表结尾 { if (p->key==key) // 查找到key值相同,删除该节点,并返回 { p->prev->next=p->next; p->next->prev=p->prev; free(p); return link; } else p=p->next; // 否则查找下一节点 } if (p->next == link) return NULL; //没找到,返回NULL } 2、请用程序打印下列图型 * * * * * * * * * * * * * * * void printTriangle(const unsigned char line); 输入行数,打印三角形。 答: 函数为 void printTriangle(const unsigned char line) { for(int i=1;i<=line;i++) { for(int j=0;j<(line*2-1);j++) // 5行每行需打印9个字符 { if (i%2==1) // 奇数行 { if (j%2==(line-1)%2 && j>=(line-1-i/2*2) && j<=(line-1+i/2*2)) printf("*");// 列从0计数 else printf(" "); } else if (j%2==(line)%2 && j>=(line-2-(i/2-1)*2) && j<=(line+(i/2-1)*2)) printf("*"); else printf(" "); } printf("\n"); } } 3、请用标准C语言实现下列标准库函数,设计中不得使用其他库函数。 char *strstr(char *str1,char *str2); 在字符串str1中,寻找字串str2,若找到返回找到的位置,否则返回NULL。 答: 函数为 char * strstr ( const char * str1, const char * str2 ) { char *cp = (char *) str1; char *s1, *s2; if ( !*str2 ) return((char *)str1); while (*cp) { s1 = cp; s2 = (char *) str2; while ( *s1 && *s2 && !(*s1-*s2) ) s1++, s2++; if (!*s2) return(cp); cp++; } return(NULL); } 4、请问这段代码循环多少次? main() { char i=0; while(i<10) { if(i<1)continue; if(i==5)break; i++; } ...... } 答:是个死循环,无限次啊,无限次。 --------------------------------------- ------- 哈哈,插播广告啦:版权所有:朱科 欢迎光临我的网站:www.goodsoft.cn,各位转贴别 删,劳动成果啊 --------------------------------------- ------- 5、用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题) 答: #define MIN (365*24*60*60) 6、请问运行main函数会有什么样的结果? main() { int x=10,y=3; printf("%d\n",y=x/y); } 答:结果为3,考察强制类型转换 7、有以下程序 #define P 3 int F(int x) { return(P*x*x); } main() { printf("%d\n",F(3+5)); } 程序运行结果为:? 答:程序运行后的输出结果是192,此题为故意混淆概念,直接用F(8)计算得答案,而非计 算3*3+5*3+5; 8、若int占2个字节,char占1个字节,float占4个字节,则定义如下: struct stu { union{ char bj[5]; int bh[2]; }class; char xm[8]; float cj; }xc; 则sizeof(xc)的值为? 答:20,一道边界对齐的题目,很多地方有讲,此处注意下联合的内存大小取决于其中字 节数最多的成员就可。 9、请问traceroute的工作原理 答: 主机先发出一个TTL(Time To Live,生存时间)为1的ICMP数据包。这个数据包到达一个 路由器后,路由器将TTL减1到0,并将并送回一个「ICMP time exceeded」消息,以说明这 个数据包不能继续向前传送,因为其TTL已经过期了。traceroute 收到这个消息后,便知 道这个路由器存在于这个路径上,接着traceroute 再送出另一个TTL是2 的数据包,发现 第2 个路由器......这个重复的动作一直持续到某个datagram 抵达目的地。 C++笔试题(六) 摩托罗拉号称百强企业,通讯行业领导者,下面是它2006年招聘出的软件类笔试题和我做 的解答,供参考。 摩托罗拉(中国)网址:http://www.motorola.com.cn 1.打印如下图案,共19行,只能有一个for循环(题目已经提供) *  ***  *****  *******  *********  *********** *************  ***************   *****************  ******************* *****************  ***************  *************  ***********  *********  *******  *****  ***  *  for(i=0;i<19;i++) { } 答: #include int main() { int maxsize = 19; char ch = * ; char *tmp=new char[3]; char *format = new char[30]; char *stars = new char[30]; strcpy(stars,""); for(int i=0;i0) //前10行每次较前一行多**,输出位置比前一行减1 { strcat(stars,"**"); strcat(format,stars); } printf(format,ch); printf("\n"); } else { // 后9行每次较前一行少**,输出位置比前一行加1 stars[maxsize-1-(2*(i+1)-maxsize-1)]=0; int k=(2*(i+2)-maxsize-1)/2; itoa(k,tmp,10); strcpy(format,"%"); strcat(format,tmp); strcat(format,"c"); strcat(format,stars); printf(format,ch); printf("\n"); } } delete []tmp; delete []format; delete []stars; tmp=NULL; format=NULL; stars=NULL; return 0; } 2. void fun(int x) { if(x/2>0)fun(x/2); printf("%d",x); } 求fun(10)的输出结果 答:依次输出fun(1),fun(2),fun(5),fun(10),得到结果12510 3. #define f1(n) (n)*(n) int i=5; int k=0; k=f1(i++); printf("%d %d",i,k); 输出结果: 答:7 25 4.下面那个for循环是无限循环 for(int i=010;i==10;i+=0) for(int i=10;(i++^--i)==0;i+=0) 还有几个忘了 答: 第一不是,因为010表示8进制,i=8; 第二是,因为i++^--i表示数字9与9进行异或运算,确实为0 --------------------------------------- ------- 嗯,插播广告啦:版权所有:朱科 欢迎光临我的网站:www.goodsoft.cn,各位转贴别删 ,劳动成果啊 --------------------------------------- ------- 5.Email relay 和Email access分别用了什么协议?(其他还有很多,略) 答:SMTP,POP3 6.stack data (栈)存在于 A.rom, B .flash C .eeprom D.ram E .none of the above 答:D.ram。这题稍微涉及到一点硬件知识,ROM的全称是Read Only Memory,即只读存储 器,flash ,eeprom都是ROM家族的一员,RAM是Random Access Memory的简称,意为随机 存取存储器,也就是内存了。不管是堆还是栈都是放在内存里的。 7. int i; int x=0x12345678; unsigned char *p=(unsigned char *)&x; for(i=0;i #include class CBuffer { char * m_pBuffer; int m_size; public: CBuffer() { m_pBuffer=NULL; } ~CBuffer() { Free(); } void Allocte(int size) (3) { m_size=size; m_pBuffer= new char[size]; } private: void Free() { if(m_pBuffer!=NULL) { delete m_pBuffer; m_pBuffer=NULL; } } public: void SaveString(const char* pText) const { strcpy(m_pBuffer, pText); } char* GetBuffer() const { return m_pBuffer; } }; void main (int argc, char* argv[]) { CBuffer buffer1; buffer1.SaveString("Microsoft"); printf(buffer1.GetBuffer()); } 答:改正后 主要改正SaveString函数 将 void SaveString(const char* pText) const { strcpy(m_pBuffer, pText); } 改为 void SaveString(const char* pText) (1) { if(m_pBuffer!=NULL) Free(); Allocte(strlen(pText)+1); (2) strcpy(m_pBuffer, pText); } 原因: (1) const成员函数表示不会修改数据成员,而SaveString做不到,去掉const声明 (2) m_pBuffer指向NULL,必须用Allocte分配空间才能赋值。 (3) 另外需要将Allocte成员函数声明为私有成员函数更符合实际 2.下来程序想打印“Welcome MSR Asia”,改正错误 #include #include char * GetName (void) { //To return “MSR Asia” String char name[]="MSR Asia"; return name; } void main(int argc, char* argv[]) { char name[32]; //Fill in zeros into name for(int i=0;i<=32;i++) { name[ i ]= \0 ; } //copy “Welcome” to name name="Welcome"; //Append a blank char name[8]=" "; //Append string to name strcat(name,GetName()); //print out printf(name); } 答:改正后为 #include #include #include //malloc函数的头文件 char * GetName (void) { //To return “MSR Asia” String //char name[]="MSR Asia"; char *name=(char *)malloc(strlen("MSR Asia")+1); //在函数内部定义的变量在 函数结束时就清空了,必须动态分配内存 strcpy(name,"MSR Asia"); return name; } void main(int argc, char* argv[]) { char name[32]; //Fill in zeros into name // for(int i=0;i<=32;i++) for(int i=0;i<=31;i++) //数组越界 { name[ i ]= \0 ; } //copy “Welcome” to name //name="Welcome"; strcat(name,"Welcome");//字符串赋值语句错误,应该用strcat //Append a blank char // name[8]=" "; strcat(name, " "); //或者 name[8]= ;name[9]= \0 ; //Append string to name char *p=GetName(); //定义一个指针指向动态分配的内存,用完后需用free语 句释放 strcat(name,p); free (p); //print out printf(name); } --------------------------------------- ------- 插播广告咯:版权所有:朱科 欢迎光临我的网站:www.goodsoft.cn,各位转贴别删,宣 传下嘛 --------------------------------------- ------- 3.写出下面程序的输出结果 #include class A { public: void FuncA() { printf("FuncA called\n"); } virtual void FuncB() { printf("FuncB called\n"); } }; class B: public A { public: void FuncA() { A::FuncA(); printf("FuncAB called\n"); } virtual void FuncB() { printf("FuncBB called\n"); } }; void main(void) { B b; A *pa; pa=&b; A *pa2=new A; b.FuncA(); (1) b.FuncB(); (2) pa->FuncA(); (3) pa->FuncB(); (4) pa2->FuncA(); (5) pa2->FuncB(); delete pa2; } 答: 1.b.FuncA(); 输出 FuncA called FuncAB called 2.b.FuncB();输出 FuncBB called 上两者好理解,直接调用类B的相应成员函数 3.pa->FuncA();输出 FuncA called 调用类A的FuncA() 4.pa->FuncB();输出 FuncBB called调用类B的FuncB(),原因是C++的动态决议机制,当基类函数声明为virtua l时,指向派生类对象的基类指针来调用该函数会选择派生类的实现,除非派生类没有才调 用基类的虚函数。还有一点注意的是:指向基类类型的指针可以指向基类对象也可以指向 派生类对象,如pa=&b; 5. pa2->FuncA(); pa2->FuncB();输出 FuncA called FuncB called 这也好理解,直接调用类A的相应成员函数 4.In the main() function, after ModifyString(text) is called, what’s the val ue of ‘text’? #include #include int FindSubString(char* pch) { int count=0; char* p1=pch; while(*p1!= \0 ) { if(*p1==p1[1]-1) { p1++; count++; } else { break; } } int count2=count; while(*p1!= \0 ) { if(*p1==p1[1]+1) { p1++; count2--; } else { break; } } if(count2==0) return count; return 0; } void ModifyString(char* pText) { char* p1=pText; char* p2=p1; while(*p1!= \0 ) { int count=FindSubString(p1); if(count>0) { *p2++=*p1; sprintf(p2, "%I", count); while(*p2!= \0 ) { p2++; } p1+=count+count+1; } else { *p2++=*p1++; } } } void main(void) { char text[32]="XYBCDCBABABA"; ModifyString(text); printf(text); } 答:XYBCDCBAIBAA FindSubString返回连续出现字母增加又递减的个数,且增加个数刚好等于递减个数。如A BA返回1,ABAB返回1,ABCBA返回2,BCBA返回0。 sprintf(p2, "%I", count);将*p2= I ,*(p2+1)= \0 。 (转载者注:对原文有部分修改) C++笔试题(八)   索尼公司在视听产品,游戏产品,通讯产品,信息产品方面都做的很不错,相信大家 都或多或少用过它的东西,“抵制日货”,呵呵,说到这个那我就不加评论了,还是直接 来看SONY的笔试题目吧,题后是我做的解答。 1.完成下列程序 * *.*. *..*..*.. *...*...*...*... *....*....*....*....*.... *.....*.....*.....*.....*.....*..... *......*......*......*......*......*......*...... *.......*.......*.......*.......*.......*.......*.......*....... #include #define N 8 int main() { int i; int j; int k; --------------------------------------------------------- │ │ │ │ │ │ --------------------------------------------------------- return 0; } 答: #define N 8 int main() { int i; int j; int k; for(i=0;i void sort( ); int main() { int array[]={45,56,76,234,1,34,23,2,3}; //数字任意给出 sort( ); return 0; } void sort( ) { --------------------------------------------------------- │ │ │ │ │ │ --------------------------------------------------------- } 答:使用选择排序法,我为sort函数多加了两个形参,至少第一个是必须的,否则无法传 入待排序数组。不知道这样做是否符合题意。 void sort(int *array,int num) { int temp; for(int i=0;i int Pheponatch(int); int main() { printf("The 10th is %d",Pheponatch(10)); return 0; } int Pheponatch(int N) { -------------------------------- │ │ │ │ -------------------------------- } 答: 使用递归,理由是递归编程简单,代码容易理解,但缺点是效率不高,而且有深度限制,如果 深度太深,则堆栈会溢出。 int Pheponatch(int N) { if (N==2||N==1) return 1; else return Pheponatch(N-1)+Pheponatch(N-2); } 4.下列程序运行时会崩溃,请找出错误并改正,并且说明原因。 #include #include typedef struct TNode { TNode* left; TNode* right; int value; }TNode; TNode* root=NULL; void append(int N); int main() { append(63); append(45); append(32); append(77); append(96); append(21); append(17); // Again, 数字任意给出 return 0; } void append(int N) { TNode* NewNode=(TNode *)malloc(sizeof(TNode)); NewNode->value=N; if(root==NULL) { root=NewNode; return; } else { TNode* temp; temp=root; while((N>=temp->value && temp->left!=NULL)||(Nvalue && temp->right! =NULL)) { while(N>=temp->value && temp->left!=NULL) temp=temp->left; while(Nvalue && temp->right!=NULL) temp=temp->right; } if(N>=temp->value) temp->left=NewNode; else temp->right=NewNode; return; } } 答: void append(int N) { TNode* NewNode=(TNode *)malloc(sizeof(TNode)); NewNode->value=N; NewNode->left=NULL; NewNode->right=NULL; if(root==NULL) { root=NewNode; return; } else { TNode* temp; temp=root; //while((N>=temp->value && temp->left!=NULL)||(Nvalue && temp->righ t!=NULL)) //易引起死循环,去掉 //{ while(N>=temp->value && temp->left!=NULL) temp=temp->left; while(Nvalue && temp->right!=NULL) temp=temp->right; //} if(N>=temp->value) { if(temp->left!=NULL) temp->left->right=NewNode; else root=NewNode; NewNode->left=temp->left; NewNode->right=temp; temp->left=NewNode; } else { if(temp->right!=NULL) temp->right->left=NewNode; NewNode->right=temp->right; NewNode->left=temp; temp->right=NewNode; } return; } } (转载者注:对原文有部分修改) C++笔试题(九) 加拿大著名电信设备制造商北电网络公司始建于一个世纪以前,在通讯发展进步历程中始 终处于领袖地位,广东北电通信设备有限公司成立于1995年3月,是北电在华投资的核心公 司之一。公司网址是http://www.gdnt.com.cn/   下面是广东北电的笔试题(中英文题),这套题早已在网络上流传数年,从来只见题 目,不见解答,那就让我做做吧。英文搞得不对的地方那就没办法了。希望大家转贴的时 候声明出处。 一:英文题。 1. Tranlation (Mandatory)   CDMA venders have worked hard to give CDMA roaming capabilities via the de velopment of RUIM-essentially, a SIM card for CDMA handsets currently being de ployed in China for new CDMA operator China Unicom. Korean cellco KTF demonstr ated earlier this year the ability to roam between GSM and CDMA using such car ds.However,only the card containing the user’s service data can roam-not the CDMA handset or the user’s number (except via call forwarding). 翻译:CDMA开发商一直致力通过RUIM卡的开发,使CDMA具有漫游的能力。RUIM卡是一种CD MA手机使用的SIM卡,目前它在中国已经由新的CDMA运营商中国联通部署使用。韩国手机制 造企业KTF今年早些时候展示了通过使用此种卡可以在GSM和CDMA网络之间进行漫游的功能 ,但是,只有包含用户服务数据的卡能够漫游,而不是CDMA手机本身或者用户号码(除非 通过呼叫前转业务)。 呵呵。上文可能翻译的不太精准,欢迎批评。   2. Programming (Mandatory)   Linked list   a. Implement a linked list for integers,which supports the insertafter (in sert a node after a specified node) and removeafter (remove the node after a s pecified node) methods;   b. Implement a method to sort the linked list to descending order. 答:题目的意思是实现一个整型链表,支持插入,删除操作(有特殊要求,都是在指定节 点后进行操作),并写一个对链表数据进行降序排序的方法。 那我们不妨以一个线性链表进行编程。 // 单链表结构体为 typedef struct LNode { int data; struct LNode *next; }LNode, *pLinkList; // 单链表类 class LinkList { private: pLinkList m_pList; int m_listLength; public: LinkList(); ~LinkList(); bool InsertAfter(int afternode, int data);//插入 bool RemoveAfter(int removenode);//删除 void sort();//排序 }; 实现方法 //insert a node after a specified node, insert as the head node when afternode ==0 bool LinkList::InsertAfter(int afternode, int data) { LNode *pTemp = m_pList; if (afternode > m_listLength || afternode<0) // 插入点超过总长度 { return false; } for(int i=0;inext; } if (pTemp==NULL && m_pList!=NULL) // 节点未寻到,错误退出 { return false; } LNode *newNode = new LNode; // 将新节点插入指定节点后 newNode->data = data; if(afternode==0) { newNode->next = pTemp; m_pList = newNode; } else { newNode->next = pTemp->next; pTemp->next = newNode; } m_listLength++; return true; } //remove the node after a specified node, remove the head node when removenode ==0 bool LinkList::RemoveAfter(int removenode) { LNode *pTemp = m_pList; if (removenode >= m_listLength || removenode<0) // 删除点超过总长度 { return false; } // 找到指定的节点 for(int i=0;inext != NULL;i++) { pTemp = pTemp->next; } if(pTemp->next==NULL && removenode!=0)//最后一个节点,后面没有节点可以删除 return false; if(removenode==0) { m_pList=pTemp->next; delete pTemp; } else { LNode *pDel = pTemp->next; pTemp->next=pDel->next; delete pDel; } m_listLength--; return true; } //sort the linked list to descending order. void LinkList::sort() { if (m_listLength<=1) { return; } LNode *pList2 = m_pList;//新建一个链表 m_pList=m_pList->next; pList2->next=NULL; for(int i=0;idata data) //插入到新链表变成头节点 { pPre=m_pList; m_pList=m_pList->next; pPre->next=pTemp; pList2=pPre; } else { while(pTemp!=NULL && pTemp->data > m_pList->data )//寻找插入位置 { pPre=pTemp; pTemp=pTemp->next; } pTemp=m_pList; m_pList=m_pList->next; pTemp->next=pPre->next; pPre->next=pTemp; } } m_pList=pList2; }   前两个函数实现了要求a,后一个函数sort()实现了要求b 3. Debugging (Mandatory) a. For each of the following recursive methods, enter Y in the answer box if t he method terminaters (assume i=5), Otherwise enter N. (题目意思:判断下面的递归函数是否可以结束) static int f(int i){ return f(i-1)*f(i-1); } Ansewr: N,明显没有返回条件语句,无限递归了 static int f(int i){ if(i==0){return 1;} else {return f(i-1)*f(i-1);} }   Ansewr:Y,当i=0时可结束递归 static int f(int i){ if(i==0){return 1;} else {return f(i-1)*f(i-2);} } Ansewr:N,因为i=1时,f(i-2)=f(-1),进入一个无限递归中 b. There are two errors in the following JAVA program: static void g(int i){ if(i==1){return;} if(i%2==0){g(i/2);return;} else {g(3*i);return;} } please correct them to make sure we can get the printed-out result as below: 3 10 5 16 8 4 2 1 答:在第一个if语句前加 System.out.print(i+" ");   else 里面的g(3*i)改为g(3*i+1) 该题由网友alvin补上,我不熟java。谢谢他。   --------------------------------------- ------- 又到广告时间:版权所有:朱科 欢迎光临我的网站:www.goodsoft.cn,各位转贴别删, 劳动成果啊 --------------------------------------- ------- 中文笔试题 1.汉译英   北电网络的开发者计划使来自于不同组织的开发者,能够在北电网络的平台上开发圆 满的补充业务。北电网络符合工业标准的开放接口,为补充业务的开展引入了无数商机, 开发者计划为不同层面的开发者提供不同等级的资格,资格的划分还考虑到以下因素:补 充业务与北电网络平台的集合程度,开发者团体与北电网络的合作关系,等等。 答:呵呵。这个这个基本上还是不现丑了吧。 2.编程   将整数转换成字符串:void itoa(int,char); 例如itoa(-123,s[])则s=“-123”; 答: char* itoa(int value, char* string) { char tmp[33]; char* tp = tmp; int i; unsigned v; char* sp; // 将值转为正值 if (value < 0) v = -value; else v = (unsigned)value; // 将数转换为字符放在数组tmp中 while (v) { i = v % 10; v = v / 10; *tp++ = i+ 0 ; } // 将tmp里的字符填入string指针里,并加上负号(如果有) sp = string; if (value < 0) *sp++ = - ; while (tp > tmp) *sp++ = *--tp; *sp = 0; return string; } (转载者注:对原文有部分修改) 1. 找错 void test1() { char string[10]; char* str1="0123456789"; strcpy(string, str1); } 答:表面上并且编译都不会错误。但如果string数组原意表示的是字符串的话,那这个赋 值就没有达到意图。最好定义为char string[11],这样最后一个元素可以存储字符串结尾 符 \0 ; void test2() { char string[10], str1[10]; for(int I=0; I<10;I++) { str1[I] = a ; } strcpy(string, str1); } 答:strcpy使用错误,strcpy只有遇到字符串末尾的 \0 才会结束,而str1并没有结尾标 志,导致strcpy函数越界访问,不妨让str1[9]= \0 ,这样就正常了。 void test3(char* str1) { char string[10]; if(strlen(str1)<=10) { strcpy(string, str1); } } 答:这又会出现第一道改错题的错误了。strlen(str1)算出来的值是不包含结尾符 \0 的 ,如果str1刚好为10个字符+1结尾符,string就得不到结尾符了。可将strlen(str1)<=1 0改为strlen(str1)<10。 2. 找错 #define MAX_SRM 256 DSN get_SRM_no() { static int SRM_no; int I; for(I=0;I=MAX_SRM) return (NULL_SRM); else return SRM_no; } 答:我不知道这段代码的具体功能,但明显有两个错误 1,SRM_no没有赋初值 2,由于static的声明,使该函数成为不可重入(即不可预测结果)函数,因为SRM_no变量 放在程序的全局存储区中,每次调用的时候还可以保持原来的赋值。这里应该去掉static 声明。 3. 写出程序运行结果 int sum(int a) { auto int c=0; static int b=3; c+=1; b+=2; return(a+b+c); } void main() { int I; int a=2; for(I=0;I<5;I++) { printf("%d,", sum(a)); } } 答:8,10,12,14,16 该题比较简单。只要注意b声明为static静态全局变量,其值在下次调用时是可以保持住原 来的赋值的就可以。 --------------------------------------- ------- 插播广告啦:版权所有:朱科 欢迎光临我的网站:www.goodsoft.cn,各位转贴别删,劳 动成果啊 --------------------------------------- ------- 4. int func(int a) { int b; switch(a) { case 1: b=30; case 2: b=20; case 3: b=16; default: b=0; } return b; } 则func(1)=? 答:func(1)=0,因为没有break语句,switch中会一直计算到b=0。这是提醒我们不要忘了 break。呵呵。 5: int a[3]; a[0]=0; a[1]=1; a[2]=2; int *p, *q; p=a; q=&a[2]; 则a[q-p]=? 答:a[q-p]=a[2]=2;这题是要告诉我们指针的运算特点 6. 定义 int **a[3][4], 则变量占有的内存空间为:_____ 答:此处定义的是指向指针的指针数组,对于32位系统,指针占内存空间4字节,因此总空 间为3×4×4=48。 7. 编写一个函数,要求输入年月日时分秒,输出该年月日时分秒的下一秒。如输入2004年12 月31日23时59分59秒,则输出2005年1月1日0时0分0秒。 答: /*输入年月日时分秒,输出年月日时分秒的下一秒,输出仍然在原内存空间*/ bool NextMinute(int *nYear,int *nMonth,int *nDate,int *nHour,int *nMinute,int *nSecond) { if(*nYear<0 || *nMonth>12 || *nMonth<0 || *nHour>23 || *nHour<0 || *nMinute< 0 || *nMinute>59 || *nSecond<0 || *nSecond>59) return false; int nDays; switch(*nMonth) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: nDays=31; break; case 2:// 判断闰年 if(*nYear%400==0||*nYear%100!=0&&*nYear%4==0) { nDays=29; } else { nDays=28; } break; default: nDays=30; break; } if(*nDate<0 || *nDate>nDays) return false; (*nSecond)++; // 秒加1 if(*nSecond>=60) // 秒满60,做出特殊处理,下面时,日,月等类同 { *nSecond=0; (*nMinute)++; if(*nMinute>=60) { *nMinute=0; (*nHour)++; if(*nHour>=24) { *nHour=0; (*nDate)++; if(*nDate>nDays) { *nDate=1; (*nMonth)++; if(*nMonth>12) { *nMonth=1; (*nYear)++; } } } } } return true; } /*示例可运行代码*/ void main() { int nYear=2004,nMonth=12,nDate=31,nHour=23,nMinute=59,nSecond=59; bool res = NextMinute(&nYear,&nMonth,&nDate,&nHour,&nMinute,&nSecond); if(res) printf("The result:%d-%d-%d %d:%d:%d",nYear,nMonth,nDate,nHour,nMinute,nSe cond); else printf("Input error!\n"); } 转载者注:(对原文有部分修改) 下面这套题我起码遇到三次以上 C++笔试题(十一) const char*, char const*, char*const的区别问题几乎是C++面试中每次都会有的题目。 事实上这个概念谁都有只是三种声明方式非常相似很容易记混。 Bjarne在他的The C++ Programming Language里面给出过一个助记的方法: 把一个声明从右向左读。 char * const cp; ( * 读成 pointer to ) cp is a const pointer to char const char * p; p is a pointer to const char; char const * p; 同上因为C++里面没有const*的运算符,所以const只能属于前面的类型。 --------------------------------- 下面这个程序执行后会有什么错误或者效果: #define MAX 255 int main() { unsigned char A[MAX],i; for (i=0;i<=MAX;i++) A[ i ]=i; } 解答: MAX=255 数组A的下标范围为:0..MAX-1,这是其一.. 其二.当i循环到255时,循环内执行: A[255]=255; 这句本身没有问题..但是返回for (i=0;i<=MAX;i++)语句时, 由于unsigned char的取值范围在(0..255),i++以后i又为0了..无限循环下去. 注:char类型为一个字节,取值范围是[-128,127],unsigned char [0 ,255] --------------------------------- 编写用C语言实现的求n阶阶乘问题的递归算法: long int fact(int n) { int x; long int y; if(n<0) { printf("error!"); } if(n==0) return 1; x=n-1; y=fact(x); return (n*y); } -------------------------------- 二分查找算法: 1、递归方法实现: int BSearch(elemtype a[],elemtype x,int low,int high) /*在下届为low,上界为high的数组a中折半查找数据元素x*/ { int mid; if(low>high) return -1; mid=(low+high)/2; if(x==a[mid]) return mid; if(x2 解: int f(int n) { int i,s,s1,s2; s1=1;/*s1用于保存f(n-1)的值*/ s2=1;/*s2用于保存f(n-2)的值*/ s=1; for(i=3;i<=n;i++) { s=s1+s2; s2=s1; s1=s; } return(s); } ------------------------------ 交换两个数,不用第三块儿内存: int a = ……; int b = ……; a = a + b; b = a - b; a = a - b; ------------------------------- Q1:请你分别划划OSI的七层网络结构图,和TCP/IP的五层结构图? 1、OSI每层功能及特点 a 物理层 为数据链路层提供物理连接,在其上串行传送比特流,即所传送数据的单位是比 特。此外,该层中还具有确定连接设备的电气特性和物理特性等功能。 b 数据链路层 负责在网络节点间的线路上通过检测、流量控制和重发等手段,无差错地传 送以帧为单位的数据。为做到这一点,在每一帧中必须同时带有同步、地址、差错控制及 流量控制等控制信息。 c 网络层 为了将数据分组从源(源端系统)送到目的地(目标端系统),网络层的任务就 是选择合适的路由和交换节点,使源的传输层传下来的分组信息能够正确无误地按照地址 找到目的地,并交付给相应的传输层,即完成网络的寻址功能。 d 传输层 传输层是高低层之间衔接的接口层。数据传输的单位是报文,当报文较长时将它 分割成若干分组,然后交给网络层进行传输。传输层是计算机网络协议分层中的最关键一层 ,该层以上各层将不再管理信息传输问题。 e 会话层 该层对传输的报文提供同步管理服务。在两个不同系统的互相通信的应用进程之 间建立、组织和协调交互。例如,确定是双工还是半双工工作。 f 表示层 该层的主要任务是把所传送的数据的抽象语法变换为传送语法,即把不同计算机 内部的不同表示形式转换成网络通信中的标准表示形式。此外,对传送的数据加密(或解 密)、正文压缩(或还原)也是表示层的任务。 g 应用层 该层直接面向用户,是OSI中的最高层。它的主要任务是为用户提供应用的接口 ,即提供不同计算机间的文件传送、访问与管理,电子邮件的内容处理,不同计算机通过 网络交互访问的虚拟终端功能等。 2、TCP/IP a 网络接口层 这是TCP/IP协议的最低一层,包括有多种逻辑链路控制和媒体访问协议。 网络接口层的功能是接收IP数据报并通过特定的网络进行传输,或从网络上接收物理帧, 抽取出IP数据报并转交给网际层。 b 网际网层(IP层)  该层包括以下协议:IP(网际协议)、ICMP(Internet Control Message Protocol,因特网控制报文协议)、ARP(Address Resolution Protocol,地址 解析协议)、RARP(Reverse Address Resolution Protocol,反向地址解析协议)。该层 负责相同或不同网络中计算机之间的通信,主要处理数据报和路由。在IP层中,ARP协议用 于将IP地址转换成物理地址,RARP协议用于将物理地址转换成IP地址,ICMP协议用于报告差 错和传送控制信息。IP协议在TCP/IP协议组中处于核心地位。 c 传输层  该层提供TCP(传输控制协议)和UDP(User Datagram Protocol,用户数据 报协议)两个协议,它们都建立在IP协议的基础上,其中TCP提供可靠的面向连接服务,U DP提供简单的无连接服务。传输层提供端到端,即应用程序之间的通信,主要功能是数据 格式化、数据确认和丢失重传等。 d 应用层  TCP/IP协议的应用层相当于OSI模型的会话层、表示层和应用层,它向用户提 供一组常用的应用层协议,其中包括:Telnet、SMTP、DNS等。此外,在应用层中还包含有 用户应用程序,它们均是建立在TCP/IP协议组之上的专用程序。 3、OSI参考模型和TCP/IP参考模型的区别: a OSI模型有7层,TCP/IP只有4层; b OSI先于协议出现,因此不会偏向于任何一组特定的协议,通用性更强,但有些功能不知 该放哪一层上,因此不得不加入一些子层;TCP/IP后于协议出现,仅是将已有协议的一个 描述,因此两者配合的非常好;但他不适合其他的协议栈,不容易描述其他非TCP/IP的网 络; c OSI中网络层同时支持无连接和面向连接的通信,但在传输层上只支持面向连接的通信; TCP/IP中网络层只支持无连接通信,传输层同时支持两种通信; d 在技术发生变化时,OSI模型比TCP/IP模型中的协议更容易被替换。 --------------------------------------- - Q2:请你详细的解释一下IP协议的定义,在哪个层上面,主要有什么作用? TCP与UDP呢?   解:与IP协议配套使用的还有三个协议: ARP-地址解析协议 RARP-逆地址解析协议 ICMP-因特网控制报文协议ICMP IP协议-网际协议 IP地址、IP包头 --------------------------------------- - Q3:请问交换机和路由器分别的实现原理是什么?分别在哪个层次上面实现的? 将网络互相连接起来要使用一些中间设备(或中间系统),ISO的术语称之为中继(re lay)系统。根据中继系统所在的层次,可以有以下五种中继系统: 1.物理层(即常说的第一层、层L1)中继系统,即转发器(repeater)。 2.数据链路层(即第二层,层L2),即网桥或桥接器(bridge)。 3.网络层(第三层,层L3)中继系统,即路由器(router)。 4.网桥和路由器的混合物桥路器(brouter)兼有网桥和路由器的功能。 5.在网络层以上的中继系统,即网关(gateway). 当中继系统是转发器时,一般不称之为网络互联,因为这仅仅是把一个网络扩大了, 而这仍然是一个网络。高层网关由于比较复杂,目前使用得较少。因此一般讨论网络互连 时都是指用交换机和路由器进行互联的网络。本文主要阐述交换机和路由器及其区别。 第二层交换机和路由器的区别: 传统交换机从网桥发展而来,属于OSI第二层即数据链路层设备。它根据MAC地址寻 址,通过站表选择路由,站表的建立和维护由交换机自动进行。路由器属于OSI第三层 即网络层设备,它根据IP地址进行寻址,通过路由表路由协议产生。因特网的路由选择 协议:内部网关协议IGP和外部网关协议EGP 第三层交换机和路由器的区别: 在第三层交换技术出现之前,几乎没有必要将路由功能器件和路由器区别开来,他们完全 是相同的:提供路由功能正在路由器的工作,然而,现在第三层交换机完全能够执行传统 路由器的大多数功能。 综上所述,交换机一般用于LAN-WAN的连接,交换机归于网桥,是数据链路层的设 备,有些交换机也可实现第三层的交换。路由器用于WAN-WAN之间的连接,可以解 决异性网络之间转发分组,作用于网络层。他们只是从一条线路上接受输入分组,然后向 另一条线路转发。这两条线路可能分属于不同的网络,并采用不同协议。相比较而言,路 由器的功能较交换机要强大,但速度相对也慢,价格昂贵,第三层交换机既有交换机线速 转发报文能力,又有路由器良好的控制功能,因此得以广播应用。 --------------------------------------- -------- Q4:请问C++的类和C里面的struct有什么区别? c++中的类具有成员保护功能,并且具有继承,多态这类oo特点,而c里的struct没有 --------------------------------------- -------- Q5:请讲一讲析构函数和虚函数的用法和作用? 析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重 载。知识在类对象生命期结束的时候,由系统自动调用释放在构造函数中分配的资源。 这种在运行时,能依据其类型确认调用那个函数的能力称为多态性,或称迟后联编。 另: 析构函数一般在对象撤消前做收尾工作,比如回收内存等工作,虚拟函数的功能是使子类 可以用同 名的函数对父类函数进行重载,并且在调用时自动调用子类重载函数,如果是纯虚函数, 则纯粹是为了 在子类重载时有个统一的命名而已。 --------------------------------------- -------- Q6:全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的? 全局变量的生命周期是整个程序运行的时间,而局部变量的生命周期则是局部函数或过程 调用的时 间段。其实现是由编译器在编译时采用不同内存分配方法。全局变量在main函数调用后, 就开始分配, 如果是静态变量则是在main函数前就已经初始化了。而局部变量则是在用户栈中动态分配 的(还是建议 看编译原理中的活动记录这一块) --------------------------------------- ------- Q7:一些寄存器的题目,主要是寻址和内存管理等一些知识。 。。。 --------------------------------------- ----- Q8:8086是多少尉的系统?在数据总线上是怎么实现的? 8086系统是16位系统,其数据总线是20位 -------------------------------------- -------------------------------------- C++ 一、请填写BOOL , float, 指针变量 与“零值”比较的 if 语句。(10 分) 请写出 BOOL flag 与“零值”比较的 if 语句。(3 分) 标准答案: if ( flag ) if ( !flag ) 如下写法均属不良风格,不得分。 if (flag == TRUE) if (flag == 1 ) if (flag == FALSE) if (flag == 0) 请写出 float x 与“零值”比较的 if 语句。(4 分) 标准答案示例: const float EPSINON = 0.00001; if ((x >= - EPSINON) && (x <= EPSINON) 不可将浮点变量用“==”或“!=”与数字 比较,应该设法转化成“>=”或“<=”此 类形式。 如下是错误的写法,不得分。 if (x == 0.0) if (x != 0.0) 请写出 char *p 与“零值”比较的 if 语句。(3 分) 标准答案: if (p == NULL) if (p != NULL) 如下写法均属不良风格,不得分。 if (p == 0) if (p != 0) if (p) if (!) 二、以下为Windows NT 下的32 位C++程序,请计算sizeof 的值(10 分) void Func ( char str[100]) { 请计算 sizeof( str ) = 4 (2 分) } char str[] = “Hello” ; char *p = str ; int n = 10; 请计算 sizeof (str ) = 6 (2 分) sizeof ( p ) = 4 (2 分) sizeof ( n ) = 4 (2 分) void *p = malloc( 100 ); 请计算 sizeof ( p ) = 4 (2 分) 三、简答题(25 分) 1、头文件中的 ifndef/define/endif 干什么用?(5 分) 答:防止该头文件被重复引用。 2、#include 和 #include “filename.h” 有什么区别?(5 分) 答:对于#include ,编译器从标准库路径开始搜索 filename.h 对于#include “filename.h” ,编译器从用户的工作路径开始搜索 filename.h 3、const 有什么用途?(请至少说明两种)(5 分) 答:(1)可以定义 const 常量 (2)const 可以修饰函数的参数、返回值,甚至函数的定义体。被const 修饰的东 西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 4、在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”? (5 分) 答:C++语言支持函数重载,C 语言不支持函数重载。函数被C++编译后在库中的名字 与C 语言的不同。假设某个函数的原型为: void foo(int x, int y); 该函数被C 编译器编译后在库中的名字为_foo , 而C++编译器则会产生像 _foo_int_int 之类的名字。 C++提供了C 连接交换指定符号extern“C”来解决名字匹配问题。 5、请简述以下两个for 循环的优缺点(5 分) for (i=0; i #include void main() { WORDwVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1,1); err = WSAStartup(wVersionRequested,&wsaData); if( err != 0){ return; } if(LOBYTE( wsaData.wVersion ) != 1|| HIBYTE( wsaData.wVersion) != 1){ WSACleanup(); return; } SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000); bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); listen(sockSrv,5); SOCKADDR_IN addrClient; int len=sizeof(SOCKADDR); while(1) { SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); char sendBuf[100]; sprint(sendBuf,"Welcome %s tohttp://www.sunxin.org inet_ntoa(addrClient.sin_addr)); send(sockConn,sendBuf,strlen(sendBuf)+1,0); char recvBuf[100]; recv(sockConn,recvBuf); printf("%s\n",recvBuf); closesocket(sockConn); WSACleanup(); } } 注:这是Server端;File->New->Win32 Console Application,工程名:TcpSrv;然后, File->New->C++ Source File,文件名:TcpSrv;在该工程的Setting的Link的Object/li brary modules项要加入ws2_32.lib --------------------------------------- ---- #include #include void main() { WORDwVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1,1); err = WSAStartup(wVersionRequested,&wsaData); if( err != 0){ return; } if(LOBYTE( wsaData.wVersion ) != 1|| HIBYTE( wsaData.wVersion) != 1){ WSACleanup(); return; } SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); addrSrv.sin_family=AF_INET; addrSrv.sin_porthtons(6000); connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); char recvBuf[100]; recv(sockClient,recvBuf,100,0); printf("%s\n",recvBuf); send(sockClient,"This is zhangsan",strlen("This is zhangsan")+1,0); closesocket(sockClient); WSACleanup(); } 注:这是Client端;File->New->Win32 Console Application,工程名:TcpClient;然后 ,File->New->C++ Source File,文件名:TcpClient;同理,在该工程的Setting的Link 的Object/library modules项要加入ws2_32.lib --------------------------------------- ----- C++ #include class human { public: human(){ human_num++;}; static int human_num; ~human(){ human_num--; print(); } void print() { cout<<"human num is: "<x[j+1].key) { temp=x[j]; x[j]=x[j+1]; x[j+1]=temp; } } } ------------------------------- c语言 文件读写 #include "stdio.h" main() { FILE *fp; char ch,filename[10]; scanf("%s",filename); if((fp=fopen(filename,"w")==NULL) { printf("cann t open file\n"); exit(0); } ch=getchar(); while(ch!= # ) { fputc(ch,fp); putchar(ch); ch=getchar(); } fclose(fp); } ----------------------------------- c指针 int *p[n];-----指针数组,每个元素均为指向整型数据的指针。 int (*)p[n];------p为指向一维数组的指针,这个一维数组有n个整型数据。 int *p();----------函数带回指针,指针指向返回的值。 int (*)p();------p为指向函数的指针。 ----------------------------------- Windows的消息机制1 Windows是一个消息(Message)驱动系统。Windows的消息提供了应用程序之间、应用程序 与Windows系统之间进行通信的手段。应用程序想要实现的功能由消息来触发,并且靠对消 息的响应和处理来完成。 Windows系统中有两种消息队列:系统消息队列和应用程序消息队列。计算机的所有 输入设备由Windows监控。当一个事件发生时,Windows先将输入的消息放入系统消息队列 中,再将消息拷贝到相应的应用程序消息队列中。应用程序的消息处理程序将反复检测消 息队列,并把检测到的每个消息发送到相应的窗口函数中。这便是一个事件从发生至到达 窗口函数必须经历的过程。 必须注意的是,消息并非是抢占性的,无论事件的缓急,总是按照到达的先后派对, 依次处理(一些系统消息除外),这样可能使一些实时外部事件得不到及时处理。 ----------------------------------- Windows的消息机制2 Windows中的消息是放在对应的进程的消息队列里的。可以通过GetMessage取得,并且对于 一般的消息,此函数返回非零值,但是对于WM_QUIT消息,返回零。可以通过这个特征,结 束程序。当取得消息之后,应该先转换消息,再分发消息。所谓转换,就是把键盘码的转 换,所谓分发,就是把消息分发给对应的窗口,由对应的窗口处理消息,这样对应窗体的 消息处理函数就会被调用。两个函数可以实现这两个功能:TranslateMessage和Dispatch Message。 另外,需要注意,当我们点击窗口的关闭按钮关闭窗口时,程序并没有自动退出,而是向 程序发送了一个WM_DESTROY消息(其实过程是这样的,首先向程序发送WM_CLOSE消息,默 认的处理程序是调用DestroyWindow销毁窗体,从而引发WM_DESTROY消息),此时在窗体中 我们要响应这个消息,如果需要退出程序,那么就要向程序发送WM_QUIT消息(通过PostQu itMessage实现)。 一个窗体如果想要调用自己的消息处理函数,可以使用SendMessage向自己发消息。 如上所述,大部分(注意是大部分)的消息是这样传递的:首先放到进程的消息队列中, 之后由GetMessage取出,转换后,分发给对应的窗口。这种消息成为存储式消息。存储式 消息基本上是使用者输入的结果,以击键(如WM_KEYDOWN和WM_KEYUP讯息)、击键产生的 字符(WM_CHAR)、鼠标移动(WM_MOUSEMOVE)和鼠标按钮(WM_LBUTTONDOWN)的形式给出 。存储式消息还包含时钟消息(WM_TIMER)、更新消息(WM_PAINT)和退出消息(WM_QUI T)。 但是也有的消息是直接发送给窗口的,它们被称为非存储式消息。例如,当WinMain调用C reateWindow时,Windows将建立窗口并在处理中给窗口消息处理函数发送一个WM_CREATE消 息。当WinMain调用ShowWindow时,Windows将给窗口消息处理函数发送WM_SIZE和WM_SHOW WINDOW消息。当WinMain调用UpdateWindow时,Windows将给窗口消息处理函数发送WM_PAI NT消息。 ----------------------------------- Windows的消息机制3 --------------------------------- C++:memset ,memcpy 和strcpy 的根本区别? #include "memory.h" memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为 ‘ 或‘\0 ;例:char a[100];memset(a, \0 , sizeof(a)); memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度 ;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内 存地址溢出。 strcpy就只能拷贝字符串了,它遇到 \0 就结束拷贝;例:char a[100],b[50];strcpy(a ,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘\0 之前)是否超过50位,如超 过,则会造成b的内存地址溢出。 strcpy 原型:extern char *strcpy(char *dest,char *src); 用法:#include 功能:把src所指由NULL结束的字符串复制到dest所指的数组中。 说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 返回指向dest的指针。 memcpy 原型:extern void *memcpy(void *dest, void *src, unsigned int count); 用法:#include 功能:由src所指内存区域复制count个字节到dest所指内存区域。 说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。 memset 原型:extern void *memset(void *buffer, char c, int count); 用法:#include 功能:把buffer所指内存区域的前count个字节设置成字符c。 说明:返回指向buffer的指针。 ASSERT()是干什么用的 ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表 达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的 语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免 导致严重后果,同时也便于查找错误。例如,变量n在程序中不应该为0,如果为0可能导致 错误,你可以这样写程序: ...... ASSERT( n != 0); k = 10/ n; ...... ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略。 assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以 用在Release版本中。 system("pause"); 系统的暂停程序,按任意键继续,屏幕会打印,"按任意键继续。。。。。" 省去了使用g etchar(); VERITAS(维尔)软件公司是世界领先的存储管理软件厂商。其产品涵盖数据保护、灾难恢 复、虚拟存储、存储区域网和应用高可用性。在全球财富500强中有86%以上的企业采用了 VERITAS的产品来实现不同应用、服务器、硬件和存储设备之间的互操作性。公司网址是:http://www.veritas.com/,进入网站,你可能觉得那个醒目的Symantec标志那么熟悉,是 的,你熟悉的赛门铁克(Symantec)公司2005年初收购了VERITAS的全部股份。   说实话,VERITAS(维尔)软件公司出的笔试题是我做的笔试题中最让人头痛的了。不信 ,你自己看看吧。  1. A class B network on the internet has a subnet mask of 255.255.240.0, wha t is the maximum number of hosts per subnet .   a. 240   b. 255  c. 4094  d. 65534 答:C 对于B类网络地址,子网掩码255.255.240.0有: 1.子网数=2*4-2=6 (4代表掩码位,即2进制为1的部分) 2.主机数=2的12次方-2=16382 (12代表主机位,即2进制为0的部分) 具体计算公式见:http://www.adawei.com/blogview.asp?logID=95&cateID=3   2. What is the difference: between o(log n) and o(log n^2), where both log arithems have base 2 .   a. o(log n^2) is bigger  b. o(log n) is bigger   c. no difference 答:A log n^2=2*log n(n^2此处应该表示的是n的2次方),所以大于log n;   3. For a class what would happen if we call a class’s constructor from wi th the same class’s constructor .   a. compilation error  b. linking error   c. stack overflow    d. none of the above 答:C 相当于递归调用,不停的在栈上分配空间使栈溢出。   4. "new" in c++ is a: .   a. library function like malloc in c   b. key word c. operator   d. none of the above 答:C 注意new/delete都是C++直接支持的运算符,其他可能错认为是库函数的的有sizeof()和 typeid()及C++新增的四个类型转换运算符。 --------------------------------------- ------- 插播广告啦:版权所有:朱科 欢迎光临我的网站:www.goodsoft.cn,各位转贴别删,劳 动成果啊 --------------------------------------- -------   5. Which of the following information is not contained in an inode .   a. file owner  b. file size   c. file name  d. disk address 答:C Inodes是index node的缩写,是UNIX/Linux文件系统中单个文件的电脑存储档案索引结构 。每个文件的信息存储在inodes中。通常inode信息包含两部分:1)文件的所有者、类型、 权限、修改日期和大小,2)文所关联数据块的指针;但它不包含文件名和目录。一个文件 的文件名只是与inode相关联,inode再提供对数据块的访问。 具体情况要看UNIX文件系统 的书。   6. What’s the number of comparisons in the worst case to merge two sorted lists containing n elements each .   a. 2n  b.2n-1  c.2n+1  d.2n-2 答:B 假设两个排好序的数组为a{1,3}和b{2,4}(此种交错为最坏情况)要排序成一个数组c{1, 2,3,4},第一次1与2比较,插入1至c,第二次3与2比较,插入2至c,的三次3与4比较,插 入3至c。4不用比较直接插入c。共用3次比较。可推算通用公式为2n-1;   7. Time complexity of n algorithm T(n), where n is the input size ,is T(n) =T(n-1)+1/n if n>1 otherwise 1 the order of this algorithm is .   a. log (n)  b. n  c. n^2  d. n^n 答:a 解得:T(n)=1+1+1/2+1/3+……+1/n. 当n很大时,有:1+1/2+1/3+1/4+1/5+1/6+...1/n = 0.57721566490153286060651209 + ln(n)//C++里面用log(n),pascal里面用ln(n) 0.57721566490153286060651209叫做欧拉常数 参见:http://www.jstvu.edu.cn/xuebao/2003-3/pages/oulachangshu.htm   8. The number of 1 in the binary representation of 3*4096+ 15*256+5*16+3 are .   a. 8  b. 9  c. 10  d. 12 答:C 分解为:11*1000000000000+1111*100000000+101*10000+11=11111101010011共10个1。 C++笔试题(十三) 上海聚力传媒技术有限公司成立于2005年5月,是家新冒出来的公司,而他能够冒出来的原 因是由于它的电视直播软件PPLIVE(www.pplive.com)抢占了基于P2P技术的网络视讯服务 的先机,超级女生电视节目的火爆成就了PPLIVE软件这款软件,不过现在这个领域的竞争 者蜂拥而上,日子并不轻松。如果是我,我会很慎重的考虑这类新兴小公司的,当然我还 是很佩服它的,公司的创始人是华中科技大学的校友,有幸见过他的演讲。   下面是它2005年度的官方VC笔试题,他称:如有自信2小时能做完的应聘者请将做完答 案发mail至campus_hr@synacast.com,我们会马上和你联系的。呵呵,我并不打算把答案 发到这个邮箱去。 一、问答 1、实模式与保护模式。为什么要设计这两种模式?好处在什么地方?分别写出各自寻址的 过程。 答: 1. 实模式,又叫实地址模式,CPU完全按照8086的实际寻址方法访问从00000h--FFFFFh( 1MB大小)的地址范围的内存,在这种模式下,CPU只能做单任务运行;寻址公式为:物理 地址=左移4位的段地址+偏移地址,即:物理地址是由16位的段地址和16位的段内偏移地址 组成的。 2.保护模式,又叫内存保护模式,寻址采用32位段和偏移量,最大寻址空间4GB,在这种模 式下,系统运行于多任务,设计这种模式的原因和好处是:保护模式增加了寻址空间,增 加了对多任务的支持,增加了段页式寻址机制的内存管理(分段机制使得段具有访问权限 和特权级,各应用程序和操作系统的代码和核心是被保护的,这也是多任务支持的实现关 键和保护这个名字的由来)。寻址过程为:物理地址=由段地址查询全局描述符表中给出的 段基址+偏移地址,即:物理地址由影像寄存器中的基址加上16位或者32位的偏移组成。 2、请阅读以下一段程序,并给出答案。 class A { public: A(){ doSth(); } virtual void doSth(){printf("I am A");} }; class B:public A { public: virtual void doSth(){ printf("I am B");} }; B b; 执行结果是什么?为什么? 答:执行结果是I am A 因为b对象构造时调用基类A的构造函数A(),得此结果。 3、在STL的应用中 map这种key-value的应用很多,如果key的类型是GUID,该如何处理? 答:谁知道怎么处理补上吧。 4、一个内存变量a=5,有5个线程需要对其进行操作,其中3个对a进行加1操作,2个对a进 行减1操作,为了保证能够得到正常结果6,需要使用什么方法?(列出越多越好) 答:即要求列出线程同步方法,具体答案可见下面一题。 5、描述并比较以下对象:事件,信标,临界区,互斥对象。 答:这些对象都是用于线程同步的对象。 临界区:一种保证在某一时刻只有一个线程能访问数据的简便办法。它只可以在同一进程 内部使用。主要API函数有,产生临界区:InitializeCriticalSection,删除临界区:De leteCriticalSection,进入临界区:EnterCriticalSection,退出临界区:LeaveCritic alSection。 互斥对象:互斥对象跟临界区相似,但它不仅仅能够在同一应用程序不同线程中实现资源 的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享,当然下面两者 也有这个特点。主要API函数有,创建互斥量: CreateMutex,打开一个存在的互斥量: OpenMutex,释放互斥量的使用权:ReleaseMutex,关闭互斥量: CloseHandle。 信标:使用信号量(信标)最重要用途是:信号允许多个线程同时使用共享资源,它指出 了同时访问共享资源的线程最大数目。它的API函数和使用方法都与互斥对象相似,如创建 信号灯:CreateSemaphore,传入的参数可以指定信号灯的初始值。 事件:用来通知其他进程/线程某件操作已经完成。API函数有创建,打开事件对象等,特 殊点的是可以用函数SetEvent人工设置事件为有无信号状态,因此创建事件对象时可以有 两种方式,一种为自动重置,一种为人工重置。只有人工重置方式创建的事件对象才能正 确使用函数SetEvent。 鉴于本套题考的是VC,有必要说明的是在MFC中对于各种同步对象都提供了相对应的类CCt iticalSection,CMutex,CSemaphore ,CEvent,另外为使用等待功能封装了两个类:CSing leLock和CMultiLock。这些类方便了使用这些同步对象。 6、cdecl、stdcall、fastcall是什么?哪种可以实现个数不定的入口参数,为什么? 答:三者都是函数调用的约定。 cdecl:c declare(C调用约定)的缩写,是C和C++程序的缺省调用方式,规则是,按从右 至左的顺序压参数入栈,由调用者把参数弹出栈,对于传送参数的内存栈是由调用者来维 护的,正因为如此,只有这种调用方式可实现个数不定的入口参数(可变参数)。 stdcall:是Pascal程序的缺省调用方式,规则是,按从右至左的顺序压参数入栈,被调用 的函数在返回前清理传送参数的内存栈。 上两者的主要区别是前者由调用者清理栈,后者由被调用的函清理栈。当然函数名的修饰 部分也是不同的。 fastcall:采用寄存器传递参数,特点就是快了。 二、程序设计(以下题目请写出实现代码) 1、有一段文本,统计其中的单词数。例如: As a technology , "HailStorm" is so new that it is still only known by its code name. 注意:单词间的间隔不一定是一个空格。 答:可执行程序代码如下,假设该文本已存入text这个数组里。 void main() { char text[1000]={"As a technology , HailStorm is so new that it is still o nly known by its code name."}; int i=0,count=0; bool flag=false;//前面的字符是否为字母 while (text[ i]&&i<1000) { if (flag && !((text[ i]>= a &&text[ i]<= z )||(text[ i]>= A &&text[ i ]<= Z ))) {//前面是字母,当前不是字母,表示出现一个单词 flag=false; count++; } else if (!flag && ((text[ i]>= a &&text[ i]<= z )||(text[ i]>= A &&text[ i ]<= Z ))) { // 前面不是字母,当前是字母 flag=true; } i++; } if(flag) count++; cout< #define QUEEN 8 //皇后数量 int queen[QUEEN] ; //下标代表所在列号,值代表所在行号, //如queen[1]=2表示第1列第2行有个皇后 bool row_YN[QUEEN] ; //棋局的每一行是否有棋,有则为1,无为0 ; bool passive_YN[2*QUEEN-1] ; //斜率为1的斜线方向上是否有棋,共有2*QUEEN-1个斜线 bool negative_YN[2*QUEEN-1] ; //斜率为负1的斜线方向上是否有棋 //用全局变量,因全局数组元素值自动为0 int main() { int row = 0 ;//游标,当前移动的棋子(以列计) bool flag = false ; //当前棋子位置是否合法 queen[0] = -1 ; //第0列棋子准备,因一开始移动的就是第0列棋子 int count = 0 ; //一共有多少种解法的计数器 ; while(row>=0 ) //跳出条件是回溯到无法回溯时 { queen[row]++ ; //row列上的皇后走到下一行试试 if(queen[row] >= QUEEN) //当前列全部走完 { queen[row] = -1 ; //当前列棋子置于准备状态 row-- ; //回溯到上一列的棋子 if(row>=0) //回溯时要清理如下行,斜线的标志位 { row_YN[queen[row]] = false ; passive_YN[queen[row] + row] = false ; negative_YN[QUEEN-1 + row - queen[row]] = false ; } } else { //先判断棋子所在行没有棋子 if(row_YN[queen[row]] == false) { flag = true ; //以下检查当前棋子是否与之前的棋子斜线相交 if( passive_YN[queen[row] + row] == true || negative_YN[QUEEN-1 + row - queen[row]] == true) flag = false ; else flag = true ; if(flag) // flag为真表示位置合法 { if(row == QUEEN-1) //列到达最后,即最后一个皇后也找到位置,输出解 { count++ ; //解法的数目加一 ; cout<<"***第"<= QUEEN) { // 找到解后再次回溯找另外的解,这同上面无解回溯是一样的 row-- ; row_YN[queen[row]] = false ; passive_YN[queen[row] + row] = false ; negative_YN[QUEEN-1 + row - queen[row]] = false ;//原理同回溯 } flag = false ; } } } } cout< #define MAX 100 int str_num(char str[]) //计算字符串的长度,等效于strlen(str); { int i=0,num_str=0; while(str[ i ]!=0) {num_str++; i++; } return(num_str); } void place(int num_str,char str[]) //将字符串高低颠倒。 { int temp=0,i=0,j=0; for(i=0,j=num_str-1;i-1;i--) { if(sign_temp==0) {if(c[ i ]!=0) sign_temp=1; } if(sign_temp==1) { if(i==quan-1) cout<<"."; cout< 9 ) if(str[ i ]!= . ) {cout<<"data error"<1) {cout<<"data error"<>str1; cout<<"Please input the second number:"; cin>>str2; sign=sign_comp(str1,str2); quan1=format(str1); quan2=format(str2); if(quan1==-1||quan2==-1) { clear(str1); clear(str2); } }while(quan1==-1||quan2==-1||str1[0]==0||str2[0]==0); multiply_string(str1,str2,c); output(sign,c,quan1+quan2); } 所有题目到此结束,说实话后面两题的算法我就是看别人的代码(呵呵,再次实话,后两 题代码也不是我写的,只是对已有代码做了些修改,使结构更清晰,便于阅读)理解清楚 也用了2个小时以上,所以我还真没有自信将答案发到那个邮箱呢。看白云黄鹤上别的学生 的反响,让人怀疑这套题是否出得有点难了。 C++笔试题(十四) 1. 假设有如下一个类 class String{ public: String(const char *value); ~String(); char* strcpy(char* dest, const char* source); size t strlen( const char *string ); … private: char *data; }; 要求利用类中的已知函数实现该类的赋值运算符“operator=”。 String& String::operator=(const String& rhs) 答案: String& String::operator=(const String& rhs) { if(this == &rhs) return *this; // 检查对自己赋值的情况 delete [ ] data; // delete old memory //分配新内存,将rhs 的值拷贝给它 data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); return *this; //返回 } 2. 假设Complex是一个类。请问以下两种实现方式在效率上可能有什么区别?为什 么? 方式1: Complex a, b, c, d, result; … result = a + b + c + d; 方式2: Complex a, b, c, d, result; … result += a; result += b; result += c; result += d; 答案: 方式2的效率有可能比方式1要高一些。因为方式1运算中要产生三个临时对象, 如 果该类的构造复杂,那么会浪费较多时间。而一般情况下,方式2可以不用产生任 何临时对象。 3. 判断下列每行代码是否正确,错误的请解释原因。 ( a ) int ival = 1.01; ( k ) int i = -1; (b) int &rval1 = 1.01; ( l ) const int ic = i; ( c ) int &rval2 = ival; (m) const int *pic = ⁣ (d) int &rval3 = &ival; (n) int *const cpi = ⁣ ( e ) int *pi = &ival; ( o ) const int const* cpic = & ic; ( f ) int &rval4 = pi; (p) pic = cpic; ( g ) int &rval5 = *pi; ( q ) cpic = ⁣ (h) int &*prval1 = pi; ( r ) cpi = pic; ( i ) const int &ival2 = 1; ( s ) ic = *cpic; ( j ) const int &*prval2 = &ival; ( t ) pic = ⁣ 答案: (a) 正确; (b) 错误,必须是一个const引用才正确改为:const int &rval1 = 1.01; (c) 正确; (d) 错误,rval3的类型是int而非int *,改为int &rval3 = ival; 或者int* const &rva l3 = &ival; (e) 正确; ( f ) 错误,rval4的类是int而非int *,改为int * &rval4 =pi; (g) 正确; (h) 错误,指向引用的指针是不合法的,改为int *&prval1 = pi; ( i ) 正确; ( j ) 错误,指向引用的指针是不合法的,改为int * const & prval2 = &ival; (k) 正确; ( l ) 正确; (m) 正确; (n) 错误,cpi是一个常量指针,指向int,但是ic却是一个const int; (o) 正确,cpic是一个常量指针,指向const int, ic的类型也是const; (p) 正确; (q) 正确; (r) 错误,cpi是个常量,不能被修改; (s) 错误,ic是个常量,不能被修改; (t) 正确。 4. 阅读下面的程序段,写出运行结果。 class A{ public: A() { printf("A 构造!\n"); } virtual ~A(){printf("A 析构!\n"); } virtual output1(){ printf( "output A1!\n" );} virtual output2() { printf( "output A2!\n" ); } }; class B : public A{ public: B() { printf("B 构造!\n");} virtual ~B(){ printf("B 析构!\n");} virtual output1(){ printf( "output B1!\n " ); } }; class C : public B{ public: C(){ printf("C 构造!\n");} virtual ~C() { printf("C 析构!\n");} virtual output1() { printf( "output C1!\n " );} }; int main() { C ObjC; ObjC.output1(); ObjC.output2(); } 答案: A 构造! B 构造! C 构造! output C1 ! output A2 ! C 析构! B 析构! A 析构! 5. 阅读下面的程序段,写出运行结果。请说明理由。 #include using namespace std; class Base { public: virtual double f(double i){ cout << " Here in the class Base, f(int): "; return i+1; } }; class Derived : public Base{ public: double f(double d){ cout << " Here in the class Derived, f(double): "; return d+1.1; } }; int main() { Base* derived = new Base; cout << derived->f(10) << \n ; cout << derived->f(10.1) << \n ; } 答案: Here in the class Derived, f(double): 11.1 Here in the class Derived, f(double): 11.2 理由:C++语言中无法在派生类中进行重载,所以两个函数调用均调用派生类中 的函数。 6. 阅读下面的程序段,写出运行结果。请说明理由。 #include #include using namespace std; int main(){ string s1(“Nancy"); string s2(“Clancy"); string& rs = s1; string *ps = &s1; rs = s2; cout<class namedptr { public: namedptr(const string& initname, t *initptr){name = initname; ptr = initptr;} private: const string& name; t * const ptr; }; 答案: 这个类的定义要求使用一个成员初始化列表,因为const成员只能被初始 化,不能被赋值。 9. (编程题)验证歌德巴赫猜想:任一充分大的偶数,可以用两个素数之和表示。 例如: 4 = 2 + 2 6 = 3 + 3 … 98 = 19 + 79 答案: #include #include using namespace std; bool IsPrime(int nPrime); int main(int argc, char* argv[]) { int nEven = 0; cout <<"Please input an even number (N >= 4)!" << endl; cout << "If you want to exit this program, please input 0." << endl << endl; cout <<"N = "; cin >> nEven; while(nEven != 0) //0 to exit { bool bSuccess = false; while (nEven < 4) //too small { cout << "Sorry, please input a number no less than 4!" << endl; cout << "N = "; cin >> nEven; if(nEven == 0) //exit { cout <<"Exit!" << endl; return 0; } } while((nEven % 2) == 1)//not an even number { cout <<"Sorry, please input an even number (N >= 4)!" << endl; cout << "N = "; cin >> nEven; if(nEven == 0) //exit { cout <<"Exit!" << endl; return 0; } } for(int i = 2; i <= nEven/2; i++) { if( IsPrime(i) && IsPrime(nEven - i) ) //prime number { cout << nEven <<" = " << i <<" + " << nEven-i << endl; cout << "N = "; cin >> nEven; bSuccess = true; break; } } if (!bSuccess) //is that possible? :-) { cout << endl <<"God!" << endl; cout << "The Goldbach Conjecture is Wrong!" << endl; cout <<"Exit!" << endl; return 0; } } cout << "Exit!" << endl; return 0; } bool IsPrime(int nPrime) //Is a number Prime? { if(nPrime == 2 || nPrime == 3) return true; for(int i = 2; i <= int(sqrt((double)nPrime) + 0.5); i++) if(nPrime % i == 0) return false; //no, it isn t a prime number return true; //yes, it is a prime number. } 10. (编程题)设有一个背包可以放入的物品的重量为s,现有n件物品,重量分别 为w[1];w[2]; … ;w[n]。问能否从这n件物品中选择若干件放入此背包中, 使得放 入的重量之和正好为s。如果存在一种符合上诉要求的选择,则称此背包问题有解 (或称其解为真);否则称此背包问题无解(或称其解为假)。试用的递归方法 设计求解背包问题的算法。(提示:此背包问题的递归定义可分四种情况来考虑: 1) s = 0; 2) s < 0; 3) s > 0 and n < 1; 4) s > 0 and n>=1.) 答案: KNAP(s,n) 有以下四种情况: True s = 0 False s < 0 False s > 0 and n < 1 KNAP(s, n- 1) or KNAP(s- w[n], n- 1) s > 0 and n >= 1 #include #include bool KNAP(int s,int n, int *w,int &rnum) { bool ret,ret1; if(s == 0) return true; else if(s < 0) return false; else if(s > 0 && n <= 0) return false; else if(s > 0 && n > 0) { int snew; int wnew[100]; //用来保存新的数据 int i, j, k=0; for(i=0; i0) { int len = rnum; for(j=0; j>s; cout <<"Input the number of the goods: "<>num; if(num <= 0) { printf("the number of the goods must be greater than 0!\n"); return 0; } w = new int[num]; int i = 0; while(i < num) { printf("Input the weight of the %d th goods:", i); cin>>w[ i ]; if(w[ i ] < 0) printf("the weight of the %d th goods must be great/equal 0!\n", i); else i++; } int len=0; bool ret = KNAP(s,num,w, len); if(!ret) printf("There is no solution!\n"); else printf("There is a solution!\n"); delete [ ]w; return 0; } C++笔试题(十五) 4. static有什么用途?(请至少说明两种) 1.限制变量的作用域 2.设置变量的存储域 7. 引用与指针有什么区别? 1) 引用必须被初始化,指针不必。 2) 引用初始化以后不能被改变,指针可以改变所指的对象。 2) 不存在指向空值的引用,但是存在指向空值的指针。 8. 描述实时系统的基本特性 在特定时间内完成特定的任务,实时性与可靠性 9. 全局变量和局部变量在内存中是否有区别?如果有,是什么区别? 全局变量储存在静态数据库,局部变量在堆栈 10. 什么是平衡二叉树? 左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1 11. 堆栈溢出一般是由什么原因导致的? 没有回收垃圾资源 12. 什么函数不能声明为虚函数? constructor 13. 冒泡排序算法的时间复杂度是什么? O(n^2) 14. 写出float x 与“零值”比较的if语句。 if(x>0.000001&&x<-0.000001) 16. Internet采用哪种网络协议?该协议的主要层次结构? tcp/ip 应用层/传输层/网络层/数据链路层/物理层 17. Internet物理地址和IP地址转换采用什么协议? ARP (Address Resolution Protocol)(地址解析協議) 18.IP地址的编码分为哪俩部分? IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分 哪些是网络位哪些是主机位。 2.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出 C程序。 循环链表,用取余操作做 3.不能做switch()的参数类型是: switch的参数不能为实型。 華為 1、局部变量能否和全局变量重名? 答:能,局部会屏蔽全局。要用全局变量,需要使用"::" 局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不 会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量, 比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环 体内 2、如何引用一个已经定义过的全局变量? 答:extern 可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在 头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用ex tern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错 3、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么? 答:可以,在不同的C文件中以static形式来声明同名全局变量。 可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初 值,此时连接不会出错 4、语句for( ;1 ;)有什么问题?它是什么意思? 答:和while(1)相同。 5、do……while和while……do有什么区别? 答:前一个循环一遍再判断,后一个判断以后再循环 6、请写出下列代码的输出内容 #include main() { int a,b,c,d; a=10; b=a++; c=++a; d=10*a++; printf("b,c,d:%d,%d,%d",b,c,d); return 0; } 答:10,12,120 1、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么 区别?static函数与普通函数有什么区别? 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就 是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同 。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文 件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作 用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。 由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可 以避免在其它源文件中引起错误。 从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的 生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。 static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明 为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以 外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件 static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其 他文件单元中被引用; static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依 据上一次结果值; static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调 用中维持一份拷贝 2、程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存 在于( 堆)中。 3、设有以下说明和定义: typedef union {long i; int k[5]; char c;} DATE; struct data { int cat; DATE cow; double dog;} too; DATE max; 则语句 printf("%d",sizeof(struct date)+sizeof(max));的执行结果是:___52____ 答:DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所 以它的大小是20 data是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 = 32. 所以结果是 20 + 32 = 52. 当然...在某些16位编辑器下, int可能是2字节,那么结果是 int2 + DATE10 + double8 = 20 4、队列和栈有什么区别? 队列先进先出,栈后进先出 5、写出下列代码的输出内容 #include int inc(int a) { return(++a); } int multi(int*a,int*b,int*c) { return(*c=*a**b); } typedef int(FUNC1)(int in); typedef int(FUNC2) (int*,int*,int*); void show(FUNC2 fun,int arg1, int*arg2) { INCp=&inc; int temp =p(arg1); fun(&temp,&arg1, arg2); printf("%d\n",*arg2); } main() { int a; show(multi,10,&a); return 0; } 答:110 7、请找出下面代码中的所以错误 说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba” 1、#include"string.h" 2、main() 3、{ 4、 char*src="hello,world"; 5、 char* dest=NULL; 6、 int len=strlen(src); 7、 dest=(char*)malloc(len); 8、 char* d=dest; 9、 char* s=src[len]; 10、 while(len--!=0) 11、 d++=s--; 12、 printf("%s",dest); 13、 return 0; 14、} 答: 方法1: int main(){ char* src = "hello,world"; int len = strlen(src); char* dest = (char*)malloc(len+1);//要为\0分配一个空间 char* d = dest; char* s = &src[len-1];//指向最后一个字符 while( len-- != 0 ) *d++=*s--; *d = 0;//尾部要加\0 printf("%s\n",dest); free(dest);// 使用完,应当释放空间,以免造成内存汇泄露 return 0; } 方法2: #include #include main() { char str[]="hello,world"; int len=strlen(str); char t; for(int i=0; i #include int main(void) { long l; char *str = "98765432"; l = atol(lstr); printf("string = %s integer = %ld\n", str, l); return(0); } 2.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现? c用宏定义,c++用inline 3.直接链接两个信令点的一组链路称作什么? PPP点到点连接 4.接入网用的是什么接口? 5.voip都用了那些协议? 6.软件测试都有那些种类? 黑盒:针对系统功能的测试 白合:测试函数功能,各函数接口 7.确定模块的功能和模块的接口是在软件设计的那个队段完成的? 概要设计阶段 8.enum string { x1, x2, x3=10, x4, x5, }x; 问x= ? ; 9.unsigned char *p1; unsigned long *p2; p1=(unsigned char *)0x801000; p2=(unsigned long *)0x810000; 请问p1+5= ; p2+5= ; p1+5=0x8010005; p2+5=0x810014; 三.选择题: 1.Ethternet链接到Internet用到以下那个协议?(ARP) A.HDLC;B.ARP;C.UDP;D.TCP;E.ID 2.属于网络层协议的是:(IP) A.TCP;B.IP;C.ICMP;D.X.25 3.Windows消息调度机制是:(消息队列) A.指令队列;B.指令堆栈;C.消息队列;D.消息堆栈; 4.unsigned short hash(unsigned short key) { return (key>>)%256 } 请问hash(16),hash(256)的值分别是: A.1.16;B.8.32;C.4.16;D.1.32 四.找错题: 1.请问下面程序有什么错误? int a[60][250][1000],i,j,k; for(k=0;k<=1000;k++) //k<1000 for(j=0;j<250;j++) for(i=0;i<60;i++) a[ i][j][k]=0; 2.#define Max_CB 500 void LmiQueryCSmd(Struct MSgCB * pmsg) { unsigned char ucCmdNum; ...... for(ucCmdNum=0;ucCmdNumMax_GT_Length) { return GT_Length_ERROR; } ....... } 五.问答题: 1.IP Phone的原理是什么? IPV6 2.TCP/IP通信建立的过程怎样,端口有什么作用? 三次握手,确定是哪个应用程序使用该协议 3.1号信令和7号信令有什么区别,我国某前广泛使用的是那一种? 4.列举5种以上的电话新业务? 微软亚洲技术中心的面试题!!! 1.进程和线程的差别。 线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位 (2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行 (3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于 进程的资源. (4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销 明显大于创建或撤消线程时的开销。 2.测试方法 人工测试:个人复查、抽查和会审 机器测试:黑盒测试和白盒测试 2.Heap与stack的差别。 Heap是堆,stack是栈。 Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。 Stack空间有限,Heap是很大的自由存储区 C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。 程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传 递也在栈上进行 3.Windows下的内存是如何管理的? 4.介绍.Net和.Net的安全性。 5.客户端如何访问.Net组件实现Web Service? 6.C/C++编译器中虚表是如何完成的? 7.谈谈COM的线程模型。然后讨论进程内/外组件的差别。 8.谈谈IA32下的分页机制 小页(4K)两级分页模式,大页(4M)一级 9.给两个变量,如何找出一个带环单链表中是什么地方出现环的? 一个递增一,一个递增二,他们指向同一个接点时就是环内的一个点,记做p1。设递增1的 走了N步,递增2的走了2N步。p2指向链表头。则p1,p2同时走N步还在p1点相遇。第一次相 遇的点就是出现环的节点。 10.在IA32中一共有多少种办法从用户态跳到内核态? 通过调用门,从ring3到ring0,中断从ring3到ring0,进入vm86等等 11.如果只想让程序有一个实例运行,不能运行两个。像winamp一样,只能开一个窗口, 怎样实现? 用内存映射或全局原子(互斥变量)、查找窗口句柄.. FindWindow,互斥,写标志到文件或注册表,共享内存。.  12.如何截取键盘的响应,让所有的‘a’变成‘b’? 键盘钩子SetWindowsHookEx  13.Apartment在COM中有什么用?为什么要引入?  14.存储过程是什么?有什么用?有什么优点? 我的理解就是一堆sql的集合,可以建立非常复杂的查询,编译运行,所以运行一次后,以 后再运行速度比单独执行SQL快很多  15.Template有什么特点?什么时候用? 16.谈谈Windows DNA结构的特点和优点。 网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别? 1,进程:子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。 2,线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他 线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。 两者都可以提高程序的并发度,提高程序运行效率和响应时间。 线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源管理和保护;而进程正 相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。 思科 1. 用宏定义写出swap(x,y) #define swap(x, y) x = x + y; y = x - y; x = x - y; 2.数组a[N],存放了1至N-1个数,其中某个数重复一次。写一个函数,找出被重复的数字 .时间复杂度必须为o(N)函数原型: int do_dup(int a[],int N) (“存放了1至N-1个数”有歧异。如果存放的数是1到N-1就好办了。如果原意是存放N-1个 数,我就没有思路了,会的网友请回帖告知,多谢。) 3 一语句实现x是否为2的若干次幂的判断 int i = 512; cout << boolalpha << ((i & (i - 1)) ? false : true) << endl; 4.unsigned int intvert(unsigned int x,int p,int n)实现对x的进行转换,p为起始转化 位,n为需要转换的长度,假设起始点在右边.如x=0b0001 0001,p=4,n=3转换后x=0b0110 00 01 unsigned int intvert(unsigned int x,int p,int n){ unsigned int _t = 0; unsigned int _a = 1; for(int i = 0; i < n; ++i){ _t |= _a; _a = _a << 1; } _t = _t << p; x ^= _t; return x; } 慧通: 什么是预编译 何时需要预编译: 1、总是使用不经常改动的大型代码体。 2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这 种情况下,可以将所有包含文件预编译为一个预编译头。 char * const p; char const * p const char *p 上述三个有什么区别? char * const p; //指针常量,p的值不可以修改 char const * p;//常量指针,指向常量的指针,指向的常量值不可以改 const char *p; //和char const *p char str1[] = "abc"; char str2[] = "abc"; const char str3[] = "abc"; const char str4[] = "abc"; const char *str5 = "abc"; const char *str6 = "abc"; char *str7 = "abc"; char *str8 = "abc"; cout << ( str1 == str2 ) << endl; cout << ( str3 == str4 ) << endl; cout << ( str5 == str6 ) << endl; cout << ( str7 == str8 ) << endl; 结果是:0 0 1 1 解答:str1,str2,str3,str4是数组变量,它们有各自的内存空间; 而str5,str6,str7,str8是指针,它们指向相同的常量区域。 12. 以下代码中的两个sizeof用法有问题吗?[C易] void UpperCase( char str[] ) // 将 str 中的小写字母转换成大写字母 { for( size_t i=0; i(Y)?(Y):(X))//结尾没有; 2、嵌入式系统中经常要用到无限循环,你怎么用C编写死循环。 while(1){}或者for(;;) 3、关键字static的作用是什么? 定义静态变量 4、关键字const有什么含意? 表示常量不可以修改的变量。 5、关键字volatile有什么含意?并举出三个不同的例子? 提示编译器对象的值可能在编译器未监测到的情况下改变。 int (*s[10])(int) 表示的是什么啊 int (*s[10])(int) 函数指针数组,每个指针指向一个int func(int param)的函数。 1.有以下表达式: int a=248; b=4;int const c=21;const int *d=&a; int *const e=&b;int const *f const =&a; 请问下列表达式哪些会被编译器禁止?为什么? *c=32;d=&b;*d=43;e=34;e=&a;f=0x321f; *c 这是个什么东东,禁止 *d 说了是const, 禁止 e = &a 说了是const 禁止 const *f const =&a; 禁止 2.交换两个变量的值,不使用第三个变量。即a=3,b=5,交换之后a=5,b=3; 有两种解法, 一种用算术算法, 一种用^(异或) a = a + b; b = a - b; a = a - b; or a = a^b;// 只能对int,char.. b = a^b; a = a^b; or a ^= b ^= a; 3.c和c++中的struct有什么不同? c和c++中struct的主要区别是c中的struct不可以含有成员函数,而c++中的struct可以。 c++中struct和class的主要区别在于默认的存取权限不同,struct默认为public,而clas s默认为private 4.#include #include void getmemory(char *p) { p=(char *) malloc(100); strcpy(p,"hello world"); } int main( ) { char *str=NULL; getmemory(str); printf("%s/n",str); free(str); return 0; } 给p分配内存,并没有给str分配内存,没有达到原来的目的。 5.char szstr[10]; strcpy(szstr,"0123456789"); 产生什么结果?为什么? 长度不一样,会造成非法的OS 6.列举几种进程的同步机制,并比较其优缺点。 原子操作 信号量机制 自旋锁 管程,会合,分布式系统 7.进程之间通信的途径 共享存储系统 消息传递系统 管道:以文件系统为基础 11.进程死锁的原因 资源竞争及进程推进顺序非法 12.死锁的4个必要条件 互斥、请求保持、不可剥夺、环路 13.死锁的处理 鸵鸟策略、预防策略、避免策略、检测与解除死锁 15. 操作系统中进程调度策略有哪几种? FCFS(先来先服务),优先级,时间片轮转,多级反馈 8.类的静态成员和非静态成员有何区别? 类的静态成员每个类只有一个,非静态成员每个对象一个 9.纯虚函数如何定义?使用时应注意什么? virtual void f()=0; 是接口,子类必须要实现 10.数组和链表的区别 数组:数据顺序存储,固定大小 连表:数据可以随机存储,大小可动态改变 12.ISO的七层模型是什么?tcp/udp是属于哪一层?tcp/udp有何优缺点? 应用层 表示层 会话层 运输层 网络层 物理链路层 物理层 tcp /udp属于运输层 TCP 服务提供了数据流传输、可靠性、有效流控制、全双工操作和多路复用技术等。 与 TCP 不同, UDP 并不提供对 IP 协议的可靠机制、流控制以及错误恢复功能等。由于 UDP 比较简单, UDP 头包含很少的字节,比 TCP 负载消耗少。 tcp: 提供稳定的传输服务,有流量控制,缺点是包头大,冗余性不好 udp: 不提供稳定的服务,包头小,开销小 1:(void *)ptr 和 (*(void**))ptr的结果是否相同?其中ptr为同一个指针 .(void *)ptr 和 (*(void**))ptr值是相同的 2:int main() { int x=3; printf("%d",x); return 1; } 问函数既然不会被其它函数调用,为什么要返回1? mian中,c标准认为0表示成功,非0表示错误。具体的值是某中具体出错信息 1,要对绝对地址0x100000赋值,我们可以用 *(unsigned int*)0x100000 = 1234; 那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做? *((void (*)( ))0x100000 ) ( ); 首先要将0x100000强制转换成函数指针,即: (void (*)())0x100000 然后再调用它: *((void (*)())0x100000)(); 用typedef可以看得更直观些: typedef void(*)() voidFuncPtr; *((voidFuncPtr)0x100000)(); 2,已知一个数组table,用一个宏定义,求出数据的元素个数 #define NTBL #define NTBL (sizeof(table)/sizeof(table[0])) 面试题: 线程与进程的区别和联系? 线程是否具有相同的堆栈? dll是否有独立的堆栈? 进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候 操作系统就帮你创建了一个主线程。 每个线程有自己的堆栈。 DLL中有没有独立的堆栈,这个问题不好回答,或者说这个问题本身是否有问题。因为DLL 中的代码是被某些线程所执行,只有线程拥有堆栈,如果DLL中的代码是EXE中的线程所调 用,那么这个时候是不是说这个DLL没有自己独立的堆栈?如果DLL中的代码是由DLL自己创 建的线程所执行,那么是不是说DLL有独立的堆栈? 以上讲的是堆栈,如果对于堆来说,每个DLL有自己的堆,所以如果是从DLL中动态分配的 内存,最好是从DLL中删除,如果你从DLL中分配内存,然后在EXE中,或者另外一个DLL中 删除,很有可能导致程序崩溃 unsigned short A = 10; printf("~A = %u\n", ~A); char c=128; printf("c=%d\n",c); 输出多少?并分析过程 第一题,~A =0xfffffff5,int值 为-11,但输出的是uint。所以输出4294967285 第二题,c=0x10,输出的是int,最高位为1,是负数,所以它的值就是0x00的补码就是12 8,所以输出-128。 这两道题都是在考察二进制向int或uint转换时的最高位处理。 分析下面的程序: void GetMemory(char **p,int num) { *p=(char *)malloc(num); } int main() { char *str=NULL; GetMemory(&str,100); strcpy(str,"hello"); free(str); if(str!=NULL) { strcpy(str,"world"); } printf("\n str is %s",str); getchar(); } 问输出结果是什么?希望大家能说说原因,先谢谢了 输出str is world。 free 只是释放的str指向的内存空间,它本身的值还是存在的. 所以free之后,有一个好的习惯就是将str=NULL. 此时str指向空间的内存已被回收,如果输出语句之前还存在分配空间的操作的话,这段存储 空间是可能被重新分配给其他变量的, 尽管这段程序确实是存在大大的问题(上面各位已经说得很清楚了),但是通常会打印出 world来。 这是因为,进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。 当你malloc一块内存的时候,管理库向操作系统申请一块空间(可能会比你申请的大一些 ),然后在这块空间中记录一些管理信息(一般是在你申请的内存前面一点),并将可用 内存的地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你 是可以继续访问这块地址的,只不过。。。。。。。。楼上都说过了,最好别这么干。 char a[10],strlen(a)为什么等于15?运行的结果 #include "stdio.h" #include "string.h" void main() { char aa[10]; printf("%d",strlen(aa)); } sizeof()和初不初始化,没有关系; strlen()和初始化有关。 char (*str)[20];/*str是一个数组指针,即指向数组的指针.*/ char *str[20];/*str是一个指针数组,其元素为指针型数据.*/ long a=0x801010; a+5=? 0x801010用二进制表示为:“1000 0000 0001 0000 0001 0000”,十进制的值为8392720 ,再加上5就是8392725罗 1)给定结构struct A { char t:4; char k:4; unsigned short i:8; unsigned long m; };问sizeof(A) = ? 给定结构struct A { char t:4; 4位 char k:4; 4位 unsigned short i:8; 8位 unsigned long m; // 偏移2字节保证4字节对齐 }; // 共8字节 2)下面的函数实现在一个数上加一个数,有什么错误?请改正。 int add_n ( int n ) { static int i = 100; i += n; return i; } 当你第二次调用时得不到正确的结果,难道你写个函数就是为了调用一次?问题就出在 s tatic上? // 帮忙分析一下 #include #include #include #include #include #include typedef struct AA { int b1:5; int b2:2; }AA; void main() { AA aa; char cc[100]; strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz"); memcpy(&aa,cc,sizeof(AA)); cout << aa.b1 <高字节 所以,最后一步:显示的是这4个字节的最后5位(低字节),和之前的2位 分别为:10000,和01 (补码) 因为int是有正负之分  所以:答案是-16和1 再看下面程序: #include #include #include #include typedef struct AA { int b1:6; int b2:2; char a1; char a2; char a3; char a4; char a5; char a6; char a7; char a8; char a9; double c; char d; }AA; void main() { AA aa; char cc[100]; strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz"); memcpy(&aa,cc,sizeof(AA)); cout << sizeof(aa)<