关于java:Java面试中最容易忽略的细节你中了几个避坑指南送你

1次阅读

共计 7504 个字符,预计需要花费 19 分钟才能阅读完成。

今日分享开始啦,请大家多多指教~

学习 Java 要明确本人的需要,晓得本人要做什么;剖析思路,晓得本人要怎么做。确定步骤,每一个思路局部用到哪些办法和对象。最初用代码实现,用具体的 java 语言把思路体现进去。

1.Java 的 8 种根本数据类型 及其大小?

Java 要确定每种根本类型所占存储空间的大小,它们的大小并不像其余大多数语言那样随机器硬件架构的变动而变动。这种所占存储空间大小的不变性是 Java 程序比用其余大多数语言编写的程序更具可移植性的起因之一。

2.Java 根本类型与援用类型的区别?

根本类型保留原始值,援用类型保留的是援用值(援用值就是指对象在堆中所处的地位 / 地址)

3. 主动装箱和拆箱是什么?

主动装箱是 Java 编译器在根本数据类型和对应的对象包装类型之间做的一个转化。

比方:把 int 转化成 Integer,double 转化成 Double,等等。反之就是主动拆箱。

原始类型: boolean,char,byte,short,int,long,float,double

封装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

装箱:将根本类型用它们对应的援用类型包装起来;

拆箱:将包装类型转换为根本数据类型;

4. 字节与字符的区别?

字节是存储容量的根本单位。

字符是数字,字母,汉字以及其余语言的各种符号。

1 字节 =8 个二进制单位;字符由一个字节或多个字节的二进制单位组成。

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

简便答复:

1. 面向对象因为有封装、继承和多态等个性,所以是易保护、易复用和易扩大的。

2. 面向过程性能比面向对象高。因为类调用时实例化开销大,耗费资源。罕用在单片机、嵌入式等。
3. 最典型的例子就是。雕版印刷是面向过程,活字印刷是面向对象。

具体介绍

面向过程:面向过程性能比面向对象高。因为类调用时须要实例化,开销比拟大,比拟耗费资源,所以当性能是最重要的考量因素的时候,比方单片机、嵌入式开发、Linux/Unix 等个别采纳面向过程开发。然而,面向过程没有面向对象易保护、易复用、易扩大。

面向对象:面向对象易保护、易复用、易扩大。因为面向对象有封装、继承、多态性的个性,所以能够设计出低耦合的零碎,使零碎更加灵便、更加易于保护。然而,面向对象性能比面向过程低。

实例:

面向对象如活字印刷,面向过程如雕版印刷,面向过程的时候你须要从头到尾思考每一个细节,比方你要刻下学而时习之,不亦说乎这几个字,如果是雕版印刷,你必定要一环扣一环,“学”前面要刻“而”,“而”前面要刻好“时”,一旦你想改成学而时习之,我不可开交。则原来那一块雕版就得作废,重头改。

而面向对象则把每一个字看作一个对象,相似于活字印刷,你如果想加字,你只有再多刻一个“我”就能够了,其它写好的就不必改了。并且在这里我引申出以下几个概念

一、要改,只需更改要改之字,此为可保护;

二、这些字并非用完这次就无用,齐全能够在起初的印刷中重复使用,此乃可复用;

三、此诗若要加字,只需另刻字退出即可,这是可扩大;

6. JDK 和 JRE 的区别?

JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。

JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。具体来说 JDK 其实蕴含了 JRE,同时还蕴含了编译 Java 源码的编译器 Javac,还蕴含了很多 Java 程序调试和剖析的工具。

简略来说:如果你须要运行 Java 程序,只需装置 JRE 就能够了,如果你须要编写 Java 程序,须要装置 JDK。

JDK(Java Development Kit),Java 语言的软件开发工具包。

两个次要组件:

javac- 编译器,将源程序转成字节码

java- 运行编译后的 java 程序(.class 后缀的)

JRE(Java Runtime Environment)

包含 Java 虚拟机(JVM)、Java 外围类库和反对文件

如果只须要运行 Java 程序,下载并装置 JRE 即可

如果要开发 Java 软件,须要下载 JDK

在 JDK 中附带有 JRE

7. 重载和重写的区别?

办法的重载和重写都是实现多态的形式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。

重载产生在一个类中,同名的办法如果有不同的参数列表(类型不同、个数不同、程序不同)则视为重载。重载对返回类型没有非凡的要求。

重写产生在子类与父类之间,重写要求子类重写之后的办法与父类被重写办法有雷同的返回类型,比父类被重写办法更好的拜访范畴,不能比父类被重写办法申明更多的异样(里氏代换准则)。

办法重载的规定:

  • 办法名统一,参数列表中参数的程序,类型,个数不同。
  • 重载与办法的返回值无关,存在于父类和子类,同类中。
  • 能够抛出不同的异样,能够有不同修饰符。

办法重写的规定:

  • 参数列表、办法名、返回值类型必须完全一致;
  • 构造方法不能被重写;
  • 申明为 final 的办法不能被重写;
  • 申明为 static 的办法不存在重写(重写和多态联结才有意义);
  • 拜访权限不能比父类更低;
  • 重写之后的办法不能抛出更宽泛的异样;

8. String 和 StringBuffer、StringBuilder 的区别是什么?

简便答复

1.String 是不可变的,StringBuffer 和 StringBuilder 都是可变的。

2.String 不可变,可视为常量,所以线程平安;StringBuffer 应用时加了同步锁,所以是线程平安的;StringBuilder 没加锁,所以不是线程平安的。

3. 操作大量数据用 String;单线程字符串缓冲区下操作大量数据用 StringBuilder;多线程字符串缓冲区下操作大量数据用 StringBuffer。

1. 可变性

简略地来说:String 类中应用 final 关键字润饰字符数组来保留字符串,private final char value[],所以 String 对象是不可变的。而 StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是应用字符数组保留字符串 char[]value 然而没有用 final 关键字润饰,所以这两种对象都是可变的。

StringBuilder 与 StringBuffer 的构造方法都是调用父类构造方法也就是 AbstractStringBuilder 实现的,大家能够自行查阅源码。

AbstractStringBuilder.java

2. 线程安全性

String 中的对象是不可变的,也就能够了解为常量,线程平安。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共办法。StringBuffer 对办法加了同步锁或者对调用的办法加了同步锁,所以是线程平安的。StringBuilder 并没有对办法进行加同步锁,所以是非线程平安的。

3. 性能

每次对 String 类型进行扭转的时候,都会生成一个新的 String 对象,而后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象自身进行操作,而不是生成新的对象并扭转对象援用。雷同状况下应用 StringBuilder 相比应用 StringBuffer 仅能取得 10%~15% 左右的性能晋升,但却要冒多线程不平安的危险。

对于三者应用的总结:

  • 操作大量的数据: 实用 String
  • 单线程字符串缓冲区下操作大量数据: 实用 StringBuilder
  • 多线程字符串缓冲区下操作大量数据: 实用 StringBuffer

9. 反射 Class.forName 和 classLoader 有什么区别

第一:Class.forName(“className”);

其实这种办法调运的是:Class.forName(className,true,ClassLoader.getCallerClassLoader()) 办法

  • 参数一:className,须要加载的类的名称。
  • 参数二:true,是否对 class 进行初始化(须要 initialize)
  • 参数三:classLoader,对应的类加载器

第二:ClassLoader.laodClass(“className”);

其实这种办法调运的是:ClassLoader.loadClass(name,false) 办法

  • 参数一:name, 须要加载的类的名称
  • 参数二:false,这个类加载当前是否须要去连贯(不须要 linking)

第三:区别

可见 Class.forName 除了将类的.class 文件加载到 jvm 中之外,还会对类进行解释,执行类中的 static 块。

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

10. 反射的应用场景

代理模式,JDBC 链接数据库,Spring

11. 反射的毛病是什么?如何优化?

毛病:java 反射是要解析字节码,将内存中的对象进行解析,包含了一些动静类型,所以 JVM 无奈对这些代码进行优化。因而,反射操作的效率要比那些非反射操作低得多!

进步反射性能的形式有哪些?

  1. setAccessible(true), 能够避免安全性查看(做这个很费时)
  2. 做缓存,把要常常拜访的元数据信息放入内存中,class.forName 太耗时
  3. getMethods() 等办法尽量少用,尽量调用 getMethod(name) 指定办法的名称,缩小遍历次数

12. 动态代理模式和动静代理模式的区别

动态:由程序员创立代理类。在程序运行前要代理的对象就曾经指定了。

动静:在程序运行时使用反射机制动态创建而成。(InvocationHandler 的利用)

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

String 类中应用 final 关键字润饰字符数组来保留字符串,private final char value[],所以 String 对象是不可变的。而 StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是应用字符数组保留字符串 char[]value 然而没有用 final 关键字润饰,所以这两种对象都是可变的。

14. 抽象类和接口的区别是什么?

实现:抽象类的子类应用 extends 来继承;接口必须应用 implements 来实现接口。

构造函数:抽象类能够有构造函数;接口不能有。

实现数量:类能够实现很多个接口;但只能继承一个抽象类【java 只反对单继承】。

拜访修饰符:接口中的办法默认应用 public 润饰;抽象类中的形象办法能够应用 Public 和 Protected 润饰,如果形象办法修饰符为 Private,则报错:The abstract method 办法名 in type Test can only set a visibility modifier, one of public or protected。

接口中除了 static、final 变量,不能有其余变量,而抽象类中则不肯定

设计层面:形象是对类的形象,是一种模板设计,而接口是对行为的形象,是一种行为的标准。

在抽象类中能够为局部办法提供默认的实现,从而防止了反复实现它们,进步了代码的可重用性,这是抽象类的劣势。

15. 常见的异样类有哪些?

NullPointerException 空指针异样

ClassNotFoundException 指定类不存在

NumberFormatException 字符串转换为数字异样

IndexOutOfBoundsException 数组下标越界异样

ClassCastException 数据类型转换异样

FileNotFoundException 文件未找到异样

NoSuchMethodException 办法不存在异样

IOException IO 异样

SocketException Socket 异样

16. 什么是 Java 序列化?什么状况下须要序列化?

Java 序列化是为了保留各种对象在内存中的状态,并且能够把保留的对象状态再读出来。

以下状况须要应用 Java 序列化:

想把的内存中的对象状态保留到一个文件中或者数据库中时候;

想用套接字在网络上传送对象的时候;

想通过 RMI(近程办法调用)传输对象的时候。

17. 一般类和抽象类有哪些区别?

一般类不能蕴含形象办法,抽象类能够蕴含形象办法。

抽象类是不能被实例化的,就是不能用 new 调出构造方法创建对象,一般类能够间接实例化。

如果一个类继承于抽象类,则该子类必须实现父类的形象办法。如果子类没有实现父类的形象办法,则必须将子类也定义为 abstract 类。

18. 抽象类能应用 final 润饰吗?

不能,定义抽象类就是让其余类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能润饰抽象类

19.String 类的罕用办法都有哪些?

indexOf():返回指定字符的索引。

charAt():返回指定索引处的字符。

replace():字符串替换。

trim():去除字符串两端空白。

split():宰割字符串,返回一个宰割后的字符串数组。

getBytes():返回字符串的 byte 类型数组。

length():返回字符串长度。

toLowerCase():将字符串转成小写字母。

toUpperCase():将字符串转成大写字符。

substring():截取字符串。

equals():字符串比拟。

20. 抽象类必须要有形象办法吗?

不须要,抽象类不肯定非要有形象办法;然而蕴含一个形象办法的类肯定是抽象类。

21.String str=”i” 与 String str=new String(“i”) 一样吗?

不一样,因为内存的调配形式不一样。String str=“i” 的形式,Java 虚构机会将其调配到常量池中,如果常量池中有 ”i”,就返回 ”i” 的地址,如果没有就创立 ”i”,而后返回 ”i” 的地址;而 String str=new String(“i”) 则会被分到堆内存中新开拓一块空间。

22.String 属于根底的数据类型吗?

String 不属于根底类型,根底类型有 8 种:byte、boolean、char、short、int、float、long、double,而 String 属于对象。

23. final 在 Java 中有什么作用?

final 润饰的类叫最终类,该类不能被继承。

final 润饰的办法不能被重写。

final 润饰的变量叫常量,常量必须初始化,初始化之后值就不能被批改。

24.Java 中的 Math. round(-1. 5) 等于多少?

等于 -1。round() 是四舍五入,留神正数 5 是舍的,例如:Math.round(1.5) 值是 2,Math.round(-1.5) 值是 -1。

25.== 与 equals 的区别?

== 解读:

对于根本类型和援用类型 == 的作用成果是不同的,如下所示:

根本类型:比拟的是值是否雷同;援用类型:比拟的是援用是否雷同;代码示例:

代码解读:因为 x 和 y 指向的是同一个援用,所以 == 也是 true,而 new String() 办法则重写开拓了内存空间,所以 == 后果为 false,而 equals 比拟的始终是值,所以后果都为 true。

equals 解读:

equals 实质上就是 ==,只不过 String 和 Integer 等重写了 equals 办法,把它变成了值比拟。看上面的代码就明确了。

首先来看默认状况下 equals 比拟一个有雷同值的对象,代码如下:

输入后果出乎咱们的预料,居然是 false?这是怎么回事,看了 equals 源码就晓得了,源码如下:

原来 equals 实质上就是 ==。那问题来了,两个雷同值的 String 对象,为什么返回的是 true?代码如下:

同样的,当咱们进入 String 的 equals 办法,找到了答案,代码如下:

原来是 String 重写了 Object 的 equals 办法,把援用比拟改成了值比拟。

总结:== 对于根本类型来说是值比拟,对于援用类型来说是比拟的是援用;而 equals 默认状况下是援用比拟,只是很多类从新了 equals 办法,比方 String、Integer 等把它变成了值比拟,所以个别状况下 equals 比拟的是值是否相等。

26.hashCode 与 equals

  • hashCode()介绍

hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引地位。hashCode() 定义在 JDK 的 Object.java 中,这就意味着 Java 中的任何类都蕴含有 hashCode() 函数。

散列表存储的是键值对 (key-value),它的特点是:能依据“键”疾速地检索出对应的“值”。这其中就利用到了散列码!(能够疾速找到所须要的对象)

  • 为什么要有 hashCode

当你把对象退出 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象退出的地位,同时也会与其余曾经退出的对象的 hashcode 值作比拟,如果没有相符的 hashcode,HashSet 会假如对象没有反复呈现。然而如果发现有雷同 hashcode 值的对象,这时会调用 equals()办法来查看 hashcode 相等的对象是否真的雷同。如果两者雷同,HashSet 就不会让其退出操作胜利。如果不同的话,就会从新散列到其余地位。(摘自我的 Java 启蒙书《Head first java》第二版)。这样咱们就大大减少了 equals 的次数,相应就大大提高了执行速度。

  • hashCode()与 equals()的相干规定

1. 如果两个对象相等,则 hashcode 肯定也是雷同的

2. 两个对象相等, 对两个对象别离调用 equals 办法都返回 true

3. 两个对象有雷同的 hashcode 值,它们也不肯定是相等的

4. 因而,equals 办法被笼罩过,则 hashCode 办法也必须被笼罩

5.hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即便这两个对象指向雷同的数据)

小结:

首先建设好 Java 根底十分重要,工欲善其事,必先利其器。做任何事件,首先就是要把这个根底筹备好,之后就能够去做各种尝试,尝试过程中就能逐步建设信念。

今日份分享已完结,请大家多多包涵和指导!

正文完
 0