北京治疗白癜风到那家医院 http://pf.39.net/bdfyy/

年Java面试题基础系列道

Java面试题(一)

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

2、访问修饰符public,private,protected,以及不写(默认)时的区别?

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

4、floatf=3.4;是否正确?

5、shorts1=1;s1=s1+1;有错吗?shorts1=1;s1+=1;有错吗?

6、Java有没有goto?

7、int和Integer有什么区别?

8、和的区别?

9、解释内存中的栈(stack)、堆(heap)和方法区(methodarea)的用法。

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

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

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

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

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

15、构造器(constructor)是否可被重写(override)?

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

17、是否可以继承String类?

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

19、String和StringBuilder、StringBuffer的区别?

20、重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?

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

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

23、抽象类(abstractclass)和接口(interface)有什么异同?

24、静态嵌套类(StaticNestedClass)和内部类(InnerClass)的不同?

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

26、抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?

27、阐述静态变量和实例变量的区别。

28、是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?

29、如何实现对象克隆?

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

31、Strings=newString(“xyz”);创建了几个字符串对象?

32、接口是否可继承(extends)接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concreteclass)?

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

34、AnonymousInnerClass(匿名内部类)是否可以继承其它类?是否可以实现接口?

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

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

37、指出下面程序的运行结果

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

39、如何实现字符串的反转及替换?

40、怎样将GB编码的字符串转换为ISO--1编码的字符串?

41、日期和时间:

42、打印昨天的当前时刻。

43、比较一下Java和JavaSciprt。

44、什么时候用断言(assert)?

45、Error和Exception有什么区别?

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

47、Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?

48、运行时异常与受检异常有何异同?

49、列出一些你常见的运行时异常?

50、阐述final、finally、finalize的区别。

51、类ExampleA继承Exception,类ExampleB继承ExampleA。

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

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

54、Collection和Collections的区别?

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

56、TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?

57、Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?

58、线程的sleep()方法和yield()方法有什么区别?

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

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

61、编写多线程程序有几种实现方式?

62、synchronized关键字的用法?

63、举例说明同步和异步。

64、启动一个线程是调用run()还是start()方法?

65、什么是线程池(threadpool)?

66、线程的基本状态以及状态之间的关系?

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

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

69、Java中有几种类型的流?

70、写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。

71、如何用Java代码列出一个目录下所有的文件?

72、用Java的套接字编程实现一个多线程的回显(echo)服务器。

73、XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?

74、你在项目中哪些地方用到了XML?

75、阐述JDBC操作数据库的步骤。

76、Statement和PreparedStatement有什么区别?哪个性能更好?

77、使用JDBC操作数据库时,如何提升读取数据的性能?如何提升更新数据的性能?

78、在进行数据库编程时,连接池有什么作用?

79、什么是DAO模式?

80、事务的ACID是指什么?

82、JDBC能否处理Blob和Clob?

83、简述正则表达式及其用途。

84、Java中是如何支持正则表达式操作的?

85、获得一个类的类对象有哪些方式?

88、如何通过反射调用对象的方法?

90、简述一下你了解的设计模式。

91、用Java写一个单例类。

92、什么是UML?

93、UML中有哪些常用的图?

95、用Java写一个折半查找。

Java面试题(二)

1、Java中能创建volatile数组吗?

2、volatile能使得一个非原子操作变成原子操作吗?

3、volatile修饰符的有过什么实践?

4、volatile类型变量提供什么保证?

5、10个线程和2个线程的同步代码,哪个更容易写?

6、你是如何调用wait()方法的?使用if块还是循环?为什么?

8、什么是Busyspin?我们为什么要使用它?

9、Java中怎么获取一份线程dump文件?

10、Swing是线程安全的?

11、什么是线程局部变量?

12、用wait-notify写一段代码来解决生产者-消费者问题?

13、用Java写一个线程安全的单例模式(Singleton)?

14、Java中sleep方法和wait方法的区别?

15、什么是不可变对象(immutableobject)?Java中怎么创建一个不可变对象?

16、我们能创建一个包含可变对象的不可变对象吗?

17、Java中应该使用什么数据类型来代表价格?

18、怎么将byte转换为String?

19、Java中怎样将bytes转换为long类型?

20、我们能将int强制转换为byte类型的变量吗?如果该值大于byte类型的范围,将会出现什么现象?

21、存在两个类,B继承A,C继承B,我们能将B转换为C么?如C=(C)B;

22、哪个类包含clone方法?是Cloneable还是Object?

23、Java中++操作符是线程安全的吗?

23、不是线程安全的操作。它涉及到多个指令,如读取变量值,增加,然后存储回内存,这个过程可能会出现多个线程交差。

24、a=a+b与a+=b的区别

25、我能在不进行强制转换的情况下将一个double值赋值给long类型的变量吗?

26、3*0.1==0.3将会返回什么?true还是false?

27、int和Integer哪个会占用更多的内存?

28、为什么Java中的String是不可变的(Immutable)?

31、64位JVM中,int的长度是多数?

32、Serial与ParallelGC之间的不同之处?

33、32位和64位的JVM,int类型变量的长度是多数?

34、Java中WeakReference与SoftReference的区别?

35、WeakHashMap是怎么工作的?

36、JVM选项-XX:+UseCompressedOops有什么作用?为什么要使用?

37、怎样通过Java程序来判断JVM是32位还是64位?

38、32位JVM和64位JVM的最大堆内存分别是多数?

39、JRE、JDK、JVM及JIT之间有什么不同?

40、解释Java堆空间及GC?

41、你能保证GC执行吗?

42、怎么获取Java程序使用的内存?堆使用的百分比?

43、Java中堆和栈有什么区别?

44、“a==b”和”a.equals(b)”有什么区别?

45、a.hashCode()有什么用?与a.equals(b)有什么关系?

46、final、finalize和finally的不同之处?

47、Java中的编译期常量是什么?使用它又什么风险?

48、List、Set、Map和Queue之间的区别(答案)

49、poll()方法和remove()方法的区别?

50、Java中LinkedHashMap和PriorityQueue的区别是什么?

51、ArrayList与LinkedList的不区别?

52、用哪两种方式来实现集合的排序?

53、Java中怎么打印数组?

54、Java中的LinkedList是单向链表还是双向链表?

55、Java中的TreeMap是采用什么树实现的?(答案)

56、Hashtable与HashMap有什么不同之处?

57、Java中的HashSet,内部是如何工作的?

58、写一段代码在遍历ArrayList时移除一个元素?

59、我们能自己写一个容器类,然后使用for-each循环码?

60、ArrayList和HashMap的默认大小是多数?

61、有没有可能两个不相等的对象有有相同的hashcode?

62、两个相同的对象会有不同的的hashcode吗?

63、我们可以在hashcode()中使用随机数字吗?

64、Java中,Comparator与Comparable有什么不同?

66、在我Java程序中,我有三个socket,我需要多少个线程来处理?

67、Java中怎么创建ByteBuffer?

68、Java中,怎么读写ByteBuffer?

69、Java采用的是大端还是小端?

70、ByteBuffer中的字节序是什么?

71、Java中,直接缓冲区与非直接缓冲器有什么区别?

72、Java中的内存映射缓存区是什么?

73、socket选项TCPNODELAY是指什么?

74、TCP协议与UDP协议有什么区别?

75、Java中,ByteBuffer与StringBuffer有什么区别?(答案)

76、Java中,编写多线程程序的时候你会遵循哪些最佳实践?

77、说出几点Java中使用Collections的最佳实践

78、说出至少5点在Java中使用线程的最佳实践。

79、说出5条IO的最佳实践(答案)

80、列出5个应该遵循的JDBC最佳实践

81、说出几条Java中方法重载的最佳实践?

82、在多线程环境下,SimpleDateFormat是线程安全的吗?

83、Java中如何格式化一个日期?如格式化为ddMMyyyy的形式?

84、Java中,怎么在格式化的日期中显示时区?

85、Java中java.util.Date与java.sql.Date有什么区别?

86、Java中,如何计算两个日期之间的差距?

87、Java中,如何将字符串YYYYMMDD转换为日期?

89、如何测试静态方法?(答案)

90、怎么利用JUnit来测试一个方法的异常?

91、你使用过哪个单元测试库来测试你的Java程序?

92、

Before和

BeforeClass有什么区别?

93、怎么检查一个字符串只包含数字?解决方案

94、Java中如何利用泛型写一个LRU缓存?

95、写一段Java程序将byte转换为long?

96、在不使用StringBuffer的前提下,怎么反转一个字符串?

97、Java中,怎么获取一个文件中单词出现的最高频率?

98、如何检查出两个给定的字符串是反序的?

99、Java中,怎么打印出一个字符串的所有排列?

、Java中,怎样才能打印出数组中的重复元素?

、Java中如何将字符串转换为整数?

、在没有使用临时变量的情况如何交换两个整数变量的值?

、接口是什么?为什么要使用接口而不是直接使用具体类?

、Java中,抽象类与接口之间有什么不同?

、除了单例模式,你在生产环境中还用过什么设计模式?

、你能解释一下里氏替换原则吗?

、什么情况下会违反迪米特法则?为什么会有这个问题?

、适配器模式是什么?什么时候使用?

、什么是“依赖注入”和“控制反转”?为什么有人使用?

、抽象类是什么?它与接口有什么区别?你为什么要使用过抽象类?

、构造器注入和setter依赖注入,那种方式更好?

、依赖注入和工程模式之间有什么不同?

、适配器模式和装饰器模式有什么区别?

、适配器模式和代理模式之前有什么不同?

、什么是模板方法模式?

、什么时候使用访问者模式?

、什么时候使用组合模式?

、继承和组合之间有什么不同?

、描述Java中的重载和重写?

、Java中,嵌套公共静态类与顶级类有什么不同?

、OOP中的组合、聚合和关联有什么区别?

、给我一个符合开闭原则的设计模式的例子?

、抽象工厂模式和原型模式之间的区别?

、嵌套静态类与顶级类有什么区别?

、你能写出一个正则表达式来判断一个字符串是否是一个数字吗?

、Java中,受检查异常和不受检查异常的区别?

、Java中,throw和throws有什么区别

、Java中,Serializable与Externalizable的区别?

、Java中,DOM和SAX解析器有什么不同?

、说出JDK1.7中的三个新特性?

、说出5个JDK1.8引入的新特性?

、Java中,Maven和ANT有什么区别?

上一篇更新1~20题的答案解析

年Java面试题基础系列道(1),快看看哪些你还不会?

本次更新Java面试题(一)的21~50题答案

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

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

由于Java的跨平台性,经过编译的Java源程序并不是一个可执行程序,而是一个或多个类文件。当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。类的加载是指把类的.class文件中的数据读入到内存中,通常是创建一个字节数组读入.class文件,然后产生与所加载类对应的Class对象。加载完成后,Class对象还不完整,所以此时的类还不可用。当类被加载后就进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引用替换为直接引用)三个步骤。最后JVM对类进行初始化,包括:1)如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;2)如果类中存在初始化语句,就依次执行这些初始化语句。

类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和用户自定义类加载器(java.lang.ClassLoader的子类)。从Java2(JDK1.2)开始,从Java2(JDK1.2)开始,类加载过程采取了父亲委托机制(PDM)。PDM更好的保证了Java平台的安全性,在该机制中,JVM自带的Bootstrap是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。JVM不会向Java程序提供对Bootstrap的引用。下面是关于几个类加载器的说明:

(1)Bootstrap:一般用本地代码实现,负责加载JVM基础核心类库(rt.jar);

(2)Extension:从java.ext.dirs系统属性所指定的目录中加载类库,它的父加载器是Bootstrap;

(3)System:又叫应用类加载器,其父类是Extension。它是应用最广泛的类加载器。它从环境变量classpath或者系统属性java.class.path所指定的目录中记载类,是用户自定义加载器的默认父加载器。

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

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

补充:使用Unicode意味着字符在JVM内部和外部有不同的表现形式,在JVM内部都是Unicode,当这个字符被从JVM内部转移到外部时(例如存入文件系统中),需要进行编码转换。所以Java中有字节流和字符流,以及在字符流和字节流之间进行转换的转换流,如InputStreamReader和OutputStreamReader,这两个类是字节流和字符流之间的适配器类,承担了编码转换的任务;对于C程序员来说,要完成这样的编码转换恐怕要依赖于union(联合体/共用体)共享内存的特征来实现了。

23、抽象类(abstractclass)和接口(interface)有什么异同?

抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类。接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法。抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。

24、静态嵌套类(StaticNestedClass)和内部类(InnerClass)的不同?

StaticNestedClass是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化,其语法看起来挺诡异的,如下所示。

/***扑克类(一副扑克)*

author骆昊**/publicclassPoker{  privatestaticString[]suites={"黑桃","红桃","草花","方块"};  privatestaticint[]faces={1,2,3,4,5,6,7,8,9,10,11,12,13};  privateCard[]cards;  /***构造器**/  publicPoker(){    cards=newCard[52];    for(inti=0;isuites.length;i++){      for(intj=0;jfaces.length;j++){        cards[i*13+j]=newCard(suites[i],faces[j]);      }    }  }  /***洗牌(随机乱序)**/  publicvoidshuffle(){    for(inti=0,len=cards.length;ilen;i++){      intindex=(int)(Math.random()*len);      Cardtemp=cards[index];      cards[index]=cards[i];      cards[i]=temp;    }  }  /***发牌*

paramindex发牌的位置**/  publicCarddeal(intindex){    returncards[index];  }  /***卡片类(一张扑克)*[内部类]*

author骆昊**/  publicclassCard{    privateStringsuite;    //花色    privateintface;    //点数    publicCard(Stringsuite,intface){      this.suite=suite;      this.face=face;    }    

Override    publicStringtoString(){      StringfaceStr="";      switch(face){        case1:faceStr="A";        break;        case11:faceStr="J";        break;        case12:faceStr="Q";        break;        case13:faceStr="K";        break;        default:faceStr=String.valueOf(face);      }      returnsuite+faceStr;    }  }}测试代码:classPokerTest{  publicstaticvoidmain(String[]args){    Pokerpoker=newPoker();    poker.shuffle();    //洗牌    Poker.Cardc1=poker.deal(0);    //发第一张牌    //对于非静态内部类Card    //只有通过其外部类Poker对象才能创建Card对象    Poker.Cardc2=poker.newCard("红心",1);    //自己创建一张牌    System.out.println(c1);    //洗牌后的第一张    System.out.println(c2);    //打印:红心A  }}

面试题-下面的代码哪些地方会产生编译错误?

classOuter{  classInner{  }  publicstaticvoidfoo(){    newInner();  }  publicvoidbar(){    newInner();  }  publicstaticvoidmain(String[]args){    newInner();  }}

注意:Java中非静态内部类对象的创建要依赖其外部类对象,上面的面试题中foo和main方法都是静态方法,静态方法中没有this,也就是说没有所谓的外部类对象,因此无法创建内部类对象,如果要在静态方法中创建内部类对象,可以这样做:

newOuter().newInner();

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

理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因);然而在实际开发中,可能会存在无用但可达的对象,这些对象不能被GC回收,因此也会导致内存泄露的发生。例如Hibernate的Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)或清空(flush)一级缓存就可能导致内存泄露。下面例子中的代码也会导致内存泄露。

importjava.util.Arrays;importjava.util.EmptyStackException;publicclassMyStackT{  privateT[]elements;  privateintsize=0;  privatestaticfinalintINIT_CAPACITY=16;  publicMyStack(){    elements=(T[])newObject[INIT_CAPACITY];  }  publicvoidpush(Telem){    ensureCapacity();    elements[size++]=elem;  }  publicTpop(){    if(size==0)    thrownewEmptyStackException();    returnelements[--size];  }  privatevoidensureCapacity(){    if(elements.length==size){      elements=Arrays.copyOf(elements,2*size+1);    }  }}

上面的代码实现了一个栈(先进后出(FILO))结构,乍看之下似乎没有什么明显的问题,它甚至可以通过你编写的各种单元测试。然而其中的pop方法却存在内存泄露的问题,当我们用pop方法弹出栈中的对象时,该对象不会被当作垃圾回收,即使使用栈的程序不再引用这些对象,因为栈内部维护着对这些对象的过期引用(obsoletereference)。在支持垃圾回收的语言中,内存泄露是很隐蔽的,这种内存泄露其实就是无意识的对象保持。如果一个对象引用被无意识的保留起来了,那么垃圾回收器不会处理这个对象,也不会处理该对象引用的其他对象,即使这样的对象只有少数几个,也可能会导致很多的对象被排除在垃圾回收之外,从而对性能造成重大影响,极端情况下会引发DiskPaging(物理内存与硬盘的虚拟内存交换数据),甚至造成OutOfMemoryError。

26、抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?

都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。

27、阐述静态变量和实例变量的区别。

静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。

补充:在Java开发中,上下文类和工具类中通常会有大量的静态成员。

28、是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?

不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,在调用静态方法时可能对象并没有被初始化。

29、如何实现对象克隆?

有两种方式:

1).实现Cloneable接口并重写Object类中的clone()方法;

2).实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下。

importjava.io.ByteArrayInputStream;importjava.io.ByteArrayOutputStream;importjava.io.ObjectInputStream;importjava.io.ObjectOutputStream;importjava.io.Serializable;publicclassMyUtil{  privateMyUtil(){    thrownewAssertionError();  }  

SuppressWarnings("unchecked")  publicstaticTextendsSerializableTclone(Tobj)throws  Exception{    ByteArrayOutputStreambout=newByteArrayOutputStream();    ObjectOutputStreamoos=newObjectOutputStream(bout);    oos.writeObject(obj);    ByteArrayInputStreambin=new    ByteArrayInputStream(bout.toByteArray());    ObjectInputStreamois=newObjectInputStream(bin);    return(T)ois.readObject();    //说明:调用ByteArrayInputStream或ByteArrayOutputStream    对象的close方法没有任何意义    //这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这    一点不同于对外部资源(如文件流)的释放  }}

下面是测试代码:

importjava.io.Serializable;/***人类*

author骆昊**/classPersonimplementsSerializable{  privatestaticfinallongserialVersionUID=-901702028L;  privateStringname;  //姓名  privateintage;  //年龄  privateCarcar;  //座驾  publicPerson(Stringname,intage,Carcar){    this.name=name;    this.age=age;    this.car=car;  }  publicStringgetName(){    returnname;  }  publicvoidsetName(Stringname){    this.name=name;  }  publicintgetAge(){    returnage;  }  publicvoidsetAge(intage){    this.age=age;  }  publicCargetCar(){    returncar;  }  publicvoidsetCar(Carcar){    this.car=car;  }  

Override  publicStringtoString(){    return"Person[name="+name+",age="+age+",car="+    car+"]";  }}/***小汽车类*

author骆昊**/classCarimplementsSerializable{  privatestaticfinallongserialVersionUID=-L;  privateStringbrand;  //品牌  privateintmaxSpeed;  //最高时速  publicCar(Stringbrand,intmaxSpeed){    this.brand=brand;    this.maxSpeed=maxSpeed;  }  publicStringgetBrand(){    returnbrand;  }  publicvoidsetBrand(Stringbrand){    this.brand=brand;  }  publicintgetMaxSpeed(){    returnmaxSpeed;  }  publicvoidsetMaxSpeed(intmaxSpeed){    this.maxSpeed=maxSpeed;  }  

Override  publicStringtoString(){    return"Car[brand="+brand+",maxSpeed="+maxSpeed+    "]";  }}classCloneTest{  publicstaticvoidmain(String[]args){    try{      Personp1=newPerson("HaoLUO",33,newCar("Benz",      ));      Personp2=MyUtil.clone(p1);      //深度克隆      p2.getCar().setBrand("BYD");      //修改克隆的Person对象p2关联的汽车对象的品牌属性      //原来的Person对象p1关联的汽车不会受到任何影响      //因为在克隆Person对象时其关联的汽车对象也被克隆了      System.out.println(p1);    }    catch(Exceptione){      e.printStackTrace();    }  }}

注意:基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用Object类的clone方法克隆对象。让问题在编译的时候暴露出来总是好过把问题留到运行时。

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

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

补充:垃圾回收机制有很多种,包括:分代复制垃圾回收、标记垃圾回收、增量垃圾回收等方式。标准的Java进程既有栈又有堆。栈保存了原始型局部变量,堆保存了要创建的对象。Java平台对堆内存回收和再利用的基本算法被称为标记和清除,但是Java对其进行了改进,采用“分代式垃圾收集”。这种方法会跟Java对象的生命周期将堆内存划分为不同的区域,在垃圾收集过程中,可能会将对象移动到不同区域:

(1)伊甸园(Eden):这是对象最初诞生的区域,并且对大多数对象来说,这里是它们唯一存在过的区域。

(2)幸存者乐园(Survivor):从伊甸园幸存下来的对象会被挪到这里。

(3)终身颐养园(Tenured):这是足够老的幸存对象的归宿。年轻代收集(Minor-GC)过程是不会触及这个地方的。当年轻代收集不能把对象放进终身颐养园时,就会触发一次完全收集(Major-GC),这里可能还会牵扯到压缩,以便为大对象腾出足够的空间。

与垃圾回收相关的JVM参数:

-Xms/-Xmx—堆的初始大小/堆的最大大小-Xmn—堆中年轻代的大小-XX:-DisableExplicitGC—让System.gc()不产生任何作用-XX:+PrintGCDetails—打印GC的细节-XX:+PrintGCDateStamps—打印GC操作的时间戳-XX:NewSize/XX:MaxNewSize—设置新生代大小/新生代最大大小-XX:NewRatio—可以设置老生代和新生代的比例-XX:PrintTenuringDistribution—设置每次新生代GC后输出幸存者乐园中对象年龄的分布-XX:InitialTenuringThreshold/-XX:MaxTenuringThreshold:设置老年代阀值的初始值和最大值-XX:TargetSurvivorRatio:设置幸存区的目标使用率

31、Strings=newString(“xyz”);创建了几个字符串对象?

两个对象,一个是静态区的”xyz”,一个是用new创建在堆上的对象。

32、接口是否可继承(extends)接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concreteclass)?

接口可以继承接口,而且支持多重继承。抽象类可以实现(implements)接口,抽象类可继承具体类也可以继承抽象类。

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

可以,但一个源文件中最多只能有一个公开类(publicclass)而且文件名必须和公开类的类名完全保持一致。

34、AnonymousInnerClass(匿名内部类)是否可以继承其它类?是否可以实现接口?

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

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

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

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

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

37、指出下面程序的运行结果

classA{  static{    System.out.print("1");  }  publicA(){    System.out.print("2");  }}classBextendsA{  static{    System.out.print("a");  }  publicB(){    System.out.print("b");  }}publicclassHello{  publicstaticvoidmain(String[]args){    Aab=newB();    ab=newB();  }}

执行结果:1a2b2b。创建对象时构造器的调用顺序是:先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器。

提示:如果不能给出此题的正确答案,说明之前第21题Java类加载机制还没有完全理解,赶紧再看看吧。

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

(1)如何将字符串转换为基本数据类型?

(2)如何将基本数据类型转换为字符串?

答:

(1)调用基本数据类型对应的包装类中的方法parseXXX(String)或valueOf(String)即可返回相应基本类型;

(2)一种方法是将基本数据类型与空字符串(”“)连接(+)即可获得其所对应的字符串;另一种方法是调用String类中的valueOf()方法返回相应字符串

39、如何实现字符串的反转及替换?

方法很多,可以自己写实现也可以使用String或StringBuffer/StringBuilder中的方法。有一道很常见的面试题是用递归实现字符串反转,代码如下所示:

publicstaticStringreverse(StringoriginStr){  if(originStr==null

originStr.length()=1)  returnoriginStr;  returnreverse(originStr.substring(1))+originStr.charAt(0);}

40、怎样将GB编码的字符串转换为ISO--1编码的字符串?

代码如下所示:

Strings1="你好";Strings2=newString(s1.getBytes("GB"),"ISO--1");

41、日期和时间:

(1)如何取得年月日、小时分钟秒?

(2)如何取得从年1月1日0时0分0秒到现在的毫秒数?

(3)如何取得某月的最后一天?

(4)如何格式化日期?

答:

问题1:创建java.util.Calendar实例,调用其get()方法传入不同的参数即可获得参数所对应的值。Java8中可以使用java.time.LocalDateTimel来获取,代码如下所示。

publicclassDateTimeTest{  publicstaticvoidmain(String[]args){    Calendarcal=Calendar.getInstance();    System.out.println(cal.get(Calendar.YEAR));    System.out.println(cal.get(Calendar.MONTH));    //0-11    System.out.println(cal.get(Calendar.DATE));    System.out.println(cal.get(Calendar.HOUR_OF_DAY));    System.out.println(cal.get(Calendar.MINUTE));    System.out.println(cal.get(Calendar.SECOND));    //Java8    LocalDateTimedt=LocalDateTime.now();    System.out.println(dt.getYear());    System.out.println(dt.getMonthValue());    //1-12    System.out.println(dt.getDayOfMonth());    System.out.println(dt.getHour());    System.out.println(dt.getMinute());    System.out.println(dt.getSecond());  }}

问题2:以下方法均可获得该毫秒数。

Calendar.getInstance().getTimeInMillis();System.currentTimeMillis();Clock.systemDefaultZone().millis();//Java8

问题3:代码如下所示。

Calendartime=Calendar.getInstance();time.getActualMaximum(Calendar.DAY_OF_MONTH

问题4:利用java.text.DataFormat的子类(如SimpleDateFormat类)中的format(Date)方法可将日期格式化。Java8中可以用java.time.format.DateTimeFormatter来格式化时间日期,代码如下所示。

importjava.text.SimpleDateFormat;importjava.time.LocalDate;importjava.time.format.DateTimeFormatter;importjava.util.Date;classDateFormatTest{  publicstaticvoidmain(String[]args){    SimpleDateFormatoldFormatter=new    SimpleDateFormat("yyyy/MM/dd");    Datedate1=newDate();    System.out.println(oldFormatter.format(date1));    //Java8    DateTimeFormatternewFormatter=    DateTimeFormatter.ofPattern("yyyy/MM/dd");    LocalDatedate2=LocalDate.now();    System.out.println(date2.format(newFormatter));  }}

补充:Java的时间日期API一直以来都是被诟病的东西,为了解决这一问题,Java8中引入了新的时间日期API,其中包括LocalDate、LocalTime、LocalDateTime、Clock、Instant等类,这些的类的设计都使用了不变模式,因此是线程安全的设计。

42、打印昨天的当前时刻。

importjava.util.Calendar;classYesterdayCurrent{  publicstaticvoidmain(String[]args){    Calendarcal=Calendar.getInstance();    cal.add(Calendar.DATE,-1);    System.out.println(cal.getTime());  }}

在Java8中,可以用下面的代码实现相同的功能。

importjava.time.LocalDateTime;classYesterdayCurrent{  publicstaticvoidmain(String[]args){    LocalDateTimetoday=LocalDateTime.now();    LocalDateTimeyesterday=today.minusDays(1);    System.out.println(yesterday);  }}

43、比较一下Java和JavaSciprt。

JavaScript与Java是两个公司开发的不同的两个产品。Java是原SunMicrosystems公司推出的面向对象的程序设计语言,特别适合于互联网应用程序开发;而JavaScript是Netscape公司的产品,为了扩展Netscape浏览器的功能而开发的一种可以嵌入Web页面中运行的基于对象和事件驱动的解释性语言。JavaScript的前身是LiveScript;而Java的前身是Oak语言。

下面对两种语言间的异同作如下比较:

(1)基于对象和面向对象:Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象;JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。它是一种基于对象(Object-Based)和事件驱动(Event-Driven)的编程语言,因而它本身提供了非常丰富的内部对象供设计人员使用。

(2)解释和编译:Java的源代码在执行之前,必须经过编译。JavaScript是一种解释性编程语言,其源代码不需经过编译,由浏览器解释执行。(目前的浏览器几乎都使用了JIT(即时编译)技术来提升JavaScript的运行效率)

(3)强类型变量和类型弱变量:Java采用强类型变量检查,即所有变量在编译之前必须作声明;JavaScript中变量是弱类型的,甚至在使用变量前可以不作声明,JavaScript的解释器在运行时检查推断其数据类型。

(4)代码格式不一样。

补充:上面列出的四点是网上流传的所谓的标准答案。其实Java和JavaScript最重要的区别是一个是静态语言,一个是动态语言。目前的编程语言的发展趋势是函数式语言和动态语言。在Java中类(class)是一等公民,而JavaScript中函数(function)是一等公民,因此JavaScript支持函数式编程,可以使用Lambda函数和闭包(closure),当然Java8也开始支持函数式编程,提供了对Lambda表达式以及函数式接口的支持。对于这类问题,在面试的时候最好还是用自己的语言回答会更加靠谱,不要背网上所谓的标准答案。

44、什么时候用断言(assert)?

断言在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。一般来说,断言用于保证程序最基本、关键的正确性。断言检查通常在开发和测试时开启。为了保证程序的执行效率,在软件发布后断言检查通常是关闭的。断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为true;如果表达式的值为false,那么系统会报告一个AssertionError。断言的使用如下面的代码所示:

assert(a0);//throwsanAssertionErrorifa=0

断言可以有两种形式:

assertExpression1;

assertExpression1:Expression2;

Expression1应该总是产生一个布尔值。

Expression2可以是得出一个值的任意表达式;这个值用于生成显示更多调试信息的字符串消息。

要在运行时启用断言,可以在启动JVM时使用-enableassertions或者-ea标记。要在运行时选择禁用断言,可以在启动JVM时使用-da或者-disableassertions标记。要在系统类中启用或禁用断言,可使用-esa或-dsa标记。还可以在包的基础上启用或者禁用断言。

注意:断言不应该以任何方式改变程序的状态。简单的说,如果希望在不满足某些条件时阻止代码的执行,就可以考虑用断言来阻止它。

45、Error和Exception有什么区别?

Error表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情况;

Exception表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况。

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

会执行,在方法返回调用者前执行。

注意:在finally中改变返回值的做法是不好的,因为如果存在finally代码块,try中的return语句不会立马返回调用者,而是记录下返回值待finally代码块执行完毕之后再向调用者返回其值,然后如果在finally中修改了返回值,就会返回修改后的值。显然,在finally中返回或者修改返回值会对程序造成很大的困扰,C#中直接用编译错误的方式来阻止程序员干这种龌龊的事情,Java中也可以通过提升编译器的语法检查级别来产生警告或错误,Eclipse中可以在如图所示的地方进行设置,强烈建议将此项设置为编译错误。

47、Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?

Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并可以对其进行处理。Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果系统会抛出(throw)一个异常对象,可以通过它的类型来捕获(catch)它,或通过总是执行代码块(finally)来处理;try用来指定一块预防所有异常的程序;catch子句紧跟在try块后面,用来指定你想要捕获的异常的类型;throw语句用来明确地抛出一个异常;throws用来声明一个方法可能抛出的各种异常(当然声明异常时允许无病呻吟);finally为确保一段代码不管发生什么异常状况都要被执行;try语句可以嵌套,每当遇到一个try语句,异常的结构就会被放入异常栈中,直到所有的try语句都完成。如果下一级的try语句没有对某种异常进行处理,异常栈就会执行出栈操作,直到遇到有处理这种异常的try语句或者最终将异常抛给JVM。

48、运行时异常与受检异常有何异同?

异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译器要求方法必须声明抛出可能发生的受检异常,但是并不要求必须声明抛出未被捕获的运行时异常。异常和继承一样,是面向对象程序设计中经常被滥用的东西,在EffectiveJava中对异常的使用给出了以下指导原则:

(1)不要将异常处理用于正常的控制流(设计良好的API不应该强迫它的调用者为了正常的控制流而使用异常)

(2)对可以恢复的情况使用受检异常,对编程错误使用运行时异常

(3)避免不必要的使用受检异常(可以通过一些状态检测手段来避免异常的发生)

(4)优先使用标准的异常

(5)每个方法抛出的异常都要有文档

(6)保持异常的原子性

(7)不要在catch中忽略掉捕获到的异常

49、列出一些你常见的运行时异常?

(1)ArithmeticException(算术异常)

(2)ClassCastException(类转换异常)

(3)IllegalArgumentException(非法参数异常)

(4)IndexOutOfBoundsException(下标越界异常)

(5)NullPointerException(空指针异常)

(6)SecurityException(安全异常)

50、阐述final、finally、finalize的区别。

(1)final:修饰符(关键字)有三种用法:如果一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,因此它和abstract是反义词。将变量声明为final,可以保证它们在使用中不被改变,被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取不可修改。被声明为final的方法也同样只能使用,不能在子类中被重写。

(2)finally:通常放在try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要JVM不关闭都能执行,可以将释放外部资源的代码写在finally块中.

(3)finalize:Object类中定义的方法,Java中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作。

你在看吗?

预览时标签不可点收录于话题#个上一篇下一篇


转载请注明地址:http://www.lanbuzhenga.com/lbzfb/15110.html