笔试2

 

1.在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?
答:首先,extern是C/C++语言中表明函数和全局变量作用范围的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。
通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。extern "C"是连接申明(linkage declaration),被extern "C"修饰的变量和函数是按照C语言方式编译和连接的。作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。
所以,可以用一句话概括extern “C”这个声明的真实目的:解决名字匹配问题,实现C++与C的混合编程。

2.头文件中的ifndef/define/endif有什么作用?

答:这是C++预编译头文件保护符,保证即使文件被多次包含,头文件也只定义一次。

3. #include<file.h> 与 #include "file.h"的区别?
答:前者是从标准库路径寻找和引用file.h,而后者是从当前工作路径搜寻并引用file.h。

4.评价一下C/C++各自的特点

答:C语言是一种结构化语言,面向过程,基于算法和数据结构,所考虑的是如何通过一个过程或者函数从输入得到输出;

C++是面向对象,基于类、对象和继承,所考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题,通过获取对象的状态信息得到输出或实现过程控制。

5.const 有什么用途?

答:在C/C++中,(1)可以定义const常量,(2)修饰函数的返回值和形参;

在C++中,还可以修饰函数的定义体,定义类的const成员函数。被const修饰的东西受到强制保护,可以预防意外的变动,提高了程序的健壮性。

6.const和#define有什么区别?

答:(1)const和#define都可以定义常量,但是const用途更广。

(2)const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
(3) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。

7.关于sizeof小结的。

答:sizeof计算的是在栈中分配的内存大小。

(1) sizeof不计算static变量占得内存;

(2) 指针的大小一定是4个字节,而不管是什么类型的指针;

(3) char型占1个字节,int占4个字节,short int占2个字节

long int占4个字节,float占4字节,double占48字节,string占4字节

一个空类占1个字节,单一继承的空类占1个字节,虚继承涉及到虚指针所以占4个字节

(4) 数组的长度:

若指定了数组长度,则不看元素个数,总字节数=数组长度*sizeof(元素类型)

若没有指定长度,则按实际元素个数类确定

Ps:若是字符数组,则应考虑末尾的空字符。

(5) 结构体对象的长度

在默认情况下,为方便对结构体内元素的访问和管理,当结构体内元素长度小于处理器位数的时候,便以结构体内最长的数据元素的长度为对齐单位,即为其整数倍。若结构体内元素长度大于处理器位数则以处理器位数为单位对齐。

(6) unsigned影响的只是最高位的意义,数据长度不会改变,所以sizeof(unsigned int)=4

(7) 自定义类型的sizeof取值等于它的类型原型取sizeof

(8) 对函数使用sizeof,在编译阶段会被函数的返回值的类型代替

(9) sizeof后如果是类型名则必须加括号,如果是变量名可以不加括号,这是因为sizeof是运算符

(10) 当使用结构类型或者变量时,sizeof返回实际的大小。当使用静态数组时返回数组的全部大小,sizeof不能返回动态数组或者外部数组的尺寸

8.sizeof与strlen的区别?

答: (1)sizeof的返回值类型为size_t(unsigned int);

(2)sizeof是运算符,而strlen是函数;

(3)sizeof可以用类型做参数,其参数可以是任意类型的或者是变量、函数,而strlen只能用char*做参数,且必须是以’\0’结尾;

(4)数组作sizeof的参数时不会退化为指针,而传递给strlen是就退化为指针;

(5)sizeo是编译时的常量,而strlen要到运行时才会计算出来,且是字符串中字符的个数而不是内存大小;

9.指针和引用的区别?

答:指针和引用都提供了间接操作对象的功能。

(1) 指针定义时可以不初始化,而引用在定义时就要初始化,和一个对象绑定,而且一经绑定,只要引用存在,就会一直保持和该对象的绑定;

(2) 赋值行为的差异:指针赋值是将指针重新指向另外一个对象,而引用赋值则是修改对象本身;

(3) 指针之间存在类型转换,而引用分const引用和非const应用,非const引用只能和同类型的对象绑定,const引用可以绑定到不同但相关类型的对象或者右值

10.数组和指针的区别?

答:(1)数组要么在全局数据区被创建,要么在栈上被创建;指针可以随时指向任意类型的内存块;

(2)修改内容上的差别:

char a[] = “hello”;
a[0] = ‘X’;
char *p = “world”; // 注意p 指向常量字符串
p[0] = ‘X’; // 编译器不能发现该错误,运行时错误

(3)用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。C++/C 语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。

11.空指针和悬垂指针的区别?

答:空指针是指被赋值为NULL的指针;delete指向动态分配对象的指针将会产生悬垂指针。

(1) 空指针可以被多次delete,而悬垂指针再次删除时程序会变得非常不稳定;

(2) 使用空指针和悬垂指针都是非法的,而且有可能造成程序崩溃,如果指针是空指针,尽管同样是崩溃,但和悬垂指针相比是一种可预料的崩溃。

12.C++中有malloc/free,为什么还有new/delete?

答:malloc/free是C/C++标准库函数,new/delete是C++运算符。他们都可以用于动态申请和释放内存。

对于内置类型数据而言,二者没有多大区别。malloc申请内存的时候要制定分配内存的字节数,而且不会做初始化;new申请的时候有默认的初始化,同时可以指定初始化;

对于类类型的对象而言,用malloc/free无法满足要求的。对象在创建的时候要自动执行构造函数,消亡之前要调用析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制之内,不能把执行构造函数和析构函数的任务强加给它,因此,C++还需要new/delete。

13.什么是智能指针?

答:当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝;另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。

  智能指针的一种通用实现技术是使用引用计数。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。

  每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。

14.面向对象技术的基本概念是什么,三个基本特征是什么?

答:基本概念:类、对象、继承; 基本特征:封装、继承、多态。

封装:将低层次的元素组合起来形成新的、更高实体的技术;
继承:广义的继承有三种实现形式:实现继承、可视继承、接口继承。
多态:允许将子类类型的指针赋值给父类类型的指针

15.C++空类默认有哪些成员函数?

答:默认构造函数、析构函数、复制构造函数、赋值函数

16.哪一种成员变量可以在一个类的实例之间共享?

答:static静态成员变量

17.继承层次中,为什么基类析构函数是虚函数?

答:编译器总是根据类型来调用类成员函数。但是一个派生类的指针可以安全地转化为一个基类的指针。这样删除一个基类的指针的时候,C++不管这个指针指向一个基类对象还是一个派生类的对象,调用的都是基类的析构函数而不是派生类的。如果你依赖于派生类的析构函数的代码来释放资源,而没有重载析构函数,那么会有资源泄漏。

18.为什么构造函数不能为虚函数?

答:虚函数采用一种虚调用的方法。需调用是一种可以在只有部分信息的情况下工作的机制。如果创建一个对象,则需要知道对象的准确类型,因此构造函数不能为虚函数。

19.如果虚函数是有效的,那为什么不把所有函数设为虚函数?

答:不行。首先,虚函数是有代价的,由于每个虚函数的对象都要维护一个虚函数表,因此在使用虚函数的时候都会产生一定的系统开销,这是没有必要的。

20.构造函数可以是内联函数

21.什么是多态?多态有什么作用?

答:多态就是将基类类型的指针或者引用指向派生类型的对象。多态通过虚函数机制实现。

多态的作用是接口重用。

22.重载和覆盖有什么区别?

答:虚函数是基类希望派生类重新定义的函数,派生类重新定义基类虚函数的做法叫做覆盖;

重载就在允许在相同作用域中存在多个同名的函数,这些函数的参数表不同。重载的概念不属于面向对象编程,编译器根据函数不同的形参表对同名函数的名称做修饰,然后这些同名函数就成了不同的函数。

重载的确定是在编译时确定,是静态的;虚函数则是在运行时动态确定。

23.公有继承、受保护继承、私有继承

答:(1)公有继承时,派生类对象可以访问基类中的公有成员,派生类的成员函数可以访问基类中的公有和受保护成员;

(2)私有继承时,基类的成员只能被直接派生类的成员访问,无法再往下继承;

(3)受保护继承时,基类的成员也只被直接派生类的成员访问,无法再往下继承。

24.公有继承时基类受保护的成员,可以通过派生类对象访问但不能修改。

25.有哪几种情况只能用构造函数初始化列表而不能用赋值初始化?

答:const成员,引用成员

26.什么是虚指针?

答:虚指针或虚函数指针是虚函数的实现细节。带有虚函数的每一个对象都有一个虚指针指向该类的虚函数表。

27.C++如何阻止一个类被实例化?一般在什么时候将构造函数声明为private?

答:(1)将类定义为抽象基类或者将构造函数声明为private;

(2)不允许类外部创建类对象,只能在类内部创建对象

28.main函数执行之前会执行什么?执行之后还能执行代码吗?

答:(1)全局对象的构造函数会在main函数之前执行;

(2)可以,可以用_onexit 注册一个函数,它会在main 之后执行;

如果你需要加入一段在main退出后执行的代码,可以使用atexit()函数,注册一个函数。

语法:

#include <stdlib.h>

#include <stdio.h>

int atexit(void (*function")(void));

void fn1( void ), fn2( void ), fn3( void );

int main( void )

{

atexit(fn1);

atexit( fn2 );

printf( "This is executed first.\n" );

}

void fn1()

{

printf( " This is\n" );

}

void fn2()

{

printf( " executed next." );

}

结果:

This is executed first.

This is executed next.

29.请描述进程和线程的区别?

答:(1)进程是程序的一次执行,线程是进程中的执行单元;

(2)进程间是独立的,这表现在内存空间、上下文环境上,线程运行在进程中;

(3)一般来讲,进程无法突破进程边界存取其他进程内的存储空间;而同一进程所产生的线程共享内存空间;

(4)同一进程中的两段代码不能同时执行,除非引入多线程。

30.进程间如何通信?

答:信号、信号量、消息队列、共享内存

31.在网络编程中涉及并发服务器,使用多进程与多线程的区别?

答:(1)线程执行开销小,但不利于资源管理和保护;进程则相反,进程可跨越机器迁移。

(2)多进程时每个进程都有自己的内存空间,而多线程间共享内存空间;

(3)线程产生的速度快,线程间通信快、切换快;

(4)线程的资源利用率比较好;

(5)线程使用公共变量或者资源时需要同步机制。

32.说一下TCP 3次握手、4次挥手的全过程。

33.TCP和UDP有什么区别。

答:

TCP——传输控制协议,提供的是面向连接、可靠的字节流服务。

当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

UDP——用户数据报协议,是一个简单的面向数据报的传输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快.

TCP协议和UDP协议的一些特性区别如下:

1.TCP协议在传送数据段的时候要给段标号;UDP 协议不需要。

2.TCP协议可靠;UDP协议不可靠。

3.TCP协议是面向连接;UDP协议采用无连接。

4.TCP协议负载较高,采用虚电路;UDP协议低负载。

5.TCP协议的发送方要确认接受方是否收到数据段(3次握手协议)。

6.TCP协议采用窗口技术和流控制。

34.如何编写套接字?

35.调用函数时要进行参数压栈,一般情况下顺序是从最右边参数往左压栈。

36.经常要操作的内存分为那几个类别?

答:(1)栈区:由编译器自动分配和释放,存放函数的参数值、局部变量的值等;

(2)堆:一般由程序员分配和释放,存放动态分配的变量;

(3)全局区(静态区):全局变量和静态变量存放在这一块,初始化的和未初始化的分开放;

(4)文字常量区:常量字符串就放在这里,程序结束自动释放;

(5)程序代码区:参访函数体的二进制代码。

37.请讲述堆和栈的区别。

答:(1)申请方式不同。栈上有系统自动分配和释放;堆上有程序员自己申请并指明大小;

(2)栈是向低地址扩展的数据结构,大小很有限;堆是向高地址扩展,是不连续的内存区域,空间相对大且灵活;

(3)栈由系统分配和释放速度快;堆由程序员控制,一般较慢,且容易产生碎片;

38.全局变量放在数据段,内部变量static int count;放在数据段,内部变量char *p=“AAA”,p的位置在堆栈上,指向的空间的位置数据段,内部变量char *p=new char;p的位置,指向的空间的位置数据段

 

39.字符数组与字符串的比较:最明显的区别是字符串会在末尾自动添加空字符。

40.函数指针相关概念(C++学习笔记)

41.类使用static成员的优点,如何访问?

答:优点:

(1)static 成员的名字是在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突;

(2)可以实施封装。static 成员可以是私有成员,而全局对象不可以;

(3) static 成员是与特定类关联的,可清晰地显示程序员的意图。

static 数据成员必须在类定义体的外部定义(正好一次),static 关键字只能用于类定义体内部的声明中,定义不能标示为static. 不像普通数据成员,static成员不是通过类构造函数进行初始化,也不能在类的声明中初始化,而是应该在定义时进行初始化.保证对象正好定义一次的最好办法,就是将static 数据成员的定义放在包含类非内联成员函数定义的文件中。

静态数据成员初始化的格式为:

<数据类型><类名>::<静态数据成员名>=<值>

类的静态数据成员有两种访问形式:

<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>

42. static数据成员和static成员函数

答:(1)static数据成员:
static数据成员独立于该类的任意对象而存在;每个static数据成员是与类关联的对象,并不与该类的对象相关联。Static数据成员(const static数据成员除外)必须在类定义体的外部定义。不像普通数据成员,static成员不是通过类的构造函数进行初始化,而是应该在定义时进行初始化。
(2)static成员函数:
Static成员函数没有this形参,它可以直接访问所属类的static成员,不能直接使用非static成员。因为static成员不是任何对象的组成部分,所以static成员不能被声明为const。同时,static成员函数也不能被声明为虚函数。

43.static成员变量定义放在cpp文件中,不能放在初始化列表中。Const static成员可就地初始化。

 

44.如何引用一个已经定义过的全局变量?

答:可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变量,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。

44.static关键字的作用。

答:static总是使得变量或对象的存储形式变成静态存储,连接方式变成内部连接,对于局部变量(已经是内部连接了),它仅改变其存储方式;对于全局变量(已经是静态存储了),它仅改变其连接类型。

45.奈奎斯特定理

46.香农定理

47.多态类中的虚函数表是 Compile-Time,还是 Run-Time时建立的?

答案:虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组。而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键。

48. 一个父类写了一个 virtual 函数,如果子类覆盖它的函数不加 virtual ,也能实现多态?

在子类的空间里,有没有父类的这个函数,或者父类的私有变量? (华为笔试题)

答案:只要基类在定义成员函数时已经声明了 virtue关键字,在派生类实现的时候覆盖该函数时,virtue关键字可加可不加,不影响多态的实现。子类的空间里有父类的所有变量(static除外)。

49. 完成字符串拷贝可以使用 sprintf、strcpy 及 memcpy 函数,请问这些函数有什么区别

,你喜欢使用哪个,为什么?

答案:这些函数的区别在于 实现功能以及操作对象不同。

(1)strcpy 函数操作的对象是字符串,完成从源字符串到目的字符串的拷贝功能。

(2)sprintf 函数操作的对象不限于字符串:虽然目的对象是字符串,但是源对象可以是字符串、也可以是任意基本类型的数据。这个函数主要用来实现(字符串或基本数据类型)向字符串的转换功能。如果源对象是字符串,并且指定 %s 格式符,也可实现字符串拷贝功能。

(3)memcpy 函数顾名思义就是内存拷贝,实现将一个内存块的内容复制到另一个内存块这一功能。内存块由其首地址以及长度确定。程序中出现的实体对象,不论是什么类型,其最终表现就是在内存中占据一席之地(一个内存区间或块)。因此,memcpy 的操作对象不局限于某一类数据类型,或者说可适用于任意数据类型,只要能给出对象的起始地址和内存长度信息、并且对象具有可操作性即可。鉴于memcpy 函数等长拷贝的特点以及数据类型代表的物理意义,memcpy 函数通常限于同种类型数据或对象之间的拷贝,其中当然也包括字符串拷贝以及基本数据类型的拷贝。

对于字符串拷贝来说,用上述三个函数都可以实现,但是其实现的效率和使用的方便程度不同:

• strcpy 无疑是最合适的选择:效率高且调用方便。

• sprintf 要额外指定格式符并且进行格式转化,麻烦且效率不高。

• memcpy 虽然高效,但是需要额外提供拷贝的内存长度这一参数,易错且使用不便;并且如果长度指定过大的话(最优长度是源字符串长度 + 1),还会带来性能的下降。其实 strcpy 函数一般是在内部调用 memcpy 函数或者用汇编直接实现的,以达到高效的目的。因此,使用 memcpy 和 strcpy 拷贝字符串在性能上应该没有什么大的差别。

对于非字符串类型的数据的复制来说,strcpy 和 snprintf 一般就无能为力了,可是对 memcpy 却没有什么影响。但是,对于基本数据类型来说,尽管可以用 memcpy 进行拷贝,由于有赋值运算符可以方便且高效地进行同种或兼容类型的数据之间的拷贝,所以这种情况下 memcpy 几乎不被使用 。memcpy 的长处是用来实现(通常是内部实现居多)对结构或者数组的拷贝,其目的是或者高效,或者使用方便,甚或两者兼有。

50. 应用程序在运行时的内存包括代码区和数据区,其中数据区又包括哪些部分?

答:对于一个进程的内存空间而言,可以在逻辑上分成 3个部份:代码区,静态数据区和动态数据区。

动态数据区一般就是“堆栈”。 栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”。

全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。

51. C++函数中值的传递方式有哪几种?

答:三种传递方式为:值传递、指针传递和引用传递。

52. C++里面是不是所有的动作都是main()引起的?如果不是,请举例.

比如全局变量的初始化,就不是由main函数引起的

举例: class A{};

A a; //a的构造函数限执行

int main() {}

53. 下列哪两个是等同的

int b;

A const int* a = &b;

B const* int a = &b;

C const int* const a = &b;

D int const* const a = &b;

54. 内联函数在编译时是否做参数类型检查?

答:内联函数要做参数类型检查, 这是内联函数跟宏相比的优势。

55. 全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的?

(1)生命周期不同:

全局变量随主程序创建和创建,随主程序销毁而销毁

局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在; 内存中

分配在全局数据区

(2)使用方式不同:通过声明后全局变量程序的各个部分都可以用到;局部变量只能在局部使用,分配在栈区

操作系统和编译器通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运行的时候被加载。局部变量则分配在堆栈里面 。

56. 有 A 、 B 、 C 、 D 四个人,要在夜里过一座桥。他们通过这座桥分别需要耗时 1 、 2 、 5 、 10 分钟,只有一支手电,并且同时最多只能两个人一起过桥。请问,如何安排,能够在 17 分钟内这四个人都过桥?

Solution:关键是时间最长的两个人必须同时过桥

The First Time : A(1) 和 B(2) 过桥, A(1) 返回 Cost : 1+2

The Second Time : C(5) 和 D(10) 过桥, B(2) 返回 Cost : 10+2

The Third Time A(1) 和 B(2) 过桥 Cost : 2

Total Time Cost : (1+2)+(10+2)+2=17 minutes

57. static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?

答:static全局变量与普通全局变量区别:static全局变量只初使化一次,防止在其他文件单元中被引用;

static局部变量和普通局部变量区别:static局部变量只被初始化一次,下一次依据上一次结果值;

static函数与普通函数区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。

58. 程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存在于( 堆)中。

 

59. 对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?

c用宏定义,c++用inline

60. 有1,2,....一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数。

#include<iostream.h>

Using namespace std;

int main(){

int a[] = {10,6,9,5,2,8,4,7,1,3};

int len = sizeof(a) / sizeof(int);

int temp;

for(int i = 0; i < len; )

{

temp = a[a[i] - 1];

a[a[i] - 1] = a[i];

a[i] = temp;

if ( a[i] == i + 1)

i++;

}

for (int j = 0; j < len; j++)

cout<<a[j]<<",";

return 0;

}

61、内存分配方式
 
内存分配方式有三种:
  [1]从 静态存储区域分配。内存在 程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如 全局变量,static变量。
  [2]在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于 处理器的指令集中,效率很高,但是分配的 内存容量有限。
  [3]从堆上分配,亦称 动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存, 程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现 内存泄漏,频繁地分配和释放不同大小的堆空间将会产生堆内碎块。

1\局部变量能否和全局变量重名?

     答:能,局部会屏蔽全局。要用全局变量,需要使用"::"

局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。

2、如何引用一个已经定义过的全局变量?

     答:extern

     可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。

3、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?

    答:可以,在不同的C文件中以static形式来声明同名全局变量。

    可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。

4、语句for( ;1 ;)有什么问题?它是什么意思?

    答:无限循环,和while(1)相同。

5、do……while和while……do有什么区别?

    答:前一个循环一遍再判断,后一个判断以后再循环。

6、请写出下列代码的输出内容

#i nclude<stdio.h>

main()

{

int a,b,c,d;

a=10;

b=a++;

c=++a;

d=10*a++;

printf("b,c,d:%d,%d,%d",b,c,d);

return 0;

}

答:10,12,120

1.static有什么用途?(请至少说明两种)

    1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。

    2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

    3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用

2.引用与指针有什么区别?

    1) 引用必须被初始化,指针不必。

    2) 引用初始化以后不能被改变,指针可以改变所指的对象。

    3) 不存在指向空值的引用,但是存在指向空值的指针。

3.描述实时系统的基本特性

       在特定时间内完成特定的任务,实时性与可靠性。

4.全局变量和局部变量在内存中是否有区别?如果有,是什么区别?

      全局变量储存在静态数据库,局部变量在堆栈。

5.什么是平衡二叉树?

      左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1。

6.堆栈溢出一般是由什么原因导致的?

      没有回收垃圾资源。

7.什么函数不能声明为虚函数?

      constructor函数不能声明为虚函数。

8.冒泡排序算法的时间复杂度是什么?

      时间复杂度是O(n^2)。

9.写出float x 与“零值”比较的if语句。

      if(x>0.000001&&x<-0.000001)

10.Internet采用哪种网络协议?该协议的主要层次结构?

      Tcp/Ip协议

      主要层次结构为: 应用层/传输层/网络层/数据链路层/物理层。

11.Internet物理地址和IP地址转换采用什么协议?

      ARP (Address Resolution Protocol)(地址解析協議)

12.IP地址的编码分为哪俩部分?

     IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。

13.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。

     循环链表,用取余操作做

14.不能做switch()的参数类型是:

     switch的参数不能为实型。

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[] = “http://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)

答:(1)17 (2)4 (3) 4 (4)4 (5)4

3. 回答下面的问题. (4分)

(1).头文件中的 ifndef/define/endif 干什么用?预处理

答:防止头文件被重复引用

(2). #i nclude 和 #i nclude “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 */

}

(2)strcat能把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 关于内存对齐的问题以及sizof()的输出

答:编译器自动对齐的原因:为了提高程序的性能,数据结构(尤其是栈)应该尽可能

地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问

;然而,对齐的内存访问仅需要一次访问。

20 int i=10, j=10, k=3; k*=i+j; k最后的值是?

答:60,此题考察优先级,实际写成: k*=(i+j);,赋值运算符优先级最低

21.对数据库的一张表进行操作,同时要对另一张表进行操作,如何实现?

答:将操作多个表的操作放入到事务中进行处理

22.TCP/IP 建立连接的过程?(3-way shake)

答:在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

  第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状

态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个

SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

  第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)

,此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

 

23.ICMP是什么协议,处于哪一层?

答:Internet控制报文协议,处于网络层(IP层)

24.触发器怎么工作的?

答:触发器主要是通过事件进行触发而被执行的,当对某一表进行诸如UPDATE、 INSERT

、 DELETE 这些操作时,数据库就会自动执行触发器所定义的SQL 语句,从而确保对数

据的处理必须符合由这些SQL 语句所定义的规则。

25.winsock建立连接的主要实现步骤?

答:服务器端:socker()建立套接字,绑定(bind)并监听(listen),用accept()

等待客户端连接。

客户端:socker()建立套接字,连接(connect)服务器,连接上后使用send()和recv(

),在套接字上写读数据,直至数据交换完毕,closesocket()关闭套接字。

服务器端:accept()发现有客户端连接,建立一个新的套接字,自身重新开始等待连

接。该新产生的套接字使用send()和recv()写读数据,直至数据交换完毕,closesock

et()关闭套接字。

26.动态连接库的两种方式?

答:调用一个DLL中的函数有两种方法:

1.载入时动态链接(load-time dynamic linking),模块非常明确调用某个导出函数

,使得他们就像本地函数一样。这需要链接时链接那些函数所在DLL的导入库,导入库向

系统提供了载入DLL时所需的信息及DLL函数定位。

2.运行时动态链接(run-time dynamic linking),运行时可以通过LoadLibrary或Loa

dLibraryEx函数载入DLL。DLL载入后,模块可以通过调用GetProcAddress获取DLL函数的

出口地址,然后就可以通过返回的函数指针调用DLL函数了。如此即可避免导入库文件了

27.IP组播有那些好处?

答:Internet上产生的许多新的应用,特别是高带宽的多媒体应用,带来了带宽的急剧

消耗和网络拥挤问题。组播是一种允许一个或多个发送者(组播源)发送单一的数据包

到多个接收者(一次的,同时的)的网络技术。组播可以大大的节省网络带宽,因为无

论有多少个目标地址,在整个网络的任何一条链路上只传送单一的数据包。所以说组播

技术的核心就是针对如何节约网络资源的前提下保证服务质量。

找错

Void test1()

{

  char string[10];

  char* str1="0123456789";

strcpy(string, str1);

}

Void test2()

{

  char string[10], str1[10];

for(I=0; I<10;I++)

{

    str1 ='a';

}

strcpy(string, str1);

}

Void test3(char* str1)

{

  char string[10];

  if(strlen(str1)<=10)

{

  strcpy(string, str1);

}

}

2.  找错

#define MAX_SRM 256

DSN get_SRM_no()

{

    static int SRM_no;

    int I;

    for(I=0;I{

SRM_no %= MAX_SRM;

if(MY_SRM.state==IDLE)

{

  break;

}

}

if(I>=MAX_SRM)

return (NULL_SRM);

else

return SRM_no;

}

3.  写出程序运行结果

int sum(int a)

{

    auto int c=0;

    static int b=3;

c+=1;

b+=2;

return(a+b+C);

}

  void main()

{

    int I;

int a=2;

for(I=0;I<5;I++)

{

  printf("%d,", sum(a));

}

}

4.  

int func(int a)

{

  int b;

  switch(a)

  {

    case 1: 30;

    case 2: 20;

    case 3: 16;

    default: 0

}

return b;

}

则func(1)=?

5:

int a[3];

a[0]=0; a[1]=1; a[2]=2;

int *p, *q;

p=a;

q=&a[2];

则a[q-p]=?

6.

定义 int **a[3][4], 则变量占有的内存空间为:_____

7.

编写一个函数,要求输入年月日时分秒,输出该年月日时分秒的下一秒。如输入2004年12月31日23时59分59秒,则输出2005年1月1日0时0分0秒

JAVA

 

第一部分:选择题

  QUESTION NO: 1

  1、public class Test {

  public static void changeStr(String str){

  str="welcome";

  }

  public static void main(String[] args) {

  String str="1234";

  changeStr(str);

  System.out.println(str);

  }

  }

  Please write the output result :

  QUESTION NO:2

  1. public class Test {

  2. static boolean foo(char c) {

  3. System.out.print(c);

  4. return true;

  5. }

  6. public static void main( String[] argv ) {

  7. int i =0;

  8. for ( foo('A'); foo('B')&&(i<2); foo('C')){

  9. i++ ;

  10. foo('D');

  12. }

  13. }

  14. }

  What is the result?

  A. ABDCBDCB

  B. ABCDABCD

  C. Compilation fails.

  D. An exception is thrown at runtime.

  QUESTION NO: 3

  1. class A {

  2. protected int method1(int a, int b) { return 0; }

  3. }

  Which two are valid in a class that extends class A? (Choose two)

  A. public int method1(int a, int b) { return 0; }

  B. private int method1(int a, int b) { return 0; }

  C. private int method1(int a, long b) { return 0; }

  D. public short method1(int a, int b) { return 0; }

  E. static protected int method1(int a, int b) { return 0; }

  QUESTION NO: 4

  1. public class Outer{

  2. public void someOuterMethod() {

  3. // Line 3

  4. }

  5. public class Inner{}

  6. public static void main( String[]argv ) {

  7. Outer o = new Outer();

  8. // Line 8

  9. }

  10. }

  Which instantiates an instance of Inner?

  A. new Inner(); // At line 3

  B. new Inner(); // At line 8

  C. new o.Inner(); // At line 8

  D. new Outer.Inner(); // At line 8//new Outer().new Inner()

  QUESTION NO: 5

  Which method is used by a servlet to place its session ID in a URL that is written to the servlet’s response output stream?

  A. The encodeURL method of the HttpServletRequest interface.

  B. The encodeURL method of the HttpServletResponse interface.

  C. The rewriteURL method of the HttpServletRequest interface.

  D. The rewriteURL method of the HttpServletResponse interface.

  QUESTION NO: 6

  Which two are equivalent? (Choose two)

  A. <%= YoshiBean.size%>

  B. <%= YoshiBean.getSize()%>

  C. <%= YoshiBean.getProperty("size")%>

  D.

  E.

  F.

  G.

  QUESTION NO: 7

  Which of the following statements regarding the lifecycle of a session bean are correct?

  1. java.lang.IllegalStateException is thrown if SessionContext.getEJBObject() is invoked when a stateful session bean instance is passivated.

  2. SessionContext.getRollbackOnly() does not throw an exception when a session bean with bean-managed transaction demarcation is activated.

  3. An exception is not thrown when SessionContext.getUserTransaction() is called in the afterBegin method of a bean with container-managed transactions.

  4. JNDI access to java:comp/env is permitted in all the SessionSynchronization methods of a stateful session bean with container-managed transaction demarcation.

  5. Accessing resource managers in the SessionSynchronization.afterBegin method of a stateful session bean with bean-managed transaction does not throw an exception.

  第二部分:概念题

  1. 描述Struts体系结构?对应各个部分的开发工作主要包括哪些?

  3. JSP有哪些内置对象和动作?它们的作用分别是什么?

  4、SQL问答题

  SELECT * FROM TABLE

  和

  SELECT * FROM TABLE

  WHERE NAME LIKE '%%' AND ADDR LIKE '%%'

  AND (1_ADDR LIKE '%%' OR 2_ADDR LIKE '%%'

  OR 3_ADDR LIKE '%%' OR 4_ADDR LIKE '%%' )

  的检索结果为何不同?

  5、SQL问答题

  表结构:

  1、 表名:g_cardapply

  字段(字段名/类型/长度):

  g_applyno varchar 8;//申请单号(关键字)

  g_applydate bigint 8;//申请日期

  g_state varchar 2;//申请状态

  2、 表名:g_cardapplydetail

  字段(字段名/类型/长度):

  g_applyno varchar 8;//申请单号(关键字)

  g_name varchar 30;//申请人姓名

  g_idcard varchar 18;//申请人身份证号

  g_state varchar 2;//申请状态

  其中,两个表的关联字段为申请单号。

  题目:

  1、 查询身份证号码为440401430103082的申请日期

  2、 查询同一个身份证号码有两条以上记录的身份证号码及记录个数

  3、 将身份证号码为440401430103082的记录在两个表中的申请状态均改为07

  4、 删除g_cardapplydetail表中所有姓李的记录

");

 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值