程序员面试要点
2021-07-03 19:11:52 0 举报
AI智能生成
程序员面试涉及知识点:Reids,MQ,ES等
作者其他创作
大纲/内容
MQ
MQ的作用有哪些?
应用解耦,流量削峰填谷,消息分发,异步消息
MQ缺点
可用性降低
系统引入的外部依赖越多,越容易挂掉,本来你就是A系统调用BCD三个系统的接口就好了,现在又加入一个mq,万一mq挂掉了,整个系统也就崩溃了.
复杂性增加
硬生生的增加一个MQ进来怎么保证不被重复消费?怎么保证不会出现消息丢失的情况?怎么保证消息传递的顺序性?
数据一致性问题
系统A处理完以后直接返回成功了,人家都认为你这个请求成功了,但问题是,要是BCD三个系统成功了,结果C系统写库失败了,咋整?数据就不一致了
如何保障消息幂等性处理
开放:消息大量积压,如何解决?
ElasticSearch
数据库<br>Mysql
mysql执行流程
1、查询缓存<i> (MySQL 8.0 版本后移除))</i><br>2、解析器生成解析树<br>3、预处理再次生成解析树<br>4、查询优化器<br>5、查询执行计划<br>6、查询执行引擎<br>7、查询数据返回结果
事务
事务的ACID
<b><font color="#ff0000">原子性、一致性、隔离性、持久性</font></b>
分类
1、<b>扁平事务</b> <使用最频繁的事务,要么都成功提交,要么都失败回滚><br>2、<b>带有扁平点的扁平事务</b> <允许事务回滚到同一个事务中比较早的一个状态><br>3、<b>链事务</b> <回滚到最近的一个保存点,在所有的事务都提交之后才会释放锁,并且下一个事务的开始需要上一个事务来进行通知><br>4、<b>嵌套事务</b> <树结构,只有当父级事务提交之后子级事务才会提交,任意一个父级事务的回滚都会导致下面的子级事务回滚><br>5、<b>分布式事务</b> <操作两个不同的数据库,使其实现数据的同步,例如将中国银行的钱转到工商银行,这个不同银行的不同数据库,为分布式事务>
并发事务带来哪些问题?
脏读(Dirty read)
A事务修改但未提交,B事务来进行读取
丢失修改(Lost to modify)
A事务修改但未提交,B事务也来进行读取修改,导致某一方修改无效
不可重复读(Unrepeatableread)
幻读(Phantom read)
锁
Lock
1、<b>共享锁</b> <s lock>允许事务读取一行数据<br> <i>共享锁允许多个事务来读取相同的数据,因为读取不会改变数据,但是不能与排他锁共存,当有事务想要update数据的时候就要等共享锁释放之后才能使用排他锁进行update</i><br>2、<b>排他锁</b> <x lock>允许事务更新或者是删除一条数据<br><i> 当排他锁进行了行数据的锁定的时候就必须等这个锁释放之后下一个锁才能进来,也就是说必须当数据更新完成之后才能接收下一个事务的锁<br></i>3、<b>意向共享锁</b> <is lock>事务想要获得一张表某几行的共享锁<br>4、<b>意向排他锁</b> <ix lock>事务想要获得一张表的某几行的排他锁<br>
死锁
指两个或者事务在同一个资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象
死锁发生后,只有部分或者完全回滚其中一个事务,才能打破死锁
乐观锁悲观锁是什么,区别?
悲观锁 <br> 共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程<br>
乐观锁(ABA)<br> 适用于多读的应用类型,这样可以提高吞吐量,不能解决读问题<br>
索引
最左前缀原则
聚簇索引
<b>聚簇索引</b>:将数据存储与索引放到了一块,找到索引也就找到了数据 <br><b>非聚簇索引</b>:将数据与索引分开存储,索引结构的叶子节点指向了数据的对应行<br>
索引创建注意点
1、较频繁的作为查询条件的字段应该创建索引;<br>2、唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件;<br> 作为索引的列,如果不能有效的区分数据,那么这个列就不适合作为索引列;比如(性别,状态不多的状态列)<br>3、更新非常频繁的字段不适合创建索引;原因:索引有维护成本;<br>4、不会出现在WHERE 子句中的字段不该创建索引;<br>5、索引不是越多越好;(只为必要的列创建索引)<br> 不管你有多少个索引,一次查询至多采用一个索引;(索引和索引之间是独立的)<br> 因为索引和索引之间是独立的,所以说每一个索引都应该是单独维护的;数据的增/改/删,会导致所有的索引都要单独维护;
无效索引原因?
1、最好全值匹配;<br>2、最左前缀法则:如果索引了多列,查询从索引的最左前列开始,且不能跳过索引中的列;<br>3、不在索引列上做任何操作(计算,函数,类型转换),会导致索引时校而转向全表扫描;<br>4、存储引擎不能使用索引中范围条件右边的列,即范围之后全失效;<br>5、尽量使用覆盖索引,只访问索引的查询(索引列和查询列一致),减少selec *;<br>6、MySQL在使用不等于的时候无法使用索引会导致全表扫描;<br>7、is null,is not null 也无法使用索引;<br>8、like 以通配符开头(’%aa‘)索引会失效,变成全表扫描;<br>9、字符串不加单引号,索引失效;<br>10、少用 or,用它来连接时候会索引失效<br>
SQL优化原则
1、选择需要优化的SQL<br>2、Explain和Profile入手<br> 2.1 任何SQL的优化,都从Explain语句开始;Explain语句能够得到数据库执行该SQL选择的执行计划;<br> 2.2 首先明确需要的执行计划,再使用Explain检查;<br> 3、使用profile明确SQL的问题和优化的结果;<br>3、永远用小结果集驱动大的结果集<br>4、在索引中完成排序<br>5、使用最小Columns<br>6、使用最有效的过滤条件<br>7、避免复杂的JOIN和子查询
JOIN的原理
并发
其他
主键使用自增ID还是UUID?
<b><font color="#ff0000">推荐使用自增ID,不要使用UUID</font></b><br>为在InnoDB存储引擎中,主键索引是作为聚簇索引存在的,也就是说,主键索引的B+树叶子节 点上存储了主键索引以及全部的数据(按照顺序),如果主键索引是自增ID,那么只需要不断向后 排列即可,如果是UUID,由于到来的ID与原来的大小不确定,会造成非常多的数据插入,数据移动, 然后<b>导致产生很多的内存碎片,进而造成插入性能的下降</b>.<br>总之,在<b>数据量大一些的情况下,用自增主键性能会好一些</b><br>
字段为什么要求定义为not null
null值会占用更多的字节,且会在程序中造成很多与预期不符的情况。
<b><font color="#ff0000">168道面试题目</font></b>
Java
wait 和 sleep有啥区别
1、sleep是线程中的方法,但是wait是Object中的方法。<br>2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。<br>3、sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。<br>4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)
Redis
优势
<ol><li>高性能,高并发量,QPS最高可达到10W</li><li>丰富的数据类型</li><li>redis所有操作都具有原子性</li></ol>
Redis是单线程吗?为何这么快?
Reids是基于内存操作,CPU不是瓶颈,限制Redis是内存大小或网络带宽,故用单线程即可<br><br>快的原因:<br><ol><li>完全基于内存 ,时间复杂度O(1)</li><li>数据结构简单</li><li>采用单线程设计:避免上下文和竞争条件(<font color="#e57373">新版引入多线程,但仅对一些删除才用多线程</font>)</li><li>IO多路复用机制</li><li>底层模型不同(redis自己构建VM机制)</li></ol>
常用数据结构有哪些?
String
Hash
List
Set
核心:自动排重<br>
场景:如微博共同关注,共同喜好,二度好友等功能<br>差集取不同,交集取相同,并集取所有不同
Zset<br><i>有序集合</i>
核心:自动排重,权重参数排序(相同安装ascii排序)
场景:直播实时用户列表,礼物排行,弹幕消息等
BitMaps
场景:用户访问统计;在线用户统计;用户签到;与、或、异或、非运算;
Hyperloglog
场景:不太精确的基数统计;统计网站UV;日活,月活
Geospatial
核心:存放经纬度,地理位置信息
场景:最近门店,范围内门店等
String类型的底层实现
自己造轮子SDS
通讯协议?
使用RESP协议
纯文本协议,虽换行符较多,但简单、解析极其容易
事务
特点
<ol><li>把一组命令一起执行</li><li>按进入队列的顺序执行</li><li>不会受到其他客户端的请求影响</li><li>事务不能嵌套,多个multi命令效果一样</li></ol>
使用
multi 开始事务
exec 执行事务
<ol><li>执行exec之前发生错误,事务会被拒绝执行</li><li>执行exec之后发生错误,错误前命令执行成功(若需解决使用LUA脚本)</li></ol>
discard 取消事务
watch 监视
<ol><li>防止事务过程中某个key值被其他客户端修改并且取消事务</li><li>CAS乐观锁行为</li></ol>
弱事务
只能保证事务的隔离性,串行话,中间有命令执行错误依然会向下执行不回滚
持久化
RDB(Redis Database)记录快照<br><i>默认方式</i>
自动触发
x秒内至少有x个key被修改,则生成快照
lastsave查看最近一次成功生成快照时间
正常关机也会触发快照生成
调用flushall也会生成快照,但是空文件
手动触发
save 阻塞其他命令生成快照
bgsave 后台生成快照
优点
<ol><li>文件紧凑,适用于备份和灾备</li><li>生成文件不影响主程序</li><li>大数据恢复速度较快</li></ol>
缺点
<ol><li>不能做到实时持久化</li><li>宕机会丢失最后一次快照后的数据</li></ol>
AOF(Append Only File) 记录日志<br><i>开启优先使用</i>
no
不执行fsync,由操作系统保证数据同步到磁盘<br>速度快<br>不安全
always
每次写都执行fsync<br>保证同步到磁盘<br>效率低
everysec(推荐)
每秒执行一次fsync<br>效率与安全兼顾<br>可能丢失一秒数据
优点
AOF提供多种同步频率
缺点
比RDB文件更大<br>高并发情况下,性能差于RDB
当AOF文件大小超过所设定的阀值时,会启动AOF文件压缩,只保留可以恢复的最小指令集
如何选择持久化方案
<ol><li>能容忍短时间段内数据丢失选择RDB</li><li>数据非常宝贵AOF</li><li>不要单独设置一种持久化机制,两种一起用,AOF比RDB数据完整</li></ol>
fork阻塞:CPU的阻塞
AOF追加阻塞:硬盘阻塞
Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别不要启用内存快照做持久化
缓存设计与优化
缓存穿透:key对应的数据在缓存和数据源都不存在<br>
<font color="#f44336"><b>解决方案</b></font><br><b>1、接口层增加校验</b>,如用户鉴权校验,id做基础校验,id<=0的直接拦截;<br><b>2、</b>从缓存取不到的数据,在数据库中也没有取到,这时也可以<b>将key-value对写为key-null</b>,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击<br><b>3、布隆过滤器</b>。bloomfilter就类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。布隆过滤器的关键就在于hash算法和容器大小<br> 布隆过滤器判定情况:某个元素一定不存在或可能存在(<i><font color="#f44336">不会出现实际存在某元素告知不存在的情况</font></i>)<br> 布隆过滤器缺陷:不支持删除元素(因存在误删情况)
缓存击穿:某个热点key,在并发情况下正好缓存过期,导致大量请求没有命中缓存
<font color="#f44336"><b>解决方案</b></font><br>1、设置热点数据永远不过期。<br>2、接口限流与熔断,降级。重要的接口一定要做好限流策略,防止用户恶意刷接口,同时要降级准备,当接口中的某些 服务 不可用时候,进行熔断,失败快速返回机制。
缓存雪崩:同一时间缓存大面积过期
<b><font color="#f44336">解决方案</font></b><br>1、缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。<br>2、如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中。<br>3、设置热点数据永远不过期。
缓存更新策略
数据库和缓存一致性
先删除缓存,还是先删除数据库?<br> 延时双删策略<br> <b> 先删除缓存,更新数据,再删除缓存</b>
可能导致Redis阻塞原因?<br>如何去发现?
代码问题
慢查询
bigkey大对象
API或数据结构使用不合理<br>
持久化造成阻塞
fork子进程
AOF刷盘阻塞
外因素
Redis输入、输出缓冲区导致的阻塞
CPU饱和
网络问题
过期策略和内存淘汰策略<br><i>内存回收</i>
过期/失效策略
立即过期
<b>每个key设置过期时间,时间到就会清除<br>优点:</b>对内存友好<br><b>缺点</b>:占用CPU资源,影响吞吐
惰性过期(被动)
<b>只有get时候会判断是否过期<br>优点:</b>节省CPU资源<br><b>缺点:对</b>内存不友好
定期过期
<b>每隔一段时间会扫描一定数量过期字典中一定数量key进行清除</b><br><b>优点:</b>在不同情况下会使得CPU和内存资源达到最优平衡
淘汰策略<br><i>内存满了</i><br>
最大内存设置
32位系统最多使用3GB内存<br>64位系统无限制
volatile-lru / allkeys-lru:优先保留最近访问过的数据<br>volatile-lfu / allkeys-lfu:优先保留访问次数最频繁的数据(4.0+版本支持)<br>volatile-ttl :优先淘汰即将过期的数据<br>volatile-random / allkeys-random:随机淘汰数据
如何做内存优化?
缩减键值对象长度
共享对象池
字符串优化
控制key数量
尽可能使用散列表(hashes)
设置内存上限
配置内存回收策略
主从复制
方式/原理
<br>全量复制<br>
第一次连接到主节点,需全部数据
同步:<br><ol><li>将RDB文件发送给从节点</li><li>从节点如果有数据,先清除自身数据</li></ol>
增量复制
之前连接过master节点,进行增量备份<br>通过偏移量记录上一次数据地址
无磁盘复制<br>
2.8后支持,纯内存复制
复制过程
<ol><li>当从库和主库建立MS关系后,会向主数据库发送SYNC命令</li><li>主库接收到SYNC命令后会开始在后台保存快照(RDB持久化过程),并将期间接收到的写命令缓存起来</li><li>当快照完成后,主Redis会将快照文件和所有缓存写命令发送从redis</li><li>从redis接收到后,会载入快照文件并执行收到的缓存命令</li><li>之后,每当主redis接到写命令时就会将命令发送从redis,从而保证数据一致性</li></ol>
主从心跳链接<br>
说明:主从节点在建立复制后,他们之间维护着长连接并彼此发送心跳命令。<br>1、主从都有心跳检测机制,各自模拟成对方的客户端进行通信,通过 client list 命令查看复制相关客户端信息,<br>主节点的连接状态为 flags = M,从节点的连接状态是 flags = S。 <br>2、主节点默认每隔 10 秒对从节点发送 ping 命令,可修改配置 repl-ping-slave-period 控制发送频率。<br>3、从节点在主线程每隔 1秒发送 replconf ack{offset} 命令,给主节点上报自身当前的复制偏移量。<br>4、主节点收到 replconf 信息后,判断从节点超时时间,如果超过 repl-timeout 60 秒,则判断节点下线。
缺点:<br><ol><li>复制延时 (RDB文件过大,同步非常耗时)</li><li>未解决高可用问题</li><li>需要手动切换主从</li></ol>
为了主从复制速度和链接稳定性,Slave和Master最好在同一个局域网<br>尽量避免在压力较大的主库上增加从库
哨兵模式
哨兵的作用?
保障集群高可用 (不能保证数据0丢失,只能保证高可用)<br>管理多个Redis服务器,提供<b><font color="#f44336">监控,消息通知以及自动的故障转移</font></b>功能 (<b>自动主从切换</b>)<br>
选举机制
哨兵选举<br>
选举Leader,通过Leader进行选举<br>Raft算法:先到先得,少数服从多数<br>
Master选举
优先级 高于 复制数据最多 高于 进程id最小<br><i>优先级:配置文件设置</i><br>
分布式锁
支持setnx实现,后可用set代替
官方推荐RedLock
集群模式下,半数以上节点获取成功才能获取锁成功,否则释放
互斥访问,永远只有一个client才能获取锁成功<br>避免死锁
大量数据插入
Redis 2.6开始redis-cli支持<b><font color="#f44336">pipe mode</font></b>模式用于执行大量数据插入工作
常用工具
redisson<br>
不支持事务<br>实现分布式锁
jedis
常用,轻量,简洁,易集成<br>可以使用连接池
lettuce
线程安全客户端
<font color="#ff0000" style=""><b>68道面试题目</b></font>
第一部分:Redis 的概念理解<br>1. 什么是 Redis?<br>2. Redis 的特点有哪些?<br>3. Memcache 与 Redis 的区别都有哪些? <br>4. Redis 相比 Memcached 有哪些优势?<br>5. 如何实现本地缓存?请描述一下你知道的方式<br>6. Redis 通讯协议是什么?有什么特点?<br><br>第二部分:Redis 数据结构与指令<br>7. Redis 支持的数据类型<br>8. Redis 常用的命令有哪些?<br>9. 一个字符串类型的值 能存储最大容量是多少?<br>10. Redis 各个数据类型最大存储量分别是多少?<br>11. 请介绍一下 Redis 的数据类型 SortedSet(zset)以及底层实现机制?<br>12. Redis 事务相关命令有哪些?<br>13. 什么是 Redis 事务?原理是什么?<br>14. Redis 事务的注意点有哪些?<br>15. Redis 为什么不支持回滚?<br>16. 请介绍一下 Redis 的 Pipeline(管道),以及使用场景<br>17. 请说明一下 Redis 的批量命令与 Pipeline 有什么不同?<br>18. 请介绍一下 Redis 的发布订阅功能<br>19. Redis 的链表数据结构的特征有哪些?<br>20. 请介绍一下 Redis 的 String 类型底层实现?<br>21. Redis 的 String 类型使用 SSD 方式实现的好处?<br>22. 设置键的生存时间和过期时间有哪些命令?<br><br>第三部分:Redis 高并发处理策略<br>23. 为什么 Redis 需要把所有数据放到内存中?<br>24. Redis 是单线程的吗?<br>25. Redis 为什么设计成单线程的?<br>26. 什么是缓存穿透?怎么解决?<br>27. 什么是缓存雪崩? 怎么解决?<br>28. 缓存的更新策略有几种?分别有什么注意事项?<br>29. 请介绍几个可能导致 Redis 阻塞的原因<br>30. 怎么去发现 Redis 阻塞异常情况?<br><br>第四部分:Redis 集群结构以及设计理念<br>31. Redis 集群架构模式有哪几种?<br>32. Redis 集群最大节点个数是多少?<br>33. Redis 集群的主从复制模型是怎样的?<br>34. 请介绍一下 Redis 集群实现方案<br>35. Redis 集群会有 写操作丢失吗?为什么?<br>36. Redis 慢查询是什么?通过什么配置?<br>37. Redis 的慢查询修复经验有哪些?怎么修复的?<br>38. 如何优化 Redis 服务的性能?<br>39. Redis 的主从复制模式有什么优缺点?<br>40. Redis sentinel(哨兵)模式优缺点有哪些?<br>41. 如何设置 Redis 的最大连接数?查看 Redis 的最大连接数?查看 Redis 的当前<br>42. 介绍一些 Redis 常用的安全设置?<br><br>第五部分:Redis 缓存管理与持久化机制<br>43. Redis 持久化机制有哪些?<br>44. Redis 持久化机制 AOF 和 RDB 有哪些不同之处?<br>45. 请介绍一下 RDB 持久化机制的优缺点<br>46. 请介绍一下 AOF 持久化机制的优缺点<br>47. 如果 AOF 文件的数据出现异常, Redis 服务怎么处理?<br>48. 常见的淘汰算法有哪些?<br>49. Redis 淘汰策略有哪些?<br>50. Redis 缓存失效策略有哪些?<br>51. Redis 如何做内存优化?<br>52. 什么是 bigkey? 有什么影响?<br>53. 怎么发现 bigkey?<br>54. Redis 的内存消耗分类有哪些?内存统计使用什么命令?<br>55. 简单介绍一下 Redis 的内存管理方式有哪些?<br>56. 如何设置 Redis 的内存上限?有什么作用?<br>57. Redis 报内存不足怎么处理?<br><br>第六部分:Redis 应用场景设计<br>58. Redis 适用场景有哪些?<br>59. Redis 常用的业务场景有哪些?<br>60. Redis 支持的 Java 客户端有哪些? 简单说明一下特点。<br>61. 请简单描述一下 Jedis 的基本使用方法?<br>62. Jedis 连接池连接方法有什么优点?<br>63. 什么是分布式锁?有什么作用?<br>64. 分布式锁可以通过什么来实现?<br>65. 介绍一下分布式锁实现需要注意的事项?<br>66. Redis 怎么实现分布式锁?<br>67. 缓存命中率表示什么?<br>68. 怎么提高缓存命中率?
计算机网络
TCP与UDP区别?
TCP<br> 面向连接,可靠服务(无差错,不丢失,不重复,按序)<br> 点对点<br>UDP<br> 是无连接,发送数据前不需要建立连接,不保证可靠交付<br> 支持一对一,一对多,多对一,多对多交互通信
TCP协议通过三次握手,四次挥手
https怎么做到安全的?
加密,身份验证
开放:如何设计出一个对外安全接口?
数据加密,数据加签名防篡改<br>时间戳机制,AppID机制,限流机制<br>黑名单,数据合法性校验
项目管理
0 条评论
下一页