面试题整理

前言:几年前写的博文,离开一段后又回来了,发布与你们共享。

1.简述数据库以及线程死锁产生的原理及必要条件,简述如何避免死锁。

产生死锁的缘由主要是:
(1) 由于系统资源不足。
(2) 进程运行推动的顺序不合适。
(3) 资源分配不当等。
产生死锁的四个必要条件:
(1)互斥条件:一个资源每次只能被一个进程使用。
(2)请求与保持条件:一个进程因请求资源而阻塞时,对已得到的资源保持不放。
(3)不可剥夺条件:进程已得到的资源,在末使用完以前,不能强行剥夺。
(4)循环等待条件:若干进程之间造成一种头尾相接的循环等待资源关系。算法

避免死锁:
死锁的预防是经过破坏产生条件来阻止死锁的产生,但这种方法破坏了系统的并行性和并发性。
死锁产生的前三个条件是死锁产生的必要条件,也就是说要产生死锁必须具有的条件,而不是存在这3个条件就必定产生死锁,那么只要在逻辑上回避了第四个条件就能够避免死锁。
避免死锁采用的是容许前三个条件存在,但经过合理的资源分配算法来确保永远不会造成环形等待的封闭进程链,从而避免死锁。该方法支持多个进程的并行执行,为了不死锁,系统动态的肯定是否分配一个资源给请求的进程。
预防死锁:具体的作法是破坏产生死锁的四个必要条件之一。数据库

2. 请列举面向对象设计的三个基本要素和五种主要涉及原则。

面向对象的3个基本要素:封装、继承、多态 

面向对象的5个基本设计原则: 
单一职责原则(Single-Resposibility Principle) 
    其核心思想为:一个类,最好只作一件事,只有一个引发它的变化。单一职责原则能够看作是低耦合、高内聚在面向对象原则上的引伸,将职责定义为引发变化的缘由,以提升内聚性来减小引发变化的缘由。职责过多,可能引发它变化的缘由就越多,这将致使职责依赖,相互之间就产生影响,从而大大损伤其内聚性和耦合度。一般意义下的单一职责,就是指只有一种单一功能,不要为类实现过多的功能点,以保证明体只有一个引发它变化的缘由。 
    专一,是一我的优良的品质;一样的,单一也是一个类的优良设计。交杂不清的职责将使得代码看起来特别别扭牵一发而动全身,有失美感和必然致使丑陋的系统错误风险。 

开放封闭原则(Open-Closed principle) 
    其核心思想是:软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。开放封闭原则主要体如今两个方面一、对扩展开放,意味着有新的需求或变化时,能够对现有代码进行扩展,以适应新的状况。二、对修改封闭,意味着类一旦设计完成,就能够独立完成其工做,而不要对其进行任未尝试的修改。 
    实现开开放封闭原则的核心思想就是对抽象编程,而不对具体编程,由于抽象相对稳定。让类依赖于固定的抽象,因此修改就是封闭的;而经过面向对象的继承和多态机制,又能够实现对抽象类的继承,经过覆写其方法来改变固有行为,实现新的拓展方法,因此就是开放的。 
    “需求老是变化”没有不变的软件,因此就须要用封闭开放原则来封闭变化知足需求,同时还能保持软件内部的封装体系稳定,不被需求的变化影响。 

Liskov替换原则(Liskov-Substituion Principle) 
    其核心思想是:子类必须可以替换其基类。这一思想体现为对继承机制的约束规范,只有子类可以替换基类时,才能保证系统在运行期内识别子类,这是保证继承复用的基础。在父类和子类的具体行为中,必须严格把握继承层次中的关系和特征,将基类替换为子类,程序的行为不会发生任何变化。同时,这一约束反过来则是不成立的,子类能够替换基类,可是基类不必定能替换子类。 
    Liskov替换原则,主要着眼于对抽象和多态创建在继承的基础上,所以只有遵循了Liskov替换原则,才能保证继承复用是可靠地。实现的方法是面向接口编程:将公共部分抽象为基类接口或抽象类,经过Extract Abstract Class,在子类中经过覆写父类的方法实现新的方式支持一样的职责。 
    Liskov替换原则是关于继承机制的设计原则,违反了Liskov替换原则就必然致使违反开放封闭原则。 
    Liskov替换原则可以保证系统具备良好的拓展性,同时实现基于多态的抽象机制,可以减小代码冗余,避免运行期的类型判别。 

依赖倒置原则(Dependecy-Inversion Principle) 
    其核心思想是:依赖于抽象。具体而言就是高层模块不依赖于底层模块,两者都同依赖于抽象;抽象不依赖于具体,具体依赖于抽象。 
    咱们知道,依赖必定会存在于类与类、模块与模块之间。当两个模块之间存在紧密的耦合关系时,最好的方法就是分离接口和实现:在依赖之间定义一个抽象的接口使得高层模块调用接口,而底层模块实现接口的定义,以此来有效控制耦合关系,达到依赖于抽象的设计目标。 
    抽象的稳定性决定了系统的稳定性,由于抽象是不变的,依赖于抽象是面向对象设计的精髓,也是依赖倒置原则的核心。 
    依赖于抽象是一个通用的原则,而某些时候依赖于细节则是在所不免的,必须权衡在抽象和具体之间的取舍,方法不是一层不变的。依赖于抽象,就是对接口编程,不要对实现编程。 

接口隔离原则(Interface-Segregation Principle) 
    其核心思想是:使用多个小的专门的接口,而不要使用一个大的总接口。 
    具体而言,接口隔离原则体如今:接口应该是内聚的,应该避免“胖”接口。一个类对另一个类的依赖应该创建在最小的接口上,不要强迫依赖不用的方法,这是一种接口污染。 
    接口有效地将细节和抽象隔离,体现了对抽象编程的一切好处,接口隔离强调接口的单一性。而胖接口存在明显的弊端,会致使实现的类型必须彻底实现接口的全部方法、属性等;而某些时候,实现类型并不是须要全部的接口定义,在设计上这是“浪费”,并且在实施上这会带来潜在的问题,对胖接口的修改将致使一连串的客户端程序须要修改,有时候这是一种灾难。在这种状况下,将胖接口分解为多个特色的定制化方法,使得客户端仅仅依赖于它们的实际调用的方法,从而解除了客户端不会依赖于它们不用的方法。 
    分离的手段主要有如下两种:一、委托分离,经过增长一个新的类型来委托客户的请求,隔离客户和接口的直接依赖,可是会增长系统的开销。二、多重继承分离,经过接口多继承来实现客户的需求,这种方式是较好的。 编程

3. windows内存管理的几种方式及优缺点

(1)块式管理。把主存分为一大块、一大块的,当所需的程序片断不在主存时就分配一块主存空间,把程序片断加载到主存,就算所须要的程序片断只有几个字节也只能把这块分配给它。优势:易于管理;缺点:浪费空间。windows

(2)页式管理。把主存分为一页一页的,每一页的空间要比一块一块的空间小不少,显然这种方式的空间利用率要比块式管理高出不少。并发

(3)段式管理。把主存分为一段一段的,每一段的空间又要比一页一页的空间小不少,这种方法在空间利用率上比页式管理高出不少,但也有另一个缺点,一个程序片断可能会被分为几十个段,这样不少时间就会浪费在计算每一段的物理地址上。(I/O操做)ui

(4)段页式管理。结合了段式管理和页式管理的优势。把主存分为若干页,每一页又分为若干段。线程

相关文章
相关标签/搜索