# 十万个为什么 > 来源:原 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 bid: `2022050622313400000000000023` ## 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.序列化 bid: `2022050822283700000000000002` ### 序列化 --- 什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决。 du --- ## 3. 反射的原理是什么 bid: `2022050900177700000000000003` 反射的原理,反射创建类实例的三种方式是什么 Jvm加载类(包括接口,注解,枚举,接口)信息时,会将该信息以类对象(包名.类名)的形式存储于方法区。 Java反射是指,在Jvm运行时,对于一个类,都能通过反射获取,这个类的属性,方法,构造器等,对于一个对象,通过反射可以调用他的全部属性和方法,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 Java反射作为动态编译而存在,极大的提高了Java语言的灵活性。 Java反射有三种方式获取类实例(不是对象实例): 1.Class.forName(),通过指定包名类名的方式在方法区去需要找该类。 2.XXX.class, 通过类名.class,局限性是非动态。 3.实例对象.getClass()。 第一种类加载方式,是加载外部类的最常用方式。 第三种方式,是已知对象情况下的,获取该类的最好方式 --- ## 4. 为什么JDK动态代理只能代理接口 bid: `2022122811384800000000000013` 为什么JDK动态代理只能代理接口,不能直接代理类?CGlib为什么可以代理类? 动态代理生成的Proxy\$0类是继承了Proxy类并且implements代理接口,但由于java是不能多继承的,所以动态代理不能代理类。 cglib实现动态代理的逻辑是使用子类继承代理类,就没有单继承的限制了. ---