java基础面试题

1.面向对象和面向过程的区别?

面向过程

优点:性能比面向对象高,因为类调用时需要实例化,开销比较大

缺点:没有面向对象易维护、易复用、易扩展

面向对象

优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护

缺点:性能比面向过程低。

2. 重载和重写的区别?

重写 override

方法名、参数、返回值相同 ,子类方法不能缩小父类方法的访问权限,子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常) ,存在于父类和子类之间,方法被定义为 final 不能被重写

重载 overload

参数类型、个数、顺序至少有一个不相同,不能重载只有返回值不同的方法名 ,不能重载只有返回值不同的方法名

3.Java 中,什么是构造方法?什么是构造方法重载? 

1.构造方法

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

2.构造方法重载

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

4.jdk,jre,jvm分别是什么关系?

JDK 即为 Java 开发工具包,包含编写 Java 程序所必须的编译、运行等开发工具以及 JRE ,JRE 即为 Java 运行环境,提供了运行 Java 应用程序所必须的软件环境,包含有 Java 虚拟机(JVM)和丰富的系统类库 ,JRE 即为 Java 运行环境,提供了运行 Java 应用程序所必须的软件环境,包含有 Java 虚拟机(JVM)和丰富的系统类库

5.Java程序运行的过程?

Java 源代码
=> 编译器 => JVM 可执行的 Java 字节码(即虚拟指令)
=> JVM => JVM 中解释器 => 机器可执行的二进制机器码 => 程序运行

6.java中的几种基本数据类型是什么,各自占用多少字节?

基本数据类型

整数值型:byteshortintlong

字符型:char

浮点类型:floatdouble

布尔型:boolean

整数型:默认 int 型,小数默认是 double 型。Float 和 Long 类型的必须加后缀。比如:float f = 100f

引用数据类型声明的变量是指该变量在内存中实际存储的是一个引用地址,实体在堆中

引用类型包括类、接口、数组等

引用类型包括类、接口、数组等

7.什么是值传递和引用传递?

值传递,是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量

引用传递,一般是对于对象型变量而言的,传递的是该对象地址的一个副本,并不是原对象本身

一般认为,Java 内的传递都是值传递,Java 中实例对象的传递是引用传递

8.是否可以在 static 环境中访问非 static 变量?

static 变量在 Java 中是属于类的,它在所有的实例中的值是一样的。当类被 Java 虚拟机载入的时候,会对 static 变量进行初始化 ,如果你的代码尝试不用实例来访问非 static 的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上 。

9.char 型变量中能不能存贮一个中文汉字?为什么?

在 Java 语言中,char 类型占 2 个字节,而且 Java 默认采用 Unicode 编码,一个 Unicode 码是 16 位,所以一个 Unicode 码占两个字节,Java 中无论汉字还是英文字母,都是用 Unicode 编码来表示的。所以,在 Java 中,char 类型变量可以存储一个中文汉字

10.string,stringbuffer,stringbuilder的区别

Java 平台提供了两种类型的字符串:String 和 StringBuffer/StringBuilder,它们可以储存和操作字符串

String ,是只读字符串,也就意味着 String 引用的字符串内容是不能被改变的 ,String ,是只读字符串,也就意味着 String 引用的字符串内容是不能被改变的 。

StringBuffer/StringBuilder 类,表示的字符串对象可以直接进行修改。StringBuilder 是 Java 5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被 synchronized 修饰,因此它的效率也比 StringBuffer 要高

StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。

相同情况下使用 StirngBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险

11.对于三者使用的区别

操作少量的数据=string,这也是实际经常使用的方式

单线程操作字符串缓冲区下操作大量数据=stringbuilder

多线程操作字符串缓冲下操作大量数据=stringbuffer

12.String s = new String("xyz") 会创建几个对象?

首先,在 String 池内找,找到 "xyz" 字符串,不创建 "xyz" 对应的 String 对象,否则创建一个对象。 然后,遇到 new 关键字,在内存上创建 String 对象,并将其返回给 s ,又一个对象 ,所以,总共是 1 个或者 2 个对象

13. String 为什么是不可变的?

简单的来说,String 类中使用 final 关键字字符数组保存字符串。代码如下:

所以 String 对象是不可变的,

而 StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串 char[] value ,但是没有用 final 关键字修饰。代码如下

所以这两种对象都是可变的 

14. StringTokenizer 是什么 ?

StringTokenizer ,是一个用来分割字符串的工具类 

 输出如下

15.什么是自动装拆箱,为什么要转换?

自动装箱和拆箱,就是基本类型和引用类型之间的转换

如果在 Java5 下进行过编程的话,不能直接地向集合( Collection )中放入原始类型值,因为集合只接收对象。

16.int 和 Integer 有什么区别?

int 是基本数据类型

int 是基本数据类型

17.equals与==的区别

值类型:int,char,long,boolean等都是用==判断相等性

对象引用:

==判断引用所指的对象是否是同一个

equals方法是object的成员函数,有些类会覆盖这个方法用于判断对象的等价性

例如 String 类,两个引用所指向的 String 都是 "abc" ,但可能出现他们实际对应的对象并不是同一个(和 JVM 实现方式有关),因此用 == 判断他们可能不相等,但用 equals 方法判断一定是相等的。

18.如何在父类中为子类自动完成所有的 hashCode 和 equals 实现?这么做有何优劣?

父类的 equals ,一般情况下是无法满足子类的 equals 的需求 。

比如所有的对象都继承 Object ,默认使用的是 Object 的 equals 方法,在比较两个对象的时候,是看他们是否指向同一个地址。但是我们的需求是对象的某个属性相同,就相等了,而默认的 equals 方法满足不了当前的需求,所以我们要重写 equals 方法。

如果重写了 equals 方法,就必须重写 hashCode 方法,否则就会降低 Map 等集合的索引速度

19.这样的 a.hashCode() 有什么用,与 a.equals(b) 有什么关系?

1.equals 方法,用于比较对象的内容是否相等

当覆盖了 equals 方法时,比较对象是否相等将通过覆盖后的 equals 方法进行比较(判断对象的内容是否相等)

2.hashCode 方法,大多在集合中用到

将对象放入到集合中时,首先判断要放入对象的 hashCode 值与集合中的任意一个元素的 hashCode 值是否相等,如果不相等直接将该对象放入集合中

如果 hashCode 值相等,然后再通过 equals 方法判断要放入对象与集合中的任意一个对象是否相等,如果 equals 判断不相等,直接将该元素放入到集合中,否则不放入。

20. 有没有可能 2 个不相等的对象有相同的 hashCode?

可能会发生,这个被称为哈希碰撞。当然,相等的对象,即我们重写了 equals 方法,一定也要重写 hashCode 方法,否则将出现我们在 HashMap 中,相等的对象作为 key ,将找不到对应的 value

equals 不相等,hashCode 可能相等。

equals 相等,请重写 hashCode 方法,保证 hashCode 相等

21.final,finally,finalize的区别?

final

如果一个类被声明为 final ,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract 的,又被声明为 final 的 ,将变量或方法声明为 final ,可以保证它们在使用中不被改变。被声明为 final 的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为 final 的方法也同样只能使用,不能重写。

finally

在异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)

在以下 4 种特殊情况下,finally块不会被执行

finally 语句块中发生了异常 

在前面的代码中用了 System.exit() 退出程序

程序所在的线程死亡。

关闭 CPU

finalize

Java 允许使用 finalize() 方法,在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的

它是在 Object 类中定义的,因此所有的类都继承了它

子类覆盖 finalize() 方法,以整理系统资源或者执行其他清理工作

finalize() 方法,是在垃圾收集器删除对象之前对这个对象调用的

22.String 类能被继承吗,为什么?

不能,因为 String 是 final 修饰

23.抽象类和接口有什么区别?

接口中的所有方法都是抽象的,抽象类中可以有非抽象方法

类可以实现多个接口,但是只能继承一个抽象类

抽象类可以在不提供接口方法实现的情况下实现接口

Java 接口中声明的变量默认都是 final 的。抽象类可以包含非 final 的变量

Java 接口中的成员函数默认是 public 的。抽象类的成员函数可以是 privateprotected 或者是 public

接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包main(String[] args) 方法的话是可以被调用的。

23.类实例化的顺序?

1.父类静态变量。

2.父类静态代码块

3.子类静态变量

4.子类静态代码块

5.父类非静态变量(父类实例成员变量)

6.父类构造函数

7.子类非静态变量(子类实例成员变量)

8.子类构造函数

24.什么是io

25.什么是java序列化?

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化

可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。

序列化是为了解决在对对象流进行读写操作时所引发的问题

反序列化的过程,则是和序列化相反的过程

另外,我们不能将序列化局限在 Java 对象转换成二进制数组,例如说,我们将一个 Java 对象,转换成 JSON 字符串,或者 XML 字符串,这也可以理解为是序列化。

26.如何实现 Java 序列化?

将需要被序列化的类,实现 Serializable 接口,该接口没有需要实现的方法,implements Serializable 只是为了标注该对象是可被序列化的。

27. Java 序列话中,如果有些字段不想进行序列化怎么办?

对于不想进行序列化的变量,使用 transient 关键字修饰。

当对象被序列化时,阻止实例中那些用此关键字修饰的的变量序列化。

当对象被反序列化时,被 transient 修饰的变量值不会被持久化和恢复。

transient 只能修饰变量,不能修饰类和方法。

28.如何实现对象克隆?

1、实现 Cloneable 接口,并重写 Object 类中的 clone() 方法。可以实现浅克隆,也可以实现深克隆。

2、实现 Serializable 接口,通过对象的序列化和反序列化实现克隆。可以实现真正的深克隆

29.error和excepion有什么区别?

Error(错误),表示系统级的错误和程序不必处理的异常,是 Java 运行环境中的内部错误或者硬件问题。

例如:内存资源不足等 。

对于这种错误,程序基本无能为力,除了退出运行外别无选择,它是由 Java 虚拟机抛出的。

Exception(异常),表示需要捕捉或者需要程序进行处理的异常,它处理的是因为程序设计的瑕疵而引起的问题或者在外的输入等引起的一般性问题,是程序必须处理的。Exception 又分为运行时异常,受检查异常。

RuntimeException(运行时异常),表示无法让程序恢复的异常,导致的原因通常是因为执行了错误的操作,建议终止逻辑,因此,编译器不检查这些异常

CheckedException(受检查异常),是表示程序可以处理的异常,也即表示程序可以修复(由程序自己接受异常并且做出处理),所以称之为受检查异常。

30.Throwable 类常用方法?

getMessage() 方法:返回异常发生时的详细信息

getCause() 方法:获得导致当前 Throwable 异常的 Throwable 异常

printStackTrace() 方法:在控制台上打印。

31.请列出 5 个运行时异常 ?

NullPointerException ,IndexOutOfBoundsException ,ClassCastException ,ArrayStoreException ,BufferOverflowException

32.throwthrows 的区别 ?

throw ,用于在程序中显式地抛出一个异常。

throws ,用于指出在该方法中没有处理的异常。每个方法必须显式指明哪些异常没有处理,以便该方法的调用者可以预防可能发生的异常。最后,多个异常用逗号分隔。

33. 异常处理中 finally 语句块的重要性?

不管程序是否发生了异常, finally 语句块都会被执行,甚至当没有catch 声明但抛出了一个异常时, finally 语句块也会被执行。 inally 语句块通常用于释放资源, 如 I/O 缓冲区, 数据库连接等等。

34.异常被处理后异常对象会发生什么?

异常对象会在下次 GC 执行时被回收

35.反射的用途及实现?

在运行时构造一个类的对象。

判断一个类所具有的成员变量和方法

调用一个对象的方法。

生成动态代理

36.反射的应用

Spring 框架的 IoC 基于反射创建对象和设置依赖属性。

Spring MVC 的请求调用对应方法,也是通过反射

JDBC 的 ClassforName(String className) 方法,也是使用反射。

37. 反射中,Class.forName 和 ClassLoader 区别?

ClassforName(...) 方法,除了将类的 .class 文件加载到JVM 中之外,还会对类进行解释,执行类中的 static 块。

ClassLoader 只干一件事情,就是将 .class 文件加载到 JVM 中,不会执行 static 中的内容,只有在 newInstance 才会去执行 static 块。

38.java创建对象的方式?

1.使用 new 关键字创建对象

2.使用 Class 类的 newInstance 方法(反射机制)。

3.使用 Constructor 类的 newInstance 方法(反射机制)。

4.使用 clone 方法创建对象

5.使用(反)序列化机制创建对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值