网站首页 > java教程 正文
去任何公司面试技术这个岗位,缓存都是要被问及的题目。一方面缓存在开发中必不可少,没有缓存的组合搭配,系统可能会垮掉。另外一方面,许多优秀的缓存框架被不断推广普及已经成为广大程序员的家常便饭,但真正能讲其核心原理,没有那么简单,需要你平时对缓存技术有足够的学习和沉淀。那去阿里面试,关于缓存会被问及哪些问题呢?
1、为什么要使用缓存
这个问题一般是送分题。但回答这个问题还是要强调两个点,第一个点就是效率。第二个点是稳定。前者强调使用缓存,可以让我们更快速的拿到响应结果,后者是为了保护数据库,缓存能抗住就走缓存,减少对数据库的并发访问。
我记得我刚工作那会,不知道什么是缓存,在实际项目中也没有用缓存,所有操作都是直接读取数据库来完成,客户还问我为什么系统这么慢?我的回复是网络太差了,偶发的,别在意。
2、你知道哪些优秀的缓存框架
此类的框架就很多了。但如果是阿里的面试官问了,你的答案最好是可以涉及阿里的开源技术,比如jetCache。
jetcache是阿里开源的基于java开发的缓存框架,支持多种缓存类型:本地缓存、分布式缓存、多级缓存。能够满足不同业务场景的缓存需求。jetcache具有上手简单、性能高效、拓展性强的特点。支持缓存预热 、缓存key前缀等功能。结合spring-cache使用,可以实现十分优雅的缓存类型切换
官网地址:https://github.com/alibaba/jetcache
官方文档:https://github.com/alibaba/jetcache/tree/master/docs/CN
当前,估计大多数使用最广泛的缓存框架就是Redis了,Redis是完全开源免费的,是用C语言编写的,是一个高性能的kv分布式内存数据库,是当前最热门的Nosql数据库之一。
3、你们公司为什么要用Redis
这还用说,因为redis快啊,这么回答就完了,谁不知道redis快,并且又不快的缓存框架吗?你得回答出Redis的优点,比如
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
那都说redis快,为什么快?简单说3个点:
- 1、纯粹的内存操作
Redis 是在内存中进行键值存储。
Redis 中的每次读写操作都相当于从内存的变量中进行读写。
访问内存比直接访问磁盘快几个数量级,因此Redis 比其他数据存储快得多。
- 2、单线程
最大限度地减少由于线程创建或销毁而产生的 CPU 消耗
最大限度地减少上下文切换造成的 CPU 消耗
减少锁开销,因为多线程应用程序需要锁来进行线程同步,而这容易出现错误
能够使用各种“线程不安全”命令,例如 Lpush
- 3、采用非阻塞IO多路复用机制
redis是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以IO操作在一般情况下都不能直接返回,这会导致某一个文件的IO阻塞会导致整个进程无法为其他客户端提供服务,而IO多路复用就可以解决这个问题。IO多路复用机制,就是通过一种机制,可以同时监听多个状态,当状态发生变化(一把为就绪),则通知程序进行相应的读写操作。
4、Redis支持哪些数据结构,底层结构是什么
跳跃表:将有序链表中的部分节点分层,每一层都是一个有序链表(1)可以快速查找到需要的节点O(logn),额外存储了一倍空间(2)可以在O(1)的时间复杂度下,快速获得跳跃表的头节点、尾节点、长度和高度。
散列表(hash),是用来存储键值对的一种数据结构,redis整个数据库是用字典来存储的(Hash+数组+链表),redi字典实现包括:字典(dict)、Hash表(dictht)、Hash表节点(dictEntry)。字典达到存储上限(阈值0.75)需要rehash(扩容)
1、初次申请默认容量为4个dictEntry,非初次申请为当前hash表容量的一倍
2、rehashidx=0表示要进行rehash操作
3、新增加的数据在新的hash表h[1],修改、删除、查询在老的hash表[0]
4、将老的hash表h[0]的数据重新计算索引值后全部迁移到新的hash表h[1]中,这个过程称之为rehash
压缩列表zipList
是又一系列特殊编码的连续内存组成的顺序型数据结构,节省内容
整数集合intSet
是一个有序的整数升序、存储整数的连续存储结构,当redis集合类型的元素都是整数全额处于64位有符号整数范围内,使用该结构体存储。
快速列表quickList
是redis底层重要的数据结构,是redis3.2列表的底层实现,在此之前是用双向链表和压缩列表实现的。
Redis Stream
底层主要使用listpack(紧凑列表)和Rax树(基数树)
5、使用缓存要注意哪些问题
缓存雪崩:指缓存,在同一时间大面积的失效,后面的请求都会请求到数据库,造成数据库崩溃的情况。解决方案:本地缓存+限流+降级,避免数据库打死;缓存数据的时间设置随机,防止同时失效;可让缓存永不过期,但要有缓存更新机制。
缓存穿透:缓存和数据库都没有的数据,导致所有请求都达到数据库上,造成数据库短时间内承受大量请求而崩溃。解决方案:增加异常场景校验;如果缓存和数据库都没有数据,可以将空值进行缓存,但有效时间尽量短,避免被暴力攻击;布隆过滤器,将所有可能存在的数据哈希到一个足够大的bigmap中,一个一定不存在的数据也会被它拦截。
缓存击穿:并发访问特别多,同时读缓存没有读到,又同时去读数据库,引起数据库压力瞬间增大,造成压力。和缓存雪崩的区别是范围比雪崩小。解决方案:设置热点数据永远不过期;数据库操作加互斥锁;缓存预热。
数据不一致:例如当带宽被打满或机房网络故障,缓存更新失效,新数据没有写入缓存会导致缓存和DB数据不一致。解决方案:更新缓存要有重试机制,例如将失败的key放入MQ,异步不间断重试更新;缓存时间适当调短;
数据并发竞争:例火车票信息过期,但仍然有大量用户查询车次信息。会导致并发竞争读取的问题。解决方案:缓存数据可保持多个备份,减少并发竞争。
热点Key:高流量缓存key,例如秒杀、热门商品等。都会出现高流量访问情况,对redis操作高访问压力。解决方案:提前评估热点key;将key分散存储多个节点,客户端随机访问不通节点,分散压力;缓存集群可单节点扩容;利用多次缓存抗压;缓存更新时要加锁,限制逃逸流量。
BigKey:某个key存储的value信息量巨大,造成带宽被占用,影响其他接口使用。解决方案:杜绝大value;对value进行合适拆分;多次缓存应对。
猜你喜欢
- 2024-10-25 Caffeine高性能本地缓存框架初探(caffeine缓存原理)
- 2024-10-25 Redis学习3——Redis应用之缓存(redis的缓存的使用方式)
- 2024-10-25 Java高级——缓存的使用场景(java缓存机制)
- 2024-10-25 java中常用的几种缓存类型介绍(java常用缓存技术)
- 2024-10-25 本地缓存之王caffeine#代码(本地缓存 js)
- 2024-10-25 skywalking agent 本地缓存队列参数设置
- 2024-10-25 史上最实用的:分布式缓存方案(分布式缓存设计方案)
- 2024-10-25 使用Guava作为本地缓存让系统飞起来
- 2024-10-25 深究分布式缓存的九个点(分布式缓存技术有哪些)
- 2024-10-25 面试题之java缓存总结,从单机缓存到分布式缓存架构
你 发表评论:
欢迎- 最近发表
-
- pyinstaller打包python程序高级技巧
- 将python打包成exe的方式(python打包成exe的方法)
- Python打包:如何将 Flask 项目打包成exe程序
- py2exe实现python文件打包为.exe可执行程序(上篇)
- 如何将 Python 项目打包成 exe,另带卸载功能!
- Python打包成 exe,太大了该怎么解决?
- 可视化 Python 打包 exe,这个神器绝了!
- 案例详解pyinstaller将python程序打包为可执行文件exe
- Cocos 3.x 菜鸟一起玩:打包window程序
- 怎么把 Python + Flet 开发的程序,打包为 exe ?这个方法很简单!
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)