1、内存泄漏和内存溢出有什么区别?
内存泄漏(memory leak):内存泄漏指程序运行过程中分配内存给临时变量,用完之后却没有被GC回收,始终占用着内存,既不能被使用也不能分配给其他程序,于是就发生了内存泄漏。
内存溢出(out of memory):简单地说内存溢出就是指程序运行过程中申请的内存大于系统能够提供的内存,导致无法申请到足够的内存,于是就发生了内存溢出。
避免内存泄漏:尽早释放无用对象的引用。避免在循环中创建对象。使用字符串处理时避免使用String,应使用StringBuffer。尽量少使用静态变量,因为静态变量存放在永久代,基本不参与垃圾回收。
避免内存溢出的解决方案:第一步,修改JVM启动参数,直接增加内存。第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。第四步,使用内存查看工具动态查看内存使用情况。
3、Java 内存区域
Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为6个运行时数据区域。
程序计数器、Java 虚拟机栈、本地方法栈、方法区、运行时常量池
3、 finalize() 方法工作原理
一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其 finalize() 方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。
4、类加载机制-双亲委派模型
双亲委派模式,即加载器加载类时先把请求委托给自己的父类加载器执行,直到顶层的启动类加载器。父类加载器能够完成加载则成功返回,不能则子类加载器才自己尝试加载。
优点:1. 避免类的重复加载 2. 避免Java的核心API被篡改
5、分代回收
年轻代->标记-复制
老年代->标记-清除
分代回收基于两个事实:大部分对象很快就不使用了,还有一部分不会立即无用,但也不会持续很长时间.
什么是 GC?
GC,即就是 Java 垃圾回收机制。GC 触发的条件有两种,一是程序调用 System.gc 时可以触发,一是系统自身来决定 GC 触发的时机。
什么是 Minor GC?
从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC。当 Eden 区满时,触发 Minor GC。
什么是 Full GC?
Full GC 是清理整个堆空间,包括年轻代和老年代。
Full GC 的触发条件
- 调用 System.gc 时,系统建议执行 Full GC,但是不一定执行
- 老年代空间不足
- 方法区空间不足
- 通过 Minor GC 后进入老年代的平均大小大于老年代的可用内存
- 由 Eden 区、From Space 区向 To Space 区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小
垃圾回收的两次标记
第一次标记:对于一个没有其他引用的对象,筛选该对象是否有必要执行 finalize() 方法,如果没有执行必要,则意味可直接回收。(筛选依据:是否覆写或执行过 finalize 方法;因为 finalize 方法只能被执行一次)。
第二次标记:如果被筛选判定位有必要执行,则会放入 FQueue 队列,并自动创建一个低优先级的 finalize 线程来执行释放操作。如果在一个对象释放前被其他对象引用,则该对象会被移除 FQueue 队列。
0
SSM和SpringBoot的区别?
说一下项目SSM迁移到SpringBoot的过程?有难点吗?迁移过程只是代码迁移,还是有额外的业务优化?
项目为什么要升级成SpringBoot呢?
你项目中前端用了JS,有用Vue吗?
如何部署的?有专门的同学部署吗?
Redis在项目中怎么用的?
项目中Gateway和OAuth2.0如何整合的?
SpringBoot常见的注解
RestController和Controller的区别
JVM:
内存泄漏和内存溢出的概念
有哪些垃圾回收算法,
介绍一下它们?
介绍一下老年代
老年代会被回收吗?
MySQL:
MySQL注入?
MySQL如何优化?
1
基本数据类型
2、静态代码块,什么时候执行
3、jvm了解过没
没
4、垃圾回收机制
没
5、java可变参数
2
1、说说对Spring Boot的理解
2、对依赖注入的理解
3、对缓存机制的认识;了解Redis的注解嘛?
4、HTTP三次握手和四次挥手
这四个问题是根据我的项目经历来问的。
3
- 有跟后端交互吗?
7.数据库有用过吗?数据库的增删改查语句说一下 - Java有接触过吗?
- JSP用过吗?
- JQuery用过吗?
4
全程没有问其他,只问了项目,两个面试官。
自我介绍
死磕项目
项目是干嘛的
具体实现了那些功能
MySQL有用到事务吗
用什么框架操作MySQL
MyBatis的分页原理
Nginx了解过吗 原理了解吗
要是项目中出错了 你怎么定位
Vue的部分是你自己写的吗 要你自己搭Vue脚手架你能搭吗
ssm框架有没有自己集成过
MySQL慢语句 怎么定位 怎么解决
用过Linux吗
对Linux了解多少
了解过Tomcat吗
项目是怎么部署的
项目部署用的是jar包还是war包
5
- 自我介绍
- 了解消息队列嘛,说一下消息队列的原理
- mysql慢查询怎么看
4.怎么解决慢查询
5.redis用来做什么
6.说下实习
7.你要来济南嘛
6
自我介绍
介绍一下你的第二个项目
String与StringBuffer的区别?
MySQL索引为什么是B+树?
说一说MVC的执行流程?
反射有应用过吗?
SpringBoot有了解过吗?
7
自我介绍
java面向对象特性
封装的作用
类支持多继承吗
说下抽象类
抽象类和接口的区别
说下项目
说下IO流
python为什么不支持多线程
linux常用命令
数据库常用命令
如何优化数据库
索引如何添加
反射机制了解吗
说下HTML常用标签
8
hr面:问意向地点、实习时间、家庭情况、对象的工作等,就是看你愿不愿意来浪潮。
二面(视频):
- 自我介绍
- 项目
- 项目中的多线程怎么实现的
- Notify()和NotifyAll()的区别(???我上一个问题扯了各种线程管理线程通信并发安全问题,你就问我这??? 听到这问题我都不想面了)
- 继续聊项目
全程十分钟吧 最水的面试没有之一!
三面:
就 OC了…
1、代码块使用注意事项和细节讨论
2、 final 使用注意事项和细节讨论
- final修饰的属性又叫常量,一般用XX XX XX来命名
- final修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如
下位置之一【选择一个位置赋初值即可】:
①定义时:如public final double TAX_RATE=0.08; ②在构造器中 ③在代码块中。 - 如果final修饰的属性是静态的,则初始化的位置只能是
① 定义时 ② 在静态代码块,不能在构造器中赋值。 - final类不能继承,但是可以实例化对象。
- 如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承。
- 一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法。
- final不能修饰构造方法(即构造器)
- final和static往往搭配使用,效率更高,不会导致类加载.底层编译器做了优化处理。
class Demo{
public static final int i=16; //不写final下边语句就输出了。
static{ System.out.println(“Java教育~”);} - 包装类(Integer,Double,Float,Boolean等都是final),String也是final类.
3、抽象类的介绍
- 用abstract关键字来修饰一个类时,这个类就叫抽象类,访问修饰符 abstract类名{ }
- 用abstract关键字来修饰一个方法时,这个方法就是抽象方法
访问修饰符 abstract 返回类型 方法名 (参数列表) ; //没有方法体,即不加 { } - 抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类()
- 抽象类,是考官比较爱问的知识点,在框架和设计模式使用较多
4、抽象类使用的注意事项和细节讨论
- 抽象类不能被实例化 , [举例]
- 抽象类不一定要包含abstract方法。也就是说,抽象类里边可以没有abstract方法 , [举例]
- 一旦类包含了abstract方法,则这个类必须声明为abstract [说明]
- abstract只能修饰类和方法,不能修饰属性和其它的。[说明]
- 抽象类可以有任意成员【抽象类本质还是类】,比如:抽象类可以有非抽象方法、构造器、静态属性等等
- 抽象方法不能有主体,即不能实现.如图所示
abstract void aaa ( ) { } ;//是错误的,不能有 { } 方法。 - 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类。
- 抽象方法不能使用private、final和static来修饰,因为这些关键字都是和重写相违背的。
抽象类最佳实践-模板设计模式
5、 抽象类最佳实践-模板设计模式
- 基本介绍
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。 - 模板设计模式能解决的问题
- 当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
- 编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式.
6、内部类
7、 集合的框架体系
Java 的集合类很多,主要分为两大类,如图:[背下来]
- 解读
1. 集合主要是两组(单列集合 , 双列集合)
2. Collection 接口有两个重要的子接口 List Set , 他们的实现子类都是单列集合
3. Map 接口的实现子类 是双列集合,存放的 K-V
4. 把梳理的两张图记住
8、数组
- 长度开始时必须指定,而且一旦指定,不能更改
- 保存的必须为同一类型的元素
- 使用数组进行增加/删除元素的示意代码-比较麻烦
写出Person数组扩容示意代码。
Person[] pers = new Person[1];1//大小是1
per[0]=new Person();
//增加新的Person对象?
Person[] pers2 = new Person[pers.length+1];//新创建数组
for(){}//拷贝pers数组的元素到pers2
pers2[pers2.length-1]=new Person();//添加新的对象
9、集合
- 可以动态保存任意多个对象,使用比较方便!
- 提供了一系列方便的操作对象的方法:add,remove、set、get等
- 使用集合添加,删除新元素的示意代码-简洁了
10、IO流
以Buffered开头的缓冲流,用于在读写数据时对数据进行缓存,以减少IO次数;
InputStreamReader、InputStreamWriter是转换流,用于将字节流转换为字符流;
以Object开头的流是对象流,用于实现对象的序列化;
11、介绍一下线程的生命周期
在线程的生命周期中,它要经过新建(New)、就绪(Ready)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态。尤其是当线程启动以后,它不可能一直“霸占”着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、就绪之间切换。
12、 说一说Java多线程之间的通信方式
在Java中线程通信主要有以下三种方式:
wait()、notify()、notifyAll()
如果线程之间采用synchronized来保证线程安全,则可以利用wait()、notify()、notifyAll()来实现线程通信。这三个方法都不是Thread类中所声明的方法,而是Object类中声明的方法。原因是每个对象都拥有锁,所以让当前线程等待某个对象的锁,当然应该通过这个对象来操作。并且因为当前线程可能会等待多个线程的锁,如果通过线程来操作,就非常复杂了。另外,这三个方法都是本地方法,并且被final修饰,无法被重写。
wait()方法可以让当前线程释放对象锁并进入阻塞状态。notify()方法用于唤醒一个正在等待相应对象锁的线程,使其进入就绪队列,以便在当前线程释放锁后竞争锁,进而得到CPU的执行。notifyAll()用于唤醒所有正在等待相应对象锁的线程,使它们进入就绪队列,以便在当前线程释放锁后竞争锁,进而得到CPU的执行。
每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列。就绪队列存储了已就绪(将要竞争锁)的线程,阻塞队列存储了被阻塞的线程。当一个阻塞线程被唤醒后,才会进入就绪队列,进而等待CPU的调度。反之,当一个线程被wait后,就会进入阻塞队列,等待被唤醒。