一份最贴近真实面试的Java基础面试题

       

        这是一份Java基础知识的面试题。在网上的关于Java的面试题数不胜数,但认真看过感受大多数都没有实用性,有不少是面试官根本就不会问到的,那些已经脱离了实际开发的技术问题。而这份资料来源自一份我的以为最贴近真实面试的Java面试题,网上流传较少。java

 

        最近又对这份Java基础面试题从新整理了一遍,本人从新编辑后结合了本身许屡次的面试经历和经验,作出了标记,划分了重点,以及对某些知识作出一些简单明白的注释,相信能够对须要回顾Java知识,以及准备着面试的Java开发工程师会有必定帮助。c++

 

 

 

1.     面向对象的特征有哪些方面?程序员

答:web

1.      继承面试

经过继承容许复用已有的类。继承关系是一种通常到特殊的关系,好比苹果类继承水果类,这个过程称为类继承。算法

子类能够从父类那里继承获得方法和成员变量,并且子类能够修改或增长新的方法使之适合子类的须要。sql

2.      封装编程

封装是把对象的状态数据隐藏起来,再经过暴露合适的方法来容许外部程序修改对象的状态数据。Java的封装主要经过private,protected,public等访问控制符来实现。bootstrap

3.      多态设计模式

多态指的是同一个类型的引用类型的变量执行相同的方法时,实际上会呈现出多种不一样的行为特征

多态增长了编程的灵活性,实际上大量设计模式都是基于多态类实现的。

4.      抽象

抽象就是忽略与当前目标无关的方面,以便更充分的突出与当前目标有关的方面。

抽象包括两个方面,一是过程抽象,二是数据抽象

 

2.      Java中实现多态的机制是什么?

答:Java容许父类或接口定义的引用变量指向子类或具体实现类的实例对象

(致使编译时引用变量指向的方法和程序在内存里运行时实例对象调用的方法不一致。)

程序调用的方法在运行时才动态绑定,就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

 

3.      一个.java源文件中是否能够包括多个类(不是内部类)?有什么限制?

答:能够有多个类,可是只能有一个有public修饰的类,而且public类的类名必须与文件名相同。包含多个类的.java源文件编译以后会产生多个.class文件。

 

4.      String是最基本的数据类型吗?

答:不是。

最基本的数据类型有:byte,short,int,long,char,float,double,Boolean

Stringjava.lang.String 类,属于引用类型

(所谓的引用类型包括:类,接口,数组。

由于Stringfinal修饰的类,是不可继承的类。而且是一个不可变类。所以若是程序须要使用的字符串所包含的字符序列须要常常改变,建议使用StringBuffer(线程安全,性能略差)类或者StringBuilder(线程不安全,性能好)类。)

 

5.    Java有没有goto (转到)

答:没有。由于gotoJava的保留字,暂时不是Java的关键字。

 

6.    intInteger有什么区别?

答:intJava的基本数据类型,IntegerJavaint提供的包装类(封装类)。Integer包装类具备面向对象的特征。

Java5开始,Java提供了自动装箱,自动拆箱功能。所以包装类也能够直接参与表达式运算,所以使用起来十分方便。

(Java为每一个原始类型提供了包装类。

JSP开发中,Integer的默认值为null,因此用EL输出nullInteger时,会显示空白字符串,而int的默认值为0,因此int不适合做为Web层的表单数据的类型。

另外,Integer提供了多个与整数相关的操做方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。)

 

7.StringStringBufferStringBuilder的区别?

答:

StringBuffer是线程安全的,性能较差,而StringBuilder是线程不安全的,适合单线程环境使用,性能较好。

String表明了字符序列不可变的字符串,而StringBufferStringBuilder表明了字符序列可变的字符串。

(它们都是CharSequence(字符序列)的实现类,均可以做为字符串使用。

)

 

8.CollectionCollections的区别?

答:Collection是集合类(List集合,Set集合,Queue队列)的根接口。

Collections是针对集合类的一个工具类,它提供一系列静态方法实现对各类集合的搜索,排序,线程安全化等操做。

 

9.说说&&&的区别?

       答:

&&&均可以用做逻辑与的运算符,&当运算符两边的表达式的结果都为true时,整个运算结果才为true,不然,只要有一方为false,则结果为false

       双与有短路的功能,也称短路与。若是第一个表达式为false,则再也不计算第二个表达式了。实际开发中能够用来把要比较的表达式放后面,排除报空指针异常的状况。

       而单与在第一个表达式为false时,还会计算第二个表达式,因此性能略慢。

       除此以外,&还能够用做位运算符,当&操做符两边不是boolean类型时,&表示按位与操做。

 

10.OverloadOverride的区别。

Overloaded的方法是否能够改变返回值的类型?

答:Overload是方法的重载。(load 加载)

       Override是方法的重写,也叫覆盖。

Overload要求两个方法具备方法名相同,形参列表不一样的要求,返回值类型不能做为重载的条件。

              Override要求子类方法与父类方法具备“两同两小一大”的要求。

       两同:父类方法,子类方法的方法名形参列表相同。

       两小:子类方法的返回值类型要么是父类方法返回值类型的子类,要么返回值类型相同。

       子类方法的抛出异常类型要么是父类方法抛出异常类型的之类,要么异常类型相同。

       一大:子类的访问权限要么比父类的大,要么相同。

Overloaded方法能够改变返回值的类型。

 

11.Java如何跳出当前的多重嵌套循环?

答:能够在外面的循环语句前定义一个标号,而后在里层循环体的代码中使用带有标号的break语句,便可跳出外层循环。

例如:

       Outer:

       for(int i=0;i<10;i++)

       {

              for(int j=0;j<10;j++)

              {

                     System.out.println(“i=” + i + “,j=” + j);

                     if(j == 5) break Outer;

              }

       }

 

12.switch语句(判断选择)可否做用在byte上,可否做用在long上,可否做用在String上?

答:在Java1.7之前,能够做用在char,byte,short,int以及对应的包装类上。

Java1.7之后,switch中能够是字符串类型,因此能够做用在String上。

也能够是枚举类型,在Java1.7之前以及之后都不能做用在longdoublefloatboolean以及对应的包装类上。

longdoublefloatlong比较特殊)

 

13.String s = new String(“xyz”);建立了几个String Object?

答:两个。一个是直接量的xyz对象,另外一个是经过new String()构造器建立出来的String对象。一般来讲,应该尽可能使用直接量的String对象,这样具备更好的性能。

直接量就是程序中直接使用的数据值。

 

14.数组有没有length()这个方法?String有没有length()这个方法?

答:数组没有length()这个方法,只有length这个属性。Stringlength()方法。

Length长度。

 

15.short s1 = 1;s1 = s1 + 1;有什么错?short s1 = 1;s1+=s1有什么错?

答:s1 + 1 在运算时会自动提高表达式的类型,s1 + 1结果是int型,但复制给short类型的s1时,编译器将报告须要强制转换类型的错误。

第二个,因为+=运算符里已经包括了一个隐式的强制类型转换,所以它不会有任何错误。

 

16.char型变量中能不能存储一个中文字符?为何?

答:char型变量是用来存储Unicode编码的字符的,Unicode编码字符集中包含了汉字,所以char型变量中能够存储汉字。

不过,若是某个特殊汉字没有被包含在Unicode编码字符集中,那么,char型变量中不能存储这个特殊汉字。

此外,char类型的变量占两个字节,而Unicode编码中每一个字符也占两个字节。所以char型变量能够存储任何一个Unicode字符。

Unicode又称统一码。

 

17.用最有效率的方法算出2乘以8等于几?

答:2<<3 <<,箭头向左,是左移运算符,>>,箭头向右,是右移运算符

由于将一个数左移n位,就至关于乘以了2n次方;那么,一个数乘以8只要将其左移3位便可,23次方,而CPU直接支持位运算,效率最高。

可是须要注意的是,若是这个数字自己已经很大,好比自己已是230次方了,此时再使用这种位移运算就可能致使“溢出”,这样就得不到正确的结果了。

 

18.使用final关键字修饰一个变量时,是引用不能变,仍是引用的对象不能变?

答:使用final关键字修饰一个变量时,是指被修饰的引用变量不能变,引用变量所指向的对象的内容是能够改变的。

例如,对于以下语句:

final StringBuilder a=new StringBuilder ("immutable");

执行以下语句将报告编译错误:

a = new StringBuilder ("");

但以下语句则是彻底正确的

a.append("fkjava.org");

有人但愿在定义方法的形参时,经过final修饰符来阻止方法内部修改传进来的实参:

public void method(final StringBuilder param)

{

}

实际上这没有用,在该方法内部仍然能够增长以下代码来修改实参对象:

param.append("fkjava.org");

 

19.”==”equals方法究竟有什么区别?

答:通俗地讲,”==”比较左右是否是一个东西,equals是比较左右是否是长得同样。

==操做符的功能有两个:

A. 若是==的两边是基本类型的变量,包装类对象所组成的表达式,==用于比较两边的表达式的值是否相等,若是值相等,即便数据类不一样,也会返回true

B. 若是==的两边是引用类型的变量,==用于判断这两个引用类型的变量是否引用同一块内存,只有它们引用同一块内存时,==才会返回true

C. equals()则是java.lang.Object类的一个方法,所以任何Java对象均可以调用此方法与其它对象进行比较。

D. 开发者重写equals()方法就能够根据业务要求来决定这两个对象是否“相等”。

 

20.静态变量和实例变量的区别?

答:A.在语法定义上的区别,静态变量前要加static关键字,而实例变量前则不加。

       B.在程序运行时的区别,实例变量属于一个对象,必须先建立实例对象,它的实例变量才会被分配空间,才能使用这个实例变量。静态变量则属于类,只要程序加载了类的字节码,不用建立任何实例对象,静态变量就会被分配空间,静态变量就能够被使用了。

总之,实例变量必须建立对象后才能够经过这个对象来使用,静态变量则能够直接使用类名来引用。

       C.在内存中,static修饰的类变量只能有一个,而实例变量每建立一个实例对象就能够分配一个。

 

21.是否能够从一个static方法内部调用非static方法?

答:不能够,静态成员不能够调用非静态成员。

static方法属于对象,必须建立一个对象后,才能够经过该对象来调用实例方法。

static方法调用时不须要建立对象,经过类就能够调用该方法。

也就是说,当一个static方法被调用时,可能尚未建立任何实例对象。

所以Java不容许static方法内部调用非static方法。

 

22.Math.round(11.5)等于多少?Math.round(-11.5)等于多少?

答:Math类中提供了三个与取整有关的方法:ceil,floor,round,这些方法的做用与它们的英文名称的含义相对应。Ceil:天花板,向上取整Math.ceil(11.3)=12,Math.ceil(-11.3)=-11

Floor:地板,向下取整Math.floor(11.6)的结果为11Math.floor(-11.6)=-12

Round:表示“四舍五入”,Math.round(11.5)=12,Math.round(-11.5)=-11

 

23.请说出做用域public,private,protected,以及不写时的区别。

答:这四个做用域的可见范围以下表所示。

做用域    当前类   同一package    子类    全局

public                                  

protected                              ×  

default                           ×      × 

private                               

若是在修饰的元素上面没有写任何访问修饰符,则表示default

访问权限由大到小是:public,protected,default,private

Java存在的4个访问范围:全局,子类,同一个package,当前类

 

24.外部类能用private,protected修饰吗?内部类能够用privateprotected修饰吗?

答:外部类不能用private,protected修饰。内部类能用private,protected修饰。

外部类的上一级程序单位是包package,所以它只能有两个使用范围:包内和包外,所以它只能使用public(表示能够在全局位置访问),和默认修饰符default(表示只能被同一个包内的其它类使用)修饰。

 

25.一个类定义多个重载方法,参数分别是intchar,和double,而后将double x=2传递进去,会选择哪一个方法?

答:选择参数类型为double的方法。

 

26.说说has a(有)与is a(是)的区别。

答:is a是典型的“通常到特殊“的关系,也就是典型的继承关系。例如Apple is a Fruit.。苹果是水果。Apple是一种特殊的Fruit,也就是说Apple继承了Fruit

has a是典型的“组合“关系。好比Wolf has a Leg.狼有腿。也就是Leg组合成了Wolf

须要指出的是:因为继承会形成对父类的破坏,所以有时候能够经过组合来代替继承。

使用继承的好处:程序语义更好理解。坏处是:子类可能重写父类方法,不利于父类封装。

使用组合则形成语义的混淆,但组合类不会重写被组合类的方法,所以更利于被复合类封装。

 

27.ClassLoader如何加载Class?

答:JVM(Java虚拟机)里有多个类加载,每一个类加载能够负责加载特定位置的类。

除了bootstrap以外,其它的类加载器自己也是java类,它们的父类是ClassLoader

 

28.Java抽象类的做用。

答:抽象类更利于代码的维护和重用。

抽象类的特色:1.拥有抽象方法。

                       2.抽象方法和抽象类都必须被abstract关键字修饰。

                       3.抽象类不能够建立实例和实例化对象,由于抽象类自己是不完整的。

                       4.抽象类的抽象方法要被使用,必须由子类重写全部父类抽象类的抽象方法,创建子类对象调用。(若是子类只重写(覆盖)了部分抽象方法,那么该子类仍是一个抽象类)

抽象类比通常类多了抽象方法。

 

28.GC是什么?为何要有GC?

答:GC是垃圾收集的意思,是Java的垃圾回收机制。

内存处理是编程人员容易出现问题的地方,Java提供的GC功能能够自动监测对象是否超过做用域从而达到自动回收内存的目的。

JavaSystemRuntime类都提供了“通知“程序进行垃圾回收的方法。

JVM什么时候来进行垃圾回收,仍是由JVM本身来决定。

 

29垃圾回收的优势和原理。并考虑2种回收机制。

答:

1.Java语言最显著的特色就是引入了垃圾回收机制,它使java程序员在编写程序时再也不考虑内存管理的问题。

2.因为有垃圾回收机制,Java中的对象再也不有“做用域“的概念,只有引用的对象才有做用域。

3.垃圾回收机制有效的防止了内存泄漏,能够有效的使用可以使用的内存。

4.垃圾回收器一般做为一个单独的低级别的线程运行,在不可预知的状况下对内存堆中已经死亡的或很长的时间没有用过的对象进行清除和回收。

5.程序员不能实时的对某个对象或全部对象调用垃圾回收器进行垃圾回收。

 

垃圾回收机制有分代复制垃圾回收,标记垃圾回收,增量垃圾回收。

 

30.垃圾回收器的基本原理是什么?垃圾回收器能够立刻回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?

答:对于Java程序中对象而言,若是这个对象没有任何引用变量引用它,那么这个对象不能被程序访问,所以可认为它是垃圾。

1.      只要有1个以上的引用变量引用该对象,该对象就不会被垃圾回收。

2.      对于Java的垃圾回收器来讲,它使用“有向图“来记录和管理堆内存中的全部对象,经过这个有向图就能够识别哪些对象是”可达的“(有1个引用变量引用该对象),哪些对象是”不可达的“,全部不可达的对象就会被垃圾回收。

3.      程序员能够手动执行System.gc(),通知GC运行,但这只是一个通知,而JVM依然有权决定什么时候进行垃圾回收。

 

31.何时用assert

答:assertJDK1.4新增的关键字。

assertion断言在软件开发中是一种常见的调试方式,不少开发语言中都支持这种机制。在实现中,assert就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true,若是该值为false,说明程序已经处于不正确的状态下,assert将给出警告或退出。

Javaassert是关键字。

Java命令默认不启动断言,

为了启动用户断言,应该在运行java命令时增长-eaEnable Assert)选项。

为了启动系统断言,应该在运行java命令时增长-esaEnable System Assert)选项。

 

32.Java中会存在内存泄漏吗?请简单描述。

答:什么是内存泄漏:程序运行过程当中会不断地分配空间;那些再也不使用的内存空间应该即时回收它们,从而保证系统能够再次使用这些内存。若是存在无用的内存没有被回收回来,那就是内存泄漏。

 

33.能不能本身写个类,也叫java.lang.String?

答:能够,但在应用的时候,须要用本身的类加载器去加载,不然,系统的类加载器永远只是去加载jre.jar包中的那个java.lang.String

但在Tomcatweb应用程序中,都是由webapp本身的类加载器先本身加载WEB-INF/classes目录中的类,而后才委托上级的类加载器加载,若是咱们在Tomcatweb应用程序中写一个java.lang.String,这时候Servlet程序加载的就是咱们本身写的java.lang.String。但这样作就会出不少潜在的问题,原来全部用了java.lang.String类都将出现问题。

 

34.ArrayList如何实现插入的数据按自定义的方式有序存放?

答:编程思路:实现一个类对ArrayList进行包装,当程序试图向ArrayList中放入数据时,程序将先检查该元素与ArrayList集合中其余元素的大小,而后将该元素插入到指定位置。

 

35.序列化接口的id有什么用?

答:(对象的序列化:把对象转换为字节序列的过程.

       对象的反序列化:把字节序列恢复为对象的过程。

       对象的序列化主要有两种用途:

1.      把对象的字节序列永久地保存到硬盘上,一般放在一个文件中。

2.      在网络上传送对象的字节序列。

在不少应用中,须要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。)

反序列化Java对象时必须提供该对象的class文件,如今的问题是随着项目的升级,系统的class文件也会升级,Java如何保证两个class文件的兼容性?

Java序列化机制容许为序列化类提供一个UID,也就是说若是一个类升级后,只要它的id值保持不变,序列化机制也会把它们当成同一个序列化版本。

(序列化类的id是为了在进行项目升级时,保证系统的两个class文件的兼容性,不会致使重复和冲突。)

 

36.hashCode()方法的做用?

答:hashCode()方法与equals()方法相似。都容许用户定义子类重写这两个方法。

equals()主要判断两个对象表面上或者内容上看是否相同。

hashCode方法的判断就要严格的多。

若是两个对象的hashCode()相等,便可认为这两个对象是相等的。

所以当咱们重写一个类的equals()方法时,也应该重写它的hashCode()方法。并且这两个方法判断对象的标准也应该是同样的。

 

37.编写一个函数将十六进制的字符串参数转换成整数返回。

String str = “13abf”;

Int len = str.length;

Int sum = 0;

Integer.parseInt(str,16);

 

parseInt方法提供了把16进制字符串参数转换成整数返回的方法。

 

38.银行还款问题

银行贷款的还款方式中最经常使用的是一种叫“等额本息”,还款法,即借款人在约定还款期限内的每一期(月)归还的金额(产生的利息+部分本金)都是相等的,现有一笔总额为T元的N年期住房贷款,年利率为R,要求算出每一期的还款的本金和利息总额,请写出解决思路和任意一种编程语言实现的主要代码。

       思路:既然是按月还款,那我就要将N年按月来计算,即要还N*12个月,这样就能够求出每个月要还的本金。因为每个月要还的那部分本金所欠的时间不一样,因此,它们所产生的利息是不一样的,该部分本金的利息为:部分本金额*所欠月数*月利率。应该是这么个算法,若是利息还计利息,若是月还款不按年利率来算,老百姓算不明白的。

 

39.*任意数字序列“123456”之类,输出它们全部的排列组合

答:String str = "fkjav";

       char[] arr1 = str.toCharArray();

       char[] arr2 = java.util.Arrays.copyOf(arr1,arr1.length);

       for(int i=0;i<arr1.length-1;i++)

       {

              for(int j = i+1;j<arr2.length;j++){

                     System.out.println(arr1[i] + "," + arr2[j]);

              }

       }

 

40.构造器Constructor是否可被override

答:构造器Constructor不能被继承,所以不能重写Override,但能够被重载Overrload(形参列表不一样)

 

41.接口是否能够继承接口?抽象类是否能够实现(implements)接口?抽象类是否能够继承具体类(concrete class)?抽象类中是否能够有静态的main方法?

答:接口能够继承接口。

       抽象类能够实现接口。

       抽象类能够继承具体类。

       抽象类中能够有静态的main方法。

归法:抽象类的特征是有得有失,获得的功能是抽象类能够拥有抽象方法(固然也能够没有);失去的功能是抽象类不能建立实例了。至于其余的,抽象类与普通类在语法上大体是同样的。

(抽象类除了不能建立实例,只要普通类能够的它均可以。)

 

42.clone()方法时,一般都有一行代码,是什么?

答:clone故名思意就是复制,当对象调用此方法,就会在内存中分配一个和源对象一样大小的空间,在这个空间中建立一个新的复制对象。

clone有缺省(默认)行为,super.clone();

由于首先要把父类中的成员复制到位,而后才是复制本身的成员。

 

43.abstract class interface有什么区别?

答:抽象类和接口的语法区别:

接口能够说成是抽象类的一种特例,接口中全部方法都必须是抽象的。

1.一个类能够实现多个接口,但只能继承一个抽象类。

1.接口是完全的抽象类。抽象类能够包含非抽象的普通方法,接口中的全部方法必须都是抽象的。

2.抽象类能够有构造器,接口中不能有构造器。

3.抽象类中能够有实例成员变量,接口中没有实例成员变量。

4.抽象类中的抽象方法的访问类型能够是public , protected和默认访问权限。但接口中的抽象方法只能是public类型的。

5.抽象类中能够包含static静态方法,接口中不能包含static静态方法。

6.抽象类和接口均可以包含静态成员变量,但抽象类的静态成员变量的访问类型能够是任意,而接口的静态成员变量的访问类型只能是public static final

二者在应用上的区别:

接口体现的是一种规范,而抽象类在代码实现方面发挥做用,能够实现代码的重用。

例如,模板设计模式是抽象类的一个典型应用。假设项目中须要大量的DAO组件,这些组件一般都有增,删,改,查等基本方法。所以咱们就能够定义一个抽象的DAO基类,而后让其它DAO组件来继承这个抽象的DAO基类,把这个DAO基类当成模板使用。

 

44.abstract抽象的method方法是否可同时是static,是否可同时是native(原生态方法,方法对应的实现不在当前文件,而是在其余语言(c,c++)实现的文件中),是否可同时是synchronized同步的?

答:抽象的方法不能够是static的,由于抽象方法要被子类实现。

native方法表示该方法要用另外一种依赖平台的编程语言实现,不存在着被子类实现的问题,因此,它也不能是抽象的。

Synchronized同步锁与abstract不能同时使用,它修饰一个方法时,表示将会使用该方法的调用者做为同步监视器。但abstract方法所在的类是抽象类,不能建立实例,所以没法肯定synchronized修饰方法时的同步监视器。

 

45.什么是内部类?Static Nested Class(静态嵌入类型)和 Inner Class(插入类型)的不一样。

答:内部类就是一个在类的内部定义的类,内部类中不能定义静态成员。

静态成员不能访问非静态成员, 所以静态内部类不能访问外部类的非静态成员。

若是内部类使用了static修饰,该内部类就是静态内部类,也就是所谓的static nested class

若是内部类没有使用inner修饰,它就是Inner class

除此以外,还有一种局部内部类,在方法中定义的内部类就是局部内部类,局部内部类只在方法中有效。

对于Inner class而言,它属于实例成员,所以Inner class的实例必须寄生在外部类的实例中,所以程序在建立Inner Class实例以前,必须先得到它所寄生的外部类的实例。不然程序没法建立Inner Class的实例。

 

46.内部类能够引用它的外部类的成员吗?有没有什么限制?

答:内部类能够访问所在外部类的成员。

可是因为Java中,静态成员不能访问非静态成员,所以静态内部类(属于静态成员)就不能访问外部类的非静态成员。

 

47.Anonymous Inner Class(匿名内部类)是否能够extends(继承)其它类,是否能够implements(实现)interface(接口)

答:匿名内部类能够继承其余类或实现其它接口。

鉴于匿名内部类的特殊语法

new 父类、接口(){

类体实现部分

}

因此匿名内部类因为语法缘由必需要实现父类或接口。

 

48.super.getClass()方法调用

下面程序的输出结果是多少?

import java.util.Date;

public class Test extends Date{

       public static void main(String[] args) {

              new Test().test();

       }

       public void test(){

              System.out.println(super.getClass().getName());

       }

}

输出结果:Test

Super是一个限定词,当用super引用时,它也是引用当前对象自己,只是super限定了访问当前对象从父类那里获得成员变量和方法。

若是要访问父类的类名,应该使用以下语法:

Super.getClass().getSupserClass().getName();

 

49.JDK中哪些类是不可继承的?

答:不能继承的类是用final关键字修饰的类。

使用final关键字修饰的类,能够阻止被继承,不会有子类来重写该类的方法,彻底封闭起来,所以更安全。

50.String s = “Hello”;

s = s + “world!”;这两行代码执行后,原始String对象中的内容到底变了没有?

答:没有。String被设计成是一个不可变类。当第2行代码执行之后,s引用变量指向了一个新的对象,原来的内容为”Hello”直接量对象被存放在内存中。

建议使用StringBufferStringBuilder类。

 

51.是否能够继承String类?

答:String类是final类,被final关键字修饰,因此不能被继承。

 

52.如何把一段逗号分割的字符串转换成一个数组?

答:可使用String.split(“,”)方法使用String[]数组接收。

如:String [] result = "this,is,a,test".split(",");

其中result数组中存放了thisisatest等字符串元素。

 

53.下面这条语句一共建立了多少个对象:String s=”a”+”b”+”c”+”d”;

答:一个String对象。Java会在编译时对字符串相加进行优化处理,在编译时发现全部参与运算的都是字符串直接量,Java会把这个表达式的值计算出来。直接将该表达式的结果赋值给字符串引用变量。

对于以下代码:

String s1=”a”;

String s2=s1 + “b”;//对象+字符串=新的对象,和字符串常量池中的直接量没有关系

String s3=”a” + “b”;

System.out.println(s2 == “ab”);//false

System.out.println(s3 == “ab”);//true

字符串直接量会被放入字符串缓冲池中。

以下两行代码:

String s = “a” + “b” + “c” + “d”;

System.out.println(s == “abcd”);//true

因为s引用了字符串缓冲池中的”abcd”字符串,所以上面的输出结果为true

 

54.Collection集合框架中实现比较要实现什么接口。

:Java集合框架中须要比较大小的集合包括TreeMapTreeSet,其中TreeMap会根据key-value对中key的大小进行排序,而TreeSet则会对集合元素进行排序。

集合框架中比较大小有2种方式:

A.     天然排序

要求TreeMap中的全部key都实现Comparable接口。JDK不少类都已经实现了Comparable接口,如String,Date,BigDecimal等。

B.      定制排序

须要在建立TreeMapTreeSet时传入一个Comparator对象,Comparator只是一个接口,所以建立Comparator对象只能是建立它的实现类的对象,因此须要实现Comparator接口。

 

55.ArrayListVector的区别?

答:

Collection是接口,Collections是工具类。

相同点:这两个类都实现了List接口,List接口继承了Collection接口,它们都是有序集合。

(咱们能够按位置索引号取出某个元素,而且其中的数据是容许重复的,这是List集合规范制定的)

并且ArrayListVector底层都是基于数组的,所以它们的实现代码也大体类似。

区别:在于Vector是一个古老的集合,从JDK1.0开始就有了,所以它包含了大量方法名很长的方法。JDK1.2开始引入集合框架,引入List接口,才让Vector实现了List接口,所以又增长了一些List接口中定义的方法。

整体来讲,ArrayList能够彻底替代Vector,除了在一些很古老的API中强制要求使用Vector以外。

Vector还有一个特征,它是线程安全的,所以性能较差,而ArrayList并非线程安全的,所以性能较好。

实际上即便咱们要在多线程环境下使用List集合,也应该选择ArrayList而不是Vector,由于Java还提供了一个Collections工具类,它能够把ArrayList包装成线程安全的集合类,例如以下代码:

List list = Collections.synchronizedList(new ArrayList());

 

56.HashMapHashTable的区别

答:HashMapHashTable的区别相似于ArrayListVector的区别。

HashTableVector都是JDK1.0就有一个古老的集合,HashTable是一个继承自Dictionary(字典)类的古老集合。

JDK1.2引入集合框架的Map接口以后,JavaHashTable也实现了Map接口,所以HashTable也新增实现了一些Map接口中定义的方法。

实际上HashMapHashTable底层的实现很类似,它们都是基于Hash表的实现。

HashMapHashTable的区别主要有2点:

A.     HashMap容许null做为keyvalue,而HashTable不容许。

B.      HashMap是线程不安全的,所以性能较好。HashTable是线程安全的,所以性能较差。

实际上在多线程环境下,Java提供了Collection工具类把HashMap包装成线程安全的类,所以依然应该使用HashMap,以下代码所示:

Map map = Collections. synchronizedMap(new HashMap());

简单的说,编程时应该尽可能避免使用HashTable,它与HashMap的底层实现很类似,但除非在一个古老的API中强制要求HashTable

 

57.ListMap的区别?

答:List集合的特色:可重复,有序,有索引,程序能够经过元素的索引来读取元素,所以List至关于一个动态数组。

Map集合的特色:有Key-Value对,不容许重复,无序,无索引,程序能够根据key来取出对应的Value

深刻阐述:若是换个角度来看,咱们能够把List当成Map来看,List至关于key都是数值的Map,程序经过元素的索引来读取List集合时,彻底能够当成Map根据key来读取value。从另外一个角度看,Map也能够当成元素索引能够是任意类型的List集合。

 

58.List,Set,Map是否继承自Collection接口?

答:List,Set集合继承自Collection接口,Map集合很多继承自Collection接口。

 

59.List,MapSet三个接口,存取元素时,各有什么特色?

答:List集合:可重复,有序,有索引,实现类,ArrayList

       Set集合:不容许重复,无序,无索引

       对于Map集合而言,其底层存,取性能与Set集合彻底同样。其实Set集合自己就是基于Map实现的,除了有键值对之外。

 

60.说出ArrayListVectorLinkedList的存储性能和特性。

答:ArrayListVector都是使用数组方式存储数据,Vector因为使用了synchrnized(线程安全)的方法,所以性能较ArrayList差,而LinkedList使用了双向链表实现存储,因此插入速度较快,并且线程也是不安全的。LinkedList提供了一些方法,使得LinkedList能够被看成堆栈和队列来使用。

实际上Java提供了Collection集合的工具类,它能够把ArrayList,vector包装成线程安全的集合,所以在实际编程中应该避免使用Vector集合,它是一个古老的,在JDK1.0时代就出现的集合。

 

61.去掉一个Vector集合中重复的元素。

最简单的方式:HashSet set = new HashSet(vector);

       基于HashSet不容许重复的特性。

 

62.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==仍是equals()?它们有何区别?

答:Set只是一个接口,它的不一样实现类判断元素是否相等的标准是不一样的。笼统地说,Set里的元素是不能重复的,判断元素重复应该使用equals方法而不是==

对于HashSet而言,判断两个对象是否相等是经过equals()方法和hashCode()方法,只要两个对象经过equals()比较返回false,或两个对象的hashCode值不同,那么HashSet就会把它们当成不相同的元素。

对于TreeSet而言,判断两个对象是否相等的惟一标准是:两个对象经过compareTo(Object obj)比较是否返回0,与equals()方法无关。

 

63.你所知道的集合类都有哪些?主要方法?

答:最经常使用的集合接口是Set,List,Queue,它们都是Collection的子接口,除此以外还有Map接口。

对于Set集合而言,它的经常使用实现类包括HashSetTreeSet,HashSet还有一个子类,LinkedHashSet

对于List集合而言,它的经常使用实现类包括ArrayList,VectorLinkedList

对于Queue集合而言,它有一个子接口,表明双端队列,Deque,它的经常使用实现类包括ArrayDequeLinkedList

对于Map集合而言,它的经常使用实现类是HashMap,TreeMap,HashMap还有一个子类,LinkedHashMap

至于这些集合的方法,因为集合类也就是“容器类”,所以它的方法无非就是向容器中添加,删除,取出,遍历元素的方法。

List集合的元素都是有序,有索引的,所以它包括了大量根据索引来添加,删除,取出集合元素的方法。

对于Deque集合而言,因为它是双端队列,既能够当成队列使用,也能够当成栈使用,所以它增长栈,队列的方法,压栈和弹栈,如pushpopofferpeek等。

对于Map集合而言,它的方法无非就是根据key来添加,删除,取出value的方法。

 

64.两个对象值相同(x.equals(y)==true),但却能够有不一样的hash code,这句话对不对?

答:对。

由于equals方法和hashcode方法均可以由开发者来重写,所以它们是否相等并无必然的关系。

若是对象要保存在HashSet或者HashMap中,它们的equals相等,那么hashcode返回值也应该相等。

 

65.TreeSet里面放对象,若是同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,仍是使用子类的compareTo方法,仍是抛异常?

答:当前正在添加父类对象就屡次调用父类对象的CompareTo方法,当前正在添加子类对象就屡次调用子类对象的CompareTo方法。

至于程序是否抛出异常,则取决于CompareTo方法的实现,若是子类在实现CompareTo方法时,试图把被比较对象转换为子类对象以后再比较,若是TreeSet集合中已经包括了父类对象,这就会引发ClassCastException类型转换异常。

 

66.说出一些经常使用的类,包,接口,请各举5个。

答:经常使用的包有:

java.lang包下包括Math,System,StringBuilder,StringBuffer,Runtime,Thread,Runnable

Math数学,System系统,StringBuilder/StringBuffer,运行时类,线程类)

java.util包下包括List,Set,Map,以及这些接口的经常使用实现类,ArrayListLinkedList,HashSet,TreeSet,HashMapTreeMap

java.io包下包括

(字节流,字符流,缓冲流)

InputStream,OutputStream,Reader,Writer,FileInputStream,FileOutputStream,FileReader,FileWriter,BufferInputStream,BufferOutputStream,BufferReader,BuffWriter

Java.sql包下包括Connection,Statement,PrepareStatement,ResultSet等(建立链接对象,编译,预编译语句,结果集)

Java.net包下包括

Socket,ServerSocket,URL,URLConnection,DatagramPacker,DatagramSocket

Socket套接字)

 

67.java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以继承,请说出它们分别是那些类?

答:字节流和字符流,字节流由InputStream,OutputStream派生出来,字符流由Reader,Writer派生出来。java.io包中还有许多其它的流,主要是为了提升性能和使用方便。

 

68.字符流和字节流的区别。

答:字节流和字符流的区别是,它们的用法几乎彻底同样,区别在于字节流和字符流所操做的数据单元不一样,字节流操做的数据单元是8位的字节,而字符流操做的数据单元是16位的字符。

节流主要由InputStream,OutputStream做为基类,字符流主要由Reader,Writer做为基类。

字节流是基于字节输入,输出的,所以它的适用性更广。字符流则在处理文本内容时的输入,输出更加方便——不会出现只读取半个字符的状况。

Java提供了将字节流转换为字符串的InputStreamReader , OutputStreamWriter,但没有提供将字符流转化为字节流的方法。由于,字节流比字符流的使用范围更广,但字符流在处理字符的时候比字节流操做方便。若是有一个字节流,咱们知道它的内容是文本内容,所以把它转换成字符流来处理就会更方便一些。各有所需。

 

69.什么是Java序列化,如何实现Java序列化?或者请解释Serializable接口的做用。

答:序列化的目标是将对象保存到磁盘中,或容许在网络中直接传输对象,对象序列化机制容许把内存中的Java对象转换成平台无关的二进制流,持久保存到磁盘上,经过网络将这种二进制流传输到另外一个网络节点。其它程序一旦得到了这种二进制流,不管是从磁盘中获取仍是经过网络获取,均可以将这种二进制流恢复成原来的Java对象。

Serializable接口只是一个标记接口,实现该接口无需实现任何方法,实现了该接口的类就是可序列化的类。

序列化在Web开发中十分重要,Tomcat在某些时候须要把保存在Session中的对象序列化到硬盘,所以放入Session中的对象必须是可序列化的,这就能够经过Serializable接口来实现。还有,若是一个对象要通过网络传输(好比RMI远程方法调用的形参或返回值),这个对象也应该是可序列化的。

 

70.描述一下JVM加载class文件的原理机制?

答:

当程序主动使用某个类,若是该类还未必加载到内存中,系统会经过3个步骤来对该类进行初始化。加载,链接,初始化。

类加载指的当程序中使用任何类时,系统都会为之创建一个java.lang.Class类对象。

类的加载由加载器完成,类加载器一般由JVM提供,除此以外,开发者能够经过继承ClassLoader基类来建立本身的类加载器。

 

71.heapstack有什么区别?

答:stack指的是栈区,当程序进入一个方法时,系统会专门为这个方法分配一个内存空间,这块内存空间也被称为该方法栈区,该方法的栈区专门用于存储该方法中定义的局部变量,(括基本类型变量和引用变量)。当这个方法结束时,该方法栈区将会自动被销毁,栈区中的全部局部变量也会被销毁。

heap指的是堆,堆内存是Java虚拟机拥有的内存区。全部的Java对象都被放在堆内存中,位于堆内存中的Java对象由系统垃圾回收器负责跟踪管理——垃圾回收(GC),当堆内存中的对象没有引用变量引用它时,这个Java对象就变成了垃圾,垃圾回收器会在合适的时候回收它

 

72.try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,何时被执行,在return前仍是return后?

答:确定会执行,在return后执行。

Finally{}块的代码只有在try{}块中包含遇到System.exit(0;之类的致使Java虚拟机直接退出的语句才会不执行。

当程序执行try{}遇到return时,程序会先执行return语句,但并不会当即返回,而是把执行流程转到finally块,完成finally块的执行后就直接返回刚才return语句已经准备好的结果。

 

73.下面程序代码输出的结果是多少?

public class smallT

{

       public static void main(String args[])

       {

              smallT t = new smallT();

              int b = t.get();

              System.out.println(b);

       }

       public int get()

       {

              try

              {

                     return 1 ;

              }

              finally

              {

                     return 2 ;

              }

       }

}

输出结果是:2

Java会把return语句先执行完,把全部须要处理的东西都先处理完成,可是还未返回以前,程序流程会转去finally块。但若是在执行finally块时遇到了return语句,那么程序会直接使用finally块中的return语句来返回,所以上面程序会输出2

 

74.final,finally,finalize的区别。

答:final最终的,finally最后,finalize完成。

Final是一个修饰符,它能够修饰类,方法,变量。

final修饰类代表这个类不能够被继承,final修饰方法时代表这个方法不能够被其子类重写(重写就是覆盖Override.finalfinal修饰变量可分为局部变量,实例变量,静态变量。)

final修饰局部变量时,该局部变量能够被赋值一次。当final修饰实例变量时,实例变量必须由程序在构造器,初始化块,定义时3个位置的其中之一指定初始值。当final修饰静态变量时,静态变量必须由程序在静态初始化块,定义时这2个位置的其中之一指定初始值。

Finally是异常处理语句结构的一部分,表示总会执行的代码块。

FinalizeObject类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。但实际上重写此方法进行资源回收并不安全,由于JVM并不保证该方法总被调用。

 

75.运行时异常与通常异常有何异同?

答:Checked检查异常就是通常异常,体现了Java的设计哲学,没有完善错误处理的代码根本不会被执行。

通常异常的处理方式有2种,

A.     当前方法知道如何处理异常,程序应使用try…catch块来捕获异常,而后在对应的catch块中修补该异常。

B.      当前方法不知道如何处理异常,应该在定义方法时声明抛出该异常。Throw Exception

Runtime异常对比处理更加灵活,Runtime异常无需显式声明抛出,若是程序须要捕捉Runtime异常,也可使用try…catch块来捕捉runtime异常。

 

76.errorexception有什么区别?

答:Error错误,通常是指虚拟机相关的问题,如系统崩溃,虚拟机出错,动态链接失败等。这种错误没法恢复或不能被捕获,将致使应用程序中断。

Exception异常,表示一种设计或实现问题。也就是说,程序员应该对这些状况进行考虑,并提供相应的处理。

 

77.Java中的异常处理机制的简单原理和应用。

答:程序运行过程当中可能出现各类非预期状况,这种非预期状况可能致使程序非正常结束。为了提升程序的健壮性,Java提供了异常处理机制。

Java对异常进行了分类,不一样类型的异常分别用不一样的Java类表示,全部异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error错误和Exception异常,Error错误通常是指虚拟机相关的问题,如系统崩溃,虚拟机出现错误,动态链接失败等。这种错误没法恢复或不能捕获,将致使应用程序中断。一般应用程序没法处理这种错误,所以不能使用try…catch{}块来捕获Error对象。

Exception表示一种设计或实现问题,也就是说,程序员应该对这些状况进行考虑,并提供相应的处理。

异常分为运行时异常和通常检查异常,通常检查异常体现了Java的设计哲学,没有完善错误的代码根本就不会被执行。

对于通常检查异常的处理方式有两种:

A. 当前方法知道如何处理异常,程序应使用try…catch块来捕获异常,而后在对应的catch块中修补该异常。

B. 当前方法不知道如何处理异常,应该在定义方法时声明抛出该异常。

实际上Java的通常异常后来争议不断,由于通常异常要求程序员要么显式声明抛出,要么进行捕捉,不能对通常异常漠不关心,这就给编程带来了必定的复杂度。

好比SpringHibernate框架的一大特色就是把通常异常包装成了运行时异常。

运行时异常则比较灵活,开发者既能够选择捕获运行时异常,也能够不捕获。

 

78.请写出你最多见到的5runtime exception.

答:对于一个有1—2年左右编程经验的人来讲,总会遇到一些常见的异常。

其中有些就是

Runtime Exception运行时异常

NullPointerException空指针异常:当调用一个未初始化的引用变量的实例Field,实例方法时都会引起该异常。

ArithmeticException算术异常:好比5/0将引起异常。

ArrayIndexOutOfBoundsException数组索引越界异常

ClassCastException类型转换异常

IllegalArgumentException参数非法的异常

79.Java语言如何进行异常处理,关键字:throws ,throw ,try ,catch ,finally分别表明什么意义?在try块中能够抛出异常吗?

答:try块表示程序正常的业务执行代码。若是程序在执行try块的代码时出现了“非预期”状况,JVM将会生成一个异常对象,这个异常对象将会被后面相应的catch块捕获。

Throw用于手动抛出异常对象。Throw后面须要一个异常对象。

Throws用于在方法签名中声明抛出一个或多个异常类throws关键字后能够紧跟一个或多个异常类。

Finally块表明异常处理流程中总会执行的代码块。

对于一个完整的异常处理流程,try块是必须的,try块后能够紧跟一个或多个catch块,最后还能够带一个finally块。

Try块中能够抛出异常。

 

80.Java中有几种方法能够实现一个线程?用什么关键字修饰同步方法?stop()suspend()方法为什么不推荐使用?

答:在java5之前,有以下两种

A. 继承Thread类,重写它的run()方法。

代码以下:

new Thread()

{

       public void run()

       {

              //线程执行体

       }

}.start();

C.     实现Runnable接口,并重写它的run()方法。

new Thread(new Runnable()

{

       public void run()

       {

              //线程执行体

       }     

}).start();

从上面代码不难看出,线程的执行体是一个run()方法,而后程序经过start()方法启动一条线程。

Java5开始,Java提供了第三种方式来建立多线程:实现Callable接口,并实现Call()方法。Callable接口至关于Runnable接口的加强版,由于Callable接口中定义的call()方法既拥有返回值,也能够声明抛出异常。

代码以下:

new Thread(new FutureTask<Object >(new Callable<Object>()

{

       public Object call() throws Exception

       {

              //线程执行体

       }

})).start();

不只如此,Java5还提供了线程支持,ExecutorService对象就表明了线程池,若是开发者利用ExecutorService来启动线程,ExecutorService底层会负责管理线程池。此时,开发者只要把Runnable对象传给ExecutorService便可。以下代码:

ExecutorService pool = Executors.newFixedThreadPool(3)

pool.execute(new Runnable()

{

       public void run()

       {

              //线程执行体

       }     

});

若是执行经过Callable方式实现的线程,则可按以下代码:

ExecutorService pool = Executors.newFixedThreadPool(3)

pool.execute(new FutureTask<Object >(new Callable<Object>()

{

       public Object call() throws Exception

       {

              //线程执行体

       }

}));

 

synchronized关键字修饰同步方法。须要指出的是,非静态的同步方法的同步监视器是this,也就是调用该方法的对象,而静态的同步方法的同步监视器是该类自己。所以使用synchronized修饰的静态方法,非静态方法的同步监视器并不相同,只有基于同一个同步监视器的同步方法,同步代码块才能实现同步。

使用stop()中止方法不安全。它会解除由线程获取的全部锁定,并且若是对象处于一种不连贯状态,那么其余线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。

Suspend()延迟方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这以前得到的锁定。此时,其余任何线程都不能访问锁定的资源,除非被“挂起”的线程恢复运行。对任何线程来讲,若是它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会形成死锁。因此不该该使用suspend(),而应在本身的Thread类中置入一个标志,指出线程应该活动仍是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()从新启动线程。

 

82.sleep()wait()又什么区别?

答:sleep()Thread类的静态方法,它的做用是让当前线程从运行状态转入,阻塞状态,线程执行暂停下来,当一个线程经过sleep()方法暂停以后,该线程并不会释放它对同步监视器的加锁。

Wait()Object对象的方法,但实际上只有同步监视器才能调用该方法。当程序在同步代码块,或同步方法内经过同步监视器调用该方法时,将会致使当前线程释放对该同步监视器的加锁,而该线程则会进入该同步监视器的等待池中,直到该同步监视器调用notify()(通知)或notifyAll()来通知该线程。

 

83.同步和异步有何异同,在什么状况下分别使用它们?举例说明。

答:同步,对于一个银行帐户,若是有多个线程试图去访问这个帐户时,若是不对多个线程进行同步控制,有可能帐户余额只有1000块,但多个线程都试图取款800块时,这些线程同时判断余额以后,都会显示余额足够,从而致使每一个线程都取款成功。这显然不是咱们但愿看到的结果。

当程序试图执行一个耗时操做时,程序不但愿阻塞当前执行流,所以程序也不该该试图当即获取该耗时操做返回的结果,此时就使用异步编程了,典型的应用场景就是Ajax。当浏览器经过JavaScript发出一个异步请求以后,JavaScript执行流并不会停下来,而是继续向下执行,这就是异步。程序会经过监听器来监听远程服务器响应的到来。

 

84.多线程有几种实现方法?同步有几种实现方法?

答:

多线程的实现方法:

Java5之前,有以下两种:

第一种,继承Thread类,重写它的run()方法。

第二种,实现Runnable接口,并重写它的run()方法。

线程的执行体是一个run()方法,而后程序经过start()方法启动一条线程。

Java5开始,Java提供了实现Callable接口来建立多线程,并实现call()方法。Callable接口至关于Runnable接口的加强版,由于Callable接口中定义的call()方法既拥有返回值,也能够声明抛出异常。

不只如此,Java5还提供了线程支持,ExecutorService对象就表明了线程池。开发者只要把Runnable对象,传给ExecutorService便可。

同步的实现方法:

同步方法:使用synchronized关键字修饰方法,因为java的每个对象都有一个内置锁,在调用该方法前须要得到内置锁,不然就处于阻塞状态。

同步代码块:有synchronized关键字修饰的语句块。

使用特殊域变量volatile实现线程同步,须要同步的变量加上volatile

使用重入锁实现线程同步,建立一个ReentrantLock的实例,得到锁lock(),释放锁unlock()

使用局部变量实现线程同步,若是使用ThreadLocal管理变量,则每个使用该变量的线程都得到该变量的副本,副本之间相互独立,这样每个线程均可以随意修改本身的变量副本,而不会对其余线程产生影响。

注:ThreadLocal与同步机制

A. ThreadLocal与同步机制都是为了解决多线程中相同变量的访问冲突问题。

B. 前者采用以“空间换时间”的方法,后者采用以“时间换空间”的方式。

 

85.启动一个线程是用run()仍是start()?

答:启动一个线程是调用start()方法,使线程就绪状态,之后能够被调度为运行状态。run()方法是线程的线程执行体——也就是线程将要完成的事情。

 

86.当线程进入一个对象的一个synchronized方法后,其余线程是否能够进入此对象的其余方法?

答:当线程进入一个对象的synchronized方法以后,其余线程彻底有可能再次进入该对象的其余方法。

不过要分几种状况来看:

1.      若是其余方法没有使用synchronized关键字修饰,则能够进入。

2.      若是当前线程进入的synchronized方法是static方法,其余线程能够进入其余synchronized修饰的非静态方法,若是当前线程进入的synchronized方法是非static方法,其余线程能够进入其余synchronized方法。

3.      若是两个方法都是静态方法,或者都是非静态方法,而且都使用了synchronized修饰,但只要在该方法内部调用了同步监视器的wait(),则其余线程依然能够进入其余使用synchronized方法修饰的方法。

4.      若是没有调用wait(),其余线程不能进入其余使用synchronized方法修饰的方法。

 

87.线程的基本概念,线程的基本状态以及状态之间的关系。

答:线程是进程的组成部分,一个进程能够拥有多个线程,一个线程必须有一个父进程。线程能够拥有本身的堆栈,本身的程序计数器和本身的局部变量,但再也不拥有系统资源,它与父进程的其余线程共享该进程所拥有的所有资源。由于多个线程共享父进程里的所有资源,所以编程更加方便;但必须更加当心,咱们必须确保线程不会妨碍同一进程里的其余线程。

线程的执行须要通过以下状态:

新建线程new

就绪start()

运行

阻塞sleep()

死亡stop()

各状态的转换关系以下图所示:

 

 

88.简述synchronizedjava . util .concurrent .locks .Lock的异同

答:主要相同点:Lock能完成synchronized所实现的全部功能。

主要不一样点:Lock有比synchronized更精确的线程语义和更好的性能Synchronized会自动释放锁,Lock必定要求程序员手工释放,而且必须在finally从句中释放。Lock还有更强大的功能,它tryLock方法能够非阻塞方式去拿锁

 

Java代码查错部分

1.

abstract class Name {

   private String name;

   public abstract boolean isStupidName(String name) {}

}

答:错。abstract方法必须以分号;结尾,并且不带花括号{}

 

2.

public class Something {

   void doSomething () {

       privateString s = "";

       int l = s.length();

   }

}

有错吗?

 

答:错。局部变量前不能放置任何修饰符(private,public,protected),final能够用来修饰局部变量。

1.     面向对象的特征有哪些方面?

答:

1.      继承

经过继承容许复用已有的类。继承关系是一种通常到特殊的关系,好比苹果类继承水果类,这个过程称为类继承。

子类能够从父类那里继承获得方法和成员变量,并且子类能够修改或增长新的方法使之适合子类的须要。

2.      封装

封装是把对象的状态数据隐藏起来,再经过暴露合适的方法来容许外部程序修改对象的状态数据。Java的封装主要经过private,protected,public等访问控制符来实现。

3.      多态

多态指的是同一个类型的引用类型的变量执行相同的方法时,实际上会呈现出多种不一样的行为特征

多态增长了编程的灵活性,实际上大量设计模式都是基于多态类实现的。

4.      抽象

抽象就是忽略与当前目标无关的方面,以便更充分的突出与当前目标有关的方面。

抽象包括两个方面,一是过程抽象,二是数据抽象

 

2.      Java中实现多态的机制是什么?

答:Java容许父类或接口定义的引用变量指向子类或具体实现类的实例对象

(致使编译时引用变量指向的方法和程序在内存里运行时实例对象调用的方法不一致。)

程序调用的方法在运行时才动态绑定,就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

 

3.      一个.java源文件中是否能够包括多个类(不是内部类)?有什么限制?

答:能够有多个类,可是只能有一个有public修饰的类,而且public类的类名必须与文件名相同。包含多个类的.java源文件编译以后会产生多个.class文件。

 

4.      String是最基本的数据类型吗?

答:不是。

最基本的数据类型有:byte,short,int,long,char,float,double,Boolean

Stringjava.lang.String 类,属于引用类型

(所谓的引用类型包括:类,接口,数组。

由于Stringfinal修饰的类,是不可继承的类。而且是一个不可变类。所以若是程序须要使用的字符串所包含的字符序列须要常常改变,建议使用StringBuffer(线程安全,性能略差)类或者StringBuilder(线程不安全,性能好)类。)

 

5.    Java有没有goto (转到)

答:没有。由于gotoJava的保留字,暂时不是Java的关键字。

 

6.    intInteger有什么区别?

答:intJava的基本数据类型,IntegerJavaint提供的包装类(封装类)。Integer包装类具备面向对象的特征。

Java5开始,Java提供了自动装箱,自动拆箱功能。所以包装类也能够直接参与表达式运算,所以使用起来十分方便。

(Java为每一个原始类型提供了包装类。

JSP开发中,Integer的默认值为null,因此用EL输出nullInteger时,会显示空白字符串,而int的默认值为0,因此int不适合做为Web层的表单数据的类型。

另外,Integer提供了多个与整数相关的操做方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。)

 

7.StringStringBufferStringBuilder的区别?

答:

StringBuffer是线程安全的,性能较差,而StringBuilder是线程不安全的,适合单线程环境使用,性能较好。

String表明了字符序列不可变的字符串,而StringBufferStringBuilder表明了字符序列可变的字符串。

(它们都是CharSequence(字符序列)的实现类,均可以做为字符串使用。

)

 

8.CollectionCollections的区别?

答:Collection是集合类(List集合,Set集合,Queue队列)的根接口。

Collections是针对集合类的一个工具类,它提供一系列静态方法实现对各类集合的搜索,排序,线程安全化等操做。

 

9.说说&&&的区别?

       答:

&&&均可以用做逻辑与的运算符,&当运算符两边的表达式的结果都为true时,整个运算结果才为true,不然,只要有一方为false,则结果为false

       双与有短路的功能,也称短路与。若是第一个表达式为false,则再也不计算第二个表达式了。实际开发中能够用来把要比较的表达式放后面,排除报空指针异常的状况。

       而单与在第一个表达式为false时,还会计算第二个表达式,因此性能略慢。

       除此以外,&还能够用做位运算符,当&操做符两边不是boolean类型时,&表示按位与操做。

 

10.OverloadOverride的区别。

Overloaded的方法是否能够改变返回值的类型?

答:Overload是方法的重载。(load 加载)

       Override是方法的重写,也叫覆盖。

Overload要求两个方法具备方法名相同,形参列表不一样的要求,返回值类型不能做为重载的条件。

              Override要求子类方法与父类方法具备“两同两小一大”的要求。

       两同:父类方法,子类方法的方法名形参列表相同。

       两小:子类方法的返回值类型要么是父类方法返回值类型的子类,要么返回值类型相同。

       子类方法的抛出异常类型要么是父类方法抛出异常类型的之类,要么异常类型相同。

       一大:子类的访问权限要么比父类的大,要么相同。

Overloaded方法能够改变返回值的类型。

 

11.Java如何跳出当前的多重嵌套循环?

答:能够在外面的循环语句前定义一个标号,而后在里层循环体的代码中使用带有标号的break语句,便可跳出外层循环。

例如:

       Outer:

       for(int i=0;i<10;i++)

       {

              for(int j=0;j<10;j++)

              {

                     System.out.println(“i=” + i + “,j=” + j);

                     if(j == 5) break Outer;

              }

       }

 

12.switch语句(判断选择)可否做用在byte上,可否做用在long上,可否做用在String上?

答:在Java1.7之前,能够做用在char,byte,short,int以及对应的包装类上。

Java1.7之后,switch中能够是字符串类型,因此能够做用在String上。

也能够是枚举类型,在Java1.7之前以及之后都不能做用在longdoublefloatboolean以及对应的包装类上。

longdoublefloatlong比较特殊)

 

13.String s = new String(“xyz”);建立了几个String Object?

答:两个。一个是直接量的xyz对象,另外一个是经过new String()构造器建立出来的String对象。一般来讲,应该尽可能使用直接量的String对象,这样具备更好的性能。

直接量就是程序中直接使用的数据值。

 

14.数组有没有length()这个方法?String有没有length()这个方法?

答:数组没有length()这个方法,只有length这个属性。Stringlength()方法。

Length长度。

 

15.short s1 = 1;s1 = s1 + 1;有什么错?short s1 = 1;s1+=s1有什么错?

答:s1 + 1 在运算时会自动提高表达式的类型,s1 + 1结果是int型,但复制给short类型的s1时,编译器将报告须要强制转换类型的错误。

第二个,因为+=运算符里已经包括了一个隐式的强制类型转换,所以它不会有任何错误。

 

16.char型变量中能不能存储一个中文字符?为何?

答:char型变量是用来存储Unicode编码的字符的,Unicode编码字符集中包含了汉字,所以char型变量中能够存储汉字。

不过,若是某个特殊汉字没有被包含在Unicode编码字符集中,那么,char型变量中不能存储这个特殊汉字。

此外,char类型的变量占两个字节,而Unicode编码中每一个字符也占两个字节。所以char型变量能够存储任何一个Unicode字符。

Unicode又称统一码。

 

17.用最有效率的方法算出2乘以8等于几?

答:2<<3 <<,箭头向左,是左移运算符,>>,箭头向右,是右移运算符

由于将一个数左移n位,就至关于乘以了2n次方;那么,一个数乘以8只要将其左移3位便可,23次方,而CPU直接支持位运算,效率最高。

可是须要注意的是,若是这个数字自己已经很大,好比自己已是230次方了,此时再使用这种位移运算就可能致使“溢出”,这样就得不到正确的结果了。

 

18.使用final关键字修饰一个变量时,是引用不能变,仍是引用的对象不能变?

答:使用final关键字修饰一个变量时,是指被修饰的引用变量不能变,引用变量所指向的对象的内容是能够改变的。

例如,对于以下语句:

final StringBuilder a=new StringBuilder ("immutable");

执行以下语句将报告编译错误:

a = new StringBuilder ("");

但以下语句则是彻底正确的

a.append("fkjava.org");

有人但愿在定义方法的形参时,经过final修饰符来阻止方法内部修改传进来的实参:

public void method(final StringBuilder param)

{

}

实际上这没有用,在该方法内部仍然能够增长以下代码来修改实参对象:

param.append("fkjava.org");

 

19.”==”equals方法究竟有什么区别?

答:通俗地讲,”==”比较左右是否是一个东西,equals是比较左右是否是长得同样。

==操做符的功能有两个:

A. 若是==的两边是基本类型的变量,包装类对象所组成的表达式,==用于比较两边的表达式的值是否相等,若是值相等,即便数据类不一样,也会返回true

B. 若是==的两边是引用类型的变量,==用于判断这两个引用类型的变量是否引用同一块内存,只有它们引用同一块内存时,==才会返回true

C. equals()则是java.lang.Object类的一个方法,所以任何Java对象均可以调用此方法与其它对象进行比较。

D. 开发者重写equals()方法就能够根据业务要求来决定这两个对象是否“相等”。

 

20.静态变量和实例变量的区别?

答:A.在语法定义上的区别,静态变量前要加static关键字,而实例变量前则不加。

       B.在程序运行时的区别,实例变量属于一个对象,必须先建立实例对象,它的实例变量才会被分配空间,才能使用这个实例变量。静态变量则属于类,只要程序加载了类的字节码,不用建立任何实例对象,静态变量就会被分配空间,静态变量就能够被使用了。

总之,实例变量必须建立对象后才能够经过这个对象来使用,静态变量则能够直接使用类名来引用。

       C.在内存中,static修饰的类变量只能有一个,而实例变量每建立一个实例对象就能够分配一个。

 

21.是否能够从一个static方法内部调用非static方法?

答:不能够,静态成员不能够调用非静态成员。

static方法属于对象,必须建立一个对象后,才能够经过该对象来调用实例方法。

static方法调用时不须要建立对象,经过类就能够调用该方法。

也就是说,当一个static方法被调用时,可能尚未建立任何实例对象。

所以Java不容许static方法内部调用非static方法。

 

22.Math.round(11.5)等于多少?Math.round(-11.5)等于多少?

答:Math类中提供了三个与取整有关的方法:ceil,floor,round,这些方法的做用与它们的英文名称的含义相对应。Ceil:天花板,向上取整Math.ceil(11.3)=12,Math.ceil(-11.3)=-11

Floor:地板,向下取整Math.floor(11.6)的结果为11Math.floor(-11.6)=-12

Round:表示“四舍五入”,Math.round(11.5)=12,Math.round(-11.5)=-11

 

23.请说出做用域public,private,protected,以及不写时的区别。

答:这四个做用域的可见范围以下表所示。

做用域    当前类   同一package    子类    全局

public                                  

protected                              ×  

default                           ×      × 

private                               

若是在修饰的元素上面没有写任何访问修饰符,则表示default

访问权限由大到小是:public,protected,default,private

Java存在的4个访问范围:全局,子类,同一个package,当前类

 

24.外部类能用private,protected修饰吗?内部类能够用privateprotected修饰吗?

答:外部类不能用private,protected修饰。内部类能用private,protected修饰。

外部类的上一级程序单位是包package,所以它只能有两个使用范围:包内和包外,所以它只能使用public(表示能够在全局位置访问),和默认修饰符default(表示只能被同一个包内的其它类使用)修饰。

 

25.一个类定义多个重载方法,参数分别是intchar,和double,而后将double x=2传递进去,会选择哪一个方法?

答:选择参数类型为double的方法。

 

26.说说has a(有)与is a(是)的区别。

答:is a是典型的“通常到特殊“的关系,也就是典型的继承关系。例如Apple is a Fruit.。苹果是水果。Apple是一种特殊的Fruit,也就是说Apple继承了Fruit

has a是典型的“组合“关系。好比Wolf has a Leg.狼有腿。也就是Leg组合成了Wolf

须要指出的是:因为继承会形成对父类的破坏,所以有时候能够经过组合来代替继承。

使用继承的好处:程序语义更好理解。坏处是:子类可能重写父类方法,不利于父类封装。

使用组合则形成语义的混淆,但组合类不会重写被组合类的方法,所以更利于被复合类封装。

 

27.ClassLoader如何加载Class?

答:JVM(Java虚拟机)里有多个类加载,每一个类加载能够负责加载特定位置的类。

除了bootstrap以外,其它的类加载器自己也是java类,它们的父类是ClassLoader

 

28.Java抽象类的做用。

答:抽象类更利于代码的维护和重用。

抽象类的特色:1.拥有抽象方法。

                       2.抽象方法和抽象类都必须被abstract关键字修饰。

                       3.抽象类不能够建立实例和实例化对象,由于抽象类自己是不完整的。

                       4.抽象类的抽象方法要被使用,必须由子类重写全部父类抽象类的抽象方法,创建子类对象调用。(若是子类只重写(覆盖)了部分抽象方法,那么该子类仍是一个抽象类)

抽象类比通常类多了抽象方法。

 

28.GC是什么?为何要有GC?

答:GC是垃圾收集的意思,是Java的垃圾回收机制。

内存处理是编程人员容易出现问题的地方,Java提供的GC功能能够自动监测对象是否超过做用域从而达到自动回收内存的目的。

JavaSystemRuntime类都提供了“通知“程序进行垃圾回收的方法。

JVM什么时候来进行垃圾回收,仍是由JVM本身来决定。

 

29垃圾回收的优势和原理。并考虑2种回收机制。

答:

1.Java语言最显著的特色就是引入了垃圾回收机制,它使java程序员在编写程序时再也不考虑内存管理的问题。

2.因为有垃圾回收机制,Java中的对象再也不有“做用域“的概念,只有引用的对象才有做用域。

3.垃圾回收机制有效的防止了内存泄漏,能够有效的使用可以使用的内存。

4.垃圾回收器一般做为一个单独的低级别的线程运行,在不可预知的状况下对内存堆中已经死亡的或很长的时间没有用过的对象进行清除和回收。

5.程序员不能实时的对某个对象或全部对象调用垃圾回收器进行垃圾回收。

 

垃圾回收机制有分代复制垃圾回收,标记垃圾回收,增量垃圾回收。

 

30.垃圾回收器的基本原理是什么?垃圾回收器能够立刻回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?

答:对于Java程序中对象而言,若是这个对象没有任何引用变量引用它,那么这个对象不能被程序访问,所以可认为它是垃圾。

1.      只要有1个以上的引用变量引用该对象,该对象就不会被垃圾回收。

2.      对于Java的垃圾回收器来讲,它使用“有向图“来记录和管理堆内存中的全部对象,经过这个有向图就能够识别哪些对象是”可达的“(有1个引用变量引用该对象),哪些对象是”不可达的“,全部不可达的对象就会被垃圾回收。

3.      程序员能够手动执行System.gc(),通知GC运行,但这只是一个通知,而JVM依然有权决定什么时候进行垃圾回收。

 

31.何时用assert

答:assertJDK1.4新增的关键字。

assertion断言在软件开发中是一种常见的调试方式,不少开发语言中都支持这种机制。在实现中,assert就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true,若是该值为false,说明程序已经处于不正确的状态下,assert将给出警告或退出。

Javaassert是关键字。

Java命令默认不启动断言,

为了启动用户断言,应该在运行java命令时增长-eaEnable Assert)选项。

为了启动系统断言,应该在运行java命令时增长-esaEnable System Assert)选项。

 

32.Java中会存在内存泄漏吗?请简单描述。

答:什么是内存泄漏:程序运行过程当中会不断地分配空间;那些再也不使用的内存空间应该即时回收它们,从而保证系统能够再次使用这些内存。若是存在无用的内存没有被回收回来,那就是内存泄漏。

 

33.能不能本身写个类,也叫java.lang.String?

答:能够,但在应用的时候,须要用本身的类加载器去加载,不然,系统的类加载器永远只是去加载jre.jar包中的那个java.lang.String

但在Tomcatweb应用程序中,都是由webapp本身的类加载器先本身加载WEB-INF/classes目录中的类,而后才委托上级的类加载器加载,若是咱们在Tomcatweb应用程序中写一个java.lang.String,这时候Servlet程序加载的就是咱们本身写的java.lang.String。但这样作就会出不少潜在的问题,原来全部用了java.lang.String类都将出现问题。

 

34.ArrayList如何实现插入的数据按自定义的方式有序存放?

答:编程思路:实现一个类对ArrayList进行包装,当程序试图向ArrayList中放入数据时,程序将先检查该元素与ArrayList集合中其余元素的大小,而后将该元素插入到指定位置。

 

35.序列化接口的id有什么用?

答:(对象的序列化:把对象转换为字节序列的过程.

       对象的反序列化:把字节序列恢复为对象的过程。

       对象的序列化主要有两种用途:

1.      把对象的字节序列永久地保存到硬盘上,一般放在一个文件中。

2.      在网络上传送对象的字节序列。

在不少应用中,须要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。)

反序列化Java对象时必须提供该对象的class文件,如今的问题是随着项目的升级,系统的class文件也会升级,Java如何保证两个class文件的兼容性?

Java序列化机制容许为序列化类提供一个UID,也就是说若是一个类升级后,只要它的id值保持不变,序列化机制也会把它们当成同一个序列化版本。

(序列化类的id是为了在进行项目升级时,保证系统的两个class文件的兼容性,不会致使重复和冲突。)

 

36.hashCode()方法的做用?

答:hashCode()方法与equals()方法相似。都容许用户定义子类重写这两个方法。

equals()主要判断两个对象表面上或者内容上看是否相同。

hashCode方法的判断就要严格的多。

若是两个对象的hashCode()相等,便可认为这两个对象是相等的。

所以当咱们重写一个类的equals()方法时,也应该重写它的hashCode()方法。并且这两个方法判断对象的标准也应该是同样的。

 

37.编写一个函数将十六进制的字符串参数转换成整数返回。

String str = “13abf”;

Int len = str.length;

Int sum = 0;

Integer.parseInt(str,16);

 

parseInt方法提供了把16进制字符串参数转换成整数返回的方法。

 

38.银行还款问题

银行贷款的还款方式中最经常使用的是一种叫“等额本息”,还款法,即借款人在约定还款期限内的每一期(月)归还的金额(产生的利息+部分本金)都是相等的,现有一笔总额为T元的N年期住房贷款,年利率为R,要求算出每一期的还款的本金和利息总额,请写出解决思路和任意一种编程语言实现的主要代码。

       思路:既然是按月还款,那我就要将N年按月来计算,即要还N*12个月,这样就能够求出每个月要还的本金。因为每个月要还的那部分本金所欠的时间不一样,因此,它们所产生的利息是不一样的,该部分本金的利息为:部分本金额*所欠月数*月利率。应该是这么个算法,若是利息还计利息,若是月还款不按年利率来算,老百姓算不明白的。

 

39.*任意数字序列“123456”之类,输出它们全部的排列组合

答:String str = "fkjav";

       char[] arr1 = str.toCharArray();

       char[] arr2 = java.util.Arrays.copyOf(arr1,arr1.length);

       for(int i=0;i<arr1.length-1;i++)

       {

              for(int j = i+1;j<arr2.length;j++){

                     System.out.println(arr1[i] + "," + arr2[j]);

              }

       }

 

40.构造器Constructor是否可被override

答:构造器Constructor不能被继承,所以不能重写Override,但能够被重载Overrload(形参列表不一样)

 

41.接口是否能够继承接口?抽象类是否能够实现(implements)接口?抽象类是否能够继承具体类(concrete class)?抽象类中是否能够有静态的main方法?

答:接口能够继承接口。

       抽象类能够实现接口。

       抽象类能够继承具体类。

       抽象类中能够有静态的main方法。

归法:抽象类的特征是有得有失,获得的功能是抽象类能够拥有抽象方法(固然也能够没有);失去的功能是抽象类不能建立实例了。至于其余的,抽象类与普通类在语法上大体是同样的。

(抽象类除了不能建立实例,只要普通类能够的它均可以。)

 

42.clone()方法时,一般都有一行代码,是什么?

答:clone故名思意就是复制,当对象调用此方法,就会在内存中分配一个和源对象一样大小的空间,在这个空间中建立一个新的复制对象。

clone有缺省(默认)行为,super.clone();

由于首先要把父类中的成员复制到位,而后才是复制本身的成员。

 

43.abstract class interface有什么区别?

答:抽象类和接口的语法区别:

接口能够说成是抽象类的一种特例,接口中全部方法都必须是抽象的。

1.一个类能够实现多个接口,但只能继承一个抽象类。

1.接口是完全的抽象类。抽象类能够包含非抽象的普通方法,接口中的全部方法必须都是抽象的。

2.抽象类能够有构造器,接口中不能有构造器。

3.抽象类中能够有实例成员变量,接口中没有实例成员变量。

4.抽象类中的抽象方法的访问类型能够是public , protected和默认访问权限。但接口中的抽象方法只能是public类型的。

5.抽象类中能够包含static静态方法,接口中不能包含static静态方法。

6.抽象类和接口均可以包含静态成员变量,但抽象类的静态成员变量的访问类型能够是任意,而接口的静态成员变量的访问类型只能是public static final

二者在应用上的区别:

接口体现的是一种规范,而抽象类在代码实现方面发挥做用,能够实现代码的重用。

例如,模板设计模式是抽象类的一个典型应用。假设项目中须要大量的DAO组件,这些组件一般都有增,删,改,查等基本方法。所以咱们就能够定义一个抽象的DAO基类,而后让其它DAO组件来继承这个抽象的DAO基类,把这个DAO基类当成模板使用。

 

44.abstract抽象的method方法是否可同时是static,是否可同时是native(原生态方法,方法对应的实现不在当前文件,而是在其余语言(c,c++)实现的文件中),是否可同时是synchronized同步的?

答:抽象的方法不能够是static的,由于抽象方法要被子类实现。

native方法表示该方法要用另外一种依赖平台的编程语言实现,不存在着被子类实现的问题,因此,它也不能是抽象的。

Synchronized同步锁与abstract不能同时使用,它修饰一个方法时,表示将会使用该方法的调用者做为同步监视器。但abstract方法所在的类是抽象类,不能建立实例,所以没法肯定synchronized修饰方法时的同步监视器。

 

45.什么是内部类?Static Nested Class(静态嵌入类型)和 Inner Class(插入类型)的不一样。

答:内部类就是一个在类的内部定义的类,内部类中不能定义静态成员。

静态成员不能访问非静态成员, 所以静态内部类不能访问外部类的非静态成员。

若是内部类使用了static修饰,该内部类就是静态内部类,也就是所谓的static nested class

若是内部类没有使用inner修饰,它就是Inner class

除此以外,还有一种局部内部类,在方法中定义的内部类就是局部内部类,局部内部类只在方法中有效。

对于Inner class而言,它属于实例成员,所以Inner class的实例必须寄生在外部类的实例中,所以程序在建立Inner Class实例以前,必须先得到它所寄生的外部类的实例。不然程序没法建立Inner Class的实例。

 

46.内部类能够引用它的外部类的成员吗?有没有什么限制?

答:内部类能够访问所在外部类的成员。

可是因为Java中,静态成员不能访问非静态成员,所以静态内部类(属于静态成员)就不能访问外部类的非静态成员。

 

47.Anonymous Inner Class(匿名内部类)是否能够extends(继承)其它类,是否能够implements(实现)interface(接口)

答:匿名内部类能够继承其余类或实现其它接口。

鉴于匿名内部类的特殊语法

new 父类、接口(){

类体实现部分

}

因此匿名内部类因为语法缘由必需要实现父类或接口。

 

48.super.getClass()方法调用

下面程序的输出结果是多少?

import java.util.Date;

public class Test extends Date{

       public static void main(String[] args) {

              new Test().test();

       }

       public void test(){

              System.out.println(super.getClass().getName());

       }

}

输出结果:Test

Super是一个限定词,当用super引用时,它也是引用当前对象自己,只是super限定了访问当前对象从父类那里获得成员变量和方法。

若是要访问父类的类名,应该使用以下语法:

Super.getClass().getSupserClass().getName();

 

49.JDK中哪些类是不可继承的?

答:不能继承的类是用final关键字修饰的类。

使用final关键字修饰的类,能够阻止被继承,不会有子类来重写该类的方法,彻底封闭起来,所以更安全。

50.String s = “Hello”;

s = s + “world!”;这两行代码执行后,原始String对象中的内容到底变了没有?

答:没有。String被设计成是一个不可变类。当第2行代码执行之后,s引用变量指向了一个新的对象,原来的内容为”Hello”直接量对象被存放在内存中。

建议使用StringBufferStringBuilder类。

 

51.是否能够继承String类?

答:String类是final类,被final关键字修饰,因此不能被继承。

 

52.如何把一段逗号分割的字符串转换成一个数组?

答:可使用String.split(“,”)方法使用String[]数组接收。

如:String [] result = "this,is,a,test".split(",");

其中result数组中存放了thisisatest等字符串元素。

 

53.下面这条语句一共建立了多少个对象:String s=”a”+”b”+”c”+”d”;

答:一个String对象。Java会在编译时对字符串相加进行优化处理,在编译时发现全部参与运算的都是字符串直接量,Java会把这个表达式的值计算出来。直接将该表达式的结果赋值给字符串引用变量。

对于以下代码:

String s1=”a”;

String s2=s1 + “b”;//对象+字符串=新的对象,和字符串常量池中的直接量没有关系

String s3=”a” + “b”;

System.out.println(s2 == “ab”);//false

System.out.println(s3 == “ab”);//true

字符串直接量会被放入字符串缓冲池中。

以下两行代码:

String s = “a” + “b” + “c” + “d”;

System.out.println(s == “abcd”);//true

因为s引用了字符串缓冲池中的”abcd”字符串,所以上面的输出结果为true

 

54.Collection集合框架中实现比较要实现什么接口。

:Java集合框架中须要比较大小的集合包括TreeMapTreeSet,其中TreeMap会根据key-value对中key的大小进行排序,而TreeSet则会对集合元素进行排序。

集合框架中比较大小有2种方式:

A.     天然排序

要求TreeMap中的全部key都实现Comparable接口。JDK不少类都已经实现了Comparable接口,如String,Date,BigDecimal等。

B.      定制排序

须要在建立TreeMapTreeSet时传入一个Comparator对象,Comparator只是一个接口,所以建立Comparator对象只能是建立它的实现类的对象,因此须要实现Comparator接口。

 

55.ArrayListVector的区别?

答:

Collection是接口,Collections是工具类。

相同点:这两个类都实现了List接口,List接口继承了Collection接口,它们都是有序集合。

(咱们能够按位置索引号取出某个元素,而且其中的数据是容许重复的,这是List集合规范制定的)

并且ArrayListVector底层都是基于数组的,所以它们的实现代码也大体类似。

区别:在于Vector是一个古老的集合,从JDK1.0开始就有了,所以它包含了大量方法名很长的方法。JDK1.2开始引入集合框架,引入List接口,才让Vector实现了List接口,所以又增长了一些List接口中定义的方法。

整体来讲,ArrayList能够彻底替代Vector,除了在一些很古老的API中强制要求使用Vector以外。

Vector还有一个特征,它是线程安全的,所以性能较差,而ArrayList并非线程安全的,所以性能较好。

实际上即便咱们要在多线程环境下使用List集合,也应该选择ArrayList而不是Vector,由于Java还提供了一个Collections工具类,它能够把ArrayList包装成线程安全的集合类,例如以下代码:

List list = Collections.synchronizedList(new ArrayList());

 

56.HashMapHashTable的区别

答:HashMapHashTable的区别相似于ArrayListVector的区别。

HashTableVector都是JDK1.0就有一个古老的集合,HashTable是一个继承自Dictionary(字典)类的古老集合。

JDK1.2引入集合框架的Map接口以后,JavaHashTable也实现了Map接口,所以HashTable也新增实现了一些Map接口中定义的方法。

实际上HashMapHashTable底层的实现很类似,它们都是基于Hash表的实现。

HashMapHashTable的区别主要有2点:

A.     HashMap容许null做为keyvalue,而HashTable不容许。

B.      HashMap是线程不安全的,所以性能较好。HashTable是线程安全的,所以性能较差。

实际上在多线程环境下,Java提供了Collection工具类把HashMap包装成线程安全的类,所以依然应该使用HashMap,以下代码所示:

Map map = Collections. synchronizedMap(new HashMap());

简单的说,编程时应该尽可能避免使用HashTable,它与HashMap的底层实现很类似,但除非在一个古老的API中强制要求HashTable

 

57.ListMap的区别?

答:List集合的特色:可重复,有序,有索引,程序能够经过元素的索引来读取元素,所以List至关于一个动态数组。

Map集合的特色:有Key-Value对,不容许重复,无序,无索引,程序能够根据key来取出对应的Value

深刻阐述:若是换个角度来看,咱们能够把List当成Map来看,List至关于key都是数值的Map,程序经过元素的索引来读取List集合时,彻底能够当成Map根据key来读取value。从另外一个角度看,Map也能够当成元素索引能够是任意类型的List集合。

 

58.List,Set,Map是否继承自Collection接口?

答:List,Set集合继承自Collection接口,Map集合很多继承自Collection接口。

 

59.List,MapSet三个接口,存取元素时,各有什么特色?

答:List集合:可重复,有序,有索引,实现类,ArrayList

       Set集合:不容许重复,无序,无索引

       对于Map集合而言,其底层存,取性能与Set集合彻底同样。其实Set集合自己就是基于Map实现的,除了有键值对之外。

 

60.说出ArrayListVectorLinkedList的存储性能和特性。

答:ArrayListVector都是使用数组方式存储数据,Vector因为使用了synchrnized(线程安全)的方法,所以性能较ArrayList差,而LinkedList使用了双向链表实现存储,因此插入速度较快,并且线程也是不安全的。LinkedList提供了一些方法,使得LinkedList能够被看成堆栈和队列来使用。

实际上Java提供了Collection集合的工具类,它能够把ArrayList,vector包装成线程安全的集合,所以在实际编程中应该避免使用Vector集合,它是一个古老的,在JDK1.0时代就出现的集合。

 

61.去掉一个Vector集合中重复的元素。

最简单的方式:HashSet set = new HashSet(vector);

       基于HashSet不容许重复的特性。

 

62.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==仍是equals()?它们有何区别?

答:Set只是一个接口,它的不一样实现类判断元素是否相等的标准是不一样的。笼统地说,Set里的元素是不能重复的,判断元素重复应该使用equals方法而不是==

对于HashSet而言,判断两个对象是否相等是经过equals()方法和hashCode()方法,只要两个对象经过equals()比较返回false,或两个对象的hashCode值不同,那么HashSet就会把它们当成不相同的元素。

对于TreeSet而言,判断两个对象是否相等的惟一标准是:两个对象经过compareTo(Object obj)比较是否返回0,与equals()方法无关。

 

63.你所知道的集合类都有哪些?主要方法?

答:最经常使用的集合接口是Set,List,Queue,它们都是Collection的子接口,除此以外还有Map接口。

对于Set集合而言,它的经常使用实现类包括HashSetTreeSet,HashSet还有一个子类,LinkedHashSet

对于List集合而言,它的经常使用实现类包括ArrayList,VectorLinkedList

对于Queue集合而言,它有一个子接口,表明双端队列,Deque,它的经常使用实现类包括ArrayDequeLinkedList

对于Map集合而言,它的经常使用实现类是HashMap,TreeMap,HashMap还有一个子类,LinkedHashMap

至于这些集合的方法,因为集合类也就是“容器类”,所以它的方法无非就是向容器中添加,删除,取出,遍历元素的方法。

List集合的元素都是有序,有索引的,所以它包括了大量根据索引来添加,删除,取出集合元素的方法。

对于Deque集合而言,因为它是双端队列,既能够当成队列使用,也能够当成栈使用,所以它增长栈,队列的方法,压栈和弹栈,如pushpopofferpeek等。

对于Map集合而言,它的方法无非就是根据key来添加,删除,取出value的方法。

 

64.两个对象值相同(x.equals(y)==true),但却能够有不一样的hash code,这句话对不对?

答:对。

由于equals方法和hashcode方法均可以由开发者来重写,所以它们是否相等并无必然的关系。

若是对象要保存在HashSet或者HashMap中,它们的equals相等,那么hashcode返回值也应该相等。

 

65.TreeSet里面放对象,若是同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,仍是使用子类的compareTo方法,仍是抛异常?

答:当前正在添加父类对象就屡次调用父类对象的CompareTo方法,当前正在添加子类对象就屡次调用子类对象的CompareTo方法。

至于程序是否抛出异常,则取决于CompareTo方法的实现,若是子类在实现CompareTo方法时,试图把被比较对象转换为子类对象以后再比较,若是TreeSet集合中已经包括了父类对象,这就会引发ClassCastException类型转换异常。

 

66.说出一些经常使用的类,包,接口,请各举5个。

答:经常使用的包有:

java.lang包下包括Math,System,StringBuilder,StringBuffer,Runtime,Thread,Runnable

Math数学,System系统,StringBuilder/StringBuffer,运行时类,线程类)

java.util包下包括List,Set,Map,以及这些接口的经常使用实现类,ArrayListLinkedList,HashSet,TreeSet,HashMapTreeMap

java.io包下包括

(字节流,字符流,缓冲流)

InputStream,OutputStream,Reader,Writer,FileInputStream,FileOutputStream,FileReader,FileWriter,BufferInputStream,BufferOutputStream,BufferReader,BuffWriter

Java.sql包下包括Connection,Statement,PrepareStatement,ResultSet等(建立链接对象,编译,预编译语句,结果集)

Java.net包下包括

Socket,ServerSocket,URL,URLConnection,DatagramPacker,DatagramSocket

Socket套接字)

 

67.java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以继承,请说出它们分别是那些类?

答:字节流和字符流,字节流由InputStream,OutputStream派生出来,字符流由Reader,Writer派生出来。java.io包中还有许多其它的流,主要是为了提升性能和使用方便。

 

68.字符流和字节流的区别。

答:字节流和字符流的区别是,它们的用法几乎彻底同样,区别在于字节流和字符流所操做的数据单元不一样,字节流操做的数据单元是8位的字节,而字符流操做的数据单元是16位的字符。

节流主要由InputStream,OutputStream做为基类,字符流主要由Reader,Writer做为基类。

字节流是基于字节输入,输出的,所以它的适用性更广。字符流则在处理文本内容时的输入,输出更加方便——不会出现只读取半个字符的状况。

Java提供了将字节流转换为字符串的InputStreamReader , OutputStreamWriter,但没有提供将字符流转化为字节流的方法。由于,字节流比字符流的使用范围更广,但字符流在处理字符的时候比字节流操做方便。若是有一个字节流,咱们知道它的内容是文本内容,所以把它转换成字符流来处理就会更方便一些。各有所需。

 

69.什么是Java序列化,如何实现Java序列化?或者请解释Serializable接口的做用。

答:序列化的目标是将对象保存到磁盘中,或容许在网络中直接传输对象,对象序列化机制容许把内存中的Java对象转换成平台无关的二进制流,持久保存到磁盘上,经过网络将这种二进制流传输到另外一个网络节点。其它程序一旦得到了这种二进制流,不管是从磁盘中获取仍是经过网络获取,均可以将这种二进制流恢复成原来的Java对象。

Serializable接口只是一个标记接口,实现该接口无需实现任何方法,实现了该接口的类就是可序列化的类。

序列化在Web开发中十分重要,Tomcat在某些时候须要把保存在Session中的对象序列化到硬盘,所以放入Session中的对象必须是可序列化的,这就能够经过Serializable接口来实现。还有,若是一个对象要通过网络传输(好比RMI远程方法调用的形参或返回值),这个对象也应该是可序列化的。

 

70.描述一下JVM加载class文件的原理机制?

答:

当程序主动使用某个类,若是该类还未必加载到内存中,系统会经过3个步骤来对该类进行初始化。加载,链接,初始化。

类加载指的当程序中使用任何类时,系统都会为之创建一个java.lang.Class类对象。

类的加载由加载器完成,类加载器一般由JVM提供,除此以外,开发者能够经过继承ClassLoader基类来建立本身的类加载器。

 

71.heapstack有什么区别?

答:stack指的是栈区,当程序进入一个方法时,系统会专门为这个方法分配一个内存空间,这块内存空间也被称为该方法栈区,该方法的栈区专门用于存储该方法中定义的局部变量,(括基本类型变量和引用变量)。当这个方法结束时,该方法栈区将会自动被销毁,栈区中的全部局部变量也会被销毁。

heap指的是堆,堆内存是Java虚拟机拥有的内存区。全部的Java对象都被放在堆内存中,位于堆内存中的Java对象由系统垃圾回收器负责跟踪管理——垃圾回收(GC),当堆内存中的对象没有引用变量引用它时,这个Java对象就变成了垃圾,垃圾回收器会在合适的时候回收它

 

72.try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,何时被执行,在return前仍是return后?

答:确定会执行,在return后执行。

Finally{}块的代码只有在try{}块中包含遇到System.exit(0;之类的致使Java虚拟机直接退出的语句才会不执行。

当程序执行try{}遇到return时,程序会先执行return语句,但并不会当即返回,而是把执行流程转到finally块,完成finally块的执行后就直接返回刚才return语句已经准备好的结果。

 

73.下面程序代码输出的结果是多少?

public class smallT

{

       public static void main(String args[])

       {

              smallT t = new smallT();

              int b = t.get();

              System.out.println(b);

       }

       public int get()

       {

              try

              {

                     return 1 ;

              }

              finally

              {

                     return 2 ;

              }

       }

}

输出结果是:2

Java会把return语句先执行完,把全部须要处理的东西都先处理完成,可是还未返回以前,程序流程会转去finally块。但若是在执行finally块时遇到了return语句,那么程序会直接使用finally块中的return语句来返回,所以上面程序会输出2

 

74.final,finally,finalize的区别。

答:final最终的,finally最后,finalize完成。

Final是一个修饰符,它能够修饰类,方法,变量。

final修饰类代表这个类不能够被继承,final修饰方法时代表这个方法不能够被其子类重写(重写就是覆盖Override.finalfinal修饰变量可分为局部变量,实例变量,静态变量。)

final修饰局部变量时,该局部变量能够被赋值一次。当final修饰实例变量时,实例变量必须由程序在构造器,初始化块,定义时3个位置的其中之一指定初始值。当final修饰静态变量时,静态变量必须由程序在静态初始化块,定义时这2个位置的其中之一指定初始值。

Finally是异常处理语句结构的一部分,表示总会执行的代码块。

FinalizeObject类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。但实际上重写此方法进行资源回收并不安全,由于JVM并不保证该方法总被调用。

 

75.运行时异常与通常异常有何异同?

答:Checked检查异常就是通常异常,体现了Java的设计哲学,没有完善错误处理的代码根本不会被执行。

通常异常的处理方式有2种,

A.     当前方法知道如何处理异常,程序应使用try…catch块来捕获异常,而后在对应的catch块中修补该异常。

B.      当前方法不知道如何处理异常,应该在定义方法时声明抛出该异常。Throw Exception

Runtime异常对比处理更加灵活,Runtime异常无需显式声明抛出,若是程序须要捕捉Runtime异常,也可使用try…catch块来捕捉runtime异常。

 

76.errorexception有什么区别?

答:Error错误,通常是指虚拟机相关的问题,如系统崩溃,虚拟机出错,动态链接失败等。这种错误没法恢复或不能被捕获,将致使应用程序中断。

Exception异常,表示一种设计或实现问题。也就是说,程序员应该对这些状况进行考虑,并提供相应的处理。

 

77.Java中的异常处理机制的简单原理和应用。

答:程序运行过程当中可能出现各类非预期状况,这种非预期状况可能致使程序非正常结束。为了提升程序的健壮性,Java提供了异常处理机制。

Java对异常进行了分类,不一样类型的异常分别用不一样的Java类表示,全部异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error错误和Exception异常,Error错误通常是指虚拟机相关的问题,如系统崩溃,虚拟机出现错误,动态链接失败等。这种错误没法恢复或不能捕获,将致使应用程序中断。一般应用程序没法处理这种错误,所以不能使用try…catch{}块来捕获Error对象。

Exception表示一种设计或实现问题,也就是说,程序员应该对这些状况进行考虑,并提供相应的处理。

异常分为运行时异常和通常检查异常,通常检查异常体现了Java的设计哲学,没有完善错误的代码根本就不会被执行。

对于通常检查异常的处理方式有两种:

A. 当前方法知道如何处理异常,程序应使用try…catch块来捕获异常,而后在对应的catch块中修补该异常。

B. 当前方法不知道如何处理异常,应该在定义方法时声明抛出该异常。

实际上Java的通常异常后来争议不断,由于通常异常要求程序员要么显式声明抛出,要么进行捕捉,不能对通常异常漠不关心,这就给编程带来了必定的复杂度。

好比SpringHibernate框架的一大特色就是把通常异常包装成了运行时异常。

运行时异常则比较灵活,开发者既能够选择捕获运行时异常,也能够不捕获。

 

78.请写出你最多见到的5runtime exception.

答:对于一个有1—2年左右编程经验的人来讲,总会遇到一些常见的异常。

其中有些就是

Runtime Exception运行时异常

NullPointerException空指针异常:当调用一个未初始化的引用变量的实例Field,实例方法时都会引起该异常。

ArithmeticException算术异常:好比5/0将引起异常。

ArrayIndexOutOfBoundsException数组索引越界异常

ClassCastException类型转换异常

IllegalArgumentException参数非法的异常

79.Java语言如何进行异常处理,关键字:throws ,throw ,try ,catch ,finally分别表明什么意义?在try块中能够抛出异常吗?

答:try块表示程序正常的业务执行代码。若是程序在执行try块的代码时出现了“非预期”状况,JVM将会生成一个异常对象,这个异常对象将会被后面相应的catch块捕获。

Throw用于手动抛出异常对象。Throw后面须要一个异常对象。

Throws用于在方法签名中声明抛出一个或多个异常类throws关键字后能够紧跟一个或多个异常类。

Finally块表明异常处理流程中总会执行的代码块。

对于一个完整的异常处理流程,try块是必须的,try块后能够紧跟一个或多个catch块,最后还能够带一个finally块。

Try块中能够抛出异常。

 

80.Java中有几种方法能够实现一个线程?用什么关键字修饰同步方法?stop()suspend()方法为什么不推荐使用?

答:在java5之前,有以下两种

A. 继承Thread类,重写它的run()方法。

代码以下:

new Thread()

{

       public void run()

       {

              //线程执行体

       }

}.start();

C.     实现Runnable接口,并重写它的run()方法。

new Thread(new Runnable()

{

       public void run()

       {

              //线程执行体

       }     

}).start();

从上面代码不难看出,线程的执行体是一个run()方法,而后程序经过start()方法启动一条线程。

Java5开始,Java提供了第三种方式来建立多线程:实现Callable接口,并实现Call()方法。Callable接口至关于Runnable接口的加强版,由于Callable接口中定义的call()方法既拥有返回值,也能够声明抛出异常。

代码以下:

new Thread(new FutureTask<Object >(new Callable<Object>()

{

       public Object call() throws Exception

       {

              //线程执行体

       }

})).start();

不只如此,Java5还提供了线程支持,ExecutorService对象就表明了线程池,若是开发者利用ExecutorService来启动线程,ExecutorService底层会负责管理线程池。此时,开发者只要把Runnable对象传给ExecutorService便可。以下代码:

ExecutorService pool = Executors.newFixedThreadPool(3)

pool.execute(new Runnable()

{

       public void run()

       {

              //线程执行体

       }     

});

若是执行经过Callable方式实现的线程,则可按以下代码:

ExecutorService pool = Executors.newFixedThreadPool(3)

pool.execute(new FutureTask<Object >(new Callable<Object>()

{

       public Object call() throws Exception

       {

              //线程执行体

       }

}));

 

synchronized关键字修饰同步方法。须要指出的是,非静态的同步方法的同步监视器是this,也就是调用该方法的对象,而静态的同步方法的同步监视器是该类自己。所以使用synchronized修饰的静态方法,非静态方法的同步监视器并不相同,只有基于同一个同步监视器的同步方法,同步代码块才能实现同步。

使用stop()中止方法不安全。它会解除由线程获取的全部锁定,并且若是对象处于一种不连贯状态,那么其余线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。

Suspend()延迟方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这以前得到的锁定。此时,其余任何线程都不能访问锁定的资源,除非被“挂起”的线程恢复运行。对任何线程来讲,若是它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会形成死锁。因此不该该使用suspend(),而应在本身的Thread类中置入一个标志,指出线程应该活动仍是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()从新启动线程。

 

82.sleep()wait()又什么区别?

答:sleep()Thread类的静态方法,它的做用是让当前线程从运行状态转入,阻塞状态,线程执行暂停下来,当一个线程经过sleep()方法暂停以后,该线程并不会释放它对同步监视器的加锁。

Wait()Object对象的方法,但实际上只有同步监视器才能调用该方法。当程序在同步代码块,或同步方法内经过同步监视器调用该方法时,将会致使当前线程释放对该同步监视器的加锁,而该线程则会进入该同步监视器的等待池中,直到该同步监视器调用notify()(通知)或notifyAll()来通知该线程。

 

83.同步和异步有何异同,在什么状况下分别使用它们?举例说明。

答:同步,对于一个银行帐户,若是有多个线程试图去访问这个帐户时,若是不对多个线程进行同步控制,有可能帐户余额只有1000块,但多个线程都试图取款800块时,这些线程同时判断余额以后,都会显示余额足够,从而致使每一个线程都取款成功。这显然不是咱们但愿看到的结果。

当程序试图执行一个耗时操做时,程序不但愿阻塞当前执行流,所以程序也不该该试图当即获取该耗时操做返回的结果,此时就使用异步编程了,典型的应用场景就是Ajax。当浏览器经过JavaScript发出一个异步请求以后,JavaScript执行流并不会停下来,而是继续向下执行,这就是异步。程序会经过监听器来监听远程服务器响应的到来。

 

84.多线程有几种实现方法?同步有几种实现方法?

答:

多线程的实现方法:

Java5之前,有以下两种:

第一种,继承Thread类,重写它的run()方法。

第二种,实现Runnable接口,并重写它的run()方法。

线程的执行体是一个run()方法,而后程序经过start()方法启动一条线程。

Java5开始,Java提供了实现Callable接口来建立多线程,并实现call()方法。Callable接口至关于Runnable接口的加强版,由于Callable接口中定义的call()方法既拥有返回值,也能够声明抛出异常。

不只如此,Java5还提供了线程支持,ExecutorService对象就表明了线程池。开发者只要把Runnable对象,传给ExecutorService便可。

同步的实现方法:

同步方法:使用synchronized关键字修饰方法,因为java的每个对象都有一个内置锁,在调用该方法前须要得到内置锁,不然就处于阻塞状态。

同步代码块:有synchronized关键字修饰的语句块。

使用特殊域变量volatile实现线程同步,须要同步的变量加上volatile

使用重入锁实现线程同步,建立一个ReentrantLock的实例,得到锁lock(),释放锁unlock()

使用局部变量实现线程同步,若是使用ThreadLocal管理变量,则每个使用该变量的线程都得到该变量的副本,副本之间相互独立,这样每个线程均可以随意修改本身的变量副本,而不会对其余线程产生影响。

注:ThreadLocal与同步机制

A. ThreadLocal与同步机制都是为了解决多线程中相同变量的访问冲突问题。

B. 前者采用以“空间换时间”的方法,后者采用以“时间换空间”的方式。

 

85.启动一个线程是用run()仍是start()?

答:启动一个线程是调用start()方法,使线程就绪状态,之后能够被调度为运行状态。run()方法是线程的线程执行体——也就是线程将要完成的事情。

 

86.当线程进入一个对象的一个synchronized方法后,其余线程是否能够进入此对象的其余方法?

答:当线程进入一个对象的synchronized方法以后,其余线程彻底有可能再次进入该对象的其余方法。

不过要分几种状况来看:

1.      若是其余方法没有使用synchronized关键字修饰,则能够进入。

2.      若是当前线程进入的synchronized方法是static方法,其余线程能够进入其余synchronized修饰的非静态方法,若是当前线程进入的synchronized方法是非static方法,其余线程能够进入其余synchronized方法。

3.      若是两个方法都是静态方法,或者都是非静态方法,而且都使用了synchronized修饰,但只要在该方法内部调用了同步监视器的wait(),则其余线程依然能够进入其余使用synchronized方法修饰的方法。

4.      若是没有调用wait(),其余线程不能进入其余使用synchronized方法修饰的方法。

 

87.线程的基本概念,线程的基本状态以及状态之间的关系。

答:线程是进程的组成部分,一个进程能够拥有多个线程,一个线程必须有一个父进程。线程能够拥有本身的堆栈,本身的程序计数器和本身的局部变量,但再也不拥有系统资源,它与父进程的其余线程共享该进程所拥有的所有资源。由于多个线程共享父进程里的所有资源,所以编程更加方便;但必须更加当心,咱们必须确保线程不会妨碍同一进程里的其余线程。

线程的执行须要通过以下状态:

新建线程new

就绪start()

运行

阻塞sleep()

死亡stop()

各状态的转换关系以下图所示:

 

 

88.简述synchronizedjava . util .concurrent .locks .Lock的异同

答:主要相同点:Lock能完成synchronized所实现的全部功能。

主要不一样点:Lock有比synchronized更精确的线程语义和更好的性能Synchronized会自动释放锁,Lock必定要求程序员手工释放,而且必须在finally从句中释放。Lock还有更强大的功能,它tryLock方法能够非阻塞方式去拿锁

 

Java代码查错部分

1.

abstract class Name {

   private String name;

   public abstract boolean isStupidName(String name) {}

}

答:错。abstract方法必须以分号;结尾,并且不带花括号{}

 

2.

public class Something {

   void doSomething () {

       privateString s = "";

       int l = s.length();

   }

}

有错吗?

答:错。局部变量前不能放置任何修饰符(private,public,protected),final能够用来修饰局部变量。