面试中会遇到的 12 个 Java 冷知识,你懂多少?

发布于:2021-10-28 02:42:49

通常,在面试中,会遇到面试官提一些比较“偏冷”的基础知识,比如基本数据类型所占用的字节数,或者Unicode和UTF-8的区别之类的问题,这时很多应聘者会答错。还有在*常编码的过程中,很多时候会用到除法计算,比如对一个长度为100万的List中的所有元素进行除16的操作,那么CPU对element<<4操作的运算会快于element/16的操作……


因此,本文对一些容易被遗忘的基础知识进行归纳,希望可以帮助广大程序员轻松应对面试官的基础技术问题,以及提升编码效率。本文适合有一定Java基础的技术人员阅读,部分内容对初学者来说可能会比较吃力。


1.Java中的基本数据类型以及所占内存大小

(1)整形
byte 1字节
short 2字节
int 4字节
long 8字节


(2)浮点型
float 4字节
double 8字节


(3)字符类型
char 2字节(Unicode-16)


(4)布尔类型
布尔类型boolean比较特殊,尽管Java虚拟机定义了boolean类型,但虚拟机对boolean类型的支持是有限的,没有为boolean值单独设计JVM指令。操作布尔值的表达式在编译之后,它使用的是JVM的int数据类型,也就是占用4个字节。
JVM也不会直接支持boolean数组,boolean数组在编译之后,它的元素采用byte数据类型,用0表示false,1表示true,也就是boolean数组的元素只占用一个字节。



需要更多大厂面试资料的话也可以点击直接进入,免费获取!暗号:CSDN



2.UTF-8与Unicode的关系

Unicode是一个统一的编码标准,将现有的所有字符进行唯一编码。在第一个Unicode版本中,使用两个字节(16位)来表示一个字符,注意这里的字节并非指的是计算机内存中的存储单元,而是一个数学长度单位而已。然而,一个Unicode字符在内存中存储所占用的长度,就需要一个具体的编码规则来实现,比如UTF-8。因此,Unicode只是一个编码标准,而UTF-8是对这个标准的一个实现,UTF-8规定了一个Unicode字符在内存中占用的空间(英文和中文所占空间是不同的,有兴趣的读者可以查阅相关资料)。


代码点指的是可以用于对字符集进行编码的那些数字,比如在16位的Unicode编码字符集中,字符“A”的编码是U+0041,那么0041就是一个代码点。


代码单元指的是字符所占空间的单元。例如在UTF-32中,一个代码单元为32位,一个字符占用32位,恰好使用一个代码单元,这种方式会耗费大量内存。在UTF-16中,一个代码单元为16位,值 U+0000 至 U+FFFF 编码对应一个字符,每个字符占用一个代码单元,但是,对于超过这个范围的那些增补字符的编码,需要两个这样的单元(即32位)。而在UTF-8中,一个代码单元为8位,UTF-8 使用一至四个字节的序列对编码 Unicode 代码点进行编码,原理同UTF-32和UTF-16。


3.String字符串常量

在Java语言中,一个String字符串常量对应着一个String对象,并且是不可更改和继承的(因为String类被final关键字修饰)。Java语言这样设计,主要是为了使得字符串常量(注意是字符串常量,字符串变量不符合这里所讲的规则)可以共享,因为JVM将字符串常量放入公共的存储池中,不同的变量可以引用相同的字符串常量。

以上代码运行结果为:true。这就说明a和b引用的是同一String对象。


4.基本数据类型转换规则

在双操作数运算中,会根据操作数类型将低级的一个类型转换为高级的一个类型。
1)只要两个操作数中有一个是double类型的,另一个将会被转换成double类型,并且结果也是double类型;
2)只要两个操作数中有一个是float类型的,另一个将会被转换成float类型,并且结果也是float类型;
3)只要两个操作数中有一个是long类型的,另一个将会被转换成long类型,并且结果也是long类型;
4)两个操作数(包括byte、short、int、char)都将会被转换成int类型,并且结果也是int类型。


5.按值调用与按引用调用

按值调用表示方法接收的是调用者提供的参数值。按引用调用表示方法接收的是调用者提供的是调用者提供的参数地址。Java程序设计语言总是按值调用的。下面是反例代码:

以上代码启动交换a和b所引用的对象,但实际编译执行会发现没有成功交换。这也就证明Java不是按引用调用的,a和b仅代表两个Person对象的值,而不是代表两个对象的引用,在参数传递上与int等基本类型的值没有区别。


6.对象初始化

在使用构造器初始化对象时,首先运行初始化块,然后运行构造器的主题部分。调用构造器的具体初始化步骤如下:
1)类的所有数据域被初始化为默认值(0、false或null)。
2)按照在类中声明的次序,依次执行所有初始化语句和初始化块。
3)如果构造器第一行调用了第二个构造器,则执行第二个构造器。
4)执行构造器的主体。
类第一次加载的时候,将会进行静态域的初始化。所有的静态初始化语句以及静态初始化块都将依照定义的顺序进行。
使用super调用构造器的语句必须是子类构造器的第一条语句。


7.数组

在Java中,子类数组的引用可以转换成父类数组的引用,而不需要采用强制类型转换。


8.继承

在覆盖一个方法的时候,子类方法不能低于父类方法的可见性。即父类方法是protected的,子类覆盖的方法只能是protected或public的。


9.final修饰的类

如果将一个类声明为final的,只有其中的方法自动成为final,而不包括域。


10.equals方法

Object类的equals方法用于检测一个对象与另一个对象是否相等,即判断两个变量的引用是否相同。如果重新定义了equals方法,就必须重新定义hashCode方法,因为向散列表中添加数据时会根据hashCode和equals方法来确定插入位置。如果x.equals(y)返回true,那么x.hashCode()与y.hashCode()的返回值必须相同。


由于枚举值具有固定的实例,因此直接使用“==”就可以判定两个枚举值是否相同,而不需使用equals方法。


11.Class类

JVM会为每个加载的类生成一个Class类型的实例,用于跟踪对象所属的类,获取Class类型实例的方法如下:
1)Object类中的getClass()方法将会返回一个Class类型的实例。
2)Class.forName(className)可以返回className指定类的Class实例。
3)MyClass.class可以返回MyClass类的Class实例。


12.局部类

在方法中声明的类称为局部类(也属于内部类),局部类不仅能够访问包含它们的外部类,还可以访问局部变量。不过,可以被访问的局部变量必须被声明为final。


读者福利

感谢你看到了这里!
我这边整理很多2021最新Java面试题(含答案)和Java学*笔记,如下图



上述的面试题答案小编都整理成文档笔记。 同时也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)免费分享给大家,有需要的可以 点击进入暗号:CSDN!免费分享~



如果喜欢本篇文章,欢迎转发、点赞。


记得关注我!

相关推荐

最新更新

猜你喜欢