184 lines
5.5 KiB
Markdown
184 lines
5.5 KiB
Markdown
# 十万个为什么
|
||
|
||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||
> 分类 ID:`2022050622313300000000000022` · 排序:3 · 文章数:4
|
||
|
||
## 目录
|
||
|
||
1. [java基础面试问题1](#java基础面试问题1)
|
||
2. [31.序列化](#31序列化)
|
||
3. [反射的原理是什么](#反射的原理是什么)
|
||
4. [为什么JDK动态代理只能代理接口](#为什么jdk动态代理只能代理接口)
|
||
|
||
---
|
||
|
||
## 1. java基础面试问题1
|
||
|
||
<sub>bid: `2022050622313400000000000023`</sub>
|
||
|
||
## java基础面试问题
|
||
|
||
### 1. JAVA中的几种基本数据类型是什么,各自占用多少字节。
|
||
基本数据类型有8种:
|
||
|
||
整数型
|
||
byte 1个字节
|
||
short 2 字节
|
||
int 4字节
|
||
long 8个字节
|
||
|
||
浮点型
|
||
float 4字节
|
||
double 8字节
|
||
|
||
布尔型
|
||
boolean 4字节
|
||
|
||
字节型
|
||
Char 两字节
|
||
|
||
### 2. String类能被继承吗,为什么。
|
||
String类是被final修饰的。
|
||
|
||
不可以的
|
||
被final修饰的类是不能被继承的,
|
||
final修饰的方法是不能被重写的
|
||
被final修饰的变量是无法重新指向另一个对象的。
|
||
|
||
可以的
|
||
但是被final的方法是可以重载的。
|
||
|
||
### 3. StringBuilder和Stringbuffer区别
|
||
都是字符串的类,性能String最低,Stringbuffer较好,StringBuilder最快。
|
||
安全性上StringBuilder是线程不安全的。
|
||
Stringbuffer是线程安全的。
|
||
|
||
### 4. 用过哪些Map类,都有什么区别,
|
||
HashMap是线程安全的吗,并发下使用的Map是什么,他们
|
||
内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。
|
||
|
||
比较我比较常用的
|
||
线程不安全的HashMap,TreeMap。
|
||
线程安全的ConcurrentHashMap,
|
||
|
||
### 5. ArrayList和LinkedList有什么区别
|
||
|
||
### 6. hashMap
|
||
|
||
JDK1.8 开始, 数组 + 链表 或者 数组 + 红黑树
|
||
HashMap 维护了 一个 Node[] 的数组,默认的初始数组大小是16
|
||
负载因子为0.75,当数组中超出容量的0.75倍时,进行容量x2扩容。
|
||
|
||
## 重要源码部分
|
||
|
||
|
||
默认的负载因子,为什么是0.75?
|
||
static final float DEFAULT_LOAD_FACTOR = 0.75f;
|
||
默认的初始容量为16
|
||
1 -》 10000 —-》 16
|
||
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
|
||
最大容量为2的30次方
|
||
static final int MAXIMUM_CAPACITY = 1 << 30;
|
||
链表到红黑树转化的阈值
|
||
static final int TREEIFY_THRESHOLD = 8;
|
||
红黑树到链表转化的阈值
|
||
static final int UNTREEIFY_THRESHOLD = 6;
|
||
转树所必要的最小容量
|
||
static final int MIN_TREEIFY_CAPACITY = 64;
|
||
public HashMap() {
|
||
this.loadFactor = DEFAULT_LOAD_FACTOR;
|
||
}
|
||
|
||
为什么是 异或 ? 保持更好的散列性
|
||
右移 16位,高位补0,为什么
|
||
static final int hash(Object key) {
|
||
int h;
|
||
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
|
||
}
|
||
|
||
这个loadFactor 会在 resize()方法中被调用
|
||
resize() 也是node 节点初始化的
|
||
|
||
## 为什么是 异或
|
||
^ 表示 异或 运算符 - 》 相同为0 不相同为1
|
||
异或 可以保持更好的散列性。
|
||
与 运算 1/4 的是1 ,3/4 的是0,所以得到的数更小
|
||
或 运算 1/4 的是0 ,3/4 的是1,所以得到的数更大
|
||
异或 运算 2/4 的是1 ,2/4 的是0,所以得到的数更有散列性
|
||
|
||
## HashMap源码中在计算hash值的时候为什么要右移16位
|
||
|
||
(h = key.hashCode()) ^ (h >>> 16)
|
||
h & (length-1) 与运算
|
||
|
||
|
||
## 为什么 负载因子 是 0.75
|
||
|
||
## mod 取模运算符
|
||
|
||
在java 中
|
||
取 商 运算符 /
|
||
取 余 运算符 %
|
||
|
||
计算整数商 c = a/b
|
||
计算模 r = a - c*b
|
||
|
||
x mod 2^n = x & (2^n - 1)
|
||
|
||
还是 以 10 / 8 为类
|
||
x -》 1010
|
||
2^n 0111
|
||
& 运算 0010
|
||
-----------
|
||
2
|
||
从二进制角度来说,x (1010)向右移动3位,得到商(1)
|
||
除掉的部分010 则是余数,即2
|
||
|
||
---
|
||
|
||
## 2. 31.序列化
|
||
|
||
<sub>bid: `2022050822283700000000000002`</sub>
|
||
|
||
### 序列化
|
||
---
|
||
什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决。
|
||
|
||
du
|
||
|
||
---
|
||
|
||
## 3. 反射的原理是什么
|
||
|
||
<sub>bid: `2022050900177700000000000003`</sub>
|
||
|
||
反射的原理,反射创建类实例的三种方式是什么
|
||
|
||
Jvm加载类(包括接口,注解,枚举,接口)信息时,会将该信息以类对象(包名.类名)的形式存储于方法区。
|
||
|
||
Java反射是指,在Jvm运行时,对于一个类,都能通过反射获取,这个类的属性,方法,构造器等,对于一个对象,通过反射可以调用他的全部属性和方法,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
|
||
|
||
Java反射作为动态编译而存在,极大的提高了Java语言的灵活性。
|
||
|
||
Java反射有三种方式获取类实例(不是对象实例):
|
||
1.Class.forName(),通过指定包名类名的方式在方法区去需要找该类。
|
||
2.XXX.class, 通过类名.class,局限性是非动态。
|
||
3.实例对象.getClass()。
|
||
|
||
第一种类加载方式,是加载外部类的最常用方式。
|
||
第三种方式,是已知对象情况下的,获取该类的最好方式
|
||
|
||
---
|
||
|
||
## 4. 为什么JDK动态代理只能代理接口
|
||
|
||
<sub>bid: `2022122811384800000000000013`</sub>
|
||
|
||
为什么JDK动态代理只能代理接口,不能直接代理类?CGlib为什么可以代理类?
|
||
|
||
动态代理生成的Proxy\$0类是继承了Proxy类并且implements代理接口,但由于java是不能多继承的,所以动态代理不能代理类。
|
||
|
||
cglib实现动态代理的逻辑是使用子类继承代理类,就没有单继承的限制了.
|
||
|
||
---
|