一些面试知识点整理
浏览量 732
1.倒排索引与正排索引区别
正排索引: 由文档指向关键词
文档--> 单词1 ,单词2
倒排索引:关键词通过分词器分词指向文档
单词1--->文档1,文档2,文档3
单词2--->文档1,文档2
lucene知识点整理
2.覆盖索引为什么检索快
不需要回表操作
什么回表?
1)先扫描name索引树,找到主键值id=5。
2)再扫描主键索引,找到对应行。
这就是“回表查询”,先定位主键值,再通过主键值定位行记录,性能上较之直接查询索引树定位行记录更慢
什么是覆盖索引?
1)只需要在一棵索引树上就可以获取sql所需所有的列数据,不需要回表,较之回表速度要更快
2)explain输出结果extra字段为Using index时,触发了索引覆盖
mysql的一些技术名词
3.聚集索引与非聚集索引的区别
_1 聚集索引(聚簇索引,Innodb):叶子节点存放完整的数据
_2 非聚集索引(Mylsam):叶子节点存放是主键
4.mysql为什么选择b+tree
_1 由于在叶子节点的链表结构使得b+树更好支持范围查找
_2 由于b+树的所有数据都只存放在叶子节点,使得查询数据的时候,读取次数更稳定
_3 由于mysql单独一个存储片大小是固定,使用b+树让目录节点上没有真实数据可以存放
更多的叶子节点连接,降低树的高度,减少访问次数
B+树 与 B树 索引
B树与红黑树,为什么数据库使用B树索引
5.springboot与springmvc区别
_1 基于Spring4的条件注册的一套快速开发整合包;
_2 springmvc基于servlet的mvc框架
6.MQ遇到的问题以及解决方案
_1 保证消息的顺序性:
将消息放入同一个交换机,交给同一个队列,这个队列只有一个消费者,消费者只允许同时开启一个线程
_2 消息积压:
消息积压的mq的消息,写一个应用程序迁移到3个mq,每个mq对应的消费者去消费。
针对过期消息,过期后转入死信队列,写一个程序处理死信消息(重新如队列或者即使处理或记录到数据库延后处理)
_3 保证消息不重复消费
__1 每个消息用一个唯一标识来区分,消费前先判断标识有没有被消费过,若已消费过,则直接ACK
_4 保证消息可靠性
__1 开启事务(不推荐)
__2 开启confirm(推荐)
__3 开启RabbitMQ持久化(交换机、队列、消息)
__4 关闭RabbitMQ自动ack(改成手动)
_5 RabbitMQ死信队列
死信队列是当消息在一个队列因为下列原因
__1 消息被拒绝(basic.reject或basic.nack)并且requeue=false.
__2 消息TTL过期
__3 队列达到最大长度(队列满了,数据无法添加到mq中)变成了 “死信队列” 后被重新投递(publish)到另一个Exchange,然后重新消费。说白了就是没有被消费的消息换个地方重新被消费
7.elasticsearch脑裂的问题
_1 什么是脑裂:
由于各种问题导致出现两个以上的master节点
_2 怎么造成:
__1.网络延迟
__2.节点负载
_3 怎么发现 :
__1 查询非常缓慢
__2 集群状态异常
_4 怎么解决:
__1 对于网络问题,只能进行网络修复,在重启集群
__2 对于负载的问题.一个直观的解决方案就是将master节点与data节点分离,准备几台机器加入集群中,这几台机器只能充当master节点,不可担任存储和搜索的角色
_5 怎么避免脑裂:
__1 discovery.zen.ping_timeout:默认情况下,一个节点会认为,如果master节点在3秒之内没有应答,那么这个节点就是死掉了,而增加这个值,会增加节点等待响应的时间,从一定程度上会减少误判
__2 discovery.zen.minimum_master_nodes:作用是只有足够的master候选节点时,才可以选举出一个master。官方的推荐值是(N/2)+1,其中N是具有master资格的节点的数量
Elasticsearch知识点整理
8.elasticsearch深度分页解决方案
_1 es 默认采用的分页方式是 from+ size 的形式,在深度分页的情况下,这种使用方式效率是非常低的,比如执行如下查询:
GET /student/student/_search
{
"query":{
"match_all": {}
},
"from":5000,
"size":10
}
意味着 es 需要在各个分片上匹配排序并得到5010条数据,协调节点拿到这些数据再进行排序等处理,然后结果集中取最后10条数据返回
es为了性能,限制分页的深度,es目前支持的最大的 max_result_window = 10000;也就是说不能分页到10000条数据以上
_2 scroll 无法反应数据的实时性(快照版本)维护成本高,需要维护一个 scroll_id
执行如下curl,每次请求两条。可以定制 scroll = 5m意味着该窗口过期时间为5分钟。
在返回结果中,有一个很重要的
_scroll_id
在后面的请求中都要带着这个 scroll_id 去请求。
现在student这个索引中共有6条数据,id分别为 1, 2, 3, 4, 5, 6。
当使用 scroll 查询第4次的时候,返回结果应该为空。这时就知道已经结果集已经匹配完了。
_3 search_after 性能最好 能够反映数据的实时问题
为了找到每一页最后一条数据,每个文档必须有一个全局唯一值,官方推荐使用 _uid 作为全局唯一值,但是只要能表示其唯一性就可以。
结果集
下一次分页,需要将上述分页结果集的最后一条数据的值带上。
9.深复制与浅复制的区别
浅拷贝(Shallow Copy)
①对于数据类型是基本数据类型的成员变量,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据。
②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。
因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值
深拷贝:首先介绍 对象图 的概念
一个类有一个对象,其成员变量中又有一个对象,该对象指向另一个对象,另一个对象又指向另一个对象,直到一个确定的实例。这就形成了对象图。
那么,对于深拷贝来说,不仅要复制对象的所有基本数据类型的成员变量值,还要为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。
也就是说,对象进行深拷贝要对整个对象图进行拷贝!
深拷贝对引用数据类型的成员变量的对象图中所有的对象都开辟了内存空间;而浅拷贝只是传递地址指向,新的对象并没有对引用数据类型创建内存空间。
10.mysql到elasticsearch实时增量同步
介绍
1)已验证:仅支持增量同步,不支持全量已有数据同步。这点,canal的初衷订位就是“mysql数据库binlog的增量订阅&消费组件”。
2)已验证:由于采用了binlog机制,Mysql中的新增、更新、删除操作,对应的Elasticsearch都能实时新增、更新、删除。
canal适用于对于Mysql和Elasticsearch数据实时增、删、改要求高的业务场景。
实时场景要求不高的业务场景,logstash_input_jdbc也能满足
运行原理:
Canal模拟MySQL的slave的交互协议,伪装成mysql slave,并将转发协议发送到MySQL Master服务器。
MySQL Master接收到转储请求并开始将二进制日志推送到slave(即canal)
Canal将二进制日志对象解析为自己的数据类型(原始字节流)
11.在mysql中,三个字段A、B、C的联合索引,查询条件B、A、C,会用到索引吗
会走索引,mysql优化器会把BAC优化成ABC
12.mybatis与mybatisplus区别
单表的增删改查都不需要写XML了,而且Mybatis-Plus提供的BaseMapper是可以支持各类关系型数据库使用的
14.aop的理解
切面编程,原有的功能基础上进行扩展新的功能。
传统oop开发代码逻辑之上而下的,这个过程中会产生一些横切性问题,这些问题与主业务逻辑关系不大,会散落在代码的各个地方,造成难以维护,
aop思想就是把业务逻辑与横切的问题进行分离,达到解耦的目的
15.spring aop的原理
_1 @EnableAspectJAutoProxy给容器(beanFactory)中注册一个AnnotationAwareAspectJAutoProxyCreator对象;
_2 AnnotationAwareAspectJAutoProxyCreator是一个后置处理器,在目标对象初始化完后,利用BeanPostProcessor后置通知的机制,完成对目标对对象象的AOP对象创建,内部,是封装JDK和CGlib两个技术,实现动态代理对象创建的;
_3 代理对象执行目标方法,得到目标方法的拦截器链,利用拦截器的链式机制,依次进入每一个拦截器进行执行
16.mybatis mapper接口方法为什么不能重载
mybatis动态代理寻找策略是 全限定名+方法名。不涉及参数。所以不支持重载
17.mybatis的原理
一级缓存:
_1 sqlsession
_2 执行了任何一个update操作(update()、delete()、insert()) 、sqlsession.close()、sqlSession.clearCache()缓存都会失效
_3 默认开启
二级缓存:
_1 application
_2 执行了任何一个update操作(update()、delete()、insert()) 缓存都会失效
_2 默认不开启
禁用 MyBatis 一级缓存
一级缓存默认开启,session 级别
禁用一级缓存,设置为 statement 级别
< setting name="localCacheScope" value="SESSION"/>
mybatis:
configuration:
// 一级缓存 session statement
local-cache-scope: session
// 二级缓存
cache-enabled: false
if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
clearLocalCache();
}
18.mysql 优化
_1 数据库服务器内核优化
_2 my.cnf配置,搭配压力测试进行调试
_3 sql语句优化
__1 使用缓存优化查询(进行多次相同的查询,结果就会放入缓存中,后续再进行同样的查询,就直接从缓存中提取,不会表中提取)
__2 explain执行计划检测SQL查询
__3 给搜索字段建立索引 where后面的字段建立索引(聚集索引和非聚集索引的查询原理)大数据量的查询不合适
__4 limit 1 (前提该字段没有建立索引,明确只有一行数据的时候。只要找到了对应的一条记录,就不会继续向下扫描了,效率会大大提高)
__5 永久连接 (在一些极端环境中,apache 会发出http请求,创建子进程去请求数据库)
__6 选择正确的数据库引擎 myisam 和 innodb
__7 在进行大量的delete、insert拆分 limit进行优化
__8 数据类型 尽量使用小的
__9 固定字段长度 有利于mysql计算数据的偏移量
__10 尽量不要给null 设置‘ ’
__11 明确固定的字段上使用enum(性别、国家、市)
__12 id 主键每张表都要建立
__13 避免使用select * (查询越多,速度越慢,数据多对网络的传输也会负载过重)
__14 rand() 计算在cpu上面进行
__15 join 尽量保持两个字段的类型一致
__16 垂直分割 将表的按列的形式分割成表
19.mysql优化器在选择索引时,主要会考虑哪些因素
扫描的行数:扫描的行数越少,就证明访问磁盘数据的次数越少,消耗的 CPU 资源就越少。
有没有涉及到临时表
排序
关于扫描行数的确定
计算索引的基数
20.事务的基本要素
_1 原子性 :事务开始的所有操作是一个整体
_2 一致性:事务开始和结束后,数据是完整性没有被破坏
_3 隔离性:不同事务互不干扰
_4持久性:事务完成后,事务对数据所有的更新将被保存到数据库
21.事务隔离级别
_1 读未提交 脏读
_2 读已提交 不可重复读
_3 可重复读 幻读 MVCC只解决查询的幻读,next-key-lock解决当前读的幻读
_4 串行化
22.内存溢出生产环境怎么定位
23.双亲委派机制设计有什么好处
_1 避免类的重复加载
_2 避免了java的核心API被篡改
24.redis常见问题
_1 mysql与redis数据一致性问题
__1 延迟双删
__2 分布式锁
__3 利用binlog变动触发缓存更新
_2 高并发场景出现的问题
__1 雪崩
key大面积失效
解决方案:分布式锁、key失效时间随机
__2 击穿
针对某一热点key失效
解决方案:key不过期、分布式锁
__3 穿透
不存在数据攻击
解决方案:布隆过滤器、接口校验、key的value值设置null
25.redis的数据类型以及各个应用场景
_1 list
__1 常用命令 :lpush(添加左边元素),rpush,lpop(移除左边第一个元素),rpop,lrange(获取列表片段,LRANGE key start stop)等
__2 应用场景:twitter的关注列表,粉丝列表等
_2 set
在微博中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能
_3 hash
__1 常用命令:hget hset hgetall
__2 应用场景:用来存储对象信息
_4 zset
__1 实现方式:Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,跳跃表按score从小到大保存所有集合元素
__2 应用场景:排行榜
_5 string
__1微博数、粉丝数
26.mysql幻读的解决方案
_1 next-lock-key
_2 MVCC(多版本并发控制)
27.描述一下hashmap底层原理,它是在什么时机进行扩容的
_1 jdk 1.8原理 hashmap
_2 扩容条件是元素的数量大于16*0.75阈值且table[index]!=null,它是 在添加元素的时机去判断扩容条件进行扩容的
树化条件:链表节点个数8个以上,数组长度小于64,进行扩容。数组长度大于或等于64,进行树化
28.模糊查询的索引会失效吗,某个业务场景一定要用like %xx%进行查询有什么解决方案吗
_1 覆盖索引
29.事务失效
_1 同类A方法没加@transaction,B方法加了@transaction。A方法调用B方法,B的事务会失效
_2 方法不是public修饰事务失效
_3 方法被final、static修饰事务失效
_4 方法内部异常被捕获事务失效
30.Executors创建线程池有哪些
_1 newScheduledThreadPool
_2 newCachedThreadPool
_3 newFixedThreadPool
_4 newSingleThreadExecutor
31.线程池拒绝策略有哪些
__1 CallerRunsPolicy
该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。
__2 AbortPolicy
该策略下,直接丢弃任务,并抛出RejectedExecutionException异常。
__3 DiscardPolicy
该策略下,直接丢弃任务,什么都不做。
__4 DiscardOldestPolicy
该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列
32.自定义线程池的参数有哪些
_1 corePoolSize 线程池核心线程大小
_2 maximumPoolSize 线程池最大线程数量
_3 keepAliveTime 空闲线程存活时间
_4 unit 空闲线程存活时间单位
_5 workQueue 工作队列
_6 threadFactory 线程工厂(创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等)
_7 handler 拒绝策略
33.==与equals有什么区别
34.抽象类与接口有什么区别
35.spring怎么解决循环依赖问题
36.构造器注入能解决spring循环依赖吗
_1 部分解决
37.spring boot自动装配的原理
https://www.cnblogs.com/leihuazhe/p/7743479.html
38.spring的生命周期
39.jdk8的新特性
_1 Lambda表达式
_2 函数式接口
_3 方法引用和构造器调用
_4 Stream API
_5 接口中的默认方法和静态方法
_6 新时间日期API
40.Integer a=150,b=150. a==b 输入什么
小于128的值都是缓存获取 true 否则就是false
41.可重复读和提交读底层怎么实现的
_1 MVCC(多版本并发控制)
_2 原理:
__1 可重复读 :都引用第一次查询生成readview (一致性试图) 与undo日志的版本链的事务id进行比对
__2 提交读: 每次查询生成独立readview(一致性试图)
43.mysql存储引擎有哪些
_1 myisam
_2 innodb
44.myisam与innodb的有什么区别
_1 InnoDB 支持事务,MyISAM 不支持事务
_2 InnoDB 支持外键,而 MyISAM 不支持
_3 InnoDB 是聚集索引,MyISAM 是非聚集索引。
聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。
但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。
而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的
_4 InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。而MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快
_5 InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一
45.mysql怎么查看索引失效
explain执行计划
46.explain执行计划有哪些参数
https://blog.csdn.net/qq_16268979/article/details/106652565
48.spi会破坏双亲委派模型吗?为什么会破坏
https://www.jianshu.com/p/9cf306550b0a
49.不同阻塞队列对线程池带来的哪些影响
50.springmvc原理
_1 用户发送请求至前端控制器DispatcherServlet。
_2 DispatcherServlet收到请求调用HandlerMapping处理器映射器。
_3 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
_4 DispatcherServlet调用HandlerAdapter处理器适配器。
_5 HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
_6 Controller执行完成返回ModelAndView。
_7 HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。
_8 DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
_9 ViewReslover解析后返回具体View。
_10 DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
_11 DispatcherServlet响应用户。
51.怎么让jwt主动失效
52.synchronized做了哪些优化
_1 无锁->偏向锁->轻量级锁->自旋锁->重量级锁
_2 对象的内存布局
__1 对象头
__2 实例数据
__3 对齐填充
53.synchronize与lock有哪些区别
54.并行与并发的区别
55.线程的创建方式
_1 callable和future
_2 thread
_3 runnable
_4 线程池
56.有哪些设计模式以及你在实际项目的运用到哪些
57.ArrayList与LinkedList的区别
58.ConcurrentHashMap的底层实现
59.spring security底层是怎么进行认证的
60.redis持久方式
_1 aof
_2 rdb
_3 混合
61.redis主从是怎么同步数据的
_1 全量同步
_2 增量同步
62.volatile有什么特性
63.怎么解决接口的dos攻击
64.怎么解决接口的幂等性问题
65.aop实际的应用场景
66.tcp与udp的区别
67.双亲委派机制
68.3个线程依次打印ABCABC20遍,怎么实现
69.每科学科成绩大于80的学生信息
70.elasticsearch聚合出现数据偏差的问题
https://blog.51cto.com/u_15050720/2562395
71.elasticsearch聚合性能优化
深度优先修改为广度优先
集合策略:1.深度优化:先构建完整的树,然后修剪无用节点 2.广度优化:执行第一层聚合,下一层聚合之前会先做修剪
72.redis内存淘汰策略
1.noeviction 不删除策略,达到最大内存限制时,如果需要内存,直接返回错误信息
2.allkeys_lru 所有key通用; 优先删除最近最少使用(less recently used ,LRU) 的 key
3.只限于设置了 expire 的部分; 优先删除最近最少使用(less recently used ,LRU) 的 key。
4.volatile-random: 只限于设置了 expire 的部分; 随机删除一部分 key
5.volatile-ttl: 只限于设置了 expire 的部分; 优先删除剩余时间(time to live,TTL) 短的key。
73.JAVA 复制对象时为什么要用克隆clone()而不用“=”的原因
74.redis过期策略内存淘汰机制
_1 定期删除和惰性删除
_2 6种内存淘汰机制
75 垃圾收集器
_1 serial
_2 parallel
_3 cms
_4 G1
76 线程的生命周期
新建 就绪 运行 阻塞 死亡
77 jvm垃圾回收算法
标记复制 标记清除 标记整理
78 redis分布式锁实现方式
_1 事务和watch
_2 setnx
_3 redission
79 online ddl
_1 mysql 5.5及以下 copy
_2 mysql 5.6 inplace
_3 mysql 5.8 instant
80 redis实现延迟队列
81 sychronized关键字修饰情况
synchronized关键字可以修饰方法,可以修饰代码块,但不能修饰构造器、属性等
82 JVM类加载过程
_1 加载
__1 通过一个类的全限定名来获取定义此类的二进制字节流
__2 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
__3 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
_2 连接
__1 验证
___1 文件格式验证
___2 元数据验证
___3 字节码验证
___4 符号引用验证
__2 准备
为类的静态变量分配内存,并将其赋默认值
__3 解析
将常量池中的符号引用替换为直接引用(内存地址)的过程
_3 初始化
为类的静态变量赋初值
_4 使用
_5 卸载
83 springboot加载配置文件顺序
application.properties优先级大于application.yml
_1 项目根目录
__1 /
__2 config
_2 resource
__1 /
__2 config
84 什么是反射
反射(Reflection)能够让运行于 JVM 中的程序检测和修改运行时的行为
85 避免批量更新导致的锁表
添加索引只锁住当前需要更新的行
上一篇
下一篇
获取当前shell脚本所在目录绝对路径
play框架简介
play REST hello 实例
Scala快速入门
play scala slick example
scala简易指南