程序员模拟面试题

更新时间:2023-09-20 15:09:01 阅读量: 医药卫生 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

程序员笔试题

概念性题目:

1) 指针和引用有什么分别;如果传引用比传指针安全,为什么?如果我使用常

量指针难道不行吗?

答案:引用必须初始化,指针不用; 引用初始化后不能被改变,而指针可以改变所指向的对象; 不存在指向空值的引用,但是存在可以指向空值的指针。

解释:

(1) 引用在创建的同时必须初始化,即引用到一个有效的对象;而指针在定义的时候不必初始化,可以在定义后面的任何地方重新赋值.

(2) 不存在NULL引用,引用必须与合法的存储单元关联;而指针则可以是NULL.

(3) 引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用;而指针在任何时候都可以改变为指向另一个对象.给引用赋值并不是改变它和原始对象的绑定关系.

(4) 引用的创建和销毁并不会调用类的拷贝构造函数

(5) 语言层面,引用的用法和对象一样;在二进制层面,引用一般都是通过指针来实现的,只不过编译器帮我们完成了转换.

不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,显得很安全。

const 指针仍然存在空指针,并且有可能产生野指针.

总的来说:引用既具有指针的效率,又具有变量使用的方便性和直观性.

2)参数传递有几种方式;实现多态参数传递采用什么方式,如果没有使用某种方式原因是什么;

传值,传指针或者引用

采用引用的方式在多态中进行传参

原因:使用引用可以节省空间和时间,用于对象时不用调用拷贝构造函数

产生参数副本,可以调高效率,直观,安全。

3)C++和C定义结构的分别是什么。

C 语言的结构仅仅是数据的结合,不可以定义方法。

C++的struct 和 class 其实具备几乎一样的功能,只是默认的访问属性不一样而已。

4)构造函数可否是虚函数,为什么?析构函数呢,可否是纯虚的呢?

构造函数不能为虚函数,要构造一个对象,必须清楚地知道要构造什么,否则无法构造一个对象。

析构函数可以为纯虚函数。

5)拷贝构造函数相关问题,深拷贝,浅拷贝,临时对象等。 深拷贝意味着拷贝了资源和指针。而浅拷贝只是拷贝了指针,没有拷贝资源, 这样使得两个指针指向同一份资源,造成对同一份析构两次,程序崩溃。

1

临时对象的开销比局部对象小些。

6)在什么时候需要使用“常引用”? 如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:const 类型标识符 &引用名=目标变量名。

7)将“引用”作为函数返回值类型的格式、好处和需要遵守的规则? 好处:在内存中不产生被返回值的副本;(注意:正是因为这点原因,所以返回一个局部变量的引用是不可取的。因为随着该局部变量生存期的结束,相应的引用也会失效,产生runtime error! 注意事项:

(1)不能返回局部变量的引用。

(2)不能返回函数内部new分配的内存的引用。 (3)可以返回类成员的引用,但最好是const。 (4)流操作符重载返回值申明为“引用”的作用:

(5)在另外的一些操作符中,却千万不能返回引用:+-*/ 四则运算符。

8)引用与多态的关系?

引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。

9) #include 与 #include \的区别? 答:

前者是从Standard Library的路径寻找和引用file.h,而后者是从当前工作路径搜寻并引用file.h。

10)New delete 与malloc free 的联系与区别?

都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数。delete 会调用对象的destructor,而free 不会调用对象的destructor.

11)描述内存分配方式以及它们的区别?

1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。

2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。 3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。

12)C++中struct 和 class 的区别

struct 的成员默认是公有的,而类的成员默认是私有的。struct 和 class

2

在其他方面是功能相当的。

13)当一个类A 中没有声明任何成员变量与成员函数,这时sizeof(A)的值是多少?

1 14)(重要)分别写出BOOL,int,float,指针类型的变量a 与“零”的比较语句。 答案:规范写法

BOOL : if ( !a ) or if(a) int : if ( a == 0)

float : const EXPRESSION EXP = 0.000001 if ( a < EXP && a >-EXP)

pointer : if ( a != NULL) or if(a == NULL)

15)请说出const与#define 相比,有何优点? 答案:

1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。

2)有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。

16)类成员函数的重载、覆盖和隐藏区别? 答案:

a.成员函数被重载的特征:

(1)相同的范围(在同一个类中); (2)函数名字相同; (3)参数不同;

(4)virtual 关键字可有可无。

b.覆盖(重写)是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类); (2)函数名字相同; (3)参数相同;

(4)基类函数必须有virtual 关键字。

c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下: (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

17)ISO的七层模型是什么?tcp/udp是属于哪一层?tcp/udp有何优缺点? 应用层、表示层、会话层、传输层、网络层、链路层、物理层 tcp /udp属于传输层

TCP 服务提供了数据流传输、可靠性、有效流控制、全双工操作和多路复用

3

技术等。

与 TCP 不同, UDP 并不提供对 IP 协议的可靠机制、流控制以及错误恢复功能等。由于 UDP 比较简单, UDP 头包含很少的字节,比 TCP 负载消耗少。 tcp: 提供稳定的传输服务,有流量控制,缺点是包头大,冗余性不好 udp: 不提供稳定的服务,包头小,开销小

18)数组和链表的区别

数组:数据顺序存储,固定大小

链表:数据可以随机存储,大小可动态改变

19)类的静态成员和非静态成员有何区别?

类的静态成员每个类只有一个,非静态成员每个对象一个

20) 纯虚函数如何定义?使用时应注意什么? virtual void f()=0; 是接口,子类必须要实现

21)进程死锁的原因

资源竞争及进程推进顺序非法

23) 死锁的4个必要条件

互斥、请求保持、不可剥夺、环路

24) 死锁的处理

鸵鸟策略、预防策略、避免策略、检测与解除死锁

25)列举几种进程的同步机制,并比较其优缺点。

原子操作 信号量机制 自旋锁

管程,会合,分布式系统

26) 进程之间通信的途径 共享存储系统 消息传递系统

管道:以文件系统为基础

4

27)TCP/IP 建立连接的过程

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。 第一次握手:建立连接时,客户端发送连接请求到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到客户端连接请求,向客户端发送允许连接应答,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的允许连接应答,向服务器发送确认,客户端和服务器进入通信状态,完成三次握手

28)头文件中的ifndef/define/endif的作用是什么?

防止该头文件被重复引用。 29)C++是不是类型安全的?

不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。C#是类型安全的。

30)流操作符重载返回值申明为“引用”的作用:

流操作符<<和>>,这两个操作符常常希望被连续使用,例如:cout << \<< endl; 因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。可选的其它方案包括:返回一个流对象和返回一个流对象指针。但是对于返回一个流对象,程序必须重新(拷贝)构造一个新的流对象,也就是说,连续的两个<<操作符实际上是针对不同对象的!这无法让人接受。对于返回一个流指针则不能连续使用<<操作符。因此,返回一个流对象引用是惟一选择。这个唯一选择很关键,它说明了引用的重要性以及无可替代性,也许这就是C++语言中引入引用这个概念的原因吧。 赋值操作符=。这个操作符象流操作符一样,是可以连续使用的,例如:x = j = 10;或者(x=10)=100;赋值操作符的返回值必须是一个左值,以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。

5

本文来源:https://www.bwwdw.com/article/fe7h.html

Top