6、TCP/IP协议中,每一层对应的协议
答:
网络层:IP,ICMP,ARP,RARP
传输层:UDP,TCP
应用层:FTP,Telenet,DNS,SMTP,P0P3,HTTP
7、进程与线程的区别
答:
并发性:多个进程可以并发执行;多个线程也可以并发执行。
调 度:进程是拥有资源的基本单位;
线程是独立调度的基本单位
。
拥有资源:进程拥有资源;线程几乎不拥有资源。
系统开销:创建和撤销进程时,系统都要为之分配或回收资源;而线程切换时只需要保存和设置少量寄存器内容,因此开销少。
地址空间和其他资源(打开的文件):进程的地址空间之间相互独立,同一进程的各线程间共享进程的资源,某进程内的线程对于其他线程不可见。
通信方面:进程间通信需要借助操作系统;而线程间可以直接 读/写 进程数据段。
8、使用多线程的好处
答:
(1)和进程相比,它只是一种非常节俭的多任务操作方式
在 Linux 系统下,启动一个新的进程,必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段,堆栈段和数据段。这种任务太消耗内存资源,而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的时间,空间远小于进程,而且进程之间的切换也没有线程容易。
(2)线程间方便的通信机制
对于进程来说:它具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,费时而且不方便,而线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其他线程所用,快捷,方便。
多线程程序作为一种多任务,并发的工作方式,有以下优点:
a,提高程序响应(将耗时长的操作置于一个新的线程)
b,使多CPU系统更加有效(操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上)
c,改善程序结构(把一个长又复杂的进程分为多个线程,有利于程序的理解和修改)
9、多线程通信的互斥和同步
答:
线程间的互斥
a:临界区:一个线程在运行时使用的资源,另一个线程在修改,就需要临界区。
b:互斥:为使多个线程在进入临界区时不出现问题,要实现线程互斥。
线程间的同步
存在直接制约关系的一个线程可以在另一个线程的执行多条件满足后,给对方发送相应的消息或信号,这样被制约的线程可以在条件不满足的处于阻塞状态,条件满足后,被对方唤醒继续工作。
10、常见的置换算法、虚拟内存的三种实现方式
答:置换算法:最佳置换算法;先进先出页面置换算法;最近最久未使用置换算法
虚拟内存的三种实现方式:请求分页存储管理;请求分段存储管理;请求段页式存储管理
11、指针和引用的区别是什么?传值,传引用和传地址的区别是什么?
答:
一、指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。
a:指针是一个实体,而引用仅是个别名
b:指针可以改变所指的对象,而引用只能在定义时被初始化一次,之后不可以变。
c:指针可以为空,不存在指向空值的引用
d:指针不必初始化,引用必须初始化
e:指针传递也叫值传递,引用传递的是地址
f:从内存分配来看:程序为指针变量分配内存区域,而引用不需要
二、传值:堆栈中开辟了内存空间,以存放由主调函数放进来的实参的值,从而形成了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。
传引用:(变量的别名)真正的以地址的方式传递参数,传递之后,形参和实参都是同一个对象,只是他们的名字不同而已,对形参的修改将影响实参的值。
传地址:传地址之后实参和形参都指向同一个对象。
12、常量指针、指针常量
答:
常量指针:首先是一个指针,是一个指向常量的指针, const int *p = &a;指针所指向的地址内容是不可修改的
作用:设置常量指针指向一个常量,防止出现修改常量的误操作;
指针常量:首先是一个常量,再才是个指针,常量的性质是不能修改的,指针的内容实际是一个地址,那么指针常量就是内容不可修改的常量,不能修改这个指针所指向的地址,一开始初始化,指向哪就只能指向哪。
不可改变地址的指针,但是可以对它所指向的内容进行修改。
13、什么是野指针,如何避免,野指针和空指针的区别
答:“野指针”不是NULL指针,而是指向“垃圾”的内存指针。
其主要原因:指针变量没有被初始化,或者指针 p 被 free或者 delete之后,没有置为 NULL;
避免:
a:把指针指向NULL
b:使用malloc分配内存
空指针:是一个特殊的指针值,也是唯一一个对应任何指针类型都合法的指针值,指针变量具有空指针值,表示他当时处于闲置状态,没有指向有意义的东西。
14、IP地址的分类
答:
A类地址:以0开头,第一个字节范围: 0~127
B类地址:以10开头,第一个字节范围:128~191
C类地址:以110开头,第一个字节范围:192~223
D类地址:以1110开头,第一个字节范围:224~239
15、在浏览器中输入www.baidu.com后,执行的全部过程
答:现在假设如果我们在客户端(客户端)浏览器中输入 http://www.baidu.com,而baidu.com为要访问的服务器(服务器)下面详细分析客户端为了访问服务器而执行的一系列关于协议的操作:
a:客户端浏览器通过 DNS解析到 www.baidu.com的 IP地址 220.181.27.48,通过这个IP地址找到客户端到服务器的路径。客户端浏览器发起一个 HTTP会话到 220.161.27.48 ,然后通过 TCP进行封装数据包,输入到网络层。
b:在客户端的传输层,把 HTTP会话请求分成报文段,添加源和目的端口,如服务器使用 80端口监听客户端的请求,客户端由系统随机选择一个端口,如 5000,与服务器进行交换,服务器把相应的请求返回给客户端的 5000端口,然后使用 IP层的 IP地址查找目的端。
c:客户端的网络层不用关系应用层或者传输层的东西,主要做的是通过查找路由表确定如何到达服务器,期间可能经过多个路由器,这些都是由路由器来完成工作,无非就是通过查找路由表决定通过哪个路径到达服务器。
d:客户端的链路层,包通过链路层发送到路由器,通过邻居协议查找给定的 IP地址的 MAC地址,然后发送 ARP请求查找目的地址。如果得到回应后就可以使用 ARP的请求应答交换的 IP数据包现在就可以传输了,然后发送 IP数据包到达服务器的地址。
16、HTTP协议包括那些请求
答:GET
, POST ,PUT ,DELETE ,HEAD ,OPTIONS
17、HTTP中GET与POST的区别
答:a:GET是从服务器上获取数据
b:GET是把参数数据队列加到提交表单的 Action 属性所指向的 URL中,值和表单内各个字段一一对应,在 URL中可以看到。
c:GET传送的数据量小,不能大于 2kb ;POST传送的数据量较大,一般被默认为不受限制。
d:根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的。
所谓的“安全的”意味着该操作用于获取用于获取信息而非修改信息。换句话说,GET请求一般不应该产生副作用,就是说,它仅仅是获取资源信 息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。
“幂等”的意味着对同一 URL的多个请求应该返回同样的结果。
18、特殊的IP地址
答:
- 网络地址
- 广播地址
- 组播地址
- 255.255.255.255
- 0.0.0.0
- 回环地址
- A类私有地址:10.0.0.0/8
- B类私有地址:172.16.0.0/12
- C类私有地址:192.168.0.0/16
19、写出23种设计模式的任意五种
答:单例模式;工厂模式;适配器模式;享元模式;代理模式
20、简述:堆排序,归并排序,快速排序的思想
答:堆排序:将排序的序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点,将他移走,然后将剩余的 n-1 个序列重新构造成一个堆,这样就会得到 N 个元素中的次小值,如此反复执行,便能得到一个有序列的队列了。
归并排序:先使每个子序列有序,再使子序列段间有序,若将两个有序表合并成一个有序表,称为二路归并。
快速排序:任取待排序序列中的某个元素作为标杆,将待排序序列划分为左右两个子序列,左侧元素小于标杆元素,右侧元素大于标杆元素,标杆元素则排在这两个子序列的中间,然后再对这两个子序列重复上述方法,直至排序结束。
21、链表和数组的区别,栈和队列的区别,红黑树和平衡二叉树的区别
答:
链表和数组的区别:
- 数组在内存中是逐个存放的,链表每个节点设有相对固定的位置关系,而是在内存的其他空闲区域,呈现一种随机状态。
- 数组一旦显示的被申请后,其大小就固定了,不能动态进行扩充。而链表则可以,可以动态生成节点并且添加到已有的链表后面。
- 链表灵活,但是空间和时间额外耗费较大;数组大小固定,元素位置固定,但是操作不灵活,且容易浪费空间,但是时间耗费较小,尤其是元素变化不大的时候效率很高,双向链表比单向链表更灵活,但空间耗费较大。
栈和队列的区别----从数据结构角度看,都是线性结构
- 栈是先进后出,队列是先进先出。
- 遍历速度不同:栈只能是从头部取数据,最先放入的需要遍历整个栈最后才能取出来,栈是限定只能在表的一端进行插入和删除操作的线性表;队列是限定只能在表的一端进行插入和另一端进行删除操作的线性表。
栈和堆的区别:
- 红黑树放弃了追求完全平衡,追求大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能够达到平衡,实现起来更为简单。
- 平衡二叉树追求绝对平衡,条件比较苛刻,实现起来比较麻烦,每次插入新节点之后需要旋转的次数不能须知。
22、static的用法
答:
- 隐藏
- 初始化
- 保持局部变量内容的永久性
- 类中 staic 的作用:表示属于一个类而不是属于此类的任何特定对象的变量和函数。
23、C++中static,const,static const成员变量初始化说明
答:
- staic静态成员变量不能在类内部初始化,在类内部声明,外部定义。
- const成员变量也不能在类定义处初始化,只能通过构造函数初始化列表,const数据成员只有某个对象生存期内是常量
- const数据成员的初始化只能在类的构造函数的初始化列表中进行,要想建立整个类中都恒定的常量,应用类中的枚举常量来实现或 staic const。
24、class和struct的区别
答:struct里面默认的访问控制是public,class中默认的访问控制是private,struct是为了让C++编译器兼容以前的C开发的项目。
25、递归和迭代的区别
答:递归的基本概念:程序调用自身的编程技巧称为递归,是函数自己调用自己.
迭代:利用变量的原值推算出变量的一个新值.
如果递归是自己调用自己的话,迭代就是A不停的调用B.递归中一定有迭代,但是迭代中不一定有递归,大部分可以相互转换.能用迭代的不用递归,递归调用函数,浪费空间,并且递归太深容易造成堆栈的溢出.
26、常用的数据结构,线性数据结构,树形结构,图形结构
答:
常用的数据结构:数组,链表,栈,队列,二叉树,树,图
线性数据结构:数组,链表,队列,栈
树形结构:树,二叉树,平衡二叉树,查找树
图形结构:图
27、在C++程序中调用被C编译器编译后的函数,为什么要加 extern "c"
答: extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般之包括函数名。
因为在C++出现以前,很多代码都是C语言写的,而且很底层的库也是C语言写的,为了更好的支持原来的C代码和已经写好的C语言库,需要在C++中尽可能的支持C,而extern "C"就是其中的一个策略。
28、C++中四种强制类型转换的区别
答:
①static_cast <>() 静态类型转换。编译的时候C++编译器会做类型检查:基本类型能转换,但是不能转换指针类型
②若不同类型之间,进行强制类型转换,用reinterpreter_cast<>() 进行重新解释
③一般性结论:
C语言中 能隐式类型转换的,在C++中可以用static_cast<TYPE>()进行类型转换。因C++编译器在编译检查一般都能通过;
C语言中不能隐式类型转换的,在C++中可以用reinterpreter_cast<>()进行强制类型解释。
总结:static_cast <>()和reinterpreter_cast<>()基本上把C语言中的强制类型转换给覆盖
reinterpreter_cast<>()很难保证移植性
④ dynamic_cast<>()动态类型转换,安全的基类和子类之间转换,运行时类型检查
⑤ const_cast<>()去除变量的只读性
29、成员函数的重载,覆盖和隐藏
答:
a.成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
30、STL的Map,Set,List,Vector
答:
STL中List,Vector,Map,Set的理解
List封装了链表,Vector封装了数组, list和vector得最主要的区别在于vector使用连续内存存储的,他支持[]运算符,而list是以链表形式实现的,不支持[]。
Vector对于随机访问的速度很快,但是对于插入尤其是在头部插入元素速度很慢,在尾部插入速度很快。List对于随机访问速度慢得多,因为可能要遍历整个链表才能做到,但是对于插入就快的多了,不需要拷贝和移动数据,只需要改变指针的指向就可以了。另外对于新添加的元素,Vector有一套算法,而List可以任意加入。
Map,Set属于标准关联容器,使用了非常高效的平衡检索二叉树:红黑树,他的插入删除效率比其他序列容器高是因为不需要做内存拷贝和内存移动,而直接替换指向节点的指针即可。
Set和Vector的区别在于Set不包含重复的数据。Set和Map的区别在于Set只含有Key,而Map有一个Key和Key所对应的Value两个元素。
Map和Hash_Map的区别是Hash_Map使用了Hash算法来加快查找过程,但是需要更多的内存来存放这些Hash桶元素,因此可以算得上是采用空间来换取时间策略。
31、C++中,分别简述封装,继承,多态
答:
封装
定义:封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员,目的在于将对象的使用者和设计者分开,
以提高软件的可维护性和可修改性
特性:1. 结合性,即是将属性和方法结合 2. 信息隐蔽性,利用接口机制隐蔽内部实现细节,只留下接口给外界调用 3. 实现代码重用
继承
定义:继承就是新类从已有类那里得到已有的特性。 类的派生指的是从已有类产生新类的过程。原有的类成为基类或父类,产生的新类称为派生类或子类,
子类继承基类后,可以创建子类对象来调用基类函数,变量等
多态
定义:可以简单概括为“一个接口,多种方法”,即用的是同一个接口,但是效果各不相同,多态有两种形式的多态,一种是静态多态,一种是动态多态
动态多态:是指在程序运行时才能确定函数和实现的链接,此时才能确定调用哪个函数,父类指针或者引用能够指向子类对象,调用子类 的函数,所以在编译时是无法确定调用哪个函数
使用时在父类中写一个虚函数,在子类中分别重写,用这个父类指针调用这个虚函数,它实际上会调用各自子类重写的虚函数。
运行期多态的设计思想要归结到类继承体系的设计上去。对于有相关功能的对象集合,我们总希望能够抽象出它们共有的功能集合,在基类中将这些功能声明为虚接口(虚函数),
然后由子类继承基类去重写这些虚接口,以实现子类特有的具体功能。
运行期多态的实现依赖于虚函数机制。当某个类声明了虚函数时,编译器将为该类对象安插一个虚函数表指针,并为该类设置一张唯一的虚函数表,虚函数表中存放的是该类虚函数地址。
运行期间通过虚函数表指针与虚函数表去确定该类虚函数的真正实现。
优点: OO设计重要的特性,对客观世界直觉认识; 能够处理同一个继承体系下的异质类集合
32、继承与多态的区别?为什么要使用多态,多态的好处
答:
继承:
子类继承父类的特征和行为,使得子类具有父类的各种属性和方法。或子类从父类继承方法,使得子类具有父类相同的行为。
特点:在继承关系中,父类更通用、子类更具体。父类具有更一般的特征和行为,而子类除了具有父类的特征和行为,还具有一些自己特殊的特征和行为。
在继承关系中。父类和子类需要满足is-a的关系。子类是父类。
表示父类和子类的术语:父类和子类、超类和子类、基类和派生类,他们表示的是同一个意思。
多态:
多态的特征是表现出多种形态,具有多种实现方式。或者多态是具有表现多种形态的能力的特征。或者同一个实现接口,使用不同的实例而执行不同的操作。
需要使用多态和多态的好处:
可以增强程序的可扩展性及可维护性,使代码更加简洁。
不但能减少编码的工作量,也能大大提高程序的可维护性及可扩展性。