1. spring MVC的执行过程
DispatcherServlet接受前端请求,HandlerAapter获取拦截器链,Handler匹配请求,交给具体的Controller处理请求,把处理结果借给ModelAndView进行视图处理,并返回给前端进行显示SpringMVC是基于Servlet的拦截处理,Struts的拦截是Filter的。
2.spring框架 bean 是单例还是多列 ,默认单例。多例怎么配置? 为什么要做成单例?
通过配置scope属性--->scope=prototype"
1.减少了新生成实例的消耗:spring会通过反射或者cglib来生成bean实例这都是耗性能的操作
2.减少jvm垃圾回收:因为不会给每个请求都新生成bean实例
3.可以快速获取到bean:除第一次需要创建实例之外,剩下的从缓存获取就可以
3.GC消耗过大怎么解决?
GC:1.将进入老年代的对象数量降到最低:老年代GC相对来说会比新生代GC更耗时
2.减少Full GC的执行时间
使用 StringBuilder或 StringBuffer来代替 String
尽量少输出日志
3.jdk1.8新特性常用的知道几种?最好讲清楚 用法和原理
1.Optional:是一个可以为null的容器对象,Optional 类的引入很好的解决空指针异常。
2.使用Lambda作为参数和返回值:如果方法的参数是一个函数式接口类型,那么就可以使用Lambda表达式进行替代
使用Lambda表达式作为方法参数,就是使用函数式接口作为方法参数
1)函数型接口: 有参数,且需要返回值。
2)供给型接口:无参数,指定返回值类型,经常用于只关注过程的代码。
3)消费型接口:不需要返回值,有参数,经常用于迭代
4)判断型接口:返回true/false,经常用于判断。
3.新的日期API——Date time
4..方法引用
方法引用符:::(双冒号)
通过对象名引用成员方法;
通过类名称引用静态方法;
通过super引用成员方法;
通过this引用成员方法。
5.新增Stream类:1)逐一处理:forEach;2)过滤:filter;3)映射:map(将stream里面的内容映射到另一个stream中)
4.sql 优化?
1 执行计划 。看是否有全表扫描,子查询等。一般 在where 条件,倒序,分组 等字段加索引。
5.大数据量 分库分表,怎么分?
会对数据库进行垂直拆分或水平拆分
水平拆分:就是把一个表的数据给弄到多个库的多个表里去
所有库表的数据加起来就是全部数据
垂直拆分:就是把一个有很多字段的表给拆分成多个表,或者是多个库上去,每个库表都包含部分字段
1.按自然时间来分表/分库;
2.按数字类型hash分表/分库;
3.按md5值来分表/分库;
6.数据库锁设计?悲观锁,乐观锁含义?什么场景用悲观锁?什么场景乐观锁
幂等性?当多个线程同时执行 同一个方法。 方法级锁有哪些,区别是什么?
悲观锁:共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程
比如行锁,表锁
行锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度最高
表锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低
实现:sql语句后边加上for update
乐观锁:乐观锁适用于多读的应用类型,这样可以提高吞吐量
7. 创建线程的四种方式?有返回结果的是哪一种?怎么才能知道子线程结束
1)继承Thread类创建线程
2)实现Runnable接口创建线程
3)使用Callable和Future创建线程(有返回结果)
4)使用线程池例如用Executor框架
子线程已结束:用GetThreadExitCode())其他线程结束,发消息告知主线程
8.分布式系统中,分布式锁的应用场景是什么?
1)基于数据库:在数据库中创建一个表,表中包含方法名等字段,并在方法名字段上创建唯一索引,
想要执行某个方法,
就使用这个方法名向表中插入数据,成功插入则获取锁,执行完成后删除对应的行数据释放锁。
2)redis:1.Redis有很高的性能;
2.Redis命令对此支持较好,实现起来比较方便
(1)获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,
锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。
(2)获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
(3)释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。
3)zookeeper:Apache的开源库Curator,它是一个ZooKeeper客户端,Curator提供的InterProcessMutex是分布式锁的实现,
acquire方法用于获取锁,release方法用于释放锁。
优点:具备高可用、可重入、阻塞锁特性,可解决失效死锁问题。
缺点:因为需要频繁的创建和删除节点,性能上不如Redis方式。
9. mybatis 都有哪些配置?怎么提高持久层的效率?二级缓存会遇到哪些问题?
settings:定义mybatis的一些全局设置
typeAlias :定义java类型的别名
environments :用于配置数据源
mappers :mapper文件用于定义sql语句,以及与其对应的entity
提高持久层的效率:使用动态代理模式生成dao层接口的代理实现类
mybatis二级缓存对细粒度的数据级别的缓存实现不好
因为mybaits的二级缓存区域以mapper为单位划分,
当一个商品信息变化会将所有商品信息的缓存数据全部清空
10.class 反射原理是什么?哪些方法可以获取到属性值
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性
★ 方式一
通过对象的getClass方法进行获取。这种方式需要具体的类和该类的对象,以及调用getClass方法。
★ 方式二
调用类中的静态属性class完成,无需调用方法,性能更好。
★ 方式三
通过Class.forName()方法获取。这种方式仅需使用类名,就可以获取该类的Class对象,更有利于扩展。
11.hashmap 和 hashtable 区别?线程哪个最安全?如果想高效率利用hashmap 用他哪个扩展方法
HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题
1.继承的父类不同:HashMap继承自AbstractMap类。但二者都实现了Map接口。
Hashtable继承自Dictionary类(已被废弃)
2.HashMap线程不安全,HashTable线程安全
3.Hashmap是允许key和value为null值的
HashTable键值对都不能为空,否则包空指针异常。
不为一原则:重写HashCode()
分散原则:生成hashcode的算法尽量使hashcode的值分散一些,不要很多hashcode都集中在一个范围内
12.arrylist 和 linklist 的区别及原理?
1、二者实现结构不同arraylist是基于数组,linkedlist是基于链表,他们的特性也是由其数据结构决定的。
2、随机遍历访问时linkedlist的性能要低于arraylist.
3、arraylist的初始化时默认10容量,而linkedlist默认初始化为空。
4、linkedlist的增删要优于arraylist
13. redis 数据哪些数据类型?
String字符串类型(一个由字节组成的序列)
List列表类型(链表)使用场景:消息队列
Set集合类型(各不相同的元素,无序排列)
Redis的集合和列表都可以存储多个字符串,他们的不同支持在于,列表可以存储多个相同的字符串,
而集合通过使用散列表来保证自己存储的每个字符串都是各不相同的
14 消息队列 如kafka,mq消息丢失怎么处理?
生产者端解决方法:1.开启 RabbitMQ 事务
2.开启 confirm 模式(每次写的消息都会分配一个唯一的 id)
RabbitMQ 弄丢了数据:1.开启 RabbitMQ 的持久化
2 持久化机制与生产者的 confirm 机制配合
消费端丢失了数据:关闭 RabbitMQ 的自动 ack(通过一个 api 来调用就行,确保每次数据处理完后手动 ack)
kafka:
给 topic 设置 replication.factor 参数:这个值必须大于 1,要求每个 partition 必须有至少 2 个副本。
在 Kafka 服务端设置 min.insync.replicas 参数:这个值必须大于 1,这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower 吧。
在 producer 端设置 acks=all:这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了。
在 producer 端设置 retries=MAX(很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了。
消息队列是一种异步的服务间通信方式,是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。使用较多的消息队列有ActiveMQ、RocketMQ、RabbitMQ、Kafka等。