http://topic.csdn.net/u/20080924/15/3b00a84e-970f-4dea-92f2-868c5d1ad825.html 前段时间刚参加了n多公司的C/C++软件工程师的面试,有国企,外企,私企(moto,飞思卡尔,港湾,中国卫星XXX(这个牛))等等等等。感受感想颇多,近日终于空闲,在此表述一下。 本人基本条件:3年开发经验,2year+ Windows developmentexperence,1year+ Linux experence.熟悉C,C++,MFC/SDK/API,MiniGUI...(都是一些基本的了)。前公司并不知名,但在其中做个team leader。 言归正传 找工作本人认为最重要的就是前期准备了。 首先。简历一定要写的切合主题。招聘单位要的是你的技能,这个只要大概能符合就可以,关键他们需要的是你的开发经验,一定要在简历中完美的体现出你之前所参与的项目,一定要写明你在项目中的职责和地位,企业通过这方面侧面对你的技术水平进行定位,因此一定要实事求是的写的尽可能的详细,只要别吹牛B,再详细都不过分。只要上面这些内容得到充分的发挥,那么你基本可以得到面试的机会了。 面试之笔试。去了10多个单位面试。题惊人的相似,如果你想顺利通过笔试,有两条建议:一,去网上找一些汇总的笔试题,仔细的看看里面关于数组,指针,链表,类的问题,90%的笔试题目就是里面的原题,从CSDN的下载频道可以找到N多笔试题汇总,看过1遍之后你会发现所有的汇总内容都差不多。二、这点就有点那个了,呵呵。不好听叫作弊,好听的话叫夹带。可以把所有您认为比较复杂的算法题打印出来,大概常考的有十几个吧,比如strcpy,strcat,链表逆序,排序,字符串匹配查找,检测单向链表上的环等等,一定要带着这个去笔试,好公司一般都会为前来笔试的人员单独准备一间屋子,所以只要看到差不多的算法,放心大胆的把答案拿出来copy吧。 这里我说一下,不是出的这些题我们不会写,只是在笔试这种情况下,要把代码写的尽量简练,完善,并且工整确实有些困难。 去外企或规模大的私企或者股份制,要做好有英语题的准备,不过一般情况下不难,汉译英,英译汉,只要别空着就没问题。 只要你按照上面的做了,OK,你已经可以和HR以及技术主管直接对话了。 面试相对上面两个环节是最关键的。如果公司很不错,那么,你一定要准备英文自我介绍,英文项目介绍,英文优缺点介绍,英文个人喜好介绍,我去的公司大多数都要求这个。一上来就是can you introduce yourself in English? Can you introduce youresponsibility in your team/project? 接下来就是技术面试了,一定要好好总结你在之前公司的项目经历和饰演角色,一定要应付的游刃有余,准备充分。然后就是一些技术方面的东西了,virtual,const,static,extern“C”,虚函数表,构造、析构函数可否为virtual,纯虚函数,虚拟继承,偶尔也会问到一些小算法,放心,都是网上有的,只要看过,非常容易应付的。 最后是问一些其他乱七八糟的事情以及让你本人提一些要求,这些看情况发挥吧。 OK,如果上述都顺利昨晚,回家等offer去吧。。。如果你确实认为这个单位非常适合你,那你在面试后的1、2天内可以发邮件再次表达自己的心情,并且给自己定一个客观来说相对合理的范围。 去应聘,看起来很难,其实过程非常轻松。但所有这些其实都是在一个又一个不成熟的面试和笔试过程中积累起来的。 希望能给大家一些帮助。也希望大家都好运。 说一下最后的成果吧,在没有任何经验误打误撞了几家之后,2家外企和N家私企来了offer,外企由于是通过外包进去,感觉没什么保障拒绝了,最后挑了一家国内的股份制上市公司,感觉还算可以吧。 最后,只要你做好了充分的准备,那么机会,高薪定会摆在你的面前。 与君共勉。 附注: 在一次人才招聘会上,招聘人员告诉记者,他们认为现在的大学毕业生在求职中存在着很多误区,而这些都是直接导致自己求职失败的原因。 一、对企业一无所知 很多毕业生应聘企业很随意,在一次招聘会上,一家化妆品公司的招聘主管让应聘大学生说出几款该公司代理的品牌名字,没想到求职者一个都答不出来。这位招聘主管说:“对公司这么陌生,在求职前不去了解该公司,很难想像他对自己的职业生涯有所规划。这样不负责的人,我们肯定不会用。”记者了解到,这种情况招聘单位遇到很多。 二、自以为是 对于一些大学生而言,并非找不到任何工作,而是由于对工作的期望值过高,对一些低档次的工作不屑一顾,盲目地追求一些脱离自身实际的“高工资、高待遇”的理想工作。这种“半吊子”型的人才,在就业压力日益增大的今天必然要走向失业。 三、应聘太盲目 不少大学生并不知道某个职位的职责分工是什么,只会从字面上去理解。一家公司“营业服务部”下属的商品企划室招聘人,结果许多大学生看到“服务”二字,就以为是做服务工作无人应聘。而当公司把“服务”两字去掉后,马上就有很多人投简历。人事主管告诫说,如果对职位不明白可以询问用人单位,不要单从字面上去片面理解,这样很可能会错过一个好机会。 四、不愿到基层去吃苦 大学生刚刚踏入社会,刚进入企业,很难立刻进入角色。一些公司规定所有新参加工作的大学生都要到一线去锻炼一年,有的同学一看不能马上搞设计、搞管理工作,要“吃一年的苦”,就打退堂鼓不愿意干了,白白丢掉了很好的工作。 五、独立性欠缺 不少大学生在学习中只知死啃书本,没有足够的社会实践,每次应聘都要父母参与求职,自己则缺乏主见。还有的毕业生笔试、面试通过后,在与公司签约的时候,父母到场与用人单位说长道短谈条件。对于这种行为,多家公司的人事主管都表示反感。“找工作的前提是,你是一个独立的人,有自己的判断能力,能对自己负责。”一位人事经理说。 IT公司面试-笔试题目1 1一个父类写了一个virtual 函数,如果子类覆盖它的函数不加virtual ,也能实现多态? 在子类的空间里,有没有父类的这个函数,或者父类的私有变量? (华为笔试题) 答案:只要基类在定义成员函数时已经声明了virtue关键字,在派生类实现的时候覆盖该函数时,virtual关键字可加可不加,不影响多态的实现。子类的空间里有父类的所有变量(static除外)。 2.main主函数执行完毕后,是否可能会再执行一段代码?(朗讯的一道笔试题) 答案:可以,可以用_onexit 注册一个函数,它会在main 之后执行; 如果你需要加入一段在main退出后执行的代码,可以使用atexit()函数,注册一个函数。 语法: #include <stdlib.h> int atexit(void (*function)(void)); #include <stdlib.h> #include <stdio.h> void fn1( void ), fn2( void ), fn3( void ), fn4( void ); int main( void ) { atexit( fn1 ); atexit( fn2 ); atexit( fn3 ); atexit( fn4 ); printf( "This is executed first./n" ); } void fn1() { printf( "next./n" ); } void fn2() { printf( "executed " ); } void fn3() { printf( "is " ); } void fn4() { printf( "This " ); } 结果: This is executed first. This is executed next. 3. 有双向循环链表结点:(华为面试题) typedef struct node { int date; struct node *front,*next; }_Node; 有两个双向循环链表A,B,知道其头指针为:pHeadA,pHeadB,请写一函数将两上链表中date值相同的结点删除 参考算法: 1.取出A的一个元素d 2.收集B中有相同元素d的结点到垃圾箱,并从B里删除 3.收集A中有相同元素d的结点到垃圾箱,并从A里删除 4.删除垃圾箱中的所有元素 5.A链的指针指向下一个 6.重复1~5,直到A链循环到头了 注意的是第3步,在2步执行后垃圾箱不为空时才执行。 上述算法还可以做一点点优化: 1.加入两个变量cA, cB,分别记录当前A中和B中的元素个数 每次从较长者中取出一个元素来,先从较小者中找起 若没有,则不必在较长者中浪费时间了 #include<iostream.h> ? struct NODE { int date; NODE *front,*next; }; void redel(NODE *&ahead,NODE *&bhead) { int boy=0; NODE *pa=ahead,*pb=bhead,*paa,*paaa,*paaaa,*pbb; while(pa->next!=ahead) { int boys=pa->date; //取pa中一个值 paaaa=pa; paa=pa; pb=bhead; while(pb->next!=bhead) { if(boys==pb->date) //如果pa,pb中有值相同 { cout<<endl; cout<<"delete B:"<<paa->date<<" "; if(pb==bhead) { boy=1; pb->front->next=pb->next; pb->next->front=pb->front; bhead=bhead->next; pbb=pb; pb=pb->next; delete pbb; } else { boy=1; pb->front->next=pb->next; pb->next->front=pb->front; pbb=pb; pb=pb->next; delete pbb; } } else pb=pb->next; } while(paa->next!=ahead && boy==1) { if(paa->date==boys) { cout<<"delete A:"<<paa->date<<" "; if(paa==pa) { pa=pa->next; ahead=pa; paa->front->next=paa->next; paa->next->front=paa->front; paaa=paa; paa=paa->next; delete paaa; } else { paa->front->next=paa->next; paa->next->front=paa->front; paaa=paa; paa=paa->next; delete paaa; } } else { paa=paa->next; } } boy=0; if(paaaa==pa) pa=pa->next; } cout<<endl; } int main() { NODE *A,*pHeadA,*B,*pHeadB; A=new NODE; B=new NODE; pHeadA=A; pHeadB=B; for(int i=1;i<21;++i) //生成链表A,并赋初值! { A->date=i; A->next=new NODE; A->next->front=A; A=A->next; } A=A->front; delete A->next; A->next=pHeadA; pHeadA->front=A; for(int i=1;i<33;i+=2) //生成链表B,并赋初值! { B->date=i; B->next=new NODE; B->next->front=B; B=B->next; } B=B->front; delete B->next; B->next=pHeadB; pHeadB->front=B; redel(pHeadA,pHeadB); //调用函数删除相同结点! } 4. C++里面如何声明const void f(void)函数为C程序中的库函数(华为) 11 下列哪两个是等同的 int b; A const int* a = &b; B const* int a = &b; C const int* const a = &b; D int const* const a = &b; 5. 把一个链表反向 填空 (lucent) void reverse(test* head) { test* pe = head; test* ps = head->next; while(ps) { pe->next = ps->next; ps->next = head; head = ps; ps = pe->next; } } 从第一个元素开始,ps指向他,将他(ps)指向头节点(ps->next = head),将ps设为头节点(head = ps;)操作下一个元素(ps = pe->next;)等于是依次将每个元素翻到原头节点前面。 【Sony笔试题】 25.完成下列程序 * *.*. *..*..*.. *...*...*...*... *....*....*....*....*.... *.....*.....*.....*.....*.....*..... *......*......*......*......*......*......*...... *.......*.......*.......*.......*.......*.......*.......*....... #include <stdio.h> #define N 8 int main() { int i; int j; int k; --------------------------------------------------------- | | | | | | --------------------------------------------------------- return 0; } 【北电】 昨天笔试共5道题目: 1.英译汉 ,关于ITU和CCITT的 2.汉译英,关于VMware的 3.两个有序数组的合并,写一个完整的程序 4.填空题,排序二叉树节点的删除,5个空 5.调试题,多线程文件的读写,编译没有错误,请找出至少三个bug. 翻译只占10分,后面三道每道30 1.实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数。 2.写一个函数,将其中的/t都转换成4个空格。 3.Windows程序的入口是哪里?写出Windows消息机制的流程。 4.如何定义和实现一个类的成员函数为回调函数? 5.C++里面是不是所有的动作都是main()引起的?如果不是,请举例。 6.C++里面如何声明const void f(void)函数为C程序中的库函数? 7.下列哪两个是等同的 int b; A const int* a = &b; B const* int a = &b; C const int* const a = &b; D int const* const a = &b; 8.内联函数在编译时是否做参数类型检查? void g(base & b){ b.play; } void main(){ son s; g(s); return; } 1,程序设计(可以用自然语言来描述,不编程):C/C++源代码中,检查花括弧(是"("与 ")","{"与"}")是否匹配,若不匹配,则输出不匹配花括弧所在的行与列。 2,巧排数字,将1,2,...,19,20这20个数字排成一排,使得相邻的两个数字之和为一个素数,且 首尾两数字之和也为一个素数。编程打印出所有的排法。 3,打印一个N*N的方阵,N为每边字符的个数( 3〈N〈20 ),要求最外层为"X",第二层为"Y",从第三层起每层依次打印数字0,1,2,3,... 例子:当N =5,打印出下面的图形: X X X X X X Y Y Y X X Y 0 Y X X Y Y Y X X X X X X 【普天】 C++最后几个大题目是 1.实现双向链表删除一个节点P,在节点P后插入一个节点,这两个函数。(北电重复) 2.写一个函数将其中的/t都转换成4个空格。 3.Windows程序的入口是哪里?写出windows消息机制的流程。 4.如何定义和实现一个类的成员函数为回调函数。 还有前面的几个: 1. class A{ int a; int b; } 问的是编译时的default constructor function的问题。 还有一个说,A有其他自己定义的构造函数,问是否还有default constructor function 还是什么来着,记不清乐。 2.C++里面是不是所有的动作都是main()引起的?如果不是,请举例。 3.C++里面如何声明const void f(void)函数为C库函数?(这个我前几天还看来着, 居然就忘记乐, ) 对了,还考乐一些关于const的问题 问下列哪两个是等同的 int b; A const int* a = &b; B const* int a = &b; C const int* const a = &b; D int const* const a = &b; 还有一个是考类的成员函数是 void f() const;型的时候调用的问题。 幸好昨天刚刚看乐这部分的内容,呵呵 内联函数考了一题,问内联函数在编译时是否做参数类型检查。 虚函数也考了一题,不过不难。 class base{ public: virtual void play(){ cout<<"base"; } } class son: public base{ public: void play(){cout<<"son";} } void g(base & b){ b.play; } void main(){ son s; g(s); return; } 【intel笔试题面试题】 【2005笔试 】 1.高效的内存管理 2.8皇后问题 【面试】 (2) 编译中的问题:全局变量如int i=5; int*(pf)()=foo; 分别在何时被初始化?设计时候如何具体的实现。 (3) OS相关的问题,内存访问,cache等(包括cache在整个系统中的位置,画出来,并解释) (4) 解释例如mov ax,100H 这样一条指令的cpu, os, memory等都完成了什么样的工作。 (5) Strlen()的C语言实现,不能使用任何变量。 (6) 编译中display表的一些问题 (7) 一个hash函数,输入随机,现发生冲突,如数据集中在某几条中,问怎样处理hash函数保证高效的访问,怎样实现? (8) 把Switch()case…语句翻译成三元组。 (9) 一个byte(用C语言实现计数其中1的个数),给出最高效的实现方法。(位域)或者查表最快的; (10) 上海有多少个加油站?你是怎样解决这一问题? (11) C语言参数的入栈顺序?为什么这么实现? (12) 你的最大的优点和缺点分别是什么? (13) C语言中字符串的翻转,最高效率(时间和空间)的实现? 【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 <string.h> #include <iostream> 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))^(b&(1<<i)))) i--; return (i^-1)?(((a>>i)&1)?1:-1):0; } int _tmain() { int c; c = Cmp(5,4); cout<<c<<endl; return 0; } #define COMPARE(a,b) ((a)-(b)) //<0: a<b =0:a==b>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)+length(b)-l1-l2-2; 2, 去掉a,b中的小数点,(a,b小数点后移,使a,b变为整数) 3, 计算c=a*b; (同整数的大数相乘算法) 4, 输出c,(注意在输出倒数第l个数时,输出一个小数点。若是输出的数少于l个,就补0) du51(郁郁思扬)的答案: 变为整数求就行了.输入的时候记一下,小数点位置..输出再做点文章就行了. 下面的是大整数的运算. #include<iostream> 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<<head->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<<endl; while(head) //释放空间 { p=head->next; delete head; head=p; } } int main() { cout<<"请输入两个数"<<endl; char test1[MAX],test2[MAX]; cin.getline(test1,MAX,'/n'); cin.getline(test2,MAX,'/n'); Mul(strrev(test1),strrev(test2)); system("PAUSE"); return 0; } 上面大整数已经写了.你加几个东西就行了. #include<iostream> 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<<head->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<<endl; while(head) //释放空间 { p=head->next; delete head; head=p; } } int main() { cout<<"请输入两个数"<<endl; char test1[MAX],test2[MAX],*p; int pos=0; cin.getline(test1,MAX,'/n'); cin.getline(test2,MAX,'/n'); if(p=strchr(test1,'.')) { pos+=strlen(test1)-(p-test1)-1; do { p++; *(p-1)=*p; }while(*p); } if(p=strchr(test2,'.')) { pos+=strlen(test2)-(p-test2)-1; do { p++; *(p-1)=*p; }while(*p); } Mul(strrev(test1),strrev(test2),pos); system("PAUSE"); return 0; } 4.写一个病毒 cout<<"一个病毒"<<endl; (开玩笑的,没搞过,^_^) 5.让你在100000000个浮点数中找出最大的10000个,要求时间复杂度优。 //本算法使用快排,O(n*lg(n)) //最低可以找到线性算法,使用预先区域统计划分!类试于构造Quad Trees! 写起来代码会长些! #include <stdio.h> #include <stdlib.h> #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:关键是时间最长的两个人必须同时过桥 Total Time Cost : (1+2)+(10+2)+2=17 minutes 1.请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句 2.如何输出源文件的标题和目前执行行的行数 3.两个数相乘,小数点后位数没有限制,请写一个高精度算法 4.写一个病毒 【微软】 智力题 1.烧一根不均匀的绳子,从头烧到尾总共需要1个小时,问如何用烧绳子的方法来确定半小时的时间呢? 2.10个海盗抢到了100颗宝石,每一颗都一样大小且价值连城。他们决定这么分: (1)抽签决定自己的号码(1~10); (2)首先,由1号提出分配方案,然后大家表决,当且仅当超过半数的人同意时,按照他的方案进行分配,否则将被扔进大海喂鲨鱼; (3)如果1号死后,再由2号提出分配方案,然后剩下的4个人进行表决,当且仅当超过半数的人同意时,按照他的方案进行分配,否则将被扔入大海喂鲨鱼; (4)依此类推…… 条件:每个海盗都是很聪明的人,都能很理智地做出判断,从而做出选择。 问题:第一个海盗提出怎样的分配方案才能使自己的收益最大化? 3.为什么下水道的盖子是圆的? 4.中国有多少辆汽车? 5.你让工人为你工作7天,回报是一根金条,这根金条平分成相连的7段,你必须在每天结束的时候给他们一段金条。如果只允许你两次把金条弄断,你如何给你的工人付费? 6.有一辆火车以每小时15公里的速度离开北京直奔广州,同时另一辆火车以每小时20公里的速度从广州开往北京。如果有一只鸟,以30公里每小时的速度和两辆火车同时启动,从北京出发,碰到另一辆车后就向相反的方向返回去飞,就这样依次在两辆火车之间来回地飞,直到两辆火车相遇。请问,这只鸟共飞行了多长的距离? 7.你有两个罐子以及50个红色弹球和50个蓝色弹球,随机选出一个罐子,随机选出一个弹球放入罐子,怎样给出红色弹球最大的选中机会?在你的计划里,得到红球的几率是多少? 8.想像你站在镜子前,请问,为什么镜子中的影像可以左右颠倒,却不能上下颠倒呢? 9.如果你有无穷多的水,一个3公升的提捅,一个5公升的提捅,两只提捅形状上下都不均匀,问你如何才能准确称出4公升的水? 10.你有一桶果冻,其中有黄色、绿色、红色三种,闭上眼睛抓取同种颜色的两个。抓取多少次就可以确定你肯定有两个同一颜色的果冻? 11.连续整数之和为1000的共有几组? 12.从同一地点出发的相同型号的飞机,可是每架飞机装满油只能绕地球飞半周,飞机之间可以加油,加完油的飞机必须回到起点。问至少要多少架次,才能满足有一架绕地球一周。 参考答案: 1.两边一起烧。 2.96,0,1,0,1,0,1,0,1,0。 3.因为口是圆的。 4.很多。 5.分1,2,4。 6.6/7北京到广州的距离。 7.100%。 8.平面镜成像原理(或者是“眼睛是左右长的”)。 9.3先装满,倒在5里,再把3装满,倒进5里。把5里的水倒掉,把3里剩下的水倒进5里,再把3装满,倒进5里,ok! 10.一次。 11.首先1000为一个解。连续数的平均值设为x,1000必须是x的整数倍。假如连续数的个数为偶数个,x就不是整数了。x的2倍只能是5,25,125才行。因为平均值为12.5,要连续80个达不到。125/262.5是可以的。即62,63,61,64,等等。连续数的个数为奇数时,平均值为整数。1000为平均值的奇数倍。10002×2×2×5×5×5;x可以为2,4,8,40,200排除后剩下40和200是可以的。所以答案为平均值为62.5,40,200,1000的4组整数。 12.答案是5架次。一般的解法可以分为如下两个部分: (1)直线飞行 一架飞机载满油飞行距离为1,n架飞机最远能飞多远?在不是兜圈没有迎头接应的情况,这问题就是n架飞机能飞多远?存在的极值问题是不要重复飞行,比如两架飞机同时给一架飞机加油且同时飞回来即可认为是重复,或者换句话说,离出发点越远,在飞的飞机就越少,这个极值条件是显然的,因为n架飞机带的油是一定的,如重复,则浪费的油就越多。比如最后肯定是只有一架飞机全程飞行,注意“全程”这两个字,也就是不要重复的极值条件。如果是两架飞机的话,肯定是一架给另一架加满油,并使剩下的油刚好能回去,就说第二架飞机带的油耗在3倍于从出发到加油的路程上,有三架飞机第三架带的油耗在5倍于从出发到其加油的路程上,所以n架飞机最远能飞行的距离为s1+1/3+…+1/(2n+1)这个级数是发散的,所以理论上只要飞机足够多最终可以使一架飞机飞到无穷远,当然实际上不可能一架飞机在飞行1/(2n+1)时间内同时给n1个飞机加油。 (2)可以迎头接应加油 一架飞机载满油飞行距离为1/2,最少几架飞机能飞行距离1?也是根据不要重复飞行的极值条件,得出最远处肯定是只有一架飞机飞行,这样得出由1/2处对称两边1/4肯定是一架飞机飞行,用上面的公式即可知道一边至少需要两架飞机支持,(1/3+1/5)/2>1/4(左边除以2是一架飞机飞行距离为1/2),但是有一点点剩余,所以想像为一个滑轮(中间一个飞机是个绳子,两边两架飞机是个棒)的话,可以滑动一点距离,就说加油地点可以在一定距离内变动(很容易算出来每架飞机的加油地点和加油数量,等等) 数学篇 1.1000!有几位数,为什么? 2.F(n) 1 n>8 n<12 F(n) 2 n<2 F(n) 3 n 6 F(n)4 n other 使用+ * /和sign(n)函数组合出F(n)函数 sign(n) 0 n 0 sign(n)1 n<0 sign(n) 1 n>0 3.编一个程序求质数的和,例如F(7) 1+3+5+7+11+13 +17 57。 逻辑推理题 1.此题源于1981年柏林的德国逻辑思考学院,98%的测验者无法解答此题。 有五间房屋排成一列;所有房屋的外表颜色都不一样;所有的屋主来自不同的国家;所有的屋主都养不同的宠物;喝不同的饮料;抽不同的香烟。 (1)英国人住在红色房屋里;(2)瑞典人养了一只狗;(3)丹麦人喝茶;(4)绿色的房子在白色的房子的左边;(5)绿色房屋的屋主喝咖啡;(6)吸Pall Mall香烟的屋主养鸟;(7)黄色屋主吸Dunhill香烟;(8)位于最中间的屋主喝牛奶;(9)挪威人住在第一间房屋里;(10)吸Blend香烟的人住在养猫人家的隔壁;(11)养马的屋主在吸Dunhill香烟的人家的隔壁;(12)吸Blue Master香烟的屋主喝啤酒;(13)德国人吸Prince香烟;(14)挪威人住在蓝色房子隔壁;(15)只喝开水的人住在吸Blend香烟的人的隔壁 问:谁养鱼? 提示:首先确定 房子颜色:红、黄、绿、白、蓝 Color 1 2 3 4 5 国籍:英、瑞、丹、挪、德=> Nationality 1 2 3 4 5 饮料:茶、咖、奶、酒、水=> Drink 1 2 3 4 5 烟:PM、DH、BM、PR、混=> Tobacco 1 2 3 4 5 宠物:狗、鸟、马、猫、鱼=> Pet 1 2 3 4 5 然后有: (9)=>N1=挪威 (14)=>C2=蓝 (4)=>如C3=绿,C4=白,则(8)和(5)矛盾,所以C4=绿,C5=白 剩下红黄只能为C1,C3 (1)=>C3=红,N3=英国,C1=黄 (8)=>D3=牛奶 (5)=>D4=咖啡 (7)=>T1=DH (11)=>P2=马 那么: 挪威 ? 英国 ? ? 黄 蓝 红 绿 白 ? ? 牛奶 咖啡 ? DH ? ? ? ? ? 马 ? ? ? (12)=>啤酒只能为D2或D5,BM只能为T2或T5=>D1=矿泉水 (3)=>茶只能为D2或D5,丹麦只能为N2或N5 (15)=>T2=混合烟=>BM=T5, 所以剩下啤酒=D5,茶=T2=>丹麦=D2 然后: 挪威 丹麦 英国 ? ? 黄 蓝 红 绿 白 矿泉水 茶 牛奶 咖啡 啤酒 DH 混合烟 ? ? BM ? 马 ? ? ? (13)=>德国=N4,PR=T4 所以,瑞典=N5,PM=T3 (2)=>狗=P5 (6)=>鸟=P3 (10)=>猫=P1 得到: 挪威 丹麦 英国 德国 瑞典 黄 蓝 红 绿 白 矿泉水 茶 牛奶 咖啡 啤酒 DH 混合烟 PM PR BM 猫 马 鸟 ? 狗 所以,最后剩下的鱼只能由德国人养了。 2. . . . . . . . . . 请仅用一笔画四根直线,将上图9个点全部连接。 3.对一批编号为1~100全部开关朝上(开)的灯进行以下操作: 凡是1的倍数反方向拨一次开关;2的倍数反方向又拨一次开关;3的倍数反方向又拨一次开关…… 问:最后为关熄状态的灯的编号。 微软招聘总经理助理的三道面试题 1.某手机厂家由于设计失误,有可能造成电池寿命比原来设计的寿命短一半(不是冲放电时间),解决方案就是更换电池或给50元购买该厂家新手机的折换券。请给所有已购买的用户写信告诉解决方案。 2.一高层领导在参观某博物馆时,向博物馆馆员小王要了一块明代的城砖作为纪念,按国家规定,任何人不得将博物馆收藏品变为私有。博物馆馆长需要如何写信给这位领导,将城砖取回? 3.王小姐由于工作失误,将2万元的笔记本电脑以1.2万元错卖给李先生,王小姐的经理应该怎么写信给李先生将钱要回? 英文面试题目 1. Algorithms * What’s the difference between a linked list and an array? * Implement an algorithm to sort a linked list. Why did you pick the method you did? * Implement an algorithm to sort an array. Why did you pick the method you did? * Implement strstr() (or some other string library function). * Reverse a string. Optimize for speed. Optimize for space. * Count the number of set bits in a number. Now optimize for speed. Now optimize for size. * How would you find a cycle in a linked list? * Give me an algorithm to shuffle a deck of cards, given that the cards are stored in an array of ints. *Write a function that takes in a string parameter and checks to seewhether or not it is an integer, and if it is then return the integervalue. * Write a function to print all of the permutations of a string. * Implement malloc. * Write a function to print the Fibonacci numbers. * Write a function to copy two strings, A and B. The last few bytes of string A overlap the first few bytes of string B. * How would you print out the data in a binary tree, level by level, starting at the top? 2. Applications *How can computer technology be integrated in an elevator system for ahundred story office building? How do you optimize for availability?How would variation of traffic over a typical work week or floor ortime of day affect this? * How would you redesign an ATM? * Suppose we wanted to run a microwave oven from the computer. What kind of software would you write to do this? * How would you design a coffee-machine for an automobile. 3. Thinkers * How are M&Ms made? * If you had to learn a new computer language, how would you go about doing it? * If MS told you we were willing to invest $5 million in a start up of your choice, what business would you start? Why? *If you could gather all of the computer manufacturers in the worldtogether into one room and then tell them one thing that they would becompelled to do,what would it be? * Explain a scenario for testing a salt shaker. * If you are going to receive an award in 5 years, what is it for and who is the audience? * How would you explain how to use Microsoft Excel to your grandma? *Why is it that when you turn on the hot water in any hotel, forexample, the hot water comes pouring out almost instantaneously? 微软亚洲技术支持中心面试题目 1.进程和线程的差别。 2.Heap与stack的差别。 3.Windows下的内存是如何管理的? 4.介绍.Net和.Net的安全性。 5.客户端如何访问.Net组件实现Web Service? 6.C/C++编译器中虚表是如何完成的? 7.谈谈COM的线程模型。然后讨论进程内/外组件的差别。 8.谈谈IA32下的分页机制。 9.给两个变量,如何找出一个带环单链表中是什么地方出现环的? 10.在IA32中一共有多少种办法从用户态跳到内核态? 11.如果只想让程序有一个实例运行,不能运行两个。像winamp一样,只能开一个窗口,怎样实现? 12.如何截取键盘的响应,让所有的‘a’变成‘b’? 13.Apartment在COM中有什么用?为什么要引入? 14.存储过程是什么?有什么用?有什么优点? 15.Template有什么特点?什么时候用? 16.谈谈Windows DNA结构的特点和优点。 微软研究院笔试题目 1.#include <stdio.h> #include <String.h> class CBuffer { char * m_pBuffer; int m_size; publc: CBuffer() { m_pBuffer=NULL; } ~CBuffer() { Free(); } void Allocte(int size) { 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()); } } 找出Allocate, SaveString, main的错误。 2.打印“Welcome MSR Asia” #include <stdio.h> #include <string.h> 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[1]=‘/0‘; } //copy “Welcome” to name name=“Welcome”; //Append a blank char name[8]=”; //Append string to name strcat(name,GetName()); //print out printf(name); } 找出程序中的错误。 3.#include <stdio.h> 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(); b.FuncB(); pa->FuncA(); pa->FuncB(); pa2->FuncA(); pa2->FuncB(); delete pa2; } What is the output of the above program? 4.#include <stdio.h> #include <string.h> 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); } In the main() function, after ModifyString(text) is called, what’s the value of ‘text’? 微创笔试题目(微创,微软在中国的合资公司) 1.上海的苏州河由于遭受多年的工业污染,一直是条臭水沟。上海市*下了很大决心清理苏州河,你觉得需要几年能让河水变清?你的依据是什么? 2.找出字符串A中包含的字符可以进行的所有不同组合。例如:abccd中,ab,ac,bc,cc,abd等都是可能的组合。(请用C/C++编程,不允许上机操作) 3.请估算月球的体积。 4.经常去的技术网站,请举例。 5.对软件开发过程的理解。 6.上海有多少外籍和港澳台人士?你的依据是什么?(不得引用*和调研机构数据) 7.字符串A是由n个小写英文字母(a ~ z)构成的,定义为char A[n]。你能用更少的空间表示这个字符串吗?请写出从char A[n]到你的新的储存格式的转换函数。(请用C/C++编程,不允许上机操作) 8.哈希表和数组的定义,区别,优缺点。 9.用递归实现菲波列数列。 10.用dhtml写页面。 11.一楼到十楼的每层电梯门口都放着一颗钻石,钻石大小不一。你乘坐电梯从一楼到十楼,每层楼电梯门都会打开一次,只能拿一次钻石,问怎样才能拿到最大的一颗? (去年应聘到微创的S小姐面试遇到的就是这道智力题。她的回答是:选择前五层楼都不拿,观察各层钻石的大小,做到心中有数。后五层楼再选择,选择大小接近前五层楼出现过最大钻石大小的钻石。她至今也不知道这道题的准确答案,“也许就没有准确答案,就是考一下你的思路,”她如是说。) 12.U2合唱团在17分钟内得赶到演唱会场,途中必需跨过一座桥,四个人从桥的同一端出发,你得帮助他们到达另一端,天色很暗,而他们只有一只手电筒。一次同时最多可以有两人一起过桥,而过桥的时候必须持有手电筒,所以就得有人把手电筒带来带去,来回桥两端。手电筒是不能用丢的方式来传递的。四个人的步行速度各不同,若两人同行则以较慢者的速度为准。Bono需花1分钟过桥,Edge需花2分钟过桥,Adam需花5分钟过桥,Larry需花10分钟过桥。他们要如何在17分钟内过桥呢?(有个同济的学生写文章说他当时在微软面试时就是碰到了这道题,最短只能做出在19分钟内过桥,微软的人对他讲这样的结果已经是不错的了!) 13.烧一根不均匀的绳要用一个小时,如何用它来判断半个小时?(参考答案:两边一起烧) 14.为什么下水道的盖子是圆的?(从复旦大学一位计算机系教授那里听来的答案:因为如果是方的、长方的或椭圆的,那无聊之徒拎起来它就可以直接扔进地下道啦!但圆形的盖子嘛,就可以避免这种情况了) 15.有7克、2克砝码各一个,天平一只,如何只用这些物品三次将140克的盐分成50、90克各一份? Intel笔试面试题目 智力题 1.每天中午从法国塞纳河畔的勒阿佛有一艘轮船驶往美国纽约,在同一时刻纽约也有一艘轮船驶往勒阿佛。已知横渡一次的时间是7天7夜,轮船匀速航行,在同一航线,轮船近距离可见。 请问今天中午从勒阿佛开出的船会遇到几艘从纽约来的船? 2.巴拿赫病故于1945年8月31日。他的出生年份恰好是他在世时某年年龄的平方,问:他是哪年出生的? 答案: 设他在世时某年年龄为x,则x的平方<1945,且x为自然数。其出生年份x的平方xx(x1),他在世年龄1945x(x1)。1945的平方根44.1,则x应为44或略小于此的数。而x44时,x(x1)44×431892,算得其在世年龄为1945189253;又x43时,x(x1)43×421806,得其在世年龄为19451806139;若x再取小,其在世年龄越大,显然不妥。故x44,即他出生于1892年,终年53岁。 3. (图形描述:一个各边相等的十字图案) 上图中各边相等,要求:用最少的分割,拼成一个正方形。 笔试题目 1.设计一个重采样系统,说明如何anti-alias。 2.y1(n)x(2n),y2(n)x(n/2),问: 如果y1为周期函数,那么x是否为周期函数? 如果x为周期函数,那么y1是否为周期函数? 如果y2为周期函数,那么x是否为周期函数? 如果x为周期函数,那么y2是否为周期函数? 3.如果模拟信号的带宽为5kHz,要用8k的采样率,怎么办。 4.某个程序在一个嵌入式系统(200M的CPU,50M的SDRAM)中已经最优化了,换到另一个系统(300M的CPU,50M的SDRAM)中运行,还需要优化吗? 5.x^4+a*x^3+x^2+c*x+d最少需要做几次乘法。 6.三个float:a,b,c 问值: (a+b)+c(b+a)+c (a+b)+c(a+c)+b 7.把一个链表反向填空。 8.下面哪种排序法对12354最快? 。 A. quick sort B. buble sort C. merge sort 9.哪种结构平均来讲获取一个值最快? 。 A. binary tree B. hash table C. stack 10. #include “stdafx.h” #include <iostream.h> struct bit { int a:3; int b:2; int c:3; }; int main(int argc, char* argv[]) { bit s; char *c = (char*)&s; *c = 0x99; cout << s.a <<endl <<s.b<<endl<<s.c<<endl; return 0; } Output:? 11. 挑bug,在linux下运行: #include <stdio.h> char *reverse(char* str) { int len=0, i=0; char *pstr=str, *ptemp,*pd; while(*++pstr) len++; pstr--; //ptemp=(char*)malloc(len+1); ptemp=(char*)malloc(len+1); pd=ptemp; while(len--){ *ptemp=*pstr; ptemp++; pstr--; i++; } *ptemp=*pstr; ptemp++; *ptemp=‘/0’; return pd; } main() { char string[40]= “Hello World!”; char *pstr=string; printf(“%s”, pstr); printf(“%s”, reverse(pstr)); } 1.写出下列信号的奈亏斯特频率 (1)f(t)1cos(2000pait)sin(4000pait) (2)f(t)sin(4000pait)/pait (3)f(t)(sin(4000pait)的平方)/pait 2.有两个线程 void producer() { while(1) { GeneratePacket(); PutPacketIntoBuffer(); Signal(customer); } } void customer() { while(1) { WaitForSignal(); if(PacketInBuffer>10) { ReadAllPackets(); ProcessPackets(); } } } (1)有没有其他方法可以提高程序的性能 (2)可不可以不使用信号之类的机制来实现上述的功能 3.优化下面的程序 (0)sum0 (1)I1 (2)T14*I (3)T2address(A)4 (4)T3T2[T1] (5)T4address(B)4 (6)T54*I (7)T6T4[T5] (8)T7T3*T5 (9)sumsum+T6 (10)II+1 (11)IF I<20 GOTO (2) 面试题目 1.下面这段代码不符合Pipeline要求,请你改动一下 if(a>b) i0; else i1; 2.对于运行在ring3上的这个指令,请你指出CPU和操作系统分别参与了哪部分操作? mov eax, [0x12345678] 3.如果有一个芯片,只是裸机,如何写它的操作系统?最难的部分在哪儿?如何解决? 4.如何写一个主板的BIOS? 5.没有操作系统来给你完成它的一些初始化工作,如何写出PCI的driver? Intel 2004北京笔试题 问答题 1.你觉得C程序中为什么会有main(),有没有想过exit,return,或什么都不做也可以让程序正常终止? 2.TOTAL个人围一圈,从1开始数到N,谁数到N出圈,下一个人继续从1开始数,返回最后一个出局的人。 #define TOTAL 15; int xxxx(int N) { int ring[TOTAL] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1} //全是1 int nextstart = 0, counter=0; for (i =1; i<TOTAL; i++){ counter = 0; while(counter <N) { if (_______________) ( ;) else (____________;) } ring[nextstart]=0 } return nextstart +1; } 3.列举Intel四种架构 4.概率题 (1)x, y为随机变量,联合概率密度f(x,y) intig(0,1)* dx*intig(0,x)*k*dy,k为常数,求k? E(xy) ? 注:intig(a,b)为a到b的定积分。 (2)A,B为随机事件,以下哪个正确。 A.P(A U B)*p(AB) < P(A)P(B) B.P(A U B)*p(AB) > P(A)P(B) C.P(A U B)*p(AB) < P(A) + P(B) D.P(A U B)*p(AB) > P(A) + P(B) 5.信道带宽200kHz,信噪比10dB,求信道波特率? 6.以下代码运行结果是 。 int main() { int a,b,c,abc = 0; a=b=c=40; if(c) { int abc; abc = a*b+c; } printf(“%d,%d”, abc, c); return 0; } 7.给出了从纽约出发和到达洛杉机的各种航班信息,写出找到一条从纽约到洛杉机的最短距离的航班组合的代码。 8.从计算机图形上截取某个物体边缘的若干个坐标,求这个物体的面积,并判断是方形还是圆形,说明原因。 9.离散卷机与DFT的区别与关系。快速求出不满足2^N长度的离散傅立叶变换的方法有哪些?如何用fft求N*M点的离散卷机? 10.给出fir和iir的优缺点。 11.如何计算线性标量量化器的量化噪声?需要哪些假设? IBM IBM笔试题目 字母矩阵题目(15分钟) 给你一个矩阵: (一) (二) (三) (四) (五) 1 a b c d e 2 b c a e d 3 c b e a d 4 c e d b a 5 e d a c b 回答以下问题。 (1)将第一行和第四行交换后,第一行第四个字母下面的左边的下面的右边的字母是 。(简单) (2)将所有出现在d左边的字母从矩阵中删掉。将所有出现在a左边的c字母从矩阵中删掉。如果矩阵中剩下的字母的种类的数目大于3,答案为原矩阵中左上方至右下方对角线上出现两次的字母。如果矩阵中剩下的字母的种类的数目小于或者等于3,答案为原矩阵中右上至左下对角线上出现4次的字母是 。 (3)将所有的a用4替换,所有的d用2替换,哪一列的总和最大 ①第1列 ②第2列 ③第3列 ④第4列 ⑤第五列 (4)从左上角的字母开始,顺时针沿矩阵外围,第4次出现的字母是。 ①a ②b ③c ④d ⑤e (5)沿第5列从上到下,接着沿第3列从下到上,接着沿第4列从上到下,接着沿第1列从下到上,接着沿第2列从上到下,第1个出现5次的字母是 。 ①a ②b ③c ④d ⑤e (6)从左上角的字母开始,顺时针沿矩阵外围,第4次出现的字母是以下哪个。 ①a ②b ③c ④d ⑤e 智力题 1.有50家人家,每家一条狗。有一天警察通知,50条狗当中有病狗,行为和正常狗不一样。每人只能通过观察别人家的狗来判断自己家的狗是否生病,而不能看自己家的狗,如果判断出自己家的狗病了,就必须当天一枪打死自己家的狗。结果,第一天没有枪声,第二天没有枪声,第三天开始一阵枪响,问:一共死了几条狗? 1.死了3条(第几天枪响就有几条)。 简单分析:从有一条不正常的狗开始,显然第一天将会听到一声枪响。这里的要点是你只需站在那条不正常狗的主人的角度考虑。 有两条的话思路继续,只考虑有两条不正常狗的人,其余人无需考虑。通过第一天他们了解了对方的信息。第二天杀死自己的狗。换句话说每个人需要一天的时间证明自己的狗是正常的。有三条的话,同样只考虑那三个人,其中每一个人需要两天的时间证明自己的狗是正常的狗。 2.已知两个数字为1~30之间的数字,甲知道两数之和,乙知道两数之积,甲问乙:“你知道是哪两个数吗?”乙说:“不知道”。乙问甲:“你知道是哪两个数吗?”甲说:“也不知道”。于是,乙说:“那我知道了”,随后甲也说:“那我也知道了”,这两个数是什么? 2.1和4,或者4和7。 3.一个经理有三个女儿,三个女儿的年龄加起来等于13,三个女儿的年龄乘起来等于经理自己的年龄。有一个下属已知道经理的年龄,但仍不能确定经理的三个女儿的年龄,这时经理说只有一个女儿的头发是黑的,然后这个下属就知道了经理的三个女儿的年龄。请问三个女儿的年龄分别是多少?为什么? 3答案:分别是2,2,9。 ??? 简单分析: 1 1 11 11 伪穷举,呵呵 1 2 10 20 1 3 9 27 1 4 8 32 1 5 7 35 1 6 6 36 2 2 9 36在所有的可能性中,只有这两个相同,如果经理的年龄为其他,则他下属就可以确定 三个人分别为几岁了,所以只有两种可能:1,6,6或者2,2,9。如果是1,6,6的话,那么两个同样大的6岁的孩子应该都是黑头发, 所以只有2,2,9比较合理,大的那个是黑头发,另外两个是黄毛丫头 2 3 8 40 2 4 7 56 2 5 6 60 3 3 7 42 3 4 6 72 3 5 5 75 4 4 5 80 VC/C++的面试题 1、估计一下广州有多少理发师,如果允许,你还需要那些调研工作?并给出你的推导过程。你认为你的 估算结果可信吗? 2、看过那些软件方面的书籍 3、什么是软件,软件开发包括那些步骤,并说出你对这些步骤的理解 4、OSI网络结构的七层模型分别是什么,并说出你认为划分为7层的理由。 5、软件过程中了解、使用过版本控制或建模工具吗?对你工作有什么帮助? 6、软件过程中你都写过什么文档?分别是什么目的及其对你的帮助? 7、我们知道,C++将内存划分为三个逻辑区域:堆、栈和静态存储,请说出它们的区别及你的理解。 8、字符串A是由n个小写英文字母(a ~ z)构成的,定义为char A[n]。你能用更少的空间表示这个字符串吗?请写出从char A[n]到你的新的储存格式的转换函数。(请用C/C++编程,不允许上机操作)(数据结构) 12、对现在的Stack(栈)数据结构进行改进,加一个min()功能,使之能在常数,即O(1),时间内给出栈中的最小值。可对push()和pop()函数进行修改,但要求其时间复杂度都只能是O(1)。(数据结构) 9、C++构造函数为什么不能是虚函数? 10、C++中virtual与inline的含义分别是什么?虚函数的特点;内联函数的特点;一个函数能否即是虚函数又是内联函数? 12、请列出实现C++代码你认为需要注意的一些问题。 11、你在原来的项目中有没有遇到什么困难,又是如何解决的? 1 dll,lib处理实现 .lib文件中包含什么? dll在内存中被多个函数共享,有几个拷贝? ▲? 2 template,template等编译的时候作为几个类▲? 3 struct ,class的区别,联系 4 MAcro,inline区别,实现.编译运行时▲? 5 进程与线程区别 6 hdc-cdc区别联系▲? 7 model dialog,modeless dialog,从创建到销毁全过程具体描述 8 各个线程new的内存,别的线程是否可以使用? 9 RUNTIME_CLASS, is what?? http://www.sinoprise.com/simple/index.php?t32.html 1. 堆和栈的区别? 栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 堆区(heap) - 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。 2. 虚函数的本质和实现机制? 虚函数的本质就是通过基类访问派生类定义的函数。虚函数只能借助于指针或者引用来达到多态的效果。 3. C++中传递函数参数的方式及他们的优缺点? 4. static关键字的作用?▲ 5. 引用和指针的区别? 6. 函数重载和覆盖的区别? 7. 深拷贝和浅拷贝的区别? 8. 数组a[4][3]的内存结构?并指出a[2][3]和a[3][2]在内存中的位置?▲▲▲? 9. 包含和私有继承的区别?▲? 10. 实现一个操作栈的模板(empty,push,pop,),并实现错误处理(对空栈的pop) 11. ANSI和Unicode的区别?并指出C RunTime Library 和 Win32 API对他们的支持。 12. 线程同步的四种方式的机制。▲▲▲? 13. 虚拟内存。▲▲▲? 14. DLL的实现机制和DLL的输出方式。▲▲▲? 15. D3D的顶点着色。? 16. 几种数据结构在游戏中的支持。? 17. 游戏引擎? 服务器程序员笔试题 C++ 1.简述堆和栈的区别。 2.简述虚函数的本质和实现机制。 3.列举C++中向函数传递参数的各种方式,并比较它们之间的区别和优缺点。 4.static关键字有几种用途?请简述每种用途。 5.简述引用和指针的异同。 6.简述函数重载(overloading)和覆盖(overriding)的区别。 7.什么是深拷贝?什么是浅拷贝? 8.请画出二维数组char a[4][3]的内存结构图,并指出a[3][2]和a[2][3]在内存中的位置。 9.简述包含和私有继承的异同。 10.用模板实现一个通用的栈,要求实现empty, size, push, pop, top五个成员函数,并用异常机制来报告错误(比如在一个大小为0的栈上执行pop操作)。▲▲▲? 标准库 11.用string类编写一个程序,它从标准输入接收一行输入,然后统计出其中单词的个数,单词的分隔符只有逗号、点号和空格三种。 12.简述STL的容器container、迭代器iterator、算法algorithm和函数器functor的作用以及它们之间的关系,举例说明。▲▲▲? 13.下面的代码存在什么问题,如何修正?▲▲? list list1; for (int i = 0; i < 8; i ++) { list1.push_back(i); } for (list::iterator it = list1.begin(); it != list1.end(); ++it) { if (*it % 2 == 0) { list1.erase(it); } } Win32 14.比较ANSI和Unicode的区别,并说明C Runtime Library和Win32 API如何支持二者▲▲▲? 15.简述线程同步的四种机制。 16.简述虚拟内存机制,并描述在win95和winnt下内存空间的结构。 17.简述DLL的实现机制以及输出DLL中函数的两种方法。 网络 18.简述TCP和UDP之间的区别。 19.简述Winsock的六种主要IO处理模式。 20.描述一个你以前实现过的服务器的结构图,并分析其中可能存在的瓶颈。 16. 关联、聚合(Aggregation)以及组合(Composition)的区别? 涉及到UML中的一些概念:关联是表示两个类的一般性联系,比如“学生”和“老师”就是一种关联关系;聚合表示has-a的关系,是一种相对松散的关系,聚合类不需要对被聚合类负责,如下图所示,用空的菱形表示聚合关系: 从实现的角度讲,聚合可以表示为: class A {...} class B { A* a; .....} 而组合表示contains-a的关系,关联性强于聚合:组合类与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表示组合关系: 实现的形式是: class A{...} class B{ A a; ...} 参考文章:http://www.cnitblog.com/Lily/archive/2006/02/23/6860.html http://www.vckbase.com/document/viewdoc/?id=422 17.面向对象的三个基本特征,并简单叙述之? 1. 封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private, protected,public) 2.继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=>接口继承以及纯虚函数)构成了功能复用的两种方式。 3. 多态:是将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。 18. 重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别? 常考的题目。从定义上来说: 重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。 重写:是指子类重新定义复类虚函数的方法。 从实现原理上来说: 重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func(p:integer):integer;和functionfunc(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关! 重写:和多态真正相关。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)。 19. 多态的作用? 主要是两个:1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。 20. Ado与Ado.net的相同与不同? 除了“能够让应用程序处理存储于DBMS中的数据“这一基本相似点外,两者没有太多共同之处。但是Ado使用OLE DB 接口并基于微软的COM 技术,而ADO.NET拥有自己的ADO.NET 接口并且基于微软的.NET 体系架构。众所周知.NET 体系不同于COM 体系,ADO.NET接口也就完全不同于ADO和OLE DB 接口,这也就是说ADO.NET 和ADO是两种数据访问方式。ADO.net 提供对XML 的支持。 21. New delete 与malloc free 的联系与区别? 答案:都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数。delete 会调用对象的destructor,而free 不会调用对象的destructor. 22. #define DOUBLE(x) x+x ,i = 5*DOUBLE(5); i 是多少? 答案:i 为30。 23. 有哪几种情况只能用intialization list 而不能用assignment? 答案:当类中含有const、reference 成员变量;基类的构造函数都需要初始化表。 24. C++是不是类型安全的? 答案:不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。C#是类型安全的。 25. main 函数执行以前,还会执行什么代码? 答案:全局对象的构造函数会在main 函数之前执行。 26. 描述内存分配方式以及它们的区别? 1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。 2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。 3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。 27.struct 和 class 的区别 答案:struct 的成员默认是公有的,而类的成员默认是私有的。struct 和 class 在其他方面是功能相当的。 从感情上讲,大多数的开发者感到类和结构有很大的差别。感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位,而类就象活的并且可靠的社会成员,它有智能服务,有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为,那么只有在你的类有很少的方法并且有公有数据(这种事情在良好设计的系统中是存在的!)时,你也许应该使用 struct 关键字,否则,你应该使用 class关键字。 28.当一个类A 中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。(Autodesk) 答案:肯定不是零。举个反例,如果是零的话,声明一个class A[10]对象数组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]…了。 29. 在8086 汇编下,逻辑地址和物理地址是怎样转换的?(Intel) 答案:通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址*10H+通用寄存器内地址,就得到了真正要访问的地址。 30. 比较C++中的4种类型转换方式? 请参考:http://blog.bioon.com/user1/8688/archives/2006/45399.shtml,重点是static_cast, dynamic_cast和reinterpret_cast的区别和应用。 [C/C++] C/C++ 笔试、面试题目大汇总[31-40] bioeconomy 发表于 2006-3-22 17:49:00 31.分别写出BOOL,int,float,指针类型的变量a 与“零”的比较语句。 答案: BOOL : if ( !a ) or if(a) int : if ( a == 0) float : const EXPRESSION EXP = 0.000001 if ( a < EXP && a >-EXP) pointer : if ( a != NULL) or if(a == NULL) 32.请说出const与#define 相比,有何优点? 答案:1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。 2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。 33.简述数组与指针的区别? 数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。 (1)修改内容上的差别 char a[] = “hello”; a[0] = 'X’; char *p = “world”; // 注意p 指向常量字符串 p[0] = 'X’; // 编译器不能发现该错误,运行时错误 (2) 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。 char a[] = "hello world"; char *p = a; cout<< sizeof(a) << endl; // 12 字节 cout<< sizeof(p) << endl; // 4 字节 计算数组和指针的内存容量 void Func(char a[100]) { cout<< sizeof(a) << endl; // 4 字节而不是100 字节 } 34.类成员函数的重载、覆盖和隐藏区别? 答案: a.成员函数被重载的特征: (1)相同的范围(在同一个类中); (2)函数名字相同; (3)参数不同; (4)virtual 关键字可有可无。 b.覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类); (2)函数名字相同; (3)参数相同; (4)基类函数必须有virtual 关键字。 c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下: (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。 (2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆) 35. There are two int variables: a and b,don’t use “if”, “? :”, “switch”or other judgement statements, find outthe biggest one of the two numbers. 答案:( ( a + b ) + abs( a - b ) ) / 2 36. 如何打印出当前源文件的文件名以及源文件的当前行号? 答案: cout << __FILE__ ; cout<<__LINE__ ; __FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。 37. main 主函数执行完毕后,是否可能会再执行一段代码,给出说明? 答案:可以,可以用_onexit 注册一个函数,它会在main 之后执行int fn1(void), fn2(void), fn3(void), fn4 (void); void main( void ) { String str("zhanglin"); _onexit( fn1 ); _onexit( fn2 ); _onexit( fn3 ); _onexit( fn4 ); printf( "This is executed first./n" ); } int fn1() { printf( "next./n" ); return 0; } int fn2() { printf( "executed " ); return 0; } int fn3() { printf( "is " ); return 0; } int fn4() { printf( "This " ); return 0; } The _onexit function is passed the addressof a function (func) to be called when the program terminates normally.Successive calls to _onexit create a register of functions that areexecuted in LIFO (last-in-first-out) order. The functions passed to_onexit cannot take parameters. 38. 如何判断一段程序是由C 编译程序还是由C++编译程序编译的? 答案: #ifdef __cplusplus cout<<"c++"; #else cout<<"c"; #endif 39.文件中有一组整数,要求排序后输出到另一个文件中 答案: #i nclude #i nclude using namespace std; void Order(vector& data) //bubble sort { int count = data.size() ; int tag = false ; // 设置是否需要继续冒泡的标志位 for ( int i = 0 ; i < count ; i++) { for ( int j = 0 ; j < count - i - 1 ; j++) { if ( data[j] > data[j+1]) { tag = true ; int temp = data[j] ; data[j] = data[j+1] ; data[j+1] = temp ; } } if ( !tag ) break ; } } void main( void ) { vectordata; ifstream in("c://data.txt"); if ( !in) { cout<<"file error!"; exit(1); } int temp; while (!in.eof()) { in>>temp; data.push_back(temp); } in.close(); //关闭输入文件流 Order(data); ofstream out("c://result.txt"); if ( !out) { cout<<"file error!"; exit(1); } for ( i = 0 ; i < data.size() ; i++) out<<DATA[I]<<" ?; 40. 链表题:一个链表的结点结构 struct Node { int data ; Node *next ; }; typedef struct Node Node ; (1)已知链表的头结点head,写一个函数把这个链表逆序 ( Intel) Node * ReverseList(Node *head) //链表逆序 { if ( head == NULL || head->next == NULL ) return head; Node *p1 = head ; Node *p2 = p1->next ; Node *p3 = p2->next ; p1->next = NULL ; while ( p3 != NULL ) { p2->next = p1 ; p1 = p2 ; p2 = p3 ; p3 = p3->next ; } p2->next = p1 ; head = p2 ; return head ; } (2)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序。(保留所有结点,即便大小相同) Node * Merge(Node *head1 , Node *head2) { if ( head1 == NULL) return head2 ; if ( head2 == NULL) return head1 ; Node *head = NULL ; Node *p1 = NULL; Node *p2 = NULL; if ( head1->data < head2->data ) { head = head1 ; p1 = head1->next; p2 = head2 ; } else { head = head2 ; p2 = head2->next ; p1 = head1 ; } Node *pcurrent = head ; while ( p1 != NULL && p2 != NULL) { if ( p1->data <= p2->data ) { pcurrent->next = p1 ; pcurrent = p1 ; p1 = p1->next ; } else { pcurrent->next = p2 ; pcurrent = p2 ; p2 = p2->next ; } } if ( p1 != NULL ) pcurrent->next = p1 ; if ( p2 != NULL ) pcurrent->next = p2 ; return head ; } (3)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。 (Autodesk) 答案: Node * MergeRecursive(Node *head1 , Node *head2) { if ( head1 == NULL ) return head2 ; if ( head2 == NULL) return head1 ; Node *head = NULL ; if ( head1->data < head2->data ) { head = head1 ; head->next = MergeRecursive(head1->next,head2); } else { head = head2 ; head->next = MergeRecursive(head1,head2->next); } return head ; } [C/C++] C/C++ 笔试、面试题目大汇总[41-45] bioeconomy 发表于 2006-3-22 20:28:00 41. 分析一下这段程序的输出 (Autodesk) class B { public: B() { cout<<"default constructor"<<ENDL; } ~B() { cout<<"destructed"<<ENDL; } B(int i):data(i) //B(int) works as a converter ( int -> instance of B) { cout<<"constructed by parameter " << data <<ENDL; } private: int data; }; B Play( B b) { return b ; } (1) results: int main(int argc, char* argv[]) constructed by parameter 5 { destructed B(5)形参析构 B t1 = Play(5); B t2 = Play(t1); destructed t1形参析构 return 0; destructed t2 注意顺序! } destructed t1 (2) results: int main(int argc, char* argv[]) constructed by parameter 5 { destructed B(5)形参析构 B t1 = Play(5); B t2 = Play(10); constructed by parameter 10 return 0; destructed B(10)形参析构 } destructed t2 注意顺序! destructed t1 42. 写一个函数找出一个整数数组中,第二大的数 (microsoft) 答案: const int MINNUMBER = -32767 ; int find_sec_max( int data[] , int count) { int maxnumber = data[0] ; int sec_max = MINNUMBER ; for ( int i = 1 ; i < count ; i++) { if ( data[i] > maxnumber ) { sec_max = maxnumber ; maxnumber = data[i] ; } else { if ( data[i] > sec_max ) sec_max = data[i] ; } } return sec_max ; } 43. 写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数。 KMP算法效率最好,时间复杂度是O(n+m),详见:http://www.zhanglihai.com/blog/c_335_kmp.html 44. 多重继承的内存分配问题: 比如有class A : public class B, public class C {} 那么A的内存结构大致是怎么样的? 这个是compiler-dependent的, 不同的实现其细节可能不同。 如果不考虑有虚函数、虚继承的话就相当简单;否则的话,相当复杂。 可以参考《深入探索C++对象模型》,或者: http://blog.csdn.net/rainlight/archive/2006/03/03/614792.aspx http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnarvc/html/http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnarvc/html/jangrayhood.asp 45. 如何判断一个单链表是有环的?(注意不能用标志位,最多只能用两个额外指针) struct node { char val; node* next;} bool check(const node* head) {} //return false : 无环;true: 有环 一种O(n)的办法就是(搞两个指针,一个每次递增一步,一个每次递增两步,如果有环的话两者必然重合,反之亦然): bool check(const node* head) { if(head==NULL) return false; node *low=head, *fast=head->next; while(fast!=NULL && fast->next!=NULL) { low=low->next; fast=fast->next->next; if(low==fast) return true; } return false; } 一、请填写BOOL , float, 指针变量 与“零值”比较的 if 语句。(10分) 提示:这里“零值”可以是0, 0.0 , FALSE或者“空指针”。例如 int 变量 n 与“零值”比较的 if 语句为: if ( n == 0 ) if ( n != 0 ) 以此类推。 请写出 BOOL flag 与“零值”比较的 if 语句: 请写出 float x 与“零值”比较的 if 语句: 请写出 char *p 与“零值”比较的 if 语句: 二、以下为Windows NT下的32位C++程序,请计算sizeof的值(10分) char str[] = “Hello” ; char *p = str ; int n = 10; 请计算 sizeof (str ) = sizeof ( p ) = sizeof ( n ) = void Func ( char str[100]) { 请计算 sizeof( str ) = } void *p = malloc( 100 ); 请计算 sizeof ( p ) = 三、简答题(25分) 1、头文件中的 ifndef/define/endif 干什么用? 2、#include 和 #include “filename.h” 有什么区别? 3、const 有什么用途?(请至少说明两种) 4、在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”声明? 5、请简述以下两个for循环的优缺点 // 第一个 for (i=0; i { if (condition) DoSomething(); else DoOtherthing(); } // 第二个 if (condition) { for (i=0; i DoSomething(); } else { for (i=0; i DoOtherthing(); } 优点: 缺点: 优点: 缺点: 四、有关内存的思考题(20分) void GetMemory(char *p) { p = (char *)malloc(100); } void Test(void) { char *str = NULL; GetMemory(str); strcpy(str, "hello world"); printf(str); } 请问运行Test函数会有什么样的结果? 答: char *GetMemory(void) { char p[] = "hello world"; return p; } void Test(void) { char *str = NULL; str = GetMemory(); printf(str); } 请问运行Test函数会有什么样的结果? 答: Void GetMemory2(char **p, int num) { *p = (char *)malloc(num); } void Test(void) { char *str = NULL; GetMemory(&str, 100); strcpy(str, "hello"); printf(str); } 请问运行Test函数会有什么样的结果? 答: void Test(void) { char *str = (char *) malloc(100); strcpy(str, “hello”); free(str); if(str != NULL) { strcpy(str, “world”); printf(str); } } 请问运行Test函数会有什么样的结果? 答: 五、编写strcpy函数(10分) 已知strcpy函数的原型是 char *strcpy(char *strDest, const char *strSrc); 其中strDest是目的字符串,strSrc是源字符串。 (1)不调用C++/C的字符串库函数,请编写函数 strcpy (2)strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值? 六、编写类String的构造函数、析构函数和赋值函数(25分) 已知类String的原型为: class String { public: String(const char *str = NULL); // 普通构造函数 String(const String &other); // 拷贝构造函数 ~ String(void); // 析构函数 String & operate =(const String &other); // 赋值函数 private: char *m_data; // 用于保存字符串 }; 请编写String的上述4个函数。 以上题目摘自林锐博士的《高质量C++编程指南》。大家可以去看这本书作为参考 C++面试汇总1 2007年12月29日 星期六 08:57 P.M. 1.是不是一个父类写了一个virtual 函数,如果子类覆盖它的函数不加virtual ,也能实现多态? virtual修饰符会被隐形继承的。 private 也被集成,只事派生类没有访问权限而已 virtual可加可不加 子类的空间里有父类的所有变量(static除外) 同一个函数只存在一个实体(inline除外) 子类覆盖它的函数不加virtual ,也能实现多态。 在子类的空间里,有父类的私有变量。私有变量不能直接访问。 -------------------------------------------------------------------------- 2.输入一个字符串,将其逆序后输出。(使用C++,不建议用伪码) #include <iostream> using namespace std; void main() { char a[50];memset(a,0,sizeof(a)); int i=0,j; char t; cin.getline(a,50,'/n'); for(i=0,j=strlen(a)-1;i<strlen(a)/2;i++,j--) { t=a[i]; a[i]=a[j]; a[j]=t; } cout<<a<<endl; } //第二种 string str; cin>>str; str.replace; cout<<str; -------------------------------------------------------------------------- 3.请简单描述Windows内存管理的方法。 内存管理是操作系统中的重要部分,两三句话恐怕谁也说不清楚吧~~ 我先说个大概,希望能够抛砖引玉吧 当程序运行时需要从内存中读出这段程序的代码。代码的位置必须在物理内存中才能被运行,由于现在的操作系统中有非常多的程序运行着,内存中不能够完全放下,所以引出了虚拟内存的概念。把哪些不常用的程序片断就放入虚拟内存,当需要用到它的时候在load入主存(物理内存)中。这个就是内存管理所要做的事。内存管理还有另外一件事需要做:计算程序片段在主存中的物理位置,以便CPU调度。 内存管理有块式管理,页式管理,段式和段页式管理。现在常用段页式管理 块式管理:把主存分为一大块、一大块的,当所需的程序片断不在主存时就分配一块主存空间,把程 序片断load入主存,就算所需的程序片度只有几个字节也只能把这一块分配给它。这样会造成很大的浪费,平均浪费了50%的内存空间,但时易于管理。 页式管理:把主存分为一页一页的,每一页的空间要比一块一块的空间小很多,显然这种方法的空间利用率要比块式管理高很多。 段式管理:把主存分为一段一段的,每一段的空间又要比一页一页的空间小很多,这种方法在空间利用率上又比页式管理高很多,但是也有另外一个缺点。一个程序片断可能会被分为几十段,这样很多时间就会被浪费在计算每一段的物理地址上(计算机最耗时间的大家都知道是I/O吧)。 段页式管理:结合了段式管理和页式管理的优点。把主存分为若干页,每一页又分为若干段。好处就很明显,不用我多说了吧。 各种内存管理都有它自己的方法来计算出程序片断在主存中的物理地址,其实都很相似。 这只是一个大概而已,不足以说明内存管理的皮毛。无论哪一本操作系统书上都有详细的讲解 -------------------------------------------------------------------------- 4. #include "stdafx.h" #define SQR(X) X*X int main(int argc, char* argv[]) { int a = 10; int k = 2; int m = 1; a /= SQR(k+m)/SQR(k+m); printf("%d/n",a); return 0; } 这道题目的结果是什么啊? define 只是定义而已,在编择时只是简单代换X*X而已,并不经过算术法则的 a /= (k+m)*(k+m)/(k+m)*(k+m); =>a /= (k+m)*1*(k+m); =>a = a/9; =>a = 1; -------------------------------------------------------------------------- 5. const 符号常量; (1)const char *p (2)char const *p (3)char * const p 说明上面三种描述的区别; 如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量; 如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。 (1)const char *p 一个指向char类型的const对象指针,p不是常量,我们可以修改p的值,使其指向不同的char,但是不能改变它指向非char对象,如: const char *p; char c1='a'; char c2='b'; p=&c1;//ok p=&c2;//ok *p=c1;//error (2)char const *p (3)char * const p 这两个好象是一样的,此时*p可以修改,而p不能修改。 (4)const char * const p 这种是地址及指向对象都不能修改。 -------------------------------------------------------------------------- 6.下面是C语言中两种if语句判断方式。请问哪种写法更好?为什么? int n; if (n == 10) // 第一种判断方式 if (10 == n) // 第二种判断方式 如果少了个=号,编译时就会报错,减少了出错的可能行,可以检测出是否少了= -------------------------------------------------------------------------- 7.下面的代码有什么问题? void DoSomeThing(...) { char* p; ... p = malloc(1024); // 分配1K的空间 if (NULL == p) return; ... p = realloc(p, 2048); // 空间不够,重新分配到2K if (NULL == p) return; ... } A: p = malloc(1024); 应该写成: p = (char *) malloc(1024); 没有释放p的空间,造成内存泄漏。 -------------------------------------------------------------------------- 8.下面的代码有什么问题?并请给出正确的写法。 void DoSomeThing(char* p) { char str[16]; int n; assert(NULL != p); sscanf(p, "%s%d", str, n); if (0 == strcmp(str, "something")) { ... } } A: sscanf(p, "%s%d", str, n); 这句该写成: sscanf(p, "%s%d", str, &n); -------------------------------------------------------------------------- 9.下面代码有什么错误? Void test1() { char string[10]; char *str1="0123456789"; strcpy(string, str1); } 数组越界 -------------------------------------------------------------------------- 10.下面代码有什么问题? Void test2() { char string[10], str1[10]; for(i=0; i<10;i++) { str1[i] ='a'; } strcpy(string, str1); } 数组越界 -------------------------------------------------------------------------- 11.下面代码有什么问题? Void test3(char* str1) { char string[10]; if(strlen(str1)<=10) { strcpy(string, str1); } } ==数组越界 ==strcpy拷贝的结束标志是查找字符串中的/0 因此如果字符串中没有遇到/0的话 会一直复制,直到遇到/0,上面的123都因此产生越界的情况 建议使用 strncpy 和 memcpy -------------------------------------------------------------------------- 12.下面代码有什么问题? #define MAX_SRM 256 DSN get_SRM_no() { static int SRM_no; //是不是这里没赋初值? int I; for(I=0;I<MAX_SRM;I++,SRM_no++) { SRM_no %= MAX_SRM; if(MY_SRM.state==IDLE) { break; } } if(I>=MAX_SRM) return (NULL_SRM); else return SRM_no; } 系统会初始化static int变量为0,但该值会一直保存,所谓的不可重入... -------------------------------------------------------------------------- 13.写出运行结果: {// test1 char str[] = "world"; cout << sizeof(str) << ": "; char *p = str; cout << sizeof(p) << ": "; char i = 10; cout << sizeof(i) << ": "; void *pp = malloc(10); cout << sizeof(p) << endl; } 6:4:1:4 -------------------------------------------------------------------------- 14.写出运行结果: {// test2 union V { struct X { unsigned char s1:2; unsigned char s2:3; unsigned char s3:3; } x; unsigned char c; } v; v.c = 100; printf("%d", v.x.s3); } 3 -------------------------------------------------------------------------- 15.用C++写个程序,如何判断一个操作系统是16位还是32位的?不能用sizeof()函数 A1: 16位的系统下, int i = 65536; cout << i; // 输出0; int i = 65535; cout << i; // 输出-1; 32位的系统下, int i = 65536; cout << i; // 输出65536; int i = 65535; cout << i; // 输出65535; A2: int a = ~0; if( a>65536 ) { cout<<"32 bit"<<endl; } else { cout<<"16 bit"<<endl; } -------------------------------------------------------------------------- 16.C和C++有什么不同? 从机制上:c是面向过程的(但c也可以编写面向对象的程序);c++是面向对象的,提供了类。但是, c++编写面向对象的程序比c容易 从适用的方向:c适合要求代码体积小的,效率高的场合,如嵌入式;c++适合更上层的,复杂的; llinux核心大部分是c写的,因为它是系统软件,效率要求极高。 从名称上也可以看出,c++比c多了+,说明c++是c的超集;那为什么不叫c+而叫c++呢,是因为c++比 c来说扩充的东西太多了,所以就在c后面放上两个+;于是就成了c++ C语言是结构化编程语言,C++是面向对象编程语言。 C++侧重于对象而不是过程,侧重于类的设计而不是逻辑的设计。 -------------------------------------------------------------------------- 17.在不用第三方参数的情况下,交换两个参数的值 #include <stdio.h> void main() { int i=60; int j=50; i=i+j; j=i-j; i=i-j; printf("i=%d/n",i); printf("j=%d/n",j); } 方法二: i^=j; j^=i; i^=j; 方法三: // 用加减实现,而且不会溢出 a = a+b-(b=a) -------------------------------------------------------------------------- 18.有关位域的面试题(为什么输出的是一个奇怪的字符) a.t = 'b';效果相当于 a.t= 'b' & 0xf; 'b' --> 01100010 'b' & 0xf -->>00000010 所以输出Ascii码为2的特殊字符 char t:4;就是4bit的字符变量,同样 unsigned short i:8;就是8bit的无符号短整形变量 -------------------------------------------------------------------------- 19.int i=10, j=10, k=3; k*=i+j; k最后的值是? 60 -------------------------------------------------------------------------- 20.进程间通信的方式有? 进程间通信的方式有 共享内存, 管道 ,Socket ,消息队列 , DDE等 -------------------------------------------------------------------------- 21. struct A { char t:4; char k:4; unsigned short i:8; unsigned long m; } sizeof(A)=?(不考虑边界对齐) 7 struct CELL // Declare CELL bit field { unsigned character : 8; // 00000000 ???????? unsigned foreground : 3; // 00000??? 00000000 unsigned intensity : 1; // 0000?000 00000000 unsigned background : 3; // 0???0000 00000000 unsigned blink : 1; // ?0000000 00000000 } screen[25][80]; // Array of bit fields 二、位结构 位结构是一种特殊的结构, 在需按位访问一个字节或字的多个位时, 位结构 比按位运算符更加方便。 位结构定义的一般形式为: struct位结构名{ 数据类型 变量名: 整型常数; 数据类型 变量名: 整型常数; } 位结构变量; 其中: 数据类型必须是int(unsigned或signed)。 整型常数必须是非负的整 数, 范围是0~15, 表示二进制位的个数, 即表示有多少位。 变量名是选择项, 可以不命名, 这样规定是为了排列需要。 例如: 下面定义了一个位结构。 struct{ unsigned incon: 8; /*incon占用低字节的0~7共8位*/ unsigned txcolor: 4;/*txcolor占用高字节的0~3位共4位*/ unsigned bgcolor: 3;/*bgcolor占用高字节的4~6位共3位*/ unsigned blink: 1; /*blink占用高字节的第7位*/ }ch; 位结构成员的访问与结构成员的访问相同。 例如: 访问上例位结构中的bgcolor成员可写成: ch.bgcolor 注意: 1. 位结构中的成员可以定义为unsigned, 也可定义为signed, 但当成员长 度为1时, 会被认为是unsigned类型。因为单个位不可能具有符号。 2. 位结构中的成员不能使用数组和指针, 但位结构变量可以是数组和指针, 如果是指针, 其成员访问方式同结构指针。 3. 位结构总长度(位数), 是各个位成员定义的位数之和, 可以超过两个字 节。 4. 位结构成员可以与其它结构成员一起使用。 例如: struct info{ char name[8]; int age; struct addr address; float pay; unsigned state: 1; unsigned pay: 1; }workers; 上例的结构定义了关于一个工人的信息。其中有两个位结构成员, 每个位结 构成员只有一位, 因此只占一个字节但保存了两个信息, 该字节中第一位表示工 人的状态, 第二位表示工资是否已发放。由此可见使用位结构可以节省存贮空间。 -------------------------------------------------------------------------- 22.下面的函数实现在一个固定的数上加上一个数,有什么错误,改正 int add_n(int n) { static int i=100; i+=n; return i; } 答: 因为static使得i的值会保留上次的值。 去掉static就可了 -------------------------------------------------------------------------- 23.下面的代码有什么问题? class A { public: A() { p=this; } ~A() { if(p!=NULL) { delete p; p=NULL; } } A* p; }; 答: 会引起无限递归 -------------------------------------------------------------------------- 24. union a { int a_int1; double a_double; int a_int2; }; typedef struct { a a1; char y; } b; class c { double c_double; b b1; a a2; }; 输出cout<<sizeof(c)<<endl;的结果? 答: VC6环境下得出的结果是32 另: 我(sun)在VC6.0+win2k下做过试验: short - 2 int-4 float-4 double-8 指针-4 sizeof(union),以结构里面size最大的为union的size 解析C语言中的sizeof 一、sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 二、sizeof的使用方法 1、用于数据类型 sizeof使用形式:sizeof(type) 数据类型必须用括号括住。如sizeof(int)。 2、用于变量 sizeof使用形式:sizeof(var_name)或sizeof var_name 变量名可以不用括号括住。如sizeof (var_name),sizeof var_name等都是正确形式。带括号的用法更普遍,大多数程序员采用这种形式。 注意:sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。 如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式。 三、sizeof的结果 sizeof操作符的结果类型是size_t,它在头文件 中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。 1、若操作数具有类型char、unsigned char或signed char,其结果等于1。 ANSI C正式规定字符类型为1字节。 2、int、unsigned int 、short int、unsigned short 、long int 、unsigned long 、float、double、long double类型的sizeof 在ANSI C中没有具体规定,大小依赖于实现,一般可能分别为2、2、2、2、4、4、4、8、10。 3、当操作数是指针时,sizeof依赖于编译器。例如Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。一般Unix的指针字节数为4。 4、当操作数具有数组类型时,其结果是数组的总字节数。 5、联合类型操作数的sizeof是其最大字节成员的字节数。结构类型操作数的sizeof是这种类型对象的总字节数,包括任何垫补在内。 让我们看如下结构: struct {char b; double x;} a; 在某些机器上sizeof(a)=12,而一般sizeof(char)+ sizeof(double)=9。 这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。如double类型的结构成员x要放在被4整除的地址。 6、如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。 四、sizeof与其他操作符的关系 sizeof的优先级为2级,比/、%等3级运算符优先级高。它可以与其他操作符一起组成表达式。如i*sizeof(int);其中i为int类型变量。 五、sizeof的主要用途 1、sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如: void *malloc(size_t size), size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。 2、sizeof的另一个的主要用途是计算数组中元素的个数。例如: void * memset(void * s,int c,sizeof(s))。 六、建议 由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。 ============================================================= 本文主要包括二个部分,第一部分重点介绍在VC中,怎么样采用sizeof来求结构的大小,以及容易出现的问题,并给出解决问题的方法,第二部分总结出VC中sizeof的主要用法。 1、 sizeof应用在结构上的情况 请看下面的结构: struct MyStruct { double dda1; char dda; int type }; 对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你会这样求: sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13 但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。你知道为什么在VC中会得出这样一个结果吗? 其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了"对齐"处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0,32位系统)。 类型 对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量) Char 偏移量必须为sizeof(char)即1的倍数 int 偏移量必须为sizeof(int)即4的倍数 float 偏移量必须为sizeof(float)即4的倍数 double 偏移量必须为sizeof(double)即8的倍数 Short 偏移量必须为sizeof(short)即2的倍数 各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。 下面用前面的例子来说明VC到底怎么样来存放结构的。 struct MyStruct { double dda1; char dda; int type }; 为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,先为第一个成员dda1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double)的倍数),该成员变量占用sizeof(double)=8个字节;接下来为第二个成员dda分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用sizeof(char)=1个字节;接下来为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof(int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方,该成员变量占用sizeof(int)=4个字节;这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整个结构的大小为:sizeof(MyStruct)=8+1+3+4=16,其中有3个字节是VC自动填充的,没有放任何有意义的东西。 下面再举个例子,交换一下上面的MyStruct的成员变量的位置,使它变成下面的情况: struct MyStruct { char dda; double dda1; int type }; 这个结构占用的空间为多大呢?在VC6.0环境下,可以得到sizeof(MyStruc)为24。结合上面提到的分配空间的一些原则,分析下VC怎么样为上面的结构分配空间的。(简单说明) struct MyStruct { char dda;//偏移量为0,满足对齐方式,dda占用1个字节; double dda1;//下一个可用的地址的偏移量为1,不是sizeof(double)=8 //的倍数,需要补足7个字节才能使偏移量变为8(满足对齐 //方式),因此VC自动填充7个字节,dda1存放在偏移量为8 //的地址上,它占用8个字节。 int type;//下一个可用的地址的偏移量为16,是sizeof(int)=4的倍 //数,满足int的对齐方式,所以不需要VC自动填充,type存 //放在偏移量为16的地址上,它占用4个字节。 };//所有成员变量都分配了空间,空间总的大小为1+7+8+4=20,不是结构 //的节边界数(即结构中占用最大空间的类型所占用的字节数sizeof //(double)=8)的倍数,所以需要填充4个字节,以满足结构的大小为 //sizeof(double)=8的倍数。 所以该结构总的大小为:sizeof(MyStruc)为1+7+8+4+4=24。其中总的有7+4=11个字节是VC自动填充的,没有放任何有意义的东西。 VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。 VC中提供了#pragmapack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数; 否则必须为n的倍数。下面举例说明其用法。 #pragma pack(push) //保存对齐状态 #pragma pack(4)//设定为4字节对齐 struct test { char m1; double m4; int m3; }; #pragma pack(pop)//恢复对齐状态 以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满足我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始为m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大于n),m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用4个字节。这时已经为所有成员变量分配了空间,共分配了16个字节,满足为n的倍数。如果把上面的#pragma pack(4)改为#pragma pack(16),那么我们可以得到结构的大小为24。(请读者自己分析) 2、 sizeof用法总结 在VC中,sizeof有着许多的用法,而且很容易引起一些错误。下面根据sizeof后面的参数对sizeof的用法做个总结。 A. 参数为数据类型或者为一般变量。例如sizeof(int),sizeof(long)等等。这种情况要注意的是不同系统系统或者不同编译器得到的结果可能是不同的。例如int类型在16位系统中占2个字节,在32位系统中占4个字节。 B. 参数为数组或指针。下面举例说明. int a[50]; //sizeof(a)=4*50=200; 求数组所占的空间大小 int *a=new int[50];// sizeof(a)=4; a为一个指针,sizeof(a)是求指针 //的大小,在32位系统中,当然是占4个字节。 C. 参数为结构或类。Sizeof应用在类和结构的处理情况是相同的。但有两点需要注意,第一、结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存储位置与结构或者类的实例地址无关。 第二、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一 个实例在内存中都有唯一的地址。 下面举例说明, Class Test{int a;static double c};//sizeof(Test)=4. Test *s;//sizeof(s)=4,s为一个指针。 Class test1{ };//sizeof(test1)=1; D. 参数为其他。下面举例说明。 int func(char s[5]); { cout<<sizeof(s);//这里将输出4,本来s为一个数组,但由于做为函 //数的参数在传递的时候系统处理为一个指针,所 //以sizeof(s)实际上为求指针的大小。 return 1; } sizeof(func("1234"))=4//因为func的返回类型为int,所以相当于 //求sizeof(int). 以上为sizeof的基本用法,在实际的使用中要注意分析VC的分配变量的分配策略,这样的话可以避免一些错误。 -------------------------------------------------------------------------- 25.i最后等于多少? int i = 1; int j = i++; if((i>j++) && (i++ == j)) i+=j; 答: i = 5 -------------------------------------------------------------------------- 26. unsigned short array[]={1,2,3,4,5,6,7}; int i = 3; *(array + i) = ? 答: 4 -------------------------------------------------------------------------- 27. class A { virtual void func1(); void func2(); } Class B: class A { void func1(){cout << "fun1 in class B" << endl;} virtual void func2(){cout << "fun2 in class B" << endl;} } A, A中的func1和B中的func2都是虚函数. B, A中的func1和B中的func2都不是虚函数. C, A中的func2是虚函数.,B中的func1不是虚函数. D, A中的func2不是虚函数,B中的func1是虚函数. 答: A -------------------------------------------------------------------------- 28. 数据库:抽出部门,平均工资,要求按部门的字符串顺序排序,不能含有"human resource"部门, employee结构如下:employee_id, employee_name, depart_id,depart_name,wage 答: select depart_name, avg(wage) from employee where depart_name <> 'human resource' group by depart_name order by depart_name -------------------------------------------------------------------------- 29. 给定如下SQL数据库:Test(num INT(4)) 请用一条SQL语句返回num的最小值,但不许使用统计功能,如MIN,MAX等 答: select top 1 num from Test order by num desc -------------------------------------------------------------------------- 30. 输出下面程序结果。 #include <iostream.h> class A { public: virtual void print(void) { cout<<"A::print()"<<endl; } }; class B:public A { public: virtual void print(void) { cout<<"B::print()"<<endl; }; }; class C:public B { public: virtual void print(void) { cout<<"C::print()"<<endl; } }; void print(A a) { a.print(); } void main(void) { A a, *pa,*pb,*pc; B b; C c; pa=&a; pb=&b; pc=&c; a.print(); b.print(); c.print(); pa->print(); pb->print(); pc->print(); print(a); print(b); print(c); } A: A::print() B::print() C::print() A::print() B::print() C::print() A::print() A::print() A::print() -------------------------------------------------------------------------- 31. 试编写函数判断计算机的字节存储顺序是开序(little endian)还是降序(bigendian) 答: bool IsBigendian() { unsigned short usData = 0x1122; unsigned char *pucData = (unsigned char*)&usData; return (*pucData == 0x22); } -------------------------------------------------------------------------- 32.简述Critical Section和Mutex的不同点 答: 对几种同步对象的总结 1.Critical Section A.速度快 B.不能用于不同进程 C.不能进行资源统计(每次只可以有一个线程对共享资源进行存取) 2.Mutex A.速度慢 B.可用于不同进程 C.不能进行资源统计 3.Semaphore A.速度慢 B.可用于不同进程 C.可进行资源统计(可以让一个或超过一个线程对共享资源进行存取) 4.Event A.速度慢 B.可用于不同进程 C.可进行资源统计 -------------------------------------------------------------------------- 33.一个数据库中有两个表: 一张表为Customer,含字段ID,Name; 一张表为Order,含字段ID,CustomerID(连向Customer中ID的外键),Revenue; 写出求每个Customer的Revenue总和的SQL语句。 建表 create table customer ( ID int primary key,Name char(10) ) go create table [order] ( ID int primary key,CustomerID int foreign key references customer(id) , Revenue float ) go --查询 select Customer.ID, sum( isnull([Order].Revenue,0) ) from customer full join [order] on( [order].customerid=customer.id ) group by customer.id -------------------------------------------------------------------------- 34.请指出下列程序中的错误并且修改 void GetMemory(char *p){ p=(char *)malloc(100); } void Test(void){ char *str=NULL; GetMemory=(str); strcpy(str,"hello world"); printf(str); } A:错误--参数的值改变后,不会传回 GetMemory并不能传递动态内存,Test函数中的 str一直都是 NULL。 strcpy(str, "hello world");将使程序崩溃。 修改如下: char *GetMemory(){ char *p=(char *)malloc(100); return p; } void Test(void){ char *str=NULL; str=GetMemory(){ strcpy(str,"hello world"); printf(str); } 方法二:void GetMemory2(char **p)变为二级指针. void GetMemory2(char **p, int num) { *p = (char *)malloc(sizeof(char) * num); } -------------------------------------------------------------------------- 35.程序改错 class mml { private: static unsigned int x; public: mml(){ x++; } mml(static unsigned int &) {x++;} ~mml{x--;} pulic: virtual mon() {} = 0; static unsigned int mmc(){return x;} ...... }; class nnl:public mml { private: static unsigned int y; public: nnl(){ x++; } nnl(static unsigned int &) {x++;} ~nnl{x--;} public: virtual mon() {}; static unsigned int nnc(){return y;} ...... }; 代码片断: mml* pp = new nnl; .......... delete pp; A: 基类的析构函数应该为虚函数 virtual ~mml{x--;} -------------------------------------------------------------------------- 36.101个硬币100真、1假,真假区别在于重量。请用无砝码天平称两次给出真币重还是假币重的结论。 答: 101个先取出2堆, 33,33 第一次称,如果不相等,说明有一堆重或轻 那么把重的那堆拿下来,再放另外35个中的33 如果相等,说明假的重,如果不相等,新放上去的还是重的话,说明假的轻(不可能新放上去的轻) 第一次称,如果相等的话,这66个肯定都是真的,从这66个中取出35个来,与剩下的没称过的35个比 下面就不用说了 方法二: 第3题也可以拿A(50),B(50)比一下,一样的话拿剩下的一个和真的比一下。 如果不一样,就拿其中的一堆。比如A(50)再分成两堆25比一下,一样的话就在 B(50)中,不一样就在A(50)中,结合第一次的结果就知道了。 -------------------------------------------------------------------------- 37.static变量和static 函数各有什么特点? 答: static变量:在程序运行期内一直有效,如果定义在函数外,则在编译单元内可见,如果在函数内,在在定义的block内可见; static函数:在编译单元内可见; -------------------------------------------------------------------------- 38.用C 写一个输入的整数,倒着输出整数的函数,要求用递归方法 ; 答: void fun( int a ) { printf( "%d", a%10 ); a /= 10; if( a <=0 )return; fun( a ); } -------------------------------------------------------------------------- 39.写出程序结果: void Func(char str[100]) { printf("%d/n", sizeof(str)); } 答: 4 分析: 指针长度 -------------------------------------------------------------------------- 40.int id[sizeof(unsigned long)]; 这个对吗?为什么?? 答: 对 这个 sizeof是编译时运算符,编译时就确定了 可以看成和机器有关的常量。 本文主要包括二个部分,第一部分重点介绍在VC中,怎么样采用sizeof来求结构的大小,以及容易出现的问题,并给出解决问题的方法,第二部分总结出VC中sizeof的主要用法。 1、 sizeof应用在结构上的情况 请看下面的结构: struct MyStruct { double dda1; char dda; int type }; 对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你会这样求: sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13 但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。你知道为什么在VC中会得出这样一个结果吗? 其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了"对齐"处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0,32位系统)。 类型 对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量) Char 偏移量必须为sizeof(char)即1的倍数 int 偏移量必须为sizeof(int)即4的倍数 float 偏移量必须为sizeof(float)即4的倍数 double 偏移量必须为sizeof(double)即8的倍数 Short 偏移量必须为sizeof(short)即2的倍数 各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍?/textarea>