有没有好用的网站推荐,酒店装修,网页设计流程分为哪几个步骤,200平米火锅店装修费用微软亚洲技术中心的面试题#xff01;#xff01;#xff01; 1#xff0e;进程和线程的差别。 线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)调度#xff1a;线程作为调度和分配的基本单位#xff0c;进程作为拥有资源的基本单位 (2)并发性 1进程和线程的差别。 线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)调度线程作为调度和分配的基本单位进程作为拥有资源的基本单位 (2)并发性不仅进程之间可以并发执行同一个进程的多个线程之间也可并发执行 (3)拥有资源进程是拥有资源的独立单位线程不拥有系统资源但可以访问隶属于进程的资源. (4)系统开销在创建或撤消进程时由于系统都要为之分配和回收资源导致系统的开销明显大于创建或撤消线程时的开销。 2.测试方法 人工测试个人复查、抽查和会审 机器测试黑盒测试和白盒测试 2Heap与stack的差别 Heap是堆stack是栈。 Stack的空间由操作系统自动分配/释放Heap上的空间手动分配/释放。 Stack空间有限Heap是很大的自由存储区 C中的malloc函数分配的内存空间即在堆上,C中对应的是new操作符。 程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行 3Windows下的内存是如何管理的 4介绍.Net和.Net的安全性。 5客户端如何访问.Net组件实现Web Service 6C/C编译器中虚表是如何完成的 7谈谈COM的线程模型。然后讨论进程内/外组件的差别。 8谈谈IA32下的分页机制 小页(4K)两级分页模式大页(4M)一级 9给两个变量如何找出一个带环单链表中是什么地方出现环的 一个递增一一个递增二他们指向同一个接点时就是环出现的地方 10在IA32中一共有多少种办法从用户态跳到内核态 通过调用门从ring3到ring0中断从ring3到ring0进入vm86等等 11如果只想让程序有一个实例运行不能运行两个。像winamp一样只能开一个窗口怎样实现
用内存映射或全局原子互斥变量、查找窗口句柄.. FindWindow互斥写标志到文件或注册表,共享内存。. 12如何截取键盘的响应让所有的‘a’变成‘b’ 键盘钩子SetWindowsHookEx 13Apartment在COM中有什么用为什么要引入 14存储过程是什么有什么用有什么优点 存储过程Stored Procedure是一组为了完成特定功能的SQL 语句集经编译后存储在数据库。中用户通过指定存储过程的名字并给出参数如果该存储过程带有参数来执行它。
存储过程用于实现频繁使用的查询、业务规则、被其他过程使用的公共例行程序
存储过程在创建时即在服务器上进行编译所以执行起来比单个 SQL 语句快
15Template有什么特点什么时候用 16谈谈Windows DNA结构的特点和优点。 17.网络编程中设计并发服务器使用多进程与多线程 请问有什么区别 1进程子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。 2线程相对与进程而言线程是一个更加接近与执行体的概念它可以与同进程的其他线程共享数据但拥有自己的栈空间拥有独立的执行序列。 区别两者都可以提高程序的并发度提高程序运行效率和响应时间。线程和进程在使用上各有优缺点线程执行开销小但不利于资源管理和保护而进程正相反。同时线程适合于在SMP机器上运行而进程则可以跨机器迁移。 MSRA Interview Written ExamDecember 2003Time2.5 Hours 1写出下列算法的时间复杂度。 (1)冒泡排序 (2)选择排序 (3)插入排序 (4)快速排序 (5)堆排序 (6)归并排序 2写出下列程序在X86上的运行结果。 struct mybitfields { unsigned short a : 4; unsigned short b : 5; unsigned short c : 7; }test
void main(void) { int i; test.a2; test.b3; test.c0;
i*((short *)test); printf(%d/n,i); } 3写出下列程序的运行结果。 unsigned int i3; couti * -1; 4写出下列程序所有可能的运行结果。
int a; int b; int c;
void F1() { ba*2; ab; }
void F2() { ca1; ac; }
main() { a5; //Start F1,F2 in parallel F1(); F2(); printf(a%d/n,a); } 5考察了一个CharPrev()函数的作用。 6对 16 Bits colors的处理要求 1Byte转换为RGB时保留高5、6bits 2RGB转换为Byte时第2、3位置零。 7一个链表的操作注意代码的健壮和安全性。要求 1增加一个元素 2获得头元素 3弹出头元素获得值并删除。 8一个给定的数值由左边开始升位到右边第N位如 00101 0100 或者 0001 00114 0011 0000 请用C或者C或者其他X86上能运行的程序实现。 附加题只有在完成以上题目后才获准回答 1。In C, what does explicit mean? what does protected mean?
c中的explicit关键字用来修饰类的构造函数表明该构造函数是显式的在某些情况下我们要求类的使用者必须显示调用类的构造函数时就需要使用explicit,反之默认类型转换可能会造成无法预期的问题。
protected控制的是一个函数对一个类的成员包括成员变量及成员方法的访问权限。protected成员只有该类的成员函数及其派生类的成员函数可以访问 1 在C中有没有纯虚构造函数
构造函数不能是虚的。只能有虚的析构函数 2 在c的一个类中声明一个static成员变量有没有用
在C类的成员变量被声明为static称为静态成员变量意味着它为该类的所有实例所共享也就是说当某个类的实例修改了该静态成员变量也就是说不管创建多少对象static修饰的变量只占有一块内存。其修改值为该类的其它所有实例所见而类的静态成员函数也只能访问静态成员变量或函数。
static是加了访问控制的全局变量不被继承。 3。在C的一个类中声明一个静态成员函数有没有用 同上? 4。如何实现一个非阻塞的socket? 5。setsockopt, ioctl都可以对socket的属性进行设置他们有什么不同 linux 6。解释一下进程和线程的区别 (重复参见微软亚洲技术中心笔试) 7。解释一下多播组播和广播的含义
组播:主机之间“一对一组”的通讯模式也就是加入了同一个组的主机可以接受到此组内的所有数据网络中的交换机和路由器只向有需求者复制并转发其所需数据。主机可以向路由器请求加入或退出某个组网络中的路由器和交换机有选择的复制并传输数据即只将组内数据传输给那些加入组的主机。
广播:主机之间“一对所有”的通讯模式网络对其中每一台主机发出的信号都进行无条件复制并转发所有主机都可以接收到所有信息不管你是否需要. 8。多播采用的协议是什么 9。在c中纯虚析构函数的作用是什么请举例说明。 10。编程请实现一个c语言中类似atoi的函数功能输入可能包含非数字和空格 百度笔试题 一、选择题15分 共10题 1. 在排序方法中关键码比较次数与记录地初始排列无关的是 . A. Shell排序 B. 归并排序 C. 直接插入排序 D. 选择排序 2. 以下多线程对int型变量x的操作哪几个需要进行同步 A. xy; B. x; C. x; D. x1; 3. 代码 void func() { static int val; … } 中变量val的内存地址位于 A. 已初始化数据段 B.未初始化数据段 C.堆 D.栈 4. 同一进程下的线程可以共享以下 A. stack B. data section C. register set D. thread ID 5. TCP和IP分别对应了 OSI中的哪几层 A. Application layer B. Data link layer C. Presentation layer D. Physical layer E. Transport layer F. Session layer G. Network layer 6. short a[100]sizeof(a)返回 A 2 B 4 C 100 D 200 E 400 7. 以下哪种不是基于组件的开发技术_____。 A XPCOM B XP C COM D CORBA 8. 以下代码打印的结果是假设运行在i386系列计算机上 struct st_t { int status; short* pdata; char errstr[32]; }; st_t st[16]; char* p (char*)(st[2].errstr 32); printf(%d, (p - (char*)(st)));
A 32 B 114 C 120 D 1112 9. STL中的哪种结构是连续形式的存储 A map B set C list D vector 10. 一个栈的入栈序列是ABCDE则栈的不可能的输出序列是 A、EDCBA B、DECBA C、DCEAB D、ABCDE 参考答案D /ABC/ A/ BC /EG /D /B/ C/ D/ C 二、简答题20分共2题
1. 5分重复多次fclose一个打开过一次的FILE *fp指针会有什么结果并请解释。 考察点导致文件描述符结构中指针指向的内存被重复释放进而导致一些不可预期的异常。
2. 15分下面一段代码想在调用f2(1)时打印err1调用f2(2)时打印err4但是代码中有一些问题请做尽可能少的修改使之正确。 1 static int f1(const char *errstr, unsigned int flag) { 2 int copy, index, len; 3 const static char **__err {“err1”, “err2”, “err3”, “err4”}; 4 5 if(flag 0x10000) 6 copy 1; 7 index (flag 0x300000) 20; 8 9 if(copy) { 10 len flag 0xF; 11 errstr malloc(len); 12 if(errstr NULL) 13 return -1; 14 strncpy(errstr, __err[index], sizeof(errstr)); 15 } else 16 errstr __err index; 17 } 18 19 void f2(int c) { 20 char *err; 22 swtch(c) { 23 case 1: 24 if(f1(err, 0x110004) ! -1) 25 printf(err); 26 case 2: 27 if(f2(err, 0x30000D) ! -1) 28 printf(err); 29 } 30 }
三、编程题30分 共1题 注意要求提供完整代码如果可以编译运行酌情加分。
1. 求符合指定规则的数。 给定函数d(n) n n的各位之和n为正整数如 d(78 787893。 这样这个函数可以看成一个生成器如93可以看成由78生成。 定义数A数A找不到一个数B可以由d(B)A即A不能由其他数生成。现在要写程序找出1至10000里的所有符合数A定义的数。 输出 1 3 … 四、设计题35分 共1题 注意请尽可能详细描述你的数据结构、系统架构、设计思路等。建议多写一些伪代码或者流程说明。
1. 假设一个mp3搜索引擎收录了2^24首歌曲并记录了可收听这些歌曲的2^30条URL但每首歌的URL不超过2^10个。系统会定期检查这些URL如果一个URL不可用则不出现在搜索结果中。现在歌曲名和URL分别通过整型的SONG_ID和URL_ID唯一确定。对该系统有如下需求 1) 通过SONG_ID搜索一首歌的URL_ID给出URL_ID计数和列表 2) 给定一个SONG_ID为其添加一个新的URL_ID 3) 添加一个新的SONG_ID 4) 给定一个URL_ID将其置为不可用
限制条件内存占用不超过1G单个文件大小不超过2G一个目录下的文件数不超过128个。
为获得最佳性能请说明设计的数据结构、搜索算法以及资源消耗。如果系统数据量扩大该如何多机分布处理 汉略曾考的测试题目 QWhen speaking of software products, how do you define the term“quality”. 问当说到软件产品的时候你如何定义术语“质量” Meeting customer requirements QWhat is the role of software debelopers and quality assuranle engineers in ensuring the quality of the product? How are other functional areas important to developing a quality product? 问在确定产品的质量方面什么是软件开发工程师和质量保证工程师要做的其他的功能对如何发展产品质量有什么重要 软件测试是贯穿整个软件开发生命周期、对软件产品包括阶段性产品进行验证和确认的活动过程其目的是尽快尽早地发现在软件产品中所存在的各种问题——与用户需求、预先定义的不一致性。Quality assuranle engineers: use a set of activities designed to ensure the development process to meet the requirements. QWhat is cyclomatic complexity? 问这是一个复杂度模型吧
一种代码复杂度的衡量标准中文名称叫做圈复杂度。圈复杂度“用来衡量一个模块判定结构的复杂程度数量上表现为独立现行路径条数即合理的预防错误所需测试的最少路径条数圈复杂度大说明程序代码可能质量低且难于测试和维护根据经验程序的可能错误和高的圈复杂度有着很大关系”。 QWhat are black-box texing and white-box texting? 问什么是黑盒测试和白盒测试
黑盒测试Black-box Testing又称为功能测试或数据驱动测试是把测试对象看作一个黑盒子。利用黑盒测试法进行动态测试时需要测试软件产品的功能不需测试软件产品的内部结构和处理过程。采用黑盒技术设计测试用例的方法有等价类划分、边界值分析、错误推测、因果图和综合策略。黑盒测试注重于测试软件的功能性需求也即黑盒测试使软件工程师派生出执行程序所有功能需求的输入条件。黑盒测试并不是白盒测试的替代品而是用于辅助白盒测试发现其他类型的错误。
白盒测试(White-box Testing又称逻辑驱动测试,结构测试)是把测试对象看作一个打开的盒子。利用白盒测试法进行动态测试时需要测试软件产品的内部结构和处理过程不需测试软件产品的功能。白盒测试又称为结构测试和逻辑驱动测试。白盒测试法的覆盖标准有逻辑覆盖、循环覆盖和基本路径测试。其中逻辑覆盖包括语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖和路径覆盖。
Black box testing: a testing without knowledge of the internal working of the item being tested. white box testing: use specific knowledge of programming code to examine outputs. QThe following function divides a by b and out put to c,returns -1 as error. Int divide (int a,int b,int c) List you test cases in a black-box testing. 问对 Int divide (int a,int b,int c)函数写出黑盒测试用例
先等价后边界值
a b c 预期 结果 g g 5 0 6 2 0 1 -10 10 -10 -10 10.0 10.0 QInt a ctivity(int nage,bool bmale) {if (nage60) return zoo; else if(bmale) return golf; else return movie; } 用cyclomatic complexity共有多少条路径 3 QThe following function tests whether the three numbers can be the lengths of the three sides of a triangle. Bool triangle(float a,float b,float c) List you test cases in a black-box testing. 问也是让写黑盒测试用例是一个三个数是否是三角形的三条边的测试
先等价后边界值
a b c 预期 结果 g j 0 -1 2 2 10 2 3 2 3 4 2 2 5 6 6 6
IQ,EQ题
然后是英文的数据结构c/c数据库3D建模软件工程软件测试
题目几乎都是英文的
后面还要填表格一张中文的一张英文的
一般有三个步骤 首先会笔试。笔试题分为EQ题和专业题EQ题没什么好说的大家自由发挥就行不过其中有一些逻辑推理题要注意。专业题目全英文考的内容很多数据结构C/C语法COM3D建模软件测试基础知识如黑盒白盒测试等题不难每方面有三到五题左右。 笔试成绩达到一定分数过后才能进入第二轮人事部面试。这部分面试一般是五人一组在一房间里面试人员会问很多问题然后每个人做答问题很随机当时好像问了“最尊敬的人是谁最难忘的事是什么有何职业规划如何处理与同事之间的关系矛盾等等”。 这轮过后就到技术部面试会问一些基础知识如数据结构常用的有哪些如何用C/C写出其中的一种面象对像有哪些特性XML是什么等等可能他会用英语问你这些问题各位练下听力口语哈当时俺被问的很郁闷
COM:
COM是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术。在COM构架下人们可以开发出各种各样的功能专一的组件然后将它们按照需要组合起来构成复杂的应用系统。由此带来的好处是多方面的可以将系统中的组件用新的替换掉以便随时进行系统的升级和定制可以在多个应用系统中重复利用同一个组件可以方便的将应用系统扩展到网络环境下COM与语言平台无关的特性使所有的程序员均可充分发挥自己的才智与专长编写组件模块等等。COM是开发软件组件的一种方法。组件实际上是一些小的二进制可执行程序它们可以给应用程序操作系统以及其他组件提供服务。
开发自定义的COM组件就如同开发动态的面向对象的API。多个COM对象可以连接起来形成应用程序或组件系统。并且组件可以在运行时刻在不被重新链接或编译应用程序的情况下被卸下或替换掉。Microsoft的许多技术如ActiveX, DirectX以及OLE等都是基于COM而建立起来的。并且Microsoft的开发人员也大量使用COM组件来定制他们的应用程序及操作系统。 COM所含的概念并不止是在Microsoft Windows操作系统下才有效。COM并不是一个大的API它实际上象结构化编程及面向对象编程方法那样也是一种编程方法。在任何一种操作系统中开发人员均可以遵循“COM方法”。 有的组件必须满足两个条件第一组件必须动态链接第二它们必须隐藏或封装其内部实现细节。动态链接对于组件而言是一个至关重要的要求而消息隐藏则是动态链接的一个必要条件。对于COM来讲接口是一个包含一个函数指针数组的内存结构。每一个数组元素包含的是一个由组件所实现的函数地址。 1.写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式中 a的值(3分)
int a 4;
(A)a (a); (B) a (a) ;(C) (a) a;(D) (a) (a);
a ?
答C错误左侧不是一个有效变量不能赋值可改为(a) a;
改后答案依次为9,10,10,11 2.某32位系统下, C程序请计算sizeof 的值(5分).
char str[] “www.ibegroup.com”
char *p str ;
int n 10;
请计算
sizeof (str ) 1
sizeof ( p ) 2
sizeof ( n ) 3
void Foo ( char str[100]){
请计算
sizeof( str ) 4
}
void *p malloc( 100 );
请计算
sizeof ( p ) 5
答117 24 3 4 44 54 3. 回答下面的问题. (4分)
(1).头文件中的 ifndef/define/endif 干什么用预处理
答防止头文件被重复引用
(2). #include 和 #include “filename.h” 有什么区别
答前者用来包含开发环境提供的库头文件后者用来包含自己编写的头文件。
(3).在C 程序中调用被 C 编译器编译后的函数为什么要加 extern “C”声明
答函数和变量被C编译后在符号库中的名字与C语言的不同被extern C修饰的变量和函数是按照C语言方式编译和连接的。由于编译后的名字不同C程序不能直接调用C 函数。C提供了一个C 连接交换指定符号extern“C”来解决这个问题。
(4). switch()中不允许的数据类型是?
答实型
4. 回答下面的问题(6分)
(1).Void GetMemory(char **p, int num){
*p (char *)malloc(num);
}
void Test(void){
char *str NULL;
GetMemory(str, 100);
strcpy(str, hello);
printf(str);
}
请问运行Test 函数会有什么样的结果
答输出“hello”
(2). void Test(void){
char *str (char *) malloc(100);
strcpy(str, “hello”);
free(str);
if(str ! NULL){
strcpy(str, “world”);
printf(str);
}
}
请问运行Test 函数会有什么样的结果
答输出“world”
(3). char *GetMemory(void){
char p[] hello world;
return p;
}
void Test(void){
char *str NULL;
str GetMemory();
printf(str);
}
请问运行Test 函数会有什么样的结果
答无效的指针输出不确定 5. 编写strcat函数(6分)
已知strcat函数的原型是char *strcat (char *strDest, const char *strSrc);
其中strDest 是目的字符串strSrc 是源字符串。
1不调用C/C 的字符串库函数请编写函数 strcat
答
VC源码
char * __cdecl strcat (char * dst, const char * src)
{
char * cp dst;
while( *cp )
cp; /* find end of dst */
while( *cp *src ) ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
2strcat能把strSrc 的内容连接到strDest为什么还要char * 类型的返回值
答方便赋值给其他变量 6.MFC中CString是类型安全类么
答不是其它数据类型转换到CString可以使用CString的成员函数Format来转换 7.C中为什么用模板类。
答(1)可用来创建动态增长和减小的数据结构
2它是类型无关的因此具有很高的可复用性。
3它在编译时而不是运行时检查数据类型保证了类型安全
4它是平台无关的可移植性
5可用于基本数据类型 8.CSingleLock是干什么的。
答同步多个线程对一个数据类的同时访问
9.NEWTEXTMETRIC 是什么。
答物理字体结构用来设置字体的高宽大小
10.程序什么时候应该使用线程什么时候单线程效率高。
答1耗时的操作使用线程提高应用程序响应
2并行操作时使用线程如C/S架构的服务器端并发线程响应用户的请求。
3多CPU系统中使用线程提高CPU利用率
4改善程序结构。一个既长又复杂的进程可以考虑分为多个线程成为几个独立或半独立的运行部分这样的程序会利于理解和修改。
其他情况都使用单线程。 11.Windows是内核级线程么。
答见下一题 12.Linux有内核级线程么。
答线程通常被定义为一个进程中代码的不同执行路线。从实现方式上划分线程有两种类型“用户级线程”和“内核级线程”。 用户线程指不需要内核支持而在用户程序中实现的线程其不依赖于操作系统核心应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。这种线程甚至在象 DOS 这样的操作系统中也可实现但线程的调度需要用户程序完成这有些类似 Windows 3.x 的协作式多任务。另外一种则需要内核的参与由内核完成线程的调度。其依赖于操作系统核心由内核的内部需求进行创建和撤销这两种模型各有其好处和缺点。用户线程不需要额外的内核开支并且用户态线程的实现方式可以被定制或修改以适应特殊应用的要求但是当一个线程因 I/O 而处于等待状态时整个进程就会被调度程序切换为等待状态其他线程得不到运行的机会而内核线程则没有各个限制有利于发挥多处理器的并发优势但却占用了更多的系统开支。 Windows NT和OS/2支持内核线程。Linux 支持内核级的多线程 13.C中什么数据分配在栈或堆中New分配数据是在近堆还是远堆中
答栈: 存放局部变量函数调用参数,函数返回值函数返回地址。由系统管理
堆: 程序运行时动态申请new 和 malloc申请的内存就在堆上 14.使用线程是如何防止出现大的波峰。
答意思是如何防止同时产生大量的线程方法是使用线程池线程池具有可以同时提高调度效率和限制资源使用的好处线程池中的线程达到最大数时其他线程就会排队等候。 15函数模板与类模板有什么区别
答函数模板的实例化是由编译程序在处理函数调用时自动完成的而类模板的实例化必须由程序员在程序中显式地指定。 16一般数据库若出现日志满了会出现什么情况是否还能使用
答只能执行查询等读操作不能执行更改备份等写操作原因是任何写操作都要记录日志。也就是说基本上处于不能使用的状态。 17 SQL Server是否支持行级锁有什么好处
答支持设立封锁机制主要是为了对并发操作进行控制对干扰进行封锁保证数据的一致性和准确性行级封锁确保在用户取得被更新的行到该行进行更新这段时间内不被其它用户所修改。因而行级锁即可保证数据的一致性又能提高数据操作的并发性。 18如果数据库满了会出现什么情况是否还能使用
答见16 19 关于内存对齐的问题以及sizeof()的输出
答编译器自动对齐的原因为了提高程序的性能数据结构尤其是栈应该尽可能地在自然边界上对齐。原因在于为了访问未对齐的内存处理器需要作两次内存访问然而对齐的内存访问仅需要一次访问。 20 int i10, j10, k3; k*ij; k最后的值是
答60此题考察优先级实际写成 k*(ij);赋值运算符优先级最低
21.对数据库的一张表进行操作,同时要对另一张表进行操作,如何实现?
答将操作多个表的操作放入到事务中进行处理
22.TCP/IP 建立连接的过程?(3-way shake)
答在TCP/IP协议中TCP协议提供可靠的连接服务采用三次握手建立一个连接。第一次握手建立连接时客户端发送syn包(synj)到服务器并进入SYN_SEND状态等待服务器确认
第二次握手服务器收到syn包必须确认客户的SYNackj1同时自己也发送一个SYN包synk即SYNACK包此时服务器进入SYN_RECV状态 第三次握手客户端收到服务器的SYNACK包向服务器发送确认包ACK(ackk1)此包发送完毕客户端和服务器进入ESTABLISHED状态完成三次握手。 23.ICMP是什么协议,处于哪一层?
答Internet控制报文协议处于网络层IP层 24.触发器怎么工作的?
答触发器主要是通过事件进行触发而被执行的当对某一表进行诸如UPDATE、 INSERT、 DELETE 这些操作时数据库就会自动执行触发器所定义的SQL 语句从而确保对数据的处理必须符合由这些SQL 语句所定义的规则。 25.winsock建立连接的主要实现步骤?
答服务器端socket()建立套接字绑定bind并监听listen用accept等待客户端连接。
客户端socket()建立套接字连接connect服务器连接上后使用send()和recv在套接字上写读数据直至数据交换完毕closesocket()关闭套接字。
服务器端accept发现有客户端连接建立一个新的套接字自身重新开始等待连接。该新产生的套接字使用send()和recv写读数据直至数据交换完毕closesocket()关闭套接字。 26.动态连接库的两种方式?
答调用一个DLL中的函数有两种方法
1载入时动态链接load-time dynamic linking模块非常明确调用某个导出函数使得他们就像本地函数一样。这需要链接时链接那些函数所在DLL的导入库导入库向系统提供了载入DLL时所需的信息及DLL函数定位。
2运行时动态链接run-time dynamic linking运行时可以通过LoadLibrary或LoadLibraryEx函数载入DLL。DLL载入后模块可以通过调用GetProcAddress获取DLL函数的出口地址然后就可以通过返回的函数指针调用DLL函数了。如此即可避免导入库文件了 27.IP组播有那些好处?
答Internet上产生的许多新的应用特别是高带宽的多媒体应用带来了带宽的急剧消耗和网络拥挤问题。组播是一种允许一个或多个发送者组播源发送单一的数据包到多个接收者一次的同时的的网络技术。组播可以大大的节省网络带宽因为无论有多少个目标地址在整个网络的任何一条链路上只传送单一的数据包。所以说组播技术的核心就是针对如何节约网络资源的前提下保证服务质量。 托管代码
使用基于公共语言运行库的语言编译器开发的代码称为托管代码托管代码具有许多优点例如跨语言集成、跨语言异常处理、增强的安全性、版本控制和部署支持、简化的组件交互模型、调试和分析服务等。
重载
每个类型成员都有一个唯一的签名。方法签名由方法名称和一个参数列表方法的参数的顺序和类型组成。只要签名不同就可以在一种类型内定义具有相同名称的多种方法。当定义两种或多种具有相同名称的方法时就称作重载。 16道语言面试题例子
预处理器Preprocessor 1. 用预处理指令#define 声明一个常数用以表明1年中有多少秒忽略闰年问题 #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情 1). #define 语法的基本知识例如不能以分号结束括号的使用等等 2). 懂得预处理器将为你计算常数表达式的值因此直接写出你是如何计算一年中有多少秒而不是计算出实际的值是更清晰而没有代价的。 3). 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。 4). 如果你在你的表达式中用到UL表示无符号长整型那么你有了一个好的起点。记住第一印象很重要。 2. 写一个“标准”宏MIN这个宏输入两个参数并返回较小的一个。 #define MIN(A,B) ((A) (B)(A) : (B)) 这个测试是为下面的目的而设的 1). 标识#define在宏中应用的基本知识。这是很重要的因为直到嵌入(inline)操作符变为标准C的一部分宏是方便产生嵌入代码的唯一方法对于嵌入式系统来说为了能达到要求的性能嵌入代码经常是必须的方法。 2). 三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码了解这个用法是很重要的。 3). 懂得在宏中小心地把参数用括号括起来 4). 我也用这个问题开始讨论宏的副作用例如当你写下面的代码时会发生什么事 least MIN(*p, b); 3. 预处理器标识#error的目的是什么 如果你不知道答案请看参考文献1。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种问题的答案。当然如果你不是在找一个书呆子那么应试者最好希望自己不要知道答案。#error 停止编译并显示错误信息 死循环Infinite loops 4. 嵌入式系统中经常要用到无限循环你怎么样用C编写死循环呢 这个问题用几个解决方案。我首选的方案是 while(1) { } 一些程序员更喜欢如下方案 for(;;) { } 这个实现方式让我为难因为这个语法没有确切表达到底怎么回事。如果一个应试者给出这个作为方案我将用这个作为一个机会去探究他们这样做的基本原理。如果他们的基本答案是“我被教着这样做但从没有想到过为什么。”这会给我留下一个坏印象。 第三个方案是用 goto Loop: ... goto Loop; 应试者如给出上面的方案这说明或者他是一个汇编语言程序员这也许是好事或者他是一个想进入新领域的BASIC/FORTRAN程序员。 数据声明Data declarations 5. 用变量a给出下面的定义 a) 一个整型数An integer b) 一个指向整型数的指针A pointer to an integer c) 一个指向指针的的指针它指向的指针是指向一个整型数A pointer to a pointer to an integer d) 一个有10个整型数的数组An array of 10 integers e) 一个有10个指针的数组该指针是指向一个整型数的An array of 10 pointers to integers f) 一个指向有10个整型数数组的指针A pointer to an array of 10 integers g) 一个指向函数的指针该函数有一个整型参数并返回一个整型数A pointer to a function that takes an integer as an argument and returns an integer h) 一个有10个指针的数组该指针指向一个函数该函数有一个整型参数并返回一个整型数 An array of ten pointers to functions that take an integer argument and return an integer 答案是 a) int a; // An integer b) int *a; // A pointer to an integer c) int **a; // A pointer to a pointer to an integer d) int a[10]; // An array of 10 integers e) int *a[10]; // An array of 10 pointers to integers f) int (*a)[10]; // A pointer to an array of 10 integers g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
人们经常声称这里有几个问题是那种要翻一下书才能回答的问题我同意这种说法。当我写这篇文章时为了确定语法的正确性我的确查了一下书。 但是当我被面试的时候我期望被问到这个问题或者相近的问题。因为在被面试的这段时间里我确定我知道这个问题的答案。应试者如果不知道 所有的答案或至少大部分答案那么也就没有为这次面试做准备如果该面试者没有为这次面试做准备那么他又能为什么出准备呢 Static 6. 关键字static的作用是什么 这个简单的问题很少有人能回答完全。在C语言中关键字static有三个明显的作用 1). 在函数体一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 2). 在模块内但在函数体外一个被声明为静态的变量可以被模块内所用函数访问但不能被模块外其它函数访问。它是一个本地的全局变量。 3). 在模块内一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是这个函数被限制在声明它的模块的本地范围内使用。 大多数应试者能正确回答第一部分一部分能正确回答第二部分同是很少的人能懂得第三部分。这是一个应试者的严重的缺点因为他显然不懂得本地化数据和代码范围的好处和重要性。 Const 7关键字const是什么含意 我只要一听到被面试者说“const意味着常数”我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法因此ESP(译者Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章只要能说出const意味着“只读”就可以了。尽管这个答案不是完全的答案但我接受它作为一个正确的答案。如果你想知道更详细的答案仔细读一下Saks的文章吧。如果应试者能正确回答这个问题我将问他一个附加的问题下面的声明都是什么意思 const int a; //a是一个常整型数 int const a; //a是一个常整型数 const int *a; //一个指向常整型数的指针整型数是不可修改的但指针可以 int * const a; //一个指向整型数的常指针指针指向的整型数是可以修改的指针不可修改 int const * a const;// 一个指向常整型数的常指针整型数不可修改指针也是不可修改的
主要看const靠近*还是int,不可修改的就是它 前两个的作用是一样a是一个常整型数。第三个意味着a是一个指向常整型数的指针也就是整型数是不可修改的但指针可以。第四个意思a是一个指向整型数的常指针也就是说指针指向的整型数是可以修改的但指针是不可修改的。最后一个意味着a是一个指向常整型数的常指针也就是说指针指向的整型数是不可修改的同时指针也是不可修改的。如果应试者能正确回答这些问题那么他就给我留下了一个好印象。顺带提一句也许你可能会问即使不用关键字const也还是能很容易写出功能正确的程序那么我为什么还要如此看重关键字const呢我也如下的几下理由 1). 关键字const的作用是为给读你代码的人传达非常有用的信息实际上声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾你就会很快学会感谢这点多余的信息。当然懂得用const的程序员很少会留下的垃圾让别人来清理的。 2). 通过给优化器一些附加的信息使用关键字const也许能产生更紧凑的代码。 3). 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数防止其被无意的代码修改。简而言之这样可以减少bug的出现。 Volatile
8. 关键字volatile有什么含意 并给出三个不同的例子。 一个定义为volatile的变量是说这变量可能会被意想不到地改变这样编译器就不会去假设这个变量的值了。精确地说就是优化器在用到这个变量时必须每次都小心地重新读取这个变量的值而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子 1). 并行设备的硬件寄存器如状态寄存器 2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3). 多线程应用中被几个任务共享的变量 回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。 假设被面试者正确地回答了这是问题嗯怀疑这否会是这样我将稍微深究一下看一下这家伙是不是直正懂得volatile完全的重要性。 1). 一个参数既可以是const还可以是volatile吗解释为什么。 2). 一个指针可以是volatile 吗解释为什么。 3). 下面的函数有什么错误 int square(volatile int *ptr) { return *ptr * *ptr; } 下面是答案 1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。 2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。 3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方但是由于*ptr指向一个volatile型参数编译器将产生类似下面的代码 int square(volatile int *ptr) { int a,b; a *ptr; b *ptr; return a * b; } 由于*ptr的值可能被意想不到地该变因此a和b可能是不同的。结果这段代码可能返不是你所期望的平方值正确的代码如下 long square(volatile int *ptr) { int a; a *ptr; return a * a; } 位操作Bit manipulation 9. 嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a写两段代码第一个设置a的bit 3第二个清除a 的bit 3。在以上两个操作中要保持其它位不变。 对这个问题有三种基本的反应 1). 不知道如何下手。该被面者从没做过任何嵌入式系统的工作。 2). 用bit fields。Bit fields是被扔到C语言死角的东西它保证你的代码在不同编译器之间是不可移植的同时也保证了的你的代码是不可重用的。我最近不幸看到Infineon为其较复杂的通信芯片写的驱动程序它用到了bit fields因此完全对我无用因为我的编译器用其它的方式来实现bit fields的。从道德讲永远不要让一个非嵌入式的家伙粘实际硬件的边。 3). 用 #defines 和 bit masks 操作。这是一个有极高可移植性的方法是应该被用到的方法。最佳的解决方案如下 #define BIT3 (0x13) static int a; void set_bit3(void) { a | BIT3; } void clear_bit3(void) { a ~BIT3; } 一些人喜欢为设置和清除值而定义一个掩码同时定义一些说明常数这也是可以接受的。我希望看到几个要点说明常数、|和~操作。 访问固定的内存位置Accessing fixed memory locations 10. 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。 这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换typecast为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下 int *ptr; ptr (int *)0x67a9; *ptr 0xaa55; 一个较晦涩的方法是 *(int * const)(0x67a9) 0xaa55; 即使你的品味更接近第二种方案但我建议你在面试时使用第一种方案。 中断Interrupts 11. 中断是嵌入式系统中重要的组成部分这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是产生了一个新的关键字__interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR)请评论一下这段代码的。 __interrupt double compute_area (double radius) { double area PI * radius * radius; printf( Area %f, area); return area; } 这个函数有太多的错误了以至让人不知从何说起了 1). ISR 不能返回一个值。如果你不懂这个那么你不会被雇用的。 2). ISR 不能传递参数。如果你没有看到这一点你被雇用的机会等同第一项。 3). 在许多的处理器/编译器中浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈有些处理器/编译器就是不允许在ISR中做浮点运算。此外ISR应该是短而有效率的在ISR中做浮点运算是不明智的。 4). 与第三点一脉相承printf()经常有重入和性能上的问题。如果你丢掉了第三和第四点我不会太为难你的。不用说如果你能得到后两点那么你的被雇用前景越来越光明了。 代码例子Code examples 12 . 下面的代码输出是什么为什么 void foo(void) { unsigned int a 6; int b -20; (ab 6) puts( 6) : puts( 6); } 这个问题测试你是否懂得C语言中的整数自动转换原则我发现有些开发者懂得极少这些东西。不管如何这无符号整型问题的答案是输出是“6”。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。 因此-20变成了一个非常大的正整数所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题你也就到了得不到这份工作的边缘。 13. 评价下面的代码片断 unsigned int zero 0; unsigned int compzero 0xFFFF; /*1s complement of zero */ 对于一个int型不是16位的处理器为说上面的代码是不正确的。应编写如下 unsigned int compzero ~0; 这一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的经验里好的嵌入式程序员非常准确地明白硬件的细节和它的局限然而PC机程序往往把硬件作为一个无法避免的烦恼。 到了这个阶段应试者或者完全垂头丧气了或者信心满满志在必得。如果显然应试者不是很好那么这个测试就在这里结束了。但如果显然应试者做得不错那么我就扔出下面的追加问题这些问题是比较难的我想仅仅非常优秀的应试者能做得不错。提出这些问题我希望更多看到应试者应付问题的方法而不是答案。不管如何你就当是这个娱乐吧… 动态内存分配Dynamic memory allocation 14. 尽管不像非嵌入式计算机那么常见嵌入式系统还是有从堆heap中动态分配内存的过程的。那么嵌入式系统中动态分配内存可能发生的问题是什么 这里我期望应试者能提到内存碎片碎片收集的问题变量的持行时间等等。这个主题已经在ESP杂志中被广泛地讨论过了主要是 P.J. Plauger, 他的解释远远超过我这里能提到的任何解释所有回过头看一下这些杂志吧让应试者进入一种虚假的安全感觉后我拿出这么一个小节目下面的代码片段的输出是什么为什么 char *ptr; if ((ptr (char *)malloc(0)) NULL) puts(Got a null pointer); else puts(Got a valid pointer); 这是一个有趣的问题。最近在我的一个同事不经意把0值传给了函数malloc得到了一个合法的指针之后我才想到这个问题。这就是上面的代码该代码的输出是“Got a valid pointer”。我用这个来开始讨论这样的一问题看看被面试者是否想到库例程这样做是正确。得到正确的答案固然重要但解决问题的方法和你做决定的基本原理更重要些。 Typedef 15. Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如思考一下下面的例子 #define dPS struct s * typedef struct s * tPS; 以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢如果有的话为什么 这是一个非常微妙的问题任何人答对这个问题正当的原因是应当被恭喜的。答案是typedef更好。思考下面的例子 dPS p1,p2; tPS p3,p4; 第一个扩展为 struct s * p1, p2; 上面的代码定义p1为一个指向结构的指p2为一个实际的结构这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。 晦涩的语法 16. C语言同意一些令人震惊的结构,下面的结构是合法的吗如果是它做些什么 int a 5, b 7, c; c ab; 这个问题将做为这个测验的一个愉快的结尾。不管你相不相信上面的例子是完全合乎语法的。问题是编译器如何处理它水平不高的编译作者实际上会争论这个问题根据最处理原则编译器应当能处理尽可能所有合法的用法。因此上面的代码被处理成 c a b; 因此, 这段代码持行后a 6, b 7, c 12。 如果你知道答案或猜出正确答案做得好。如果你不知道答案我也不把这个当作问题。我发现这个问题的最大好处是:这是一个关于代码编写风格代码的可读性代码的可修改性的好的话题 群硕笔试
基本概念涉及到C、Java、软件测试、EJB、ASP和ASP.NET的知识。
今天群硕笔试考了好多内容其中Java占很大部分
本试卷中最有难度的编程题给定一个数组这个数组中既有正数又有负数找出这个数组中的子数组此子数组的和最大
#includestdio.h void main() { int a[15]{2,3,-4,5,6,-5,-1,14,9,-10,1,-71,75,4,-9}; int b[15]; //计算和 int numa[14]; int c[15]; //最大尾数标志数组 int n14; int i,j0; for(i14;i0;i--) //从后计算和放入b中 { c[i]n;b[i]num; if(num0){ni-1;num0;} numnuma[i-1]; } printf(/n); for(i0;i15;i) printf(%d, ,b[i]); printf(/n); //找到最大字符子串 numb[0];nc[0]; for(i0;i15;i) if(b[i]num){numb[i];ji;nc[i];} for(ij;in;i) printf(%d, ,a[i]); printf(sum%d,num); }
最不知道怎么答的题在TCP/IP中最经常使用的编程方法
最简单的题final, finally, finalize的区别因为经常考
final—修饰符关键字如果一个类被声明为final意味着它不能再派生出新的子类不能作为父类被继承。因此一个类不能既被声明为 abstract的又被声明为final的。将变量或方法声明为final可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值而在以后的引用中只能读取不可修改。被声明为final的方法也同样只能使用不能重载。
finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常那么相匹配的 catch 子句就会执行然后控制就会进入 finally 块如果有的话。
finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。
最容易疏忽的题main(){C c;}在前面已经定义了C的类这个地方容易迷糊的就是没有new照样执行构造函数没有free照样执行析构函数。
最迷糊的题一个无向图是否能够存到树中为什么
最然我感到有差距的题EJB中一定包括interfaceinterfaceclass
不用任何变量交换ab两个变量 用递归求最大公约数
举一个多态的例子 二叉平衡树特性内插入和 外 插入) UNIX进程包括那三个部分:...简单 new动态分配失败会抛出什么异常,C中提供了那两个标准函数来设定异常处理HANLDER有点难度 EJB包含那几种?区别压根没听过 asp和asp.net的区别假期做项目的时候碰到过嘿嘿 JAVA中的interface 和 abstract class区别照着c里面的感念随便写了点 logic thinking:检测电冰箱我用软件工程的思想随便写写
1.内连接与外连接的区别。 3.内联的定义什么情况下选择内联。 4.什么是多态用一段代码说明。 5.不经过第三者变量来交换两个整型数。 6.EJB都有那些Beans. 7.什么是平衡二叉树。 8.当new出错后怎么处理。 9.asp与asp.net的最大区别。 10.如何证明一个电冰箱是否是好的 1-1000放在含有1001个元素的数组中只有唯一的一个元素值重复其它均只出现 一次。每个数组元素只能访问一次设计一个算法将它找出来不用辅助存储空 间能否设计一个算法实现
template typename T, int index struct SumArr { static int GetValue(T* arr) { return arr[index] SumArrT, index-1::GetValue(arr); } }; template typename T struct SumArrT, 0 { static int GetValue(T* arr) { return arr[0]; } }; int main() { int arry[11] {1,2,3,4,5,6,7,8,9,10,2}; printf(%d, SumArrint, 10::GetValue(arry) - 11 * 5); } 基础题
1_1 什么叫做多态性? 在C中是如何实现多态的?
解多态是指同样的消息被不同类型的对象接收时导致完全不同的行为是对类的特定成员函数的再抽象。C支持的多态有多种类型重载(包括函数重载和运算符重载)和虚函数是其中主要的方式。
1_2 什么叫做抽象类? 抽象类有何作用? 抽象类的派生类是否一定要给出纯虚函数的实现?
解带有纯虚函数的类是抽象类。抽象类的主要作用是通过它为一个类族建立一个公共的接口使它们能够更有效地发挥多态特性。抽象类声明了一组派生类共同操作接口的通用语义而接口的完整实现即纯虚函数的函数体要由派生类自己给出。但抽象类的派生类并非一定要给出纯虚函数的实现如果派生类没有给出纯虚函数的实现
这个派生类仍然是一个抽象类。 autodesk笔试
晚上参加了autodesk笔试,留下了一丝的残念,mfc好久没有用几乎忘光了,com学院没有开这门课,还得靠自学T_T晚上听了报告,发现autodesk公司真的很不错.在cadc部门能接触到autocad最核心的代码,这是在另外很多外企所碰不到的.autolove部分那张脸上充满笑容忘着远方的小女孩的照片很让人感动,很钦佩autodesk公司所做的公益活动.得复习一下专业知识了,以后还将有很多的招聘会.
附笔试题目:
1What is virtual function what is vtable used for 虚函数主要用于实现多态用基类的某个函数前加个Virtual 用来告诉编译系统遇到这个处理过程时要等到执行时再确定到底调用哪个类的处理过程
每一个虚函数都会有一个入口地址虚函数表保存所有虚函数的入口地址 2.Whats the difference between struct and class in c? struct成员默认类型为public,class成员默认类型为private。即为数据的封装。
如果没有多态和虚拟继承在C中struct和class的存取效率完全相同简单的说就是存取class的data member和非virtual function效率和struct完全相同不管该data member是定义在基类还是派生类的。如果不是为了和C兼容C中就不会有struct关键字。
3.What do we need to make destructor vitual?why? CObject的析构函数设为virtual型则所有CObject类的派生类的析构函数都将自动变为virtual型这保证了在任何情况下不会出现由于析构函数未被调用而导致的内存泄露 4.What to declare member function as const? void fun1(int a) constconst的作用是指在该函数内部不会改变此类的成员变量(除非该成员变量定义时加上violate关键字),否则修改了该成员变量就会报错. 5.What is the Message reflection in MFC? 6.How many ways to get the handle of a model dialog?what are they? 7.How to change the default window procedure after the window shows up? 8.What is the difference between STA and MTA in COM? 9.What is marshaling in COM? 10.What is dual interface in COM? 11.What is the difference between aggregated and contained object in COM? 12.Write an insert function for a sorted singly linked list please take into considerations of various conditions including error conditions? 13.智力题目. 甲乙丙丁是血缘关系其中一个与其他三个性别不同其中有甲的母亲乙的哥哥丙的父亲丁的女儿。知道其中年龄最大的和最小的性别不同,问谁和其他人性别不同。
1. dynamic binding
2. default private
3. for safe deleting base classes
4. sometype foo const;
5. use some macro, create a message table
6-12. ill keep it blank...
13. 丁最大男的 Autodesk笔试题目
C/C Programming 1列出两个情况是必须使用成员初始化列表而不在构造函数里面赋值 2#define DOUBLE(x) xx i 5 * DOUBLE(10) 这个时候i是什么结果 正确的DOUBLE应该怎样写 3static_cast和dynamic_cast有什么区别 4namespace解决了什么问题 5auto_ptr是什么东西有什么用 Algorithm and GP 1 写出三个你熟悉的排序法以时间复杂度的大小排序 2 写出一个使用递归来反转一个单向链表的函数 3 写一个程序测试系统是Big_Endian的还是Little_Endian的以前万老师发帖讨论过了 C Programming 1 C有管理多种内存分别写出他们是什么他们的特性和性能如何 2 写出一个基于char*的string类包括构造析构函数和赋值运算符取字串长度等基本操作 Graphic两题都不会全忘了 …… IQ 1 称面粉经典题 2 在平面上有一系列间距为2的无限长的平行线在上面扔单位长度的线段和平行线相交的概率是多少 3 A君和B君见到B君的三个熟人XYZ A君问B君“他们的多大” B君说“他们的年龄之和是我们的年龄之和他们的年龄的乘积是2450” A说“我还是不知道” B说“他们都比我们的朋友C要小” A说“那我知道了” 问C的年龄是多少
MFC不太会做记不清楚了 1 怎么为窗口自定义消息
窗口自定义消息。。需用宏定义。。声明消息为WM_USER以后的消息号。。然后用USER_COMMAND做消息映射。。。最后。。自己搞个callback。。。
2 SendMessage和PostMessage的区别
sendmessage是消息发送给指定的callback函数后立即执行。。当前的调用挂起。。postmessage只是把消息发送到消息队列。。然后返回。。。所以在消息循环中。。用的是postmessage而不是sendmessage。。
3 CRuntimeClass是由什么用的他是怎样得到的?
4 怎样通过一个句柄得到CWnd的指针
fromhandle函数可以得到指定cwnd的m_hwnd。。 笔试博朗 - [笔试 职业] 早上起的早了一点刚好看到版上置顶的帖子第一个是博朗反正也没有别的事抄了一份简历过去。 笔试分为两个部分综合素质测试以及软件知识相关。软件考试如同考高程一共20个题目。大概有操作系统的状态转换
三态:运行态,就绪态,等待态
硬件中断
有限自动向量机
有限自动机(Finite Automata):有限自动机有限控制器字符输入带
如果有限状态机每次转换后的状态是唯一的则称之为确定有限状态机(DFA);如果转换后的后继状态不是唯一的则称之为不确定有限自动机(NFA);
数据库
链表操作出入新元素很简单
数据结构中的树
加密问题
PING的协议ICMP
Ping命令是在互连网络中进行故障检测的工具,通俗地说就是它向指定的机器发送一个消息,然后通知是否成功地传送了该消息. ping利用了ICMP中的请求回显和应答回显的功能. ping 程序是用来探测主机到主机之间是否可通信如果不能ping到某台主机表明不能和这台主机建立连接。ping 使用的是ICMP协议它发送icmp回送请求消息给目的主机。ICMP协议规定目的主机必须返回ICMP回送应答消息给源主机。如果源主机在一定时间内收到应答则认为主机可达。
ICMP协议通过IP协议发送的IP协议是一种无连接的不可靠的数据包协议。在Unix/Linux序列号从0开始计数依次递增。而Windows ping程序的ICMP序列号是没有规律。
UML知识全军覆没没接触过这玩意
用对象模型、动态模型、功能模型和用例模型共同完成对整个系统的建模. UML的定义包括UML语义和UML表示法两个部分.从应用的角度看当采用面向对象技术设计系统时首先是描述需求其次根据需求建立系统的静态模型以构造系统的结构第三步是描述系统的行为。其中在第一步与第二步中所建立的模型都是静态的包括用例图、类图包含包、对象图、组件图和配置图等五个图形是标准建模语言UML的静态建模机制。其中第三步中所建立的模型或者可以执行或者表示执行时的时序状态或交互关系。它包括状态图、活动图、顺序图和合作图等四个图形是标准建模语言UML的动态建模机制。因此标准建模语言UML的主要内容也可以归纳为静态建模机制和动态建模机制两大类。 UML的组成
UML模型还可作为测试阶段的依据。系统通常需要经过单元测试、集成测试、系统测试和验收测试。不同的测试小组使用不同的UML图作为测试依据单元测试使用类图和类规格说明集成测试使用部件图和合作图系统测试使用用例图来验证系统的行为验收测试由用户进行以验证系统测试的结果是否满足在分析阶段确定的需求。
UML的静态建模 机制包括用例图(Use case diagram)、类图(Class diagram)、对象图(Object diagram )、包(Package)、构件图(Component diagram)和配置图(Deployment diagram)。
在UML中,一个用例模型由若干个用例图描述,用例图主要 元素是用例和执行者。用例(use case) 从本质上讲,一个用例是用户与计算机之间的一次典型交互作用。在UML中,用例表示为一个椭圆。执行者(Actor) 执行者是指用户在系统中所扮演的角色。其图形化的表示是一个小人。
在UML中,类 和对象模型分别由类图和对象图表示. UML规定类的属性的语法为: 可见性 属性名 : 类型 缺省值 {约束特性} 图1客户类中,客户名属性描述为- 客户名 : 字符串 缺省客户名。
常用的可见性有Public、Private和Protected三种,在U ML中分别表示为、-和#。
关联类通过一根虚线与关联连接。
聚集和组成 聚集(Aggregation)是一种特殊形式的关联。聚集表示类之间的关系是 整体与部分的关系。一辆轿车包含四个车轮、一个方向盘、一个发动机和一个底盘,这是 聚集的一个例子。在需求分析中,包含、组成、分为……部分等经常设计成聚集关 系。聚集可以进一步划分成共享聚集(Shared Aggregation)和组成。
已知后序中序求前序
堆的结构。 答的惨不忍睹啊数了数大概就10个能对的其他是一点吃不准。 考完软件立刻考逻辑就是一大堆的数据40个题目40min要做完。可怜我还没有计算器做的我累死了。到最后还有10几个没勾我也懒得乱勾了。交卷。 有几点点要bs一下这个公司
Java中除了使用new还有其他的实例化方法吗(我说了ClassLoader和Class.forNa me他就继续问了些然后我感觉没底) 2.java.util包中你最常用那些类(我说Collection)Collection分那两类List和Set 有什么区别?自定义对象如何保证在Set中的唯一性(我回答equalshashCode) 3.谈谈JDBC中的DataSource 4.JSP中如何包含其他页面?(我回答jsp:include标签和include指令)然后他问我两个之 间差别 5.servlet中有哪些接口和方法GET和POST请求有哪些区别 6.分布式事务处理和RMI?(这些我不是很熟只是接触过所以就老实回答我不知道) 7.Applet和普通Application的区别Applet如何获取哪些安全权限(我回答了两种方 式和应用情况)然后他就问Java的安全机制有哪些 8.谈谈PKI和数字证书(我的项目有PKI) 9.JDOMDOM有哪些优缺点SAX 10.JAVA多线程如何实现如何获得共享对象的副本(我回答clone和并发控制他觉得 不是很满意可能我回答得不到点) 11.J2EE有哪些设计模式会话外观是什么 12.UML里你常用哪些图用例图是什么如何描述用例里面的流程(我回答了用例描述 和活动图) 14.数据库和J2EE服务器用过哪些说了些软件然后我主动说里面的机理不熟。 这个东西有些参考价值,和同学讨论一下发现还是有些错误, 1已知strcpy 函数的原型是 char *strcpy(char *strDest, const char *strSrc); 其中strDest 是目的字符串strSrc 是源字符串。不调用C/C 的字符串库函数请编写函数 strcpy 答案 char *strcpy(char *strDest, const char *strSrc) { if ( strDest NULL || strSrc NULL) return NULL ; if ( strDest strSrc) return strDest ; char *tempptr strDest ; while( (*strDest *strSrc) ! ‘’); return tempptr ; } 2已知类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 个函数。 答案 String::String(const char *str) { if ( str NULL ) //strlen在参数为NULL时会抛异常才会有这步判断 { m_data new char[1] ; m_data[0] ; } else { m_data new char[strlen(str) 1]; strcpy(m_data,str); } } String::String(const String other) { m_data new char[strlen(other.m_data) 1]; strcpy(m_data,other.m_data); } String String::operator (const String other) { if ( this other) return *this ; delete []m_data; m_data new char[strlen(other.m_data) 1]; strcpy(m_data,other.m_data); return *this ; } String::~ String(void) { delete []m_data ; } 3.简答 3.1 头文件中的ifndef/define/endif 干什么用 答防止该头文件被重复引用。 3.2#include filename.h 和#include “filename.h” 有什么区别 答对于#include filename.h 编译器从标准库路径开始搜索filename.h 对于#include “filename.h”编译器从用户的工作路径开始搜索filename.h 3.3 在C 程序中调用被C 编译器编译后的函数为什么要加extern “C” 答C语言支持函数重载C 语言不支持函数重载。函数被C编译后在库中的名字与C 语言的不同。假设某个函数的原型为 void foo(int x, int y); 该函数被C 编译器编译后在库中的名字为_foo 而C 编译器则会产生像_foo_int_int 之类的名字。 C提供了C 连接交换指定符号extern“C”来解决名字匹配问题。 3.4 一个类有基类、内部有一个其他类的成员对象构造函数的执行顺序是怎样的。Autodesk 答先执行基类的如果基类当中有虚基类要先执行虚基类的其他基类则按照声明派生类时的顺序依次执行再执行成员对象的最后执行自己的。 3.5 请描述一个你熟悉的设计模式(Autodesk) 3.6 在UML 中聚合(aggregation)和组合(composition)有什么区别 Autodesk) 答案聚合关系更强类似于pages 和book 的关系组合关系要弱类似于books和bookshelf 的关系。 3.7C#和C除了语法上的差别以外有什么不同的地方(AutodeskMicrosoft) 答案C#我只是了解不是很精通 (1) c#有垃圾自动回收机制程序员不用担心对象的回收。(2)c#严禁使用指针只能处理对象。如果希望使用指针则仅可在unsafe 程序块中能使用指针。(3)c#只能单继承。(4)必须通过类名访问静态成员。不能像C中那样通过对象访问静态成员。(5)在子类中覆盖父类的虚函数时必须用关键字override,覆盖父类的方法要用关键字new 3.8ADO.net 和ADO 的区别 答案实际上除了“能够让应用程序处理存储于DBMS 中的数据“这一基本相似点外两者没有太多共同之处。但是ADO 使用OLE DB 接口并基于微软的COM 技术而ADO.NET 拥有自己的ADO.NET 接口并且基于微软的.NET 体系架构。众所周知.NET 体系不同于COM 体系ADO.NET 接口也就完全不同于ADO和OLE DB 接口这也就是说ADO.NET 和ADO是两种数据访问方式。ADO.net 提供对XML 的支持。 3.9 New delete 与malloc free 的区别 ( Autodesk) 答案用malloc 函数不能初始化对象new 会调用对象的构造函数。Delete 会调用对象的destructor而free 不会调用对象的destructor. 3.10 #define DOUBLE(x) xx (Autodesk) i 5*DOUBLE(10) i 是多少正确的声明是什么 答案i 为60。正确的声明是#define DOUBLE(x) (xx) 3.11 有哪几种情况只能用intialization list 而不能用assignment? (Autodesk) 答案当类中含有const、reference 成员变量基类的构造函数都需要参数类中含有其他类的成员对象而该类的构造函数都需要参数。 3.11 C是不是类型安全的 (Autodesk) 答案不是。两个不同类型的指针之间可以强制转换。C#是类型安全的。 3.12 main 函数执行以前还会执行什么代码 (Autodesk) 答案全局对象的构造函数会在main 函数之前执行。 3.13 描述内存分配方式以及它们的区别。 (Autodesk , Microsoft) 答案1 从静态存储区域分配。内存在程序编译的时候就已经分配好这块内存在程序的整个运行期间都存在。例如全局变量static 变量。 2 在栈上创建。在执行函数时函数内局部变量的存储单元都可以在栈上创建函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。 3 从堆上分配亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由我们决定使用非常灵活但问题也最多。 3.14 什么是虚拟存储器virtual memory 怎样映射到physical memory?页面替换算法有哪些 (Microsoft) 见操作系统 p238 页。掌握的页面替换算法NRUFIFO第二次机会页面替换算法LRU 3.15 有四个同样的容器里面装满了粒数相同的药丸正常药丸的质量为m,变质药丸的质量为m1,现在已知这四个容器中有一个装的全是变质药丸用电子秤只称一次找出哪个容器装的是变质药丸 Microsoft 答案把四个容器依次编号为1、2、3、4然后从中分别取出1、2、3、4 粒药丸称这10 粒药丸的质量如果质量为10m1,则说明第一个容器装的是变质药丸如果为10m2 则说明第二个装的变质药丸依次类推。 3.16 比较一下C中static_cast 和 dynamic_cast 的区别。 (Autodesk dynamic_casts在帮助你浏览继承层次上是有限制的。它不能被用于缺乏虚函数的类型上它被用于安全地沿着类的继承关系向下进行类型转换。如你想在没有继承关系的类型中进行转换你可能想到static_cast 3.17 Struct 和class 的区别 (Autodesk) 答案struct 中成员变量和成员函数默认访问权限是public,class 是private 3.18 当一个类A 中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少如果不是零请解释一下编译器为什么没有让它为零。Autodesk 答案肯定不是零。我举个反例如果是零的话声明一个class A[10]对象数组而每一个对象占用的空间是零这时就没办法区分A[0],A[1]…了 3.19 在8086 汇编下逻辑地址和物理地址是怎样转换的Intel 答案通用寄存器给出的地址是段内偏移地址相应段寄存器地址*10H通用寄存器内地址就得到了真正要访问的地址。 3.20 描述一下C的多态 microsoft 答案C的多态表现在两个部分一个是静态连编下的函数重载运算符重载动态连编下的虚函数、纯虚函数抽象类 4.写出BOOL,int,float,指针类型的变量a 与零的比较语句。 答案 BOOL : if ( !a ) int : if ( a 0) float : const EXPRESSION EXP 0.000001 if ( a EXP a -EXP) pointer : if ( a ! NULL) 5.请说出const 与#define 相比优点 答案 1 const 常量有数据类型而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换没有类型安全检查并且在字符替换可能会产生意料不到的错误。 2 有些集成化的调试工具可以对const 常量进行调试但是不能对宏常量进行调试。 6简述数组与指针的区别 数组要么在静态存储区被创建如全局数组要么在栈上被创建。指针可以随时指向任意类型的内存块。 (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 字节 } 7类成员函数的重载、覆盖和隐藏区别 答案 成员函数被重载的特征 1相同的范围在同一个类中 2函数名字相同 3参数不同 4virtual 关键字可有可无。 覆盖是指派生类函数覆盖基类函数特征是 1不同的范围分别位于派生类与基类 2函数名字相同 3参数相同 4基类函数必须有virtual 关键字。 “隐藏”是指派生类的函数屏蔽了与其同名的基类函数规则如下 1如果派生类的函数与基类的函数同名但是参数不同。此时不论有无virtual关键字基类的函数将被隐藏注意别与重载混淆。 2如果派生类的函数与基类的函数同名并且参数也相同但是基类函数没有virtual 关键字。此时基类的函数被隐藏注意别与覆盖混淆 8There are two int variables: a and b, don’t use “if”, “? :”, “switch” or other judgement statements, find out the biggest one of the two numbers. 答案( ( a b ) abs( a – b ) ) / 2 9如何打印出当前源文件的文件名以及源文件的当前行号 答案 cout __FILE__ ; cout__LINE__ ; __FILE__和__LINE__是系统预定义宏这种宏并不是在某个文件中定义的而是由编译器定义的。 10main 主函数执行完毕后是否可能会再执行一段代码给出说明 答案可以可以用_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 address of a function (func) to be called when the program terminates normally. Successive calls to _onexit create a register of functions that are executed in LIFO (last-in-first-out) order. The functions passed to _onexit cannot take parameters. 11如何判断一段程序是由C 编译程序还是由C编译程序编译的 答案 #ifdef __cplusplus coutc; #else coutc; #endif 12文件中有一组整数要求排序后输出到另一个文件中 答案 void Order(vectorint data) //起泡排序 { 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[j1]) { tag true ; int temp data[j] ; data[j] data[j1] ; data[j1] temp ; } } if ( !tag ) break ; } } void main( void ) { vectorintdata; ifstream in(c://data.txt); if ( !in) { coutfile error!; exit(1); } int temp; while (!in.eof()) { intemp; data.push_back(temp); } in.close(); Order(data); ofstream out(c://result.txt); if ( !out) { coutfile error!; exit(1); } for ( i 0 ; i data.size() ; i) outdata[i] ; out.close(); } 13排序方法比较 intel 排序方法 平均时间 最坏时间 辅助存储 直接插入排序 起泡排序 快速排序 简单选择排序 堆排序 归并排序 基数排序 14一个链表的结点结构 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 ; } (2)已知两个链表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 ; } 15分析一下这段程序的输出 (Autodesk) class B { public: B() { coutdefault constructorendl; } ~B() { coutdestructedendl; } B(int i):data(i) { coutconstructed by parameter data endl; } private: int data; }; B Play( B b) { return b ; } int main(int argc, char* argv[]) { B temp Play(5); return 0; } 请自己执行一下看看。 16.写一个函数找出一个整数数组中第二大的数 microsoft 答案 const int MINNUMBER -32767 ; int find_sec_max( int data[] , int count) //类似于1 4 4 4这样的序列将认为1是第二大数 { 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 ; } 17 写一个在一个字符串中寻找一个子串第一个位置的函数 这个题目的一般算法比较简单我就不给出了如果要求高效率的话请参见数据结构中的KMP 算法不过在笔试时间有限情况下写出那个算法还是挺难的。 英文题目 1. Introduce yourself in English 2. What is your great advantage you think of yourself? 3. What is your drawback you think of yourself? Maybe I will feel very tense if I make a speech in front of a lot of people. 4. How do you feel shanghai? C语言面试题大汇总 2.用户输入M,N值从1至N开始顺序循环数数每数到M输出该数值直至全部输出。写出C程序。 循环链表用取余操作做 3.不能做switch()的参数类型是 switch的参数不能为实型。 4. static有什么用途请至少说明两种 1.限制变量的作用域 2.设置变量的存储域 7. 引用与指针有什么区别 1) 引用必须被初始化指针不必。 2) 引用初始化以后不能被改变指针可以改变所指的对象。 2) 不存在指向空值的引用但是存在指向空值的指针。 8. 描述实时系统的基本特性 在特定时间内完成特定的任务实时性与可靠性 9. 全局变量和局部变量在内存中是否有区别如果有是什么区别 全局变量储存在静态数据库局部变量在堆栈 10. 什么是平衡二叉树 左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1 11. 堆栈溢出一般是由什么原因导致的 没有回收垃圾资源 12. 什么函数不能声明为虚函数 constructor 13. 冒泡排序算法的时间复杂度是什么 O(n^2) 14. 写出float x 与“零值”比较的if语句。 if(x0.000001x-0.000001) 16. Internet采用哪种网络协议该协议的主要层次结构 tcp/ip 应用层/传输层/网络层/数据链路层/物理层 17. Internet物理地址和IP地址转换采用什么协议 ARP (Address Resolution Protocol)地址解析协议 18.IP地址的编码分为哪俩部分 IP地址由两部分组成网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。 思科 1. 用宏定义写出swapxy #define swap(x, y) x x y; y x - y; x x - y; 2.数组a[N]存放了1至N-1个数其中某个数重复一次。写一个函数找出被重复的数字.时间复杂度必须为oN函数原型int do_dup(int a[],int N)
答案方法1如果数就是1N-1,那么求出a[N]的和然后减去1N-1就行了。(确定数字1-N)
S N * (N-1) / 2; int i; int s 0; for(i0;iN;i) { s a[i]; } int res s - S;
方法2a[]中的某元素a[i]看做是pi[]数组的下标元素a[i]存储到对应数组下标pi[a[i]]的地址中
#includestdio.h #define N 10 void main() { int a[N]{1,2,3,4,5,6,7,7,8,9}; int pi[N]{0}; int key0; for(int i0;iN;i) { if(pi[a[i]]0) pi[a[i]]a[i]; else { keya[i]; break; } } printf(多余的数字是%d/n,key); } 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为需要转换的长度,假设起始点在右边.如x0b0001 0001,p4,n3转换后x0b0110 0001 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; } 慧通 什么是预编译 何时需要预编译 、总是使用不经常改动的大型代码体。 、程序由多个模块组成所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下可以将所有包含文件预编译为一个预编译头。 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是指针它们指向相同的常量区域。 一个32位的机器,该机器的指针是多少位 指针是多少位只要看地址总线的位数就行了。80386以后的机子都是32的数据总线。所以指针的位数就是4个字节了。 main() { int a[5]{1,2,3,4,5}; int *ptr(int *)(a1); printf(%d,%d,*(a1),*(ptr-1)); } 输出2,5 *(a1就是a[1]*(ptr-1)就是a[4],执行结果是25a1不是首地址1系统会认为加一个a数组的偏移是偏移了一个数组的大小本例是5个intint *ptr(int *)(a1); 则ptr实际是(a[5]),也就是a5 原因如下 a是数组指针其类型为 int (*)[5];而指针加1要根据指针类型加上一定的值不同类型的指针1之后增加的大小不同a是长度为5的int数组指针所以要加 5*sizeof(int)所以ptr实际是a[5] 但是prt与(a1)类型是不一样的(这点很重要)所以prt-1只会减去sizeof(int*) a,a的地址是一样的但意思不一样a是数组首地址也就是a[0]的地址a是对象数组首地址a1是数组下一元素的地址即a[1],a1是下一个对象的地址即a[5]. 1.请问以下代码有什么问题 int main() { char a; char *stra; strcpy(str,hello); printf(str); return 0; } 没有为str分配内存空间将会发生异常。问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果但因为越界进行内在读写而导致程序崩溃。 char* sAAA; printf(%s,s); s[0]B; printf(%s,s); 有什么错 AAA是字符串常量。s是指针指向这个字符串常量所以声明s的时候就有问题。 cosnt char* sAAA;然后又因为是常量所以对是s[0]的赋值操作是不合法的。 1、写一个“标准”宏这个宏输入两个参数并返回较小的一个。 #define Min(X, Y) ((X)(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 a248; b4;int const c21;const int *da; int *const eb;int const *f const a; 请问下列表达式哪些会被编译器禁止为什么 *c32;db;*d43;e34;ea;f0x321f; *c 这是个什么东东禁止 *d 说了是const 禁止 e a 说了是const 禁止 const *f const a; 禁止 2.交换两个变量的值不使用第三个变量。即a3,b5,交换之后a5,b3; 有两种解法, 一种用算术算法, 一种用^(异或) 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而class默认为private 4.#include stdio.h #include stdlib.h void getmemory(char *p) { p(char *) malloc(100); strcpy(p,hello world); } int main( ) { char *strNULL; getmemory(str); printf(%s/n,str); free(str); return 0; } 程序崩溃getmemory中的malloc 不能返回动态内存 free对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值是相同的 2int main() { int x3; 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 c128; printf(c%d/n,c); 输出多少并分析过程 第一题A 0xfffffff5,int值 为11但输出的是uint。所以输出4294967285 第二题c0x10,输出的是int最高位为1是负数所以它的值就是0x00的补码就是128所以输出128。 这两道题都是在考察二进制向int或uint转换时的最高位处理。 分析下面的程序 void GetMemory(char **p,int num) { *p(char *)malloc(num); } int main() { char *strNULL; 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之后有一个好的习惯就是将strNULL. 此时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 a0x801010; a5? 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; } 当你第二次调用时得不到正确的结果难道你写个函数就是为了调用一次问题就出在 static上 // 帮忙分析一下 #includeiostream.h #include string.h #include malloc.h #include stdio.h #include stdlib.h #include memory.h 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 endl; cout aa.b2 endl; } 答案是 -16和 首先sizeof(AA)的大小为4,b1和b2分别占5bit和2bit. 经过strcpy和memcpy后,aa的4个字节所存放的值是: 0,1,2,3的ASC码即00110000,00110001,00110010,00110011 所以最后一步显示的是这个字节的前位和之后的位 分别为10000,和01 因为int是有正负之分 所以答案是-16和 求函数返回值输入x9999; int func x { int countx 0; while ( x ) { countx ; x x(x-1); } return countx; } 结果呢 知道了这是统计9999的二进制数值中有多少个1的函数且有 99999×102451225615 9×1024中含有1的个数为2 512中含有1的个数为1 256中含有1的个数为1 15中含有1的个数为4 故共有1的个数为8结果为8。 1000 - 1 0111正好是原数取反。这就是原理。 用这种方法来求1的个数是很效率很高的。 不必去一个一个地移位。循环次数最少。 int a,b,c 请写函数实现Cab ,不可以改变数据类型,如将c改为long int,关键是如何处理溢出问题 bool add (int a, int b,int *c) { *cab; return (a0 b0 (*ca || *cb) || (a0 b0 (*ca || *cb))); } 分析 struct bit { int a:3; int b:2; int c:3; }; int main() { bit s; char *c(char*)s; coutsizeof(bit)endl; *c0x99; cout s.a endl s.bendls.cendl; int a-1; printf(%x,a); return 0; } 输出为什么是 4 1 -1 -4 ffffffff 因为0x99在内存中表示为 100 11 001 , a 001, b 11, c 100 当c为有符合数时, c 100, 最高1为表示c为负数负数在计算机用补码表示所以c -4;同理 b -1; 当c为有符合数时, c 100,即 c 4,同理 b 3 位域 有些信息在存储时并不需要占用一个完整的字节 而只需占几个或一个二进制位。例如在存放一个开关量时只有0和1 两种状态 用一位二进位即可。为了节省存储空间并使处理简便语言又提供了一种数据结构称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域 并说明每个区域的位数。每个域有一个域名允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿其形式为 struct 位域结构名 { 位域列表 }; 其中位域列表的形式为 类型说明符 位域名位域长度 例如 struct bs { int a:8; int b:2; int c:6; }; 位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明同时定义说明或者直接说明这三种方式。例如 struct bs { int a:8; int b:2; int c:6; }data; 说明data为bs变量共占两个字节。其中位域a占8位位域b占2位位域c占6位。对于位域的定义尚有以下几点说明 1. 一个位域必须存储在同一个字节中不能跨两个字节。如一个字节所剩空间不够存放另一位域时应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如 struct bs { unsigned a:4 unsigned :0 /*空域*/ unsigned b:4 /*从下一单元开始存放*/ unsigned c:4 } 在这个位域定义中a占第一字节的4位后4位填0表示不使用b从第二字节开始占用4位c占用4位。 2. 由于位域不允许跨两个字节因此位域的长度不能大于一个字节的长度也就是说不能超过8位二进位。 3. 位域可以无位域名这时它只用来作填充或调整位置。无名的位域是不能使用的。例如 struct k { int a:1 int :2 /*该2位不能使用*/ int b:3 int c:2 }; 从以上分析可以看出位域在本质上就是一种结构类型 不过其成员是按二进位分配的。 二、位域的使用位域的使用和结构成员的使用相同其一般形式为 位域变量名#8226;位域名 位域允许用各种格式输出。 main(){ struct bs { unsigned a:1; unsigned b:3; unsigned c:4; } bit,*pbit; bit.a1; bit.b7; bit.c15; pri 改错 #include stdio.h int main(void) { int **p; int arr[100]; p arr; return 0; } 解答 搞错了,是指针类型不同, int **p; //二级指针 arr; //得到的是指向第一维为100的数组的指针 #include stdio.h int main(void) { int **p, *q; int arr[100]; q arr; p q; return 0; } 下面这个程序执行后会有什么错误或者效果: #define MAX 255 int main() { unsigned char A[MAX],i;//i被定义为unsigned char for (i0;iMAX;i) A[i]i; } 解答死循环加数组越界访问C/C不进行数组越界检查 MAX255 数组A的下标范围为:0..MAX-1,这是其一.. 其二.当i循环到255时,循环内执行: A[255]255; 这句本身没有问题..但是返回for (i0;iMAX;i)语句时, 由于unsigned char的取值范围在(0..255),i以后i又为0了..无限循环下去. struct name1{ char str; short x; int num; } struct name2{ char str; int num; short x; } sizeof(struct name1)8,sizeof(struct name2)12 在第二个结构中为保证num按四个字节对齐char后必须留出3字节的空间同时为保证整个结构的自然对齐这里是4字节对齐在x后还要补齐2个字节这样就是12字节。 intel A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里栈还是堆或者其他的? static的全局变量表明这个变量仅在本模块中有意义不会影响其他模块。 他们都放在数据区但是编译器对他们的命名是不同的。 如果要使变量在其他模块也有意义的话需要使用extern关键字。 struct s1 { int i: 8; int j: 4; int a: 3; double b; }; struct s2 { int i: 8; int j: 4; double b; int a:3; }; printf(sizeof(s1) %d/n, sizeof(s1)); printf(sizeof(s2) %d/n, sizeof(s2)); result: 16, 24 第一个struct s1 { int i: 8; int j: 4; int a: 3; double b; }; 理论上是这样的首先是i在相对0的位置占8位一个字节然后j就在相对一个字节的位置由于一个位置的字节数是4位的倍数因此不用对齐就放在那里了然后是a要在3位的倍数关系的位置上因此要移一位在15位的位置上放下目前总共是18位折算过来是2字节2位的样子由于double是8字节的因此要在相对0要是8个字节的位置上放下因此从18位开始到8个字节之间的位置被忽略直接放在8字节的位置了因此总共是16字节。 第二个最后会对照是不是结构体内最大数据的倍数不是的话会补成是最大数据的倍数 1读文件file1.txt的内容例如 12 34 56 输出到file2.txt 56 34 12 逆序 2输出和为一个给定整数的所有组合 例如n5 514523相加的数不能重复 则输出 1423。 望高手赐教 第一题,注意可增长数组的应用. #include stdio.h #include stdlib.h int main(void) { int MAX 10; int *a (int *)malloc(MAX * sizeof(int)); int *b; FILE *fp1; FILE *fp2; fp1 fopen(a.txt,r); if(fp1 NULL) {printf(error1); exit(-1); } fp2 fopen(b.txt,w); if(fp2 NULL) {printf(error2); exit(-1); } int i 0; int j 0; while(fscanf(fp1,%d,a[i]) ! EOF) { i; j; if(i MAX) { MAX 2 * MAX; b (int*)realloc(a,MAX * sizeof(int)); if(b NULL) { printf(error3); exit(-1); } a b; } } for(;--j 0;) fprintf(fp2,%d/n,a[j]); fclose(fp1); fclose(fp2); return 0; } 第二题. #include stdio.h int main(void) { unsigned long int i,j,k; printf(please input the number/n); scanf(%d,i); if( i % 2 0) j i / 2; else j i / 2 1; printf(The result is /n); for(k 0; k j; k) printf(%d %d %d/n,i,k,i - k); return 0; } #include stdio.h void main() { unsigned long int a,i1; scanf(%d,a); if(a%20) { for(i1;ia/2;i) printf(%d,a,a-i); } else for(i1;ia/2;i) printf( %d, %d,i,a-i); } 兄弟,这样的题目若是做不出来实在是有些不应该, 给你一个递规反向输出字符串的例子,可谓是反序的经典例程. void inverse(char *p) { if( *p /0 ) return; inverse( p1 ); printf( %c, *p ); } int main(int argc, char *argv[]) { inverse(abc/0); return 0; } 借签了楼上的“递规反向输出” #include stdio.h void test(FILE *fread, FILE *fwrite) { char buf[1024] {0}; if (!fgets(buf, sizeof(buf), fread)) return; test( fread, fwrite ); fputs(buf, fwrite); } int main(int argc, char *argv[]) { FILE *fr NULL; FILE *fw NULL; fr fopen(data, rb); fw fopen(dataout, wb); test(fr, fw); fclose(fr); fclose(fw); return 0; } 在对齐为4的情况下 struct BBB { long num char *name; short int data; char ha; short ba[5]; }*p; p0x1000000; p0x200____; (Ulong)p0x200____; (char*)p0x200____; 希望各位达人给出答案和原因谢谢拉 解答假设在32位CPU上 sizeof(long) 4 bytes sizeof(char *) 4 bytes sizeof(short int) sizeof(short) 2 bytes sizeof(char) 1 bytes 由于是4字节对齐 sizeof(struct BBB) sizeof(*p) 4 4 2 1 1/*补齐*/ 2*5 2/*补齐*/ 24 bytes (经Dev-C验证) p0x1000000; p0x200____; 0x1000000 0x200*24 (Ulong)p0x200____; 0x1000000 0x200 (char*)p0x200____; 0x1000000 0x200*4 你可以参考一下指针运算的细节 写一段程序找出数组中第k大小的数输出数所在的位置。例如{24347}中第一大的数是7位置在4。第二大、第三大的数都是4位置在1、3随便输出哪一个均可。函数接口为int find_orderk(const int* narry,const int n,const int k) 要求算法复杂度不能是O(n^2 谢谢 可以先用快速排序进行排序其中用另外一个进行地址查找 代码如下在VC6.0运行通过。给分吧^-^ //快速排序 #includeiostream usingnamespacestd; intPartition (int*L,intlow,int high) { inttemp L[low]; intpt L[low]; while (low high) { while (low high L[high] pt) --high; L[low] L[high]; while (low high L[low] pt) low; L[low] temp; } L[low] temp; returnlow; } voidQSort (int*L,intlow,int high) { if (low high) { intpl Partition (L,low,high); QSort (L,low,pl - 1); QSort (L,pl 1,high); } } intmain () { intnarry[100],addr[100]; intsum 1,t; cout Input number: endl; cin t; while (t ! -1) { narry[sum] t; addr[sum - 1] t; sum; cin t; } sum - 1; QSort (narry,1,sum); for (int i 1; i sum;i) cout narry[i] /t; cout endl; intk; cout Please input place you want: endl; cin k; intaa 1; intkk 0; for (;;) { if (aa k) break; if (narry[kk] ! narry[kk 1]) { aa 1; kk; } } cout The NO. k number is: narry[sum - kk] endl; cout And its place is: ; for (i 0;i sum;i) { if (addr[i] narry[sum - kk]) cout i /t; } return0; } 1、找错 Void test1() { char string[10]; char* str10123456789; strcpy(string, str1);// 溢出应该包括一个存放/0的字符string[11] } Void test2() { char string[10], str1[10]; for(I0; I10;I) { str1[i] a; } strcpy(string, str1);// Ii没有声明。 } Void test3(char* str1) { char string[10]; if(strlen(str1)10)// 改成10,字符溢出将strlen改为sizeof也可以 { strcpy(string, str1); } } 2. void g(int**); int main() { int line[10],i; int *pline; //p是地址的地址 for (i0;i10;i) { *pi; g(p);//数组对应的值加1 } for(i0;i10;i) printf(%d/n,line[i]); return 0; } void g(int**p) { (**p); (*p);// 无效 } 输出1 2 3 4 5 6 7 8 9 10 3. 写出程序运行结果 int sum(int a) { auto int c0; static int b3; c1; b2; return(abc); } void main() { int I; int a2; for(I0;I5;I) { printf(%d,, sum(a)); } }// 考察static会保存上次结果 输出8,10,12,14,16, 4.int func(int a) { int b; switch(a) { case 1: 30; case 2: 20; case 3: 16; default: 0 } return b; } 则func(1)? // b定义后就没有赋值。
5:int a[3]; a[0]0; a[1]1; a[2]2; int *p, *q; pa; qa[2]; 则a[q-p]a[2]2 解释指针一次移动一个int但计数为1 今天早上的面试题9道比较难向牛人请教国内的一牛公司坐落在北京北四环某大厦 1、线形表a、b为两个有序升序的线形表编写一程序使两个有序线形表合并成一个有序升序线形表h 答案在严锐敏《数据结构第二版》第二章例题数据结构当中这个叫做两路归并排序 Linklist *unio(Linklist *p,Linklist *q){ linklist *R,*pa,*qa,*ra; pap; qaq; Rrap; while(pa-next!NULLqa-next!NULL){ if(pa-dataqa-data){ ra-nextqa; qaqa-next; 取两线性表的大值放入ra并将取值的表指针加1 } else{ ra-nextpa; papa-next; } } if(pa-next!NULL) ra-nextpa; if(qa-next!NULL) ra-nextqa; return R; } 2、运用四色定理为N个局域举行配色颜色为1、2、3、4四种另有数组adj[][N]如adj[i][j]1则表示i区域与j区域相邻数组color[N]如color[i]1,表示i区域的颜色为1号颜色。 四色填充 3、用递归算法判断数组a[N]是否为一个递增数组。递归的方法记录当前最大的并且判断当前的是否比这个还大大则继续否则返回false结束 bool fun( int a[], int n ) { if( n 1 ) return true; if( n 2 ) return a[n-1] a[n-2]; return fun( a,n-1) ( a[n-1] a[n-2] ); } 4、编写算法从10亿个浮点数当中选出其中最大的10000个。google百度腾讯 一种是用外部排序在《数据结构》书上有《计算方法导论》在找到第n大的数的算法上加工
另外一种是用一个有序容器保存10000个数然后其他的数字依次和容器中的最小数字比较如果大于容器已有的就插入容器并删除原先最小的那个而容器仍旧保持有序。 5、编写一unix程序防止僵尸进程的出现. 同学的4道面试题应聘的职位是搜索引擎工程师后两道超级难希望大家多给一些算发 1.给两个数组和他们的大小还有一动态开辟的内存求交集把交集放到动态内存dongtai并且返回交集个数 long jiaoji(long* a[],long b[],long* alength,long blength,long* dongtai[]) 2.单连表的建立把a--z26个字母插入到连表中并且倒叙还要打印 方法1 typedef struct val { int date_1; struct val *next; }*p; void main(void) { char c; for(c122;c97;c--) { p.datec; pp-next; } p.nextNULL; } } 方法2 node *p NULL; node *q NULL; node *head (node*)malloc(sizeof(node)); head-data ;head-nextNULL; node *first (node*)malloc(sizeof(node)); first-data a;first-nextNULL;head-next first; p first; int longth z - b; int i0; while ( ilongth ) { node *temp (node*)malloc(sizeof(node)); temp-data bi;temp-nextNULL;qtemp; head-next temp; temp-nextp;pq; i; } print(head); 3.可怕的题目终于来了 象搜索的输入信息是一个字符串统计300万输入信息中的最热门的前十条我们每次输入的一个字符串为不超过255byte,内存使用只有1G, 请描述思想写出算发c语言空间和时间复杂度 4.国内的一些帖吧如baidu,有几十万个主题假设每一个主题都有上亿的跟帖子怎么样设计这个系统速度最好请描述思想写出算发c语言空间和时间复杂度 #include string.h main(void) { char *srchello,world; char *destNULL; dest(char *)malloc(strlen(src)); int lenstrlen(str); char *ddest; char *ssrc[len]; while(len--!0) ds--; printf(%s,dest); } 找出错误 #include string.h #include stdio.h #include malloc.h main(void) { char *srchello,world; char *destNULL; dest(char *)malloc(sizeof(char)*(strlen(src)1)); int lenstrlen(src); char *ddest; char *ssrclen-1; while(len--!0) *d*s--; *d/0; printf(%s,dest); } 1. 简述一个Linux驱动程序的主要流程与功能。 2. 请列举一个软件中时间换空间或者空间换时间的例子。 void swap(int a,int b) { int c; ca;ab;ba; } ---空优 void swap(int a,int b) { aab;ba-b;aa-b; } 6. 请问一下程序将输出什么结果 char *RetMenory(void) { char p[] “hellow world”; return p; } void Test(void) { char *str NULL; str RetMemory(); printf(str); } RetMenory执行完毕p资源被回收指向未知地址。返回地址str的内容应是不可预测的, 打印的应该是str的地址 写一个函数,它的原形是int continumax(char *outputstr,char *intputstr) 功能 在字符串中找出连续最长的数字串并把这个串的长度返回并把这个最长数字串付给其中一个函数参数outputstr所指内存。例如abcd12345ed125ss123456789的首地址传给intputstr后函数将返回9outputstr所指的值为123456789 int continumax(char *outputstr, char *inputstr) { char *in inputstr, *out outputstr, *temp, *final; int count 0, maxlen 0; while( *in ! /0 ) { if( *in 47 *in 58 ) { for(temp in; *in 47 *in 58 ; in ) count; } else in; if( maxlen count ) { maxlen count; count 0; final temp; } } for(int i 0; i maxlen; i) { *out *final; out; final; } *out /0; return maxlen; } 不用库函数,用C语言实现将一整型数字转化为字符串 方法1 int getlen(char *s){ int n; for(n 0; *s ! /0; s) n; return n; } void reverse(char s[]) { int c,i,j; for(i 0,j getlen(s) - 1; i j; i,j--){ c s[i]; s[i] s[j]; s[j] c; } } void itoa(int n,char s[]) { int i,sign; if((sign n) 0) n -n; i 0; do{/*以反序生成数字*/ s[i] n%10 0;/*get next number*/ }while((n / 10) 0);/*delete the number*/ if(sign 0) s[i] -; s[i] /0; reverse(s); } 方法2: #include iostream using namespace std; void itochar(int num); void itochar(int num) { int i 0; int j ; char stra[10]; char strb[10]; while ( num ) { stra[i]num%1048; numnum/10; } stra[i] /0; for( j0; j i; j) { strb[j] stra[i-j-1]; } strb[j] /0; coutstrbendl; } int main() { int num; cinnum; itochar(num); return 0; } 前几天面试有一题想不明白,请教大家 typedef struct { int a:2; int b:2; int c:1; }test; test t; t.a 1; t.b 3; t.c 1; printf(%d,t.a); printf(%d,t.b); printf(%d,t.c); 谢谢! t.a为01,输出就是1 t.b为11输出就是1 t.c为1输出也是-1 3个都是有符号数int嘛。 这是位扩展问题 01 11 1 编译器进行符号扩展 求组合数 求n个数1....n中k个数的组合.... 如combination(5,3) 要求输出543542541532531521432431421321 #includestdio.h int pop(int *); int push(int ); void combination(int ,int ); int stack[3]{0}; top-1; int main() { int n,m; printf(Input two numbers:/n); while( (2!scanf(%d%*c%d,n,m)) ) { fflush(stdin); printf(Input error! Again:/n); } combination(n,m); printf(/n); } void combination(int m,int n) { int tempm; push(temp); while(1) { if(1temp) { if(pop(temp)stack[0]n) //当栈底元素弹出为可能取的最小值循环退出 break; } else if( push(--temp)) { printf(%d%d%d ,stack[0],stack[1],stack[2]);//§auml;¨ì¤? pop(temp); } } } int push(int i) { stack[top]i; if(top2) return 0; else return 1; } int pop(int *i) { *istack[top--]; if(top0) return 0; else return 1; } 1、用指针的方法将字符串“ABCD1234efgh”前后对调显示 #include stdio.h #include string.h #include dos.h int main() { char str[] ABCD1234efgh; int length strlen(str); char * p1 str; char * p2 str length - 1; while(p1 p2) { char c *p1; *p1 *p2; *p2 c; p1; --p2; } printf(str now is %s/n,str); system(pause); return 0; } 2、有一分数序列1/2,1/4,1/6,1/8……用函数调用的方法求此数列前20项的和 #include stdio.h double getValue() { double result 0; int i 2; while(i 42) { result 1.0 / i;//一定要使用1.0做除数不能用1否则结果将自动转化成整数即0.000000 i 2; } return result; } int main() { printf(result is %f/n, getValue()); system(pause); return 0; }
有一个数组a[1000]存放0--1000;要求每隔二个数删掉一个数到末尾时循环至开头继续进行求最后一个被删掉的数的原始下标位置。 以7个数为例 {0,1,2,3,4,5,6,7} 0--1--2删除--3--4--5(删除)--6--7--0删除如此循环直到最后一个数被删除。 方法1数组 #include iostream using namespace std; #define null 1000 int main() { int arr[1000]; for (int i0;i1000;i) arr[i]i; int j0; int count0; while(count999) { while(arr[j%1000]null) j(j)%1000; j(j)%1000; while(arr[j%1000]null) j(j)%1000; j(j)%1000; while(arr[j%1000]null) j(j)%1000; arr[j]null; count; } while(arr[j]null) j(j)%1000; coutjendl; return 0; }方法2链表 #includeiostream using namespace std; #define null 0 struct node { int data; node* next; }; int main() { node* headnew node; head-data0; head-nextnull; node* phead; for(int i1;i1000;i) { node* tmpnew node; tmp-datai; tmp-nextnull; head-nexttmp; headhead-next; } head-nextp; while(p!p-next) { p-next-nextp-next-next-next; pp-next-next; } coutp-data; return 0; } 方法3通用算法 #include stdio.h #define MAXLINE 1000 //元素个数 /* MAXLINE 元素个数 a[] 元素数组 R[] 指针场 suffix 下标 index 返回最后的下标序号 values 返回最后的下标对应的值 start 从第几个开始 K 间隔 */ int find_n(int a[],int R[],int K,int index,int values,int s0) { int suffix; int front_node,current_node; suffix0; if(s0) { current_node0; front_nodeMAXLINE-1; } else { current_nodes; front_nodes-1; } while(R[front_node]!front_node) { printf(%d/n,a[current_node]); R[front_node]R[current_node]; if(K1) { current_nodeR[front_node]; continue; } for(int i0;iK;i){ front_nodeR[front_node]; } current_nodeR[front_node]; } indexfront_node; valuesa[front_node]; return 0; } int main(void) { int a[MAXLINE],R[MAXLINE],suffix,index,values,start,i,K; suffixindexvaluesstart0; K2; for(i0;iMAXLINE;i) { a[i]i; R[i]i1; } R[i-1]0; find_n(a,R,K,index,values,2); printf(the value is %d,%d/n,index,values); return 0; } 试题 void test2() { char string[10], str1[10]; int i; for(i0; i10; i) { str1[i] a; } strcpy( string, str1 ); } 解答对试题2如果面试者指出字符数组str1不能在数组内结束可以给3分如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分在此基础上指出库函数strcpy工作方式的给10分 str1不能在数组内结束:因为str1的存储为{a,a,a,a,a,a,a,a,a,a},没有/0(字符串结束符)所以不能结束 strcpy( char *s1,char *s2)他的工作原理是扫描s2指向的内存逐个字符付到s1所指向的内存直到碰到/0,因为str1结尾没有/0所以具有不确定性不知道他后面还会付什么东东。 正确应如下 void test2() { char string[10], str1[10]; int i; for(i0; i9; i) { str1[i] ai; //把abcdefghi赋值给字符数组 } str[i]/0;//加上结束符 strcpy( string, str1 ); } 第二个code题是实现strcmp int StrCmp(const char *str1, const char *str2) 做是做对了没有抄搞比较乱 int StrCmp(const char *str1, const char *str2) { assert(str1 srt2); while (*str1 *str2 *str1 *str2) { str1, str2; } if (*str1 *str2) return (*str1-*str2); elseif (*str1 *str20) return 1; elseif (*str1 0 *str2) return -1; else return 0; } int StrCmp(const char *str1, const char *str2) { //省略判断空指针(自己保证) while(*str1 *str1 *str2); return *str1-*str2; } 第三个code题是实现子串定位 int FindSubStr(const char *MainStr, const char *SubStr) 做是做对了没有抄搞比较乱 int MyStrstr(const char* MainStr, const char* SubStr) { const char *p; const char *q; const char * u MainStr; //assert((MainStr!NULL)( SubStr!NULL));//用断言对输入进行判断 while(*MainStr) //内部进行递增 { p MainStr; q SubStr; while(*q *p *p *q); if(!*q ) { return MainStr - u 1 ;//MainStr指向当前起始位u指向 } MainStr ; } return -1; } 分析 int arr[] {6,7,8,9,10}; int *ptr arr; *(ptr)123; printf(“ %d %d ”, *ptr, *(ptr)); 输出8 8 过程对于*(ptr)123;先做加法6123然后指针指向7对于printf(“ %d %d ”, *ptr, *(ptr));从后往前执行指针先指向8然后输出8紧接着再输出8
/*雅虎笔试题(字符串操作) 给定字符串A和B,输出A和B中的最大公共子串。 比如Aaocdfe Bpmcdfa 则输出cdf */ //Author: azhen #includestdio.h #includestdlib.h #includestring.h char *commanstring(char shortstring[], char longstring[]) { int i, j; char *substringmalloc(256); if(strstr(longstring, shortstring)!NULL) //如果……那么返回shortstring return shortstring; for(istrlen(shortstring)-1;i0; i--) //否则开始循环计算 { for(j0; jstrlen(shortstring)-i; j){ memcpy(substring, shortstring[j], i); substring[i]/0; if(strstr(longstring, substring)!NULL) return substring; } } return NULL; } main() { char *str1malloc(256); char *str2malloc(256); char *commanNULL; gets(str1); gets(str2); if(strlen(str1)strlen(str2)) //将短的字符串放前面 commancommanstring(str2, str1); else commancommanstring(str1, str2); printf(the longest comman string is: %s/n, comman); } 11.写一个函数比较两个字符串str1和str2的大小若相等返回0若str1大于 str2返回1若str1小于str2返回1 int strcmp ( const char * src,const char * dst) { int ret 0 ; while( ! (ret *(unsigned char *)src - *(unsigned char *)dst) *dst) { src; dst; } if ( ret 0 ) ret -1 ; else if ( ret 0 ) ret 1 ; return( ret ); }
3,求1000的未尾有几个0用素数相乘的方法来做如722*2*2*3*3; 求出1-1000里,能被5整除的数的个数n1,能被25整除的数的个数n2,能被125整除的数的个数n3, 能被625整除的数的个数n4. 1000!末尾的零的个数n1n2n3n4; #includestdio.h #define NUM 1000 int find5(int num){ int ret0; while(num%50){ num/5; ret; } return ret; } int main(){ int result0; int i; for(i5;iNUM;i5) { resultfind5(i); } printf( the total zero number is %d/n,result); return 0; } 1. 有双向循环链表结点定义为 struct node { int data; struct node *front,*next; }; 有两个双向循环链表AB知道其头指针为pHeadA,pHeadB请写一函数将两链表中data值相同的结点删除 BOOL DeteleNode(Node *pHeader, DataType Value) { if (pHeader NULL) return; BOOL bRet FALSE; Node *pNode pHead; while (pNode ! NULL) { if (pNode-data Value) { if (pNode-front NULL) { pHeader pNode-next; pHeader-front NULL; } else { if (pNode-next ! NULL) { pNode-next-front pNode-front; } pNode-front-next pNode-next; } Node *pNextNode pNode-next; delete pNode; pNode pNextNode; bRet TRUE; //不要break或return, 删除所有 } else { pNode pNode-next; } } return bRet; } void DE(Node *pHeadA, Node *pHeadB) { if (pHeadA NULL || pHeadB NULL) { return; } Node *pNode pHeadA; while (pNode ! NULL) { if (DeteleNode(pHeadB, pNode-data)) { if (pNode-front NULL) { pHeadA pNode-next; pHeadA-front NULL; } else { pNode-front-next pNode-next; if (pNode-next ! NULL) { pNode-next-front pNode-front; } } Node *pNextNode pNode-next; delete pNode; pNode pNextNode; } else { pNode pNode-next; } } } 2. 编程实现找出两个字符串中最大公共子字符串,如abccade,dgcadde的最大子串为cad int GetCommon(char *s1, char *s2, char **r1, char **r2) { int len1 strlen(s1); int len2 strlen(s2); int maxlen 0; for(int i 0; i len1; i) { for(int j 0; j len2; j) { if(s1[i] s2[j]) { int as i, bs j, count 1; while(as 1 len1 bs 1 len2 s1[as] s2[bs]) count; if(count maxlen) { maxlen count; *r1 s1 i; *r2 s2 j; } } } } 3. 编程实现把十进制数(long型)分别以二进制和十六进制形式输出不能使用printf系列库函数 char* test3(long num) { char* buffer (char*)malloc(11); buffer[0] 0; buffer[1] x; buffer[10] /0; char* temp buffer 2; for (int i0; i 8; i) { temp[i] (char)(num4*i28); temp[i] temp[i] 0 ? temp[i] : temp[i] 16; temp[i] temp[i] 10 ? temp[i] 48 : temp[i] 55; } return buffer; } 斐波拉契数列递归实现的方法如下 int Funct( int n ) { if(n0) return 1; if(n1) return 1; retrurn Funct(n-1) Funct(n-2); } 请问如何不使用递归来实现上述函数 请教各位高手 解答int Funct( int n ) // n 为非负整数 { int a0; int b1; int c; if(n0) c1; else if(n1) c1; else for(int i2;in;i) //应该n从2开始算起 { cab; ab; bc; } return c; } 解答 现在大多数系统都是将低字位放在前面而结构体中位域的申明一般是先声明高位。 100 的二进制是 001 100 100 低位在前 高位在后 001----s3 100----s2 100----s1 所以结果应该是 1 如果先申明的在低位则 001----s1 100----s2 100----s3 结果是 4 1、原题跟little-endianbig-endian没有关系 2、原题跟位域的存储空间分配有关到底是从低字节分配还是从高字节分配从Dev C和VC7.1上看都是从低字节开始分配并且连续分配中间不空不像谭的书那样会留空位 3、原题跟编译器有关编译器在未用堆栈空间的默认值分配上有所不同Dev C未用空间分配为 01110111bVC7.1下为11001100b,所以在Dev C下的结果为5在VC7.1下为1。 注PC一般采用little-endian即高高低低但在网络传输上一般采用big-endian即高低低高华为是做网络的所以可能考虑big-endian模式这样输出结果可能为4 判断一个字符串是不是回文 int IsReverseStr(char *aStr) { int i,j; int found1; if(aStrNULL) return -1; jstrlen(aStr); for(i0;ij/2;i) if(*(aStri)!*(aStrj-i-1)) { found0; break; } return found; } Josephu 问题为设编号为12… n的n个人围坐一圈约定编号为k1kn的人从1开始报数数到m 的那个人出列它的下一位又从1开始报数数到m的那个人又出列依次类推直到所有人出列为止由此产生一个出队编号的序列。 数组实现 #include stdio.h #include malloc.h int Josephu(int n, int m) { int flag, i, j 0; int *arr (int *)malloc(n * sizeof(int)); for (i 0; i n; i) arr[i] 1; for (i 1; i n; i) { flag 0; while (flag m) { if (j n) j 0; if (arr[j]) flag; j; } arr[j - 1] 0; printf(第%4d个出局的人是%4d号/n, i, j); } free(arr); return j;
} int main() { int n, m; scanf(%d%d, n, m); printf(最后胜利的是%d号/n, Josephu(n, m)); system(pause); return 0; } 链表实现 #include stdio.h #include malloc.h typedef struct Node { int index; struct Node *next; }JosephuNode; int Josephu(int n, int m) { int i, j; JosephuNode *head, *tail; head tail (JosephuNode *)malloc(sizeof(JosephuNode)); for (i 1; i n; i) { tail-index i; tail-next (JosephuNode *)malloc(sizeof(JosephuNode)); tail tail-next; } tail-index i; tail-next head; for (i 1; tail ! head; i) { for (j 1; j m; j) { tail head; head head-next; } tail-next head-next; printf(第%4d个出局的人是%4d号/n, i, head-index); free(head); head tail-next; } i head-index; free(head); return i; } int main() { int n, m; scanf(%d%d, n, m); printf(最后胜利的是%d号/n, Josephu(n, m)); system(pause); return 0; } 已知strcpy函数的原型是 char * strcpy(char * strDest,const char * strSrc); 1.不调用库函数实现strcpy函数。 2.解释为什么要返回char *。 解说 1.strcpy的实现代码 char * strcpy(char * strDest,const char * strSrc) { if ((strDestNULL)||(strSrcNULL)) file://[/1] throw Invalid argument(s); //[2] char * strDestCopystrDest; file://[/3] while ((*strDest*strSrc)!/0); file://[/4] return strDestCopy; } 错误的做法 [1] (A)不检查指针的有效性说明答题者不注重代码的健壮性。 (B)检查指针的有效性时使用((!strDest)||(!strSrc))或(!(strDeststrSrc))说明答题者对C语言中类型的隐式转换没有深刻认识。在本例中char *转换为bool即是类型隐式转换这种功能虽然灵活但更多的是导致出错概率增大和维护成本升高。所以C专门增加了bool、true、false三个关键字以提供更安全的条件表达式。 (C)检查指针的有效性时使用((strDest0)||(strSrc0))说明答题者不知道使用常量的好处。直接使用字面常量如本例中的0会减少程序的可维护性。0虽然简单但程序中可能出现很多处对指针的检查万一出现笔误编译器不能发现生成的程序内含逻辑错误很难排除。而使用NULL代替0如果出现拼写错误编译器就会检查出来。 [2] (A)return new string(Invalid argument(s));说明答题者根本不知道返回值的用途并且他对内存泄漏也没有警惕心。从函数中返回函数体内分配的内存是十分危险的做法他把释放内存的义务抛给不知情的调用者绝大多数情况下调用者不会释放内存这导致内存泄漏。 (B)return 0;说明答题者没有掌握异常机制。调用者有可能忘记检查返回值调用者还可能无法检查返回值见后面的链式表达式。妄想让返回值肩负返回正确值和异常值的双重功能其结果往往是两种功能都失效。应该以抛出异常来代替返回值这样可以减轻调用者的负担、使错误不会被忽略、增强程序的可维护性。 [3] (A)忘记保存原始的strDest值说明答题者逻辑思维不严密。 [4] (A)循环写成while (*strDest*strSrc);同[1](B)。 (B)循环写成while (*strSrc!/0) *strDest*strSrc;说明答题者对边界条件的检查不力。循环体结束后strDest字符串的末尾没有正确地加上/0。 为什么说用PHP开发大型系统令人不爽
笔者在过去的四年里一直致力于PHP应用的开发。PHP确实十分容易编写。但是PHP也有一些十分严重的缺陷。 下面笔者会给出自己的理由为什么PHP不适合于比小型业余网站更大的网站。 1. 对递归的不良支持 递归是一种函数调用自身的机制。这是一种强大的特性可以把某些复杂的东西变得很简单。有一个使用递归的例子是快速排序quicksort。不幸的是PHP并不擅长递归。Zeev一个PHP开发人员说道“PHP 4.0Zend对密集数据使用了栈方式而不是使用堆方式。也就是说它能容忍的递归函数的数量限制和其他语言比起来明显少。”见bug 1901。这是一个很不好的借口。每一个编程语言都应该提供良好的递归支持。 2. 许多PHP模块都不是线程安全的 在几年前Apache发布了Web服务器的2.0版。这个版本支持多线程模式在这个模式下软件一个一部分可以同时运行多个。PHP的发明者说PHP的核心是线程安全的但是非核心模块不一定是。但是十次有九次你想要在PHP脚本中使用这种模块但这又使你的脚本不能合适Apache的多线程模式。这也是为什么PHP小组不推荐在Apache 2 的多线程模式下运行PHP。不良的多线程模式支持使PHP常被认为是Apache 2依然不流行的原因之一。 请阅读这篇讨论 Slashdot: Sites Rejecting Apache 2?. 3. PHP 由于商业原因而不健全 通过使用缓存PHP的性能可以陡增500%[见基准测试]。那么为什么缓存没有被构建在PHP中呢因为Zend——PHP的制造者它在销售自己的Zend Accelerator所以当然他们不想抛弃自己的商业产品这块肥肉。 但是有另一个可选择的 APC. Zend后来推出Zend Optimizer免费的加速器——译者 4. 没有命名空间 设想某个人制作了一个PHP模块用来阅读文件。模块中一个函数叫做read。然后另一个人的模块可以读取网页的同样包含一个函数read。然后我们就无法同时使用这两个模块了因为PHP不知道你要用哪个函数。 但是有一个很简单的解决方法那就是命名空间。曾经有人建议PHP5加入这个特性但不幸得是他没有这么做。现在没有命名空间每个函数都必须加上模块名作为前缀来避免名称冲突。这导致了函数名恐怖得长例如xsl_xsltprocessor_transform_to_xml让代码难于书写和理解。 5. 不标准的日期格式字符 很多程序员对 日期格式字符 都很熟悉它是从UNIX和C语言中来的。其他一些编程语言采用了这个标准但是很奇怪的PHP有它自己的一套完全不兼容的日期格式字符。在C中“%j”表示一年中的当天在PHP中他表示一个月中的当天。然而使事情更混乱的是Smarty 一个很流行的PHP模版引擎的 strftime 函数和 date_format 函数却使用了C/UNIX的格式化字符。 6. 混乱的许可证 你也许认为PHP是免费的所有的在手册中提到的PHP模块也是免费的。错了例如如果你想在PHP中生成PDF文件你会在手册中发现两个模块PDF 和 ClibPDF。但是这两个都是有商业许可证的。所以你所使用的每个模块你都要确保你同意他的许可证。 7. 不一致的函数命名规则 有些函数名称是有多个单词组成的。一般有三种单词组合的习惯 直接拼接getnumberoffiles 用下划线分开get_number_of_files 骆驼法则getNumberOfFiles 大部分语言选择其中一中。但是PHP都用到了。 例如你想要把一些特殊字符转换成HTML实体你会使用函数htmlentities直接拼接单词。如果你要使用相反的功能你要用到它的小弟弟html_entity_decode。由于某些特殊的原因这个函数名是由下划线分隔单词。怎么能这样呢你知道有一个函数叫strpad。或者他是str_pad每次你都要查看一下到底这个符号是什么或者直接等他出现一个错误。函数是不分大小写的所以对于PHP来说rawurldecode和RawUrlDecode之间没有什么区别。这也很糟糕因为两个都使用到了同时他们看上去还不一样混淆了阅读者。 8. 魔法引用的地狱 魔法引用Magic quote可以保护PHP脚本免受SQL注入攻击。这很好。但是出于某些原因你可以在php.ini中关闭这个配置。所以你如果要写出一个有弹性的脚本你总要检查魔法引用是开启还是关闭。这样一个“特性”应该让编程更简单而事实上变得更复杂了。 9. 缺少标准框架 一个成长中的网站没有一个整体框架最终会变成维护的噩梦。一个框架可以让很多工作变得简单。现在最流行的框架模型时MVC-模型在其中表现层、业务逻辑和数据库访问都分离开了。 很多PHP网站不使用MVC-模型。他们甚至没有一个框架。甚至现在有一些PHP框架同时你都可以自己写一个关于PHP的文章和手册没有提高框架的一个字。同时JSP-开发人员使用像Struts的框架、ASP开发人员使用.Net看起来好像这些概念都广泛被PHP开发人员所了解。这就说明了PHP实际上到底是多专业。 总结 什么问题? 对于非常小的项目它可以是一个十分符合人意的编程语言。但是对于较大的和更为复杂的项目PHP就显出他的薄弱了。当你不断地摸索之后你会发现笔者提到的某些问题的解决方案。所以当解决方案已知之后为什么不能修正他呢另外为什么这些修补不在手册中提到呢 一个开源的语言十分流行是一件好事。但不幸得是它不是一个伟大的语言。笔者希望所有的问题能有一天得到解决也许在PHP6然后我们就将拥有一个开源语言他既开源又好用。 到现在当你要启动一个多于5个脚本页面的项目的时候你最好考虑C#/ASP.Net 或者 Java/JSP或者也许Python同样是一个更好的选择。 语言最长平台算法
已知一个已经从小到大排列好的数组,说这个数组中的一个平台(Plateau),就是连续的一串相同的元素,并且这一串元素不能再延伸例如在1,2,2,3,3,3,4,5,5,6中1,2.2,3.3.3,4,5.5,6都是平台编写程序把这个数组中最长的平台找出来
#include stdio.h int longest_plateau(int x[],int n) { int length1; int i; for(i1;in;i) { if(x[i]x[i-length]) length; } return length; } void main() { int a[]{1,2,2,3,3,3,4,5,5,6}; int tmp; tmplongest_plateau(a,9); printf(%d/n,tmp); }
本文的写作目的并不在于提供C/C程序员求职面试指导而旨在从技术上分析面试题的内涵。文中的大多数面试题来自各大论坛部分试题解答也参考了网友的意见。 许多面试题看似简单却需要深厚的基本功才能给出完美的解答。企业要求面试者写一个最简单的strcpy函数都可看出面试者在技术上究竟达到了怎样的程度我们能真正写好一个strcpy函数吗我们都觉得自己能可是我们写出的strcpy很可能只能拿到10分中的2分。读者可从本文看到strcpy 函数从2分到10分解答的例子看看自己属于什么样的层次。此外还有一些面试题考查面试者敏捷的思维能力。 分析这些面试题本身包含很强的趣味性而作为一名研发人员通过对这些面试题的深入剖析则可进一步增强自身的内功。 2.找错题 试题1
void test1() { char string[10]; char* str1 0123456789; strcpy( string, str1 ); } 试题1字符串str1需要11个字节才能存放下包括末尾的’’而string只有10个字节的空间strcpy会导致数组越界 试题2
void test2() { char string[10], str1[10]; int i; for(i0; i10; i) { str1[i] a; } strcpy( string, str1 ); } 对试题2如果面试者指出字符数组str1不能在数组内结束可以给3分如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分在此基础上指出库函数strcpy工作方式的给10 分 试题3
void test3(char* str1) { char string[10]; if( strlen( str1 ) 10 ) { strcpy( string, str1 ); } }
对试题3if(strlen(str1) 10)应改为if(strlen(str1) 10)因为strlen的结果未统计’’所占用的1个字节。 剖析 考查对基本功的掌握(1)字符串以’’结尾(2)对数组越界把握的敏感度 (3)库函数strcpy的工作方式如果编写一个标准strcpy函数的总分值为10下面给出几个不同得分的答案
char * strcpy( char *strDest, const char *strSrc ) { assert( (strDest ! NULL) (strSrc ! NULL) ); char *address strDest; while( (*strDest * strSrc) ! ‘’ ); return address; } 从2分到10分的几个答案我们可以清楚的看到小小的strcpy竟然暗藏着这么多玄机真不是盖的需要多么扎实的基本功才能写一个完美的strcpy啊 (4)对strlen的掌握它没有包括字符串末尾的。 读者看了不同分值的strcpy版本应该也可以写出一个10分的strlen函数了完美的版本为 int strlen( const char *str ) //输入参数const
{ assert( strt ! NULL ); //断言字符串地址非0 int len; while( (*str) ! ) { len; } return len; } 试题4
void GetMemory( char *p ) { p (char *) malloc( 100 ); } void Test( void ) { char *str NULL; GetMemory( str ); // strcpy( str, hello world ); printf( str ); }
试题4传入中GetMemory( char *p )函数的形参为字符串指针在函数内部修改形参并不能真正的改变传入形参的值执行完
char *str NULL; GetMemory( str );后的str仍然为NULL 试题5
char *GetMemory( void ) { char p[] hello world; return p; } void Test( void ) { char *str NULL; str GetMemory(); printf( str ); }
试题5中
char p[] hello world; return p;的p[]数组为函数内的局部自动变量在函数返回后内存已经被释放。这是许多程序员常犯的错误其根源在于不理解变量的生存期。
试题6
void GetMemory( char **p, int num ) { *p (char *) malloc( num ); } void Test( void ) { char *str NULL; GetMemory( str, 100 ); strcpy( str, hello ); printf( str ); }
试题6的GetMemory避免了试题4的问题传入GetMemory的参数为字符串指针的指针但是在GetMemory中执行申请内存及赋值语句*p (char *) malloc( num );后未判断内存是否申请成功应加上
if ( *p NULL ) { ...//进行申请内存失败处理 }
试题6的Test函数中也未对malloc的内存进行释放。 试题7
void Test( void ) { char *str (char *) malloc( 100 ); strcpy( str, hello ); free( str ); ... //省略的其它语句 }
试题7存在与试题6同样的问题在执行char *str (char *) malloc(100);后未进行内存是否申请成功的判断另外在free(str)后未置str为空导致可能变成一个“野”指针应加上str NULL; 剖析 试题47考查面试者对内存操作的理解程度基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确却也绝非易事。 对内存操作的考查主要集中在1指针的理解2变量的生存期及作用范围3良好的动态内存申请和释放习惯。 再看看下面的一段程序有什么错误
swap( int* p1,int* p2 ) { int *p; *p *p1; *p1 *p2; *p2 *p; }
在swap函数中p是一个“野”指针有可能指向系统区导致程序运行的崩溃。在VC中DEBUG运行时提示错误“Access Violation”。该程序应该改为
swap( int* p1,int* p2 ) { int p; p *p1; *p1 *p2; *p2 p; } 3.内功题 试题1分别给出BOOLintfloat指针变量 与“零值”比较的 if 语句假设变量名为var 解答 BOOL型变量if(!var) int型变量 if(var0) float型变量 const float EPSINON 0.00001; if ((x - EPSINON) (x EPSINON) 指针变量 if(varNULL) 剖析 考查对0值判断的“内功”BOOL型变量的0判断完全可以写成if(var0)而int型变量也可以写成if(!var)指针变量的判断也可以写成if(!var)上述写法虽然程序都能正确运行但是未能清晰地表达程序的意思。 一般的如果想让if判断一个变量的“真”、“假”应直接使用if(var)、if(!var)表明其为“逻辑”判断如果用if判断一个数值型变量(short、int、long等)应该用if(var0)表明是与0进行“数值”上的比较而判断指针则适宜用if(varNULL)这是一种很好的编程习惯。 浮点型变量并不精确所以不可将float变量用“”或“”与数字比较应该设法转化成“”或“”形式。如果写成if (x 0.0)则判为错得0分。 试题2以下为Windows NT下的32位C程序请计算sizeof的值
void Func ( char str[100] ) { sizeof( str ) ? } void *p malloc( 100 ); sizeof ( p ) ?
解答
sizeof( str ) 4 sizeof ( p ) 4 剖析 Func ( char str[100] )函数中数组名作为函数形参时在函数体内数组名失去了本身的内涵仅仅只是一个指针在失去其内涵的同时它还失去了其常量特性可以作自增、自减等操作可以被修改。 数组名的本质如下
1数组名指代一种数据结构这种数据结构就是数组 例如char str[10]; cout sizeof(str) endl;
输出结果为10str指代数据结构char[10]。 2数组名可以转换为指向其指代实体的指针而且是一个指针常量不能作自增、自减等操作不能被修改
char str[10];
str; //编译出错提示str不是左值
3数组名作为函数形参时沦为普通指针。 Windows NT 32位平台下指针的长度占用内存的大小为4字节故sizeof( str ) 、sizeof ( p ) 都为4。
试题3写一个“标准”宏MIN这个宏输入两个参数并返回较小的一个。另外当你写下面的代码时会发生什么事least MIN(*p, b);
解答
#define MIN(A,B) ((A) (B) ? (A) : (B))
MIN(*p, b)会产生宏的副作用 剖析 这个面试题主要考查面试者对宏定义的使用宏定义可以实现类似于函数的功能但是它终归不是函数而宏定义中括弧中的“参数”也不是真的参数在宏展开的时候对“参数”进行的是一对一的替换。 程序员对宏定义的使用要非常小心特别要注意两个问题 1谨慎地将宏定义中的“参数”和整个宏用用括弧括起来。所以严格地讲下述解答
#define MIN(A,B) (A) (B) ? (A) : (B) #define MIN(A,B) (A B ? A : B )
都应判0分 2防止宏的副作用。 宏定义#define MIN(A,B) ((A) (B) ? (A) : (B))对MIN(*p, b)的作用结果是 ((*p) (b) ? (*p) : (*p)) 这个表达式会产生副作用指针p会作三次自增操作。 除此之外另一个应该判0分的解答是
#define MIN(A,B) ((A) (B) ? (A) : (B));
这个解答在宏定义的后面加“;”显示编写者对宏的概念模糊不清只能被无情地判0分并被面试官淘汰。 试题4为什么标准头文件都有类似以下的结构
#ifndef __INCvxWorksh #define __INCvxWorksh #ifdef __cplusplus extern C { #endif /*...*/ #ifdef __cplusplus } #endif #endif /* __INCvxWorksh */ 解答头文件中的编译宏
#ifndef __INCvxWorksh
#define __INCvxWorksh #endif的作用是防止被重复引用。 作为一种面向对象的语言C支持函数重载而过程式语言C则不支持。函数被C编译后在symbol库中的名字与C语言的不同。例如假设某个函数的原型为
void foo(int x, int y);
该函数被C编译器编译后在symbol库中的名字为_foo而C编译器则会产生像_foo_int_int之类的名字。_foo_int_int这样的名字包含了函数名和函数参数数量及类型信息C就是考这种机制来实现函数重载的。 为了实现C和C的混合编程C提供了C连接交换指定符号extern C来解决名字匹配问题函数声明前加上extern C后则编译器就会按照C语言的方式将该函数编译为_foo这样C语言中就可以调用C的函数了。 试题5编写一个函数作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n2移位后应该是“hiabcdefgh” 函数头是这样的
//pStr是指向以结尾的字符串的指针 //steps是要求移动的n void LoopMove ( char * pStr, int steps ) { //请填充... }
解答
正确解答1
void LoopMove ( char *pStr, int steps ) { int n strlen( pStr ) - steps; char tmp[MAX_LEN]; strcpy ( tmp, pStr n ); //将要移动的部分放入tmp的前部 strcpy ( tmp steps, pStr); //将原字符串放入tmp的后部 *( tmp strlen ( pStr ) ) ; //保持tmp和原字符串长度一致 strcpy( pStr, tmp ); }
正确解答2
void LoopMove ( char *pStr, int steps ) { int n strlen( pStr ) - steps; char tmp[MAX_LEN]; memcpy( tmp, pStr n, steps ); memcpy(pStr steps, pStr, n ); memcpy(pStr, tmp, steps ); } 剖析 这个试题主要考查面试者对标准库函数的熟练程度在需要的时候引用库函数可以很大程度上简化程序编写的工作量。最频繁被使用的库函数包括 1 strcpy2 memcpy3 memset
试题6已知WAV文件格式如下表打开一个WAV文件以适当的数据结构组织WAV文件头并解析WAV格式的各项信息。 WAVE文件格式说明表 偏移地址 字节数 数据类型 内 容 文件头 00H 4 Char RIFF标志 04H 4 int32 文件长度 08H 4 Char WAVE标志 0CH 4 Char fmt标志 10H 4 过渡字节不定 14H 2 int16 格式类别 16H 2 int16 通道数 18H 2 int16 采样率每秒样本数表示每个通道的播放速度 1CH 4 int32 波形音频数据传送速率 20H 2 int16 数据块的调整数按字节算的 22H 2 每样本的数据位数 24H 4 Char 数据标记符data 28H 4 int32 语音数据的长度 解答 将WAV文件格式定义为结构体WAVEFORMAT
typedef struct tagWaveFormat { char cRiffFlag[4]; UIN32 nFileLen; char cWaveFlag[4]; char cFmtFlag[4]; char cTransition[4]; UIN16 nFormatTag ; UIN16 nChannels; UIN16 nSamplesPerSec; UIN32 nAvgBytesperSec; UIN16 nBlockAlign; UIN16 nBitNumPerSample; char cDataFlag[4]; UIN16 nAudioLength; } WAVEFORMAT; 假设WAV文件内容读出后存放在指针buffer开始的内存单元内则分析文件格式的代码很简单为
WAVEFORMAT waveFormat; memcpy( waveFormat, buffer,sizeof( WAVEFORMAT ) );
直接通过访问waveFormat的成员就可以获得特定WAV文件的各项格式信息。 剖析 试题6考查面试者组织数据结构的能力有经验的程序设计者将属于一个整体的数据成员组织为一个结构体利用指针类型转换可以将memcpy、memset等函数直接用于结构体地址进行结构体的整体操作。 透过这个题可以看出面试者的程序设计经验是否丰富。 试题7编写类String的构造函数、析构函数和赋值函数已知类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::String(const char *str) { if(strNULL) //加分点对m_data加NULL 判断 { m_data new char[1]; // 得分点对空字符串自动申请存放结束标志的空 *m_data ; } else { int length strlen(str); m_data new char[length1]; // 若能加 NULL 判断则更好 strcpy(m_data, str); } } // String的析构函数 String::~String(void) { delete [] m_data; // 或delete m_data; } //拷贝构造函数 String::String(const String other) // 得分点输入参数为const型 { int length strlen(other.m_data); m_data new char[length1]; //加分点对m_data加NULL 判断 strcpy(m_data, other.m_data); } //赋值函数 String String::operate (const String other) //得分点输入参数为const型 { if(this other) //得分点检查自赋值 return *this; delete [] m_data; //得分点释放原有的内存资源 int length strlen( other.m_data ); m_data new char[length1]; //加分点对m_data加NULL 判断 strcpy( m_data, other.m_data ); return *this; //得分点返回本对象的引用 } 剖析 能够准确无误地编写出String类的构造函数、拷贝构造函数、赋值函数和析构函数的面试者至少已经具备了C基本功的60%以上 在这个类中包括了指针类成员变量m_data当类中包括指针类成员变量时一定要重载其拷贝构造函数、赋值函数和析构函数这既是对C程序员的基本要求也是《Effective C》中特别强调的条款。 仔细学习这个类特别注意加注释的得分点和加分点的意义这样就具备了60%以上的C基本功 试题8请说出static和const关键字尽可能多的作用 解答 static关键字至少有下列n个作用 1函数体内static变量的作用范围为该函数体不同于auto变量该变量的内存只被分配一次因此其值在下次调用时仍维持上次的值 2在模块内的static全局变量可以被模块内所用函数访问但不能被模块外其它函数访问 3在模块内的static函数只可被这一模块内的其它函数调用这个函数的使用范围被限制在声明它的模块内 4在类中的static成员变量属于整个类所拥有对类的所有对象只有一份拷贝 5在类中的static成员函数属于整个类所拥有这个函数不接收this指针因而只能访问类的static成员变量。 const关键字至少有下列n个作用 1欲阻止一个变量被改变可以使用const关键字。在定义该const变量时通常需要对它进行初始化因为以后就没有机会再去改变它了 2对指针来说可以指定指针本身为const也可以指定指针所指的数据为const或二者同时指定为const 3在一个函数声明中const可以修饰形参表明它是一个输入参数在函数内部不能改变其值 4对于类的成员函数若指定其为const类型则表明其是一个常函数不能修改类的成员变量 5对于类的成员函数有时候必须指定其返回值为const类型以使得其返回值不为“左值”。 例如const classA operator*(const classA a1,const classA a2); operator*的返回结果必须是一个const对象。如果不是这样的变态代码也不会编译出错
classA a, b, c; (a * b) c; // 对a*b的结果赋值
操作(a * b) c显然不符合编程者的初衷也没有任何意义。 剖析 惊讶吗小小的static和const居然有这么多功能我们能回答几个如果只能回答1~2个那还真得闭关再好好修炼修炼。 这个题可以考查面试者对程序设计知识的掌握程度是初级、中级还是比较深入没有一定的知识广度和深度不可能对这个问题给出全面的解答。大多数人只能回答出static和const关键字的部分功能。 4.技巧题
试题1请写一个C函数若处理器是Big_endian的则返回0若是Little_endian的则返回1 解答
int checkCPU() { { union w { int a; char b;} c; c.a 1; return (c.b 1); } } 剖析 嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节而Big-endian模式对操作数的存放方式是从高字节到低字节。例如16bit宽的数0x1234在Little- endian模式CPU内存中的存放方式假设从地址0x4000开始存放为 内存地址 存放内容 0x4000 0x34 0x4001 0x12 而在Big-endian模式CPU内存中的存放方式则为 内存地址 存放内容 0x4000 0x12 0x4001 0x34 32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式假设从地址0x4000开始存放为 内存地址 存放内容 0x4000 0x78 0x4001 0x56 0x4002 0x34 0x4003 0x12 而在Big-endian模式CPU内存中的存放方式则为 内存地址 存放内容 0x4000 0x12 0x4001 0x34 0x4002 0x56 0x4003 0x78 联合体union的存放顺序是所有成员都从低地址开始存放面试者的解答利用该特性轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。如果谁能当场给出这个解答那简直就是一个天才的程序员。 试题2写一个函数返回123…n的值假定结果不会超过长整型变量的范围 解答
int Sum( int n ) { return ( (long)1 n) * n / 2; //或return (1l n) * n / 2;} 剖析 对于这个题只能说也许最简单的答案就是最好的答案。下面的解答或者基于下面的解答思路去优化不管怎么“折腾”其效率也不可能与直接return ( 1 l n ) * n / 2相比
int Sum( int n ) { long sum 0; for( int i1; in; i ) {sum i;} return sum; } 所以程序员们需要敏感地将数学等知识用在程序设计中。 1.C与C的异同优劣 2CCVCBCTC的区别 3C中try…catch关键字的用法与优点 4枚举的用法以及它与宏的区别 5const的用法以及声明const变量与宏的区别 const的用法有四种1. const常量如const int max 1002. const 修饰类的数据成员3. const修饰指针的情况4. 在一个函数声明中const 可以修饰函数的返回值或某个参数对于成员函数还可以修饰是整个函数。 区别1.const常量有数据类型 而宏常量没有数据类型2.编译器可以对前者进行类型安全检查而对后者只能进行字符替换没有类型安全检查而且字符替换可能会带来料想不到的边界效应3. 有些集成化工具可以对const常量进行调试 但不能对宏量进行调试。 6C中引用与指针的区别 答1 引用实际上是所引用的对象或变量的别名而指针是包含所指向对象或变量的地址的变量。 2 引用在定义时必须初始化而指针在定义时不初始化。 3 不可以有努NULL的引用而可以有指向NULL的指针。 4 引用在初始化后不可以改变引用关系而指针可以随时指向其他对象非const指针。 7C中virtual与inline的含义分别是什么 答在基类成员函数的声明前加上virtual关键字意味着将该成员函数声明为虚函数。 inline与函数的定义体放在一起使该函数称为内联。inline是一种用于实现的关键字而不是用于声明的关键字。 虚函数的特点如果希望派生类能够重新定义基类的方法则在基类中将该方法定义为虚方法这样可以启用动态联编。 内联函数的特点使用内联函数的目的是为了提高函数的运行效率。内联函数体的代码不能过长因为内联函数省去调用函数的时间是以代码膨胀为代价的。内联函数不能包含循环语句因为执行循环语句要比调用函数的开销大。 一个函数能否即是虚函数又是内联函数可以建议不使用 8以下关键字的含义与用法 externextern “C”staticexplicitregister#undef#ifndef 9什么是函数重载与覆盖 为什么C不支持函数重载 为什么C能支持函数重载 10VC中编译工具条内的Debug与Release选项是什么含义
Debug 通常称为调试版本它包含调试信息并且不作任何优化便于程序员调试程序。Release 称为发布版本它往往是进行了各种优化使得程序在代码大小和运行速度上都是最优的以便用户很好地使用。Debug带有大量的调试代码运行时需要相应的运行库发布模式程序紧凑不含有调试代码和信息直接可以运行如果不需要运行库 11编写my_memcpy函数实现与库函数memcpy类似的功能不能使用任何库函数 void* mymemcpy(void* pvTo, const char* pvFrom, size_t size) { assert((dest ! NULL) (src ! NULL)); byte* psTo (byte*)pvTo; byte* psFrom (byte*)pvFrom; while (size-- 0) {*psTo *psFrom;} return pvTo; } 12编写my_strcpy函数实现与库函数strcpy类似的功能不能使用任何库函数 答char* my_strcpy(char* strdest, const char* strsrc) { assert((strdest ! NULL) (strsrc ! NULL)) char* address strdest; while((*strdest *strsrc) ! NULL) return address; } 13编写gbk_strlen函数计算含有汉字的字符串的长度汉字作为一个字符处理 已知汉字编码为双字节其中首字节0尾字节在0~63以外如果一个字节是-128~127 14函数assert的用法? 答断言assert是仅在debug版本起作用的宏用于检查“不应该“发生的情况。程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。 15为什么在头文件的最前面都会看到这样的代码 #ifndef _STDIO_H_ #define _STDIO_H_
头文件中的#ifndef一般格式是这样的#ifndef 标识 #define 标识标识在理论上来说可以是自由命名的但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写前后加下划线并把文件名中的“.”也变成下划线如stdio.h
#ifndef _STDIO_H_ #define _STDIO_H_ 16为什么数组名作为参数会改变数组的内容而其它类型如int却不会改变变量的值 答当数组名作为参数时传递的实际上是地址。而其他类型如int作为参数时由于函数参数值实质上是实参的一份拷贝被调函数内部对形参的改变并不影响实参的值。 1实现双向链表删除一个节点P在节点P后插入一个节点写出这两个函数。 2写一个函数将其中的/t都转换成4个空格。 3Windows程序的入口是哪里写出Windows消息机制的流程。 4如何定义和实现一个类的成员函数为回调函数 5C里面是不是所有的动作都是main()引起的如果不是请举例。 6C里面如何声明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; } 3、WinMain while( (bRet GetMessage( msg, NULL, 0, 0 )) ! 0) { if (bRet -1) { // handle the error and possibly exit } else { TranslateMessage(msg); DispatchMessage(msg); } }
华为3COM
选择、填空、简答、程序都有。基本上是C和网络方面的DD还有几道概率和推理
10道选择大多数是C的50分然后两题填空20分第二题不是编程是个数学题。第三部分写两个函数3 0分第一题是把一个unsigned long的数转成一个IP地址输出应该很容易的结果自己想复杂了浪费了不少时间最后还没做对晕。第二题是两个长度为N的数字字符串相加结果保存在一个长度为N1的字符串里思路倒是很清楚后来发现好像在处理进位和前一位的和的时候还有进位的问题但是懒得改了就这样吧。最后一部分是附加题10题选择20分内容主要是和IP网络有关的笔试中有英译汉。请翻译一下ipv6的路由发现机制。是将arp和irdp和icmp重定向的融合等等。 1 H.323协商。笔试题 2 ipsec为什么是三层的。l2tp为什么是二层的 答ipsec是需要三层IP路由的。l2tp是打穿的。 反问那l2tp不需要ip吗 无语。 3 ospf中包的ttl值是多少回忆不清了。可能是吧。但没听说过有介绍啊。 4 为什么要划分区域 答用来防止LSA在整个区域内泛洪。减少对CPU和内存的损耗。 反问那area 0的一条路由条目发生了变化。area 1要不要知道呢 答要。 反问既然要的话那不还是要泛洪吗那划分区域的话就没有什么意义了嘛。 答可以通过缺省路由的方式或建立stub区域等方法。 反问正面回答。 无语。 5 MPLS VPN的标签一共有几层。内网的标签放在哪里。 答骨干里传递一层。到Mp-ibgp邻居一层。跨域一层。好象TE还可以加一层标签。内网的标签放在lfib表里。 对方没怎么做声。但估计答得不好。 我有一点不明MPLS标签有分内网和外网吗 6 MPLS中RD和RT的作用分别是什么 答RD的作用是允许VPN用户地址的重叠。RT可以用来区分不同的VPN用户。控制路由条目的出口入口策略。 反问既然RT可以区分不同的VPN用户。那RD有什么用。地址重叠那是你的规划没做好。 答RD是肯定要的。 反问为什么不是有RT可以区分用户吗 无语。 7 RR防止环路的机制。 答两个属性originate id。包含了始发这条路由的路由器的route-id因此RR不会将此路由又重新发回给源。 一个是cluster-id。包含了RR的route-id。 8 BGP控制out-bound用local-pre控制进来的用med.笔试题 9 ospf是工作在哪个协议上的可能是我记不清了 10 ospf的LSA类型。 答这个我不打字了。大家应该都知道吧。 11 简述OSPF的基本工作机制。 答昨晚补了下卷一一。向邻接路由器发出hello包。根据hello包中携带的area id ,hello time,dead interval,stub标记。如果都相同的话。建立起邻居关系。 二 向邻居发送链路状态更新包. 根据ospf 类型而定。如果是broadcast和nbma的话由DR发出三 收到邻居路由器发来的更新包后以自己为根根据 spf算法建立一条无环路的路径。四在整个区域内泛洪。五整个区域内的database同步。六数据库稳定后hello包变为keepalive报文30min发送一次。 回答肯定不是很好。请高手指正 12 ppp的lcp和ncp协商过程。 答说得不好。基本无语 13 笔试中还有一道PSTN的信令控制有哪三种笔试题 14sloari 8.0查看进程的命令是什么linux 7.3查看IP的命令是什么笔试题 15 IP是5.32.0.0,掩码255.224.0.0。请问最大的有效地址是多少。笔试题 16 下列哪一项不属于于7号信令标准选择。我乱蒙了一个 17 lx/???的有效距离是多少我选的10km 18 IP 包头几个字节加上数据部分几个字节19 QOS有一点点。 随便蒙吧反正这方面对方问得不是很细。把你知道的说出来就可以了。 20 CQ能不能有一种流量统治第二种流量(由于是英文dominate)? 笔试题 21 FTP下载一个文件完成。有几个TCP连接四次 笔试题 snmparpospf协议c的异常处理局部静态变量 全局变量的存放问题
一道是测试时的那个覆盖问题一道是int型溢出问题没考虑到其他的基本满分^_^ 程序题为把一个un int转4进制村数组考验编程的严密性还有一道是比较发散的思路题 前面50分10个选择题前七个是C程序后三个数学题。都计较简单呵呵。中间是两个填空题各填三空题一为比较两个输入字符串的大小简单。题二是填写程序注释对内存进行操作方面的如检查内存溢出内存泄漏避免产生野指针之类的。后面是两道综合题题一写C程序函数将一个整数转换为4进制的字符串题二要求提供解决一个代理服务器由于应答无响应而导致的资源得不到释放的解决方案。题一简单题二偶就模仿TCP虚电路连接的算法写了一下自己的思路和主要步骤感觉应该不会偏得很远
做完这些题后还剩十分钟后面还有10道选择题为通讯知识题为附加题都是关于网络偏数据链路层和网络层的知识 刚刚考完华为3com的软件笔试从9001000共一小时。 前面50分10个选择题前七个是C程序后三个数学题。 中间是两个填空题各填三空题一为比较两个输入字符串的大小简单。题二是填写程序注释对内存进行操作方面的如free(p)什么作用。 后面是两道综合题题一写C程序函数将一个整数转换为4进制的字符串题二要求提供解决一个代理服务器由于应答无响应而导致的资源得不到释放的解决方案。 最后20分共10道选择题为通讯知识题关于路由器网络方面的知识如果看过的话不难。 第一面技术面还有点挑战简单介绍自己后技术gg就开始正式发起技术进攻了首先问了指针函数和函数指针的区别欧最讨厌这种绕口令式的问题了不就一个是指针然后该指针指向一个函数另一个是一个函数返回一个指针啊简单一句话就是指与被指的关系。呵呵不过当时紧张绕了一小会然后技术gg又丢出一个问题一个单向链表怎样实现快速查找。偶立马想到了数组的二分查找就告诉他给单链表增加一个数据项表示它的序号然后用类数组二分查找算法开始查找。技术gg立马之处偶的错误之处要是改链表要插入删除的话改序号很麻烦而且该单向链表有个条件要排好序的唉这可为难我了过了一小会技术gg笑着说给你降低点难度假设单链表是排好序的偶还是没有放弃二分查找偶就回答常规查找是指针一位一位的移我可以一次多移几位然后缩小查找范围技术gg问偶这样做有什么好处偶说可以减少比较次数他想了会说嗯这个方法不错偶正打算得意的笑他又问还有其他方法吗偶晕还不肯放过偶回答应该可以把单链表转化成排序二叉树吧这样查找插入删除就都很easy了技术gg听了略加思索说嗯这个方法不错然后就要偶等二面唉终于pass啦 二面是hr面基本都是常规问题什么别人对我的评价啊自己的职业规划啊可不可以提前上班啊云云二面完后填了个表都到11点了被通知不早了明天早上继续三面。 今天早上8点就爬起来了8点20多一点到大活准备最后一面。到了一看门还没开呢只有一个面试的mm等在那里他们也真准时828终于看到工作人员了说是830面试可是三面的面试官迟迟未出现终于等啊等啊等了一个小时才听到了偶的名字偶跟着面试官刚到指定位置面试官的手机响了偶狂晕中途杀出个电话来此时偶的肚子已经在打鼓了唉十几分钟后电话终于讲完了面试开始了介绍了下自己的项目由于不对口所以他也没有仔细问然后就是自己的优点还有就是问偶面华为没 c题目比较多一道网络选择几道操作系统题目选择还有两道大题关于双向链表和哈希算法的。内存拷贝memcopy问题插入排序问题 moto: 笔试20题通讯多选10题计算机多选。 通讯考的都是基础知识但是不是通讯专业的一般都要靠摸的计算机考的比较有深度主要是c和c类的继承关系初始化顺序二*树的先序、中序、后序知道其中两个推导剩下的一个i和i问题。 例如: int i1; int j; j(i)(i)(i)(i);//j15 int i1; int j; j(i)(i)(i)(i)(i);//j16 moto面试中英语口语很重要技术面试一开始就是用英语的后来不行了只好用中文。第二面的那个人力资源的主管就是全英文了一路面下来不吐一个汉字。二面的时候主要就是聊天了问问你的爱好和同学关系什么的主要是看口语以及你个人的性格。 moto待遇6000770。干满三年一次性发6000*20的住房公积金 //计算字符串长度的函数 int strlen_mod(char* str) { int count 0; while(str[count] ! /0) { count;} return count; } //将字符串反转输出的函数 void print_reverse(char* str) { size_t size strlen(str); int size2 strlen_mod(str); printf(The length of %s is %d ### %d/n, str, size, size2); int i; char temp ; for(i0; i size/2; i) { printf(%d/n, i); temp str[i]; str[i] str[size - 1 - i]; str[size - 1 - i] temp; } printf(Reverse string: %s/n, str); } What will print out? 输出结果是? main() { char *p1“name”; char *p2; p2(char*)malloc(20); memset (p2, 0, 20); // while(*p2 *p1); printf(“%sn”,p2); } Answer:empty string. What will be printed as the result of the operation below: main() { int x20,y35; xy x; y y x; printf(“%d%dn”,x,y); } Answer : 5794 What will be printed as the result of the operation below: main() { int x5; printf(“%d,%d,%dn”,x,x 2,x2); } Answer: 5,20,1 What will be printed as the result of the operation below: #define swap(a,b) aab;ba-b;aa-b; void main() { int x5, y10; swap (x,y); printf(“%d %dn”,x,y); swap2(x,y); printf(“%d %dn”,x,y); } int swap2(int a, int b) { int temp; tempa; ba; atemp; return 0; } Answer: 10, 5 10, 5 What will be printed as the result of the operation below: main() { char *ptr ” Cisco Systems”; *ptr; printf(“%sn”,ptr); ptr; printf(“%sn”,ptr); } Answer:Cisco Systems isco systems What will be printed as the result of the operation below: main() { char s1[]“Cisco”; char s2[] “systems”; printf(“%s”,s1); } Answer: Cisco What will be printed as the result of the operation below: main() { char *p1; char *p2; p1(char *)malloc(25); p2(char *)malloc(25); strcpy(p1,”Cisco”); strcpy(p2,“systems”); strcat(p1,p2); printf(“%s”,p1); } Answer: Ciscosystems The following variable is available in file1.c, who can access it?: static int average; Answer: all the functions in the file1.c can access the variable. WHat will be the result of the following code? #define TRUE 0 // some code while(TRUE) { // some code } Answer: This will not go into the loop as TRUE is defined as 0. What will be printed as the result of the operation below: int x; int modifyvalue() { return(x10); } int changevalue(int x) { return(x1); } void main() { int x10; x; changevalue(x); x; modifyvalue(); printf(First output:%dn,x); x; changevalue(x); printf(Second output:%dn,x); modifyvalue(); printf(Third output:%dn,x); } Answer: 12 , 13 , 13 What will be printed as the result of the operation below: main() { int x10, y15; x x; y y; printf(“%d %dn”,x,y); } Answer: 11, 16 What will be printed as the result of the operation below: main() { int a0; if(a0) printf(“Cisco Systemsn”); printf(“Cisco Systemsn”); } Answer: Two lines with “Cisco Systems” will be printed. C语言题库 *1 A 一个C程序的执行是从_____。 A)本程序的main函数开始,到main函数结束 B)本程序文件的第一个函数开始,到本程序文件的最后一个函数结束 C)本程序的main函数开始,到本程序文件的最后一个函数结束 D)本程序文件的第一个函数开始,到本程序main函数结束 *2 C 以下叙述正确的是: A)在C程序中,main函数必须位于程序的最前面 B)C程序的每行中只能写一条语句 C)C语言本身没有输入输出语句 D)在对一个C程序进行编译的过程中,可发现注释中的拼写错误 *3 D 以下叙述不正确的是。 A)一个C源程序可由一个或多个函数组成 B)一个C源程序必须包含一个main函数 C)C程序的基本组成单位是函数 D)在C程序中,注释说明只能位于一条语句的后面 *4 C C语言规定:在一个源程序中,main函数的位置 。 A)必须在最开始 B)必须在系统调用的库函数的后面 C)可以任意 D)必须在最后 *5 B 一个C语言程序是由 A)一个主程序和若干子程序组成 B)函数组成 C)若干过程组成 D)若干子程序组成 *6 A 在C语言中(以16位PC机为例),5种基本数据类型的存储空间长度的排列顺序为 A)charINTNBSP;NBSP;1ONGNBSP;NBSP;INTFLOAT B)charint1ong intfloat C)char int 1ong intfloatdouble D)charint 1ong intfloat *7 C 若x,i,j和k都是int型变量,则执行下面表达式后x的值为 x(i4,j16,k32) A)4 B)16 C)32 D)52 *8 B 假设所有变量均为整型,则表达式(a2,b5,b,ab)的值是: A)7 B)8 C)6 D)2 *9 A 下列四组选项中,均不是C语言关键字的选项是 A)define B)getc C)include D)while IF char scanf go type printf case pow *10 B 下面四个选项中,均是C语言关键字的选项是 A)auto B)switch C)signed D)if enum typedef union struct include continue scanf type *11 C 下面四个选项中,均是不合法的用户标识符的选项是。 A) A B)float C)b-a D)一123 P_0 1a0 goto temp do 一A int INT *12 C C语言中的标识符只能由字母、数字和下划线三种字符组成,且第一个字符 A)必须为字母 B)必须为下划线 C)必须为字母或下划线 D)可以是字母,数字和下划线中任一种字符 *13 A 下面四个选项中,均是合法整型常量的选项是: A)160 B)一0xcdf C)一01 D)一0x48a 一0xffff 01a 986, 012 2e5 011 0xe 0668 0x *14 D 下面四个选项中,均是不合法的整型常量的选项是: A)一一0f1 B)一0Xcdf C)一018 D)一0x48eg 一0xffff 017 999 一068 0011 12,456 5e2 03f *15 B 下面四个选项中,均是不合法的浮点数的选项是 A) 160. B) 123 C)一.18 D)一e3 0.12 2e4.2 123e4 .234 e3 .e5 0.0 1e3 *16 b 下面四个选项中,均是合法浮点数的选项是 A) le1 B)-.60 C) 123e D)一e3 5e一9.4 12e-4 1.2e-.4 .8e4 03e2 一8e5 2e一1 5.e一0 *17 A 下面四个选项中,均是合法转义字符的选项是 A)/ B)/ C)/018 D)//0 // /017 /f 101 /n / xab xlf *18 B 下面四个选项中,均是不合法的转义字符的选项是 A)/ B)/1011 C)/011 D)/abc // / /f /101 /xf /a /} xlf *19 C 下面正确的字符常量是: A)a B)// C)W D) *20 d 下面四个选项中,均是不正确的八进制数或十六进制数的选项是。 A) 016 B)oabc C)010 D) 0a12 0x8f 017 -0x11 7ff 018 0x8 0x16 -123 *21 C 下面四个选项中,均是正确的八进制数或十六进制数的选项是。 A)一10 B)0abc C)0010 0) 0al2 0x8f 一017 一0x11-0xl23 一011 0xc 0xf1 一0x8 *22 d 下面四个选项中、均是正确的数值常量或字符常量的选项是: A)0.0 日)a C)3D)十001 0f 3.9E-2.5 011 0xabcd 8.9e lel0xFFOO 2e2 / 0a 50. *23 A 下面不正确的字符串常量是。 A)abc B)1212 C)0 D) *24 c 若有代数式3ae/bc,则不正确的C语言表达式是: A) a/b/c*e*3 B)3*a*e/b/c C)3*a*e/b*c D)a*e/c/b*3 *25 A 已知各变量的类型说明如下: int k,a,b; unsigned long w 5; double x1.42; 则以下不符合C语言语法的表达式是: A) x%(一3) B) w-2 C)k(a2,b3,a十b) D)a十 a一(b4)*(a3) *26 A 已知各变量的类型说明如下: int i8,k,a,b; unsigned long w5; double x1.42,y5.2; 则以下符合C语言语法的表达式是: A) a十a一(b 4)*(a3) B)aa*32 C) x%(一3) D)yf1oat(i) *27 D 以下不正确的叙述是 A)在C程序中,逗号运算符的优先级最低 B)在C程序中,APH和aph是两个不同的变量 C)若a和b类型相同,在执行了赋值表达式ab后b中的值将放人a中,而b中的值不变。 D)当从键盘输入数据时,对于整型变量只能输入整型数值,对于实型变量只能输入实型数值。 *28 D 以下正确的叙述是: A)在C程序中,每行中只能写一条语句 B)若a是实型变量,C程序中允许赋值a10,因此实型变量中允许存放整型数 C)在C程序中,无论是整数还是实数,都能被准确无误地表示 D)在C程序中,%是只能用于整数运算的运算符 *29 B 以下符合C语言语法的赋值表达式是 A)d9efd9B) d9e,fd9 C)d9十e,e,d十9 D)d9十ed十7 *30 A 已知字母A的ASCII码为十进制数65,且c2为字符型,则执行语句c2A十6一3;后,c2中的值为 A)D B)68 C)不确定的值 D)C *31 D 在C语言中,要求运算数必须是整型的运算符是。 A) / B) c) ! D)% *32 B 若以下变量均是整型,且numsum7;则执行表达式sUMnum,sUM,num后sum的值为 A) 7 B) 8 C) 9 D) 10 *33 D 在C语言中,int、char和short种类型数据在内存中所占用的字节数 A)由用户自己定义 B)均为2个字节 C)是任意的 D)由所用机器的机器字长决定 *34 A 若有说明语句:char c/72则变量c A)包含1个字符 B)包含2个字符 C)包含3个字符 D)说明不合法,c的值不确定 *35 A 若有定义:int a7;float x2.5,y4.7;则表达式xa%3*(int)(xy)%2/4的值是 A)2•500000 B)2.7500OO c) 3.500000 D) 0.000000。 *36 B sizeof(float)是: A)一个双精度型表达式 B)一个整型表达式 C)一种函数调用D)一个不合法的表达式 *37 C 设变量a是整型,f是实型,i是双精度型,则表达式10ai*f值的数据类型为 A)int B) float C) double D)不确定 *38 A 下面四个选项中,均是非法常量的选项是。 A)as B)// c)-0xl8 D)0xabc -0fff /01 01177 /0 /0xa 12,456 0xfa *39 D 在C语言中, char型数据在内存中的存储形式是: A)补码 B)反码 C)原码 D)ASCII码 *40 B 设变量n为f1oat类型,m为int类型,则以下能实现将n中的数值保留小数点后两位,第三位进行四舍五人运算的表达式是一一一。 A) n(n*1000.5)/100.0 B)mn*1000.5 ,n m/100.0 C) nn*1000.5/100.0 D)n(n/1000.5)*100.0 *41 C 表达式18/4*sqrt(4.0)/8值的数据类型为: A) int B)float C)double D)不确定 *42 C 设C语言中,一个int型数据在内存中占2个字节,则unsigned int型数据的取值范围为: A) 0255 B) 032767 C) 065535 D) 02147483647 *43 D 设有说明: char w; int x; f1oat y; double z;则表达式w* xz一y值的数据类型为: A)float B)char C)int D)double *44 D 若有以下定义,则能使值为3的表达式是: int k 7,x 12; A) x%(k% 5)B) x%(k一k%5) C) x%k- k%5 D) (x%k)一(k%5) *45 C 设以下变量均为int类型,则值不等于7的表达式是 A) (x y 6, xy,x1) B)(x y 6,xy,y1) C) (x 6,x1,y 6,xy) D) (y6,yl,x y,x1) *46 D putchar函数可以向终端输出一个: A)整型变量表达式值 B)实型变量值 C)字符串 D)字符或字符型变量值 *47 B printf函数中用到格式符%5s ,其中数字5表示输出的字符串占用5列。如果字符串长度大于5,则输出按方式 A)从左起输出该字串,右补空格 B)按原字符长从左向右全部输出 C)右对齐输出该字串,左补空格 D)输出错误信息 *48 C printf函数中用到格式符%5s ,其中数字5表示输出的字符串占用5列。如果字符串长度小于5,则输出按方式。 A)从左起输出该字串,右补空格 B)按原字符长从左向右全部输出 C)右对齐输出该字串,左补空格 D)输出错误信息 *49 D 已有定义 int a-2;和输出语句:printf(%8lx,a);以下正确的叙述是: A)整型变量的输出格式符只有%d一种 B)%x 是格式符的一种,它可以适用于任何一种类型的数据 C)%x 是格式符的一种,其变量的值按十六进制输出,但%8lx 是错误的 D)%8lx 不是错误的格式符,其中数字8规定了输出字段的宽度 *50 D 若x ,y均定义为int型,z定义为double型,以下不合法的scanf函数调用语句是: A) scanf( %d%lx,%le,x,y,z); B) scanf(%2d * %d%lfx,y,z ); C) scanf(%x %* d%o,x,y); D) scanf(%x%o%6.2f,x,y,z); *51 A 已有如下定义和输入语句 ,若要求a1,a2,c1,c2值分别为10,20,A和B,当从第一列开始输入数据时,正确的数据输入方式是 int a1,a2; char c1,c2; scanf(%d%c%d%c,a1,c1,a2,c2); A)10A 20B CR B)10 A 20 B C)10A20 D)10A20 B。 *52 B 已有定义int x; f1oat y;且执行scanf(%3d%f,x,y);语句,若从第一列开始输入数据12345 678(回车),则x 的值为 A)12345 B)123 。 C) 45 D) 345 *53 B 已有定义int x; f1oat y;且执行scanf(%3d%f,x,y);语句,若从第一列开始输入数据12345 678(回车),则y 的值为: A)无定值B)45.0000 C) 678.000000 D) 123.00000 *54 D 已有如下定义和输入语句,若要求a1,a2,c1,c2的值分别为10,20,A,B,当从第一列开始输入数据时,正确的数据输入方式是: int a1,a2; char c1,c2; scanf(%d%d,a1,a2); scanf(%c%c,c1,c2); A) 1020AB B)10 20AB C)10 20 AB D)10 20AB *55 D 已有程序段和输入数据的形式如下,程序中输入语句的正确形式应当为 main() {int a;float f; printf(/nInput number:); 输入语句 printf(/nf%f,a %d/n ,f,a); } Input number: 4.5 2 A )scanf(%d,%f,a,f); B)scanf(%f,%d,f,a) C)scanf(%d%f,a,f); D)scanf(%f%d,f,a); *56 B 根据定义和数据的输入方式,输入语句的正确形式为: 已有定义: float fl,f2; 数据的输入方式:4.52 3. 5 A)scanf(%f,%f,f1,f2); B)scanf(%f%f,f1,f2 ); C)scanf(%3.2f%2.1f,f1,f); D)scanf(%3.2f%2.1f,f1,f2); *57 D 阅读以下程序,当输入数据的形式为25,13,10正确的输出结果为: main() {int x,y,z scanf(%d%d%d,x,y,z ); printf(xyz%d/n ,xyz);。 } A)x yz48 B)x yz35 C)x z35D)不确定值 *58 B 阅读 下程序,若运行结果为如下形式 ,输入输出语句的正确内容是: main() {int x; float y;printf(enter x,y :) 输入语句 输出语句 } 输入形式 enter x,y: 2 3.4 输出形式 xy5.40 A)scanf(%d,%f,x,y);printf(/nxy %4.2f,xy); B)scanf(%d%f,x,y );printf(/nxy%4.2f,xy); C)scanf(%d%f,x,y); printf(/nxy%6.lf,xy); D)scanf(%d%3.1f,x,y );printf(/nx十y%4.2f,xy); *59 D 以下说法正确的是: A)输入项可以为一实型常量,如scanf(%f,3.5); B)只有格式控制,没有输入项,也能进行正确输入,如scanf(a%d,b%d); C)当输入一个实型数据时,格式控制部分应规定小数点后的位数, 如scanf(%4.2f,f); D)当输入数据时,必须指明变量的地址,如scanf(%f,f); *60 A 根据下面的程序及数据的输入方式和输出形式,程序中输入语句的正确形式应该为: main() {char ch1 ,ch2 ,ch3; 输入语句 printf(%c%c%c,ch1,ch2,ch3);} 输入形式: A B C 输出形式: A B A) scanf(%c%c%c,ch1,ch2,ch3); B) scanf(%c,%c,%c, ch1,ch2, ch3); C) scanf(%c %c %c,ch1,ch2,ch3); D) scanf(%c%c,ch1,ch2,ch3); *61 D 有输入语句: scanf(a %d,b %d,c%d,a,b,c);为使变量a的值为1,b为3,c为2,从键盘输入数据的正确形式应当是 A)132(回车) B)1,3,2(回车) C)a1b3c2(回车) D)a1,b 3,c 2(回车) *62 A 以下能正确地定义整型变量a,b和c 并为其赋初值5的语句是 A)int ab c 5; B) int a,b, c 5; C)a 5,b5,c5; D) a b c5; *63 A 已知ch是字符型变量,下面不正确的赋值语句是 A)chab; B)ch/0; C)ch79; D) ch59; *64 B 已知ch是字符型变量,下面正确的赋值语句是 A) ch 123; B) ch /xff; C) ch /08; D) ch/; *65 B 若有以下定义,则正确的赋值语句是: int a,b;float x; A) a1,b2, B)b; C) a b 5 D) b int(x); *66 B 设x 、y均为f1oat型变量,则以下不合法的赋值语句是 A)x; B)y(x%2)/10; C) x*y8; D)xy0; *67 A x,y,z均为int型变量,则执行语句x(y(z10)5)一5;后,x 、y 和之的值是: A) x10 B) x10 C) x10 D) x10 y15 y10 y10 y5 z10 z10 z15 z10 *68 D 逻辑运算符两侧运算对象的数据类型一一一。 A)只能是0或1 B)只能是0或非0正数 C)只能是整型或字符型数据 D)可以是任何类型的数据 *69 C 下关于运算符优先顺序的描述中正确的是一一一。 A)关系运算符 算术运算符 赋值运算符 逻辑与运算符 B)逻辑 运算符 关系运算符 算术运算符 赋值运算符 C)赋值运算符 逻辑与运算符 关系运算符 算术运算符 D)算术运算符 关系运算符 赋值运算符 逻辑与运算符 *70 B 下列运算符中优先级最高的是一一一。 A) B)十 C) D)! *71 C 能正确表示当x 的取值在[1,10]和[200,210]范围内为真,否则为假的表达式是一一一。 A) (x1) (x10) (x 200) (x210) B) (x1) || (x10) ||(x200) ||(x210) c) (x1) (x10)||(x 200) (x210) D) (x 1)||(x 10) (x 200)||(x210) *72 C 表示图中坐标轴上阴影部分的正确表达式是: /||//| /||//| ----------------------------- X a b c A)(XA)(XB)(XC) B) (x a)||(bxc) C)(xa)|| (x b) (xc) D)(x a)(b x c) *73 C 判断char型变量ch是否为大写字母的正确表达式是一一一。 A) A chz B)(ch A)(ch z ) C)(ch A )(chz) D)( A ch)AND(z ch) *74 D 设x,y 和z是int型变量,且x 3,y 4,z 5,则下面表达式中值为0的是 A)yy B)x y C) x||yzy-z D) !(xY)!Z||1) *75 C 已知x 43,chA,y0则表达式(x y chB!Y) 的值是 A)0 B)语法错 C)1 D)假 *76 C 若希望当A的值为奇数时,表达式的值为真,A的值为偶数 表达式的值 为假。则以下不能满足要求的表达式是: A) A%2 1 B)!(A%2 0) C)!(A%2) D) A%2 *77 B 设有 int a 1,b2,c 3, d 4, m2, n2; 执行(m ab)(ncd)后n的值为: A)1B )2 C)3 D)4 *78 D 判断char型变量c1是否为小写字母 正确表达式为: A) a cl z B) (cl a)(clz) C)( a cl)||( z cl) D)(c1a)(clz) *79 B 以下程序的运行结果是: #include stdio.h main() ,, / {int a,b,d 241; ad/100 % 9 b (一1)(一1); printf(%d,%d,a ,b); } A)6,1 B)2,1 C) 6,0 D)2,0 *80 C 执行以下语句后a的值为: int a,b,c; a b c 1; a||bc A)错误 B) 0 C) 2 D) 1 *81 A 执行以下语句后b 的值为: int a5,b6,w1,x2,y3,z4; (awx)(byz); A) 6 B) 0 C) 1 D) 4 *82 C 以下不正确的if语句形式是: A)if(xy x!y); B)if(x y) xy C)if(x ! y)scanf(%d,x )else scanf(%d,y); D)if(XY)NBSP;{X;Y;} *83 A 下列运算符中优先级最低的是: A)?: B) c) D) ! *84 B 以下if语句语法正确的是一一一。 A)if(x0) printf(%f,x) else printf(%f,- -x); B) if (x0) {xxy;printf(%f,x);} else printf(f,-x); C) if(x0) {xxy; prinrf(%f,x);}; else printf(%f,-x); D) if(x 0) { x x y;printf(%f,x)} else printf(%f,-x); *85 D 请阅读以下程序: main() {int a5,b0,c0; if(abc) printf(***/n ); e1se printf($$$/n); 以上程序 : A)有语法错不能通过编译 B)可以通过编译但不能通过连接 C)输出***D)输出$$$ *86 C 以下程序的运行结果是 : main() {int m5; if(m 5) printf( %d/n,m); e1se printf(%d/n,m- - ); } A)4 B)5 C)6 D)7 *87 B 当a1,b3,c5,d4 ,执行完下面一段程序后x 的值是 : if(a if(c else if(a if(b else x 3; else x6; else x7; A)18)2 C)3 D)6 *88 C 以下程序的输出结果是: main() {int a100,x 10,y20,okl5,ok20; if (x if(y ! 10) if(!okl) a1; else if(ok2) a10; a-1: printf( %d/n,a ) } A) 1 B) 0 C)一1 D)值不确定 *89 B 以下程序的输出结果是: main() {int x 2,y 一1,z2; if (xY)NBSP; if(y0) z 0; else z 1; printf(%d/n,z); } A)3 B )2 C)1 D) 0 *90 B 为了避免在嵌套的条件语句If一else中产生二义性,C语言规定else子句 总是与( )配对。 A)缩排位置相同的if B)其之前最近的if C) 之后最近的if D)同一行上的if *91 B 以下不正确的语句为: A) if(xy); B) if (x y) (x! 0) x y; C) if(x! y)scanf(%d,x); else scanf(%d,y); D)if(x y){x ;y十十;} *92 B 请阅读以下程序: #includeSTDIO.NBSP;H / main() {float a,b scanf(%f,a); if (a10.0) b1.0/x; else if((a0.5)(a!2.0))b 1.0/(a十2.0); else if(a10.0) b 1.0/x ; else b10.0; printf(%f/n,y); } 若运行时输入2.0(回车),则上面程序的输出结果是: A)0.000000 B)0.500000 C) 1. 000000 D) 0.250000 *93 B 若有条件表达式(exp) ? a:b--,则以下表达式中能完全等价于表 达式(exp)的是: A) (exp0) B) (exp!0) C) (exp 1) D) (exp!1) *94 A 若运行时给变量x 输入12,则以下程序的运行结果是: main() {int x,y; scanf(%d,x); yx 12?x10: x一12; printf(%d/n,y); } A)0 B)22C)12 0)10 *95 D 以下程序的运行结果是: main() {int k 4,a3,b2,c1; printf(/n %d/n,k a ? k:c } A)4 B )3 C)2 D)1 *96 B 执行以下程序段后、变量a,b,c的值分别是一。 int x10,y9; int a,b,c; a (- -x y)?- -x:y ; b x ; c y; A)a9,b 9,c 9 B )a8,b8,c10 C)a9,b 10,c9 0)a1,b 11,c10 *97 A 若w,x,y,z,m均为int型变量,则执行下面语句后的m值是: w 1;x 2;y 3;z4; m(w m (m m(m A)1B )2 C)3D)4 *98 D 若w1,X 2,y 3,z4,则条件表达式wYZ?Y:Z的值是:NBSP;NBSP; A)4 B)3 C)20)1 *99 C 执行以下程序段后的输出结果是 int w3, z7,x 10; printf(%d/n,x 10? x100:x 一10); printf(%d/n,w||z ); printf(%d/n,!wz); printf(%d/n,wz); A)0 B) 1 C)0 D) 0 1 1 1 1 1 1 0 0 1 1 1 0 *100 C 设有程序段 int k10; while (k0) k k—1; 则下面描述中正确的是 A) while循环执行10次 B)循环是无限循环 C)循环体语句一次也不执行 D)循环体语句执行一次 *101 B 有以下程序段 int x0,s0; while (! x! 0) sx; printf(%d,s); 则 A)运行程序段后输出0 B)运行程序段后输出1 C)程序段中的控制表达式是非法的 D)程序段执行无限次 *101 A 语句while(!E)中的表达式!E等价于: A) E0 B) E!1 C) E!0 D) E1 * A 下面程序段的运行结果是 a1;b 2;c2; while(aBC)NBSP;NBSP;{NBSP;NBSP;NBSP;TNBSP;A;ANBSP;B;NBSP;NBSP;BT;NBSP;C-NBSP;-;} printf(%d,%d,%d,a,b,c); A)1,2,0 B)2,1,0 C)1,2,1 D)2,1,1 *102 D 下面程序段的运行结果是: x y 0; while(x15) y,x y; printf(%d,%d,y,x); A) 20,7 B)6,12 c) 20,8 D)8,20 * C 【题5.6】下面程序段的运行结果是 if n0; while(n2); printf(%d,n); A) 2 B) 3C) 4 D)有语法错 *103 B 设有程序段 t0; while (printf*)) {t; if(t3) break } 面描述正确的是: A)其中循环控制表达式与0等价 B)其中循环控制表达式与0等价 C)其中循环控制表达式是不合法的 D)以上说法部不对 *104 B 下面程序的功能是将从键盘输入的一对数,由小到大排序输出。当输入一对相等数时结束循环,请选择填空: #indude main() {int a,b,t; scanf(%d%d,a,b); while( 【1】 ) {if(ab) {ta;ab;bt;} printf(%d,%d,a,b); scahf(%d%d,a,b);人 } 【1】 A) !ab B) a!b C) a b D) ab *105 C 下面程序的功能是从键盘输入的一组字符中统计出大写字母的个数m和小写字母的个数n,并输出m、n中的较大者,请选择填空: #indude stdio.h main() {int m0,n0; char c; 1 while((【1】)!/n) { if(cA CZ) m ; if(ca cz) n; } printf(%d/n, mM);NBSP;NBSP;NBSP;NBSP;}NBSP;NBSP;NBSP;NBSP;NBSP; 1】 A) cgetchar() B) getchar() C)cgetchar() D) scanf(%c,c) *106 C 下面程序的功能是将小写字母变成对应大写字母后的第二个字母。其中y变成A,z 变成B.请选择填空。 #include stdio. H main() { char c; while((cgetchar())!/n) {if(c a cz) c - 30; if(cz cz 2) 【2】; } printf( %c,c) } 【2】A) cB B) cA C) c-26 D) cc26 *107 B 下面程序的功能是在输入的一批正整数中求出最大者,输入0结束循环,请选择填空。 #include main() {int a,max 0; scanf(%d,a) while(【1】) {if(maxANBSP;NBSP;MAXNBSP;A;NBSP;NBSP;NBSP;NBSP;NBSP;NBSP; scanf(%d,a); } printf(%d ,max );} 【1】 A) ao B)A C) !A 1D)!a *108 C 下面程序的运行结果是。 #includeSTDIO.HNBSP;NBSP; / main() { int num 0; while(num 2) {num printf (%d/n, num);} } A)1 B ) 1 c)1D)1 2 2 2 3 3 4 *109 C 以下程序段 x -1; do {xx*x;} while(!x); A)是死循环 B)循环执行二次 C)循环执行一次 D)有语法错误 *110 C 以下描述中正确的是: A)由于do一while循环中循环体语句只能是一条可执行语句,所以循环体内不能使用复合语句 B) do一while循环由do开始,用while结束,在while(表达式)后面不能写分号 C)在do一while循环体中,一定要有能使while后表达式值变为零(假)的操作 D)do一while循环中,根据情况可以省略while *111 B 若有如下语句 int x3; do { printf( %d/n,x -2);} while(!(--x)); 则上面程序段 A)输出的是 1 B)输出的是1和-2 C)输出的是3和0 D)是死循环 *112 C 下面程序的功能是计算正整数2345的各位数字平方和,请选择填空。 #includeSTDIO.NBSP;H / main() {int n,sum0; n2345 do{ sumsum(n%10)*n%10); n【2】; }while(n); printf(sum%d,sum);} 【2】 A) n/1000 B)n/100 C) n/10 D) n%10 *113 B 下面程序是从键盘输入学号,然后输出学号中百位数字是3的学号,输入0时结束循环。请选择填空。 # includeSTDIO.NBSP;H / main() {1ong int num; scanf(%ld,num); do { if( 【1】) printf(%ld,num); scanf(%ld,num); }while(!num0);} 【1】 A)num%100/103 B)num/100%103 C)num%10/103 D)num/10%103 *114 B 下面程序的功能是把316表示为两个加数的和,使两个加数分别能被13和11整除。请选择填空。 #include main() {int i0,j,k; do{ i;k316一13*i;} while(【1】);jk/11; printf( 31613* %d十11*%d,i,j); } 【1】A)k/11 B) k%11 C) k/110 D) k/11 0 *115 D 下面程序的运行结果是: #indude main() {int y10; do{y--;} while(--y); printf(%d/n,y--); } A)一1B) 1 C)8 D) 0 *116 D 若运行以下程序时,从键盘输入ADescriptor(CR)表示回车),则下面程序的运行结果是: #includeSTDIO.NBSP;H / main() { char c; int v00.v10,v20; do{ switch(cgetchar()) {case a:case A : case e:case E : case i:case I : case o:Case O : case u:case U :vl1; default:v01;v21 ;} ; while(c!/n); printf(v0%d,v1%d,v2%d/n,v0,v1,v2); } A)v07,v14,v27B) v08,v 14,v28 C)v0 11,v14,v211 D) v012,vl4,v212 *117 B 下面程序的运行结果是: #includeSTDIO.NBSP;H / main() {int a1,b10; do {b-a;a;}while(b--0); printf(a%d,b%d/n,a,b); } A)a3,b11 B )a2,b8 C)a1, b一1 D)a4,b9 *118 D 下面有关for循环的正确描述是: A) for循环只能用于循环次数已经确定的情况 B) for循环是先执行循环体语句,后判断表达式 C) 在for循环中,不能用break语句跳出循环体 D) for循环的循环体语句中, 可以包含多条语句,但必须用花括号括起来 *119 B 对for(表达式1;;表达式3)可理解为: A) for(表达式1; 0;表达式3) B) for(表达式1;1;表达式3) C) for(表达式1;表达式1;表达式3) D) for(表达式1;表达式3;表达式3) *120 B 若i为整型变量,则以下循环执行次数是: for (i2;i0;) printf(%d,i-- ); A)无限次 B) 0次 C) 1 次 D) 2次 *121 C 以下for循环的执行次数是: for (x0,y一0; (y123)(x4); x); A)是无限循环 B)循环次数不定 C)执行4次 D)执行3次 *122 A 以下不是无限循环的语句为: A) for (y0,x1;x y;x i) ix ; B) for (;; xi); C) while (1){x ;} D) for(i10; ;i--)sumi; *123 C 下面程序段的运行结果是: for (y 1;y10;) y((x3* y,x1),x-1); printf (x%d,y%d,x,y); A)x27,y27 B)x12,y13 C)x15,y14 D)xy27 *124 D 下面程序段的运行结果是 for(x3;x6;x)printf((x %2)?(**%d):( ##%d/n),x); A)**3 B )##3 C)##3 D)**3##4 ##4 **4 **4##5 **5 **5 ##5 *125 C 下列程序段不是死循环的是 A) int i100; whiLe (1) {ii%1001; if (i100) break; } B) for(;;); C) int k0; do{k;} while (k 0) ; D) int s36; while (s);--s *126 C 执行语句for(i1;i4;);后变量i的值是 A)3 B )4 C)5 D)不定 *127 D 下面程序的功能是计算:至50中是7的倍数的数值之和,请选择填空。 #includeSTDIO.NBSP;H / • main() {int i,sum 0; for(i1;i50;i) if([1]) sumi; printf(%d,sum); } A) (int)(i/7)i/7 B) (int)i/7i/7 C) i%7 0 D) i%70 *128 B 下面程序的功能是计算 1至10之间的奇数之和及偶数之和。请选择填空; # include STDIO.NBSP;H / main() {int a,b,c,i; ac0; for(i0;i10;i2) { ai; [1]; cb; } printf(偶数之和%d/n,a); printf(奇数之和%d/n,c-11), } [1] A )bi-- B) bi1 C) bi D)bi-1 *129 B 下面程序的运行结果是: #include STDIO.NBSP;H / main() {int i; for(i1;i5;i) switch(i%5) {case 0:printf(* );break; case 1 :printf(#);break; default :printf(/n); case 2 :printf(); } A)#* B) # C) # D)# * *130 D 下面程序的运行结果是: #include STDIO.NBSP;H / main() { int x,i; for(j-1;i100;i) {xi; if(x%20) if(x%30) if(x%70) printf(%d,x); } } A)39 81 日)42 84 C)26 68 D) 28 70 *131 C 下面程序段的功能是计算1000!的末尾含有多少个零。请选择填空。 (提示:只要算出1000!中含有因数5的个数即可 for(k0,i5;i1000; i5) while(【1】){k; mm/5;} 【1】A)m%50 B)mm%50 C)m%50 D)m%5!0 *132 D 下面程序的运行结果是: #include main() {int i,b,k0; for(i1;i 5;i) {bi%2; while(b--0) k; } printf(%d,%d,k,b); } A)3,-1 B )8,-1 C)3,0 D)8,-2 *133 B 以下正确的描述是。 A)continue语句的作用是结束整个循环的执行 B)只能在循环体内和switch语句体内使用break语句 C)在循环体内使用break语句或continue语句的作用相同 D)从多层循环嵌套中退出时, 只能使用goto语句 *134 D 下面程序段: for (t1; t100;t) {scanf(%d,x); if(x0) continue; printf(%3d,t);} A) 当x0时整个循环结束 B) x0时什么也不输出 C) printf函数永远也不执行 D)最多允许输出100个非负整数 *135 C 下面程序段: x3; do {yx--; if(!y){ printf(x);continue;} printf(#); } while (1x2); A)将输出## B)将输出##* C)是死循环 D)含有不合法的控制表达式 *136 C 以下描述正确的是 A) goto语句只能用于退出多层循环 B) switch语句中不能出现continue语句 C) 只能用continue语句来终止本次循环 D) 在循环中break语句不能独立出现 *137 C 与下面程序段等价的是: for(n100;n 200; n) {if (n%30) continue; printf(%4d,n);} A) for(n100;(n%3) n200;n) printf(%4d,n); B) for(n100;(n%3)|| n200;n) printf(%4d,n); C) for(n100;n200;n)if(n%3!0)printf(%4d,n) D) for(n100;n200; n) {if(n%3) printf(%4d,n); else continue; break;} *138 B 下面程序的运行结果是: #include { int k0; char cA; do {switch(c) {case A:k;break; case B:k--; case C:k2;break; case D:kk%2;continue; case E:kk*10;breab; default:kk/3;} k;} while(cG) printf(k%d,k);} A)k3 B)k4 C)k2 D)k0 *139 B 若运行以下程序时,从键盘输入3.6,2.4,(表示回车),则下面程序的运行结果是: #indude # include main() {float x,y,z; scanf(%f%f,x,y); zx/y; while(1) {if(fabs(z)1.0) {xy;yz;zx/y;} else break;} printf(%f,y);} A) 1.5 B)1.6 C) 2.0 D) 2.4 *140 B 下面程序的运行结果是: #include stdio.h main() {int a,b; for(a1,b1;a100;a) {if (b20) break; if(b%31) {b3;continue;} b-5;} printf(%d/n,a);} A) 7 B) 8 C)9 D) 10 *141 B 下面程序的运行结果是: #include stdio.h main() {int i; for(i1;i5;i) {if (i%2) printf(#); else continue; printf(*); } printf($);} A) *#*#$ B) #*#*#*$ C) *#*#$ D)#*#*$ *142 A 下面程序的运行结果是: main() {int i,j,a0; for (i0;i2;i) { for (j0;j4;j) {if (j%2) break; a;} a;} printf(%d/n,a); } A) 4 B) 5 C) 6 D) 7 *179 c 在c语言中,引用数组元素时,其数组下标的数据类型允许是__. A)整型常量 B)整型表达式 c)整型常量或整型表达式D)任何类型的表达式 *180 D 以下对一维整型数组a的正确说明是__。 A) int a(10); B)int n 10,a[n]; c) int n; D) #define SIZE 10; scanf(%,J1); int a[SIZE]; int a[n]; *181 D 若有说明:int a[10];则对a数组元素的正确引用是__。 A)a[10] B) a[3.5] C) a(5) D) a[10-10]
*182 A 在C语言中,一维数组的定义方式为:,类型说说明符 数组名__。 A) [常量表达式] B) [整形表达式] c)[ 整型常量]或[整型表达式] D)[整型常量] *183 C 以下能对一维数组a进行正确初始化的语句是__。 A) int a[10](0,0,0,0,0) B)int a[10]{} C) int a[]{0};D) int a[10]{10*1}; *184 C 以下对二维数组a的正确说明是__。 A) int a[3][]; B) floatf a(3,4); c) double a[1][4]; D) float a(3)(4); *185 C 若有说明:int a[3][4]; 则对a数组元素的正确引用是__。 A) a[2][4] B) a[1,3] C) a[11][0] D) a(2)(1); *186 D 若有说明:int a[3][4];则对a数组元素的非法引用是__。 A) a[0][2*1] B) a[1][3] C)a[4-2][0] D)a[0][4] *187 B 以下能对二维数组a进行正确初始化的语句是__。 A) int a[2][]{{1,0,1},{5,2,3}}; B) int a[][3」{{1,2,3},{4,5,6}}; C) int a [2][4]{{1,2,3},{4,5},{6}}; D) int a[][3{{1,0,1},{},{1,1}}; *188 C 以下不能对二维数组a进行正确初始化的语句是__。 A) int a[2][3]{0}; B) int a[][3」{{1,2,3},{4,5,6}}; C) int a[2][4]{{1,2,3},{4,5}{6}}; D) int a[][3]{{1,0,1},{0},{1,1}}; *189 D 若有说明 int a[3]「4]{0};则下面正确的叙述是 A只有元素a[0][0]可得到初值0 B此说明语句不正确。 C数组a中各元素都可得到初值但其值不一定为0。 D数组a中每个元素均可得到初值0 *190 D 若有说明int a[][4]{0,0};则下面不正确的叙述是__。 A数组a的每个元素都可得到初值0 B二维数组a的第一维大小为1 C因为二维数组0中第二维大小的值除以初值个数的商为1,故数组a行 数为1 D只有元素a[0]「0」和a[0]「1」可得初值0其余元素均得不到初值0 *191 B 若有说明int a[3]「4]则数组a各元素 A可在程序的运行阶段得到初值0 B可在程序的编译阶段得到初值0 C不能得到确定的初值 D可在程序的编译或运行阶段得初值0 *192 C 以下各组选项中均能正确定义二维实型数组a的选项是 Afloat a[3][4]; Bfloat a(3,4); float a[][4]; float a[3][4]; float a[3][]{{1},{0}}; float a[][]{{0},{0}}; Cfloat a[3][4]; Dfloat a[3][4]; static float a[][4]{{0},{0}}; float a[3][]; auto float a[][4]{{0},{0},{0}}; float a[][4] *193 A 下面程序(每行程序前面的数字表示行号) 1 main() 2 { 3 int a[3]{3*0}; 4 int i; 5 for(i0;i3;i) scanf(%d,a[ i]); 6 for(i1;i3;i) a[0]a[0]a[ i] ; 7 printf(%d/n,a[0]); } A)没有错误B)第3行有错误 C)第5行有错误 D)第7行有错误 *194 C 下面程序一一一(每行程序前面的数字表示行号)。 1 main() 2 { 3 float a[10]{0.0}; 4 int i 5 for(i0;i3;i) scanf(%d,a[ i]); 6 for(i0;i10;i) a[0]a[0]a[ i]; 7 printf(%d/n,a[0]); 8 } A)没有错误 B)第3行有错误 C)第5行有错误 D)第7行有错误 *195 D 下面程序有错的行是 1 main() 2{ 3 int a[3]{1}; 4 int i; 5 scanf(%d,a); 6 for(i1;i3;i) a[0]a[0]a[ i]; 7 printf(a[0]%d/n,a[0]); 8 } A)3 B)6 C)7 D)5 *196 D 下面程序(每行程序前面的数字表示行号) 1 main() 2 { 3 int a[3]{0}; 4 int i; 5 for(i0;i3;i)scanf(%d,a[ i]); 6 for(i1;i4;i)a[0]a[0]a[ i]; 7 printf(%d/n,a[0]); 8 } A)没有错误 B)第3行有错误 C)第5行有错误 D)第6行有错误 *197 D 若二维数组a有m列,则计算任一元素a[ i][j]在数组中位置的公式为 (假设a[0][0]位于数组的第一个位置上。) A)i*mj B)j*pi。C)i*mj-1 D)i*mj1 *198 B 对以下说明语句的正确理解是 int a[10]{6,7,8,9,10}; A)将5个初值依次赋给a[1]至a[5] B)将5个初值依次赋给a[0]至a[4] C)将5个初值依次赋给a[6]至a[10] D)因为数组长度与初值的个数不相同,所以此语句不正确 *199 B 以下不正确的定义语句是__. A) double x[5]{2.0,4.0,6.0,8.0,10.0}; B) int y「5」{0,1,3,5,7,9}; C) char c1[]{’1’,’2’,’3’,’4’,’5’}; 4 。二入广 / ’ (: D) char c2[]}{/x10,/xa,/x8}; *200 B 若有说明:int a[」「3」{1,2,3,4,5,6,7};则a数组第一维的大小是__. A) 2 B) 3 C) 4 D)无确定值 *201 B 若二维数组a有m列,则在a[ i][j]前的元素个数为__. A)j*mj B)i*mj C)i*mj D)i*mj1 *202 A 定义如下变量和数组: int k; int a[3][3]{1,2,3,4,5,6,7,8,9}; 则下面语句的输出结果是 。 for(k0;k3;k) printf (%d,a[k][2-k]); A) 3 5 7B)3 6 9 C) 1 5 9 D) 1 4 7 *203 B 若有以下程序段: ...... int a[]{4,0,2,3,1};i,j,t; for(i1;i5;i) {ta[ i];ji-1; while(j0ta[j]) {a[j1]a[j];j--;} ...... 则该程序段的功能是 __. A)对数组a进行插入排序(升序) B)对数组a进行插入排序(降序) C)对数组a进行选择排序(升序) D)对数组a进行选择排序(降序) *204 D 以下正确的定义语句是__. A) int a[1」[4」{1,2,3,4,5}; B) float x[3][]{{1},{2},{3}}; C) long b[2][3]{{1},{1,2},{1,2,3}}; D) double y[][3]{0}; *205 C 下面程序的运行结果是__. main() {int a[6」「6」,i,j; for(i1;i6;i) for(j1;j6,j) a[ i][j](i/j)*(j/i); for(i1;i6;i) {for(j1;j6;j十十) printf(%2d,a[ i][j]); printf(/n_);} } A)11111 B)00001 C)10000 D)10001 11111 00010 01000 01010 11111 00100 00100 00100 11111 01000 00010 01010 11111 10000 00001 10001 *206 C 下面程序的运行结果是 __. main() {int a[6],i; for(i1;i6;i十十) {a[ i]9*(i-24*(i3))%5; printf(%2d,a[ i]); } } A)—40404B)—40403 C)一40443D)一40440 *207 D 下面是对s的初始化,其中不正确的是__. A) char s[5」{abc} B)char s[5]{a,b,c}; C) char s[5] D) char s[5]abcdef; *208 B 下面程序段的运行结果是 __. char c[5]{a,b,/0,c,/0}; printf(%s,c);} A)’a’’b’ B) ab C) ab c D) ab (其中 表示空格) *209 D 对两个数组a和6进行如下初始化 char a[]ABCDEF; char b[]{’A’,’B’,’C’,’D’,’E’,’F’};卜 则以下叙述正确的是 __. A) a与b数组完全相同 B) a与b长度相同 C) a和b中都存放字符串 D) a数组比b数组长度长 *210 B 有两个字符数组a、b,则以下正确的输入格式是 __. A) gets (a,b); B) scanf (%s%s,a,b); C) scanf (%s%s,a,b); D) gets (a), gets (b); *211 D 有字符数组a[80]和b[80],则正确的输出形式是__. A) puts (a,b); B) printf (%s,%s,a[],b[]); C) putchar(a,b); D) puts (a), puts (b); *212 D 下面程序段的运行结果是__. char a[7]abcdef; char b[4]ABC; strcpy(a,b); printf (%c,a[5]); J。 了 A)一 B)/O C) e D)f(其中一表示空格) *213 D 有下面的程序段 char a[3],b[]china; ab; printf(%s,a); 则__. A)运行后•将输出Chm、、B)运行后将输出Ch’一 C)运行后将输出Chi D)编译出错 *214 B 下面程序段的运行结果是__. char c[]/t/v///0will/n; printf(%d,strlen(c)); A)14 B) 3 C) 9 D)字符串中有非法字符,输出值不确定 *215 D 判断字符串a和b是否相等,应当使用__. A) if (ab) B) if (ab) C) if (strcpy(a,b)), D) if (strcmp(a,b)) *216 D 判断字符串s1是否大于字符串s2应当使用__. A) if (sls2) B) if (strcmp(s1,s2)) C) if (strcmp(s2,sl)0) D) if (strcmp(s1,s2)0) *217 A 下面程序段是输出两个字符串中对应字符相等的字符。请选择填空。
char x[]programming;
char y[]Fortran;
int i0;
while (x[ i]!/0 y[ i]!/0) {if (x[i ]y[ i]) printf (%c,1 ); else i;}
} 【1】A)x[i] B)y[i] C)x[ i] D)y[ i] *218 D 下面描述正确的是__. A)两个字符串所包含的字符个数相同时,才能比较字符串 B)字符个数多的字符串比字符个数少的字符串大 C)字符串STOP 与STOp相等 D)字符串hat小于字符串he
*219 C 下述对C语言字符数组的描述中错误的是 A)字符数组可以存放字符串 B)字符数组的字符串可以整体输入、输出 C)可以在赋值语句中通过赋值运算符对字符数组整体赋值 D)不可以用关系运算符对字符数组中的字符串进行比较 *220 B 有已排好序的字符串a,下面的程序是将字符串s中的每个字符按a中元素 的规律插入到a中。请选择填空。 #indude main() {char a[20」cehiknqtw; char s[]fbla; int i,k,j; for(k0;s[k]!/0;k十) {j0; while(s[k]a[j]a[j]!/0)j; for(istr1en(a);ij;i--) 【2】; a[j」S[k」; } puts(a); } 【2】 A) a[ i]a[i1] B) a[i1]a[ i]; C) a[ i]a[i-1] D) a[i-1]a[ i]; *221 A 下面程序的功能是将字符串5中所有的字符c删除。请选择填空。 #include main() {char s[80]; int i,j; gets(s); for(ij0;s[ i]!/0;i) if(s[ i]!c)【1】 puts(s); 【1】A)s[j]s[ i] B)s[j]s[ i]; C) s[j]s[ i];j; D) s[j]s[ i]; *222 B 下面程序的功能是从键盘输入一行字符,统计其中有多少个单词,单词之间 用空格分隔。请选择填空。 #indude main() {char s[80」,c1,c2; int i0,num0; gets(s); while(s[ i]!/0) {c1s[ i]; 1f(i0) c2; else c2s[i-1]; if(【1】) num; i; ) printf(There are %d words./n,num); } 【1】A)c1 c2 B)cl! c2 C)c1 c2! D)cl! c2! *223 A 下面程序的运行结果是 #indude main() {char ch[7]{12ab56}; int i,s0; for(i0;ch[ i]0ch[ i]9;i2) s10*sch[ i]-0; printf(%d/n,s); } A)1 B)1256 C) 12ab56 D)1 2 5 6 *224 A 当运行以下程序时,从键盘输入:aa bb cc dd (表示回车),则下面程序的运行结果是 # include main() {char a1[5],a2[5」,a3[5],a4[5]; scanf(%s%s,a1,a2); gets(a3); gets(a4); puts(al); puts(a2); puts(a3); puts(a4); } A) aa B) aa ()aa D) aa bb
bb bb bb cc
cc cc dd dd cc dd dd ee *225 D 当运行以下程序时,从键盘输入:ab c dd (表示回车),则下面程序的运行结果是 #include #difine N 6 main() { char c[N]; int i0; for (;i for(i0; iN;NBSP;NBSP;I)NBSP;NBSP;PUTCHAR(C[ 、 A)abcdef B)a C)b D)ab b c c c d d e f *226 A 当运行以下程序时,从键盘输入:AhaMA Aha( 则下面程序的运行结果是 #include stdio.h main() {char s[80],ca; int i0; scanf(%s,s); while(s[ i]!/0) {if(s[ i]c) s[ i]s[ i]-32; else if(s[ i]c-32) s[ i]s[ i]32; i; } puts(s); ) A)ahAMa B)AhAMa C) AhAMa ahA D) ahAMa ahA *227 D 下面程序的运行结果是一一一。 #include #inc1ude main() {char a[80」AB,b[80]LMNP; int i0; strcat(a,b); whi1e(a[i]!/0)b[ i]a[ i]; puts(b); } A)LB B)ABLMNP C)AB D)LBLMNP *228 B 下面程序的运行结果是 #include main() { char str[]SSSWLIA,c; int k; for(k2;(cstr[k])!/0;k) {switch(c) {case I:k;break; case L:continue; default:putchar(c);continue; } putchar(*); } } A)SSW* B)SW* C) SW*A D)SW *229 B 下面程序的运行结果是 #include main() {char a[]morning,t; int i,j0; for(i1;i7;i) if(a[j] ta[j];a[j]a[7]; a[7]a[j];puts(a); } A) mogninr B) mo C) morning D) mornin
将两个无序数组合并为有序链表 实现思想
把两个无序的数组首先排序然后再按照链表结构把它们分别构造好然后再把两个有序链表合并。
int const array1_size 5;//数组1的长度 int const array2_size 7;//数组2的长度 //链表结构体 typedef struct ListNode { int data; ListNode * next; }ListNode;
//合并两个有序链表返回不带头结点的头指针 ListNode * MergeList(ListNode *p,ListNode *q) { ListNode *h,*r; h new ListNode; h-next NULL; r h; while(p !NULL q ! NULL) { if(p-data q-data) { r-next p; r p; p p-next; } else { r-next q; r q; q q-next; } } if(p ! NULL) r-next p; else r-next q; p h; h h-next; delete p; return h; }
//构造一个链表没有头结点的 ListNode * GenerateList(int array[],int length) { ListNode * h,*temp,*old_head ; h new ListNode; h-next NULL; temp h; for(int i 0; i length;i) { ListNode *p new ListNode; p-data array[i]; temp-next p; temp p; } temp-next NULL; old_head h; h h-next; delete old_head; return h; } //打印链表 void Print_List(ListNode *h) { ListNode *p; p h; for(;p!NULL;pp-next) printf(%d ,p-data);
} //引入冒泡排序算法
void Swap(int *a,int *b) { int temp; temp *a; *a *b; *b temp; } void Bubble_Sort(int *array,int length) { int pass,j; for(pass 1;passlength-1;pass) for(j0;jlength-2;j) if(array[j]array[j1]) Swap(array[j],array[j1]); }
/*********************OK所有准备工作已经做好开始main()函数**********/
//输入字符表示结束 int _tmain(int argc, _TCHAR* argv[]) { char end; int List1[array1_size]{9,5,6,10,45}; int List2[array2_size]{3,1,4,6,7,9,0}; Bubble_Sort(List1,array1_size); Bubble_Sort(List2,array2_size); ListNode * m_list1,*m_list2,*m_list; m_list1 GenerateList(List1,array1_size); m_list2 GenerateList(List2,array2_size); m_list MergeList(m_list1,m_list2); Print_List(m_list); scanf(%c,end); return 0; } 上海聚力传媒技术有限公司官方VC笔试题解答 上海聚力传媒技术有限公司成立于2005年5月是家新冒出来的公司而他能够冒出来的原因是由于它的电视直播软件PPLIVEwww.pplive.com抢占了基于P2P技术的网络视讯服务的先机超级女生电视节目的火爆成就了PPLIVE软件这款软件不过现在这个领域的竞争者蜂拥而上日子并不轻松。如果是我我会很慎重的考虑这类新兴小公司的当然我还是很佩服它的公司的创始人是华中科技大学的校友有幸见过他的演讲。 下面是它2005年度的官方VC笔试题他称如有自信2小时能做完的应聘者请将做完答案发mail至campus_hrsynacast.com我们会马上和你联系的。呵呵我并不打算把答案发到这个邮箱去。 一、问答 1、实模式与保护模式。为什么要设计这两种模式好处在什么地方分别写出各自寻址的过程。 答 1. 实模式又叫实地址模式CPU完全按照8086的实际寻址方法访问从00000h--FFFFFh1MB大小的地址范围的内存在这种模式下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、一个内存变量a5有5个线程需要对其进行操作其中3个对a进行加1操作2个对a进行减1操作为了保证能够得到正常结果6需要使用什么方法列出越多越好 答即要求列出线程同步方法具体答案可见下面一题。 5、描述并比较以下对象事件信标临界区互斥对象。 答这些对象都是用于线程同步的对象。 临界区一种保证在某一时刻只有一个线程能访问数据的简便办法。它只可以在同一进程内部使用。主要API函数有产生临界区InitializeCriticalSection删除临界区DeleteCriticalSection进入临界区EnterCriticalSection退出临界区LeaveCriticalSection。 互斥对象互斥对象跟临界区相似但它不仅仅能够在同一应用程序不同线程中实现资源的安全共享而且可以在不同应用程序的线程之间实现对资源的安全共享当然下面两者也有这个特点。主要API函数有创建互斥量 CreateMutex打开一个存在的互斥量 OpenMutex释放互斥量的使用权ReleaseMutex关闭互斥量 CloseHandle。 信标使用信号量信标最重要用途是信号允许多个线程同时使用共享资源它指出了同时访问共享资源的线程最大数目。它的API函数和使用方法都与互斥对象相似如创建信号灯CreateSemaphore传入的参数可以指定信号灯的初始值。 事件用来通知其他进程/线程某件操作已经完成。API函数有创建打开事件对象等特殊点的是可以用函数SetEvent人工设置事件为有无信号状态因此创建事件对象时可以有两种方式一种为自动重置一种为人工重置。只有人工重置方式创建的事件对象才能正确使用函数SetEvent。 鉴于本套题考的是VC有必要说明的是在MFC中对于各种同步对象都提供了相对应的类CCtiticalSection,CMutex,CSemaphore ,CEvent另外为使用等待功能封装了两个类CSingleLock和CMultiLock。这些类方便了使用这些同步对象。 6、cdecl、stdcall、fastcall是什么哪种可以实现个数不定的入口参数为什么 答三者都是函数调用的约定。 cdeclc declareC调用约定的缩写是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 only known by its code name.}; int i0,count0; bool flagtrue; while (text[i]i1000) { if (text[i] ) { flagtrue; } else if (flagtrue ((text[i]atext[i]z)||(text[i]Atext[i]Z))) { // 前有空格接着出现字母表示出现一个单词。 count; flagfalse; } i; } coutcount; } 2、国际象棋有8×8格每个格子可放一个棋子。皇后的规则是可以横、竖、斜移动。在一个棋盘放置8个皇后并使它们互相无法威胁到彼此。 答以下是可执行C代码采用非递归解法你如果想了解皇后问题的算法的详细过程可看下面网址 http://www.cnjcw.cn/infoview/2005031720203563221270.html 不过下面的代码是以列优先进行试探的不是上面网址介绍的那样以行优先的当然本质是一样的。
#include iostream.h #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(row0 ) //跳出条件是回溯到无法回溯时 { queen[row] ; //row列上的皇后走到下一行试试 if(queen[row] QUEEN) //当前列全部走完 { queen[row] -1 ; //当前列棋子置于准备状态 row-- ; //回溯到上一列的棋子 if(row0) //回溯时要清理如下行斜线的标志位 { 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***第count种解法***endl ; for(int i0;iQUEEN;i) cout第i列皇后在第queen[i]行endl; } row_YN[queen[row]] true ;// 当前行设为有棋子 passive_YN[queen[row] row] true ;//当前行正斜率方向有棋子 negative_YN[QUEEN-1 row - queen[row]] true ; //当前行负斜率方向上也有棋子 row ; if(row QUEEN) { // 找到解后再次回溯找另外的解这同上面无解回溯是一样的 row-- ; row_YN[queen[row]] false ; passive_YN[queen[row] row] false ; negative_YN[QUEEN-1 row - queen[row]] false ;//原理同回溯 } flag false ; } } } } coutQUEEN皇后问题一共有count种解法endl ; return 0 ; } 3、输入二个64位的十进制数计算相乘之后的乘积。 答以下代码为网上别人贴出的输入任意位数十进制数包括小数负数都可以得出正确结果。 思路是将大数当作字符串进行处理也就是将大数用10进制字符数组进行表示然后模拟人们手工进行“竖式计算”的过程编写乘法。
#include iostream.h #define MAX 100 int str_num(char str[]) //计算字符串的长度,等效于strlen(str); { int i0,num_str0; while(str[i]!0) {num_str; i; } return(num_str); } void place(int num_str,char str[]) //将字符串高低颠倒。 { int temp0,i0,j0; for(i0,jnum_str-1;ij;i,j--) {tempstr[j]; str[j]str[i]; str[i]temp; } } void transition(unsigned int a[],char str1[]) //数字字符转化为数字。 { int i0; while(str1[i]!0) {a[i]str1[i]-0; i; } } void multiply_int(unsigned int a[],unsigned int b[],unsigned int c[]) //大数相乘算法入口为整形数组。 { int i0,j0; for(i0;iMAX;i) for(j0;jMAX;j) { c[ij]a[i]*b[j]; c[ij1]c[ij]/10; c[ij]%10; } } void output(int sign,unsigned int c[],int quan) //数据输出。 { int sign_temp0,i0; coutThe result is: ; if(sign1) cout-; for(iMAX-1;i-1;i--) { if(sign_temp0) {if(c[i]!0) sign_temp1; } if(sign_temp1) { if(iquan-1) cout.; coutc[i]; c[i]0; } } coutendl; } void multiply_string(char str1[],char str2[],unsigned int c[]) //大数相乘入口为字符串。 { unsigned int a[MAX]{0},b[MAX]{0}; int sign0; transition(a,str1); transition(b,str2); multiply_int(a,b,c); } int sign_comp(char str1[],char str2[]) //符号判断如果为负数将作相应处理。 { int i0,sign_num0; if(str1[0]45) {sign_num!sign_num; for(i0;iMAX-1;i) str1[i]str1[i1]; } if(str2[0]45) {sign_num!sign_num; for(i0;iMAX-1;i) str2[i]str2[i1]; } return (sign_num); } int format(char str[]) //将输入的字符串进行格式化。以得到字符的一些标志信息和相应格式的新数据串。 { int point0,quan0,i0,j,k0,sign_point0,num_str0; num_strstr_num(str); while(str[i]!0) { if(str[i]0||str[i]9) if(str[i]!.) {coutdata errorendl; return(-1); } else {point; sign_pointi; } if(point1) {coutdata errorendl; return(-1); } i; } if(point1) { for(jsign_point;jnum_str;j) str[j]str[j1]; num_str--; quannum_str-sign_point; } place(num_str,str); return(quan); } void clear(char str[]) //清空函数。 { int i; for(i0;iMAX;i) { str[i]0; } } void main(void) //主函数。 { char str1[MAX]{0},str2[MAX]{0}; int quan10,quan20,sign0; unsigned int c[MAX*21]{0}; do { coutPlease input the first number:; cinstr1; coutPlease input the second number:; cinstr2; signsign_comp(str1,str2); quan1format(str1); quan2format(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,quan1quan2); } 所有题目到此结束说实话后面两题的算法我就是看别人的代码呵呵再次实话后两题代码也不是我写的只是对已有代码做了些修改使结构更清晰便于阅读 intel的面试题不用任何局部和全局变量实现int strlen(char *a)
int strlen(char *a) {
if(0 *a) return 0; else return 1 strlen(a 1); } 传说中的baidu笔试题另一个版本
一、选择题15分 共10题 1. 已知一个线性表(38,25,74,63,52,48)采用的散列函数为Hash($Key)$Key mod 7将元素散列到表长为7的哈希表中存储。请选择后面两种冲突解决方法分别应用在该散列表上进行等概率成功查找的平均查找长度拉链法 线性探测法 . A. 1.0 B. 1.5 C. 1.7 D. 2.0 E. 2.3 F. 7/6 G. 4/3 H. 3/2
2. 需要将OS缓冲区的数据刷新到硬盘可以调用的函数有(多选) A.fflush() B. fsync() C. sync() D.writev()
3. 下面哪个shell语句不能打印出用户主目录的路径 A. echo “$HOME” B. echo ~ C. echo $HOME D. echo $HOME
4. 最坏情况下合并两个大小为n的已排序数组所需要的比较次数 A.2n B.2n-1 C.2n1 D.2n-2
5. 一个B类网的子网掩码是255.255.240.0这个子网能拥有的最大主机数是 A. 240 B. 255 C.4094 D. 65534
6. 以下代码执行后val的值是___: unsigned long val 0; char a 0x48; char b 0x52; val b 8 | a; A 20992 B 21064 C 72 D 0
7. 内存的速度远远高于磁盘速度所以为了解决这个矛盾可以采用 A 并行技术 B虚存技术 C 缓冲技术 D通道技术
8. 以下代码打印的结果是假设运行在i386系列计算机上 struct st_t { int status; short* pdata; char errstr[32]; }; st_t st[16]; char* p (char*)(st[2].errstr 32); printf(%d, (p - (char*)(st)));
A 32 B 114 C 120 D 1112
9. 同一进程下的线程可以共享以下 A. stack B. data section C. register set D. thread ID
10. 以下哪种操作最适合先进行排序处理 A 找最大、最小值 B 计算算术平均值 C 找中间值 D 找出现次数最多的值
二、简答题20分共2题
1. 6分下面是一个http请求 GET /baidu/blog/item/6605d1b4eb6433738ad4b26d.html HTTP/1.1 Host: hi.baidu.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.0.6) Gecko/20060728 Firefox/1.5.0.6 Accept: text/xml,application/xml,application/xhtmlxml,text/html;q0.9,text/plain;q0.8,image/png,*/*;q0.5 Accept-Language: zh-cn,zh;q0.5 Accept-Encoding: gzip,deflate Accept-Charset: gb2312,utf-8;q0.7,*;q0.7 Keep-Alive: 300 Connection: keep-alive Referer: http://hi.baidu.com/baidu Cookie: BAIDUIDAFB70E986AC48B336ABAB7505CDD1C76; 请解释以下各字段基本含义 Host、User-Agent、Accept-Charset、Connection、Referer、Cookie
2. 14分函数A将字符串str1转成小写并打印出转化前后的字符串。另外改错时不能改变函数的接口和主要思路。改错时请指出行号。 1 #include stdio.h 2 #include stdlib.h 5 char* str1 ABDFLjlero我们都是saf; 7 char* ToLower(char s[]) 8 { 9 static size_t isizeof(s); 10 11 for (i; i0; i--) { 12 if (s[i]A s[i]Z) { 13 s[i] 26; 14 } 15 } 16 return s;
} 19 int A() 20 { 21 printf(old str[%s] after lower[%s]n, str1, ToLower(str1)); 22 }
三、编程题30分 共1题 注意要求提供完整代码如果可以编译运行酌情加分。
1. 两个已排序的整型数组求交集最快算法 输入两个已排序的整型数组int a[m], b[n] 输出两个数组的交集 四、设计题35分 共1题 注意请尽可能详细描述你的数据结构、系统架构、设计思路等。建议多写一些伪代码或者流程说明。 1. 考虑一个字符串替换的过程在一个文本文件中含有一些文本内容和一些需要替换的变量变量的格式为“$Var$”原来的“$”使用“$$”进行转义原来的“$$”表示为“$$$”。我们将含有变量的文件称为模板(文件名为t)文本文件的平均长度为100K。另外还有一系列的变量文件里面为变量名和变量值的对应关系(文件名为1.v , 2.v… n.v)每个变量文件包含的变量数在百万数量级且变量排列次序不定。现要求将模板里的变量分别用变量文件里的变量替换并将生成的文件写成(1.r, 2.r… n.r)。 要求从算法和实现上和实现技术上的细节对程序进行优化尽量使程序高效。程序运行环境为2G内存4CPU。阐明主要思路给出伪码和说明可以着重指出你使用的优化技术。 例子模板文件为 This is an $FF$ $$. I like $FF$ and $FA$。 变量文件为 1.v FF : banana FA : apple 2.v FA: 苹果 FF : 香蕉 则生成文件为 1.r This is an banana $$. I like banana and apple。 2.r This is an香蕉 $$. I like 香蕉and苹果。
百度11月4日网上笔试题及答案仅供参考 1用C语言实现一个revert函数它的功能是将输入的字符串在原串上倒序后返回。 2 编程 用C语言实现函数void * memmove(void *dest,const void *src,size_t n)。memmove 函数的功能是拷贝src所指的内存内容前n个字节 到dest所指的地址上。 3 英文拼写纠错 在用户输入英文单词时经常发生错误我们需要对其进行纠错。假设已经有一个包 含了正确英文单词的词典请你设计一个拼写纠错 的程序。 1请描述你解决这个问题的思路 2请给出主要的处理流程算法以及算法的复杂度 3请描述可能的改进改进的方向如效果性能等等这是一个开放问题。 4 寻找热门查询 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来每个查询串 的长度为1-255字节。假设目前有一千万个记录 这些查询串的重复度比较高虽然总数是1千万但如果除去重复后不超过3百万个 。一个查询串的重复度越高说明查询它的用户越多 也就是越热门。请你统计最热门的10个查询串要求使用的内存不能超过1G。 1请描述你解决这个问题的思路 2请给出主要的处理流程算法以及算法的复杂度。 5 集合合并 给定一个字符串的集合格式如 {aaa bbb ccc} {bbb ddd}{eee fff}{ggg}{ddd hhh} 要求将其中交集不为空的集合合并要求合并完成后的集合之间无交集例如上例应 输出 {aaa bbb ccc ddd hhh}{eee fff} {ggg} 1请描述你解决这个问题的思路 2请给出主要的处理流程算法以及算法的复杂度 3请描述可能的改进改进的方向如效果性能等等这是一个开放问题。 1 1 题 char *revert(char * str) { int nstrlen(str); int i0; char c; for(i0;i { cstr; strstr[n-i]; str[n-i]c; } return str; } /// 2 题 void * memmove(void *dest,const void *src,size_t n) { assert((dest!0)(src!0)); char * temp(char * )dest; char * ss(char * )src; int i0; for(;iN;I) { *temp*ss; } return temp; } / 3 题 (1)思路 : 字典以字母键树组织在用户输入同时匹配 (2) 流程: 每输入一个字母 沿字典树向下一层 a若可以顺利下行则继续至结束给出结果 b)若该处不能匹配纠错处理给出拼写建议,继续至a 算法: 1.在字典中查找单词 字典采用27叉树组织,每个节点对应一个字母,查找就是一个字母 一个字母匹配.算法时间就是单词的长度k. 2.纠错算法 情况:当输入的最后一个字母不能匹配时就提示出错,简化出错处理动态提示 可能 处理方法: (a)当前字母前缺少了一个字母搜索树上两层到当前的匹配作为建议 (b)当前字母拼写错误当前字母的键盘相邻作为提示只是简单的描述可 以有更多的 根据分析字典特征和用户单词已输入部分选择(a),(b)处理 复杂性分析影响算法的效率主要是字典的实现与纠错处理 a字典的实现已有成熟的算法改进不大也不会成为瓶颈 (b)纠错策略要简单有效 ,如前述情况是线性复杂度 (3)改进 策略选择最是重要可以采用统计学习的方法改进。 // 4 题 (1)思路 用哈希做 (2) 首先逐次读入查询串算哈希值保存在内存数组中同时统计频度 注意值与日志项对应关系 选出前十的频度取出对应的日志串简单不过了。 哈希的设计是关键。 // 5 题 1思路先将集合按照大小排列后,优先考虑小的集合是否与大的集合有交集。有 就合并如果小集合与所有其他集合都没有交集则独立。独立的集合在下一轮的比 较中不用考虑。这样就可以尽量减少字符串的比较次数。当所有集合都独立的时候 就终止。 2处理流程 1.将集合按照大小排序组成集合合并待处理列表 2.选择最小的集合找出与之有交集的集合 如果有合并之 如果无则与其它集合是独立集合从待处理列表 中删除。 3.重复直到待处理列表为空 算法 1。将集合按照大小从小到大排序,组成待处理的集合列表。 2。取出待处理集合列表中最小的集合对于集合的每个元素依次在其他集合中搜索 是否有此元素存在 1若存在则将此小集合与大集合合并并根据大小插入对应的位置 。转3 。 2若不存在则在该集合中取下一个元素。如果无下一个元素即所有元素 都不存在于其他集合。则表明此集合独立从待处理集合列表中删除。并加入结果集 合列表。转3。 3。如果待处理集合列表不为空转2。 如果待处理集合列表为空成功退出则结果集合列表就是最终的输出。 算法复杂度分析 假设集合的个数为n最大的集合元素为m 排序的时间复杂度可以达到n*log(n) 然后对于元素在其他集合中查找最坏情况下为n-1*m 查找一个集合是否与其他集合有交集的最坏情况是m*m*(n-1) 合并的时间复杂度不会超过查找集合有交集的最坏情况。 所以最终最坏时间复杂度为O(m*m*n*n) 需要说明的是此算法的平均时间复杂度会很低因为无论是查找还是合并都是处 于最坏情况的概率很小而且排序后优先用最小集合作为判断是否独立的对象优先 与最大的集合进行比较这些都最大的回避了最坏情况。 (3)可能的改进 首先可以实现将每个集合里面的字符串按照字典序进行排列这样就可以将查找以及 合并的效率增高。 另外可能采取恰当的数据结构也可以将查找以及合并等操作的效率得到提高 百度笔试题 写一段程序找出数组中第k大小的数输出数所在的位置。例如{24347}中第一大的数是7位置在4。第二大、第三大的数都是4位置在1、3随便输出哪一个均可。函数接口为int find_orderk(const int * narry, const int n, const int k) 要求算法复杂度不能是O(n^2
参考答案
1
/*************************************** 输入: n:数组元素的个数 k:第几大的数 a:待查找的数组元素 ****************************************/ #include stdio.h
#include stdlib.h
#include time.h
#define N 100 void Rand_select(int*, int, int );
int partition( int*, int, int );
int swap( int, int );
int k, ans; int main()
{ int n, a[N], i; while(scanf( %d%d, n, k ) ! EOF ) { srand(time(NULL)); k--; for( i 0; i n; i ) scanf(%d, a i ); Rand_select( a, 0, n-1 ); printf( %d/n, ans ); } return 0;
} void Rand_select(int a[], int p, int q)
{ int m; if (p q) { m partition( a, p, q ); if( k m ) { ans a[m]; return; } else if( k m ) Rand_select( a, m1, q); else Rand_select( a, p, m-1 ); }
}
int partition(int a[], int p, int q)
{ int last, i; if( q ! p ) swap( a[rand()%(q-p)p], a[p] ); for( i p1, last p; i q; i ) if( a[i] a[p] ) swap( a[i], a[last] ); swap( a[last], a[p] ); return last;
}
int swap(int p, int q)
{ int temp p; p q; q temp; return 0;
}
2可以先用快速排序进行排序其中用另外一个进行地址查找 代码如下在VC6.0运行通过。 //快速排序 #include iostream using namespace std; int Partition (int *L,int low,int high) { int temp L[low]; int pt L[low]; while (low high) { while (low high L[high] pt) --high; L[low] L[high]; while (low high L[low] pt) low; L[low] temp; } L[low] temp; return low; } void QSort (int *L,int low, int high) { if (low high) { int pl Partition (L,low,high); QSort (L, low, pl - 1); QSort (L, pl 1, high); } } int main () { int narry[100],addr[100]; int sum 1, t; cout Input number: endl; cin t; while (t ! -1) { narry[sum] t; addr[sum - 1] t; sum; cin t; } sum - 1; QSort (narry,1,sum); for (int i 1; i sum; i) cout narry[i] /t; cout endl; int k; cout Please input place you want: endl; cin k; int aa 1; int kk 0; for (;;) { if (aa k) break; if (narry[kk] ! narry[kk 1]) { aa 1; kk; } } cout The NO. k number is: narry[sum - kk] endl; cout And its place is: ; for (i 0;i sum;i) { if (addr[i] narry[sum - kk]) cout i /t; } return 0; }
难得啊居然在今天看到这个题。我去年笔试baidu的时候也作过当时写的是这个答案高手分析下 #include math.h #include time.h #include string #include iostream #include vector using namespace std; #define n 10 #define k 5 int main(int argc, char *argv[]) { srand( (unsigned )time(NULL) ); if ( k n ) { cout error! endl; return 1; } vectorint src; cout 源 n 个数据如下 endl; for ( int i 0; i n; i ) { src.push_back( rand() ); cout src[i] ; } vectorint maxNum; //顺序存入最大k个数,第一个为最大的最后一个为第k大 for ( i 0; i k; i ) { maxNum.push_back(-999999); //初始化maxNum,k个-9999999 } for ( i 0; i n; i ) { for ( int j 0; j maxNum.size(); j ) { if ( src[i] maxNum[j]) //比当前的大则放入当前位置后面的数字依次后退 { for ( int i1 maxNum.size()-1; i1 j; i1-- ) { maxNum[i1] maxNum[i1-1]; } maxNum[j] src[i]; break; } } }
cout endl “第” k “大的数字为” maxNum[k-1] endl; return 0; } 分析算法对n个数字只访问一次此部分的时间复杂度为O(n);但每访问一次须与k个数字分别比较所以总的时间渐复杂度为O(n*k)
思想1.consider if(kn) exit(0) 2.if number n is a big one, use pile/stack sort 3.if number n is a small one ,use quick sort; 4;find your k number and print in the screen; find_orderk(const int* narry,const int n,const int k) { if(nk) exit (0); sort(*narry); for(i0;in;i) if(ik) return narry[k]; /*the number of the k is similiar to point*/ } 函数功能返回一个第K小的元素采用快排思想 参数T a[]目标数组 || int l左边界 || int r右边界 || int k第几小元素 template class T T select(T a[], int l, int r, int k) { if(l r) return a[l]; //参数错误直接返回 int i l; int j r1; T pivot a[i]; while(true) { do { i i 1; }while(a[i] pivot); do { j j - 1; }while(a[j] pivot); if(i j) { break; } Swap(a[i], a[j]); } if(j - l 1 k) //如果当前基准适合的位置刚好是K的话则满足了条件 返回基准值 { return pivot; } a[l] a[j]; a[j] pivot; if(j - l 1 k) { return select(a, j1, r, k-jl-1); //如果基准当前位置在K的左边则对右进行快排 } else { return select(a, l, j-1, k); //如果基准当前位置在K的右边则对左进行快排 } } 分析程序
#includestdio.h
class A
{
public: static int numA; A() { num; }; ~A() { num--; }; virtual void print(void) { printf(class A, mum:%d/n, num); } void test(void) { printf(class A test/n); print(); }
};
class B:public A
{
public: static int numB; B() { num--; }; ~B() { }; virtual void print() { printf(class B, num:%d/n, num); } void test(void) { printf(class B test/n); print(); }
};
class C
{
public: virtual void print() { printf(class B/n); }
};
int A::numA 0;
int B::numB 0;
void main()
{ B b; b.print(); b.test(); printf(1/n); A *a; B *p new(class B); p-print(); p-test(); printf(1/n); a p; a-print(); a-test(); delete(a); printf(sizeof(C):%d/n, sizeof(C));
} #include stdio.h
class A1
{
public: A1(){ doSth(); } virtual void doSth(){printf(I am A/n);} void test() {doSth();}
};
class B1:public A1
{
public: virtual void doSth(){ printf(I am B/n);}
}; void main()
{ B1 *b new B1; b-test();
} 1 用C开发的时候用来做基类的类的析构函数一般都是虚函数。
class ClxBase { public: ClxBase() {}; virtual ~ClxBase() {}; virtual void DoSomething() { cout Do something in class ClxBase! endl; }; }; class ClxDerived : public ClxBase { public: ClxDerived() {}; ~ClxDerived() { cout Output from the destructor of class ClxDerived! endl; }; void DoSomething() { cout Do something in class ClxDerived! endl; }; }; void main()
{
ClxBase *pTest new ClxDerived; pTest-DoSomething(); delete pTest;
} 的输出结果是
Do something in class ClxDerived! Output from the destructor of class ClxDerived! 这个很简单非常好理解。 但是如果把类ClxBase析构函数前的virtual去掉那输出结果就是下面的样子了
Do something in class ClxDerived! 也就是说类ClxDerived的析构函数根本没有被调用一般情况下类的析构函数里面都是释放内存资源而析构函数不被调用的话就会造成内存泄漏。我想所有的C程序员都知道这样的危险性。当然如果在析构函数中做了其他工作的话那你的所有努力也都是白费力气。 所以文章开头的那个问题的答案就是这样做是为了当用一个基类的指针删除一个派生类的对象时派生类的析构函数会被调用。