说在前面:自己为了准备面试Java后端开发准备的面经,部分有摘自其他网站,还有平时面试总结的,分享一下。
Java开发基础
0. 抽象类和接口的区别
语法:
构造器--抽象类可以,接口不可以
具体方法-抽象类可以有,接口全是抽象方法,但在1.8以后可以有默认方法
成员修饰符--接口中全是public,抽象类可以是private、默认、protected、public
继承和实现--抽象类只能是单继承,但接口可以实现多个
成员变量--抽象类中可以定义成员变量,接口中的成员变量实际都是常量
静态方法--抽象类中可以有,接口中不能有
由抽象方法的类必须声明为抽象类,但抽象类未必要有抽象方法
语义:
抽象类指的是一种概念
接口描述的是一种特征
1. 反射机制
通过getClass方法动态获取类的实例,可以提高灵活性和扩展性,但会消耗一定的系统资源,还会忽略权限检查,
导致实例可以获取到类的私有属性和方法
2. 序列化和反序列化
序列化是将类对象状态转为二进制文件保存到磁盘中;
反序列化是将硬盘中保存的Java对象状态的字节序列按照编号组转成类对象恢复到内存中。
3. String、StringBuffer和StringBuilder的区别?
String 大小固定,不可变
StringBuffer 大小可变,线程安全(有锁),同步,效率低,适用于多线程,低并发
StringBuilder 大小可变,线程不安全(无锁),不同步,效率高,适用于单线程,高并发
4. List问题汇总
ArrayList 底层数组,在查找元素的时候效率高(每个元素都有对应的索引),线程非安全,不同步
LinkedList 基于双向链表,在插入和删除元素的时候效率高(链表不需要内存移位)线程非安全,不同步
Vector 线程安全,同步,操作与ArrayList类似
5. hashTable和hashMap区别
hashTable线程安全的,但是性能不高,一般使用concurrentHashMap。HashTable是同步的,hashMap是不同步的
前者的键值不允许为空 后者允许
前者基于hashCode后者基于hash值
前者使用Enumeration遍历,后者使用iteration遍历
6.泛型的作用:泛型其实是数据类型参数化
消除强制类型转换;提高代码复用性;提高Java程序的类型的安全
7.创建线程的方法
继承Thread类,重写run方法
实现接口Runnable或者Callable接口
通过线程池来创建线程
8.Runnable和Callable的区别
前者不会返回结果和抛出异常 后者会
9.sleep和wait的区别
sleep方法是Thread类的静态方法,wait方法是Object类的方法
sleep不会释放锁 wait会释放
wait必须在同步方法和同步代码块中使用 sleep方法可以在任何地方使用
sleep必须捕获异常 wait不需要捕获异常
10.synchronized 底层实现原理?
synchronized修饰后的代码块和方法,可以阻止其他线程获取当前对象的监视锁,同时能保证
同一时刻只有一个方法能进入临界区,
还会保证所有操作都直接刷到内存中,保证了内存可见性。
11.volatile底层实现原理?
只能修饰变量,不能修饰方法和代码块
被volatile修饰后的变量会直接同步更新到内存中,可以保证其他线程立马看到更新后的变量值
不能保证原子性(原子性是要么都做要么都不执行)
还能保证有序性
12.线性安全的
Vector:只要是关键性的操作,方法前面都加了synchronized关键字,来保证线程的安全性
Hashtable:使用了synchronized关键字,所以相较于Hashmap是线程安全的。
ConcurrentHashMap:使用锁分段技术确保线性安全,是一种高效但是线程安全的集合。
Stack:栈,也是线程安全的,继承于Vector。
13.线性不安全的
HashMap HashSet TreeSet TreeMap ArrayList LinkedList
14.Synchronized和Lock区别
前者是关键字 后者是接口
前者会自动释放锁 后者不会 必须在finally中释放锁
前者是非中断锁,必须等待线程执行完后才能释放锁 后者是中断锁
前者在竞争不太激烈时性能好 后者更灵活,适用于竞争性大的场景
15.GET提交和POST提交的区别
前者是将表单数据直接追加在提交地址后面的,有大小限制,但速度快
后者是将表单数据作为一个整体的数据块进行提交的,无大小限制,但速度慢
16. 类加载的过程
其实是将Java类的字节码文件加载到机器内存中,包括两个过程:编译和执行,编译就是将java文件通过javac生成.class文件,运行就是将.class文件交给虚拟机执行。
类加载过程就是指虚拟机将.class文件中的类信息加载到内存中,并进行解析生成对应的class对象的过程。
17.双亲委派机制
按照层级关系一层一层的加载,并进行委派。要想加载一个类,从底层到高层一级一级委派,先由应用层类加载器加载,然后再向上委派给扩展类加载器,最后再向上委派
启动类加载器,如果失败,再由上层往下层加载失败信息,最终找不到那就报类找不到异常。
优点就是保证安全性,层级也代表优先级,启动类加载器优先级最高,还可以避免重复加载,父类加载器加载过了,子类加载器就不需要再加载
18. JVM内存模型
(1)方法区:属于JVM运行时数据区域的一块逻辑区域,是各线程共享的内存区域;
会加载虚拟机从字节码文件读取并解析的类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据;
方法区和元空间的关系类似于接口和类的关系。
(2)堆:JVM管理的最大的一块内存空间,是所有线程共享的,存放对象实例以及数组;
是GC(垃圾收集器)管理的主要区域,GC主要使用分代垃圾收集算法,在jdk1.8分为年轻代、老年代和元空间(取代了1.7中的永久代)。
(3)虚拟机栈:周期随线程创建而创建,随线程结束而死亡,是线程私有的;
虚拟机栈中栈帧作为基本单位,栈帧组成部分有:局部变量表,操作数栈,动态链接,方法返回地址。
动态链接主要服务一个方法调用其他方法的场景,由于在字节码文件中,所有变量和方法的引用都作为符号引用保存
在Class文件的常量池中,所以动态链接的作用就是将符号引用转换为调用方法的直接引用;
虚拟机栈会出现StackOverFlowError(死循环)和OutOfMemoryError(内存扩展时没申请到空间)两种异常。
(4)本地方法栈:与虚拟机栈的周期和栈帧组成结构、异常类似,本地方法栈是指在调用本地方法(可能是除Java语言以外的其他语言的方法接口)时创建的栈空间。
(5)程序计数器:字节码解释器通过改变程序计数器来依次读取指令,从而实现循环、选择、顺序执行、异常处理;
同时在多线程情况下,每个线程都有一个独立的程序计数器,可以在线程切换后正常运行;
不会出现内存溢出,随线程创建而创建,随线程结束而死亡。
19.JVM的GC回收
(1)内存分配和回收原则:
大部分对象在新生代中Eden区分配,如果空间不足,则会发起一次GC;
大对象直接进入老年代,比如需要连续存储空间的数组、字符串;
长期存活的对象将进入老年代,给每个对象一个年龄计数器,熬过每次GC的回收仍然存在就会年龄值加1,如果超过15则会进入老年代;
(2)死亡对象判断方法:
引用计数法:不常用,使用引用计数器,每引用一次就加1,当引用失效时,就减1,直至为0,则判断为死亡对象;
可达性分析算法:当对象到GC Roots没有引用链时则被认为需要回收。
(3)垃圾收集算法:
标记-清除算法:两个阶段-标记和清楚阶段,先标记出所有不需要回收的对象,在标记完成后统一回收掉所有未被标记的对象。缺点是效率低,且会产生不连续的碎片空间。
标记-复制算法:首先将内存分为大小相同的两块,每次使用完一块后,将还存活的对象都集中复制到另一块中,然后把使用的空间都清理掉,这样每次垃圾回收就只对一半内存进行回收即可。
标记-整理算法:与标记-清除的标记阶段一样,所有存活对象标记后,将它们都移动到连续的一端,然后再把剩余端边界以外的内存清除。
分代收集算法:将虚拟机的堆内存分为新生代、老年代,新生代一般每次收集都会有大量对象死去,所以可选择标记-复制算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集;
老年代的对象存活几率比较高,所以一般选择标记-清除或标记-整理算法进行垃圾回收。
20.jdk8新特性
(1)Lambda表达式允许把函数作为一个方法的参数或者把代码看成数据,使代码更简洁;
(2)Optional类,能很好的解决空指针异常。
(3)Base64能将非ASCII码字符转为ASCII码字符,是一种编码算法,而不是加密算法。
(4)接口可以有默认方法和静态方法,而默认方法可以极大的增强程序的扩展性,但也容易造成歧义。
(5)方法引用,可以直接引用已有的Java类或者对象(实例)的方法或构造器。
基本引用格式为:Class::method(静态方法或普通方法)或者Class::new或者实例对象::方法
(6)Stream流,可以以声明的方式处理数据,可读性强,能轻松获取并行化流,不需要自己编写
多线程代码,更专注于业务逻辑。
(7)注解,可以重复在同一个地方多次添加注解,还对注解进行了扩展,在局部变量,泛型类,
父类与接口的实现以及异常都可以添加注解。
(8)并行数组,可以提高数组排序的速度。
(9)并发,在ConcurrentHashMap方法上添加了支持聚集操作的新方法。
(10)新的日期API,解决了之前很多问题。
21. CountDownLatch和CyclicBarrier的区别以及各自的应用场景?
22.hashMap的put()和get()实现原理
23.object类的方法有哪些:
clone() equals() toString()
finalize()--垃圾回收器确定该对象不存在被引用时,由对象的垃圾回收器调用此方法
getClass()获取此时运行时的类
hashCode()返回的该对象的哈希值
notify()唤醒此对象监视器上等待的单个线程 notifyAll()唤醒所有线程
wait() 让当前线程进入等待
24.String内存的问题
String字符串变量一般直接定义的在字符串常量池中,而字符串常量池在jvm内存的堆空间,如果new对象创建的字符串变量,内存堆中肯定会创建一份,同时还会在字符串常量池中有一份(前提是字符串常量池中没有这个值)所以会出现只要是直接定义的字符串变量都会是同一个地址,而new出来的就不相同了。
数据库
1.Sql优化
查询使用适当的索引
避免空判断语句
避免左侧模糊查询
避免使用in 用exists代替
避免使用or 和 不等于条件查询
避免在 where 子句中对字段进行表达式操作和函数操作
尽可能的使用 varchar 代替 char
避免使用"*"返回所有,可以用具体的字段代替
上述会导致数据库引擎放弃索引进行全表扫描
2.什么是索引及其类型与种类?
索引是表的目录,是数据库中专门用于帮助用户快速查询数据的一种数据结构
(就像新华字典的目录一样)
类型:BTREE、RTREE、HASH、FULLTEXT
种类:普通索引、唯一索引、主键索引、全文索引、组合索引
哪些情况适合使用索引?
数据量较大的表、
经常查询的字段、
主键和做外键的字段、
经常与其他表连接的表中连接字段、
经常做排序的字段、
经常用在where子句、order by、group by的字段
3. 哪些情况不适合使用索引?
查询很少使用的情况不适合建立索引;
经常增、删、改的字段不适合建立索引;
当数据过少的时候不适合建立索引;
定义为text, image和bit数据类型的列不适合建立索引
4. 聚集索引和非聚集索引
聚集索引的索引和数据是放到一块的 而非聚集索引是分开的
前者存储记录在物理上连续的,而后者在逻辑上是连续的
前者每张表只能有一个 后者一张表可有多个
前者物理存储按照索引排序,后者不按照索引排序
5.什么是事务及其属性
事务可包含一个或多个操作,要么成功都提交,要么有一条失败就都回滚
事务的属性:
原子性
一致性: 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
隔离性:指各操作之间不互相干扰 隔离级别:读未提交 读已提交 可重复读 串行化
持久性:事务提交后,对数据库的改变是持久的
6.事务的并发问题?
脏读:事务A读取了事务B修改的数据,然后B事务回滚了,那么A读到的数据即为脏数据
不可重复读:事务A在读取数据时,事务B不断对其进行修改,最终每次取得结果都不一样即为重复读
幻读:事务A将数据由分数改为等级,在这过程事务B插入了一条新数据,而这条数据没改过来即为幻读
悲观锁:在对数据操作时会加锁直至结束操作
乐观锁:操作前不加锁,只有在提交时才根据版本号对比验证数据是否存在冲突
7. 事务的隔离级别?
读未提交:事务A在写数据,但事务B要申请读,此时事务A还未提交修改的数据,那么就会出现事务B
读取A未提交的数据;
读已提交:事务A在读取,事务B在写,等事务A再次读取只能读到提交后的数据。
可重复读:在一个事务内,未结束之前,其他事务不能对该数据进行读写,这样在同一事务内两次读到
的数据就是一样的。
可序列化:最高的隔离级别,同一时刻只能有一个事务在执行,也就是串行,不能并发执行。
8.存储引擎
(1)MySQL体系结构
连接层
服务层
引擎层
存储层
(2)存储引擎
InnoDB引擎:默认的MySQL存储引擎,高可靠性和高性能的通用存储引擎。
特点:DML操作遵循ACID模型,支持事务;
行级锁,提高并发访问性能;
支持外键约束,保证数据的完整性和正确性;
文件:每张表都对应一个表空间文件,存储该表的结构、数据和索引
MyISAM引擎:MySQL早期默认的存储引擎
特点:不支持事务,不支持外键
支持表锁,不支持行级锁
访问速度快
文件:xxx.sdi 存储表结构信息 xxx.MYD 存储数据 xxx.MYI 存储索引
Memory引擎:表数据都存储在内存中的,会收到硬件、断电问题的影响,所以只能将这些表作为临时表或缓存使用
特点:内存存放,hash索引
文件:只有xxx.sdi存储表结构信息
9.数据库存储过程
存储过程也是一组数据集,为了完成特定功能,存储在数据库中,一次编译后永久有效,存储过程的名字和参数。(存储过程有带参和无参)
有系统存储过程、用户自定义存储等。
存储过程有增强SQL语言的功能和灵活性、执行速度快、而且存储过程被创建后可以在程序中被多次调用。
10.索引
优点:可以加速查询效率;通过创建唯一性索引可以保证数据库表中每一行数据的唯一性。
缺点:创建和维护索引需要耗费时间,增删改的时候也会降低执行效率;需要使用物理文件存储,耗费空间
底层数据结构:hash表(key-value键值对的集合)和B树&B+树
11.一条sql语句的执行过程
首先经过连接层,查询用户权限;
然后查询缓存中是否已经执行过,如果有直接返回结果,否则继续下一步;
接着分析器里会分析sql的语法和词法是否正确;
然后优化器会对sql执行顺序,选择 哪个索引进行优化;
然后执行器操作引擎,返回结果;
最后,存储引擎存储数据,提供读写接口
12.sql语句优化
(1)插入数据
insert优化-批量插入方式(最好在500-1000条);手动提交事务 start transaction insert into 语句 commit;主键顺序插入 按照主键顺序插入 速度比乱序插入要快
大批量插入数据 用load指令,可以加载本地文件插入到数据库中(感觉是navicat的导入本地txt/excel等文件加载到数据库的底层)
(2)主键优化
设计原则:降低主键长度;插入时,尽量选择顺序插入,选择使用自增主键;
尽量不要使用UUID做主键;业务操作时,避免对主键的修改。
(3)order by优化
尽量用有序索引顺序扫描,即using index,效率高,不需额外排序。
尽量使用覆盖索引。
根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则。
多字段排序是,一升一降,注意联合索引在创建时的规则。
如果不可避免出现using filesort,大量数据排序时,可适当增大排序, 缓冲区大小(默认是256k)。
(4)group by优化
在分组操作时,可通过索引来提高效率,索引也要使用最左前缀法则。
(5)limit优化:
思路:通过创建覆盖索引加上子查询的形式来进行优化。
(6)count优化
思路:自己记数,利用no-sql数据库记数。
尽量使用count(*)数据库已经对排序做了优化。count(字段)<count(主键id)<count(1)<count(*)
(7)update优化
根据索引字段进行数据更新,避免行锁升级为表锁,削弱并行效率。
13.redis
(1)为什么要用redis缓存数据库?
减轻数据库的压力。redis的吞吐量是万级,而mysql吞吐量是千级,请求并发量很高时会导致数据库宕机;
提高用户体验。redis使用的是计算机内存,读取速度快,而mysql数据库使用的计算机磁盘,读取速度肯定要慢;
提高系统并发量。缓存并发量大于数据库并发量。
redis缓存可以分担一部分请求,提高了系统整体的并发。
redis除了做缓存,还可以做分布式锁、消息队列、限流、复杂业务场景(比如通过bitmap统计活跃用户、通过sorted set维护排行榜)
(2)redis常用的数据结构:
五种基础的:List、set(集合)、hash(散列)、String、zset(有序集合)
三种特殊的:Bitmap(位存储)、HyperLogLogs(基数统计)、Geospatial(地理位置)
redis的过期的数据删除策略:惰性删除(只会在key取出的时候进行过期检查)和定期删除(每隔一段时间取一批key进行删除过期key操作)
(3) redis的内存淘汰机制:
从已设置过期时间的数据集中,a.挑选最近最少使用的淘汰;b.挑选不经常使用的淘汰;c.随机淘汰;d.挑选即将要过期的淘汰
从所有数据集中,a.挑选最近最少使用的淘汰;b.挑选不经常使用的淘汰;c.随机挑选数据淘汰。
(4) redis持久化机制:RDB(快照)和AOF(只追加文件)
RDB:redis通过创建快照获取存储在内存里面的数据在某个时间点上的副本。redis对快照进行备份,将快照复制到其他服务器(redis主从结构,可提高性能)
RDB的备份过程:
redis创建一个fork子进程建一个临时存储文件,等持久化过程结束后,就会将临时存储文件替换上次的持久化文件。
过程用的是写时复制技术。主进程不进行IO操作,所以速度要快。缺点是最后一次持久化操作可能会被丢失(如果宕机,
但此时还未达到可以持久化操作的时间限制,那么就会丢失最后一次的数据)
AOF:每执行一条会更改redis数据的命令,redis就会将该命令写入到内存缓存中,再根据配置来决定何时同步到硬盘的AOF文件中。
AOF配置持久化方式有三种:每次修改都会写入AOF文件(always);每秒同步一次(everysec);让操作系统决定何时进行同步(no)
AOF重写:
由于AOF采用文件追加方式,为避免文件会越来越大,增加了重写机制,当上一次重写后的文件超过设定的阈值后,redis就会启动AOF内容压缩,只保留可以恢复数据的最小指令,会比原来的AOF文件体积小。
重写过程:这里的重写是直接读取数据库中的键值对来实现。会创建一个新的子进程将文件重写, 但由于在创建子进程过程中也会有写操作,所以在执行bgrewriteaof时会维护一个AOF重写缓冲区,将创建子进程期间的所有写操作都记录下来,然后追加到新的AOF文件末尾。最后在用新的AOF文件替换旧的AOF文件。
若同时开启RDB和AOF,默认读取AOF的数据。
(5) redis事务:不支持原子性
redis 缓存穿透、缓存击穿、缓存雪崩:
缓存穿透:用户查询的id在缓存中都查不到或者恶意者故意发起访问不存在的id请求。(也就是说每次请求都要去请求查询数据库,但每次从数据库中都查不到,这就会造成数据库压力太大而挂掉)。用校验参数方法过滤一部分恶意;用布隆过滤器通过bitmap位存储来,利用hash值可以计算请求的id在数据库中是否存在,如果不存在的直接拒绝访问。
缓存击穿:当同时有大量用户请求访问某一个数据时正巧该数据过期失效,那么该请求压力会堆到数据库,也会造成数据库挂掉。(比如双十一秒杀)可以用加锁的方法控制同一时刻请求某个id只允许有一个;也可以自动续期,在快要过期时,就给key续期;还可以设置缓存不失效。
缓存雪崩:reids缓存在同一时间大量的热门缓存同时失效,请求压力都在数据库上,会造成数据库宕机;可以用过期时间加随机数,避免同一时间大量缓存数据同一时间失效;还可以用redis集群和限流(避免同时处理大量的请求)
(6) 分布式锁:
问题描述:由于分布式集群系统的多线程、多进程在不同的机器上,原单机部署情况下的并发控制锁策略失效,需要一种跨JVM的互斥机制来控制共享资源的访问,也就是分布式锁要解决的问题。
setnx:通过该命令尝试获得锁,没有获得锁的线程会不断等待尝试。
set key ex 3000nx:设置过期时间,自动释放锁,解决当某一个业务异常而导致锁无法释放的问题。
但当业务运行超过过期时间,会开辟监控线程增加该业务的运行时间,知道运行结束,释放锁。
uuid:设置uuid,释放前获取这个值,判断是否自己的锁,防止误删锁。
Lua脚本:保证删除锁的原子性。
三种情况:(1)使用setnx上锁,通过del释放锁;(2)锁一直没释放,就设置key过期时间,自动释放锁;
(3)上锁之后突然出现异常,无法设置过期时间,那么就在上锁的时候同时设置过期时间 (set users 10 nx ex 12))
后端开发框架
1.Spring
介绍及优点:
Spring一个轻量级的Java 开发框架,Spring的核心是控制反转(IoC)和面向切面(AOP)
(1)方便解耦,简化开发 (高内聚低耦合)
Spring就是一个大工厂(容器),可以将所有对象的创建和依赖关系,交给Spring容器管理
(2)支持AOP
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
(3)方便集成各种优秀框架
Spring不排斥各种优秀的开源框架
2.SpringIOC:控制反转
IoC 控制反转,核心思想是将手动创建对象的控制权交给Spring来管理。
Spring作为容器,负责生成bean的实例和对bean的依赖注入
三种注入方法:
构造方法注入、setter方法注入、注解注入
3.SrpingAOP:
Aop是面向切面编程,是通过动态代理的方式,
在不改变原有代码的情况下对类的功能进行无限的增强
主要的功能有:添加日志,事务,权限
特点是:降低模块间的耦合度、提高可维护性
4.SpringMVC
介绍springMVC,说一下优点
springmvc是一个基于MVC的轻量级Web框架,能够完成前后台的交互
Model 业务层 = Service层 + Dao层
View 显示层 表现层 前台的页面表现(jsp页面)
Controller层 控制层 前台页面与后台代码之间的数据的交互(Servlet)
优点:耦合性低、与Spring框架集成、简化JSP开发、支持Restful风格
5.注解
注解是说明程序的,给计算机看的。JDk 1.5之后的新特性,可以声明在包、类、字段、方法、
局部变量、方法参数等前面,
用来对这些元素进行说明、注释
作用:安全性考虑 减少内存泄露 减少程序员工作量。
6.MyBatis
ORM框架 DAO层
对象关系映射框架,以面对对象的方式完成对数据库的操作
类 --> 表
属性 --> 字段
实例 --> 记录
MyBatis中#和KaTeX parse error: Expected ‘EOF’, got ‘#’ at position 5: 区别? #{}是预编译处理,
防止SQL注…{}是字符串替换。
7. Spring、SpringMVC、SpringBoot之间关系?
Spring包含很多模块,如IOC、AOP、Core(提供IOC依赖注入的功能)
SpringMVC是Spring很重要的模块,核心思想就是将业务的逻辑、显示、数据分离开来组织代码。
SpringBoot是为了简化一些XML、java 的显示配置,真正做到开箱即用
8.什么是SpringBean?
其实就是SpringIoC容器中所管理的对象,其实就是类对象,通过id、class属性配置
将一个类声明为Bean的注解有:
@Component:不知道哪一层的时候用这个
@Service:对应服务层
@Controller:对应SpringMVC控制层
@Repository:对应持久层DAO层,主要用于数据库相关的操作
9. @Autowired和@Resource的区别
@Autowired是spring提供的注解,通过byType去注入,@Resource是JDK提供的注解,
通过byName方式注入
10. SpringMVC工作原理
客户端发送请求后,被DispatchServlet拦截请求;
DispatchServlet根据请求信息调用HandlerMapping;
DispatchServlet调用HandlerAdapter适配执行Handler(也就是Controller控制器);
Handler完成对用户请求的处理后,会返回一个ModelAndView对象给DispatchServlet;
ViewResolver会根据逻辑View寻找实际的View;
DispatchServlet把返回的Model传给View(视图渲染);
把View返回给浏览器。
11. Spring框架中用到了哪些设计模式?
工厂设计模式:BeanFactory、ApplicationContext创建bean对象;
单例设计模式:bean默认都是单例的;
代理设计模式:SpringAOP功能的实现;
适配器设计模式:SpringMVC用适配器模式适配Controller。
12. Spring事务
(1)管理事务的方式:
编程式事务:手动管理事务,很少用
声明式事务:在XML配置文件中配置或者基于注解@Transactional
(2)Spring事务的隔离级别:
默认、读未提交、读已提交(解决脏读)、可重复读(解决脏读、不可重复读)、可序列化
(解决所有脏读、不可重复读、幻读)
13.SpringBoot有哪些优点/为什么要用SpringBoot?
减少开发、测试时间;
避免大量的maven导入和各种版本冲突;
没有单独的web服务器需要,意味着不再需要启动tomcat,直接启动主程序即可运行;
需要更少的配置,没有web.xml文件。只需要@Configuration注释类,@Bean注释方法,
Spring将自动加载对象,甚至用@Autowired自动装入bean中
其他
1.加密算法分对称和非对称,分别有哪些?
DES:数据dao加密标准,速度快,适用于加密大量数据的场合
3DES:基于DES,对一块数据用三个不同的密钥进行加密,强度更高;
AES:高级加密标准,速度快,安全级别高。
2.页面加载缓慢怎么解决?
页面记载速度慢两种原因及解决方法:
(1)数据请求接口返回慢。
将需要请求的接口创建为定时任务,时间间隔可以根据接口的压测进行调整;
定时任务请求的数据写入缓存,比如利用redis缓存数据库,前端发送请求后,先从缓存中取数据,若取不到再去直接请求接口,并更新缓存。
(2)页面渲染速度慢。
将页面上的数据接口拆开,异步进行请求;
页面做适配,先获取到的数据先渲染;
可以先渲染页面,数据请求到后再填充。