参考JavaGuide: 访问链接
重要问题
-
Java 语言的特点(如果你简历上有提到 C++ 可能还会问你 Java 和 C++ 的区别)。【⭐⭐】
-
面向对象 ,封装、继承、多态
-
可移植性,字节码、虚拟机
-
-
比较 JVM 和 JDK 以及 JRE 。【⭐⭐⭐】非常非常基础的一个问题!学了 Java 之后还不知这个问题如何回答的小伙伴自觉去面壁吧!
-
JDK:SDK+JRE+javac+javadoc
-
JRE:运行时环境,JVM+java类库+java命令+基础构件
-
JVM
-
-
为什么说 Java 语言“解释与编译并存”。【⭐⭐】
- 流程
- 字节码=》机器码
- JIT
-
Java 基本类型有哪几种,各占多少位?【⭐⭐】前些年面试常问的一个问题,去年面试过程中只京东问我了
- 8种
-
Java 泛型,类型擦除。【⭐⭐⭐】
-
==
和equals()
的区别。【⭐⭐⭐】:这个问题在 2018 年之前几乎是面试必问的问题,但是现在大厂以及比较少问了,现在小厂中厂问的多。- ==
- equals【重写?】
- String
-
hashCode()
和equals()
【⭐⭐⭐⭐】:这个问题经常问,面试官经常问为什么重写equals()
时要重写hashCode()
方法?另外,这个问题经常结合着HashSet
问。- hashCode()【是什么?返回?Object类?本地?作用?举例HashSet?为什么重写?】
-
重载和重写的区别。 【⭐⭐⭐⭐】
- 类、形式、阶段
-
深拷贝和浅拷贝。【⭐】
-
面向对象和面向过程的区别。【⭐⭐⭐】
- 定义、优缺点
-
成员变量与局部变量的区别。【⭐⭐⭐】
- 属于什么?static?生存时间?赋初值?
-
面向对象三大特性是什么。并解释这三大特性。【⭐⭐⭐⭐】
- 封装、继承、多态
-
String
、StringBuffer
和StringBuilder
的区别。 【⭐⭐⭐⭐】- 变?安全?
-
Java 异常。【⭐⭐⭐】:不会问的特别细。经常的问法是异常可以分为哪几种,然后你答了可检查异常和不可检查异常以后,会让你举例可检查异常有哪些,不可检查有哪些。然后,异常的代码要会写,有一场字节的面试,直接让我写一个把异常捕获了然后抛出去的代码。
-
分类、写代码
-
public static void f()throws Exception{ throw new Exception("Exception: f()"); } public static void g() throws Exception{ try{ f(); }catch(Exception e){ System.out.println("inside g()"); throw e; } }
-
-
序列化和反序列化【⭐⭐】
- 定义 transient
-
反射【⭐⭐】面试官可能会问你什么是反射,它的优缺点是什么,有哪些应用场景。
-
List
、Set、
Map
的区别。【⭐⭐】- 有序?重复?Map<key, value>
-
ArrayList
和LinkedList
的区别。【⭐⭐⭐⭐】:答清楚每个分别采用什么数据结构,对比相应的优点和缺点。- 线程、底层、内存空间
-
比较
HashSet
、LinkedHashSet
和TreeSet
三者的异同。【⭐⭐⭐】- 底层、无序
-
HashMap 多线程操作导致死循环问题。【⭐⭐⭐】jdk 1.8 后解决了这个问题,但是还是不建议在多线程下使用
HashMap
,因为多线程下使用HashMap
还是会存在其他问题比如数据丢失。并发环境下推荐使用ConcurrentHashMap
。 -
HashMap 的长度为什么是 2 的幂次方。【⭐⭐⭐】主要是考虑到了对运算效率的提升。
-
HashMap
、HashTable
、以及ConcurrentHashMap
的区别。【⭐⭐⭐⭐⭐】:现在面试的超高频考点。当面试官问到这个问题的时候,展现你背面试八股文能力的机会来了。你可以展开去讲在 Java7 和 Java8 中HashMap
分别采用什么数据结构,为什么 Java8 把之前的头插法
改成了尾插法
,怎样实现扩容
,为什么负载因子
是0.75
,为什么要用红黑树
等等一系列的东西- 底层结构
- 线程安全
- HashTable:关键方法synchronize加锁
- ConcurrentHashMap:锁优化
- 不是对整个对象加锁,而是对每个哈希桶加锁=》降低锁冲突,性能提高
- 只加了写锁,不加读锁
- 利用了CAS特性:设计时,能不加锁就不加锁,尽可能降低锁冲突的概率
- 扩容方式
- HashTable:负载因子超过阈值,触发扩容,申请一个更大的数组,将旧数组搬运到新数组
- ConcurrentHashMap:扩容时,旧数组和新数组会同时存在一段时间,直到全部搬运完才释放旧数组的空间(查时新旧一起查,插入:新,删除:旧)
知识点总结
this:
this代表类的当前对象
利用“this.”可以调用当前对象的成员
this可以实现构造方法的调用
利用this()可以调用构造方法 必须写在构造方法的第一条
static:
静态方法中不能访问类的非静态成员变量和非静态成员方法
非静态成员方法/变量都是必须依赖具体的对象才能够被调用
静态=》非静态 √
非静态=》静态 ×
final:
修饰类:不能被继承
修饰方法:不能被覆盖
修饰属性:不能重新赋值
修饰常量:不能重新赋值
用 instanceof 操作符测试一个对象是否是一个类的实例
抽象
抽象类:用abstract修饰的类;只能用于继承,不能用于创建对象;可以有抽象方法、非抽象方法
抽象方法:用abstract修饰的方法只有方法头没有方法体; 抽象方法只能定义在抽象类中
接口
可以多重继承,接口只能继承接口,不能继承类;
只能包含 静态常量和抽象方法
通过interface关键字来定义接口
通过implements让子类来实现接口
异常
try、catch、 finally、throws(用在方法声明处)、throw(用在方法内部)
集合
List:add get size contains remove
LinkedList: addFirst addLast getFirst getLast removeFirst removeLast
Map: put get remove size keySet values containsKey clear isEmpty
Iterator: iterate hasNext
for(int num : nums)
包装类
byte -----Byte
short -----Short
int -----Integer
long-----Long
float -----Float
double ------Double
char------Character
boolean------Boolean
基本数据=》栈
实例对象=》堆
File
exists isFile isDirectory getPath getAbsolutePath getName delete createNewFile length()
流
输入:InputStream字节 Reader字符
输出:OutputStream Writer
多线程
程序:静态代码
进程:程序的一次动态执行,系统进行资源分配的基本单位
线程:轻量化的进程,共享进程的资源,也有自己一小部分的资源【程序计数器、虚拟机栈、本地方法栈】
Thread类:
run()方法的主体为线程体
start()方法调用线程
创建线程:
1.继承Thread类
子类继承Thread=》子类中重写run()方法=》创建Thread子类对象=》start()放大调用线程
2.实现Runnable接口
线程生命周期=五个状态:创建, 就绪, 运行, 阻塞,死亡
死锁:当两个线程相互等待对方资源,而产生循环等到的现象