面试题总结

1.同步机制应该遵循哪些基本准则

A.空闲让进

B.忙则等待

C.让权等待

D.有限等待

答案:A\B\C\D

解析

空闲让进:当无进程处于临界区时,表明临界资源处于空闲状态,允许一个请求进入临界区的进程立即进入临界区,以有效利用临界资源

忙则等待:当已有进程处于临界区时,表明临界资源正在被访问,因而其他试图进入临界区的进程必须等待,以保证对临界资源的互斥访问

有限等待:对要求访问临界资源的进程,应保证在有限时间内能进入自己的临界区,以免陷入“死等”状态

让权等待:当进程不能进入自己的临界区时,应立即释放处理机,以免进程陷入“忙等”状态

2.关于线程和进程,下面说法正确的是

A.线程是资源分配和拥有的单位

B.线程和和进程都可以并发执行

C.在linux系统中,线程是处理器调度的基本单位

D.线程的粒度小于进程,通常多线程比多进程并发性高

E.不同的线程共享相同的栈空间

答案:B\C\D

解析

A:线程是调度和执行的单位,进程是资源分配的单位

B:二者都可以并发执行

C:同解释A

D: 线程的划分尺度小于进程,使得多线程程序的并发性高

E:同一进程之内的线程才会共享资源,同一进程内的线程会拥有自己独立的栈空间和程序计数器,共享同进程内的堆空间和方法区

3.数据库以及线程发生死锁的原理是什么?

A.资源分配不当

B.进程运行推进的顺序不合适

C.系统资源不足

D.进程过多

答案:A\B\C

解析

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

4.下面关于并行和并发的区别,说法错误的是?

A.并发计算是一种程序计算的形式,在系统中,至少有两个以上的计算在同时运作,计算结果可能同时发生

B.并行计算指许多指令得以同时进行的计算模式。在同时进行的前提下,可以将计算的过程分解成小部份,之后以并发方式来加以解决

C.并行是同时发生的多个并发事件,并发事件之间一定要同一时刻发生

D.并发是逻辑上的同时发生(simultaneous),而并行是物理上的同时发生

答案:C

解析

并发的关键是你有处理多个任务的能力,不一定要同时。  

并行的关键是你有同时处理多个任务的能力。  

5.高内聚和低耦合,下面哪个耦合度最高?

A.通过函数参数传递

B.一个函数修改另外一个函数中的数据

C.通过全局变量

D.通过指示器

答案:B

解析

耦合可以分为以下几种,它们之间的耦合度由高到低排列如下:
(1) 内容耦合:有下列情形之一,两个模块就发生了内容耦合:
*一个模块访问另一个模块的内部数据
*一个模块不通过正常入口而转到另一个模块的内部
*一个模块有多个入口
(2) 公共耦合:当两个或多个模块通过公共数据环境相互作用时,他们之间的耦合称为公共环境耦合。
(3) 控制耦合:如果两个模块通过参数交换信息,交换的信息有控制信息,那么这种耦合就是控制耦合。
(4) 特征耦合:如果被调用的模块需要使用作为参数传递进来的数据结构中的所有数据时,那么把这个数据结构作为参数整体传送是完全正确的。但是,当把整个数据结构作为参数传递而使用其中一部分数据元素时,就出现了特征耦合。在这种情况下,被调用的模块可以使用的数据多于它确实需要的数据,这将导致对数据的访问失去控制,从而给计算机犯错误提供机会。
(5) 数据耦合:如果两个模块通过参数交换信息,而且交换的信息仅仅是数据,那么这种耦合就是数据耦合。
内聚有如下的种类,它们之间的内聚度由弱到强排列如下:
(1) 偶然内聚:模块中的代码无法定义其不同功能的调用。但它使该模块能执行不同的功能,这种模块称为巧合强度模块。
(2) 逻辑内聚。这种模块把几种相关的功能组合在一起, 每次被调用时,由传送给模块参数来确定该模块应完成哪一种功能 
(3) 时间内聚:把需要同时执行的动作组合在一起形成的模块为时间内聚模块。 
(4) 过程内聚:构件或者操作的组合方式是,允许在调用前面的构件或操作之后,马上调用后面的构件或操作,即使两者之间没有数据进行传递。 
(5) 通信内聚:指模块内所有处理元素都在同一个数据结构上操作(有时称之为信息内聚),或者指各处理使用相同的输入数据或者产生相同的输出数据。 
(6) 顺序内聚:指一个模块中各个处理元素都密切相关于同一功能且必须顺序执行,前一功能元素输出就是下一功能元素的输入。
(7) 功能内聚:共同完成同一功能,缺一不可,模块不可再分割

****************************新增***********************************************

1.下面论述正确的是()?

A.如果两个对象的hashcode相同,那么它们作为同一个HashMap的key时,必然返回同样的值

B.如果a,b的hashcode相同,那么a.equals(b)必须返回true

C.对于一个类,其所有对象的hashcode必须不同

D.如果a.equals(b)返回true,那么a,b两个对象的hashcode必须相同

答案:D

解析

hashCode()方法和equals()方法的作用其实是一样的,在Java里都是用来对比两个对象是否相等一致。
那么equals()既然已实现比的功能了,为什么还要hashCode()呢?因为重写的equals()里一般比较的比较全面比较复杂,这样效率就比低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高。
那么hashCode()既然效率这么高为什么还要equals()呢 因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,
所以我们可以得出:

1.equals()相等的两个对象他们的hashCode()肯定相等,也就是用equals()对比是绝对可靠的。

2.hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。

所有对于需要大量并且快速的对比的话如果都用equals()去做显然效率太低,所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equal()去再对比了),如果hashCode()相同,此时再对比他们的equals(),如果equals()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!

2.选项中哪一行代码可以替换 //add code here 而不产生编译错误?

public abstract class MyClass {
     public int constInt = 5;
     //add code here
     public void method() {
     } 

A.public abstract void method(int a);

B.consInt=constInt+5;

C.public int method();

D.public abstract void anotherMethod(){}

答案:A

解析

A:抽象类可以包含抽象方法

B:类中定义成员和方法,不能直接进行运算,可以写在代码块{}或者静态代码块中static{}中

C:与第四行想要构成重载,二者区别是返回类型,但是返回类型不能作为重载的依据

D: 该方法使用abstract修饰,是抽象方法,但是他有方法体(带有{}的就是方法体,即使里面是空的),就不能作为抽象方法

3.有以下类定义,运行后的结果?

abstract class Animal{
    abstract void say();
}
public class Cat extends Animal{
    public Cat(){
        System.out.printf("I am a cat");
    }
    public static void main(String[] args) {
        Cat cat=new Cat();
    }
}

A.I am a cat

B.Animal能编译,Cat不能编译

C.Animal不能编译,Cat能编译

D.编译能通过,但是没有输出结果

答案:B

解析

包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样可以拥有成员变量和普通的成员方法。注意,抽象类和普通类的主要有三点区别:

1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。

2)抽象类不能用来创建对象;

3)如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。

在其他方面,抽象类和普通的类并没有区别

 4.如下语句通过算术运算和逻辑运算之后i和 j的结果是( )?

int i=0;
int j=0;
if((++i>0)||(++j>0))
{
//打印出i和j的值。
}

A.i=0;j=0

B.i=1;j=1

C.i=0;j=1

D.i=1;j=0

答案:D

解析

&& 和 || 为短路与 短路或
&&若前面的表达式为false,整个逻辑表达式为false,所以后面的表达式无论true和false都无法影响整个表达式的逻辑结果,所以为了提高代码执行速率,这里后面的表达式就不会执行。
同理,若前面表达式为true,则后面的表达式无需计算。

& 和 | 为不短路与 不短路或
无论什么情况,前面的和后面的都要执行。

5.如果一个接口Cow有个方法drink(),有个类Calf实现接口Cow,则在类Calf中正确的是?  ( )

A.void drink() { …}

B.protected void drink() { …}

C.public void drink() { …}

D.以上语句都可以用在类Calf中

答案:C

解析

 子类重写父类方法时,方法的访问权限不能小于原访问权限。接口是一种约束和规范,是一种更加更高级的抽象类,抽象类的方法必须是公开的,因为要给人继承和使用啊,不用public,别人怎么看得到,所以在接口实现时,定义的方法修饰符必须是public;因此子类在实现接口重写方法时的修饰符必须是public。

6.What will happen when you attempt to compile and run the following code?

public class Test{
static{
   int x=5;
}
static int x,y;
public static void main(String args[]){
   x--;
   myMethod( );
   System.out.println(x+y+ ++x);
}
public static void myMethod( ){
  y=x++ + ++x;
 }
}

A.compiletime error

B.prints:1

C.prints:2

D.prints:3

E.prints:7

F.prints:8

答案:D

解析

1.JVM加载class文件时,就会执行静态代码块,静态代码块中初始化了一个变量x并初始化为5,由于该变量是个局部变量,静态代码快执行完后变被释放。
2.申明了两个静态成员变量x,y,并没有赋初值,会有默认出值,int类型为0,
3.执行x--操作,变量单独进行自增或自减操作x--和--x的效果一样,此时x变为了-1
4.调用MyMethod()方法,在该方法中对x和y进行计算,由于x和y都是静态成员变量,所以在整个类的生命周期内的x和y都是同一个
5.y=x++ + ++x可以看成是y=(x++)+(++x),当++或者--和其它变量进行运算时,x++表示先运算,再自增,++x表示先自增再参与运算
所以就时x为-1参与运算,然后自增,x此时为0,++x后x为1,然后参与运算,那么y=-1+1就为0,此时x为1
6.执行并打印x+y + ++x运算方式和第5步相同,最后计算结果就为3.
 
 
题目来源:牛客网
 
 
 
 
 
 
 
 
 
posted @ 2021-03-12 22:08  云入山涧  阅读(386)  评论(0编辑  收藏  举报