1、JDK1.8 的新特性
-
HashMap集合的数据结构的优化,
- 原本HashMap的数据结构采用的是数组加链表的形式,1.8增加红黑树(在单个链表在8以上并且,数组容量大于等于64才可树化)
-
Lambda表达式:匿名表达式,也是可以传递的代码。支持函数式编程。
-
Comparator<Integer> cpt2 = (x,y) -> Integer.compare(x,y);
-
-
Stream API
-
新的日期API LocalDate | LocalTime | LocalDateTime
2、== 和 equals 的区别
- == :如果两个引用类型比较,则比较的是两者的引用地址,如果是基本类型比较的就是内容了、一般比较的是栈的内容。
- equals:在Object类中的equals其实就是==,但是在String类中重写了Object类的equals方法,所以比较的是引用的内容。也就是堆中的内容,我们可以根据自己的需求决定是否重写equals。如果不重写就会比较的引用地址。
3、Java中的容器
容器包括
-
数组:Array
-
Collection接口
-
List有序集合
-
ArrayList:底层实现Object的数组,默认0,第一次add数组长度为10,每次扩容1.5倍,不安全
擅长查询和修改
-
LinkedList 底层使用链表结构,不存在容量长度和扩容,擅长做添加和删除操作。添加和删除首先连接或断掉pev,其次next。
-
Vector:线程安全,底层使用的Object数组,默认0,可自定义扩容倍,每次扩容2倍
-
-
Set无序集合
- HashSet:底层使用HashMap集合的数据结构,数组,链表,红黑树。值就相当于key,value是Object
- LinkedHashSet:底层使用LinkedHashMap,数据结构使用的是HashMap的集合
- TreeSet:数据结构是数组,链表,虽然无序,可以根据条件比较器,控制执行顺序
-
-
Map接口
- HashMap:数据结构,数组,链表,红黑树,临界值0.75,可以修改临界值。扩容机制2倍
- LinkedHashMap:底层采用HashMap,重新定义了链表
- TreeMap
- properties
4、try catch finally return语句 finally还会执行吗?
会,前提不是System.exit(0) 终止 JVM
虚拟机的操作,当try或者catch返回了return数据,还会回来执行finally的数据,finally返回的数据可能覆盖掉之前返回的数据。
5、内连接、左连接、右连接的关键词和区别
- 内连接:inner join on,显示左右边的表共有的行。
- 外连接之左连接:left join on,左连接是以左边为主,左边表全部显示右边表符合条件的行显示。
- 外连接之右连接:right join on, 右连接是以右边为主,右边表全部显示左边表符合条件的行显示。
6、写出冒泡排序的核心逻辑代码
核心逻辑是两个数进行交换的过程,
Array[] number = [1,2,4,0,6,3,5,23];
for(int i = number.size()-1; i > 0;i--){
for(int j = 0; j <= i; j++){
int num = number[j];
number[j] = number[j+1];
number[j+1] = num;
}
}
7、什么是 IOC 和 AOP
IOC是Spring核心理念,就是将所有的Bean放到Bean工厂,进行统一的管理,在项目启动的时候,就加载了这个Bean工厂,之前创建对象时用new,现在创建对象通过Bean,其中也衍生出了DI注入,比如有的创建对象需要有参构造,或者需要给参数赋值时,就需要通过DI注入的方式进行注入。通过IOC容器,实现了控制的反转,极大的实现了解耦的现象。
AOP是面向切面编程,在不改变源代码的情况下增强代码,最大程度上减少了代码的重复性操作,将重复的代码提出来,创建切入点,让提出来的代码切进去,这样就大大提高了代码的冗余。最主要的应用场景就是日志、事务等。
IOC和AOP没有标准答案,可随意发挥。
8、说SpringSecurity是怎么实现权限管理的
实现了WebSecurityConfigurerAdaper,主要实现了认证和授权两个功能,认证就是为用户建立角色的过程,授权是根据这个角色设定可以访问哪些资源。
9、AOP的五个内置方法
- 前置通知
- 后置通知
- 环绕通知
- 异常通知
- 最终通知
10、Math.random() 是干嘛用的
用来生成随机数,默认取值返回在0-1之间,可以包括0但不包括1。
11、HashTable的实现原理
HashTable属于线程安全类集合,底层采用sync锁,并且key-value都不可为null,其底层与HashMap一致,都是用数组链表红黑树的数据结构,首次添加自动扩容长度为16,临界值是长度的0.75倍,扩容也是根据临界值进行比较的,如果等于临界值,那么就会进行扩容。每次扩容2倍,临界值每次都是长度的0.75倍。当单个链表的长度大于等于8的时候并且数组的总长度大于等于64的时候,就会将此链条进行树化,进化成红黑树。
抽象类和接口的区别
抽象类(abstract class)
- 被
abstract
修饰的类可以只声明不实现,也可以有具体的实现 - 可以被继承,如果子类没有全部实现父类的抽象方法,子类必须修饰成抽象类
- 可以有构造器
- 可以用修饰符
- 速度快,
接口
- 不能有具体的实现
- 子类必须重写全部父类的声明的接口
- 不能有构造器
- 默认修饰符 public
- 没有抽象快
重载和重写的区别
重载是在同类中方法名相同,参数列表不同,不会覆盖,可在同类中根据参数列表不同调用不同功能的方法。
重写是子继父类,重写父类的方法,增大功能,覆盖父类的方法。并且方法名和参数列表必须完全相同。
ArrayList和LinkedList的区别
ArrayList底层用Object类型的数组。所以查询快。增删慢
LinkedList底层使用链表的结构,查询慢,增删快。
HashMap底层怎么实现的
HashMap底层采用:数组链表红黑树,1.8以前没有红黑树。默认临界值为0.75倍
默认长度为16,临界值为12,长度达到12进行扩容,扩容2倍。线程不安全。
采用key-value的形式,key会根据key转换成对象的hash值,Value则是一个Object的类型
单个链表达到8并且数组长度64,则将链表进行树化!
如果hash指冲突如何进行处理的
如果hash冲突,后者会替换前者的内容,进行替换操作!
线程有几种状态
- 新建状态:创建一个线程对象
- 就绪状态:等待获取CPU的使用权
- 运行状态:得到CPU使用权,运行代码
- 阻塞状态:线程由于某种原因,放弃了CPU的使用权,暂停运行,重新进入就绪状态!
- 死亡状态:线程执行完毕或者异常退出了run方法
如何实现一个IOC的容器
使用方式:
- 配置类
- 配置文件
Session和Cookie的区别
- 存储的位置不同
- Session:服务端
- Cookie:客户端
- 存储的数据格式不同
- Session:
value
为对象。Object
类型。 - Cookie:
value
为字符串,如果我们存储一个对象,这个对象就需要将对象转换成JSON
格式。
- Session:
- 存储的数据大小
- Session:受服务器内存控制Session的大小。
- Cookie:一般来说,最大为4k。
- 生命周期不同
- Session:服务器端控制,默认30分钟,关闭浏览器,Session并不会消失。
- Cookie:客户端控制,关闭浏览器Cookie就消失,或者可以设置有效期7天免登录
并发和并行的区别
并发:同一个CPU执行多个任务,按时间片进行交替
并行:在多个CPU同时处理多个任务
数据库的三大范式
- 第一范式:不可拆分
- 第二范式:要有主键
- 第三范式:不可存在依赖传递
如何防止SQL注入
SQL注入是通过字符串连接的方式构成了一种特殊的查询语句。
数据库中SQL调优的几种方式
- 创建索引
- 避免在索引上使用计算
- 使用预编译查询
- 调整Where字句中的连接顺序
- 尽量将多条SQL语句压缩到一条SQL中
- 用where字句替换having字句
- 使用表的别名
- 用 union all替换union
- 考虑使用临时表暂存中间结果
- 只在必要的情况下使用事务 begin translation
- 尽量避免使用游标
- 使用 varchar/nvarchar 替代 char/nchar
- 查询Select语句优化(将*替换掉。不要返回用不到的字段)
- 更新update语句的优化(如果只修改一两个字段,不要修改全部,会产生大量日志)
- 删除Delete语句优化,最高效删除重复记录
rowid
- 插入insert语句优化。
谈谈事务的特点
原子型是基础,隔离性是手段,一致性是约束条件,而持久性才是我们的目的。
**原子性:**要么一起成功要么一起失败
**一致型:**转账典型案例,保持数据的一致性
**隔离性:**每个事务的执行都不会被干扰。
**持久性:**事务一旦提交,结果便是永久性的。
事务的隔离级别
为了解决并发情况下,数据的安全性问题。
- **读未提交:**脏读,没有提交事务,被其他事务使用,造成数据的脏读
- **读已提交:**如果没有提交,不会使用。不会使用脏读
- **可重复读:**可避免复读,可避免脏读,不可重复读的发生,但幻读有肯能发生
- **串化性:**可避免脏读,不可重复读,幻读的发生,但性能会 影响比较大
幻读是指:在本地事务查询数据库时只能看到3条,但是当执行更新时,却会更新4条信息,所以称为幻读。
谈谈你对Spring的认识
主要提供了IOC和AOP两种思想
IOC:实现了控制反转,帮助我们自动管理依赖对象,不需要自己去创建和管理依赖对象,从而实现层与层之间的解耦。
AOP:面向切面编程,为我们提供了非核心的代码抽离和非核心的解耦,
Bean的作用域
- 默认是singleton:单例模式
- prototype:每次从容器调用bean都需要创建一个新的对象
- request:每次http请求都会创建一个对象
- session:同一个Session共享一个对象
- global-session
什么是反射?
答:反射是指在运动状态中,对于任意一个类都能够知道这个类的所有属性和方法,并且任意一个对象,都能够调用它的任意一个方法,这种动态获取信息以及动态调用对象方法的功能成为反射机制。
深拷贝和前拷贝的区别是什么?
数据分为基本类型和引用类型。
-
基本数据类型: 数据直接存储在栈中,
引用数据类型: 存储在栈中的是对象的引用地址,真实的对象存储放在堆内存中。 -
浅拷贝: 对于基本数据类型,直接复制数据值,对于引用类型只是复制了它的引用地址。新旧对象指向同一地址,所以修改其中一个地址的值,另一个也随着修改。
-
深拷贝: 对于基本数据类型:直接复制数据值:对于引用数据类型,开辟新的内存空间,在新的内容空间里复制一个一抹一样的对象,新老对象不能共享内存,修改其中一个对象的值,不会影响另一个对象。
深拷贝相比于浅拷贝速度较慢,并且花销较大!
并发和并行有什么区别?
**并发:**两个或者多个事件在同一时间间隔发生。
**并行:**两个或者多个事件在同一时刻发生。
并行是真正意义上同一时刻做多种之情,而并发在同一时刻只做一种事情,只是可以将时间切碎,交替做多种事情。