每日一道面试题
随着互联网的环境变差,换工作也变的越来越难.生活也更加焦虑,因此开启了此文.以学习对抗焦虑.每天学习一点,可能是一道面试题也可能是算法,或者某些未知的领域,面试题主要复习开源项目JavaGuide,一个算法题,复习自代码随想录.
零.编程基础
- 学好英语,经常重构,尽可能做到代码就是注释,为自己的代码增加必要的测试.(当你做不到代码就是注释见面知意时,还是好好写好注释,为’屎山’留有一线生机),参考书籍《Clean Code》《重构》
一.Java基础
基本类型与包装类型,包装的缓存机制,自动拆箱装箱
基本类型与包装类型的区别
- 用途:都可定义变量,包装类型更常用,还可用与泛型.
- 存储方式:基本数据类型的局部变量存放在Java虚拟机栈中的局部变量表中,基本数据类型的成员变量(未被
static
修饰 )存放在 Java 虚拟机的堆中。包装类型属于对象类型,我们知道几乎所有对象实例都存在于堆中。 - 占用空间:基本类型要小于包装类型(对象类型)
- 默认空间:包装类型(对象)为
null
,基本类型有各自的默认值 - 比较方式:基本类型使用
==
比较值,包装类型(对象)使用equals(),不可用==
,对象比较的是内存地址1
2
3TODO
为什么说是几乎所有对象实例都存在于堆中呢?
这是因为 HotSpot 虚拟机引入了 JIT 优化之后,会对对象进行逃逸分析,如果发现某一个对象并没有逃逸到方法外部,那么就可能通过标量替换来实现栈上分配,而避免堆上分配内存
包装类型的缓存机制
Java基本类型的包装类型大部分都使用了缓存来提高性能.两种浮点数类型的包装类 Float
,Double
并没有实现缓存机制。Byte
,Short
,Integer
,Long
这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character
创建了数值在 [0,127] 范围的缓存数据,Boolean
直接返回 True
or False
。Integer
源码
1 | /** |
如果超出对应范围仍然会去创建新的对象,缓存的范围区间的大小只是在性能和资源之间的权衡.
1 | // 如果需要-128-127 Integer对象,可以直接使用构造函数new对象 |
自动装箱与拆箱
- 装箱:基础->包装
- 拆箱:包装->基础
以Integer
为例: - 装箱使用了包装类的
valueOf()
方法,拆箱其实就是调用了intValue()
频繁拆装箱会严重影响系统性能
为什么浮点数运算的时候会有精度丢失的风险,如何解决
精度丢失
计算机报错数据都是以二进制0101进行保存的.并且在表示一个数字时,宽度是有限的,无限循环的小数被存储是只能被截断.导致的精度损失
如何解决
使用BigDecimal可以实现对浮点数的运算,不会造成精度丢失。通常情况下,大部分需要浮点数精确运算结果(比如涉及到钱的场景),都需要通过BigDecimal
来做.
超过long整型的数字改怎么表示
超出基本类型的表达范围会有数值溢出的风险,64位的long整型是最大的整数类型为:9223372036854775807.
如果超过这个数值,可以使用BigInteger,BigInteger内部使用int[]
数组来存储任意大小的整形数据.但是运行效率相对较低.
深拷贝与浅拷贝
- 浅拷贝:浅拷贝会在堆上创建一个新的对象,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,拷贝对象和原对象共用同一个内部对象.
- 深拷贝:深拷贝会完全复制整个对象,包括这个对象所包含的内部对象
Object类的常见方法有哪些?
Object是所有类的父类,它一共提供了11个方法,其中多次出现native关键字
native关键字说明这个方法是原生函数(是使用C/C++语言实现的,并编译成了DLL,由Java去调用)
1 | /** |
hashCode()有什么用
获取哈希码(int).哈希码的作用是确定该对象在哈希表中的索引位置.hashCode在Object中是native方法.哈希表是键值对(key-value)
JDK为什么要提供hashCode和equals两个方法去做对象是否相等
- hashCode效率更高
- hashCode使用的哈希算法,有可能会让多个不通的对象返回相同的哈希值.这时就需要使用equals方法去进行比较
为什么重写equals时必须重写hashCode
可能会导致,equals判断值相同,但是hashCode调用Object中的方法,两个对象哈希值不同,导致不相同