字节 后端开发一到三面 许愿offer
字节一面
Java用多久
技术书籍
HashMap底层 数组加链表/红黑树(jdk8)
数组链表区别
Redis数据类型
字符串、数组(双端)、散列表、集合、有序集合(每个存储的值对应一个score,用于排序)
Redis 缓存穿透, 缓存击穿
缓存穿透
查询一个一定不存在的数据,数据既不存在于Redis中,也不存在于数据库中
解决方案
1. 布隆过滤器
维护一个bitmap,添加数据时,对一个key计算多个哈希,哈希值对应bitmap位设置为1。
当要查询时,对于一个key也是同样计算多个哈希,如果某个哈希值对应的bitmap值不为1,可以肯定该key一定不存在。
但如果各个哈希值对应bitmap的值都为一,也只是可能存在该key。
2. 对查询到的不存在结果做缓存,过期时间设置不会过长
3. 校验
缓存雪崩
缓存的数据设置了统一的过期时间,当某一时刻缓存同时过期,大量请求直接落到数据库上,就会对数据库造成很大压力甚至崩溃
解决方案
缓存过期时间随机分配,在原有过期时间上加上一个随机值
分级缓存
热点数据永不过期
互斥锁:控制读数据写缓存的线程数量
熔断机制,限流降级
流量达到阈值,直接返回“系统拥挤”之类的提示,防止过多的请求打在数据库上将数据库击垮,至少能保证一部分用户是可以正常使用,其他用户多刷新几次也能得到结果。
事后:开启Redis持久化机制,尽快恢复缓存数据
缓存击穿
类似于缓存雪崩,但缓存击穿是针对一个设置了过期时间的热点数据,该数据可能被大量并发请求访问。当该数据过期时,如果此时有大量并发请求访问,会在更新缓存前,这些请求就会落在数据库上,可能导致数据库崩溃。
解决方案
热点数据永不过期
互斥锁
Redis持久化
RDB快照
适合备份、灾难恢复
恢复大数据集时比AOF快
出现故障时丢失的数据比AOF多
数据集大时耗时长
AOF(append only file)
追加方式有每个写命令都同步,每秒同步,操作系统决定何时同步(no)
每秒同步情况下仍可以保持良好的性能,而且在故障时最多丢失一秒的数据
Redis可以在AOF文件体积较大时,自动在后台对AOF进行重写,重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。
AOF文件体积通常大于RDB文件体积
AOF处理巨大写入时会降低Redis性能
AOF相比快照的好处
见上
RabbitMQ 作用
削峰降流
业务解耦
异步通知
为什么不开个线程处理异步通知
-
第一是可以提高应用的稳定性,当程序崩溃后,写入外部消息队列的数据依旧是保存的
-
用线程的话,会占用主服务器资源,消息队列的话,可以放到其他机器上运行,让主服务器尽量多的服务其他请求
-
解耦更充分,架构更合理 多线程是在编程语言层面解决问题 消息队列是在架构层面解决问题
-
用线程池ExecutorService异步处理:我理解ExecutorService其实也是内部使用了队列(如LinkedBlockingQueue),所以从设计上,其实和使用中间件的消息队列是差不多一致的。只是这里应用服务器既充当生产者又充当消费者,也是消息队列中间件的实现者。这种应该适合非分布式的架构,比如简单的只有一台服务器。
RabbitMQ 最终一致性
消费端可以通过MQ自身的重发机制来保证消息被消费
基于事务消息(只有RocketMQ支持)
-
生产者预发送一个消息给MQ
-
MQ存储该消息为待发送状态
-
MQ向生产者返回ACK
-
生产者执行业务逻辑
-
生产者将业务逻辑执行结果发送给MQ
-
MQ根据执行结果选择将消息删除或设置为可发送
-
发送状态为可发送的消息给消费者
-
消费者返回ACK
基于本地消息
核心在于执行业务操作时,将一条消息数据记录到数据库,并且消息数据的记录与业务数据的记录必须在同一个事务内完成
通过一个定时任务轮询数据库中状态为待发送的消息,然后将消息发送给MQ,发送成功后MQ返回确认
弊端在于每个业务系统都需要在对应的业务库创建一张消息表来存储消息。针对这个问题,我们可以将该功能单独提取出来,做成一个消息服务来统一处理
基于消息服务
模拟了事务消息的预发送过程
生产者会预发送一个消息到消息服务,并执行业务逻辑
消息服务将消息存储为待发送状态
业务逻辑执行完成后生产者会向消息服务发送业务执行结果
消息服务设置定时任务,轮询长时间未变为可发送状态的消息,并通过生产者提供的确认接口检查业务执行结果,如果业务成功,将消息修改为可发送状态。
消息服务还有另一个定时任务,轮询可发送状态的消息,并将其发送给MQ
HTTP HTTPs
HTTPS是HTTP加上TLS或者SSL
HTTP的数据是明文传输的存在消息窃听,身份伪造,数据篡改等安全隐患
HTTP 有以下安全性问题:
-
使用明文进行通信,内容可能会被窃听;
-
不验证通信方的身份,通信方的身份有可能遭遇伪装;
-
无法证明报文的完整性,报文有可能遭篡改。
HTTPS通过使用安全层,实现了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。
加密
服务器生成一对公钥私钥
将公钥发送给客户端
客户端生成对称密钥
客户端使用公钥对对称密钥加密
将加密后的对称密钥发送给服务端
开始通信
认证
使用证书进行认证
a.服务方S向第三方机构CA提交公钥、组织信息、个人信息(域名)等信息并申请认证;
b.CA通过线上、线下等多种手段验证申请者提供信息的真实性,如组织是否存在、企业是否合法,是否拥有域名的所有权等;
c.如信息审核通过,CA会向申请者签发认证文件-证书。 证书包含以下信息:申请者公钥、申请者的组织信息和个人信息、签发机构 CA的信息、有效时间、证书序列号等信息的明文,同时包含一个签名; 签名的产生算法:首先,使用散列函数计算公开的明文信息的信息摘要,然后,采用 CA的私钥对信息摘要进行加密,密文即签名;
d.客户端 C 向服务器 S 发出请求时,S 返回证书文件;
e.客户端 C读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,然后,利用对应 CA的公钥解密签名数据,对比证书的信息摘要,如果一致,则可以确认证书的合法性,即公钥合法;
f.客户端然后验证证书相关的域名信息、有效时间等信息;
g.客户端会内置信任CA的证书信息(包含公钥),如果CA不被信任,则找不到对应 CA的证书,证书也会被判定非法。
完整性保护
提供报文摘要功能进行完整性保护
HTTPS由于需要进行加密解密等过程,速度更慢
证书费用昂贵
对称加密非对称加密
对称加密,通信双方使用同一密钥进行加密解密,需要考虑如何将密钥传递给对方
非对称加密,加密和解密使用不同密钥,公钥加密,私钥解密
对称加密安全隐患
明文传输对称密钥可能被第三方窃取
截获公钥伪造身份可能有什么隐患
中间人截获服务器发送的公钥,向服务端发送公钥加密后的对称密钥,与服务端建立通信
中间人自己生成一对公钥和私钥,将公钥发送给客户端,从而与客户端建立通信
中间人可以截获客户端和服务器端通信的内容并加以篡改。
进程线程
进程通信
僵尸进程
算法
-
重复字符交替输出
-
0 --> 01 1 --> 10
字节二面
static
静态变量存储位置
静态变量初始化过程
synchronized修饰静态字段
Class类型对象存储位置
讲一下synchronized
死锁
死锁预防
算法
完全二叉树最后一个节点
先增后减数组,查找k
字节三面
项目介绍一下
Redis会什么说一下吧
持久化
缓存穿透、击穿、雪崩
Redis数据结构,用过什么
一致性哈希了解吗
sql调优,索引没命中就要全表扫描怎么优化呢
数据库事务隔离级别
考研相关