Java面试题(高频易错题)

1. 面向对象编程有哪些特征?

一、抽象和封装

类和对象体现了抽象和封装

抽象就是解释类与对象之间关系的词。类与对象之间的关系就是抽象的关系。一句话来说明:类是对象的抽象,而对象则是类得特例,即类的具体表现形式。

封装两个方面的含义:一是将有关数据和操作代码封装在对象当中,形成一个基本单位,各个对象之间相对独立互不干扰。二是将对象中某些属性和操作私有化,已达到数据和操作信息隐蔽,有利于数据安全,防止无关人员修改。把一部分或全部属性和部分功能(函数)对外界屏蔽,就是从外界(类的大括号之外)看不到,不可知,这就是封装的意义。

二、继承

面向对象的继承是为了软件重用,简单理解就是代码复用,把重复使用的代码精简掉的一种手段。如何精简,当一个类中已经有了相应的属性和操作的代码,而另一个类当中也需要写重复的代码,那么就用继承方法,把前面的类当成父类,后面的类当成子类,子类继承父类,理所当然。就用一个关键字extends就完成了代码的复用。

三、多态

没有继承就没有多态,继承是多态的前提。虽然继承自同一父类,但是相应的操作却各不相同,这叫多态。由继承而产生的不同的派生类,其对象对同一消息会做出不同的响应。同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性.

多态,是指相同名称的操作方法,有不同的实现。具体到Java中,既可以是不同子类对父类同一个方法的不同重写,也可以是不同实现类对接口定义的同一个方法的不同实现。

  • 多态除了代码的复用性外,还可以解决项目中紧耦合的问题,提高程序的可扩展性

  • 可替换性:多态对已存在代码具有可替换性

  • 可扩充性:多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能

2. 接口(interface)和抽象类(abstract class)有什么区别?

默认方法

抽象类可以有默认的方法实现;而接口类在JDK1.8之前版本,不存在方法的实现。

实现方式

抽象类子类使用extends关键字来继承抽象类,如果子类不是抽象类,子类需要提供抽象类中所声明方法的实现;而接口类子类使用implements来实现接口,需要提供接口中所有声明的实现。

构造器

抽象类中可以有构造器;而接口中不能有构造器。

和正常类区别

抽象类不能被实例化;而接口是完全不同的类型。

访问修饰符

抽象类中抽象方法可以有public、protected、default等修饰;而接口类默认是public,不能使用其他修饰符。

多继承

抽象类一个子类只能存在一个父类;而接口类一个子类可以存在多个接口。

添加新方法

抽象类中添加新方法,可以提供默认的实现,因此可以不修改子类现有的代码;而接口类中添加新方法,则子类中需要实现该方法。

3. Java 中 throw 和 throws 有什么区别?

throws是用来声明一个方法可能抛出的所有异常信息,throws是将异常声明但是不处理,而是将异常往上传,谁调用就交由谁处理;而throw则是指抛出的一个具体的异常类型。

throws表示抛出异常,由该方法的调用者来处理,在方法声明后面是异常类名,可以是多个异常类名;而throwhrow表示抛出异常,由该方法体内的语句来处理,用在方法体内,其后面是异常类对象名,且只能抛出一个异常对象名。

4. Collection 和 Collections 有什么区别?

java.util.Collection是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java类库中有很多具体的实现。

Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。其直接继承接口有List与Set。

java.util.Collections是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

5. Comparable 和 Comparator有什么区别?

Comparable接口出自java.lang包,它有一个compareTo(Object obj)方法用来排序。

Comparator接口出自java.util包,它有一个compare(Object obj1, Object obj2)方 法用来排序。

一般对集合使用自定义排序时,需要重写compareTo()方法或compare()方法。

当需要对某一个集合实现两种排序方式,比如一个用户对象中的姓名和身份证分别采用一种排序方法。 方式一:重写compareTo()方法实现姓名、身份证排序

方式二:使用自定义的Comparator方法实现姓名、身份证排序

方法三:使用两个Comparator来实现姓名、身份证排序

其中方式二代表只能使用两个参数的形式Collections.sort()。

Collections是一个工具类,sort是其中的静态方法,是用来对List类型进行排序的,它有两种参数形式。

6. HashSet 和 HashMap 有什么区别?

HashMap实现了Map接口,而HashSet实现了Set接口。

HashMap储存键值对,而HashSet仅仅存储对象。

HashMap使用put()方法将元素放入map中,而使用add()方法将元素放入set中。

HashMap中使用键对象来计算hashcode值,而HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false

HashMap比较快,因为是使用唯一的键来获取对象,而HashSet较HashMap来说比较慢。

7. Thread 类中 start() 和 run() 方法有什么区别?

Thread类中通过start()方法来启动一个线程,此时线程处于就绪状态,可以被JVM来调度执行,在调度过程中,JVM通过调用Thread类的run()方法来完成实际的业务逻辑,当run()方法结束后,此线程就会终止,所以通过start()方法可以达到多线程的目的。

如果直接调用线程类的run()方法,会被当做一个普通的函数调用,程序中仍然只有主线程这一个线程,即start()方法呢能够异步的调用run()方法,但是直接调用run()方法确实同步的,无法达到多线程的目的。

8. 线程的生命周期包括哪几个阶段?

当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)五种状态。当线程启动以后,它不能一直占用着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换。

线程的生命周期包含5个阶段,包括:新建、就绪、运行、阻塞、死亡。

新建(new Thread)

当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。

就绪(runnable)

线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源

运行(running)

线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。

堵塞(blocked)

由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。

正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。

正在等待:调用wait()方法。(调用motify()方法回到就绪状态)

被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)

死亡(dead)

当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。

自然终止:正常运行run()方法后终止

异常终止:调用stop()方法让一个线程终止。

9. object类的常用方法?

  1. equals(Object obj):用于比较当前对象与指定对象是否相等。
  2. hashCode():返回当前对象的哈希码值。
  3. toString():返回当前对象的字符串表示。
  4. getClass():返回当前对象的运行时类。
  5. notify():唤醒正在等待当前对象监视器的单个线程。
  6. notifyAll():唤醒正在等待当前对象监视器的所有线程。
  7. wait():导致当前线程等待,直到其他线程调用notify()或notifyAll()方法唤醒它。
  8. sleep(long millis):millis参数表示线程休眠的时间长度,单位是毫秒。调用sleep方法会使当前线程暂停执行指定的时间。

10. 反射类的API?

  • Class类:用于表示Java类和接口的实例。它提供了许多方法,如获取类的名称、修饰符、字段、方法和构造函数等。

  • Field类:用于表示类的字段(成员变量)。它提供了一些方法,如获取字段的名称、类型、修饰符,并可以对字段进行读取或设置操作。

  • Method类:用于表示类的方法。它提供了一些方法,如获取方法的名称、返回类型、参数列表、修饰符,并可以通过调用invoke()方法来动态执行方法。

  • Constructor类:用于表示类的构造函数。它提供了一些方法,如获取构造函数的参数列表、修饰符,并可以通过调用newInstance()方法来动态创建类的实例。

  • Modifier类:用于操作和获取修饰符的信息。它提供了一些静态方法,如isPublic()isPrivate()isFinal()等,用于判断修饰符的类型。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值