Java场景化面试宝典
2021-08-09 00:33:00 0 举报
AI智能生成
登录查看完整内容
java进阶面试题,实际场景问题解决方案,高级程序员必知必会问题。
作者其他创作
大纲/内容
系统调优
SQL调优
JVM调优
性能调优
List集合
banner
三个豆腐块
为你推荐条件
首页
Hash表
骨架星级
注册地
车龄
里程
车辆级别
排放标准
车源属性
燃料类型
筛选条件
场次
拍场模式
所有品牌车系
热门品牌
业务城市数据
查询条件
查询结果集
竞拍大厅
通过zset排序用户出价的品牌车系;每次出价的时候异步去更新redis的记录以及数据库
为你推荐
车源id存放在Zset缓存,从缓存中拿到车源id;再去ES中获取数据;
心愿单的查询条件
心愿单
一个月前未中标
近一个月未中标
交易失败
交易成功
我的出价
String
账户余额
保证金
我的账户
做自增操作
INCR
出价次数
关注次数
数据存入缓存
redis缓存
信息摘要算法5
概述
单向不可逆,无法解密
产生一个固定长度的散列码
特点
密码存储
信息完成性校验
使用场景
MD5
散列消息鉴别码
HMAC系列
SHA系列
加密方式
不可逆特点
不可逆加密
公钥加密,私钥解密
RSA
DSA/DSS
非对称加密方式
1.比对称加密更加安全可靠;
2.加密解密比对称加密慢很多
HTTPS建立SSL连接中有一个步骤就是,将服务端的公钥加密用于对称加密的密钥;也就是把数据传输的对称加密的密钥发送给服务端,这样客户端和服务端都知道了实际做数据传输的对称密钥了
非对称加密
加密解密都是用的同一个密钥
DES
3DES
AES
对称加密方式
1.加密解密速度快;
2.适用于大量数据加密
3.由于需要把密钥传递给需要用的对接方,在传递的密钥的过程中容易被人抓包,造成数据不安全;
HTTPS建立SSL连接之后,客户端和服务端使用的就是对称加密来传输数据;主要就是利用对称加密解密速度快的优势
场景
对称加密
对称加密性能高于非对称加密
性能
非对称加密安全性比对称加密安全性高
安全性
对称加密,加密解密都是用的同一个密钥;非对称加密,加密解密密钥是分开的;
加密解密方式
对称/非对称加密区别
可逆加密
可逆:可以通过解密的密钥获取到加密之前的数据;不可逆:数据是没有办法做解密操作,无法拿到解密之前的数据;
可逆/不可逆区别
增加数据被破解的难度
让相同的数据在被加密之后显示的数据是不一样的;
作用
加密盐
加密算法
查询和修改操作都是幂等;添加和删除不是幂等
分布式环境下怎么保证接口的幂等性
1.用户对于同一操作发起的一次请求或者多次请求结果都是一样。
天然幂等的
查询操作
删除一次和删除多次可能返回的数据不是一样
删除操作
如果把某个字段的值设置为1,那么不管多少次都是幂等
如果把某个字段值加1,那么就不是幂等
更新操作
重复提交会有幂等性问题
添加操作
具体操作
幂等性概述
一般场景:代码中通过代码逻辑判断
支付场景:通过唯一的订单id来判断重复
1.通过代码逻辑判断实现
支付场景:页面跳转的时候获取全局唯一的token,把token缓存起来;等到提交到后台的时候,再校验token是否存在,第一次提交成功就会删除token
使用场景:分布式环境
2.使用token机制实现
分布式环境中,做重复校验,直接用乐观锁实现
3.乐观锁
幂等性解决方案
接口幂等性
单点登录
全局业务中必须要是唯一
全局唯一
这个id最好是能递增
趋势递增
高性能
高可用
接入方便
分布式Id要求
简单
无网路消耗
优点
无业务意义
不是递增
存储消息空间大
UUID作为数据库主键,性能低下
缺点
UUID
获取数据库自增的主键作为全局ID
方式概述
实现简单
id是递增
数值类型查询速度快
如果数据是单节点,无法完全保证数据的高可以用
数据库自增id
给几台数据库服务器自增时候设置相应的步长(比如说,自增3,自增4),获取到自增id
解决单节点,并不能高可用问题
不利于后续扩容
数据库多主模式
从数据库批量获取自增ID
批量减少数据库压力
号段模式
号段方式是推荐的使用方式
数据库实现方式
通过node节点版本生成序列号
可以生成32位,64位
实现概述
ZK
利用的incr命令实现原子的自增
redis
正数位(占1比特)+ 时间戳(占41比特)+ 机器ID(占5比特)+ 数据中心(占5比特)+ 自增值(占12比特),总共64比特组成的一个Long类型。
雪花算法
和雪花算法类似
可自定义时间戳,机器ID,序列号
百度uid-generator
同时支持号段模式,雪花算法模式,可以切换
美团Leaf
号段模式的实现
滴滴(Tinyid)
全局唯一id生成方式
全局唯一id生成
1.先去查询数据是否存在
2.在做更新的时候对比当前数据的版本是否和第一次查询的时候版本号一致,一致才更新;
操作步骤
基于第一次查询和第二次做修改时候查询的数据来判断中间的数据有没有被修改过
原理
数据库乐观锁
使用redisson连接方式
通过RedisClient对象获取到RedissionLock对象
1.在try catch外面获取锁
通过RedissionLock对象进行加锁
分支主题
2.在try catch中加锁
3.在finally里面解锁(防止死锁,解不了锁)
设置成功,说明当前就获取到了Redis的锁
设置失败,说明其他请求已经向Redis中设置过了当前值,其他线程获取到了锁,当前线程会阻塞等待获取锁;
1.先判断key是否存在,不存在才会加锁;
2.如果key存在,那么通过lua脚本判断,获取锁的客户端id是否和当前客户端的id相同,也就是进行可重入判断;
3.如果客户端id也不一样,那么会返回一个当前获取锁需要等待的时间,并且进入while死循环中等待获取锁;
Lua脚本加锁过程
Redis分布式锁
1.通过zkClient对象创建临时节点,作为加锁
2.通过zkClient对象删除临时节点,作为解锁
1.zk是不允许创建相同的临时节点
2.如果zkclient对象发现已经相同的临时节点已经存在了,那么就会阻塞被阻塞;
3.阻塞实际上就是等待创建了这个节点的客户端去删除这个临时节点;
4.阻塞结束之后,创建临时节点,就获取到了锁
zk不允许重复创建临时节点
有创建临时节点,就会客户端就会被阻塞
本质
ZK分布式锁
分布式锁
强一致性
Consistency
可用性
Availability
分区容错性
Partition tolerance
CAP
这个理论中的一致性指强一致性,而不是弱一致性
CAP只能保证两点
一般情况下保证AP和最终一致性
CAP选择
分布式事物概述
集成了4中分布式事物解决方案
AT 模式、TCC 模式、Saga 模式和 XA 模式
seata解决方案
对代码无侵入性的分布式解决方案
AT模式概述
同一项目调用两个处于不同服务上的微服务修改接口
事物的第一阶段其实已经提交了;事物的回滚操作是在原来正向操作的基础上做的一个逆向操作,这个逆向操作seata已经帮你做了;
原来的一个insert操作变成delete操作;delete操作变成insert操作;update修改操作会修改回来;
seata
解决方案
超链接
AT模式
预留业务资源
Try
确认执行提交事物
Confirm
执行事物回滚
Cancel
事物3个操作
资源预留阶段
事物提交阶段/事物回滚阶段
TCC可以分成两个阶段
TCC概述
需要标记Try,confirm,cancel方法
Hmily轻量级分布式事务的框架, 无需搭建Hmily服务器
Seata
ByteTCC
EasvTransaction
TCC事物实现方式
TCC模式
流程比较长且只需要保证事物最终一致性的长事物解决方案
事物的参与者是其他公司的服务
每个事物都有其正向的操作和逆向的事物回滚操作
正向服务,逆向补偿服务都是开发者来实现的,对业务造成了很大的侵入性
第一阶段已经提交了事物,性能比较高;
事物回滚操作基于时间异步执行,效率高;
逆向补偿服务,易于理解,易于实现;
事物在第一阶段已经提交了,也就是没有预留动作保证隔离性。
优缺点
给调用提供一个接口给被调用方回调,用来不断的通知调用方,被调用者这边是否执行结果
最大努力通知
公司内部系统直接相互推送某个事物是否执行成功;相当于给其他系统通知这个事物是否成功。
消息队列通知
当前系统调用了内部的多个数据库,或者是多个服务,在调用方这边直接做数据回滚;
finnally里面做事物回滚
实现方式
Saga模式
第一阶段每个事物完成预提交并通知把结果告诉事物协调器;事物协调器等所有分支事物都操作完成,预提交之后;第二阶段协调器通知每个事物进行逐步的提交或者是逐步的回滚操作;
2PC协议
事物协调器向所有的事物发起者询问是否可以执行提交操作,并等待各个参与者节点的响应
参与者节点执行询问发起为止的所有事物操作,并记录到redo,undo日志中;
事物的各个参与者对事务管理器响应自己的事物是执行成功还是执行失败;
准备阶段
协调者只要收到一个事物失败或者超时,那么就会给每一个参与者发送回滚消息否则发送提交消息;
提交阶段
二阶段详细过程
理论基础
mysql oracle等关系型数据都是支持两阶段提交协议的,也就是有一个支持多个多个事物的接口;
两阶段提交主要保证了分布式事务的原子性:即所有结点要么全做要么全不做)
实现原理
同一项目中直连两个数据库,做修改操作
AtomMikos
<!-- atomikos 多数据源管理 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jta-atomikos</artifactId></dependency>
springBoot整合atomikos
<dependency><groupId>com.atomikos</groupId><artifactId>transactions-jdbc</artifactId><version>4.0.6</version></dependency>
spring整合atomikos
无整合开发
使用方式
事物过程
事物粒度大,高并发环境下,系统可用性比较低
XA模式
分布式事物模型
分布式事物
redis数据处理是单线程,memcache是多线程处理
线程操作
Redis支持更多更复杂的数据结构,memcache只支持keyvalue的字符串数据;
数据结构
Redis支持数据的持久化,会把数据同步到磁盘上;memcache不支持数据的持久化
数据安全性
Redis支持数据备份,需要开启主从模式;memcache不支持数据备份
数据备份
REDIS支持更多的过期策略;memcache支持的过期策略少
过期策略
Redis与MemCache的区别
分布式缓存
分布式定时任务
分布式系统问题
1.按照不同的业务划分不同的项目
同一业务下的定时任务模块
直接查询属于本业务的库
直接调用本业务的原子微服务
直接调用本服务的非原子微服务
获取本业务数据
1.调用其他原子的微服务
2.调用其他服务的非原子微服务
获取其他业务数据
Job
同一业务下消息队列模块
MQ
同一业务下pc端接口
web
同一业务下对APP接口
App
同一业务下原子的微服务接口
Ms
同一业务下非原子的微服务接口
可以聚合其他业务的原子的微服务接口
Api
2.同一业务下不同的功能划分
模块拆分方式
微服务项目
通过Redis的key的事件通知机制
Redis的事件通知,消息只会发送一次,不管客户端是否有收到(无消息确认机制)
需要对某些key的改变做监控
RocketMQ设置固定延时时间发送消息
延时的消息时间只能是十几个固定的延时时间
RocketMQ
1.正常队列不设置消费者,给单个消息设置超时时间;
2.设置死信队列和死信队列的消费者,把超时未发送的消息发送到死信队列;
RabbitMQ
时间轮定时任务
kafka
消息队列
先对数据先进行落库,再对数据库进行定时轮询
对数据库压力大
定时任务
实现Java的延时队列,这是固定的延时时间;
java延时队列
延时任务
验证码
NGINX
Tomcat
容器限流
队列
手动控制某些接口访问
gateway
Semaphore类控制并发访问数量
任务线程池控制方式
锁
服务器限流
限流方式
实现
令牌桶
漏斗桶
滑动窗口
计数器
子主题 5
限流算法
子主题 2
子主题 3
流量计算方式
接口限流
缓存
1.读多写少
限流
负载均衡
异步
2.高并发
3.资源访问冲突
秒杀系统的特点及对应解决方式
点击之后,一段时间之后才能再次被点击
按钮控制
需要收到验证码才能点击
验证码控制
控制方式
降低用户秒杀系统的点击频率
控制目的
应用层
CDN
网络层
负载均衡,反向代理,限流
降低服务器访问压力
负载层
缓存,异步,队列,限流,原子操作
降低对数据库的压力
服务层
乐观锁,悲观锁
数据库
不同层级对应解决方案
秒杀系统设计
CDN作用
lua脚本为啥可以原子性执行
高并发问题
实际问题
0 条评论
回复 删除
下一页