很多个java面试题

1. 为什么说Java是一门平台无关语言?

平台无关实际的含义是“一次编写到处运行”。Java 能够做到是因为它的字节码(byte code)可以运行在任何操作系统上,与底层系统无关。

2. 为什么 Java 不是100%面向对象?

Java 不是100%面向对象,因为它包含8个原始数据类型,例如 boolean、byte、char、int、float、double、long、short。它们不是对象。

3. 什么是 singleton class,如何创建一个 singleton class?

Singleton class 在任何时间同一个 JVM 中只有一个实例。可以把构造函数加 private 修饰符创建 singleton。

4. 什么是多态?

多态简单地说“一个接口,多种实现”。多态的出现使得在不同的场合同一个接口能够提供不同功能,具体地说可以让变量、函数或者对象能够提供多种功能。下面是多态的两种类型:

  1. 编译时多态
  2. 运行时多态

编译时多态主要是对方法进行重载(overload),而运行时多态主要通过使用继承或者实现接口。

什么是运行时多态,也称动态方法分配?

在 Java 中,运行时多态或动态方法分配是一种在运行过程中的方法重载。在这个过程中,通过调用父类的变量引用被重载的方法。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Car {
     void run()
     {
         System.out.println(“car is running”);
     }
}
class Audi extends Car {
     void run()
     {
         System.out.prinltn(“Audi is running safely with 100km”);
     }
     public static void main(String args[])
     {
         Car b= new Audi();    //向上转型
         b.run();
     }
}

5. Java类加载器包括几种?它们之间的关系是怎么样的?

Java 类加载器有:

  • 引导类加载器(bootstrap class loader):只加载 JVM 自身需要的类,包名为 java、javax、sun 等开头。
  • 扩展类加载器(extensions class loader):加载 JAVA_HOME/lib/ext 目录下或者由系统变量 -Djava.ext.dir 指定位路径中的类库。
  • 应用程序类加载器(application class loader):加载系统类路径 java -classpath 或 -Djava.class.path 下的类库。
  • 自定义类加载器(java.lang.classloder):继承 java.lang.ClassLoader 的自定义类加载器。

注意:-Djava.ext.dirs 会覆盖 Java 本身的 ext 设置,造成 JDK 内建功能无法使用。可以像下面这样指定参数:

1
-Djava.ext.dirs=./plugin:$JAVA_HOME/jre/lib/ext。

它们的关系如下:

  • 启动类加载器,C++实现,没有父类。
  • 扩展类加载器(ExtClassLoader),Java 实现,父类加载器为 null。
  • 应用程序类加载器(AppClassLoader),Java 实现,父类加载器为 ExtClassLoader 。
  • 自定义类加载器,父类加载器为AppClassLoader。

7. 什么是JDBC驱动?

JDBC Driver 是一种实现 Java 应用与数据库交互的软件。JDBC 驱动有下面4种:

  1. JDBC-ODBC bridge 驱动
  2. Native-API 驱动(部分是 Java 驱动)
  3. 网络协议驱动(全部是 Java 驱动)
  4. Thin driver(全部是 Java 驱动)

8. 使用 Java 连接数据库有哪几步?

  • 注册驱动类
  • 新建数据库连接
  • 新建语句(statement)
  • 查询
  • 关闭连接

9. 列举Spring配置中常用的重要注解。

下面是一些重要的注解:

  • @Required
  • @Autowired
  • @Qualifier
  • @Resource
  • @PostConstruct
  • @PreDestroy

10. Spring中的Bean是什么?列举Spring Bean的不同作用域。

Bean 是 Spring 应用的骨架。它们由 Spring IoC 容器管理。换句话说,Bean 是一个由 Spring IoC 容器初始化、装配和管理的对象。

下面是 Spring Bean 的5种作用域:

  • Singleton:每个容器只创建一个实例,也是 Spring Bean 的默认配置。由于非线程安全,因此确保使用时不要在 Bean 中共享实例变量,一面出现数据不一致。
  • Prototype:每次请求时创建一个新实例。
  • Request:与 prototype 相同,区别在于只针对 Web 应用。每次 HTTP 请求时创建一个新实例。
  • Session:每次收到 HTTP 会话请求时由容器创建一个新实例。
  • 全局 Session:为每个门户应用(Portlet App)创建一个全局 Session Bean。

11. Object 类包含哪些方法?

这是一个非常常见的问题,用来确定你对基础知识的熟悉程度。以下是每个对象都具有的方法:

在 java.lang 包中,Object 类位于类层次结构的顶端。每个类都是 Object 类直接或间接的子类。你使用或编写的每个类都继承了 Object 类中的实例方法。你并不需要使用这些方法中的任何一种,但是,如果你选择这样做,则可能需要用你的类的特定代码来重写这些方法。以下是本节所讨论的从 Object 类中继承的方法:

  • protected Object clone() throws CloneNotSupportedException 创建并返回此对象的副本。
  • public boolean equals(Object obj) 判断另一对象与此对象是否「相等」。
  • protected void finalize() throws Throwable 当垃圾回收机制确定该对象不再被调用时,垃圾回收器会调用此方法。
  • public final Class getClass() 返回此对象的运行时类。
  • public int hashCode() 返回此对象的散列码值。
  • public String toString() 返回此对象的字符串表示形式。

Object 类的 notifynotifyAll 和 wait 方法都在同步程序中独立运行线程的活动方面发挥了作用,这将在后面的课程中讨论,在此不做介绍。其中有五种方法:

  • public final void notify()
  • public final void notifyAll()
  • public final void wait()
  • public final void wait(long timeout)
  • public final void wait(long timeout, int nanos)

12. 为什么 String 对象是不可变的?

  1. 字符串池之所以可能,就是因为字符串在 Java 中是不可变的。由此 Java 运行时环境节省了大量堆空间,因为不同的 String 变量可以引用池中的同一 String 变量。如果 String 不是不可变的, 则字符串驻留(String interning)将是不可能的,因为一旦任一变量更改所引用的String对象的值,它也会反映在其他变量中。
  2. 如果字符串不是不可变的,那么它可能会对应用程序造成严重的安全威胁。例如,数据库用户名和密码都作为 String 传递以获取数据库连接,Socket 编程的主机和端口信息也是如此。由于字符串是不可变的,因此其值不能被更改。否则,任何黑客都可以篡改其引用的值,这会导致应用程序中的安全问题。
  3. 由于 String 是不可变的,因此它对与多线程处理来说是安全的,并且可以在不同的线程之间共享单个 String 实例。这避免了为线程安全使用同步;字符串是隐式线程安全的。
  4. 字符串被用在 Java 类加载器中,其不可变性为类加载器加载正确的类提供了安全性。否则的话,请考虑这样一个危险的情况,在你尝试加载 java.sql.Connection 类时,你引用的值却被更改为 myhacked.Connection,并且它能对数据库执行你不需要的操作。
  5. 由于 String 是不可变的,因此在它被创建时其散列码就被缓存,不需要再次计算。这使得它成为映射中键的理想对象,它的处理速度比其他HashMap 键类型快。这就是为什么 String 是 HashMap 中最常用的键类型。

为什么 Java 中的字符串不可变?点击这里了解更多。

13. final,finally,和 finalize 三者之间有什么不同?

这是我最喜欢的问题。

  • final 关键字用于在多个语境下定义只能分配一次的实体。
  • finally 代码块是用于执行重要代码 (如关闭连接、流等) 的代码块。无论是否处理异常,finally 代码块总会被执行。finally 代码块紧随 try 代码块或 catch 代码块。
  • 这是在删除或销毁对象之前垃圾回收器总会调用的方法,该方法使得垃圾回收机制能够执行清理活动。

14. 什么是菱形继承问题?

菱形继承问题反映了为什么在 Java 中我们不被允许实现多继承。如果有两个类共同继承一个有特定方法的超类,那么该方法会被两个子类重写。然后,如果你决定同时继承这两个子类,那么在你调用该重写方法时,编译器不能识别你要调用哪个子类的方法。

我们把这个问题称为 菱形继承问题 。上图对它作了说明,它也得名于此。

15. 如何使一个类不可变?

我认为这是一个相当困难的问题。您需要对类进行多次修改,以实现不可变性:

  1. 将类声明为 final,使其无法被继承。
  2. 所有域都用 private 修饰,不允许直接访问。
  3. 不提供变量的 setter 方法。
  4. 所有可变域都用 final 修饰, 使它的值只能分配一次。
  5. 通过构造函数执行深克隆初始化所有域。
  6. 对 getter 方法获取的对象执行克隆以返回副本,而不是返回实际的对象引用。

16. 什么是单例模式?

单例模式是指一个类仅允许创建其自身的一个实例,并提供对该实例的访问权限。它包含静态变量,可以容纳其自身的唯一和私有实例。它被应用于这种场景——用户希望类的实例被约束为一个对象。在需要单个对象来协调整个系统时,它会很有帮助。

17. 什么是依赖注入?

这是你必须知道的首要问题, 无论你是使用 Java EE 还是 Spring 框架。你可以看看我的文章,其中进一步地解释了这一点: 什么是依赖注入?

总结

在本文中,我们讨论了最常见的十个 Java 面试题——在我看来这是根据我的经验总结出的时下最重要的问题。如果你了解这些问题,我相信你能在面试中获得很大的优势。

猜你喜欢

转载自www.cnblogs.com/lenlen/p/10172753.html