Java面试题·区别题·JavaSE部分

系列文章目录

总章 Java区别题



前言

本文介绍JavaSE部分区别题。
什么是区别题呢?
就是“请你介绍一下面向对象编程和面向过程编程的区别和联系?”这种问题。


private/默认/protected/public权限修饰符的区别

public修饰符表示所有人皆可直接访问
protected修饰符表示本类和子类可以直接访问
默认修饰符表示本包下的类可以直接访问
private修饰符表示只有自己可以直接访问

&和&&区别和联系,I和II区别和联系

|和||的区别和联系与&和&&的区别和联系类似,下面我们用&和&&举例
&和&&的联系:
&和&&都可以用作逻辑与运算符,但是要看使用时的具体条件来决定。
情况1:当上述的操作数是boolean类型变量时,&和&&都可以用作逻辑与运算符。
情况2:当上述的表达式结果是boolean类型变量时,&和&&都可以用作逻辑与运算符。
表示逻辑与(and),当运算符两边的表达式的结果或操作数都为true时,整个运算结果才为true,否则,只要有一方为false,结果都为false。
&和&&的区别:
1、&逻辑运算符称为逻辑与运算符,&&逻辑运算符称为短路与运算符,也可叫逻辑与运算符。
&:无论任何情况,&两边的操作数或表达式都会进行计算。真假逻辑与&&相同。
&&:当&&左边的操作数为false或左边表达式结果为false时,&&右边的操作数或表达式将不参与计算,此时最终结果都为false。&&效率更高。
2、&还可以用作位运算符。当&两边操作数或两边表达式的结果不是boolean类型时,&用于按位与运算符的操作。

if和switch的不同之处


if和switch都是做选择结构的

if一般用来实现范围判断,switch一般用来实现单数值判断,但switch也能实现范围判断
if的判断条件只能接受boolean型,switch的判断条件一般为int型,但也可以是short、char、byte、枚举类型(1.5后)、String(1.7后)
switch会用到break来退出选择结构,如果没有break跳出,会执行下面case里的语句,if不会用

==和equals的区别和联系

==

1、基本类型,比较的是值
2、引用类型,比较的是地址
3、不能比较没有父子关系的两个对象

equals()
1、系统类一般已经覆盖了equals(),比较的是内容。
2、用户自定义类如果没有覆盖equals(),将调用父类的equals(比如是Object),而Object的equals的比较是地址(return (this == obj);)
3、用户自定义类需要覆盖父类的equals()

注意:Object的==和equals比较的都是地址,作用相同

数组做形参和可变参数做形参联系和区别

联系:
1、实参都可以是数组
2、方法体中,可变参数当做数组来处理
区别:
1.个数不同 可变参数只能有一个 数组参数可以多个
2.位置不同 可变参数只能是最后一个 数组参数位置任意
3.实参不同 可变参数实参可以0,1,2…个,也可以是一个数组,数组的实参只能是数组

接口和抽象类的异同之处

相同点
抽象类和接口均包含抽象方法,类必须实现所有的抽象方法,否则是抽象类
抽象类和接口都不能实例化,他们位于继承树的顶端,用来被其他类继承和实现
两者的区别主要体现在两方面:语法方面和设计理念方面
语法
接口中只能定义全局静态常量,不能定义变量。抽象类中可以定义常量和变量。
接口中所有的方法必须都是抽象方法。抽象类可以不都是抽象方法。
抽象类中可以有构造方法,但不能用来实例化,而在子类实例化是执行,完成属于抽象类的初始化操作。接口中不能定义构造方法。
一个类只能有一个直接父类(可以是抽象类),但可以充实实现多个接口。一个类使用extends来继承抽象类,使用implements来实现接口。
设计理念
抽象类体现了一种继承关系,目的是复用代码,抽象类中定义了各个子类的相同代码,可以认为父类是一个实现了部分功能的“半成品”,而子类是“成品”。父类和子类之间必须存在“is-a”的关系,即父类和子类在概念本质上应该是相同的。
接口并不要求实现类和接口在概念本质上一致的,仅仅是实现了接口定义的约定或者能力而已。接口定义了“做什么”,而实现类负责完成“怎么做”,体现了功能(规范)和实现分离的原则。接口和实现之间可以认为是一种“has-a的关系”

面向过程和面向对象的区别

两者都是软件开发思想,先有面向过程,后有面向对象。在大型项目中,针对面向过程的不足推出了面向对象开发思想。
区别
1、编程思路不同:面向过程以实现功能的函数开发为主,而面向对象要首先抽象出类、属性及其方法,然后通过实例化类、执行方法来完成功能。
2、封装性:都具有封装性,但是面向过程是封装的是功能,而面向对象封装的是数据和功能。
3、面向对象具有继承性和多态性,而面向过程没有继承性和多态性,所以面向对象优势是明显。
4、面向过程考虑怎么做;面向对象考虑找谁来做

方法重载和方法重写(覆盖)的区别

重载overload:同一个类中,在一个类里面为一种行为提供多种实现方式并提高可读性
重写override:子类和父类间,父类方法无法满足子类的要求,子类通过方法重写满足要求

重载与修饰符、返回值、抛出异常无关,方法名必须相同,参数列表必须不同(个数、种类、顺序)

重写修饰符>=父类修饰符,返回值<=父类返回值,方法名、参数列表必须相同,抛出的异常<=父类抛出的异常

final、finally、finalize的区别

1、final修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载。

2、finally在异常处理时提供 finally 块来执行任何清除操作。如果有finally的话,则不管是否发生异常、是否捕获,finally语句都会被执行。(只有系统退出能阻止finally执行)

3、finalize是方法名。Java 技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要清理工作。finalize()方法是在垃圾收集器删除对象之前被调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法不应该被主动调用。

Error和Exception的区别

在这里插入图片描述
1、Error类,表示仅靠程序本身无法恢复的严重错误,比如说内存溢出、动态链接异常、虚拟机错误。应用程序不应该抛出这种类型的对象。假如出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以在进行程序设计时,应该更关注Exception类。

2、xception类,由Java应用程序抛出和处理的非严重错误,比如所需文件没有找到、零作除数,数组下标越界等。它的各种不同子类分别对应不同类型异常。分为Checked异常和Runtime异常两类。
(1)RuntimeaException及其所有子类。
不要求程序必须对它们作出处理,比如InputMismatchException、ArithmeticException、NullPointerException等。即使没有使用try-catch或throws进行处理,仍旧可以进行编译和运行。如果运行时发生异常,会输出异常的堆栈信息并中止程序执行。
(2)Checked异常(非运行时异常)
除了运行时异常外的其他异常类都是Checked异常。程序必须捕获或者声明抛出这种异常,否则出现编译错误,无法通过编译。包括两种处理方式:通过try-catch捕获异常,通过throws声明抛出异常从而交给上一级调用方法处理。

异常处理中throws和throw的区别

1、作用不同:throw用于程序员自行产生并抛出异常;throws用于声明在该方法内抛出了异常

2、使用的位置不同:throw位于方法体内部,可以作为单独语句使用;throws必须跟在方法参数列表的后面,不能单独使用。

3、内容不同:throw抛出一个异常对象,且只能是一个;throws后面跟异常类,而且可以有多个。

Integer与int的区别

int是java提供的8种原始数据类型之一。Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。
另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。

String、StringBuffer、StringBuilder区别与联系

1、String类是不可变类,底层实现为字符数组,即一旦一个String对象被创建后,这个堆空间里的字符数组是不可改变的,直至这个对象销毁。所以每次改变字符串的值,其实是在堆空间内创建新的字符串对象。
2、StringBuffer类则代表一个字符序列可变的字符串,可以通过append、insert、reverse、setChartAt、setLength等方法改变其内容。一旦生成了最终需要的字符串,调用toString方法可以将其转变为String。
3、JDK1.5新增了一个StringBuilder类,与StringBuffer相似,构造方法和方法基本相同。不同是StringBuffer是线程安全的,而StringBuilder是线程不安全的,所以性能相对高。通常情况下,创建一个内容可变的字符串,应该优先考虑使用StringBuilder。

java.sql.Date和java.util.Date的联系和区别(了解)

java.sql.Date是java.util.Date的子类,是一个包装了毫秒值的sql包装器
java.util.Date会拿到全部值
java.sql.Date和java.sql.Time只会从数据库里读取某部分值,分别是日期与时间

Vector和ArrayList的区别和联系

实现原理相同,功能相同,都是长度可扩展的数组结构,很多情况下可以互用,初始长度都是10
两者的主要区别如下
1、Vector是早期JDK接口,ArrayList是替代Vector的新接口
2、Vector线程安全效率慢,ArrayList重速度轻安全,线程非安全
3、长度需增长时,Vector变成2倍,ArrayList变成1.5倍

ArrayList和LinkedList的区别和联系

两者都实现了List接口,都具有List中元素有序、不唯一的特点。
ArrayList底层实现为长度可扩展的数组,在内存中分配连续空间。遍历元素和随机访问元素的效率比较高。
LinkedList底层实现为双向链表。插入、删除元素时效率比较高。

HashMap和Hashtable的区别和联系

实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在很多情况下可以互用
两者的主要区别如下
1、Hashtable是早期JDK提供的接口;HashMap是新版JDK提供的接口
2、Hashtable继承Dictionary类;HashMap实现Map接口
3、Hashtable线程安全,效率低;HashMap线程非安全,效率高
4、Hashtable不允许null值;HashMap允许null值
5、Hashtable初始值为11;HashMap初始值为16

集合和数组的比较(为什么引入集合)

数组不是面向对象的,存在明显的缺陷,集合完全弥补了数组的一些缺点,比数组更灵活更实用,可大大提高软件的开发效率而且不同的集合框架类可适用于不同场合。具体如下:
1、数组的效率高于集合类.
2、数组能存放基本数据类型和对象,而集合类中只能放对象。
3、数组容量固定且无法动态改变,集合类容量动态改变。
4、数组无法判断其中实际存有多少元素,length只告诉了array的容量。
5、集合有多种实现方式和不同的适用场合,而不像数组仅采用顺序表方式。
6、集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性调用即可实现各种复杂操作,大大提高软件的开发效率。

Collection和Collections的区别

Collection是Java提供的集合接口,存储一组不唯一,无序的对象。它有两个子接口List和Set。
Java中还有一个Collections类,专门用来操作集合类,它提供一系列静态方法实现对各种集合的排序、二分法查找、线程安全化等操作。

输入流和输出流联系和区别,节点流和处理流联系和区别

首先直观地讲,流就像管道一样。在程序和文件之间,输入输出的方向是针对程序而言,向程序中读入东西,就是输入流,从程序中向外读东西,就是输出流。输入流是得到数据,输出流是输出数据。
而节点流,处理流是流的另一种划分,按照功能不同进行的划分。节点流,可以从或向一个特定的地方(节点)读写数据。处理流是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

字符流字节流联系区别;什么时候使用字节流和字符流?

字符流和字节流是流的一种划分,按照处理流的数据单位进行的划分。两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream,在字符流中输出主要是使用Writer类完成,输入流主要使用Reader类完成。这四个都是抽象类。

字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。字节流是最基本的,所有的InputStrem和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的,但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的编码来处理,也就是要进行字符集的转化。

这两个之间通过 InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联的。

列举常用字节输入流和输出流并说明其特点,至少5对。

FileInputStream从文件系统中的某个文件中获得输入字节。
FileOutputStream文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。

ByteArrayInputStream包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。
ByteArrayOutputStream此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用toByteArray()和toString()获取数据。

FilterInputStream包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。FilterInputStream类本身只是简单地重写那些将所有请求传递给所包含输入流的 InputStream 的所有方法。FilterInputStream的子类可进一步重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。
FilterOutputStream类是过滤输出流的所有类的超类。这些流位于已存在的输出流(基础 输出流)之上,它们将已存在的输出流作为其基本数据接收器,但可能直接传输数据或提供一些额外的功能。 FilterOutputStream 类本身只是简单地重写那些将所有请求传递给所包含输出流的 OutputStream 的所有方法。FilterOutputStream 的子类可进一步地重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。

ObjectInputStream对以前使用ObjectOutputStream写入的基本数据和对象进行反序列化。
ObjectOutputStream和ObjectInputStream分别与FileOutputStream和FileInputStream一起使用时,可以为应用程序提供对对象图形的持久存储。ObjectInputStream用于恢复那些以前序列化的对象。其他用途包括使用套接字流在主机之间传递对象,或者用于编组和解组远程通信系统中的实参和形参。
StringBufferInputStream此类允许应用程序创建输入流,在该流中读取的字节由字符串内容提供。应用程序还可以使用ByteArrayInputStream从byte数组中读取字节。 只有字符串中每个字符的低八位可以由此类使用。
ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。

进程和线程有什么联系和区别?

1、定义:
(1)进程是运行中的程序,是进行资源分配和调度的单位。
(2)线程是进程的一条执行路径,处理器调度的基本单位
2、进程和线程的关系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
(4)处理机分给线程,即真正在处理机上运行的是线程。
(5)线程是指进程内的一个执行单元,也是进程内的可调度实体。
3、线程与进程的区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。

Java创建线程后,调用start()方法和run()的区别

两种方法的区别
1、start:
用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,run方法运行结束,此线程随即终止。
2、run:
run()方法只是类的一个普通方法而已,如果直接调用run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。
把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run()方法,这是由jvm的内存机制规定的。并且run()方法必须是public访问权限,返回值类型为void。

两种方式的比较
实际中往往采用实现Runable接口,一方面因为java只支持单继承,继承了Thread类就无法再继续继承其它类,而且Runable接口只有一个run方法;另一方面通过结果可以看出实现Runable接口才是真正的多线程。

简述sleep( )和wait( )有什么区别?

想像小明正在喝水,突然小明睡着了,水还在流到小明的嘴里;但如果有人跟小明说等等,小明就会把水放下。这里的水指代的是CPU资源,小明指代一个线程。
sleep不释放锁,不释放资源
wait释放锁,释放资源
sleep到达休眠时间后,自动结束,属于线程类下
wait只能等待其他线程唤醒,属于Object类下

Java反射技术主要实现类有哪些,作用分别是什么?

在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中
1、Class类:代表一个类
2、Field 类:代表类的成员变量(属性)
3、Method类:代表类的成员方法
4、Constructor 类:代表类的构造方法


总结

以上是JavaSE部分的区别题,感谢各位客官收看。

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值