java 面试知识点突击-(91-100)

Posted 栗子~~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 面试知识点突击-(91-100)相关的知识,希望对你有一定的参考价值。

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


java 知识点扫盲目录

https://blog.csdn.net/weixin_38316697/article/details/121991582

java 面试知识点突击-(91-100)

91 讲一下redis 的RDB 和AOF机制?

RDB机制: Redis DataBase
在指定时间间隔内,将内存中的数据集快照写入磁盘,实际操作是fork一个子进程,先将数据写入一个临时文件,之后替换原来的文件(二进制存储压缩)。

优点:
1、易于持久化,因为最终只有一个dump文件
2、容灾性好,方便备份
3、性能最大化,因为fork一个子进程,子进程的操作不影响主进程的操作,单独子进程进行IO操作,主进程不会执行任何IO操作,保证redis效率最大化。
4、数据集大时,相对应AOF,启动效率更高

缺点:
1、安全性低,RDB是隔段时间进行快照持久化操作,在持久化过程中,发生宕机时,容易造成数据丢失。
2、因为RDB是通过fork子进程辅助完成持久化,当数据集非常大时,可能导致整个服务器停止几百毫秒,甚至1秒钟。

AOF机制:append only file (只追加文件)
类似于mysql 的binlog日志,以日志的形式记录每个写、删除操作,不记录查询操作。

优点:
1、数据安全,append写操作,即使redis宕机了,也不会影响之前已存在的数据
2、AOF的rewrite模式,定期对AOF文件进行重写(因为AOF模式,是流水账的方式写入文件,会造成大量的数据),以达到压缩的目的。

缺点:
1、AOF文件比RDB文件大,恢复速度慢
2、数据集大时,比RDB启动效率低
3、运行效率没有RDB高

注:如果两种机制,都配的情况下:

AOF更新频率比RDB高,恢复的话优先AOF
AOF比RDB更大,也更安全
RDB性能比AOF更高
如果两个都配了,redis会优先加载AOP文件


92 redis 过期键的删除策略?

惰性过期:
访问key的时候,判断是否过期,不访问的时候永远不过期,对CPU很友好,对内存不友好。
定期过期:
隔段时间扫描(一定数量的key),清除已经过期的key,对内存友好,对cpu不友好。

redis中同时使用两种策略。


93 redis的线程模型,为什么这么快?

Redis 采用的是 ANSI C 语言编写,采用 C 语言编写的好处是底层代码执行效率高。依赖性低,使用 C 语言开发的库没有太多运行时(Runtime)依赖,并且系统兼容性好,稳定性高。
Redis 采用的 Key-Value 方式进行存储,数据的操作复杂度为 O(1)采用了多路 I/O 复用技术,这里的多路是多个 Socket 网络连接,复用是指复用一个线程,采用多路技术的好处是同一个线程中可以处理多个 I/O 请求,减少网络 IO 消耗,提升了使用效率。


94 Redis的string最大多少,hash、set、list、zset都分别最大多少?

512M,String a = '1’占 16个字节。
一个String类型最大value最大可以存储512M;
list的元素个数最多为2^32-1个;
set类型的元素个数最多为2^32-1个;
hash类型键值对个数最多2^32-1个,即4294967295个


95 Redis 的5种数据类型?

Redis是一种高级的key:value存储系统,其中value支持5种数据类型
注:命令不区分大小写,key是区分大小写的。Redis中不适合保存内容大的数据。

1)字符串(strings)
– String:key-value(做缓存)
2)字符串列表(lists)
– List:有顺序可重复
3)字符串集合(set)
– Set:元素无顺序,不能重复
4)有序字符串集合(sorted sets)
– sorted sets 有顺序,不能重复
5)哈希(hashes)
–Hash:key-fields-values(做缓存)

注意:关于key值

  • key不能太长,尽量不超过1024B。超过1024B不但消耗内存,而且会降低查找效率 ;
  • key也不能太短,key太短,key的可读性会降低 ;
  • 在一个项目中,key最好使用统一的命名规则,如:yzy:007:hello;

96 缓存雪崩

【缓存雪崩】缓存同一时间大面积失效,后面的请求都会落到数据库上,造成数据库短时间内大量请求而崩溃。

解决思想:
达到每个缓存的过期时间重复率降低的目的或者制造延迟过期时间的行为,最终防止集体失效的事件。
解决方案:
第一种解决方案:
为 key 设置不同的缓存失效时间,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
第二种解决方案:
给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存(另起线程),
第三种解决方案:
缓存预热,解决因redis重启导致重启期间,所有请求都请求到数据库。
第四种解决方案:
互斥锁,当一个请求的缓存失效时,将查询数据库和新增缓存加上一个互斥锁,防止同一时间大量请求落到数据库上。

实例伪代码如下:
说明:
1、缓存标记:记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去更新实际key的缓存;
2、缓存数据:它的过期时间比缓存标记的时间延长1倍,例:标记缓存时间30分钟,数据缓存设置为60分钟。 这样,当缓存标记key过期后,实际缓存还能把旧数据返回给调用端,直到另外的线程在后台更新完成后,才会返回新缓存;

//伪代码
public object GetProductListNew() 
  int cacheTime = 30;
  String cacheKey = "test_list";
  //缓存标记_sign
  String cacheSign = cacheKey + "_sign";
  String sign = CacheHelper.Get(cacheSign);

  //获取缓存值
  String cacheValue = CacheHelper.Get(cacheKey);
  if (sign != null) 
    return cacheValue; //未过期,直接返回
   else 
  CacheHelper.Add(cacheSign, "1", cacheTime);
  ThreadPool.QueueUserWorkItem((arg) -> 
    //这里一般是 sql查询数据
    cacheValue = GetProductListFromDB();
    //日期设缓存时间的2倍,用于脏读
    CacheHelper.Add(cacheKey, cacheValue, cacheTime * 2);
  );
  return cacheValue;


97 缓存穿透/击穿

1)、缓存穿透:缓存和数据库中都没有。

缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在 缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。

一般来自攻击/高并发。

解决方案:
第一种解决方案:
如果一个查询返回的数据为空(不管是数据不 存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟,通过这个直接设置的默认值(比如【null】)存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。
第二种解决方案:
接口层做校验,防止根本不可能存在的请求数据过来,如果发现该数据根本不可能存在直接过滤掉。
第三种解决方案:
采用布隆过滤器,一定不存在的数据拦截掉。

2)、缓存击穿:缓存中没有,数据库中有
缓存击穿是指用户查询数据时,缓存中没有,数据库有(一般是缓存时间到期),这时在高并发的场景下,由于用户特别多,一瞬间数据库的压力激增。
解决方案:
第一种解决方案:
热点数据设置成永远不过期。
第二种解决方案:
加互斥锁,让一个线程查询数据库。


98 缓存预热

缓存预热就是系统上线后,将【相关的缓存数据】直接加载到缓存系统,这样就可以避免在用户请求的时候, 先查询数据库,然后再将数据缓存的问题!

解决方案:
1、数据量不大的情况,项目启动后自动加载
2、数据量大的情况下,可以定时认为
3、设计一个缓存加载web功能


99 缓存更新

缓存更新除了缓存服务器自带的缓存失效策略之外(Redis 默认的有 6 中策略可供选择),我们还可以 根据具体的业务需求进行自定义的缓存淘汰。
(1)定时去清理过期的缓存;
(2)当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数 据并更新缓存。

两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂!具体用哪种方案,大家可以根据自己的应用场景来权衡。


100 缓存降级

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级

降级的目的:
保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。
在进行降级之前要对系统进行梳理,看看系统是不是可以丢卒保帅;从而梳理出哪些必须誓死保护,哪些可降级;比如可以参考日志级别设置预案:

(1)一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;
(2)警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;
(3)错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;
(4)严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。


创作不易、点关注、不迷路

点击主页、更精彩 !!!

以上是关于java 面试知识点突击-(91-100)的主要内容,如果未能解决你的问题,请参考以下文章

java 面试知识点突击-(61-70)

java 面试知识点突击-(71-80)

java 面试知识点突击-(51-60)

java 面试知识点突击-(81-90)

Java面试手册V2.0+突击V3.0知识点整理(二十) 附封面图片

负载均衡(纯手写,极度适合巩固基础面试突击)