java 面试基础题

第一阶段面试题集 1、面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: 1)抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

第一阶段面试题集

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

答:面向对象的特征主要有以下几个方面:
1)抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。
2)继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。
3)封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
4)多态性:多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。

2、作用域public,private,protected,以及不写时的区别?

答:区别如下:
作用域 当前类 同包 子孙类 其他
public √ √ √ √
protected √ √ √ ×
default √ √ × ×
private √ × × ×
不写时默认为default,但注意此单词不能写出,写出会报错.

3、String 是最基本的数据类型吗?

答:不是.String是引用类型,底层维护的是char类型的数组

4、float 型float f=3.4是否正确?

答:不正确.浮点型的字面值类型是double,所以应该强制类型转换3.4为float类型float f=(float)3.4

5、short s1 = 1; s1 = s1 + 1;有什么错?

short s1 = 1; s1 += 1;有什么错?
答:short s1 = 1; s1 = s1 + 1;s1+1运算结果是int 型,需要强制转换类型;short s1 = 1; s1 += 1;可以正确编译,自动类型提升。

6、Java 有没有goto?

答:goto 是java 中的保留字,现在没有在java 中使用。

7、int 和Integer 有什么区别?

答:Java 提供两种不同的类型:引用类型和原始类型(或基本类型);
int 是java 的原始数据类型,Integer 是java 为int 提供的封装类。
Java 为每个原始类型提供了封装类:
原始类型: boolean,char,byte,short,int,long,float,double
封装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double引用类型和基本类型的行为完全不同,并且它们具有不同的语义。引用类型和基本类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和基本类型用作某个类的实例数据时所指定的默认值。对象引用实例变量的默认值为null,而基本类型实例变量的默认值与它们的类型有关。

8、&和&&的区别?

答:&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and),有短路的作用。

9、简述逻辑操作(&,|,^)与条件操作(&&,||)的区别?

答:区别主要有两点:
1.条件操作只能操作布尔型的,而逻辑操作不仅可以操作布尔型,而且可以操作数值型
2.逻辑操作不会产生短路。

10、stack 是什么?

答:栈是一种线形集合,其添加和删除元素的操作按照后进先出的方式进行处理;

11、swtich 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?

答:switch(express)中,express 是一个整数表达式,支持的参数参数有:byte、int、short、char、String与enum

12、编程题: 用最有效率的方法算出2 乘以8 等于几?

答: 2 << 3。 左移符号,此处可以理解成2乘以2的3次方,0b10左移3位得到0b10000,即为16

13、数组有没有length()这个方法? String 有没有length()这个方法?

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

14、构造器Constructor 是否可被override?

答:构造器Constructor 不能被继承,因此不能重写Overriding,但可以被重载Overloading。

15、是否可以继承String 类?

答:String 类是final 类,故不可以继承。

16、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。

17、String 和StringBuffer 的区别?

答:JAVA 平台提供了两个类:String 和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String 类提供了数值不可改变的字符串。而这个StringBuffer 类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。

18、String, StringBuffer StringBuilder 的区别。

答:String 的长度是不可变的;StringBuffer 的长度是可变的,如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer 的toString()方法;线程安全;StringBuilder 是从JDK 5 开始,为StringBuffer 该类补充了一个单个线程使用的等价类;通常应该优先使用StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。

19、Overload 和Override 的区别。Overloaded 的方法是否可以改变返回值的类型?

答:方法的重写Overriding 和重载Overloading 是Java 多态性的不同表现。重写Overriding 是父类与子类之间多态性的一种表现,重载Overloading 是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded 的方法是可以改变返回值的类型。

  1. 重载: 是指在一个类中的现象,是指一个类中有很多同名的方法,但是方法的参数列表不同
  2. 重写: 是指发生了继承关系以后(两个类),子类去修改父类原有的功能
    语法规则:子类的方法签名(返回值类型 方法名(参数列表) )与父类一致
    重写方法的修饰符: 子类权限 >= 父类的权限
    3.重载的意义: 是为了方便外界对方法进行调用,什么样的参数程序都可以找到对应的方法来执行,体现的是程序的灵活性
    4.重写的意义:是在不修改源码的前提下,进行功能的修改和拓展

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

答:JVM 中类的装载是由ClassLoader 和它的子类来实现的,Java ClassLoader是一个重要的Java 运行时系统组件。它负责在运行时查找和装入类文件的类。

21、abstract class 和interface 有什么区别?

答:抽象类是一个特殊的类,特殊在,抽象类中可以包含没有方法体的方法(抽象方法)
接口可以理解成一个特殊的抽象类,特殊在,接口里的都是抽象方法,没有普通方法
接口会为方法自动拼接public abstract,还会为变量自动拼接public final static
抽象类可以有构造方法–用来给子类创建对象,接口中没有构造方法
抽象类和接口都不能实例化(创建对象)
接口可继承接口,并可多继承接口,但类只能单继承
抽象方法只能声明,不能实现,接口是设计的结果 ,抽象类是重构的结果

- JDK1.7

接口的方法默认是 public,所有方法在接口中不能有实现,而抽象类可以有非抽象的方法。
接口中除了 static、final 变量,不能有其他变量,而抽象类中则不一定。
一个类可以实现多个接口,但只能实现一个抽象类。接口自己本身可以通过 extends 关键字扩展多个接口。
接口方法默认修饰符是 public,抽象方法可以有 public、protected 和 default 这些修饰符(抽象方法就是为了被重写所以不能使用 private 关键字修饰!)
- JDK1.8改动

在 jdk 7 或更早版本中,接口里面只能有常量变量和抽象方法。这些接口方法必须由选择实现接口的类实现。
jdk8 的时候接口可以有默认方法和静态方法功能。
Jdk 9 在接口中引入了私有方法和私有静态方法

22、java 中会存在内存泄漏吗,请简单描述。

答:会;存在无用但可达的对象,这些对象不能被GC 回收,导致耗费内存资源。

23、静态变量和实例变量的区别?

答:静态变量也称为类变量,归全类共有,它不依赖于某个对象,可通过类名直接访问;而实例变量必须依存于某一实例,只能通过对象才能访问到它。

24、是否可以从一个static 方法内部发出对非static 方法的调用?

答:不可以,如果其中包含对象的method(),不能保证对象初始化。静态只能调用静态

25、GC 是什么? 为什么要有GC?

答:GC 是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java 提供的GC 功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java 语言没有提供释放已分配内存的显示操作方法。Java 程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() 。

26、垃圾回收的优点和原理。并考虑2 种回收机制。

答:Java 语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java 程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java 中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。

27、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?

答:对于GC 来说,当程序员创建对象时,GC 就开始监控这个对象的地址、大小以及使用情况。通常,GC 采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC 确定一些对象为"不可达"时,GC 就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC 运行,但是Java 语言规范并不保证GC 一定会执行。

28、String s=new String(“xyz”);创建了几个String Object?

答:两个对象,一个是"xyx",一个是指向"xyx"的引用对象s。

29、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?

答:接口可以继承接口。抽象类可以实现(implements)接口,抽象类可继承实体类,但前提是实体类必须有明确的构造函数。

30、Java 的接口和C++的虚类的相同和不同处。

答:由于Java 不支持多继承,而有可能某个类或对象要使用分别在几个类或对象里面的方法或属性,现有的单继承机制就不能满足要求。与继承相比,接口有更高的灵活性,因为接口中没有任何实现代码。当一个类实现了接口以后,该类要实现接口里面所有的方法和属性,并且接口里面的属性在默认状态下面都是public static,所有方法默认情况下是public.一个类可以实现多个接口。

31、一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制?

答:可以;必须只有一个类名与文件名相同。

32、内部类可以引用他包含类的成员吗?有没有什么限制?

答:一个内部类对象可以访问创建它的外部类对象的内容。

33、在java 中一个类被声明为final 类型,表示了什么意思?

答:表示该类不能被继承,是顶级类。

34、下面哪些类可以被继承?

1)java.lang.Thread (T)
2)java.lang.Number (T)
3)java.lang.Double (F)
4)java.lang.Math (F)
5)java.lang.Void (F)
6)java.lang.Class (F)
7)java.lang.ClassLoader (T)
答:1、2、7 可以被继承。

35、数据类型之间的转换:

1)如何将数值型字符转换为数字?
2)如何将数字转换为字符?
3)如何取小数点前两位并四舍五入?
答:1)调用数值类型相应包装类中的方法parse***(String)或valueOf(String)即可返回相应基本类型或包装类型数值;
2)将数字与空字符串相加即可获得其所对应的字符串;另外对于基本类型数字还可调用String 类中的valueOf(…)方法返回相应字符串,而对于包装类型数字则可调用其toString()方法获得相应字符串;
3)可用该数字构造一java.math.BigDecimal 对象,再利用其round()方法进行四舍五入到保留小数点后两位,再将其转换为字符串截取最后两位。

36、字符串操作:如何实现字符串的反转及替换?

答:可用字符串构造一StringBuffer 对象,然后调用StringBuffer 中的reverse方法即可实现字符串的反转,调用replace 方法即可实现字符串的替换。

37、编码转换:怎样将GB2312 编码的字符串转换为ISO-8859-1 编码的字符串?

答:示例代码如下:
String s1 = “你好”;
String s2 = new String(s1.getBytes(“GB2312”), “ISO-8859-1”);

38、日期和时间:

1)如何取得年月日、小时分秒?
2)如何取得从1970 年到现在的毫秒数?
3)如何取得某个日期是当月的最后一天?
4)如何格式化日期?
答:1)创建java.util.Calendar 实例(Calendar.getInstance()),调用其get()方法传入不同的参数即可获得参数所对应的值,如:calendar.get(Calendar.YEAR);//获得年
2)以下方法均可获得该毫秒数:Calendar.getInstance().getTimeInMillis();System.currentTimeMillis();
3)示例代码如下:
Calendar time = Calendar.getInstance();
time.set(Calendar.DAY_OF_MONTH,
time.getActualMaximum(Calendar.DAY_OF_MONTH));
4)利用java.text.DataFormat 类中的format()方法可将日期格式化。

39、Java 中的异常处理机制的简单原理和应用?

答:当JAVA 程序违反了JAVA 的语义规则时,JAVA 虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2 种情况。一种是JAVA 类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null 的对象时会引发NullPointerException。另一种情况就是JAVA 允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw 关键字引发异常。所有的异常都是java.lang.Thowable 的子类。

40、error 和exception 有什么区别?

答:error 表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情况;exception 表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况。

41、try {}里有一个return 语句,那么紧跟在这个try 后的finally {}里的code会不会被执行,什么时候被执行,在return 前还是后?

答:会执行,在return 前执行。

42、JAVA 语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try 块中可以抛出异常吗?

答:Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java 中,每个异常都是一个对象,它是Throwable 类或其它子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。
Java 的异常处理是通过5 个关键词来实现的:try、catch、throw、throws 和finally。一般情况下是用try 来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理;
try 用来指定一块预防所有“异常”的程序;
catch 子句紧跟在try 块后面,用来指定你想要捕捉的“异常”的类型;
throw 语句用来明确地抛出一个“异常”;
throws 用来标明一个成员函数可能抛出的各种“异常”;
Finally 为确保一段代码不管发生什么“异常”都被执行一段代码;
可以在一个成员函数调用的外面写一个try 语句,在这个成员函数内部写另一个try 语句保护其他代码。每当遇到一个try 语句,“异常”的框架就放到堆栈上面,直到所有的try 语句都完成。如果下一级的try 语句没有对某种“异常”进行处理,堆栈就会展开,直到遇到有处理这种“异常”的try 语句。

43、运行时异常与一般异常有何异同?

答:异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java 编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

44、给我一个你最常见到的runtime exception?

答:NullPointerException, SystemException,ProviderException, IndexOutOfBoundsException,
ClassCastException, BufferOverflowException,BufferUnderflowException,
ArrayStoreException, SecurityException,ProfileDataException,
ArithmeticException,
CannotRedoException, CannotUndoException,CMMException, ConcurrentModificationException,
DOMException, EmptyStackException, IllegalArgumentException,IllegalMonitorStateException, IllegalPathStateException,
IllegalStateException, ImagingOpException,MissingResourceException, NegativeArraySizeException,
NoSuchElementException, RasterFormatException, UndeclaredThrowableException,
UnmodifiableSetException, UnsupportedOperationException

45、final, finally, finalize 的区别?

答:

  • final:修饰符(关键字);如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承,因此一个类不能既被声明为abstract的,又被声明为final 的;将变量或方法声明为final,可以保证它们在使用中不被改变;被声明为final 的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改;被声明为final 的方法也同样只能使用,可以被重载,不可重写。
  • finally:再异常处理时提供finally 块来执行任何清除操作;如果抛出一个异常,那么相匹配的catch 子句就会执行,然后控制就会进入finally 块(如果有的话)。
  • finalize:方法名;Java 技术允许使用finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object 类中定义的,因此所有的类都继承了它。子类覆盖finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。

46、介绍JAVA 中的Collection FrameWork(骨架,框架)(及如何写自己的数据结构)

答:Collection FrameWork 如下:
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection 是最基本的集合接口,一个Collection 代表一组Object,即Collection 的元素(Elements); Map 提供key 到value 的映射。
在这里插入图片描述

47、List,Set,Map 是否继承自Collection 接口?

答:List,Set 是;Map 不是。

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

答:最常用的集合类是List 和Map。List 的具体实现包括ArrayList 和Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。List 适用于按数值索引访问元素的情形。Map 提供了一个更通用的元素存储方法。Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。

49、说出ArrayList,Vector, LinkedList 的存储性能和特性?

答:

  • ArrayList 和Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,
  • Vector 由于使用了synchronized 方法(线程安全),通常性能上较ArrayList 差,
  • LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

50、Collection 和Collections 的区别?

答:Collection 是java.util 下的接口,它是各种集合的父接口,继承于它的接口主要有Set 和List;Collections 是个java.util 下的类,是针对集合的帮助类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

51、HashMap 和Hashtable 的区别?

答:二者都实现了Map 接口,是将惟一键映射到特定的值上;主要区别在于:
1)HashMap 没有排序,允许一个null 键和多个null 值,而Hashtable 不允许;
2)HashMap 把Hashtable 的contains 方法去掉了,改成containsvalue 和containsKey,因为contains 方法容易让人引起误解;
3)Hashtable 继承自Dictionary 类,HashMap 是Java1.2 引进的Map 接口的实现;
4)Hashtable 的方法是Synchronize 的,而HashMap 不是,在多个线程访问Hashtable 时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。Hashtable 和HashMap 采用的hash/rehash 算法大致一样,所以性能不会有很大的差异。

52、List、Map、Set 三个接口,存取元素时,各有什么特点?

答:List 以特定次序来持有元素,可有重复元素。Set 无法拥有重复元素,内部排序。Map 保存key-value 值,value 可多值。

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

答:Set 里的元素是不能重复的,用equals ()方法来区分重复与否。覆盖equals()方法用来判断对象的内容是否相同,而”==”判断地址是否相等,用来决定引用值是否指向同一对象。

54、sleep() 和wait() 有什么区别?

答:sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep 不会释放对象锁。wait 是Object 类的方法,对此对象调用wait 方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify 方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

55、当一个线程进入一个对象的一个synchronized 方法后,其它线程是否可进入此对象的其它方法?

答:其它线程只能访问该对象的其它非同步方法,同步方法则不能进入。

56、请说出你所知道的线程同步的方法。

答:wait():使一个线程处于等待状态,并且释放所持有的对象的lock;sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException 异常;notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM 确定唤醒哪个线程,而且不是按优先级;
notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

57、多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?

答:多线程有两种实现方法,分别是继承Thread 类与实现Runnable 接口,同步的实现方面有两种,分别是synchronized,wait 与notify。

58、同步和异步有何异同,在什么情况下分别使用他们?举例说明。

答:如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。

59、启动一个线程是用run()还是start()?

答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM 调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。

60、线程的基本概念、线程的基本状态以及状态之间的关系?

答:线程指在程序执行过程中,能够执行程序代码的一个执行单位,每个程序至少都有一个线程,也就是程序本身;Java 中的线程有四种状态分别是:运行、就绪、挂起、结束。

61、简述synchronized 和java.util.concurrent.locks.Lock 的异同?

答:主要相同点:Lock 能完成synchronized 所实现的所有功能;主要不同点:Lock 有比synchronized 更精确的线程语义和更好的性能。synchronized 会自动释放锁,而Lock 一定要求程序员手动释放,并且必须在finally 从句中释放。

62、什么是java 序列化,如何实现java 序列化?

答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题;序列化的实现:将需要被序列化的类实现Serializable 接口,该接口没有需实现的方法,implements Serializable 只是为了标注该对象是可被序列化的,然后使用一个输出流(如FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream 对象的writeObject(Object obj)方法就可以将参数为obj 的对象写出(即保存其状态),要恢复的话则用输入流。

63、java 中有几种类型的流?JDK 为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?

答:字节流,字符流。字节流继承于InputStream、OutputStream,字符流继承于Reader、Writer。在java.io 包中还有许多其他的流,主要是为了提高性能和使用方便。

64、Java 中常用的设计模式?说明工厂模式?

答:Java 中的23 种设计模式:Factory( 抽象工厂模式),Builder( 建造模式), Factory Method(工厂方法模式),Prototype(原始模型模式),Singleton(单例模式),Facade(门面模式),Adapter(适配器模式), Bridge(桥梁模式), Composite(合成模式),Decorator(装饰模式), Flyweight(享元模式), Proxy(代理模式),Command(命令模式), Interpreter(解释器模式), Visitor(访问者模式),Iterator(迭代子模式), Mediator(调停者模式), Memento(备忘录模式),Observer(观察者模式),State(状态模式),Strategy(策略模式),Template Method(模板方法模式), Chain Of Responsibleity(责任链模式)。
工厂模式:工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。

65、开发中都用到了那些设计模式?用在什么场合?

答:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心。通过这种方式,你可以无数次地使用那些已有的解决方案,无需在重复相同的工作。主要用到了MVC 的设计模式,用来开发JSP/Servlet或者J2EE 的相关应用;及简单工厂模式等。

66、你对软件开发中迭代的含义的理解;

答:软件开发中,各个开发阶段不是顺序执行的,应该是并行执行,也就是迭代的意思。这样对于开发中的需求变化,及人员变动都能得到更好的适应。

67、java跨平台是如何实现的?

答:Java是利用JVM ( Java虚拟机)实现跨平台的。
Java源代码( *.java )经过Java编译器编译成Java字节码( *.class ),,执行Java字节 码, Java字节码经过JVM解释为具体平台的具体指令,并执行。不同平台有不同的JVM , 主流平台都提供了JVM ,所以Java字节码可以在主流平台上能够解释执行。在这个意义上 Java是跨平台的,也就是说: Java的字节码是跨平台的。

68、这你认为Java与其他(你所了解的)语言相比,有什么优点和缺点?

答:首先,Java与C/C++相比。Java语言是一种完全的面向对象语言,虽然它的底层(运行时库)是用C语言开发的,可是并不依赖于C。因为Java的运行是在运行时库的支持下进行的,所以运行效率比起可以更接近底层的C/C++来说效率会有所影响,不过Java的类库采用很好的设计理念,非常好用,也非常实用,已经成为业界的一种标准开发语言。它的跨平台的特性受到开发者的青睐,只需要开发一次就能在所有安装了Java运行时库的环境上运行。其次,Java与C#相比。C#是微软开发的一种编程语言,语法类似Java几乎就是Java的翻版。运行原理和Java也类似,也是通过运行时库的支持运行。不过支持的平台还很有限。Java几乎被所有平台支持,而C#目前只被Windows和linux支持,Windows下的支持当然是由微软自己开发的,而Linux下的支持则有mono支持。实际上,mono也是把C#应用转化为Java应用而已所以本质上,C#仍然只是被微软自己的操作系统支持。应用平台受到限制,是它最大的缺点。

69、请回答以下几个名词的意思: JVM、JDK、JRE
答:JVM:Java虚拟机,Java Virtual Machine的缩写。是一个虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

JDK:Java开发工具包,Java Development Kit的缩写。JDK是整个Java的核心,包括了Java运行环境、Java工具和Java基础类库。
JRE:Java运行环境,Java Runtime Environment的缩写。运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。

70、类、方法、变量、包、常量的命名要符合哪些规范?

答:

  • 1)类命名规范:首字母大写,如果由多个单词合成一个类名,要求每个单词的首字母也要大写,大驼峰命名法 如:HelloWorld.
  • 2)方法命名规范:首字母小写,中间的每个单词的首字母都要大写,如:getName。
  • 3)变量的命名规范:变量的命名规范和方法一-样,首字母小写,中间的每个单词的首字母都要大写,如:name。
  • 4)包的命名规范:Java包的名字都是由小写单词组成。但是由于Java面向对象编程的特性,每一名Java程序员都可以编写属于自己的Java包,为了保障每个Java包命名的 唯一性,在最新的Java编程规范中,要求程序员在自己定义的包的名称之前加.上唯一的前缀。由于互联网上的域名称是不会重复的,所以程序员-般采用自己在互联网上的域名称作为自己程序包的唯一前缀。例如:”com.sun.swt"一般公司命名会以“com.公司名项目名.模块名“开头,所以会长一点,如com.land.oa.emp.struts.action.
  • 5)常量的命名规范:基本数据类型的常量名为全大写,如果是由多个单词构成,可以用下划线隔开,如:WEEK_OF_MONTH。

71、如何增加代码的清晰度和可观性?

答:增加代码的清晰度和可观性常用的方式如下: 

1)给代码添加注释。
2)类名/包名等命名规范化。
3)缩进排版规范。
4)添加异常的处理。
5)使用测试类和测试方法。

72、阐述一下static关键字的作用?
答:static表示"静态”的意思,用来修饰成员变量和成员方法,也可以形成静态代码块。 只要这个类被加载,Java 虚拟机就能根据类名在运行时数据区的方法区内找到它们。因此,static成员可以在它的任何对象创建之前访问,无需引用任何对象。

  • 1)修饰成员变量。用static修饰的成员变量不属于对象的数据结构; static变量是属 于类的变量,通常可以通过类名来引用static 成员; static成员变量和类的信息一起存储在方法区,而不是在堆中,一个类的static成员变量只有“一份”,无论该类创建了多少对象
  • 2)修饰成员方法。static 修饰的方法则不需要针对某些对象进行操作,其运行结果仅仅与输入的参数有关,调用时直接用类名引用。由于static在调用时没有具体的对象,因此 在static方法中不能对非static 成员(对象成员)进行访问。static 方法的作用在于提供一些“工具方法”和“工厂方法”等
  • 3)static块:属于类的代码块,在类加载期间执行的代码块,只执行一次,可以用来在软件中加载静态资源。

73、线程池是什么?
答:当一个程序中若创建大量线程,并在任务结束后销毁,会给系统带来过度消耗资源,以及过度切换线程的危险,从而可能导致系统崩溃。为此我们应使用线程池来解决这个问题。首先创建一些线程,它们的集合称为线程池,当服务器接受到一个客户请求后,就从线 程池中取出一个空闲的线程为之服务, 服务结束后不关闭该线程,而是将该线程还回到线程池中。在线程池的编程模式下,任务是提交给整个线程池,而不是直接交给某个线程,线程 池在拿到任务后, 它就在内部找有无空闲的线程,再把任务交给内部某个空闲的线程, 一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。
74、简单说明什么是递归?什么情况会使用?并使用Java实现一个简单的递归程序?
答:

  • 递归做为一种算法在程序设计语言中广泛应用,是指函数/过程/子程序在运行过程中直接或间接调用自身而产生的重入现象。 递归算法-般用于解决三类问题:

  • 1 )数据的定义是按递归定义的。(Fibonacci (斐波那契)函数)

  • 2 )问题解法按递归算法实现。(回溯)

  • 3 )数据的结构形式是按递归定义的。(树的遍历,图的搜索)

75、描述一下JAVA 四中引用类型

  1. 强引用
    在 Java 中最常见的就是强引用, 把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到 JVM 也不会回收。因此强引用是造成 Java 内存泄漏的主要原因之一。
  2. 软引用
    软引用需要用 SoftReference 类来实现,对于只有软引用的对象来说,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收。软引用通常用在对内存敏感的程序中。
  3. 弱引用
    弱引用需要用 WeakReference 类来实现,它比软引用的生存期更短,对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管 JVM 的内存空间是否足够,总会回收该对象占用的内存。
  4. 虚引用
    虚引用需要 PhantomReference 类来实现,它不能单独使用,必须和引用队列联合使用。 虚引用的主要作用是跟踪对象被垃圾回收的状态。

简述 static 和 final 的用法? static:修饰属性,方法,代码块

(1)静态属性:也可叫类变量 类名.属性名 来访问
(共有的类变量与对象无关,只和类有关)
注意:类中的实例变量是在创建对象时被初始化的,被 static 修饰的属性,也就是类变
量,是在类加载时被创建并进行初始化,类加载的过程是进行一次。也就是类变量只会被创
建一次。
(2)静态方法:类名.方法名 直接访问
注意:static 修饰的方法,不能直接访问本类中的非静态(static)成员(包括方法和属性)
本类的非静态方法可以访问本类的静态成员(包括方法和属性),可以调用静态方法。
修饰变量,方法,类
final:修饰变量,类,方法
(1)修饰变量
被 fianl 修饰的成员变量就是常量(常量名大写),一旦赋值不能改变
修饰局部变量:修饰基本数据类型 -> 变量的值不能改变
修饰引用 -> 引用只能指向固定的对象
修饰实例变量:默认值不生效,可以再赋值
(2)修饰方法 :不能被子类覆盖
(3)修饰类:不能被继承
在一个 final 类中的所有方法,默认都是 final 的
注意:final,不能用来修饰构造方法。

写出冒泡排序的算法

for(int i=0;i<arr.length-1;i++){ //控制轮数
for(int j=0;j<arr.length-1-i;j++){ //控制每一轮的次数
if(arr[j]>arr[j+1]){ //每次都是和它下一个元素比
int t=arr[j];
arr[j]=arr[j+1];
arr[j+1]=t;
}
} }

abstract class 和 interface 有什么区别? 在这里插入图片描述

  1. 相同点
    A. 两者都是抽象类,都不能实例化。
    B. interface 实现类及 abstrct class 的子类都必须要实现已经声明的抽象方法。
  2. 不同点
    A. interface 需要实现,要用 implements,而 abstract class 需要继承,要用 extends。
    B. 一个类可以实现多个 interface,但一个类只能继承一个 abstract class。
    C. interface 强调特定功能的实现,而 abstract class 强调所属关系。
    D. 尽管 interface 实现类及 abstrct class 的子类都必须要实现相应的抽象方法,但实
    现的形式不同。interface 中的每一个方法都是抽象方法,都只是声明的 (declaration, 没
    有方法体),实现类必须要实现。而 abstract class 的子类可以有选择地实现。

类有哪三个基本特性?各特性的优点?

类具有封装性、继承性和多态性。
封装性:类的封装性为类的成员提供公有、缺省、保护和私有等访问权限,目的是隐藏类中
的私有变量和类中方法的实现细节。
继承性:允许通过继承原有类的某些特性或全部特性而产生全新的类,原有的累称为父类,
产生的新类称为子类。子类不仅可以直接继承父类的共性,而且也可以创建它特有的个性。
多态性:是指在基类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现
出不同行为,多态性有两种表现形式:重载和覆盖。

Error 和 Exception 有什么区别? 列出你见过的 Exception

并简要说明
答:error 表示系统级的错误和程序不必处理的异常,
是恢复不是不可能但很困难的情况下的一种严重问题;
比如内存溢出,不可能指望程序能处理这样的情况;
exception 表示需要捕捉或者需要程序进行处理的异常,
是一种设计或实现问题;也就是说,它表示如果程序运行正常,
从不会发生的情况。 常见异常有: NullPointerException:
当操作一个空引用时会出现此错误。 NumberFormatException:
数据格式转换出现问题时出现此异常。 ClassCastException:
强制类型转换类型不匹配时出现此异常。 ArrayIndexOutOfBoundsException:
数组下标越界,当使用一个不存在的数组下标时出现此异常。

java 中会存在内存泄露吗?请简单描述。

答:内存泄露是指系统中存在无法回收的内存,
有时候会造成内存不足或系统崩溃。Java 存在内存泄露。
Java 中的内存泄露当然是指:存在无用但是垃圾回收器无法回收的对象。
而且即使有内存泄露问题存在,也不一定会表现出来。
自己实现堆栈的数据结构时有可能会出现内存泄露。

多线程有几种实现方法,都是什么?同步有几种实现方法, 都是什么?

答:多线程有两种实现方法:继承 Thread 类或者实现 Runnable 接口。
实现同步也有两种方法:一种是同步方法,另一种是同步代码块。
同步方法是在方法返回类型前面加上 synchronized 关键字
同步代码块是 synchronized (这里写需要同步的对象){…}

.sleep()和 wait()有什么区别?

答案: (2)不同点:

  1. Thread 类的方法:sleep(),yield()等
    Object 的方法:wait()和 notify()等
    2.每个对象都有一个锁来控制同步访问。Synchronized 关键字可以和对象的锁交互,来
    实现线程的同步。
    sleep 方法没有释放锁,
    wait 方法释放了锁,使得其他线程可以使用同步控制块或者方法。
    3.wait,notify 和 notifyAll 只能在同步控制方法或者同步控制块里面使用,而 sleep 可
    以在任何地方使用
    4.sleep 必须捕获异常,而 wait,notify 和 notifyAll 不需要捕获异常

谈谈 java 跟你所知道的其它的语言相比,有什么优点??

Java 是一种可以撰写跨平台应用程序的面向对象的程序设计语言。Java 技术具有卓越
的通用性、高效性、平台移植性和安全性,广泛应用于 PC、数据中心、游戏控制台、科学超
级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。
Java 是功能完善的通用程序设计语言,可以用来开发可靠的、要求严格的应用程序。
java 是纯面向对象开发,功能强大,分支众多,没有 java 不能做的软件。C/S 也好 B/S 也
好。从功能上讲,没有语言可以和 java 相比。
C 是面向过程编程的,这样往往会导致所谓的单一程序,既所有的功能只能包含在几个
(通常是一个)代码模块中。当然,C 语言也有自身的不足,比如:C 语言的语法限制不太
严格,对变量的类型约束不严格,影响程序的安全性,对数族下标越界不作检查等。从应用
的角度,C 语言比其他高级语言较难掌握。

谈谈你对面向对象的理解??

所谓的面向对象就是将我们的程序模块化,对象化,把具体事物的特性属性和通过这些
属性来实现一些动作的具体方法放到一个类里面,这就是封装。封装是我们所说的面相对象
编程的特征之一。除此之外还有继承和多态。继承有点类似与我们生物学上的遗传,就是子
类的一些特征是来源于父类的,儿子遗传了父亲或母亲的一些性格,或者相貌,又或者是运
动天赋。有点种瓜得瓜种豆得豆的意思。面向对象里的继承也就是父类的相关的属性,可以
被子类重复使用,子类不必再在自己的类里面重新定义一回,父类里有点我们只要拿过来用
就好了。而对于自己类里面需要用到的新的属性和方法,子类就可以自己来扩展了。当然,
会出现一些特殊情况,就是我们在有一些方法在父类已经定义好了,但是子类我们自己再用
的时候,发现,其实,我们的虽然都是计算工资的,但是普通员工的工资计算方法跟经理的
计算方法是不一样的,所以这个时候,我们就不能直接调用父类的这个计算工资的方法了。
这个时候我们就需要用到面向对象的另一个特性,多态。对,就是多态,我们要在子类里面
把父类里面定义计算工资的方法在子类里面重新实现一遍。多态包含了重载和重写。重写很
简单就是把子类从父亲类里继承下来的方法重新写一遍,这样,父类里相同的方法就被覆盖
了,当然啦,你还是可以通过 super.CaculSalary 方法来调用父类的工资计算方法。而重载
就是类里面相同方法名,不同形参的情况,可以是形参类型不同或者形参个数不同,或者形
参顺序不同,但是不能使返回值类型不同。

简单讲一下 java 的跨平台原理

java 源程序(.java 文件)通过编译器编译成为 Class 文件(字节码文件),而它的 class
文件是基于字节码(以 byte 为单位存储的文件)的,而字节码文件是描述程序要运行的的
虚指令的集合,这些虚指令的集合与任何的平台无关,Java 虚拟机认识它(只要在不同的
平台下部署相应的 jre,运行 jvm!就可以了)
有了基本数据类型,为什么还需要包装类型?
我们知道 Java 是一个面相对象的编程语言,基本类型并不具有对象的性质,为了让基
本类型也具有对象的特征,就出现了包装类型(如我们在使用集合类型 Collection 时就一
定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象
的性质,并且为其添加了属性和方法,丰富了基本类型的操作。
另外,当需要往 ArrayList,HashMap 中放东西时,像 int,double 这种基本类型是放不进
去的,因为容器都是装 object 的,这是就需要这些基本类型的包装器类了。

说一下"=="和 equals 方法究竟有什么区别?

操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所
存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用
操作
符。
equals 方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是
否相同,它比较的两个对象是独立的。

讲一下 java 中的集合

set(集)、list(列表)和 map(映射)。
区别嘛 HASHMAP 只有 KEY 和 value 值对应的。。set 是可以自动清楚相同的元素
list 是其对象以线性方式存储,没有特定顺序,只有一个开头和一个结尾,当然,它与根
本没有顺序的集是不同的。
列表在数据结构中分别表现为:数组和向量、链表、堆栈、队列。

ArrayList 和 LinkedList 的区别?

1.ArrayList 是实现了基于动态数组的数据结构,LinkedList 基于链表的数据结构。
2.对于随机访问 get 和 set,ArrayList 觉得优于 LinkedList,因为 LinkedList 要移动指
针。
3.对于新增和删除操作 add 和 remove,LinedList 比较占优势,因为 ArrayList 要移动数
据。

讲一下 HashMap 和 HashTable 的区别?

在 Java 2 以前,一般使用 Hashtable 来映射键值和元素。为了使用 Java 集合框架,Java
对 Hashtable 进行了重新设计,但是,为了向后兼容保留了所有的方法。Hashtable 实现
了 Map 接口,除了 Hashtable 具有同步功能之外,它与 HashMap 的用法是一样的。·
在使用时一般是用 ArrayList 代替 Vector,LinkedList 代替 Stack,HashMap 代替
HashTable,即使在多线程中需要同步,也是用同步包装类。

请说出集合类中 List、Map、Set 的区别

答:List 和 Set 继承了 Collection 接口,而 map 不是;
List 中存放元素有顺序并且可以重复;
set 中存放的元素是无序并且是不可能重复的;
Map 中存放是键值对。

Collection 和 Collections 的区别?

答:Collection 是 java.util 下的接口,它是各种集合的父接口,
继承于它的接口主要有 Set 和 List;Collections 是个 java.util 下的类,
是针对集合的帮助类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操
作。
HashSet :内部封装了 HashMap 和 TreeMap,数据保存在键这一列
LinkedHashMap(哈希表,存放数据以链表来连接,数组存放无序但链表连接有序,
可看做一个有序的 HashMap),既可快速定位,查找数据,又可以使数据存放有序
ConcurrentHashMap(分段加锁)Concurrent-同步
在这里插入图片描述

String、StringBuffer 和 StringBuilder 的区别?

  1. 首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:
    StringBuilder > StringBuffer > String
  2. 再来说线程安全
    在线程安全上,StringBuilder 是线程不安全的,而 StringBuffer 是线程安
    全的
    String:适用于少量的字符串操作的情况
    StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
    StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

讲一下线程的几种实现方式?

extends Thread
implements Runnable
implements Callable
Runnable 和 Callable 的区别是,
(1)Callable 规定的方法是 call(),Runnable 规定的方法是 run()。
(2)Callable 的任务执行后可返回值,而 Runnable 的任务是不能返回值得 (3)call 方法可以抛出异常,run 方法不可以
(4)运行 Callable 任务可以拿到一个 Future 对象,表示异步计算的结果。

讲一下线程的几种启动方式? .

  1. 第一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法,然后
    在 run 方法里填写相应的逻辑代码。

  2. 第二种方法是实现 Runnable 接口,并编写 run 方法,相比继承 Thread 类创建线程的好处是
    以实现接口的方式创建线程可以对类进行更好的扩展,该类可以继承其他类来扩展自身需
    求,相比第一种方式更加灵活,扩展性强。

实现 Callable 接口创建线程与 Runnable 接口的不同之处在于:如果你想要在线程执行完
毕之后得到带有返回值的线程则实现 Callable 接口

有没有使用过线程并发库?

在 java5 之后,就有了线程池的功能了,在介绍线程池之前,先来简单看一下线程池的概念。
假设我开了家咨询公司,那么每天会有很多人过来咨询问题,如果我一个个接待的话,必然
有很多人要排队,这样效率就很差,我想解决这个问题,现在我雇几个客服,来了一个咨询
的,我就分配一个客服去接待他,再来一个,我再分配个客服去接待……如果第一个客服接
待完了,我就让她接待下一个咨询者,这样我雇的这些客服可以循环利用。这些客服就好比
不同的线程,那么装这些线程的容器就称为线程池。

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

静态变量也叫类变量,这种变量前加了 static 修饰符。可以直接用类名调用,也可以用对
象调用,而且所有对象的同一个类变量 都是共享同一块内存空间。
实例变量也叫对象变量,这种变量没有加 static 修饰符。只能通过对象调用,
而且所有对象的同一个实例变量是共享不同的内存空间的。
区别在于:
静态变量是所有对象共有的,某一个对象将它的值改变了,其他对象再去获取
它的值,得到的是改变后的值;
实例变量则是每一个对象私有的,某一个对象将它的值改变了,不影响其他对
象取值的结果,其他对象仍会得到实例变量一开始就被赋予的值。

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

会执行 try{}中的 return 执行后在没有返回数据时先去执行 finally{}中的代码,然后再
返回。所以说 finally{}在 return 中间执行

同步和异步有何异同,在什么情况下分别使用他们?举例 说明

如果数据将在线程间共享.例如正在写的数据以后可能被另一个线程读到,或者正
在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行
同步存取.
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希
望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往
往更有效率.

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

Java 中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种
流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。Java
中其他多种多样变化的流均是由它们派生出来的.

&和&&的区别?

&和&&都可以用作逻辑运算符,表示逻辑与。当运算符两边的表达式都为 true 时,结果才为
true;否则,结果为 false。
另外&&还具有短路功能,也就是说,当&&左边的表达式结果为 false 时,将不再运算&&右边
的表达式,结果肯定为 false。例如,对于 if(str!=null&&!str.equals(“”)),当 str 为
null 时,不会对&&右边的表达式进行运算,否则会出现空指针异常。
&还可以用作位运算符,当&两边的表达式不是 boolean 类型时,&表示按位与。

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

数组中没有 length()这个方法,但是数组中有 length 这个属性。用来表示数组的长度。
String 中有 length()这个方法。用来得到字符串的长度。

构造器 Constructor 是否可被 override?

构造器 Constructor 不能被继承,因此不能重写 Override,但可以被重载 Overload。
Constructor 不能被继承,所以 Constructor 也就不能被 override。每一个类必须有自己
的构造函数,负责构造自己这部分的构造。子类不会覆盖父类的构造函数,相反必须负责
在一开始调用父类的构造函数。

构造器如何工作?

Java 在构造实例时的顺序是这样的:
1、分配对象空间,并将对象中成员初始化为 0 或者空,java 不允许用户操纵一个不
定值的对象。
2、执行属性值的显式初始化
3、执行构造器
4 、将变量关联到堆中的对象上

super 与 this 的区别?

不同点:
1、super()主要是对父类构造函数的调用,this()是对重载构造函数的调用
2、super()主要是在继承了父类的子类的构造函数中使用,是在不同类中的使用;this()
主要是在同一类的不同构造函数中的使用
相同点:
1、super()和 this()都必须在构造函数的第一行进行调用,否则就是错误的

GC 是什么? 为什么要有 GC?

GC 是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,
忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java 提供的 GC 功能可以自
动监测对象是否超过作用域从而达到自动回收内存的目的,
Java 语言没有提供释放已分配内存的显示操作方法。Java 程序员不用担心内存管理,因为
垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc()或
Runtime.getRuntime().gc(),但 JVM 可以屏蔽掉显示的垃圾回收调用。
垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一
个单独的低优先级的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使
用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃
圾回收。
在 Java 诞生初期,垃圾回收是 Java 最大的亮点之一,因为服务器端的编程需要有效的防止
内存泄露问题,然而时过境迁,如今 Java 的垃圾回收机制已经成为被诟病的东西。移动智
能终端用户通常觉得 iOS 的系统比 Android 系统有更好的用户体验,其中一个深层次的原
因就在于 Android 系统中垃圾回收的不可预知性。

接口是否可继承接口? 抽象类是否可实现(implements)接 口? 抽象类是否可继承实体类?

接口可以继承接口。抽象类可以实现(implements)接口,抽象类可继承实体类,但前提
是实体类必须有明确的构造函数

内部类可以引用他包含类的成员吗?有没有什么限制?

完全可以。如果不是静态内部类,那没有什么限制!
如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类
的普通成员变量,而只能访问外部类中的静态成员

Java 有没有 goto?

答:goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。(根据 James Gosling(Java
之父)编写的《The Java Programming Language》一书的附录中给出了一个 Java 关键字
列表,其中有 goto 和 const,但是这两个是目前无法使用的关键字,因此有些地方将其
称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉 C 语言的程序员都
知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字)

解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法

答:通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保
存都使用内存中的栈空间;而通过 new 关键字和构造器创建的对象放在堆空间;程序中的
字面量(literal)如直接书写的 100、”hello”和常量都是放在静态区中。栈空间操作起来最
快但是栈很小,通常大量的对象都是放在堆空间,理论上整个内存没有被其他进程使用的空
间甚至硬盘上的虚拟内存都可以被当成堆空间来使用。

用最有效率的方法计算 2 乘以 8?

答: 2 << 3(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次方)。

在 Java 中,如何跳出当前的多重嵌套循环?

答:在最外层循环前加一个标记如 A,然后用 break A;可以跳出多重循环。(Java 中支持带标
签的 break 和 continue 语句,作用有点类似于 C 和 C++中的 goto 语句,但是就像要避免使
用 goto 一样,应该避免使用带标签的 break 和 continue,因为它不会让你的程序变得更优
雅,很多时候甚至有相反的作用,所以这种语法其实不知道更好)

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

答:不对,如果两个对象 x 和 y 满足 x.equals(y) == true,它们的哈希码(hash code)应当相
同。Java 对于 eqauls 方法和 hashCode 方法是这样规定的:(1)如果两个对象相同(equals 方
法返回 true),那么它们的 hashCode 值一定要相同;(2)如果两个对象的 hashCode 相同,它
们并不一定相同。当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使
用容器时,相同的对象可以出现在 Set 集合中,同时增加新元素的效率会大大下降(对于使
用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。

char 型变量中能不能存贮一个中文汉字,为什么?

答:char 类型可以存储一个中文汉字,因为 Java 中使用的编码是 Unicode(不选择任何特定
的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个 char 类型占 2 个字
节(16 比特),所以放一个中文是没问题的。

Anonymous Inner Class(匿名内部类)是否可以继承其它类? 是否可以实现接口?

答:可以继承其他类或实现其他接口,在 Swing 编程和 Android 开发中常用此方式来实现事
件监听和回调。

内部类可以引用它的包含类(外部类)的成员吗?有没有什么限 制?

答:一个内部类对象可以访问创建它的外部类对象的成员,包括私有成员。

Java 中的 final 关键字有哪些用法?

答:(1)修饰类:表示该类不能被继承;(2)修饰方法:表示方法不能被重写;(3)修饰变量:表
示变量只能一次赋值以后值不能被修改(常量)。

写出常见的 5 个 RuntimeException

(1)java.lang.NullPointerException 空指针异常,出现原因:调用了未经初始化的对性爱
那个或者不存在的对象。
(2)ClassNoFoundException 指定类找不到,出现原因:类的名称和路径加载错误,通常
是试图通过字符串来加载某个类时可能引发异常。
(3)NumberFormatException 字符串转换为数字异常,出现原因:字符串数据中包含非数
字型字符。
(4)IndexOutOfBoundsException 数组下标越界异常
(5)IllegalArgumentException 方法传递参数错误
(6)ClassCastException 数据类型转换异常
(7)NoClassDefFoundExcetion 未找到类定义错误
(8)SQLException SQL 异常
(9)InstantiationException 实例化异常
(10)NoSuchMethodExceptioin 方法不存在异常

阐述 final、finally、finalize 的区别。

答:

  • final:修饰符(关键字)有三种用法:如果一个类被声明为 final,意味着它不能再派生出
    新的子类,即不能被继承,因此它和 abstract 是反义词。将变量声明为 final,可以保证它们
    在使用中不被改变,被声明为 final 的变量必须在声明时给定初值,而在以后的引用中只能
    读取不可修改。被声明为 final 的方法也同样只能使用,不能在子类中被重写。
  • finally:通常放在 try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行
    还是发生异常,这里的代码只要 JVM 不关闭都能执行,可以将释放外部资源的代码写在
    finally 块中。
  • finalize:Object 类中定义的方法,Java 中允许使用 finalize()方法在垃圾收集器将对象从内存
    中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重
    写 finalize()方法可以整理系统资源或者执行其他清理工作。

阐述 ArrayList、Vector、LinkedList 的存储性能和特性。

答:ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以
便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等
内存操作,所以索引数据快而插入数据慢,Vector 中的方法由于添加了 synchronized 修饰,
因此 Vector 是线程安全的容器,但性能上较 ArrayList 差,因此已经是 Java 中的遗留容器。
LinkedList 使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形
成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,内存的
利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项
的前后项即可,所以插入速度较快。Vector 属于遗留容器(Java 早期的版本中提供的容器,
除此之外,Hashtable、Dictionary、BitSet、Stack、Properties 都是遗留容器),已经不推荐使
用,但是由于 ArrayList 和 LinkedListed 都是非线程安全的,如果遇到多个线程操作同一个容
器的场景,则可以通过工具类 Collections 中的 synchronizedList 方法将其转换成线程安全的
容器后再使用(这是对装潢模式的应用,将已有对象传入另一个类的构造器中创建新的对象
来增强实现)。

Collection 和 Collections 的区别?

答:Collection 是一个接口,它是 Set、List 等容器的父接口;Collections 是个一个工具类,提
供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等
等。

List、Map、Set 三个接口存取元素时,各有什么特点?

答:List 以特定索引来存取元素,可以有重复元素。Set 不能存放重复元素(用对象的
equals()方法来区分元素是否重复)。Map 保存键值对(key-value pair)映射,映射关系
可以是一对一或多对一。Set 和 Map 容器都有基于哈希存储和排序树的两种实现版本,基
于哈希存储的版本理论存取时间复杂度为 O(1),而基于排序树版本的实现在插入或删除元
素时会按照元素或元素的键(key)构成排序树从而达到排序和去重的效果。

当一个线程进入一个对象的 synchronized 方法 A 之后,其 它线程是否可进入此对象的 synchronized 方法 B?

答:不能。其它线程只能访问该对象的非同步方法,同步方法则不能进入。因为非静态方法
上的 synchronized 修饰符要求执行方法时要获得对象的锁,如果已经进入 A 方法说明对象锁
已经被取走,那么试图进入 B 方法的线程就只能在等锁池(注意不是等待池哦)中等待对象
的锁。

请说出与线程同步以及线程调度相关的方法。

答:

  • wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
  • sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理
    InterruptedException 异常;
  • notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某
    一个等待状态的线程,而是由 JVM 确定唤醒哪个线程,而且与优先级无关;
  • notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让
    它们竞争,只有获得锁的线程才能进入就绪状态;

Java 中如何实现序列化,有什么意义?

答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可
以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决
对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。
要实现序列化,需要让一个类实现 Serializable 接口,该接口是一个标识性接口,标注该类对
象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过 writeObject(Object)
方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立
对象输入流,然后通过 readObject 方法从流中读取对象。序列化除了能够实现对象的持久化
之外,还能够用于对象的深度克隆.

如何通过反射创建对象?

答:

  • 方法 1:通过类对象调用 newInstance()方法,例如:String.class.newInstance()
  • 方法 2:通过类对象的 getConstructor()或 getDeclaredConstructor()方法获得构造器
    (Constructor)对象并调用其 newInstance()方法创建对象,例如:
    String.class.getConstructor(String.class).newInstance(“Hello”);

谈谈 JVM 的内存结构和内存分配?

Java 内存模型
Java 虚拟机将其管辖的内存大致分三个逻辑部分:方法区(Method Area)、 Java
栈和 Java 堆。
1、方法区是静态分配的,编译器将变量绑定在某个存储位置上,而且这些绑定
不会在运行时改变。常数池,源代码中的命名常量、 String 常量和 static 变量
保存在方法区。
2、 Java Stack 是一个逻辑概念,特点是后进先出。一个栈的空间可能是连续的,
也可能是不连续的。最典型的 Stack 应用是方法的调用, Java 虚拟机每调用一
次方法就创建一个方法帧(frame),退出该
方法则对应的 方法帧被弹出(pop)。栈中存储的数据也是运行时确定的。
3、 Java 堆分配(heap allocation)意味着以随意的顺序,在运行时进行存储空间分
配和收回的内存管理模型。堆中存储的数据常常是大小、数量和生命期在编译时
无法确定的。 Java 对象的内存总是在 heap 中分配。
b) java 内存分配
1、基础数据类型直接在栈空间分配; 2、方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收; 3、引用数据类型,需要用 new 来创建,既在栈空间分配一个地址空间,又在堆
空间分配对象的类变量;
4、方法的引用参数,在栈空间分配一个地址空间,并指向堆空间的对象区,当
方法调用完后从栈空间回收;
5、局部变量 new 出来时,在栈空间和堆空间中分配空间,当局部变量生命周期
结束后,栈空间立刻被回收,堆空间区域等待 GC 回收;
6、方法调用时传入的实际参数,先在栈空间分配,在方法调用完成后从栈空间
释放;
7、字符串常量在 DATA 区域分配 , this 在堆空间分配; 8、数组既在栈空间分配数组名称, 又在堆空间分配数组实际的大小。

什么是双亲委派机制

双亲委派模式的工作原理的是;如果一个类加载器收到了类加载请求,它并不会自己先去加
载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则
进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完
成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己
去加载,这就是双亲委派模式,即每个儿子都不愿意干活,每次有活就丢给父亲去干,直到
父亲说这件事我也干不了时,儿子自己想办法去完成,这不就是传说中的双亲委派模式.那
么这种模式有什么作用呢?

Static 关键字有哪些作用?

Static 有两种作用: 第一, 为某特定数据类型或对象分配单一的存储空间,而与创建对象
的个数无关。 第二, 实现某个方法或属性与类而不是对象关联在一起。 Static 主要是有 4
种使用情况: Static 修饰成员变量:用 static 修饰的变量称之为静态变量或者也叫类变量/
全局变量。静态变量 是随着类的加载而加载到方法区中的静态区,并且在静态区中赋予了
初始值。静态变量是在对 象之前产生,所以可以不通过对象来调用,而是通过类来调用,
所以可以通过类名.静态变量的 方式调用静态变量。由于每个对象在堆内存中存储的是静态
变量在静态区中的地址,所以所有 的对象本质上共用一个静态变量。Static 修饰成员方法:
用 static 修饰的方法就称之为静态方法,也叫类方法。静态方法在类加载 的时候加载到了
方法区中的静态区,在调用的时候到栈内存中执行。—静态方法是先于对象而 存在的。静
态方法可以通过类名.方法名的方式来调用执行。 静态代码块:静态代码块在类中是独立于
成员变量和成员方法的代码块。它不在任何一个方法 体内,jvm 在加载类时会执行静态代
码块,静态代码块是先于构造代码块执行。静态代码块在 类加载的时候执行,只执行一次。
静态内部类:静态内部类是指被声明为静态内部类,它可以不依赖与外部类实例对象而被实
例 化,而通常的内部类需要在外部类实例化后才能实例化。静态内部类不能与外部类有相
同的名 字,不能访问外部类的普通成员变量,只能访问外部类中的静态成员和静态方法

Instanceof 有什么作用?

Instanceof 的作用是判断一个引用类型的变量所指向的对象是否是一个类的实例。

什么是不可变类?

不可变类是指当创建了这个类的实例后,就不允许修改它的值了,也就是说,一个对象一
旦被 创建出来,在其整个生命周期中,它的成员变量就不能被修改了。

值传递与引用传递的区别?

值传递:在方法调用中,实参会把它的值传递给形参,形参只是用实参的值初始化一个临时
的 存储单元(方法内的局部变量),因此性参与实参虽然有着相同的值,但是却有着不用的
存储单 元,因此对形参的改变不会影响实参的值。 引用传递:在方法的调用中,传递的是
对象(也可以看做是对象的地址),这时形参与实参指向 同一块存储单元(对象),因此对
形参的修改就会影响实参的值。

强制类型转换的注意事项有哪些?

Java 在涉及 byte、short 和 char 类型的运算时,首先会把这些类型的变量值强制转换为
int 类型, 然后对 int 类型的值进行计算,最后得到的值也是 int 类型。因此,如果把两个
short 类型的值相 加,最后得到的结果是 int 型;如果把两个 byte 类型的值相加,最后也
会得到一个 int 类型的值。 如果需要得到 short 类型的结果,就必须显示地把运算结果转
换为 short 类型。

++i 与 i++的区别?

++i 先运算后赋值,i++先赋值后运算。

字符串存储的机制是什么?

字符串会存储在常量池中。在给字符串赋值的时候,JVM 会检查常量池中是否已经存在该
字符 串,如果存在则直接引用该地址,否则会在常量池中创建该字符串然后引用该地址

知秋君
上一篇 2024-08-17 17:36
下一篇 2024-08-17 17:02

相关推荐