敖丙大佬面试视屏学习(一)

敖丙面试一个大厂一年经验的程序员 看完之后感觉 自己很多方面的积累还不如人家一个一年经验的人
尤其是今天学习 学的好累 感觉自己要炸裂了 感觉不会的太多了 没想到一个视频给我看清醒了 还是要积累和学习 加油

面试全过程:https://blog.csdn.net/qq_35190492/article/details/105041405
下面说一下我能想到的回答 然后整理一下
这个是在我没有被面试的时候想到的 面试的时候还是会紧张 可能就想不到这么多了
业务问题 就学习一下就好 非业务的问题 就一一记录 梳理一下

一:系统高并发访问的时候应该怎么处理

1、拆服务,将系统根据业务拆分成不同的微服务 进行请求分流 保证不是一个服务同时受到全部的请求
2、消息中间件:削峰 通过一些消息中间件进行一些数据请求的管理保证请求管理和异步处理 以此来保证 服务器不会一瞬间被请求冲垮
3、分布式数据库:读写分离 保证写操作的一致性 并保证读取数据的一个迅速性
4、缓存数据库Redis:一部分非重点需要入库的数据 存放在缓存中缓解数据库的压力

下面附上一份 我之前面试要求设计一个分布式 高并发系统时 应该怎么做:
/**
*
* 1、首先需要在web层控制 用户访问点击的次数 前台首先现在用户点击
* 每次点击都转圈或者跳离这个页面保证 等待这个请求响应完成后才能进行下一次点击
* 而且比如说一次一共有200张票 先发180张 留百分之十也就是20张进行一个容灾方案保证一些无法完全同步管理的请求
* 最终可以有正常的票来买入
* 2、但有时用户比较机智 同时开好几个窗口同时点击的话 这种 可以加入消息中间件 过滤一下请求
* 例如通过用户id 或者ip过滤
* 3、如果有人控制着大量的肉鸡账号 高并发大量攻击请求 可以通过一些算法限制这些用户
* 因为这些用户上一般来说本身就没有什么操作记录 通过这种类似的算法排除一些肉鸡账户
* 4、如果真的像春运抢票的那种情况 真的有很多人抢 可以使用 消息队列按照顺序
* 存储这些请求依次进行数据的处理 并设置过期时间 类似于购物买单前会给半个小时付费
* 如果没付费就关闭这个请求
* 5、并且也要设置请求超时时间 如果一段时间内排在队列中的请求都来不及处理就返回 失败让用户再次发送请求
* 6、请求过来后需要处理 首先多线程肯定是必要的 可以参考NIO或者异步IO处理模型 关键操作同步执行
* 例如数据入库之类的 订单支付成功之类的信息 其余不重要的步骤做成异步的增快相应
* 7、一些非关键性数据存储在Redis之类的缓存数据库中即可 在Redis库中锁定一张票后就可以返回请求
* 告诉用户可以进行支付操作了 将步骤分离 不至于一部将全部步骤完成增大服务器压力
* 8、关键的支付和确认订单请求过来 因为之前的层层过滤 基本上已经可以保证 不会存在大量的请求攻击了
* 这时就可以进行请求的同步操作 保证支付类操作的事务性
* 9、数据库可以采用读写分离的分布式数据库保证了数据的读取和写入操作不会互锁 保证了数据的正确写入
* 10、还有就是拆分系统 比如说用户管理系统 订单支付系统 商品管理系统等都做成微服务 分担请求 规避了某一个
* 服务过于高压的状态
* 11、使用dubbo和Spring Cloud之类的服务管理和rpc框架来搭建 保证服务的管理 注册 和容灾的管理
* 12、涉及的微服务都进行集群化部署 保证一个节点存在故障后 其余节点可以自动快速升主 保证服务和系统的正常运行
*
*/

二:Redis断电的场景下,怎么保证数据不丢失和业务的正常运行?

数据不丢失?
还有就是Redis本身是有备份和持久化机制的 这个机制有两种 一种是RDB方式,另外一种是AOF操作:
RDB备份就是一个定时的备份任务,他会定时的fork一个子进程定时的备份这段时间的数据,生成一个二进制的rdb文件,
aof的话就是会记录所有的写操作 将这个写操作记录到appendonly上,保证数据上的一致性
但是,
rdb的话慢慢的会将数据写的越来越大 到一定程度后就会影响性能 而且rdb方式还是会有一定程度上的数据丢失
而AOF操作的话因为每次写操作都会将数据持久化一次 虽然过一段时间会将AOF文件进行一个整合 比如过增了一条数据又修改了这条数据 又把这条数据删了 这三个操作都会被aof记录进去 最后整合一下 把这三条数据都删掉就好了 减小了aof的大小 但是因为aof相当是一个同步的操作 所以还是对性能有一些影响
需要根据实际情况选取数据同步机制

业务正常运行?
Redis是提供Master和slave的主从部署的 Redis本身提供的有哨兵机制 哨兵进制会周期性通过心跳检测Redis的Master服务是否正常运行 如果是正常的运行的话 那么就会保持 但是 如果Master持续一段时间 无法心跳不响应的话 那么哨兵就会认为这个Master挂了 然后通过竞选的方式选取一个slave 升主 其他slave自动连接这个升主的slave 以此保证Redis服务的一个高可用

三: 一个master挂了,哨兵机制拉起了一个slave并且正常运行了,这时master可能只是因为假死,而导致脑裂的一个状况?

首先这个问题我是不知道的 当我听到这个问题的第一想法
哨兵模式肯定会有一个标识 标志oldMaster这个节点 如果新的master已经运行起来了 那就把oldMaster降成slave就好了 我感觉是不可能把old再重新升主的
1、因为新的master已经开始运行了 相当于这一段时间内master已经开始管理其他所有slave节点了 这时如果要把old升主的话 整个集群切换成本太高了
2、newMaster一下该是运行 这时就会有新的数据进来了 如果oldMaster要升主 需要他开始接受新数据 并把旧的数据全部复制过去 成本太高 不如直接降备 从新的master同步数据即可

接下来查询一下这个问题的正解:
学习博客:https://blog.csdn.net/LO_YUN/article/details/97131426

解决方案
redis的配置文件中,存在两个参数

min-slaves-to-write 3
min-slaves-max-lag 10
第一个参数表示连接到master的最少slave数量
第二个参数表示slave连接到master的最大延迟时间

按照上面的配置,要求至少3个slave节点,且数据复制和同步的延迟不能超过10秒,否则的话master就会拒绝写请求,配置了这两个参数之后,如果发生集群脑裂,原先的master节点接收到客户端的写入请求会拒绝,就可以减少数据同步之后的数据丢失。

注意:较新版本的redis.conf文件中的参数变成了

min-replicas-to-write 3
min-replicas-max-lag 10
redis中的异步复制情况下的数据丢失问题也能使用这两个参数

和我想的思路差不多 但是我并不知道解决问题的具体方案 学习了

四:redis是怎么保证数据的同步和初始化的

这个具体机制还真是不太了解 copy一下
https://blog.51cto.com/14234542/2409594大佬的答案
1.从服务发送一个sync同步命令给主服务要求全量同步
2.主服务接收到从服务的sync同步命令时,会fork一个子进程后台执行bgsave命令(非阻塞)快照保存,生成RDB文件,并将
RDB文件发送给从服务
3.从服务再将接收到的RDB文件载入自己的redis内存
4.待从服务将RDB载入完成后,主服务再将缓冲区所有写命令发送给从服务
5.从服务在将主服务所有的写命令载入内存从而实现数据的完整同步
6.从服务下次在需要同步数据时只需要发送自己的offset位置(相当于mysql binlog的位置)即可,只同步新增加的数据,再不需要全量同步

五:redis的查询QPS最高是多少

我记得没错的话应该是10w/s 没记错

六:Redis如何保证数据一致性?

缓存和数据库数据因为网络异常 怎么保证数据的一致性 这个又不知道了
数据操作流程如下:
1、更新数据库前先删除缓存
2、删除缓存后更新数据库
3、然后在重新加载缓存
如果是这样的话 无论哪一步失败了 都可以保证数据的一致性

七:Redis缓存击穿?

缓存击穿这个 主要就是存在一个Hot key 有大量请求针对这个key来进行查询 当这个Hot key一旦过期 大量的请求就会直接去数据库中查询 从而击溃了数据库
结局方案:
1、设置key值永不过期
2、集群化部署 多个服务器都存在这个key值 并且设置不同的过期时间 保证在同一时间内 总会存在这个key值的存储
3、加上互斥锁 保证同一时间只有一个请求针对这个key去数据库查询

可以查看我的Redis 初步学习 了解击穿 穿透 雪崩的场景和解决方案https://blog.csdn.net/tiantang_zy/article/details/104938827

听敖丙面试的那个意思 感觉还有其他解决方案?但是查了一下没找到 下来再细致学习一下

弹幕上说布隆过滤器
TODO

八:Redis分布式锁?

我只知道基于setnx进行一个值的设置和获取 一万redis是单线程的 所以以此保证了
分布式锁的实现
但是具体细节就不知道了
SETNX+EXPIRE
Redis+Lua
mark:
https://blog.csdn.net/yb223731/article/details/90349502
https://www.jianshu.com/p/bc8dd3c0db22添加链接描述
TODO

九:多线程的安全是怎么保证的

毫无疑问问的是锁的概念
synchronized 基于monitorenter和monitorexit
enter的时候获取锁 监控对象+1 monitorexit的时候-1 当监控值为0的时候可以获取锁
jdk1.8的时候针对 synchronized 获取锁的方式,JVM 使用了锁升级的优化方式,就是先使用偏向锁优先同一线程然后再次获取锁,如果失败,就升级为 CAS 轻量级锁,如果失败就会短暂自旋,防止线程被系统挂起。最后如果以上都失败就升级为重量级锁。

ReentrantLock也是一个基于ObjectMonitor实现的锁 不过需要自己加锁和释放锁 而且可以是公平的锁也可以是不公平的 在代码里判断一下即可

我关于锁的博客:https://blog.csdn.net/tiantang_zy/article/details/104984058

后面感觉还是会继续更新的 深挖一下实现的源码
synchronized 锁对象和锁静态代码块和锁方法的实现 分别是怎么实现的
TODO

十:TreadLocal??

这个真不知道 下来补
TODO

十一:两个线程 父子线程 子线程怎么拿到父线程的值??

感觉是 violate关键字 然子线程可见吧 但是实际怎么搞 还得查一下 多线程这一块真的还是有太多的不知道
TODO

十二:Mysql 数据优化

TODO

十三:索引的具体实现 聚集索引和非聚集缩影

B+树 这个还是不知道
为啥不用hash树 数据碰撞 而且没有办法 范围查找
为啥不用二叉树 数据量大的时候 极端情况下 树的高度不可控 查找复杂度可能为O(n)
Mark下来 还是要学
TODO

十四:count(1)和count(*)

count(*)涉及到的就是数据库表所有字段的一个计算 效率是比较低下的
而count(1)是就是计算行数 相对来说效率更高
或者可以使用count(字段名)来进行某个字段的具体统计
TODO

十五:MVCC和事务隔离级别

TODO

十六:主从同步和分表

下来了解一下分表的中间件
分表的话 主键怎么不重复呢?
分布式id生成器 UUID 雪花算法
TODO

十七:消息队列如何做到保证消息不被重复消费

RocketMQ
流水表做一个幂等的操作
TODO

十八:RocketMQ是如何保证顺序消费的,比如说一个命令是增删改查的命令一起下发过来的 是怎么保证这个顺序的?

会有一个队列存储 进行顺序的管控 但是具体的实现还是需要下来慢慢的学习
根据id 像队列一下以此消费
TODO

十九:怎么保证消费成功的呢?

RocketMQ 发送成功标志 consumer success
TODO

二十:分布式事务?

1、rpc之间 失败 使的服务间数据不同步 增加轮训重试机制
2、不重要的信息的话 重试一点次数后还是失败 就失败吧
3、重要数据 另起一个线程保存相关数据进行请求的顺利进行保证 数据的一致和操作的成功 补偿机制
补偿机制是什么?
TODO

二十一: 补偿机制的一个调用链路是怎么样的?

Producter到consumer他的一个调用链路
还涉及到broker nameService
TODO

二十二:Spring注入Bean 通过Autowire和Resource实现有什么不同?

首先Spring会根据配置文件 将需要加载的Bean类都管理到容器中 等待接下来相关调用处的一个分配
Autowire 是Spring在扫描相关目录下的文件时发现这个注解然后识别出需要下发的对象 和对象名称 然后从之前加载到容器中的实例注入进去
Resource这种 就是是在扫描配置文件的时候 根据配置文件的指向 通过反射获取对应的对象 然后调用这个对象对应的set或构造器方法 将容器中的实例注入进去
我的理解是这样的 如果有什么不对 麻烦指正
下来还会根据这个详细学习一下的
TODO

二十三:为什么想换工作?

我的话就是不想做外包了
想做一些分布式的框架和技术
真的去学习和应用一些java相关的技术
这次跳槽真的是认清了一些现象
还有自己的差距 真的差的好远 还是需要努力

二十四:面试时的状态?

尽量使自己保持一个状态的平静 遇到自己不会的问题 将自己知道的东西先说出来 要让面试官觉得 是一个认真学习的态度的 不是毫无研究和深入学习的

发布了31 篇原创文章 · 获赞 8 · 访问量 467

猜你喜欢

转载自blog.csdn.net/tiantang_zy/article/details/105070240