大家好,又见面了,我是你们的朋友全栈君。
引言
有的面试会被问到有没有写博客,这时候我尴尬,不知道怎么回答,所以这篇文章仅仅是把我面试JAVA的遇到的问题记录下来而已,也算是我写博客迈出的第一步,起码,以后被问到:有没有写博客?我可以回答,我写过。 (最主要的是以后换工作我不用频繁百度常见面试题了。。。。)
ps
1,别把我太当回事,我是个LJ;
2,说得不对的地方请多多包涵,想看更详细的请百度官方文档和其他大佬的文章;
3,如果有被问到了,我这上面没有的话,也可以提出来,我去学习,补上去,谢谢各位大哥。
正文
1,跟我讲讲SpringMVC的执行流程?
浏览器提交http请求–>提交到DispatcherServlet–>根据配置文件找到请求对应的HandlerMapping–>找到对应的Controller–>Controller执行Service层业务代码–>返回结果封装到ModelAndView–>再次根据DispatcherServlet找到对应的视图解释器–>数据封装到Model中–>返回给JSP–>http请求返回给浏览器
2,跟我讲讲Spring的IOC和AOP?
IOC简称:控制反转,又被叫做依赖注入(DI),其作用是把创建对象交由Spring工厂完成,避免了程序员创建对象的麻烦。
其实现大致分为以下四个步骤:
1,加载Spring容器BeanFactory创建Resource对象。
加载Spring的容器BeanFactory在其构造方法创建实现了Resource接口的对象的实例,Resource对象创建成功后会调用getConfiguration()方法获取到Spring配置文件的位置。
Resource的实现分为三种FileResource,UrlResource,ClassPathResource,分别对应获取文件,网络资源,项目路径下资源。
Resource创建如果有父类就使用父类的容器,如果没有就创建新的容器。
2,提取验证模式
BeanFactory会调用getInputStream()方法获取到配置文件的输入流,在加载前,会以DTD或XSD,通过头标签验证配置文件的正确性和完整性。
3,提取内容
把配置文件转换成一个document对象,这个document对象把类的内容转换成Spring的特殊结构BeanDefinition,BeanDefinition中包涵了Bean的所有信息,例如:是否懒加载,是否单例,是否抽象类,是否私有类等等。
4,注册
把所有的Bean装到ConcurrentHashMap中,以BeanName作为key,BeanDefinition作为Value。其中,如果BeanName重复,并且Spring不允许重复的话,那么就会报错,否则就会覆盖。
AOP简称:面向切面编程,其主要应用在业务贯穿了整个系统的时候,例如事务的控制,权限,安全,日志。
它的核心归纳为:切面,切点,目标对象,连接点,增强,引入,植入。
通知的方式又分为五种:前置通知,后置通知,环绕通知,异常通知,返回后通知。
加载的方式有两种:动态加载和cglib加载。
3,你用AOP做过什么业务?能简单讲讲吗?
我利用AOP做过日志的管理,采用监听方法的调用去实现的。但是有缺点:每个人写的方法名不一样,有的时候监听不到方法的调用,所以我当时规定了起名规则,它的优点就是不需要去写自定义注解,可以少些代码,因为方法名的约束在所以提高代码后续的可读性。
第二种方法就是自定义注解去实现日志录入,优点就是灵活多变,缺点就是每个方法都要加这个注解。
4,能讲讲Mybatic的大概的执行流程吗?它是怎么与数据库完成数据的交互的?
mybatic会加载SqlSessionFactory容器,每次请求都会获取到一个SqlSession,由SqlSession建立起与数据库的会话,并把sql传入数据库执行,数据库执行后把结果返回,其中,也涉及到了mybatic一级缓存的调用(如果表的结构或数据没发生改变,并且SQL重复执行,那么查询的时候优先把一级缓存中的数据返回,而不是请求数据库查询SQL语句),每次查询的结果其实都会存到一级缓存中,mybatic默认开启了一级缓存,二级缓存则需要通过修改配置文件开启,二级缓存是针对Mapper的,主要是多个
SqlSession共享同一个Mapper。(这里我也把mybatic的一级缓存和二级缓存大概讲了一下)
5,数据库方面有了解吗?能讲讲NoSQL和MySql的区别吗?
数据库方面也涉及到了CAP三大定律,即:一致性(C),可用性(A),分区容忍性(P)。
其中:传统型数据库,如MySql遵循的是CA,保证了一致性和可用性;KV结构的数据库满足AP,可用性与分区容忍性。
传统型数据库的优势在于:体积小,速度快,成本低,能始终保证数据的一致性。缺点是当表数据量过大(五百万条或2.5G大小)的时候要考虑采用缓存,或者主从复制,读写分离,异构复制等数据库层次的优化操作。
NoSQL优势在于:高性能,高拓展,高可用;缺点是很难保证数据的一致性,只能在业务层的代码做约束,但是根据墨菲定律,不管业务做得再严谨,一定会有脏数据产生,所以要用数据检查去补偿。其结构为Base模型(基本可用,软状态)。
6,能讲讲事务吗?
事务的四大特性为:原子(事务的操作是原子性的),一致(数据前后保持一致),隔离(事务的操作互不影响),持久(一旦持久化则不可回滚)。
事务的隔离级别为:脏读,不可重复读,幻读。
数据库事务的又分为:Default(默认级别),uncommit,commit(解决脏读),read(解决不可重复读),Serializable (解决幻读),事务的隔离级别设置得越高,数据库的性能就越低,所以一般只设置到commit级别。
7,能讲讲你建表的时候会注意哪一些吗?
1、关于字段的类型
人类的岁数设置为tinyint,龟的岁数设置为smallint,行星的寿命设置为int,宇宙的寿命设置为bigint;
涉及到金钱的使用decimal,因为fload,double有精度的缺失;
尽量不适用text,除非字节数超过了5000,否则都是使用varchar;
2、关于字段名
判断的字段的起名为is_xxx;
3、关于索引
索引我也不会多建,过多的索引会对查询速度产生影响
4、关于设置默认值
推荐字段设置默认值,可以很好避免程序运行时的空指针异常
5、关于必有字段
创建时间,修改时间,修改人
8,能讲讲索引吗?你是怎么优化一条SQL的?
索引常见的有主键索引、普通索引、唯一索引、全文索引、聚合索引。
聚合索引在使用的时候where后字段的顺序尽量与索引的顺序一致,否则可能会失效,并且聚合索引不能为null;
使用聚合索引,应把标识读最高的字段放在最左边,因为字段的匹配从左到右;
索引在使用的时候要注意where后字段的类型是否与索引的字段的类型一致,不一致会失效,例如索引的字段类型是varchar,但是where后的字段不用单引号包起来,这样索引会失效;
不在where后直接参与运算;
一条SQL的join不应该超过五条,否则可能会影响查询速度;
SQL的优化可以用解释计划去分析,主要看以下两列:
type 这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const(最好)、eq_reg、ref(标准)、range(最低要求)、indexhe和ALL
Extra 关于MYSQL如何解析查询的额外信息。这里如果出现Using filesort和Using temporary,就要优化了。前者是数据库需要进行额外的操作发现如何对返回的行排序,后者是MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上
9,能讲讲写SQL的时候的一些注意事项吗?
1,不要用*号,而是查什么字段就写什么字段;
2,用>=,<=代替>,<;
3,用exists代替in;
4,用union代替or;
5,>=,<=不直接写在XML文件中,而是用转义字符代替;
6,#和$的区别就是#能防止SQL注入,另一个则不能,常用语表名;
7,在XML中获取当前时间不能使用NOW(),而是传时间戳进来;
8,尽量不要用count(1)或count(字段)代替count(星号)去统计行数,因为count(1)或count(字段)不会统计字段为空的行,并且也不符合数据库范式
9,尽量不要joib超过3张表,并且joib的字段保证有索引
10,参与过秒杀系统的设计开发吗?能讲讲是怎么做的吗?
秒杀的步骤为:
1,验证时间;
2,输入验证码,这一步主要是时间换取空间,换取后台代码的执行时间;
3,用户点击按钮后,按钮变灰,主要是防止用户重复点击,也只能对‘小白’起作用,其中还有限制IP,限制账号,分析用户行为等等;
4,验证库存,秒杀成功后库存-1,其中使用的是乐观锁,主要不认为会产生数据的冲突,因为并发量没那么高(如果出现商品超卖,就使用redis自旋锁配合数据库的乐观锁);
5,用户秒杀成功后,但是五分钟内不付款,视为放弃放弃本次优惠,库存+1;
11,能讲讲多线程吗?
在多线程中,可能会出现并发和并行。
并行:真正意义上的同一时间,两个或两个以上的线程争夺资源;
并发:根据CPU的调度算法, 使得用户觉得是在同一时间出现了争夺资源,但其实不是同一时间。
线程的状态有两种sleep和wait。
sleep:不放弃资源,等到时间后会再次执行业务代码;
wait:完全放弃资源,除非被notify或者notifyAll重新给予资源才会执行业务代码。
实现线程的方式分为:继承Thread,实现Runnable或Callable接口。
Java中单一继承多实现,所以一般不会继承Thread;Runnable和Callable的区别则是Callable可以捕获到异常。
加锁可以使用:threadlocal或synchonized。
threadlocal解决数据的一致性问题,因为访问的是镜像副本,不是同一个数据源;synchonized解决数据的同步问题。
11,String,StringBuilder,StringBuffer的区别?
String的底层是数组结构,长度一旦确定不可改变,出现更改也是创建一个新的模型,然后把新的数据装进去,并且指针指向这个地址;
StringBuilder是线程不安全的容器,存储的数据超过了其默认的容器大小则会自动扩容;
StringBuffer与StringBuilder机制一样,但是StringBuffer是线程安全的容器;
12,你了解的线程安全的容器和线程不安全的容器有哪些?使用不安全的容器可能会出现什么问题?要怎么解决?
线程安全的容器:vector,HashTable,ConcurrentHashMap等
线程不安全的容器:ArrayList,HashMap,StringBuilder,LinkList等
使用不安全的容器例如:ArrayList,循环插入一百次记录,ArrayList可能会出现角标越界异常。可以通过Collections.synchronizedList(XXX)把它变成线程安全的容器。
13,Redis的数据类型有几种?
五种,分别是List,String,Set,SortSet,Hash。
14,有了解过memcache吗?它和Redis的区别在哪?
1,memcache只能存储KV结构的数据或音像文件,Redis除了KV数据还有上面说的五种可以存;
2,memcache必须设置数据的过期时间,但Redis对数据的过期时间不强制要求设置;
3,在容灾上memcache的数据丢了就没了,Redis可以主从复制
4,Redis可以持久化数据到本地文件里
15,Session和Cookies有什么区别?
Session的生命周期在访问JSP,Servlet等动态资源的时候创建,访问HTML,CSS等静态资源不会创建,除非强行创建;在关闭浏览器或当前窗口消失;服务器会定期清理掉不再活跃的Session,以tomcat为例是每30分钟清理一次;
Cookies默认的age为-1,可以修改持久化到本地文件,可以存数据。
16,系统报错,你是怎么查日志进行排查,能举例说明吗?
Linux系统下查询日志有tail查询实时日志,sed根据时间筛选日志。Jenkies在浏览器也可以查询实时日志,用以复现BUG。腾讯云的日志每一个只有100M大小,一天只有十个日志文件。根据公司的日志架构与BUG的复杂度决定采用什么方式去查日志,能复现的尽量复现,不能复现的查日志。让负责该业务的人员进行BUG的修改,或者协助其修改。
17,有了解分布式吗?
Zookeeper是一个分布式协调中心。
Dubbo是一个高性能,轻量级的JAVA的RPC框架,其核心分为三类,1:远程调用;2,智能容错和负载平衡;3,服务的注册与发现。Dubbo的服务调用分为,1,消费者直连生产者;2,服务注册到注册中心,消费者到注册中心请求获取服务,注册中心返回服务给消费者,监控中心则是监控时间段内的服务调用与提供次数等记录。
eureka是SpringCloud的注册中心,它有自己的容错机制,eureka不会移除掉未监听到心跳的服务,网络波动时返回最近的数据,网络恢复正常会获取最新的服务;Dubbo采取过半节点的选举方式容错。
18,能说说微服务与SpringMVC的区别吗?
SpringBoot具有内置的服务器,其加载方式为:加载所有的Class文件,如果有SpringMVC的JAVA文件,会加载SpringMVC的容器,当所有文件加载完成后,可以直接访问项目。
SpringMVC需要配置web.xml文件,要配置jsp等页面资源,但SpringBoot省略了这部分的配置,因为它是http+rest+API模式,更符合微服务的思想。
19,说几个你认识的集成SpringCloud时使用的插件?
Feign:动态代理,默认集成Ribbon,具有负载均衡;
Hystrix:断容器,主要是业务是由多个服务组成的时候,某个服务出现异常,为了防止‘雪崩’,servlet资源耗尽,会返回给用户一个fallBack;
Ribbon:负载均衡;
eureka:起到注册中心的作用;
Zuul:网关;
20,有了解过JDK8以上版本的某些特性吗?能说说?
Steam流,Lambada,LocalDateTime,List.of(),Map.forEach(),switch的新语法;
21,有了解过容器吗?比如Docker。
Docker主要由仓库,镜像,容器三部分组成;它们间的关系为,镜像可以pull获取到仓库的资源,push把镜像提交到仓库;镜像通过run或start创建容器(run是新建容器并启动,start是启动已有的但停止的容器),容器通过commit生成镜像。
FROM 命令说明镜像来源于哪里;
run rm -rf 命令删除容器;
copy 命令把某位置的文件拷贝到哪里;
还有一些其他常用的命令,如docker image,docker ps ,docker log 等等
执行多段命令可以使用DockerFile,DockerFile需要去掉文件后缀。
22,有了解数据库的主从复制吗?怎么做到读写分离?
一般来说,对数据的修改在主库,读在从库;其原理大致为:数据在主库发生更改,会有binlog记录本次的操作,当从库知道主库更改了数据,会从binlog拿到这次操作的记录并进行同样的操作,所以,每次当主库发生了数据的更改,从库也会同步进行更改。
23,说说类加载机制?
类加载的顺序是:
加载–>验证–>准备–>解析–>初始化–>使用–>销毁
分别对应:
1,把JAVA文件加载成二进制数据;
2,验证文件的正确性和完整性;
3,为静态变量分配内存;
4,对符号进行转义;
5,初始化类,由ClassLoader及其子类完成;
6,使用这个类;
7,GC
24,String的equals是怎么实现的?
先跟自己比–>再比较类型(是不是String类型)–>再比较长度–>再比较字节;
25,UDP和TCP的区别?
TCP:安全,建立请求需要三次握手,断开要四次,速度慢,常用于视频,下载等;
UDP:不安全,不需要握手,速度快,常用于发送图片,文字等。
26,XML可以直接写>=或者<=吗?
最好不要(其实是强制)在XML的SQL中写>=或者<=或者&,要使用转义字符
27,对象的引用有几个级别?
按照生命周期从强到弱,分别为:强引用、软引用、弱引用、虚引用。
强引用对象哪怕JVM内存溢出都不会被JVM回收;
软引用对象会在内存不足时被回收,所以常用于缓存;
弱引用对像会在JVM垃圾回收被回收,也可以用来做缓存;
虚引用对像被回收时间未知,生存时间也未知,所以用途也是未知。
28,JVM的内存模型有什么?
共有五种,堆、栈、方法区、程序计数器、本地方法栈
它们的作用分别是:
堆:用来存储对象本身以及数组(数组引用是存放在Java栈中的)。堆是被所有线程共享的,在JVM中只有一个堆。
栈:Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法。
方法区:与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息、静态变量、常量以及编译器编译后的代码等。
程序计数器:保证程序的正常执行次序
本地方法栈:与栈类似,区别是栈为执行Java方法服务的,而本地方法栈则是为执行本地方法服务的
29,JVM的内存区域有几个?
新域、旧域、永久域
新域:刚创建对象时,其所处的区域;
旧域:被一次引用后,继续被使用,没有被GC的对像所处的区域;
永久域:固定大小,初始为4M;运行程序时,会动态调整大小以满足需求,每次调整,JVM会对堆进行一次完全的垃圾收集。
30,为什么要将变量分配合理的作用域?
为了能够更好的进行GC
31,什么是缓存的穿透,击穿,雪崩?遇到这三种情况要怎么解决?
缓存穿透的场景就是,某个用户用id=-1或请求一个不存在的缓存。
解决办法是:
1、对于id<=0的请求直接拦截;
2、对不存在的缓存可以设置一个其值等于null,然后过期时间设置30秒。
缓存击穿的场景就是,缓存中没有数据,但是数据库有数据,这时候并发又特别多,从而请求数据库,导致数据库压力过大,出现这种情况,一般都是缓存中数据过期。
解决办法是:
1、对热点数据设置不过期时间
2、加一个互斥锁,如果缓存中没有数据,请求数据库时,其他请求要进行等待,等待缓存写入后再继续获取数据。
缓存雪崩的场景就是,某个时间段内,大批缓存失效了,是因为,这些缓存都设置同一个过期时间,到期后,缓存统一失效,大量请求直接请求数据库,导致数据库压力过大。
解决办法是:
1、对缓存数据设置随机的过期时间,避免同一时间大批量缓存过期;
2、如果数据库是分布式部署,就把热点数据均匀地分布在不同的数据库;
3、设置热点数据永不过期
32,你用的SpringCloud是什么版本的?
Finchley版本
33,怎么处理消息丢失的问题?
如果是RabbitMQ,生产者开启confirm模式,开启RabbitMQ持久化,关闭RabbitMQ的自动ack
如果是kafka,设置ack=all,要求是,你的 leader 接收到消息,所有的 follower 都同步到了消息之后,才认为本次写成功了。如果没满足这个条件,生产者会自动不断的重试,重试无限次。
34,如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?
主要是保证多条请求进来只处理一条请求即可,可以考虑选择互斥锁,例如redis就是天然的幂等;
35,如何保证消息的顺序执行?
只要你能保证一个队列只被一个消费者消费,自然就可以保证消息的顺序性
36,如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时怎么解决?
临时将queue资源和consumer资源扩大10倍,以正常的10倍速度来消费数据。等快速消费完积压数据之后,得恢复原先部署架构
如果是因为消息积压导致的消息过期,例如RabbitMQ设置了过期时间。那么,就只能够写个程序把这些数据重新查询出来再写入到mq里去消费。
37,RabbitMQ有几个重要角色?
三个,生产者,消费者,代理。
生产者是消息的创建者,负责创建和推送消息到消息服务器;
消费者是消息的接收方,负责处理数据和接收消息;
代理是RabbitMQ本身,只负责扮演快递的角色,本身不负责生产消息
38,RabbitMQ有哪些重要的组件?
ConnectionFactory(链接管理器):应用程序与RabbitMQ建立链接的管理器,程序代码中使用
Channel(信道):消息推送使用的通道
Exchange(交换器):用于接收,分配消息
Queue(队列):用于存储生产者的消息
RoutingKey(路由键):用于把生产者的数据分配到交换器上
BindingKey(绑定键):用于把交换器的信息绑定到队列上
39,RabbitMQ 有几种广播类型?
三种,分别是:
fanout:广播,绑定到RabbitMQ的接收者都能接收到消息
direct:通过RoutingKey和Exchange决定唯一的Queue可以接收消息
topic:所有符合表达式的RoutingKey所bind的Queue可以接收消息
40,Kafka 可以脱离 zookeeper 单独使用吗?为什么?
kafka 不能脱离 zookeeper 单独使用,因为 kafka 使用 zookeeper 管理和协调 kafka 的节点服务器。
41,Kafka 有几种数据保留的策略?
kafka 有两种数据保存策略:
1,按照过期时间保留
2,按照存储的消息大小保留
42,Kafka 的分区策略有哪些?
1,给定了分区号,直接将数据发送到指定的分区里面去
2,没有给定分区号,给定数据的key值,通过key取上hashCode进行分区
3,既没有给定分区号,也没有给定key值,直接轮循进行分区
4,自定义分区
43,@Transactional默认对所有异常回滚吗?
不是。它默认仅对RuntimeException和Error发生回滚,加上rollbackFor=Exception.class,可以让事物在遇到非运行时异常时也回滚
44,list,set,map区别?
1、List、Set都是继承自Collection接口,Map则不是
2、List特点:和数组类似,List可以动态增长,查询快,增删慢,因为会引起其他元素位置改变。 元素有放入顺序,可重复 ,Set特点:查询慢,增删快,增删不会引起元素位置改变。 元素无放入顺序,不可重复,重复元素会覆盖掉
3、Map适合储存键值对的数据
45,ArrayList和LinkedList的大致区别?
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作,LinedList优于ArrayList,因为ArrayList要移动数据。
46,什么是反射?
本质是JVM得到class对象之后进行反编译,从而获取对象的各种信息。
优点:在运行时获得类的各种内容,能够让我们很方便的创建灵活的代码。
缺点:反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;
反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
47,动态代理和静态代理的区别?
静态代理只能针对对应的类进行代理,如果类很多就需要很多的代理。 动态代理就是弥补了静态代理的这个缺陷。动态生成一个持有RealObject、并实现代理接口的Proxy,同时注入我们相同的扩展逻辑。哪怕你要代理的RealObject是不同的对象,甚至代理不同的方法,都可以动过动态代理,来扩展功能。
48,spring怎么解决循环依赖?
假设A依赖B,B依赖A(注意:这里是set属性依赖)分以下步骤执行:
1、A依次执行doGetBean、查询缓存、createBean创建实例,实例化完成放入三级缓存singletonFactories中,接着执行populateBean方法装配属性,但是发现有一个属性是B的对象。
2、因此再次调用doGetBean方法创建B的实例,依次执行doGetBean、查询缓存、createBean创建实例,实例化完成之后放入三级缓存singletonFactories中,执行populateBean装配属性,但是此时发现有一个属性是A对象。
3、因此再次调用doGetBean创建A的实例,但是执行到getSingleton查询缓存的时候,从三级缓存中查询到了A的实例(早期引用,未完成属性装配),此时直接返回A,不用执行后续的流程创建A了,那么B就完成了属性装配,此时是一个完整的对象放入到一级缓存singletonObjects中。
4、B创建完成了,则A自然完成了属性装配,也创建完成放入了一级缓存singletonObjects中。
5、Spring三级缓存的应用完美的解决了循环依赖的问题
49,throw 和 throws 的区别?
throw会把异常抛出,而throws只会把异常向上传,而不会处理
50,final、finally、finalize 有什么区别?
final:可以用来修饰类,变量,方法。修饰类:该类不能被继承,修饰方法:该方法不能重写,修饰变量:表明该变量是一个常量,不能重新赋值
finally:用于try-catch,不管有没有捕获到异常,最后必定会执行的代码,一般用于关闭资源。
finalize :是一个方法,当我们调用System的gc()方法的时候,由垃圾回收器调用finalize(),回收垃圾。
51,try-catch-finally 中哪个部分可以省略?
catch 可以省略
52,try-catch-finally,如果 catch 中 return 了,finally 还会执行吗?
会执行,会在return前执行
53,jsp 和 servlet 有什么区别?
1,jsp经编译后就变成了Servlet
2,jsp更擅长表现于页面显示,servlet更擅长于逻辑控制。
3,Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到。
54,说一下 jsp 的 4 种作用域?
分别是page,request,session,application
pgae:当前页的对象和属性
request:当前请求的对象和属性
session:当前会话的对像和属性
application:整个web客户端的对像和属性
55,如果客户端禁止 cookie 能实现 session 还能用吗?
不能,因为session是通过sessionID去判断对应的服务器,而sessionID存放在cookie中,所以如果cookie被禁用,获取不到sessionID,那么session也不能使用。
56,spring mvc 和 struts 的区别是什么?
1,拦截机制的不同。struts 是类拦截机制,而springmvc是方法级别的拦截机制。
2,底层框架的不同。struts是基于filter,springmvc基于Servlet。
3,性能方面springmvc优于struts,因为struts类拦截机制,所以每次请求都要获取一个新的aciton,而springmvc基于方法拦截,只要加载一次单例bean。
4,springmvc是基于spring的,安全性上比struts要高。
57,spring 常用的注入方式有哪些?
1,构造方法注入
2,setter注入
3,基于注解的注入
58,spring 自动装配 bean 有哪些方式?
1,隐式的bean发现机制和自动装配
2,在java代码或者XML中进行显示配置
59,说一下 jvm 有哪些垃圾回收算法?
标记-清除算法
标记-整理算法
复制算法
分代算法
60,拦截器和过滤器的区别?
拦截器基于函数回调,过滤器基于反射;拦截器依赖servlet,过滤器不依赖servlet;拦截器拦截所有请求,过滤器只针对action请求。
61, 什么是死锁?
两个或两个以上的进程,因为互相竞争资源,而导致的阻塞现象,若无外力因素,它们将无法推进下去。
62, 怎么避免死锁?
满足死锁的四大条件,分别有:
互斥条件:进程对所分配到的资源不允许其他进程进行访问,若其他进程访问该资源,只能等待,直至占有该资源的进程使用完成后释放该资源
请求和保持条件:进程获得一定的资源之后,又对其他资源发出请求,但是该资源可能被其他进程占有,此事请求阻塞,但又对自己获得的资源保持不放
不可剥夺条件:是指进程已获得的资源,在未完成使用之前,不可被剥夺,只能在使用完后自己释放
环路等待条件:是指进程发生死锁后,若干进程之间形成一种头尾相接的循环等待资源关系
只要不满足以上其中任何一个条件,都不会出现死锁。
63,怎么创建线程池
第一:配置核心线程数,这是线程池初始化的线程数量
第二:配置缓冲队列,这是核心线程数满了后使用的线程数量
第三:配置最大线程数,这是缓冲队列满了后使用的线程数量
第四:配置允许的线程空闲时间
第五:配置线程池前缀
第六:配置线程池满了后的拒绝策略
64,线程池的拒绝策略有哪几种
有四种,分别是:
1、默认的,什么都不处理
2、会跑出一个异常
3、会直接执行提交的任务
4、会把队列中最老的任务丢弃,然后执行提交的任务
持续更新中…
最后:祝大家开开心心每一天
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/156218.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...