author:魏静崎
2025年04月02日
面试题else
注:来源包括自身面试经历,网络资料
I/O多路复用,select、poll、epoll的区别和应用
多路复用IO也是阻塞IO,只是阻塞的方法是select/poll/epoll。select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理是select/epoll这个函数会不断轮询所负责的IO操作,当某个IO操作有数据到达时,就通知用户进程。然后由用户进程去操作IO。
I/O多路复用的优势并不是对于单个连接能处理的更快,而是在于可以在单个线程/进程中处理更多的连接。
与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。
Select系统调用:是用来让我们的程序监视多个文件句柄的状态变化。程序会阻塞在select函数上,直到被监视的文件句柄中有一个或多个发生了状态变化。
Poll:的处理机制与Select类似,只是Poll选择了pollfd结构体来处理文件描述符的相关操作
epoll:是在Linux内核2.6引进的,是select和poll函数的增强版。与select相比,epoll没有文件描述符数量的限制。epoll使用一个文件描述符管理多个文件描述符,将用户关心的文件描述符事件存放到内核的一个事件列表中,这样在用户空间和内核空间只需拷贝一次。
websocket和http之类的区别
websocket适用于需要实时通信和双向数据流的场景,是持久连接。
http更适合于传统的客户端与服务器之间的短时请求相应的场景,连接一次后即关闭。
jwt原理、和cookie、session的区别
jwt:用户登录后,服务器生成jwt(服务器无需保存)和jwt签名密文,然后发送jwt给客户端(以cookie形式存储),用户下次访问就可以将jwt发给服务器
token的组成:生成的token分为header、payload、signature三部分,通过.连接。其中header包含了类型和加密算法,payload存储用户信息(这部分并非加密只是编解码),而signature则是结合header和payload及secret通过特定算法加密形成,确保了token的安全性。
https的SSL/TLS是如何加密的
SSL证书:保存在源服务器的数据文件
TLS握手过程:TCP三次握手以后,客户端会告诉服务端支持的TLS版本和加密套件并生成随机数1;服务端会响应服务端确认支持的TLS版本和选择的加密套件,并且也生成一个随机数2发给客户端;服务器再发一个响应来出示证书;服务器发送公钥给客户端;
客户端生成第三个随机数(预主密钥)并用公钥加密发给服务端
然后二者根据 第一随机数+第二随机数+预主密钥 = 会话密钥
也就是前半部分是非对称加密,之后是对称加密
http报文格式
请求报文格式:
1、请求行:由3部分组成,分别为:请求方法、URL以及协议版本
2、请求头部:请求报文添加了一些附加信息,由“名/值”对组成,每行一对,名和值之间使用冒号分隔
3、请求正文:可选部分,比如GET请求就没有请求正文
响应报文格式:
rpc协议报文格式
1、状态行:由3部分组成,分别为:协议版本,状态码,状态码描述
2、响应头部:与请求头部类似,为响应报文添加了一些附加信息
3、响应正文:
域名访问的过程
1、浏览器先会查询本地域名解析缓存(DNS缓存)。
2、缓存中没有该域名的IP地址,浏览器会向本地的域名解析器(通常是本地ISP提供的域名解析服务器)发送一个域名解析请求。
3、本地域名解析器会先查询自己的缓存,如果有该域名的IP地址,则返回缓存中的地址给浏览器。如果没有,则继续向根域名服务器发送请求。
4、根域名服务器收到解析请求后,会查看请求的顶级域名(比如.com、.net、.org等)的权威域名服务器的地址。
5、根域名服务器把权威域名服务器的地址返回给本地域名解析器。
6、本地域名解析器收到权威域名服务器的地址后,向该服务器发送请求。
7、权威域名服务器收到解析请求后,在自己的域名数据库中查找相应的IP地址,并将该地址返回给本地域名解析器。
8、本地域名解析器收到IP地址后,将其保存到缓存中,并将地址发送给用户的浏览器。
http流程
dns解析得到ip和端口号,浏览器与web服务器建立一个 TCP 连接,浏览器给Web服务器发送一个http请求。
传输层:在这里报文打上了传输头的包头,主要包含端口号,以及tcp的各种制信息,这些信息是直接得到的,因为接口中需要指定端口。这样就组成了tcp的数据传送单位segment。tcp是一种端到端的协议,利用这些信息,比如tcp首部中的序号确认序号,根据这些数字,发送的一方不断的进行发送等待确认,发送一个数据段后,会开启一个计数器,只有当收到确认后才会发送下一个,如果超过计数时间仍未收到确认则进行重发,在接受端如果收到错误数据,则将其丢弃,这将导致发送端超时重发。通过tcp协议,控制了数据包的发送序列的产生,不断的调整发送序列,实现流控和数据完整。
网络层:整个查找过程是这样的:
(1)根据目的地址,得到目的网络号,如果处在同一个内网,则可以直接发送。
(2)如果不是,则查询路由表,找到一个路由。
(3)如果找不到明确的路由,此时在路由表中还会有默认网关,也可称为缺省网关,IP用缺省的网关地址将一个数据传送给下一个指定的路由器,所以网关也可能是路由器,也可能只是内网向特定路由器传输数据的网关。
(4)路由器收到数据后,它再次为远程主机或网络查询路由,若还未找到路由,该数据包将发送到该路由器的缺省网关地址。而数据包中包含一个最大路由跳数,如果超过这个跳数,就会丢弃数据包,这样可以防止无限传递。路由器收到数据包后,只会查看网络层的包裹数据,目的ip。所以说它是工作在网络层,传输层的数据对它来说则是透明的。
如果上面这些步骤都没有成功,那么该数据报就不能被传送。如果不能传送的数据报来自本机,那么一般会向生成数据报的应用程序返回一个“主机不可达”或 “网络不可达”的错误。
http1.0 1.1、2.0、3.0的区别
HTTP的端口是80,==HTTPS的端口是443==.
HTTP1.0 使用的是非持久连接,主要缺点是客户端必须为每一个待请求的对象建立并维护一个新的连接。
HTTP1.1==支持长连接==。在HTTP1.0的基础上引入了更多的缓存控制策略。 引入了==请求范围==设置,优化了带宽。缺点是传输内容是明文,不够安全
HTTP2.0 ==多路复用==,HTTP1.1是多个请求串行化单线程处理,HTTP 2.0是并行执行,一个请求超时并不会影响其他请求。这个技术可以只通过一个 TCP连接就可以传输所有的请求数据。==多路复用可以绕过浏览器限制同一个域名下的请求数量的问题,进而提高了网页的性能。==
HTTP3.0 ==使用基于UDP的QUIC协议,则可以内建与TCP中不同的连接标识方法,从而在网络完成切换之后,恢复之前与服务器的连接==。
http状态码
1xx:信息性状态码,表示服务器已接收了客户端请求,客户端可继续发送请求。
一般不发送
2xx:成功状态码,表示服务器已成功接收到请求并进行处理。
200:OK
201:已创建
202:已接受
3xx:重定向状态码,表示服务器要求客户端重定向。
4xx:客户端错误状态码,表示客户端的请求有非法内容。
400:语法错误
403:无权限
404:无法找到
5xx:服务器错误状态码,表示服务器未能正常处理客户端的请求而出现意外错误。
500:服务器内部错误
504:网关错误
http缓存机制
常见的http缓存只能缓存get请求响应的资源,根据是否需要重新向服务器发起请求来分类,可分为(强制缓存,协商缓存) 根据是否可以被单个或者多个用户使用来分类,可分为(私有缓存,共享缓存) 强制缓存如果生效,不需要再和服务器发生交互,而协商缓存不管是否生效,都需要与服务端发生交互。
tcp的time_wait是什么,tcp连接大量time_wait什么情况
是主动关闭的一方,在使用FIN|ACK|FIN|ACK四分组正常关闭TCP连接的时候会出现这个TIMEWAIT。
在高并发短连接的TCP服务器上,当服务器处理完请求后立刻按照主动正常关闭连接。这个场景下,会出现大量socket处于TIMEWAIT状态。
高并发可以让服务器在短时间范围内同时占用大量端口,而端口有个0~65535的范围,并不是很多。
解决办法:
a、修改TIME_WAIT连接状态的上限值
b、启动快速回收机制
c、开启复用机制
d、修改短连接为长连接方式
e、 由客户端来主动断开连接
tcp如何保证可靠传输
TCP协议通过确认应答、超时重传、流量控制、拥塞控制等机制来保证传输的可靠性。
tcp最后一次可以重传数据吗
tpc粘包、分包
粘包:指TCP协议中,发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
TCP协议粘包拆包问题是因为TCP协议数据传输是基于字节流的,它不包含消息、数据包等概念,需要应用层协议自己设计消息的边界,即消息帧(Message Framing)。如果应用层协议没有使用基于长度或者基于终结符息边界等方式进行处理,则会导致多个消息的粘包和拆包。
什么协议是基于udp or tcp的
基于TCP的应用层协议有:SMTP、TELNET、HTTP、FTP、rpc(可以基于http也可以直接基于tcp)
基于UDP的应用层协议:DNS、RIP(路由选择协议)
ip路由的过程
IP路由过程包括查询路由表、封装数据包、发送ARP请求、等待ARP响应、完成MAC地址解析、发送数据包六个步骤。
get和post的区别
从接口去看,本质上一样,只是请求方式的差异,浏览器和服务端可能有不同限制。
但是一般使用restful规范定义,get参数放在query中,post放在body中,具体是因为post参数可能很多,但是url有上限
es的优势
是全文搜索框架的非关系型数据库,采用Restful API标准,高扩展性、高可用,采用倒排索引,传统数据库采用B+树索引。
倒排索引:把文件ID对应到关键词的映射转换为关键词到文件ID的映射,每个关键词都对应着一系列的文件,这些文件中都出现这个关键词。单词-文档矩阵是表达两者之间所具有的一种包含关系的概念模型,倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引,可以根据单词快速获取包含这个单词的文档列表。
es与mysql的数据一致性问题
双写:简单粗暴,但是这种方式代码侵入性强,要在写 mysql 的地方写 es 的代码。
binlog+kafka:解析mysql binlog,直接同步到es,可以在中间使用消息队列削峰。代码侵入性低,但是做不到秒级同步。
数据库同时处理两条一样的get or insert事务如何确保结果符合预期,数据库如何处理快照读和当前读,redis有类似的问题吗
left join和join的区别
mysql一条update语句的执行流程
客户端发起update请求
中间省略解析器,优化器等步骤,将请求传给存储引擎
先从磁盘或者缓存中找到id = 1 的这条数据,然后修改并记录到内存中
存储引擎记录 redo log 日志,此时事物状态是prepare状态
将修改的结果告诉服务端
服务端记录bin log 日志
记录之后服务端提交事物
此时事物状态为commit状态
存储引擎记录回滚日志
最终修改磁盘文件 ,完成更新
数据库主从同步问题
一般数据库都是读多写少,有一个思路就是采用数据库集群的方案,做主从架构、进行读写分离,这样同样可以提升数据库的并发处理能力。
复制三步骤:
步骤1:Master
将写操作记录到二进制日志(binlog
)。
步骤2:Slave
将Master
的binary log events拷贝到它的中继日志(relay log
);
步骤3:Slave
重做中继日志中的事件,将改变应用到自己的数据库中。
如何解决一致性问题:
读写分离情况下,解决主从同步中数据不一致的问题, 就是解决主从之间 数据复制方式 的问题,如果按照数据一致性 从弱到强 来进行划分,有以下 3 种复制方式。
方法 1:异步复制
MVSQL默认的复制方式,在异步复制的方式中主库在执行完事务操作以后,会立刻给客户端返回。他不需要关心从库是否完成该事务的执行。
这种方式会导致一个问题,那就是当主库出现故障时,那么当从库升级为主库之后,他会丢失了这次事务的变更内容。
方法 2:半同步复制
半同步复制是在执行完一个事务之后,也不会立刻给客户端反馈,但是也不会等所有从库都完成事务,而是等其中一个从库完成接收到事件之后,再反馈给客户端。
在半同步复制这个方案中,会在事务提交的2阶段都完成之后,等待从库接收到binlog,然后再返回成功。
方法 3:组复制
首先我们将多个节点共同组成一个复制组,在执行读写(RW)事务的时候,需要通过一致性协议层(Consensus 层)的同意,也就是读写事务想要进行提交,必须要经过组里“大多数人”(对应 Node 节点)的同意,大多数指的是同意的节点数量需要大于 (N/2+1),这样才可以进行提交,而不是原发起方一个说了算。而针对只读(RO)事务则不需要经过组内同意,直接 COMMIT 即可。
方法 4:全同步复制
全同步复制的这个方式中,当主库执行完一个事务之后,他会等待所有的从库完成数据复制之后,才会给客户端反馈。这种方式安全性可以保障了,但是性能很差。如果从库比较多的话,会导致整个过程更加长。
为什么mysql一张表建议最大2000w数据
因为三层索引理论上最多可以存储2000w的数据,再大就会降低性能。
原理:InnoDB是以页为单位进行存储和管理数据的,为了提高查询效率,InnoDB以索引组织表数据,且每张表至少会有一个索引(聚簇/主键索引)。所以在组织表数据时会存在索引页和数据页。
InnoDB页大小默认为16KB,「文件头」、「页头」、「页目录」等占用了1/16的空间,剩下的15KB就用来存行记录。一行索引记录会占用8B加上指针占用的空间6B,也就是14B。那么索引页就可以存放15*1024/14≈1098
行记录。- 如果树的高度为3,2层索引页和1层数据页,那么可以存放1098*1098*15≈2000W
行记录。
不同索引在叶子结点的区别
MySQL的Innodb中,B+树索引只有两种,一个是聚簇索引(主键索引),一个是非聚簇索引(非主键的其他索引,无论是否唯一),聚簇索引索引叶子节点键为主键值包含整行数据,非聚簇索引的叶子节点的键为索引字段值是主键的值。所以当命中普通索引时查询的字段不在索引中,会先获取到主键的值后再去主键的索引树中获取整行数据,这个称之为回表。然后覆盖索引(联合索引)就是因为不用回表所以会更快一些。
不适合使用索引的情况
数据量不大、数据频繁读写、对存储有严格限制(索引要占用内存)
如何检测并解决数据库死锁
通过检查数据库表,能够检查出是哪一条语句被死锁,产生死锁的机器是哪一台。
1)用dba用户执行以下语句
select username,lockwait,status,machine,program from v$session where sid in
(select session_id from v$locked_object)
如果有输出的结果,则说明有死锁,且能看到死锁的机器是哪一台。字段说明:
Username:死锁语句所用的数据库用户;
Lockwait:死锁的状态,如果有内容表示被死锁。
Status: 状态,active表示被死锁
Machine: 死锁语句所在的机器。
Program: 产生死锁的语句主要来自哪个应用程序。
解决:查找并kill掉进程
mysql的常见锁
行锁(Record Locks):行级锁,作用在索引上
间隙锁(Gap Locks):间隙锁本质上是用于阻止其他事务在该间隙内插入新记录,而自身事务是允许在该间隙内插入数据的。也就是说间隙锁的应用场景包括并发读取、并发更新、并发删除和并发插入。本质上是不区分共享间隙锁或互斥间隙锁的,而且间隙锁是不互斥的,即两个事务可以同时持有包含共同间隙的间隙锁。
临键锁(Next-key Locks):是记录锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间。
共享锁/排他锁(Shared and Exclusive Locks):当前写操作没有完成前,它会阻断其他写锁和读锁
意向共享锁/意向排他锁(Intention Shared and Exclusive Locks):是自动加的,当事务准备在某条记录上加S锁时,需要先在表级别加一个IS锁。/当事务准备在某条记录上加X锁时,需要先在表级别加一个IX锁。(意向锁是 InnoDB 自动加的,不需要用户干预。)
插入意向锁(Insert Intention Locks)
自增锁(Auto-inc Locks):主要用于事务中插入自增字段,也就是我们最常用的自增主键id。
Redis中set、setex、setnx的用法和区别
set:将字符串值 value 关联到 key 。如果 key 已经持有其他值, SET 就覆写旧值,无视类型。
setx:将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位)。如果 key 已经存在, SETEX 命令将覆写旧值。
setnx:将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作。SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。 设置成功,返回 1 。 设置失败,返回 0 。
redis储存太多会发生OOM吗
会发生,解决办法:设置最大内存、设置内存淘汰策略、redis持久化、分片存储
redis存储热点信息如果太多怎么办
考虑分布式集群、使用bitmap、bitset等数据结构,将不常用数据存到数据库中
redis为什么使用混合持久化,原理是什么
使用RDB持久化会有数据丢失的风险,但是恢复速度快,而使用AOF持久化可以保证数据完整性,但恢复数据的时候会很慢。于是从Redis4之后新增了混合AOF和RDB的模式,先使用RDB进行快照存储,然后使用AOF持久化记录所有的写操作,当重写策略满足或手动触发重写的时候,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从RDB何AOF两部分恢复数据,即保证了数据完整性,又提高了恢复的性能。
redis大key问题
大 key 并不是指 key 的值很大,而是 key 对应的 value 很大。读写大key会导致超时严重,甚至阻塞服务。
解决:拆分为多个小key,确保每个key的成员数量或者大小在合理范围内,通过get不同的key或者使用mget批量获取。
消息队列相关
消息队列分布式如何保证消息有序
对于 Kafka 来说,一个 topic 下同一个 partition 中的消息肯定是有序的,生产者在写的时候可以指定一个 key,通过我们会用订单号作为 key,这个 key 对应的消息都会发送到同一个 partition 中,所以消费者消费到的消息也一定是有序的。
那么为什么 Kafka 还会存在消息错乱的问题呢?问题就出在消费者身上。通常我们消费到同一个 key 的多条消息后,会使用多线程技术去并发处理来提高消息处理速度,否则一条消息的处理需要耗时几十 ms,1 秒也就只能处理几十条消息,吞吐量就太低了。而多线程并发处理的话,binlog 执行到数据库的时候就不一定还是原来的顺序了。
kafka消息重试机制
这里需要建立一个专门用于重试的topic(retry topic);
当消费者没有正确消费这条消息的时候,
则将这条消息转发(发布)到重试主题(retry topic)上,然后提交消息的偏移量,以便继续处理下一个消息;
kafka为什么性能好,为什么吞吐量高
Kafka的⽣产者采⽤的是 异步发送消息机制。
当发送⼀条消息时,消息并没有发送到Broker而是缓存起来,然后直接向业务返回成功。
当缓存的消息达到⼀定数量时再批量发送给Broker。这种做法减少了⽹络io,从而提⾼了消息发送的吞吐量。
但是如果消息⽣产者宕机,会导致消息丢失,业务出错,所以理论上kafka利⽤此机制提⾼了性能却降低了可靠性。
kafka哪个环节做了消息压缩
消息发送
kafka如何保证消息不重复、不丢失
- 消费端重复消费:
- 建立去重表
- 消费端丢失数据:
- 关闭自动提交offset,处理完之后受到移位
- 生产端重复发送:
- 这个不重要,消费端消费之前从去重表中判重就可以
- 生产端丢失数据:
解决策略:
1、异步方式缓冲区满了,就阻塞在那,等着缓冲区可用,不能清空缓冲区
2、发送消息之后回调函数,发送成功就发送下一条,
发送失败就记在日志里,等着定时脚本(定时器)来扫描
(发送失败可能并不真的发送失败,只是没收到反馈,定时脚本可能会重发)
ETCD相关
etcd 是一个分布式键值对存储系统,由coreos 开发,内部采用 raft 协议作为一致性算法,用于可靠、快速地保存关键数据,并提供访问。通过分布式锁、leader选举和写屏障(write barriers),来实现可靠的分布式协作。etcd集群是为高可用、持久化数据存储和检索而准备。
堆
结构
特性
实现
内存管理是如何实现的
段和页的区别
页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提高内存的利用率;段是信息的逻辑单位,分段的目的是为了更好地满足用户的需要。
项目
热点key问题
解决方法:redis缓存,本地缓存,读写分离
热点数据发现:预估,监控
调试时候目标服务器没有响应请求,如何排查
漏桶和令牌桶
漏桶:维护一个固定容量的桶,每次流量到达时,先将流量放入漏桶中,如果漏桶已满则丢弃,未满则处理流量,然后漏桶以固定速度释放流量。
令牌桶:以恒定速度产生令牌,并将令牌放入桶中,桶是有上限的,需要从桶中获取一个令牌才能继续处理该请求。如果桶中没有令牌则拒绝请求。
docker实现隔离的原理
通过namespace?
设计一个实时热门榜单,如何数据采集、计算、存储
回答可以延伸到容灾和监控
ACID、CAP、BASE等分布式原理、一致性算法Raft
ACID
ACID是传统数据库常用的设计理念,追求强一致性模型。
CAP
CAP三要素:
一致性(C):所有节点数据实时同步(如银行转账必须实时到账)
可用性(A):请求必须快速响应(如双11秒杀不能卡顿)
分区容错性(P):断网/宕机时系统仍能运行(如异地多机房灾备)
三者只能选其二!网络故障是分布式系统的“宿命”,P是必选项,因此实际设计永远在C vs A之间挣扎。
在实际使用中,金融系统,CP模式(宁死也要一致性),Zookeeper:选举Leader时集群不可用(牺牲A),但数据强一致 ETCD:写入需半数节点确认,网络分区时拒绝服务。
社交平台:AP模式(体验至上)
BASE
base 理论是指,Basically Available(基本可用)、Soft-state( 软状态)、Eventual Consistency(最终一致性),是基于CAP定理演化而来,是对CAP中一致性和可用性权衡的结果。核心思想是即使无法做到强一致性,但每个业务根据自身的特点,采用适当的方式来使系统达到最终一致性。
Raft
保证集群数据的一致性,一般要达到一半以上的节点数据写入成功。
强一致性:保证数据都一样才返回确认。弱一致性:写入单个成功,开始异步同步就返回确认。
一致性协议Raft: 共识算法的通用特点:半数以上的节点达成共识
优势:
强领导者:只能存在一个leader,所有写操作都只能通过leader完成,数据只能从leader流向follower节点,无论集群有多大,始终只有leader可以处理写请求
领导者选举:随机化定时器选举leader
成员变更:联合共识算法
一致性哈希算法
按照常用的hash算法来将对应的key哈希到一个具有2^32次方个桶的空间中,即0~(2^32)-1的数字空间中。现在我们可以将这些数字头尾相连,想象成一个闭合的环形。
在采用一致性哈希算法的分布式集群中将新的机器加入,其原理是通过使用与对象存储一样的Hash算法将机器也映射到环中(一般情况下对机器的hash计算是采用机器的IP或者机器唯一的别名作为输入值),然后以顺时针的方向计算,将所有对象存储到离自己最近的机器中。
对象与机器处于同一哈希空间中,这样按顺时针转动object1存储到了NODE1中,object3存储到了NODE2中,object2、object4存储到了NODE3中。在这样的部署环境中,hash环是不会变更的,因此,通过算出对象的hash值就能快速的定位到对应的机器中,这样就能找到对象真正的存储位置了。
数据一致性
1、数据双写
一次性写入数据库、写入es
缺点:耦合非常严重;如果不是一个事务,假设一个成功一个失败会发生不一致问题
2、异步写
写入数据库后、放入队列、消费队列写入es。
缺点:一旦服务重启队列丢失,数据就会丢失,一般要使用补偿机制(对比数据再次写入,或者使用mq的重试机制)
3、数据同步
非实时同步数据
4、binlog cancel
利用mysql的binlog进行数据同步,一旦数据库发生变更,产生binlog日志,就会发送到mq,其他服务订阅后根据自身逻辑处理即可
常见的是使用cancal,是将自身伪装成数据库的从节点从而接收并解析信息
接口高可用
1、控制依赖
能少依赖就少依赖(mysql够用就不用redis)
能不强依赖就不强依赖,可有可无的用异步进行,不要影响主流程
2、避免单点
多实例部署
3、资源隔离
数据库分库分表,数据分片存储,避免某个服务影响整体
4、接口进行限流和熔断
防止大流量产生,也防止流量到中间件或其他依赖服务
假设依赖的接口可用率下降,这个时候可以采取熔断措施处理
5、异步处理
比如领优惠卷,领取、扣减、发放,本身是异步的操作,领取成功后异步处理就可以了
6、降级方案
可以有动态开关,动态关闭一些不会影响体验的接口
7、捣乱猴子
通过提前使用一些破坏性手段,发现潜在问题
算法题
一个int64的数字如何快捷求出其二进制有多少个1
n & (n - 1)
会消除n
的二进制表示中最右边的1
。
我们可以不断执行这个操作,直到n
变成0
,统计操作次数即为1
的个数。
1 | func countBits(n int64) int { |
要背的编程题
快排
排列组合
k个一组翻转链表
LRU
接雨水
层序遍历
三数之和
二叉树的最近公共祖先
查最小的K个数字
- 本文作者: 魏静崎
- 本文链接: https://slightwjq.github.io/2055/04/02/面试题-else/
- 版权声明: 该文章来源及最终解释权归作者所有