Java面试题
1.redis key删除策略
定期删除:贪心策略
1.从过期字典中随机 20 个 key;
2.删除这 20 个 key 中已经过期的 key;
3.如果过期的 key 比率超过 1/4,那就重复步骤 1;
惰性删除:
在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。
定期删除是集中处理,惰性删除是零散处理。
3.es 为什么这么快,分词的原理,分页优化
4.配置加载顺序优先级
bootstrap.yml在项目启动时,就会加载
application.yml在springContext加载后进行加载
5.springboot常用注解
@SpringBootApplication 包含 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
@ImportResource @Scope @Primary @Lazy @Profile
6.数据库数据发生变化,如何同步给Redis
方案1:直接删除Redis缓存;
方案2: 基于MQ异步同步更新
方案3: 基于canal订阅binlog同步
7.项目高并发解决方案
非垂直拆分,水平拆分
垂直拆分的话就是,增加服务器节点,消耗成本,升级CPU
水平拆分的话包括
前端页面静态化
缓存:浏览器缓存 -> CDN加速 -> Nginx动静分离,Nginx缓存 -> Redis缓存 -> DB
应用拆分,分布式开发,业务拆分
数据库拆分:垂直拆分和水平拆分
数据库连接池、Redis连接池、线程池、消息队列
采用数据搜索引擎
JVM参数优化
8.秒杀项目会有的问题
1.商品超卖
2.高并发
页面优化,线程池、mq、信号量限制
3.重复下单
4.秒杀地址暴露
5.分布式事务
9.数据库系统的负载均衡
多主、一主一从、一主多从、多级主从
10.项目并发量,多线程的应用场景
高并发系统的本质就是充分利用硬件资源,提升cpu
11.mysql 分库分表利弊
多主、一主一从、一主多从、多级主从
缺点:
分布式事务、
关联查询 join、排序、函数 问题、
分布式ID问题、
数据迁移、扩容问题
12.你们项?如何排查JVM问题
对于还在正常运?的系统:
1.可以使?jmap来查看JVM中各个区域的使?情况
2.可以通过jstack来查看线程的运?情况,?如哪些线程阻塞、 是否出现了死锁
3.可以通过jstat命令来查看垃圾回收的情况,特别是fullgc,如果发现fullgc?较频繁,那么就得进?调优了
4.通过各个命令的结果,或者jvisualvm等?具来进?分析
5.?先,初步猜测频繁发送fullgc的原因,如果频繁发?fullgc但是??直没有出现内存溢出,那么表示fullgc实际上是回收了很多对象了,所以这些对象最好能在younggc过程中就直接回收掉,避免这些对 象进?到?年代,对于这种情况,就要考虑这些存活时间不?的对象是不是?较?,导致年轻代放不 下,直接进?到了?年代,尝试加?年轻代的??,如果改完之后,fullgc减少,则证明修改有效
6.同时,还可以找到占?CPU最多的线程,定位到具体的?法,优化这个?法的执?,看是否能避免某些 对象的创建,从?节省内存
13.对于已经发?了OOM的系统:
1.?般?产系统中都会设置当系统发?了OOM时,?成当时的dump?件(- XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/base)
2.我们可以利?jsisualvm等?具来分析dump?件
3.根据dump?件找到异常的实例对象,和异常的线程(占?CPU?),定位到具体的代码
4.然后再进?详细的分析和调试
总之,调优不是?蹴?就的,需要分析、 推理、 实践、 总结、 再分析,最终定位到具体的问题
14.Java死锁如何避免?
造成死锁的?个原因:
1.?个资源每次只能被?个线程使?
2.?个线程在等待时,不释放已占有资源
3.?个线程已经获得的资源,在未使?完之前,不能被强?剥夺
4.若?线程形成头尾相接的循环等待资源关系
这是造成死锁必须要达到的4个条件,如果要避免死锁,只需要不满?其中某?个条件即可。 ?其中前3个条件是作为锁要符合的条件,所以要避免死锁就需要打破第4个条件,不出现循环等待锁的关系。
在开发过程中:
1.要注意加锁顺序,保证每个线程按同样的顺序进?加锁
2.要注意加锁时限,可以针对所设置?个超时时间
3.要注意死锁检查,这是?种预防机制,确保在第?时间发现死锁并进?解决
15.消息队列如何保证消息可靠传输
消息可靠传输代表了两层意思,既不能多也不能少。
1.为了保证消息不能多,也就是消息不能重复
a.?先要确保消息不多发,这个不常出现,也?较难控制,因为如果出现了多发,很?的原因是?产 者??的原因,如果要避免出现问题,就需要在消费端做控制
b.要避免不重复消费,最保险的机制就是消费者实现幂等性,保证就算重复消费,也不会有问题,通 过幂等性,也能解决?产者重复发送消息的问题
2.消息不能少,意思就是消息不能丢失
a.?产者发送消息时,要确认消息投递成功,?如RabbitMQ的transaction机制和confirm机制,Kafka的ack机制都可以保证?产者能正确的将消息发送给broker
b.broker:确认broker确实收到并持久化了这条消息,将队列的持久化标识durable设置为true
c.消费端手动ack机制,消费者接收到?条消息后,如果确认没问题了,就可以给broker发送?个ack,broker接收到ack后才会删除消息
16.消息堆积的解决方案
1、消息发送的速率远远大于消息消费的速率。
通过关闭某些不重要的业务,减少发送的数据量
2、消费者出现了问题,导致无法消费。
a.先修改consumer的问题,确保其恢复消费速度
b.临时启用多个消费者,通过扩容消费端的实例数来提升总体的消费能力。
c.消费者参数优化,在初始化的时候提高并发消费者的个数
17.合适的线程数量是多少?CPU 核心数和线程数的关系?
线程数 = CPU 核心数 *(1+平均等待时间/平均工作时间)
18. 如何让你来设计消息队列中间件,如何设计?
1、MQ得支持可伸缩性
2、就是需要的时候增加吞吐量和容量?
3、考虑MQ的数据持久化
4、考虑MQ的可用性。
19. 如何保证消息的顺序性
a. 使用单线程消费来保证消息的顺序性,保证生产者 - MQServer - 消费者是一对一对一的关系
b. 对消息进行编号,消费者处理时根据编号来判断顺序
20. 什么是沾包拆包
TCP以流方式传输,是没有界限的一串数据,并没有消息边界。
- TCP传输数据时,会根据底层的TCP缓存区实际情况进行数据包划分:
- 1.业务上定义的完整数据(比方说一个完整的json串),可能会被TCP拆分成多个数据包进行发送(拆包)。
- 2.业务上特殊含义的独立数据,也有可能因为大小或者缓冲区原因,被TCP封装成一个大数据包发送(粘包)。
21. 怎么解决沾包拆包问题
1.在发送端每个数据包首部添加数据包长度字段,在接收端接收到消息后,通过读取首部的长度字段,便可知道数据包的实际长度了
2.发送端的每个数据包封装为固定长度(不够的部分补0填充),这样接收端就自然而然的把每个数据包拆分开
3.设置数据包之间的边界,如设置特殊符号
22. 一般不建议使用System.gc,为什么还要有这个方法
一般不建议使用system.gc()去显示地要求进行垃圾回收,一般每一次显示的调用system.gc()都会进行一次full gc,而full gc会导致应用的暂停,如果频繁地full gc会导致应用长时间暂停,也就无法正常运行了。
23. mysql数据库删除重复的数据保留一条
解答一:
delete from Person where Id not in (
select t.min_id from ( select min(Id) as min_id from Person group by Email) as t );
解答二:
delete p1 from Person as p1,Person as p2 where p1.Email=p2.Email and p1.Id > p2.Id;