java面试知识点
1.抽象类和接口
相同点:都不能被实例化,位于继承树的顶端,都包含抽象方法
不同点:1、设计目的:接口体现的一种规范,类似与整个系统的总纲,制订了系统各模块应该遵循的标准,因此接口不应该经常改变,一旦改变对整个系统是辐射性的。
抽象类作为多个子类的共同父类,体现的是一种模板式设计,可以当作系统实现过程中的中间产品,已经实现了系统部分功能。
2、使用不同:(1)接口只能包含抽象方法,抽象类可以包含普通方法。
(2)接口里不能定义静态方法,抽象类可以。
(3)接口只能定义静态常量属性不能定义普通属性,抽象类可以。
(4)接口不包含构造器,抽象类可以(不是用于创建对象而是让子类完成初始化)。
(5)接口里不能包含初始化块,抽象类完全可以。
(6)接口多继承,抽象类单继承(只能有一个直接父类)。
总结:接口所有方法全是抽象方法只能 public abstract修饰 (默认public abstract修饰 ),属性默认public static final修饰。
抽象类除了包含抽象方法外与普通类无区别。
2.Java实现多线程的三种方式及三种方式的区别
(1)继承Thread类,实现run 方法 (2)实现runnable接口 (3)实现Callable接口
-
实现Runnable接口可以避免Java单继承特性而带来的局限;增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的;适合多个相同程序代码的线程区处理同一资源的情况。
-
继承Thread类和实现Runnable方法启动线程都是使用start方法,然后JVM虚拟机将此线程放到就绪队列中,如果有处理机可用,则执行run方法。
-
实现Callable接口要实现call方法,并且线程执行完毕后会有返回值。其他的两种都是重写run方法,没有返回值
3.Java中的NIO,BIO,AIO分别是什么?
-
BIO
-
同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
-
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
-
-
NIO
-
同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
-
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
-
-
AIO
-
异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理.
-
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
-
3.1 同步 异步,阻塞 非阻塞
同步和异步是消息的机制(异步有通知信息返回)
同步:执行一个操作之后,等待结果,然后才继续执行后续的操作。
异步:执行一个操作后,可以去执行其他的操作,然后等待通知再回来执行刚才没执行完的操作。
阻塞 和 非阻塞关注的是程序在等待调用结果时的状态
阻塞:进程给CPU传达一个任务之后,一直等待CPU处理完成,然后才执行后面的操作。
非阻塞:进程给CPU传达任我后,继续处理后续的操作,隔断时间再来询问之前的操作是否完成。这样的过程其实也叫轮询。
4.产生死锁的必要条件
1.互斥条件,2.占有且申请,3.循环等待,4.不可抢占条件
如何预防死锁
5.如何保证线程安全
1.对非安全的代码进行加锁控制;2.使用线程安全的类;3.多线程并发情况下,线程共享的变量改为方法级的局部变量。
6.类加载的过程
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的生命周期包括了:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸载(Unloading)七个阶段,其中验证、准备、解析三个部分统称链接。
7.Spring AOP(面向切面编程)和IOC(控制反转)(DI 依赖注入)
什么是AOP?
面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面
1.面向切面编程提供声明式事务管理
2.spring支持用户自定义的切面
面向切面编程(aop)是对面向对象编程(oop)的补充,
面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。
AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象,
是对应用执行过程中的步骤进行抽象,,从而获得步骤之间的逻辑划分。
aop框架具有的两个特征:
1.各个步骤之间的良好隔离性
2.源代码无关性
什么是DI机制?
依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色
需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中
创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者
因此也称为依赖注入。
spring以动态灵活的方式来管理对象 , 注入的两种方式,设置注入和构造注入。
设置注入的优点:直观,自然
构造注入的优点:可以在构造器中决定依赖关系的顺序。
Spring 事务
8.finally
finally{}是不管try{}catch{}是否捕获到异常,它始终会被执行。finally{}后的代码也会被执行,前提是上面的语句没有检测到return语句。
9. 类加载器
10.单例模式
饿汉模式 懒汉模式 静态内部类 双重校验锁 meij
//饥饿模式
public final class EagerSingleton
{
private static EagerSingleton singObj = new EagerSingleton();
private EagerSingleton(){
}
public static EagerSingleton getSingleInstance(){
return singObj;
}
}
饿汉模式不会有线程安全的问题,如果对象很大,会造成潜在的性能问题。
//懒汉模式
public final class LazySingleton
{
private static LazySingleton singObj = null;
private LazySingleton(){
}
public static LazySingleton getSingleInstance(){
if(null == singObj ) singObj = new LazySingleton();
return singObj;
}
}
静态内部类方式
//双重校验锁
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
//Double Checked
instance = new Singleton();
}
}
}
return instance;
}
}
- 给 instance 分配内存
- 调用 Singleton 的构造函数来初始化成员变量
- 将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)
但是在 JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。
我们只需要将 instance 变量声明成 volatile 就可以了。
private volatile static Singleton instance; //声明成 volatile
11.哈希索引
- 不支持范围查询
- 不支持索引完成排序
- 不支持联合索引的最左前缀匹配规则
- 以等值查询为主,没有范围查询,没有排序的时候,适合哈希查找
12.mySql中myIsam和InnoB的区别
- InnoDB支持事务操作,同时支持外键,myIsam不支持外键。
- myIsam支持表锁,并且有一个字段存储表的行数,InnoDB支持行锁,不保存表的具体行数
- Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高(是因为MyISAM索引和数据是分开的,而且支持索引压缩,内存使用率提高了很多);
- InnoDB是聚集索引,MyIsam是非聚集索引。
- 如果创建数据不再进行修改,可以采用MyISAM压缩表
- InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,例如update table set num=1 where name like “%aaa%。
13.索引失效的情况
- 字段类型转换导致索引失效
- 对索引列运算导致索引失效
- 使用函数也会导致索引失效
- 不符合最左匹配原则
- 字符型字段为数字时在where条件里不添加引号
14.GC root的对象
- 虚拟机栈中栈帧的局部变量表所引用的对象
- 本地方法栈JNI(Native)引用的对象
- 方法区中的静态变量和常量引用的对象
15.jdk18新特性
- lambda表达式
- 接口中可以有默认方法和静态方法
- 支持多重注解
16.java 泛型
- java泛型是参数化类型
- Object 和 T 很重要的两点区别,T从一开始就会限定这个类型,(他可以限定类型为Object)。
- Object是所有类的父类,所以会强制类型转换,而T不需要强制类型转换,因为他一开始就固定了。
上一篇: java基础中常见的面试题
下一篇: Apache Flink 快速入门