前言:时间不负有心人,星光不问赶路人;
适宜阅读人群
- 准备跳槽的初/中/高级 Java 程序员
- 想要查漏补缺的人
- 想要不断完善和扩充自己 Java 技术栈的人
- Java 面试官
零、Java JVM
1.Java运行时数据区域
线程私有
- 程序计数器:记录当前线程执行的字节码行号
- 虚拟机栈:存放方法运行所需数据
- 本地方法栈:为JVM调用本地方法
线程共享
- Java堆:存储对象实例和数组
- 方法区:存储运行时常量池、已经被虚拟机加载的类信息、静态常量
2.Java垃圾回收器如何判断对象是否可回收
- 引用计数法:给对象添加一个计数器,每个地方引用对象+1;引用失效则-1;计数器为 0 的对象就不可能被使用
- 可达性分析算法:这个算法就是通过一系列称为“GC Roots"对象作为起点,节点经过的路径称为引用链,当一个对象到GC roots没有任何引用链,则证明该对象不可使用,需要回收;
3.垃圾收集算法
标记-清除法
- 首选标记出所有不需要被回收的对象,标记完成后;统一回收没有被标记的对象。
标记-复制法
- 标记复制法将内存分为大小相同两块,每次使用其中一块。当另一块内存使用完后,就会将存活的对象复制到另一块内存区域;然后把使用过的内存区域清理一遍。每次回收内存都是对内存区域另一半的回收;
标记-整理法
- 标记所有存活的对象向另一端内存区域移动,清除掉边界以外的内存
分代-收集法
- 存活周期区分为新生代和老年代
4.双亲委派机制
- 如果子类加载收到类加载请求,并不会直接加载,而是委派个父类加载加载;如果父类也找不到这个类,子类加载器才会尝试加载
类加载器分类
- 启动类加载器
- 扩展类加载器
- 应用程序加载器
- 用户自定义加载器
5.类的加载过程
- 加载
- 验证
- 准备
- 解析
- 初始化
- 使用
- 销毁
一、Java 基础
1.JDK和JRE的区别
- JDK:Java开发工具包;提供Java的开发环境和运行环境。
- JRE:Java运行环境;提供Java运行所需要的运行环境。
2.==和equals的区别
- ==:对于基本类型比较值,对于引用类型比较内存地址
- equals():默认比较内存地址
3.两个对象的HodeCode()相同,则equals()也一定相同么
- 不相同;两个对象的HashCode()相同,equals()不一定相同。
equals()和hashcode()的关系
- 如果equals()为true;HashCode一定相等
- 如果equals()为falas;HashCode不一定不相等
- 如果HashCode值相等;equals()不一定相等
- 如果HashCode值不相等;equals()一定不相等
4.final在Java中的作用
- 类:被修饰的类不能被继承
- 方法:被修饰的方法不能被重写
- 变量:被修饰的变量初始化后不能被修改
5.String字符串属于基本类型么
- String不属于基本类型,属于引用类型对象。
6.String字符串操作类
- String:String是不可变对象,每次对String改变就会派生新的对象
- StringBuilder:线程不安全,效率高,多用于单线程。
- StringBuffer:线程安全,由于加锁原因效率不如StringBuilder;多用于多线程
- 字符串使用优先级:StringBulider==>StringBuffer==>String
7.抽象类一定有抽象方法么
- 不需要,抽象类不一定有抽象方法;
8.普通类和抽象类的区别‘
- 普通类不能包含抽象方法,抽象类包含抽象方法
- 抽象类不能实例化,普通可以实例化
9.抽象类能够使用final修饰么
- 不能;因为抽象类需要被其他类继承;final修饰的类不能继承,容易矛盾。
10.接口和抽象类的区别
- 实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
- 构造函数:抽象类有构造函数;接口没有构造函数
- 实现数量:Java类只能单继承,接口能够多实现
11.Java中的IO种类
- 按功能来分:输入流、输出流。
- 按类型来分:字节流、字符流。
12.BIO和NIO、AIO区别是什么
- BIO:同步堵塞(一个连接一个线程)
- NIO:同步非堵塞(一个请求一个线程)
- AIO:异步非堵塞(一个有效请求一个线程)
13.Java-JDK1.8新特性
- 接口默认方法:default关键字向接口添加非抽象方法
- Lanmbda表达式:本质是个匿名内部类,使用Lanmbda使代码更加简洁
- 方法和函数引用:Java 8允许您通过
::
关键字传递方法或构造函数的引用。 - 新日期API:Java 8在
java.time
包下包含一个全新的日期和时间API。
14.break ,continue ,return 的区别及作用
- Break:结束当前循环
- Continue:跳出本次循环,继续执行下次循环
- Return:结束当前方法,直接返回
14.重写和重载的区别?
- 重载是多态的表现,统一处理不同数据类型,可以使用重载
- 重写是建立与子类继承父类,在父类上增加新的功能,可以使用重写
举个生活栗子
- 你想吃一碗面,我给你提供了牛肉面、阳春面供你选择,这是重载;
- 你想吃一碗面,我不但给你端来面,还给你加青菜、鸡蛋,这个是重写;
15.实例化对象方式
- new()
- clone
- Java反射机制
- 序列化
16.什么是不可变对象
- 不可变对象:对象一旦被创建状态就不能被改变。任何修改都可能导致生成新的对象;
17.&和&&区别
- 对于&:无论%左边是否是false,都会执行右边的Boolean
- 对&&:只要检查出左边为false,直接获取判断结果;
18.Java和C++区别
- Java和C++都支持封装、继承、多态
- Java不提供指针指向内存
- Java类单继承接口多实现,C++类多继承
- Java有GC垃圾回收机制,无需手动释放内存
二、Java 容器
1.Java容器有哪些
- List:ArrayList(Object数组)、LinkedList(双向循环链表)、Vector(Object数组)。
- Set:HashSet(无序,唯一)、TreeSet(有序,唯一)。
- Map:HashMap 、TreeMap、ConcurrentMap、Hashtable。
2.Conllection和Conllections区别是什么
- Conllection:是一个集合接口。他提供对集合对象进行基础操作的通用接口方法。主要接口类:List、set
- Conllections:针对集合类的工具类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全等操作;服务Conllection集合框架
3.List、Set、Map之间的区别是什么
4.HashMap和Hashtable的区别是什么
- 存储:HashMap允许键值NuLL;Hashtable不允许键值NULL
- 线程安全:HashMap非线程安全;Hatable线程安全
- 单线程情况下使用HashMap;多线程并发情况下使用ConcurrentHashMap;
5.如何决定使用TreeMap还是HashMap
- Map中插入、删除、定位一个元素使用HashMap;对于一个Key集合进行有序遍历使用TreeMap 、
6.HashMap底层实现原理
- HashMap整体是个Entry数组,每个Entry包含key-value数组节点
- HashMap基于Hash算法实现:GET获取、PUT存储
- 传入Key时根据HashCode计算Hash值,根据Hash值将value保存入数组桶中
- HashCode计算出相同的Hash值称之为Hash冲突;用链表+红黑树存储相同Hash值的value "拉链法"
- 如若Hash冲突较少时,则使用链表否则使用红黑树;
7.ArrayList和LinkedList是区别什么
- 数据结构:ArrayList动态数组实现、LinkedL