【自己整理面试Java】
2021-03-19 13:37:49 7 举报
AI智能生成
java面试总结
作者其他创作
大纲/内容
【2】基础语法
对象和类
类/
对象/
方法/
实例/
实例变量/
封装/
接口/
对象/
方法/
实例/
实例变量/
封装/
接口/
【对象】是类的一个实例(对象不是找个女朋友),
有状态和行为。例如,一条狗是一个对象,
它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
有状态和行为。例如,一条狗是一个对象,
它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
【类】是一个模板,它描述一类对象的行为和状态。
【方法】就是行为,一个类可以有很多方法。
逻辑运算、数据修改以及所有动作都是在方法中完成的。
逻辑运算、数据修改以及所有动作都是在方法中完成的。
【实例变量】每个对象都有独特的实例变量,
对象的状态由这些实例变量的值决定。
对象的状态由这些实例变量的值决定。
【封装】在面向对象程式设计方法中,封装(英语:Encapsulation)
是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
【接口】
继承
extends
implements
super/this
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。
this关键字:指向自己的引用。
final
final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:
重载/重写
理解:重写(动态)就是多态的实现方式
理解:重写(动态)就是多态的实现方式
ChildTopic
重载:方法名相同,参数不同
重写:方法名与参数都一样
重写:方法名与参数都一样
多态
理解:多态是一种思想,这种思想帮助程序员避免重复写代码
像继承、重写、父类引用指向子类对象
理解:多态是一种思想,这种思想帮助程序员避免重复写代码
像继承、重写、父类引用指向子类对象
多态是同一个行为具有多个不同表现形式或形态的能力。
比如:电脑上的F1键,不同的模式下有不同的功能
比如:电脑上的F1键,不同的模式下有不同的功能
多态的实现方式
继承
多个子类对同一个的方法的重写
接口
实现接口并覆盖接口的同一个方法
抽象类和抽象方法
Character类
String类/
StringBurrer类/
Arrays类/
Scanner类/
String类/
StringBurrer类/
Arrays类/
Scanner类/
Number & Math类
Character类
String类
字符串7种反转
StringBuffer
StringBuilder
数组
初始化
静态初始化
int[] a = { 1, 2, 3 };// 静态初始化基本类型数组;
Man[] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组;
Man[] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组;
动态初始化
int[] a1 = new int[2];//动态初始化数组,先分配空间;
a1[0]=1;//给数组元素赋值;
a1[1]=2;//给数组元素赋值;
a1[0]=1;//给数组元素赋值;
a1[1]=2;//给数组元素赋值;
默认初始化
int a2[] = new int[2]; // 默认值:0,0
boolean[] b = new boolean[2]; // 默认值:false,false
String[] s = new String[2]; // 默认值:null, null
boolean[] b = new boolean[2]; // 默认值:false,false
String[] s = new String[2]; // 默认值:null, null
java.utils.Arrays
Scanner类
ChildTopic
Java多线程编程
【2】多线程的实现方式
1、继承Thread类
2、实现Runable接口
3、使用Callable和Future
2、实现Runable接口
3、使用Callable和Future
【1】线程的生命周期和状态
NEW(初始状态) -> RUNABLE(运行状态)-> BLOCKED(阻塞状态)
WAITING(等待状态) -> TIME_WAITING(超时等待状态) -> TERMINATED(终止状态)
WAITING(等待状态) -> TIME_WAITING(超时等待状态) -> TERMINATED(终止状态)
【1】为什么我们调⽤ start() ⽅法时会执⾏ run() ⽅法,
为什么我们不能直接调⽤ run() ⽅法?
为什么我们不能直接调⽤ run() ⽅法?
【1】说说 JDK1.6 之后的synchronized 关键字底层做了哪些优化?
可以详细介绍⼀下这些优化吗?(偏向锁,轻量级锁,自旋锁,锁消除,锁粗化)
可以详细介绍⼀下这些优化吗?(偏向锁,轻量级锁,自旋锁,锁消除,锁粗化)
①偏向锁
CAS操作
java如何实现CAS原子性操作?
乐观锁:会一直等待知道冲突解决
悲观锁:会阻塞线程
理解:锁偏向于第一个获取锁的线程
② 轻量级锁
理解:偏向锁的失败后,为减少系统开销,在没有多线程竞争下使用轻量级锁
③ 自旋锁和自适应自旋
理解:轻量级锁失败后,虚拟机避免线程在系统层面挂起,
让线程执行一个忙循环("假忙操作"),叫做自旋操作
让线程执行一个忙循环("假忙操作"),叫做自旋操作
④ 锁消除
编译时,要是共享数据不存在竞争,虚拟机执行锁消除
⑤ 锁粗化
理解:锁的范围限制在共享数据实际作用的区域
【1】ThreadLocal
ThreadLocalk为每个线程开辟一块私有内存
【1】2.3.14 线程池
4. 如何创建线程池
方式一:通过ThreadPoolExecutor构造函数实现(推荐)
方式二:通过 Executor 框架的工具类 Executors 来实现
我们可以创建三种类型的 ThreadPoolExecutor:
FixedThreadPool
SingleThreadExecutor
CachedThreadPool
我们可以创建三种类型的 ThreadPoolExecutor:
FixedThreadPool
SingleThreadExecutor
CachedThreadPool
4.1 创建线程池的示例代码:
Runnable+ThreadPoolExecutor
Runnable+ThreadPoolExecutor
理解:我们在代码中模拟了 10 个任务,我们配置的核心线程数为 5 、等待队列容量为 100 ,
所以每次只可能存在 5 个任务同时执行,剩下的 5 个任务会被放到等待队列中去。
当前的5个任务中如果有任务被执行完了,线程池就会去拿新的任务执行。
所以每次只可能存在 5 个任务同时执行,剩下的 5 个任务会被放到等待队列中去。
当前的5个任务中如果有任务被执行完了,线程池就会去拿新的任务执行。
五 几种常见的线程池详解
5.1 FixedThreadPool
为什么不推荐:线程池数量不会超过设定值;
运行时不会拒绝任务,可能会导致OOM(内存溢出)
运行时不会拒绝任务,可能会导致OOM(内存溢出)
5.2 SingleThreadExecutor 详解
只有一个线程的线程池
5.3 CachedThreadPool 详解
CachedThreadPool 是一个会根据需要创建新线程的线程池。
不推荐理由:
CachedThreadPool允许创建的线程数量为 Integer.MAX_VALUE ,
可能会创建大量线程,从而导致 OOM。
不推荐理由:
CachedThreadPool允许创建的线程数量为 Integer.MAX_VALUE ,
可能会创建大量线程,从而导致 OOM。
六 ScheduledThreadPoolExecutor 详解
ScheduledThreadPoolExecutor
主要用来在给定的延迟后运行任务,或者定期执行任务。
主要用来在给定的延迟后运行任务,或者定期执行任务。
七 线程池大小确定
CPU 密集型任务(N+1):
I/O 密集型任务(2N):
如何理解Cpu密集还是IO密集任务?
【1】Java集合框架
Java中有哪些集合框架?
HashMap和Hashtable有什么区别?
1. 线程是否安全:
2. 效率: 因为线程安全的问题,HashMap 要⽐ HashTable 效率⾼⼀点。
3. 对 Null key 和 Null value 的⽀持: HashMap 可以存储 null 的 key 和 value,
4. 初始容量⼤⼩和每次扩充容量⼤⼩的不同 :
5. 底层数据结构:
Arraylist 与 LinkedList 区别?
1.是否保证线程安全:
2.底层数据结构: Arraylist 底层使⽤的是 Object 数组;
LinkedList 底层使⽤的是 双 向链表 数据结构
LinkedList 底层使⽤的是 双 向链表 数据结构
3.插⼊和删除是否受元素位置的影响:
4.是否⽀持快速随机访问:
5.内存空间占⽤:
有哪些集合是线程不安全的,怎么解决?
我们常⽤的 Arraylist , LinkedList , Hashmap , HashSet , TreeSet , TreeMap,PriorityQueue 都不是线程安全的。
解决办法很简单,可以使⽤线程安全的集合来代替。
解决办法很简单,可以使⽤线程安全的集合来代替。
hashmap的7中遍历模式
ArrayList的扩容方式
【1】JVM
JVM内存模型
堆
创建对象所指向的内存区域,
《放仓库的东西》
《放仓库的东西》
方法区
《也是放仓库的东西,只是这个东西
存放在我马上要使用的区域》
存放在我马上要使用的区域》
虚拟机栈
理解:又叫虚拟机栈(局部变量表),
存放各类数据类型/对象引用类型,类似于指针的作用
《取仓库东西里面的表格》
存放各类数据类型/对象引用类型,类似于指针的作用
《取仓库东西里面的表格》
本地方法栈
《取特定物品的表格》
程序计数器
理解:就像个指针,记录我程序运行到那个步骤了
《在仓库里面取了多少东西》
《在仓库里面取了多少东西》
对象的创建过程
Step1:类加载检查
检查类是否被创建过,
没有则去创建
没有则去创建
Step2:分配内存
指针碰撞
空闲列表
Step3:初始化零值
Step4:设置对象头
Step5:执行 init 方法
对象的访问定位的两种方式
直接指针
《同样把reference表格放到仓库的不同区域》
《同样把reference表格放到仓库的不同区域》
直接指针
使用句柄:
《栈中存放reference的表格,并把表格也放到仓库中》
《栈中存放reference的表格,并把表格也放到仓库中》
使用句柄
类加载机制
加载->验证->准备->解析->初始化->使用->卸载
加载
理解:就是将.class文件读取
验证
理解:验证.class的完整性
准备
理解:为创建类分配内存以及类变量初始化
解析
理解:就是和虚拟机完成交互
(将常量池内的符号引用替换为直接引用也即拿到方法的指针或者地址)
(将常量池内的符号引用替换为直接引用也即拿到方法的指针或者地址)
初始化
理解:上生产线使用的阶段
(也就是new出不同的对象,取出对应的类)
(也就是new出不同的对象,取出对应的类)
卸载
理解:类使用完成,准备回收
知道哪些类加载器?
双亲委派原则
父类加载 不重复加载
理解:就是寻找父类加载,要是没有被加载过(或者父类不能的加载)
才考虑启动BootstrapClassLoader作为父类加载器
才考虑启动BootstrapClassLoader作为父类加载器
理解:就是不同类会对应不同的加载过程,
就是比如类的重写过程,
就是比如类的重写过程,
垃圾回收机制/算法
标记清除
适用场景
对象存活比较多的时候适用
老年代
缺点
提前GC
碎片空间
扫描了两次
标记存活对象
清除没有标记的对象
我的理解:标记需要回收的对象,统一回收
标记复制
适合场景
存活对象少 比较高效
扫描了整个空间(标记存活对象并复制异动)
适合年轻代
缺点
需要空闲空间
需要复制移动对象
我的理解:每次回收一半内存,将回收的一半内存中存活的对象复制到另一半上
标记整理
我的理解:是让存活的部分往一端移动,从的另一端开始清除
分代收集法
新生代
使用标记-复制的算法
老生代
标记-清除/标记-整理
定位垃圾的方法
1、引用计数
没办法解决循环引用的问题
2、可达性分析算法
GCroot的根节点:线程栈的本地变量、静态变量、本地方法栈等
【针对堆区?】分代回收过程
年轻代
Minor GC
老年代
Major GC
永久代/元空间
实战
性能调优
原则 就是减少gc stw【stop the world机制】
设置堆的最大最小值 -xms -xmx
调整老年和年轻代的比例
-XX:newSize设置绝对大小
防止年轻代堆收缩:老年代同理
主要看是否存在更多持久对象和临时对象
观察一段时间 看峰值老年代如何 不影响gc就加大年轻代
配置好的机器可以用 并发收集算法
每个线程默认会开启1M的堆栈 存放栈帧 调用参数 局部变量 太大了 500k够了
FullGC 内存泄露排查
jasvism
dump
监控配置 自动dump
JVM调优
OOM
内存泄露
线程死锁
锁争用
Java进程消耗CPU过高
JVM性能检测工具
Jconsole
Jprofiler
jvisualvm
MAT
内存泄露
help dump
生产机 dump
mat
jmap
-helpdump
CPU100%
topc -c
top -Hp pid
jstack
进制转换
cat
SpringMVC
常见的注解
1、常见的标注类注解
@Controller
@RestController
@Component
@Repository
用于注解Dao层
@Service
2、MVC常见注解
@ResponseBody
1、异步请求
2、该注解放回Body数据区,一般是json/xml文件
@ResquestMapping
path
请求的路径
value
也是请求的路径
method
传递get/post/。。。等方法
params
指定限制请求参数的条件
@Autowired
在使用ioc容器里面的类之前,取的时候用autowired
@PathVariable
@requestParam
RequestHeader
3、其他注解
@ModelAttribute
@SessionAttribute
@Vaild
CookieValue
请求参数的绑定
收藏
0 条评论
下一页