热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

拒绝面试造火箭,工作拧螺丝——Java经典面试题分享『带答案』

本文转载自:拒绝面试造火箭,工作拧螺丝——Java经典面试题分享『带答案』1.Java三大版本Java2平台包括标准版(J2SE&#

本文转载自:拒绝"面试造火箭,工作拧螺丝"——Java经典面试题分享『带答案』



1. Java三大版本

Java2平台包括标准版(J2SE)、企业版(J2EE)和微缩版(J2ME)三个版本:

  • Standard Edition(标准版) J2SE 包含那些构成Java语言核心的类。
    • 比如:数据库连接、接口定义、输入/输出、网络编程
  • Enterprise Edition(企业版) J2EE 包含J2SE 中的类,并且还包含用于开发企业级应用的类。
    • 比如servlet、JSP、XML、事务控制
  • Micro Edition(微缩版) J2ME 包含J2SE中一部分类,用于消费类电子产品的软件开发。
    • 比如:呼机、智能卡、手机、PDA、机顶盒

他们的范围是:J2SE包含于J2EE中,J2ME包含了J2SE的核心类,但新添加了一些专有类;应用场合,API的覆盖范围各不相同。

2. Java三种注释类型说明

共有单行注释、多行注释、文档注释3种注释类型。使用如下:

  • 单行注释,采用“//”方式.只能注释一行代码。如://类成员变量
  • 多行注释,采用“//”方式,可注释多行代码,其中不允许出现嵌套。如:

/*System.out.println("a");
System.out.println("b");
System.out.println("c");*/
文档注释,采用“
/**...*/
”方式。如:
/**
* 子类 Dog
* @author www.wuliaokankan.cn
**/
public class Dog extends Animal{
}

3. Java与JavaSciprt比较

Java与JavaSciprt比较,比较一下Java 和JavaSciprt

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

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

  • 基于对象和面向对象:Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象;Javascript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。它是一种基于对象(Object-Based)和事件驱动(Event-Driven)的编程语言。因而它本身提供了非常丰富的内部对象供设计人员使用;
  • 解释和编译:Java 的源代码在执行之前,必须经过编译;Javascript 是一种解释性编程语言,其源代码不需经过编译,由浏览器解释执行;
  • 强类型变量和类型弱变量:Java采用强类型变量检查,即所有变量在编译之前必须作声明;Javascript中变量声明,采用其弱类型。即变量在使用前不需作声明,而是解释器在运行时检查其数据类型;
  • 代码格式不一样。

补充:上面列出的四点是原来所谓的标准答案中给出的。其实Java和Javascript最重要的区别是一个是静态语言,一个是动态语言。目前的编程语言的发展趋势是函数式语言和动态语言。在Java中类(class)是一等公民,而Javascript中函数(function)是一等公民。对于这种问题,在面试时还是用自己的语言回答会更加靠谱。


4. Java中Final和Abstract关键字的作用

final和abstract关键字的作用;final和abstract是功能相反的两个关键字,可以对比记忆;abstract可以用来修饰类和方法,不能用来修饰属性和构造方法;使用abstract修饰的类是抽象类,需要被继承,使用abstract修饰的方法是抽象方法,需要子类被重写。

final可以用来修饰类、方法和属性,不能修饰构造方法。使用final修饰的类不能被继承,使用final修饰的方法不能被重写,使用final修饰的变量的值不能被修改,所以就成了常量。

特别注意:final修饰基本类型变量,其值不能改变,由原来的变量变为常量;但是final修饰引用类型变量,栈内存中的引用不能改变,但是所指向的堆内存中的对象的属性值仍旧可以改变。例如

class Test {public static void main(String[] args) {final Dog dog = new Dog("欧欧");dog.name = "美美";//正确dog = new Dog("亚亚");//错误}
}

5. Java中i++和++i的异同之处

共同点:

  • i++和++i都是变量自增1,都等价于i=i+1
  • 如果i++,++i是一条单独的语句,两者没有任何区别
  • i++和++i的使用仅仅针对变量。 5++和++5会报错,因为5不是变量。

不同点:

  • 如果i++,++i不是一条单独的语句,他们就有区别i++ :先运算后增1。如:

int x=5;
int y=x++;
System.out.println("x="+x+", y="+y);
//以上代码运行后输出结果为:x=6, y=5

  • ++i : 先增1后运算。如:

int x=5;
int y=++x;
System.out.println("x="+x+", y="+y);
//以上代码运行后输出结果为:x=6, y=6

6. Java中if多分支语句和switch多分支语句的异同之处


  • 相同之处:都是分支语句,多超过一种的情况进行判断处理。
  • 不同之处&#xff1a;switch更适合用于多分支情况&#xff0c;就是有很多种情况需要判断处理&#xff0c;判断条件类型单一&#xff0c;只有一个入口&#xff0c;在分支执行完后&#xff08;如果没有break跳出&#xff09;&#xff0c;不加判断地执行下去;而if—elseif—else多分枝主要适用于分支较少的分支结构&#xff0c;判断类型不是单一&#xff0c;只要一个分支被执行后&#xff0c;后边的分支不再执行。switch为等值判断&#xff08;不允许比如>&#61; <&#61;&#xff09;&#xff0c;而if为等值和区间都可以&#xff0c;if的使用范围大。

7. Java中static关键字的作用

static可以修饰变量、方法、代码块和内部类

static属性属于这个类所有&#xff0c;即由该类创建的所有对象共享同一个static属性。可以对象创建后通过对象名.属性名和类名.属性名两种方式来访问。也可以在没有创建任何对象之前通过类名.属性名的方式来访问。

static变量和非static变量的区别(都是成员变量&#xff0c;不是局部变量)

①. 在内存中份数不同

不管有多少个对象&#xff0c;static变量只有1份。对于每个对象&#xff0c;实例变量都会有单独的一份

static变量是属于整个类的&#xff0c;也称为类变量。而非静态变量是属于对象的&#xff0c;也称为实例变量

②. 在内存中存放的位置不同

③. 访问的方式不同

  • 实例变量&#xff1a; 对象名.变量名 stu1.name&#61;“小明明”;
  • 静态变量&#xff1a;对象名.变量名 stu1.schoolName&#61;“西二旗小学”; 不推荐如此使用

类名.变量名 Student.schoolName&#61;“东三旗小学”; 推荐使用

④. 在内存中分配空间的时间不同

Student.schoolName&#61;“东三旗小学”;或者Student stu1 &#61; new Student(“小明”,“男”,20,98);

static方法也可以通过对象名.方法名和类名.方法名两种方式来访问static代码块。当类被第一次使用时&#xff08;可能是调用static属性和方法&#xff0c;或者创建其对象&#xff09;执行静态代码块&#xff0c;且只被执行一次&#xff0c;主要作用是实现static属性的初始化。

static内部类&#xff1a;属于整个外部类&#xff0c;而不是属于外部类的每个对象。不能访问外部类的非静态成员&#xff08;变量或者方法&#xff09;&#xff0c;.可以访问外部类的静态成员

8. Java中String类的面试题

①. 下面程序的运行结果是&#xff08;&#xff09;&#xff08;选择一项&#xff09;

String str1&#61;"hello";
String str2&#61;new String("hello");
System.out.println(str1&#61;&#61;str2);

A. true
B. false
C. hello
D. he

答案&#xff1a;B

分析&#xff1a;str1没有使用new关键字&#xff0c;在堆中没有开辟空间&#xff0c;其值”hello”在常量池中&#xff0c;str2使用new关键字创建了一个对象&#xff0c;在堆中开辟了空间&#xff0c;”&#61;&#61;”比较的是对象的引用&#xff0c;即内存地址&#xff0c;所以str1与str2两个对象的内存地址是不相同的

②. Java语言中&#xff0c;String类中的indexOf()方法返回值的类型是&#xff08;&#xff09;

A. int16
B. int32
C. int
D. long

答案&#xff1a;C

③. 给定以下代码&#xff0c;程序的运行结果是 &#xff08;&#xff09;&#xff08;选择一项&#xff09;

public class Example {String str&#61;new String("good");char [] ch&#61;{&#39;a&#39;,&#39;b&#39;,&#39;c&#39;};

public static void main(String[] args) {Example ex&#61;new Example();ex.change(ex.str, ex.ch);System.out.print(ex.str&#43;"and");System.out.print(ex.ch);
}

public void change(String str,char ch[]){str&#61;"test ok";ch[0]&#61;&#39;g&#39;;
}
}

A. goodandabc
B. goodandgbc
C. test okandabc
D. test okandgbc

答案&#xff1a;B

分析&#xff1a;在方法调用时&#xff0c;在change方法中对str的值进行修改&#xff0c;是将str指向了常量江池中的”test ok”&#xff0c;而主方法中的ex.str仍然指向的是常量池中的”good”。字符型数组在方法调用时&#xff0c;将主方法中ex.ch的引用传递给change方法中的ch&#xff0c;指向是堆中的同一堆空间&#xff0c;所以修改ch[0]的时候,ex.ch可以看到相同的修改后的结果。

④. 执行下列代码后&#xff0c;哪个结论是正确的&#xff08;&#xff09;&#xff08;选择两项&#xff09;

String[] s&#61;new String[10];

A. s[10]为””
B. s[9]为null
C. s[0]为未定义
D. s.length为10

答案&#xff1a;BD

分析&#xff1a; 引用数据类型的默认值均为nulls.length数组的长度

⑤. 实现String类的replaceAll方法

思路说明&#xff1a;replaceAll方法的本质是使用正则表达式进行匹配&#xff0c;最终调用的其实是Matcher对象的replaceAll方法。

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestStringReplaceAll {public static void main(String[] args) {String str &#61; "a1s2d3f4h5j6k7";// 将字符串中的数字全部替换为0System.out.println(replaceAll(str, "\d", "0"));}/**
* &#64;param str:源字符串
* &#64;param regex:正则表达式
* &#64;param newStr:替换后的子字符串
* &#64;return 返回替换成功后的字符串
*/public static String replaceAll(String str, String regex, String newStr) {Pattern pattern &#61; Pattern.compile(regex);Matcher mathcer &#61; pattern.matcher(str);String reslut &#61; mathcer.replaceAll(newStr);return reslut;}
}

⑥. 在“&#61;”后填写适当的内容&#xff1a;

String []a&#61;new String[10];

则&#xff1a;

a[0]~a[9]&#61;null;
a.length&#61;10;

如果是

int[]a&#61;new int[10];

则&#xff1a;

a[0]~a[9]&#61; (0)
a.length&#61; (10)

⑦. 是否可以继承String类?

答:不可以&#xff0c;因为String类有final修饰符&#xff0c;而final修饰的类是不能被继承的&#xff0c;实现细节不允许改变。

public final class String implements java.io.Serializable,
Comparable, CharSequence

⑧. 给定两个字符串s和t&#xff0c; 写一个函数来决定是否t是s的重组词。你可以假设字符串只包含小写字母

public class Solution {public Boolean isAnagram(String s, String t) {if(s.length()!&#61;t.length())return false;int bit[] &#61; new int[26];for (int i&#61;0;i}

⑨. String s&#61;new String(“abc”);创建了几个String对象

两个或一个&#xff0c;”abc”对应一个对象&#xff0c;这个对象放在字符串常量缓冲区&#xff0c;常量”abc”不管出现多少遍&#xff0c;都是缓冲区中的那一个。New String每写一遍&#xff0c;就创建一个新的对象&#xff0c;它一句那个常量”abc”对象的内容来创建出一个新String对象。如果以前就用过’abc’&#xff0c;这句代表就不会创建”abc”自己了&#xff0c;直接从缓冲区拿。

⑩. 输出结果&#xff1f;

String str1&#61;“hello”&#xff1b;
Sring str2&#61;“he”&#43;new String(“llo”)&#xff1b;
Sysem.out.println(str1&#61;&#61;str2));
Sysem.out.println(str.equal(str2));
false
true

⑪. 关于java.lang.String类&#xff0c;以下描述正确的一项是&#xff08;&#xff09;

A. String类是final类故不可继承
B. String类final类故可以继承
C. String类不是final类故不可继承
D. String;类不是final类故可以继承

答案&#xff1a;A

⑫. 下面哪个是正确的&#xff08;&#xff09;

A. String temp[ ] &#61; new String{“a”,”b”,”c”};
B. String temp[ ] &#61; {“a”,”b”,”c”};
C. String temp&#61; {“a”,”b”,”c”};
D. String[ ] temp &#61; {“a”,”b”,”c”};

答案&#xff1a;BD

⑬. 已知如下代码&#xff1a;执行结果是什么&#xff08;&#xff09;

public class Test {public static void main(String[] args) {String s1 &#61; new String("Hello");String s2 &#61; new String("Hello");System.out.print(s1 &#61;&#61; s2);String s3 &#61; "Hello";String s4 &#61; "Hello";System.out.print(s3 &#61;&#61; s4);s1 &#61; s3;s2 &#61; s4;System.out.print(s1 &#61;&#61; s2);}
}

A. false true true
B. true false true
C. true true false
D. true true false

答案&#xff1a;A

9. java中this和super关键字的作用

this是对象内部指代自身的引用,同时也是解决成员变量和局部变量同名问题&#xff1b;this可以调用成员变量&#xff0c;不能调用局部变量&#xff1b;this也可以调用成员方法&#xff0c;但是在普通方法中可以省略this&#xff0c;在构造方法中不允许省略&#xff0c;必须是构造方法的第一条语句。&#xff0c;而且在静态方法当中不允许出现this关键字。

super代表对当前对象的直接父类对象的引用&#xff0c;super可以调用直接父类的成员变量&#xff08;注意权限修饰符的影响&#xff0c;比如不能访问private成员&#xff09;

super可以调用直接父类的成员方法&#xff08;注意权限修饰符的影响&#xff0c;比如不能访问private成员&#xff09;&#xff1b;super可以调用直接父类的构造方法&#xff0c;只限构造方法中使用&#xff0c;且必须是第一条语句。

10. Java中while和do-while循环的区别

while先判断后执行&#xff0c;第一次判断为false,循环体一次都不执行

do while先执行 后判断&#xff0c;最少执行1次。

如果while循环第一次判断为true, 则两种循环没有区别。

11. Java中会存在内存泄漏吗&#xff0c;请简单描述&#xff1f;

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

12. Java中垃圾回收&#xff08;GC&#xff09;有什么目的&#xff1f;有哪些GC?什么时候进行垃圾回收&#xff1f;

垃圾回收&#xff08;GC&#xff09;的目的是识别并且丢弃应用不再使用的对象来释放和重用资源。

System.gc()和Runtime.gc()会做什么事情&#xff1f;

这两个方法用来提示JVM要进行垃圾回收。但是&#xff0c;立即开始还是延迟进行垃圾回收是取决于JVM的。

finalize()方法什么时候被调用&#xff1f;析构函数(finalization)的目的是什么&#xff1f;

在释放对象占用的内存之前&#xff0c;垃圾收集器会调用对象的finalize()方法。一般建议在该方法中释放对象持有的资源。

如果对象的引用被置为null&#xff0c;垃圾收集器是否会立即释放对象占用的内存&#xff1f;
不会&#xff0c;在下一个垃圾回收周期中&#xff0c;这个对象将是可被回收的。

13. Java中如何实现序列化&#xff0c;有什么意义&#xff1f;

序列化就是一种用来处理对象流的机制&#xff0c;所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作&#xff0c;也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题&#xff08;如果不进行序列化可能会存在数据乱序的问题&#xff09;。

要实现序列化&#xff0c;需要让一个类实现Serializable接口&#xff0c;该接口是一个标识性接口&#xff0c;标注该类对象是可被序列化的&#xff0c;然后使用一个输出流来构造一个对象输出流并通过writeObject(Object)方法就可以将实现对象写出&#xff08;即保存其状态&#xff09;&#xff1b;如果需要反序列化则可以用一个输入流建立对象输入流&#xff0c;然后通过readObject方法从流中读取对象。

例如&#xff0c;在web开发中&#xff0c;如果对象被保存在了Session中&#xff0c;tomcat在重启时要把Session对象序列化到硬盘&#xff0c;这个对象就必须实现Serializable接口。如果对象要经过分布式系统进行网络传输或通过rmi等远程调用&#xff0c;这就需要在网络上传输对象&#xff0c;被传输的对象就必须实现Serializable接口。

14. Java中如何获取到线程dump文件

死循环、死锁、阻塞、页面打开慢等问题&#xff0c;打线程dump是最好的解决问题的途径。所谓线程dump也就是线程堆栈&#xff0c;获取到线程堆栈有两步&#xff1a;

①. 获取到线程的pid&#xff0c;可以通过使用jps命令&#xff0c;在Linux环境下还可以使用ps -ef | grep java
②. 打印线程堆栈&#xff0c;可以通过使用jstack pid命令&#xff0c;在Linux环境下还可以使用kill -3 pid

另外提一点&#xff0c;Thread类提供了一个getStackTrace()方法也可以用于获取线程堆栈。这是一个实例方法&#xff0c;因此此方法是和具体线程实例绑定的&#xff0c;每次获取获取到的是具体某个线程当前运行的堆栈

15. JAVA中如何解析xml&#xff0c;不同方式有和优缺点&#xff1f;

1. DOM&#xff08;Document Object Model)

DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构&#xff0c;然后才能做任何工作。由于它是基于信息层次的&#xff0c;因而DOM被认为是基于树或基于对象的。

优点&#xff1a;

  • ①. 允许应用程序对数据和结构做出更改。
  • ②. 访问是双向的&#xff0c;可以在任何时候在树中上下导航&#xff0c;获取和操作任意部分的数据。

缺点&#xff1a;

  • ①. 通常需要加载整个XML文档来构造层次结构&#xff0c;消耗资源大。

2. SAX&#xff08;Simple API for XML)

SAX处理的优点非常类似于流媒体的优点。分析能够立即开始&#xff0c;而不是等待所有的数据被处理。而且&#xff0c;由于应用程序只是在读取数据时检查数据&#xff0c;因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上&#xff0c;应用程序甚至不必解析整个文档&#xff1b;它可以在某个条件得到满足时停止解析。一般来说&#xff0c;SAX还比它的替代者DOM快许多。

选择DOM还是选择SAX&#xff1f; 对于需要自己编写代码来处理XML文档的开发人员来说&#xff0c; 选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档&#xff0c;而SAX采用的是事件模型。

DOM解析器把XML文档转化为一个包含其内容的树&#xff0c;并可以对树进行遍历。用DOM解析模型的优点是编程容易&#xff0c;开发人员只需要调用建树的指令&#xff0c;然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档&#xff0c;所以对性能和内存的要求比较高&#xff0c;尤其是遇到很大的XML文件的时候。由于它的遍历能力&#xff0c;DOM解析器常用于XML文档需要频繁的改变的服务中。

SAX解析器采用了基于事件的模型&#xff0c;它在解析XML文档的时候可以触发一系列的事件&#xff0c;当发现给定的tag的时候&#xff0c;它可以激活一个回调方法&#xff0c;告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低&#xff0c;因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时&#xff0c;SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难&#xff0c;而且很难同时访问同一个文档中的多处不同数据。

优势&#xff1a;

  • ①. 不需要等待所有数据都被处理&#xff0c;分析就能立即开始。
  • ②. 只在读取数据时检查数据&#xff0c;不需要保存在内存中。
  • ③. 可以在某个条件得到满足时停止解析&#xff0c;不必解析整个文档。
  • ④. 效率和性能较高&#xff0c;能解析大于系统内存的文档。

缺点&#xff1a;

  • ①. 需要应用程序自己负责TAG的处理逻辑&#xff08;例如维护父/子关系等&#xff09;&#xff0c;文档越复杂程序就越复杂。
  • ②. 单向导航&#xff0c;无法定位文档层次&#xff0c;很难同时访问同一文档的不同部分数据&#xff0c;不支持XPath。

3. JDOM(Java-based Document Object Model)

JDOM的目的是成为Java特定文档模型&#xff0c;它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型&#xff0c;JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。

JDOM与DOM主要有两方面不同。首先&#xff0c;JDOM仅使用具体类而不使用接口。这在某些方面简化了API&#xff0c;但是也限制了灵活性。第二&#xff0c;API大量使用了Collections类&#xff0c;简化了那些已经熟悉这些类的Java开发者的使用。

JDOM文档声明其目的是“使用20%&#xff08;或更少&#xff09;的精力解决80%&#xff08;或更多&#xff09;Java/XML问题”&#xff08;根据学习曲线假定为20%&#xff09;。JDOM对于大多数Java/XML应用程序来说当然是有用的&#xff0c;并且大多数开发者发现API比DOM容易理解得多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何在XML中无意义的事。然而&#xff0c;它仍需要您充分理解XML以便做一些超出基本的工作&#xff08;或者甚至理解某些情况下的错误&#xff09;。这也许是比学习DOM或JDOM接口都更有意义的工作。

JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档&#xff08;尽管它还可以将以前构造的DOM表示作为输入&#xff09;。它包含一些转换器以将JDOM表示输出成SAX2事件流、DOM模型或XML文本文档。JDOM是在Apache许可证变体下发布的开放源码。

优点&#xff1a;

  • ①. 使用具体类而不是接口&#xff0c;简化了DOM的API。
  • ②. 大量使用了Java集合类&#xff0c;方便了Java开发人员。

缺点&#xff1a;

  • ①. 没有较好的灵活性。
  • ②. 性能较差。

4. DOM4J(Document Object Model for Java)

虽然DOM4J代表了完全独立的开发结果&#xff0c;但最初&#xff0c;它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能&#xff0c;包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项&#xff0c;它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始&#xff0c;它就一直处于开发之中。

为支持所有这些功能&#xff0c;DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类&#xff0c;但是在许多情况下&#xff0c;它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是&#xff0c;虽然DOM4J付出了更复杂的API的代价&#xff0c;但是它提供了比JDOM大得多的灵活性。

在添加灵活性、XPath集成和对大文档处理的目标时&#xff0c;DOM4J的目标与JDOM是一样的&#xff1a;针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案&#xff0c;实现在本质上处理所有Java/XML问题的目标。在完成该目标时&#xff0c;它比JDOM更少强调防止不正确的应用程序行为。

DOM4J是一个非常非常优秀的Java XML API&#xff0c;具有性能优异、功能强大和极端易用使用的特点&#xff0c;同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML&#xff0c;特别值得一提的是连Sun的JAXM也在用DOM4J.

优点&#xff1a;

  • ①. 大量使用了Java集合类&#xff0c;方便Java开发人员&#xff0c;同时提供一些提高性能的替代方法。
  • ②. 支持XPath。
  • ③. 有很好的性能。

缺点&#xff1a;

  • ①. 大量使用了接口&#xff0c;API较为复杂。

5. 比较

①. DOM4J性能最好&#xff0c;连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J&#xff0c;例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性&#xff0c;那就采用DOM4J.
②. JDOM和DOM在性能测试时表现不佳&#xff0c;在测试10M文档时内存溢出&#xff0c;但可移植。在小文档情况下还值得考虑使用DOM和JDOM.虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题&#xff0c;但是从性能观点来看&#xff0c;它确实没有值得推荐之处。另外&#xff0c;DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础&#xff0c;因为它正式获得W3C推荐&#xff08;与基于非标准的Java模型相对&#xff09;&#xff0c;所以在某些类型的项目中可能也需要它&#xff08;如在Javascript中使用DOM&#xff09;。
③. SAX表现较好&#xff0c;这要依赖于它特定的解析方式&#xff0d;事件驱动。一个SAX检测即将到来的XML流&#xff0c;但并没有载入到内存&#xff08;当然当XML流被读入时&#xff0c;会有部分文档暂时隐藏在内存中&#xff09;。

我的看法&#xff1a;如果XML文档较大且不考虑移植性问题建议采用DOM4J&#xff1b;如果XML文档较小则建议采用JDOM&#xff1b;如果需要及时处理而不需要保存数据则考虑SAX。但无论如何&#xff0c;还是那句话&#xff1a;适合自己的才是最好的&#xff0c;如果时间允许&#xff0c;建议大家讲这四种方法都尝试一遍然后选择一种适合自己的即可。


16. Java中实现多态的机制是什么&#xff1f;

靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象&#xff0c;而程序调用的方法在运行期才动态绑定&#xff0c;就是引用变量所指向的具体实例对象的方法&#xff0c;也就是内存里正在运行的那个对象的方法&#xff0c;而不是引用变量的类型中定义的方法。

17. Java中实现线程通信的三个方法的作用是什么&#xff1f;

Java提供了3个方法解决线程之间的通信问题&#xff0c;均是java.lang.Object类的方法&#xff0c;都只能在同步方法或者同步代码块中使用&#xff0c;否则会抛出异常。

方法名作用
final void wait()表示线程一直等待&#xff0c;直到其它线程通知
void wait(long timeout)线程等待指定毫秒参数的时间
final void wait(long timeout,int nanos)线程等待指定毫秒、微妙的时间
final void notify()唤醒一个处于等待状态的线程。注意的是在调用此方法的时候&#xff0c;并不能确切的唤醒某一个等待状态的线程&#xff0c;而是由JVM确定唤醒哪个线程&#xff0c;而且不是按优先级。
final void notifyAll()唤醒同一个对象上所有调用wait()方法的线程&#xff0c;注意并不是给所有唤醒线程一个对象的锁&#xff0c;而是让它们竞争

18. Java中接口有什么用

①. 通过接口可以实现不相关类的相同行为&#xff0c;而不需要了解对象所对应的类。
②. 通过接口可以指明多个类需要实现的方法。
③. 通过接口可以了解对象的交互界面&#xff0c;而不需了解对象所对应的类。

另&#xff1a;Java是单继承&#xff0c;接口可以使其实现多继承的功能。

19. java中有几种方法可以实现一个线程&#xff1f;用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用&#xff1f;

有两种实现方法&#xff0c;分别是继承Thread类与实现Runnable接口用synchronized关键字修饰同步方法。反对使用stop()&#xff0c;是因为它不安全。它会解除由线程获取的所有锁定&#xff0c;而且如果对象处于一种不连贯状态&#xff0c;那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候&#xff0c;目标线程会停下来&#xff0c;但却仍然持有在这之前获得的锁定。此时&#xff0c;其他任何线程都不能访问锁定的资源&#xff0c;除非被"挂起"的线程恢复运行。对任何线程来说&#xff0c;如果它们想恢复目标线程&#xff0c;同时又试图使用任何一个锁定的资源&#xff0c;就会造成死锁。所以不应该使用suspend()&#xff0c;而应在自己的Thread类中置入一个标志&#xff0c;指出线程应该活动还是挂起。若标志指出线程应该挂起&#xff0c;便用wait()命其进入等待状态。若标志指出线程应当恢复&#xff0c;则用一个notify()重新启动线程。

20. Java中有几种类型的流&#xff1f;

1. 字节流 InputStream/OutputStream

  • ①FileInputStream/FileOutputStream&#xff1a;文件字节流&#xff0c;用于文件的读写操作
  • ②BufferedInputStream/BufferedFileOutputStream&#xff1a;加缓冲区的字节流&#xff0c;用于提高效率

2. 字符流 Reader/Writer

  • ①FileReader/FileWriter&#xff1a;文件字符流&#xff0c;用于文本文件的读写操作
  • ②BufferedReader/BufferedWriter&#xff1a;加缓冲区的字符流&#xff0c;用于提高效率

3. 转换流 InputStreamReader/OutputStreamWriter

21. Java中用到的线程调度算法是什么&#xff1f;

抢占式。一个线程用完CPU之后&#xff0c;操作系统会根据线程优先级、线程饥饿情况等数据算出一个总的优先级并分配下一个时间片给某个线程执行。

22. Java中的两种异常类型是什么&#xff1f;有什么区别&#xff1f;Exception和Error有什么区别&#xff1f;

Java中有两种异常&#xff1a;受检查的(checked)异常和不受检查的(unchecked)异常。不受检查的异常不需要在方法或者是构造函数上声明&#xff0c;就算方法或者是构造函数的执行可能会抛出这样的异常。而且不受检查的异常可以传播到方法或者是构造函数的外面。相反&#xff0c;受检查的异常必须要用throws语句在方法或者是构造函数上声明。

Exception和Error都是Throwable的子类。Exception用于用户程序可以捕获的异常情况。Error定义了不期望被用户程序捕获的异常。

23. Java中的继承、重载和覆盖是什么意思

继承&#xff08;英语&#xff1a;inheritance&#xff09;是面向对象软件技术当中的一个概念。如果一个类别A“继承自”另一个类别B&#xff0c;就把这个A称为“B的子类别”&#xff0c;而把B称为“A的父类别”也可以称“B是A的超类”。继承可以使得子类别具有父类别的各种属性和方法&#xff0c;而不需要再次编写相同的代码。在令子类别继承父类别的同时&#xff0c;可以重新定义某些属性&#xff0c;并重写某些方法&#xff0c;即覆盖父类别的原有属性和方法&#xff0c;使其获得与父类别不同的功能。另外&#xff0c;为子类别追加新的属性和方法也是常见的做法。 一般静态的面向对象编程语言&#xff0c;继承属于静态的&#xff0c;意即在子类别的行为在编译期就已经决定&#xff0c;无法在执行期扩充。

24. Java中继承条件下构造方法的执行过程

继承条件下构造方法的调用规则如下&#xff1a;

  • 情况1&#xff1a;如果子类的构造方法中没有通过super显式调用父类的有参构造方法&#xff0c;也没有通过this显式调用自身的其他构造方法&#xff0c;则系统会默认先调用父类的无参构造方法。在这种情况下&#xff0c;写不写“super();”语句&#xff0c;效果是一样的。
  • 情况2&#xff1a;如果子类的构造方法中通过super显式调用父类的有参构造方法&#xff0c;那将执行父类相应构造方法&#xff0c;而不执行父类无参构造方法。
  • 情况3&#xff1a;如果子类的构造方法中通过this显式调用自身的其他构造方法&#xff0c;在相应构造方法中应用以上两条规则。

特别注意的是&#xff0c;如果存在多级继承关系&#xff0c;在创建一个子类对象时&#xff0c;以上规则会多次向更高一级父类应用&#xff0c;一直到执行顶级父类Object类的无参构造方法为止。

25. Java中&#xff0c;什么是构造函数&#xff1f;什么是构造函数重载&#xff1f;什么是复制构造函数&#xff1f;

当新对象被创建的时候&#xff0c;构造函数会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下&#xff0c;Java编译器会为这个类创建一个默认的构造函数。

Java中构造函数重载和方法重载很相似。可以为一个类创建多个构造函数。每一个构造函数必须有它自己唯一的参数列表。

Java不支持像C&#43;&#43;那样的复制构造函数&#xff0c;这个不同点是因为如果你不自己写构造函数的情况下&#xff0c;Java不会创建默认的复制构造函数。

Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思&#xff1f;

方法覆盖是说子类重新实现父类的方法。方法覆盖必须有相同的方法名&#xff0c;参数列表和返回类型。

方法重载发生在同一个类里面&#xff0c;两个或者是多个方法的方法名相同但是参数列表不同。



本文转载自&#xff1a;拒绝"面试造火箭&#xff0c;工作拧螺丝"——Java经典面试题分享『带答案』


推荐阅读
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 浏览器作为我们日常不可或缺的软件工具,其背后的运作机制却鲜为人知。本文将深入探讨浏览器内核及其版本的演变历程,帮助读者更好地理解这一关键技术组件,揭示其内部运作的奥秘。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • OpenAI首席执行官Sam Altman展望:人工智能的未来发展方向与挑战
    OpenAI首席执行官Sam Altman展望:人工智能的未来发展方向与挑战 ... [详细]
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • Framework7:构建跨平台移动应用的高效框架
    Framework7 是一个开源免费的框架,适用于开发混合移动应用(原生与HTML混合)或iOS&Android风格的Web应用。此外,它还可以作为原型开发工具,帮助开发者快速创建应用原型。 ... [详细]
  • poj 3352 Road Construction ... [详细]
  • MySQL的查询执行流程涉及多个关键组件,包括连接器、查询缓存、分析器和优化器。在服务层,连接器负责建立与客户端的连接,查询缓存用于存储和检索常用查询结果,以提高性能。分析器则解析SQL语句,生成语法树,而优化器负责选择最优的查询执行计划。这一流程确保了MySQL能够高效地处理各种复杂的查询请求。 ... [详细]
  • 2009年12月28日,易语言公司正式推出了“易语言5.0静态编译测试版1”,这一版本标志着易语言在技术上的重要突破。与之前的4.x版本相比,5.0测试版1引入了静态编译功能,显著提升了程序的运行效率和安全性。此外,新版本还优化了代码生成机制,增强了语言的表达能力和兼容性。自发布以来,用户反馈非常积极,普遍认为新功能带来了更加流畅的开发体验。 ... [详细]
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • Silverlight 实战指南:深入解析用户提交数据的验证与捕获机制
    本文深入探讨了Silverlight中用户提交数据的验证与捕获机制,详细分析了四种主要的验证方法:基本异常处理、DataAnnotation注解、IDataErrorInfo客户端同步验证以及自定义验证策略。通过实例解析,帮助开发者更好地理解和应用这些机制,提升应用程序的数据处理能力和用户体验。 ... [详细]
  • 在处理大规模数据数组时,优化分页组件对于提高页面加载速度和用户体验至关重要。本文探讨了如何通过高效的分页策略,减少数据渲染的负担,提升应用性能。具体方法包括懒加载、虚拟滚动和数据预取等技术,这些技术能够显著降低内存占用和提升响应速度。通过实际案例分析,展示了这些优化措施的有效性和可行性。 ... [详细]
author-avatar
天秤蜗牛666
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有