双指针,hash表。node
l Volatile: 对于一段代码中的变量,若是没有加volatile关键字申明,那么编译器将会进行优化,假定该变量首次和第二次出现之间,没有修改,直接预读取以前的值。而加入volatile,则告诉编译器不要进行这样的优化,避免出现寄存器修改,使得每次都从地址中去读取这个值。react
数组能够处理一组数据类型相同的数据,但不容许动态定义数组的大小,在使用以前必须肯定数组的长度,而链表能够动态分配。linux
从逻辑结构上看,数组必须固定长度,不能适应数据动态增减的状况,容易溢出或内存浪费;链表可适应数据动态增减,且能够方便插入、删除。ios
从内存角度来看,数组从栈中分配空间(用new则在堆上建立),对程序员方便快速,可是自由度小;链表从堆中分配空间,自由度大可是申请管理比较麻烦。c++
从访问方式类看,数组在内存中是连续的存储,所以能够利用下标索引进行访问;链表是链式存储结构,在访问元素时候只可以经过线性方式由前到后顺序的访问,因此访问效率比数组要低。程序员
在C++中,Struct和class同样能包含成员函数,可以继承和多态。区别在于算法
默认是public继承仍是private继承,取决于子类而不是基类。sql
即struct能够继承class,一样class也能够继承struct,那么默认的继承访问权限是看子类究竟是用的struct仍是class。以下:shell
struct A{};class B : A{}; //private继承
struct C : B{}; //public继承数据库
进程是具备必定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程本身基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),可是它可与同属一个进程的其余的线程共享进程所拥有的所有资源.一个线程能够建立和撤销另外一个线程;同一个进程中的多个线程之间能够并发执行.
进程和线程的主要差异在于它们是不一样的操做系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不一样执行路径。线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。
http://blog.csdn.net/gatieme/article/details/50908749
TCP提供可靠的通讯传输,而UDP则常被用于让广播和细节控制交给应用的通讯传输。
TCP充分实现数据传输时各类控制功能,能够进行丢包的重发控制,还能够对次序乱掉的分包进行顺序控制。而这些在UDP中都没有。此外,TCP做为一种面向有链接的协议,只有在确认通讯对端存在时才会发送数据,从而能够控制通讯流量的浪费。TCP经过检验和、序列号、确认应答、重发控制、链接管理以及窗口控制等机制实现可靠性传输。
TCP用于在传输层有必要实现可靠性传输的状况。因为它是面向有链接并具有顺序控制、重发控制等机制的。因此它能够为应用提供可靠传输。另外一方面,UDP主要用于那些对高速传输和实时性有较高要求的通讯或广播通讯。
TCP与UDP区别总结:
一、TCP面向链接(如打电话要先拨号创建链接);UDP是无链接的,即发送数据以前不须要创建链接
二、TCP提供可靠的服务。也就是说,经过TCP链接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
三、TCP面向字节流,其实是TCP把数据当作一连串无结构的字节流;UDP是面向报文的。UDP没有拥塞控制,所以网络出现拥塞不会使源主机的发送速率下降(对实时应用颇有用,如IP电话,实时视频会议等)
四、每一条TCP链接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通讯
五、TCP首部开销20字节;UDP的首部开销小,只有8个字节
六、TCP的逻辑通讯信道是全双工的可靠信道,UDP则是不可靠信道
1. RUDP(Reliable UDP)
可靠用户数据报协议(RUDP)是一种基于可靠数据协议(RDP)的简单分组传输协议,用于传输 IP 网络间的电话信号。RUDP 提供一组数据服务质量加强机制,如拥塞控制的改进、重发机制及淡化服务器算法等,从而在包丢失和网络拥塞的状况下, RTP 客户机(实时位置)面前呈现的就是一个高质量的 RTP 流。在不干扰协议的实时特性的同时,可靠 UDP 的拥塞控制机制容许 TCP 方式下的流控制行为。为了与网络 TCP 通讯量同时工做, RUDP 使用相似于 TCP 的重发机制和拥塞控制算法。
2. RTP(Real Time Protocol)
RTP,实时协议被用来为应用程序如音频,视频等的实时数据的传输提供端到端(end to end)的网络传输功能。传输的模型能够是单点传送或是多点传送。数据传输被一个姐妹协议——实时控制协议(RTCP)来监控,后者容许在一个大的多点传送网络上监视数据传送,而且提供最小限度的控制和识别功能。
3. UDT (UDP-based Data Transfer Protocol,简称UDT)
基于UDP的数据传输协议是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能不好。 顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向链接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。 因为UDT彻底在UDP上实现,它也能够应用在除了高速数据传输以外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。
系统调用、异常、中断。
Ps:用户态的程序能够经过三种方式访问内核态的资源:系统调用、库函数、shell脚本。
答:能,局部会屏蔽全局。要用全局变量,须要使用"::" 。局部变量能够与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内能够定义多个同名的局部变量,好比在两个循环体内都定义一个同名的局部变量,而那个局部变量的做用域就在那个循环体内
答:extern 。能够用引用头文件的方式,也能够用extern关键字,若是用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,若是你用extern方式引用时,假定你犯了一样的错误,那么在编译期间不会报错,而在链接期间报错。
使用3个指针遍历单链表,逐个连接点进行反转
所谓死锁,是指多个进程循环等待它方占有的资源而无限期地僵持下去的局面。eg: 进程A占有资源R1,等待进程B占有的资源Rr;进程B占有资源Rr,等待进程A占有的资源R1。并且资源R1和Rr只容许一个进程占用,即:不容许两个进程同时占用。结果,两个进程都不能继续执行,若不采起其它措施,这种循环等待情况会无限期持续下去,就发生了进程死锁。
计算机系统产生死锁的根本缘由就是资源有限且操做不当。即一种缘由是系统提供的资源太少了,远不能知足并发进程对资源的需求。另外一种缘由是因为进程推动顺序不合适引起的死锁。
计算机系统只有同时具有如下四个条件才会发生死锁。
〈1〉互斥条件。即某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占有。这种独占资源如CD-ROM驱动器,打印机等等,必须在占有该资源的进程主动释放它以后,其它进程才能占有该资源。这是由资源自己的属性所决定的。如独木桥就是一种独占资源,两方的人不能同时过桥。
〈2〉不可抢占条件。进程所得到的资源在未使用完毕以前,资源申请者不能强行地从资源占有者手中夺取资源,而只能由该资源的占有者进程自行释放。如过独木桥的人不能强迫对方后退,也不能非法地将对方推下桥,必须是桥上的人本身过桥后空出桥面(即主动释放占有资源),对方的人才能过桥。
〈3〉占有且申请条件。进程至少已经占有一个资源,但又申请新的资源;因为该资源已被另外进程占有,此时该进程阻塞;可是,它在等待新资源之时,仍继续占用已占有的资源。还以过独木桥为例,甲乙两人在桥上相遇。甲走过一段桥面(即占有了一些资源),还须要走其他的桥面(申请新的资源),但那部分桥面被乙占有(乙走过一段桥面)。甲过不去,前进不能,又不后退;乙也处于一样的情况。
〈4〉循环等待条件。存在一个进程等待序列{P1,P2,...,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一源,......,而Pn等待P1所占有的的某一资源,造成一个进程循环等待环。就像前面的过独木桥问题,甲等待乙占有的桥面,而乙又等待甲占有的桥面,从而彼此循环等待。
1)打破互斥条件。容许进程同时访问某些资源,不可取。
2)打破不可抢占条件。容许进程强行从占有者那里夺取某些资源,实现困难下降性能。
3)打破占有且申请条件。能够实行资源预先分配策略。即进程在运行前一次性地向系统申请它所须要的所有资源。若是某个进程所需的所有资源得不到知足,则不分配任何资源,此进程暂不运行。只有当系统可以知足当前进程的所有资源需求时,才一次性地将所申请的资源所有分配给该进程。因为运行的进程已占有了它所需的所有资源,因此不会发生占有资源又申请资源的现象,所以不会发生死锁。可是,这种策略也有以下缺点:
l 在许多状况下,一个进程在执行以前不可能知道它所须要的所有资源。这是因为进程在执行时是动态的,不可预测的;
l 资源利用率低。不管所分资源什么时候用到,一个进程只有在占有所需的所有资源后才能执行。即便有些资源最后才被该进程用到一次,但该进程在生存期间却一直占有它们,形成长期占着不用的情况。这显然是一种极大的资源浪费;
l 下降了进程的并发性。由于资源有限,又加上存在浪费,能分配到所需所有资源的进程个数就必然少了。
物理地址:用于内存芯片级的单元寻址,与处理器和CPU链接的地址总线相对应。
逻辑地址:逻辑地址指的是机器语言指令中,用来指定一个操做数或者是一条指令的地址。
线性地址:跟逻辑地址相似,它也是一个不真实的地址,若是逻辑地址是对应的硬件平台段式管理转换前地址的话,那么线性地址则对应了硬件页式内存的转换前地址。
类中除了定义的函数成员,还有一个成员是虚函数表指针(占四个基本内存单元),这个指针指向一个虚函数表的起始位置,这个表会与类的定义同时出现,这个表存放着该类的虚函数指针,调用的时候能够找到该类的虚函数表指针,经过虚函数表指针找到虚函数表,经过虚函数表的偏移找到函数的入口地址,从而找到要使用的虚函数。
父类和子类出现同名函数称为隐藏。父类和子类出现同名虚函数称为覆盖。
特色:当咱们在父类中经过virtual修饰析构函数以后,经过父类指针指向子类对象,经过delete接父类指针就能够释放掉子类对象。
解决问题:经过父类指针操做子类对象的成员函数的时候是没有问题的,但是在销毁对象内存的时候则只是执行了父类的析构函数,子类的析构函数却没有执行,这会致使内存泄漏,即多态中的内存泄漏问题。
原理:若是父类当中定义了虚析构函数,那么父类的虚函数表当中就会有一个父类的虚析构函数的入口指针,指向的是父类的虚析构函数,子类虚函数表当中也会产生一个子类的虚析构函数的入口指针,指向的是子类的虚析构函数,这个时候使用父类的指针指向子类的对象,delete接父类指针,就会经过指向的子类的对象找到子类的虚函数表指针,从而找到虚函数表,再虚函数表中找到子类的虚析构函数,从而使得子类的析构函数得以执行,子类的析构函数执行以后系统会自动执行父类的虚析构函数。这个是虚析构函数的实现原理。
class Shape { public: virtual double calcArea()//虚函数 {....} virtual double calcPerimeter()=0;//纯虚函数 .... }; |
纯虚函数没有函数体,同时在定义的时候函数名后面要加“=0”。
纯虚函数的实现原理:
在虚函数原理的基础上,虚函数表中,虚函数的地址是一个有意义的值,若是是纯虚函数就实实在在的写一个0。
含有纯虚函数的类被称为抽象类,纯虚函数没有函数体,因此抽象类不容许实例化对象,而对于一些具体的类来讲,咱们要求必须实现那些要求(纯虚函数),使之成为有具体动做的类。抽象类的子类也能够是一个抽象类。抽象类子类只有把抽象类当中的全部的纯虚函数都作了实现才能够实例化对象。
若是在抽象类当中仅含有纯虚函数而不含其余任何东西,咱们称之为接口类。
l 类里声明为虚函数的话,这个函数是实现的,哪怕是空实现,它的做用就是为了能让这个函数在它的子类里面能够被重载,这样的话,这样编译器就可使用后期绑定来达到多态了;纯虚函数只是一个接口,是个函数的声明而已,它要留到子类里去实现。
l 虚函数在子类里面也能够不重载的;但纯虚必须在子类去实现,这就像Java的接口同样。一般咱们把不少函数加上virtual,是一个好的习惯,虽然牺牲了一些性能,可是增长了面向对象的多态性,由于你很难预料到父类里面的这个函数不在子类里面不去修改它的实现。
l 虚函数的类用于“实做继承”,继承接口的同时也继承了父类的实现。固然咱们也能够完成本身的实现。纯虚函数的类用于“介面继承”,主要用于通讯协议方面。关注的是接口的统一性,实现由子类完成。通常来讲,介面类中只有纯虚函数的。