- 说说你的⼯作经历?
- 项⽬主要负责哪⼏个模块?
- 画出你项⽬的结构图
- Eureka是如何进⾏服务注册的?
a. 每30s发送⼼跳检测重新进⾏租约,如果客户端不能多次更新租约,
它将在90s内从服务器注册中⼼移除。
a. 注册信息和更新会被复制到其他Eureka 节点,来⾃任何区域的客户
端可以查找到注册中⼼信息,每30s发⽣⼀次复制来定位他们的服务,
并进⾏远程调⽤。
b. 客户端还可以缓存⼀些服务实例信息,所以即使Eureka全挂掉,客户
端也是可以定位到服务地址的。 - 如果服务宕机或者⽆法访问了,我还去请求该服务,Eureka会怎么处理?
会有什么现象?
Eureka服务注册中⼼的失效剔除与⾃我保护机
制:https://www.jianshu.com/p/6cf86e0392a3 - 谈谈Eureka的保护机制
Eureka Server的⾃我保护机制会检查最近15分钟内所有Eureka
Client正常⼼跳的占⽐,如果低于85%就会被触发。
我们如果在Eureka Server的管理界⾯发现如下的红⾊内容,就说明
已经触发了⾃我保护机制。
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING
INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN
THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED
JUST TO BE SAFE.
当触发⾃我保护机制后Eureka Server就会锁定服务列表,不让服务
列表内的服务过期,不过这样我们在访问服务时,得到的服务很有可能是已经失
效的实例,如果是这样我们就会⽆法访问到期望的资源,会导致服务调⽤失败,
所以这时我们就需要有对应的容错机制、熔断机制,我们在接下来的⽂章内会详
细讲解这块知识点。
我们的服务如果是采⽤的公⽹IP地址,出现⾃我保护机制的⼏率就会⼤
⼤增加,所以这时更要我们部署多个相同InstanId的服务或者建⽴⼀套完整的
熔断机制解决⽅案。
⾃我保护开关
如果在本地测试环境,建议关掉⾃我保护机制,这样⽅便我们进⾏测
试,也更准备的保证了服务实例的有效性!!!
关闭⾃我保护只需要修改application.yml配置⽂件内参
数eureka.server.enable-self-preservation将值设置为false即可。 - Ribbon的负载均衡是⾯向服务内部还是外部的?
外部,https://blog.csdn.net/u013087513/article/details/79775306 - Ribbon如何实现负载均衡的?
这篇讲的⾮常好:https://www.jianshu.com/p/e459f43ef96d - 如果没有Eureka,我能直接通过Ribbon进⾏服务请求吗?
可以的,需要导⼊ eureka-client-cat
,https://blog.csdn.net/wangmx1993328/article/details/95513359 - Hystrix如何实现熔断?
Hystrix在运⾏过程中会向每个commandKey对应的熔断器报告成功、失
败、超时和拒绝的状态,熔断器维护计算统计的数据,根据这些统计的信息来确
定熔断器是否打开。如果打开,后续的请求都会被截断。然后会隔⼀段时间默认
是5s,尝试半开,放⼊⼀部分流量请求进来,相当于对依赖服务进⾏⼀次健康检
查,如果恢复,熔断器关闭,随后完全恢复调⽤。如下图: - 当服务⽆法访问时,是直接熔断还是降级?
先降级,后熔断。 - 怎么样才会出现熔断?
熔断就跟保险丝⼀样,当⼀个服务请求并发特别⼤,服务器已经招架不
住了,调⽤错误率飙升,当错误率达到⼀定阈值后,就将这个服务熔断了。熔断
之后,后续的请求就不会再请求服务器了,以减缓服务器的压⼒。 - 在Springcloud中,消费者调⽤提供者的流程是如何的?请画图
springcloud的⼯作原理
springcloud由以下⼏个核⼼组件构成:
Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka
Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,
从⽽知道其他服务在哪⾥
Ribbon:服务间发起请求的时候,基于Ribbon做负载均衡,从⼀个服
务的多台机器中选择⼀台
Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求
URL地址,发起请求
Hystrix:发起请求是通过Hystrix的线程池来⾛的,不同的服务⾛不同
的线程池,实现了不同服务调⽤的隔离,避免了服务雪崩的问题
Zuul:如果前端、移动端要调⽤后端系统,统⼀从Zuul⽹关进⼊,由
Zuul⽹关转发请求给对应的服务 - Redis的集群⽅式有哪些?
主从、哨兵、redis-cluster:https://uule.iteye.com/blog/2438778 - 如果你原来读取的Redis中的数据,它的数据的结构发⽣了变化,如何在
不改变代码的情况下进⾏处理,使下游业务不受影响? - Redis的持久化⽅式有哪些?说说他们的具体实现、
Redis有两种持久化的⽅式:快照(RDB⽂件)和追加式⽂件(AOF⽂
件):
i. RDB持久化⽅式会在⼀个特定的间隔保存那个时间点的⼀个数据
快照。
ii. AOF持久化⽅式则会记录每⼀个服务器收到的写操作。在服务启
动时,这些记录的操作会逐条执⾏从⽽重建出原来的数据。写操作
命令记录的格式跟Redis协议⼀致,以追加的⽅式进⾏保存。
iii. Redis的持久化是可以禁⽤的,就是说你可以让数据的⽣命周期
只存在于服务器的运⾏时间⾥。
iv. 两种⽅式的持久化是可以同时存在的,但是当Redis重启时,
AOF⽂件会被优先⽤于重建数据。 - 使⽤Redis的过程中有没有遇到什么问题?
1、缓存和数据库双写⼀致性问题解决⽅案
前提是对数据有强⼀致性要求,不能放缓存;
只能降低不⼀致发⽣的概率,⽆法完全避免;
只能保证最终⼀致性。
1)采⽤正确的更新策略,先更新数据库,再删缓存
2)可能存在删除缓存失败的问题,提供⼀个补偿措施:如利⽤消
息队列。
2、缓存雪崩解决⽅案
(⼤并发项⽬,流量在⼏百万)
-利⽤互斥锁:会使吞吐量下降
-给缓存加失效时间:随机值,避免集体失效
-双缓存
3、缓存穿透解决⽅案
(⼤并发项⽬,流量在⼏百万)
-利⽤互斥锁
-采⽤异步更新策略,⽆论Key是否取到值都直接返回
-提供⼀个能迅速判断请求是否有效的拦截机制(布隆过滤器)
4、缓存并发竞争解决⽅案
-不要求顺序时,准备⼀个分布式锁,同时去抢锁,然后在set操
作。
-要求顺序时,在数据写⼊数据库时,需要保存⼀个时间戳。
-利⽤队列,将set操作变成串⾏访问。 - Redis的内存回收机制有哪些?
了解:https://juejin.im/post/5d107ad851882576df7fba9e - Redis的过期策略有哪些?简单介绍下不同策略
- 定时过期:每个设置过期时间的key都需要创建⼀个定时器,到过期
时间就会⽴即清除。该策略可以⽴即清除过期的数据,对内存很友好;但是会占
⽤⼤量的CPU资源去处理过期的数据,从⽽影响缓存的响应时间和吞吐量。 - 惰性过期:只有当访问⼀个key时,才会判断该key是否已过期,过期
则清除。该策略可以最⼤化地节省CPU资源,却对内存⾮常不友好。极端情况可
能出现⼤量的过期key没有再次被访问,从⽽不会被清除,占⽤⼤量内存。 - 定期过期:每隔⼀定的时间,会扫描⼀定数量的数据库的expires字
典中⼀定数量的key,并清除其中已过期的key。该策略是前两者的⼀个折中⽅
案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使
得CPU和内存资源达到最优的平衡效果。(expires字典会保存所有设置了过期时
间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是
该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存
的所有键。) - 说说Redis的淘汰策略?淘汰的算法可以修改或者⾃⼰重写吗?
默认:noeviction - 你们的项⽬中消息中间件⽤的是什么?
详⻅“⾯试题库/消息中间件” - 你们的Rabbit集群是怎么部署的?
- Rabbit集群之间的数据是如何同步的?同步⽅式还是异步⽅式?
- ⼀个队列中的数据你们是存放在⼀台机⼦上还是多台机⼦上?为什么?
- RabbitMQ内部结构是怎么样的?请画出RabbitMQ的架构图
RabbitMQ是⼀个⾼可⽤的消息中间件,⽀持多种协议和集群扩展。并
且⽀持消息持久化和镜像队列,适⽤于对消息可靠性较⾼的场合,基本模型如
下。https://fanchao01.github.io/blog/2018/02/09/rabbitmq-arch/ - 你们公司的数据库有分库分表吗?如何实现的?
详读https://www.cnblogs.com/butterfly100/p/9034281.html - Mysql的索引是基于什么?
a. InnoDB: - ⽀持事务处理
- ⽀持外键
- ⽀持⾏锁
- 不⽀持FULLTEXT类型的索引(在Mysql5.6已引⼊)
- 不保存表的具体⾏数,扫描表来计算有多少⾏
- 对于AUTO_INCREMENT类型的字段,必须包含只有该字段的索
引 - DELETE 表时,是⼀⾏⼀⾏的删除
- InnoDB 把数据和索引存放在表空间⾥⾯
- 跨平台可直接拷⻉使⽤
- 表格很难被压缩
b. MyISAM: - 不⽀持事务,回滚将造成不完全回滚,不具有原⼦性
- 不⽀持外键
- ⽀持全⽂搜索
- 保存表的具体⾏数,不带where时,直接返回保存的⾏数
- DELETE 表时,先drop表,然后重建表
- MyISAM 表被存放在三个⽂件 。frm ⽂件存放表格定义。 数据
⽂件是MYD (MYData) 。 索引⽂件是MYI (MYIndex)引伸 - 跨平台很难直接拷⻉
- AUTO_INCREMENT类型字段可以和其他字段⼀起建⽴联合索引
- 表格可以被压缩
c. 选择:因为MyISAM相对简单所以在效率上要优于InnoDB.如果系统
读多,写少。对原⼦性要求低。那么MyISAM最好的选择。且MyISAM
恢复速度快。可直接⽤备份覆盖恢复。如果系统读少,写多的时候,尤
其是并发写⼊⾼的时候。InnoDB就是⾸选了。两种类型都有⾃⼰优缺
点,选择那个完全要看⾃⼰的实际类弄。
d. InnoDB引擎表是基于B+树的索引组织表 - 说说B+树
- B-tree:
B-tree 利⽤了磁盘块的特性进⾏构建的树。每个磁盘块⼀个节点,
每个节点包含了很关键字。把树的节点关键字增多后树的层级⽐原来的
⼆叉树少了,减少数据查找的次数和复杂度。
B-tree巧妙利⽤了磁盘预读原理,将⼀个节点的⼤⼩设为等于⼀个
⻚(每⻚为4K),这样每个节点只需要⼀次I/O就可以完全载⼊。
B-tree 的数据可以存在任何节点中。 - B+tree:
B+tree 是 B-tree 的变种,B+tree 数据只存储在叶⼦节点中。这样在B
树的基础上每个节点存储的关键字数更多,树的层级更少所以查询数据更快,所
有指关键字指针都存在叶⼦节点,所以每次查找的次数都相同所以查询速度更稳
定; - 使⽤⾃增ID和UUID作为主键有什么不同?
(1).如果InnoDB表的数据写⼊顺序能和B+树索引的叶⼦节点顺序⼀致的
话,这时候存取效率是最⾼的。为了存储和查询性能应该使⽤⾃增⻓id做主键。
(2).对于InnoDB的主索引,数据会按照主键进⾏排序,由于UUID的⽆序
性,InnoDB会产⽣巨⼤的IO压⼒,此时不适合使⽤UUID做物理主键,可以把它
作为逻辑主键,物理主键依然使⽤⾃增ID。为了全局的唯⼀性,应该⽤uuid做索
引关联其他表或做外键。
https://blog.csdn.net/XDSXHDYY/article/details/78994045 - 说说数据库的事务隔离级别有哪些?
- 在代码中,我们如何实现事务?
1.增加@EnableTransactionManagement注解
2.在service的实现类或者⽅法上添加下⾯这个注解即可.事务管理器的
配置在多数据源那篇⾥已经配置过了.默认情况下只有
RuntimeException才回滚,为了让Exception也回滚,增加了 rollbackFor
= Exception.class. - 如果在⼀个事务中,代码业务流程很⻓,会有什么问题吗?为什么会出
现这种问题?
可能出现事务超时:
@Transactional(timeout = 60)
如果⽤这个注解描述⼀个⽅法的话,线程已经跑到⽅法⾥⾯,如果已经
过去60秒了还没跑完这个⽅法并且线程在这个⽅法中的后⾯还有涉及到对数据库
的增删改查操作时会报事务超时错误(会回滚)。如果已经过去60秒了还没跑完
但是后⾯已经没有涉及到对数据库的增删改查操作,那么这时不会报事务超时错
误(不会回滚)。 - 使⽤volatile关键字的时候有遇到过什么问题吗?为什么会出现这种问
题? - 请说说volatile的底层实现原理
深⼊理解:https://crowhawk.github.io/2018/02/10/volatile/ - 如何创建线程池?有什么参数?线程池的实现原理
实践操
作:https://blog.csdn.net/u011974987/article/details/51027795 - 你有什么问题想问我们的吗?
oppo2019年Java开发工程师(面试题)
最新推荐文章于 2023-06-30 09:00:00 发布