目录
1. 设计一个短网址服务,(mysql + redis ,key + url, 不重复随机字符串,)
(1)设计会议室预定系统。设计库表,解决冲突(A, B, C, 5:00 --- 6:00)
(2)设计 12306 订票系统,如何快速查询邮票车次、座位(性能)
3. 小米(几十亿的用户配置数据key:value,如何存储,如何快速查询)
5. 如何提高系统稳定性:故障预防与避免+故障预案与演练+故障监控与恢复+复盘与改进
6. 如何提高单机吞吐量(QPS/TPS):增加并发数+减少平均响应时间(限流削峰 + 减少调用链 + 优化代码/数据库)
7. 如何设计RPC(远程调用)框架:服务注册与发现(etcd/zookeeper)+服务入口+序列化(grpc/json)+扩展集群
8. 一台机器负载高,如何排查:top查机器负载+sar查机器的io读写和网络+ps查哪个进程有占用资源高
11. 滴滴如何设计消息网关(给百万级别的用户发送消息,包括定时、实时、定期发送,支持随时取消,可查看成功失败、状态,可重试)
12. 淘宝下单系统,怎么没有分布式系统,单机的,如何设计库表接口和查询
(1)索引,B+为什么、聚簇索引区别、二级索引、覆盖查询、回表,查询覆盖查询、回表
(3)主从同步(bin/log)redo log/undo log
(1)用过哪些 redis 的数据结构。跳表(zset 底层数据结构),SDS(简单字符串,小string 的底层数据)
3. 分布式一致性理论(cap,base,paxio,raft,zlib)
(1)提高吞吐量(partiion,page cache,零拷贝)
(3)分区重新分配。什么时候发生(增减消费者+新增topic+topic新增分区),有几个算法(Round Robin + Range + Sticky)
(3)http2,http3(问的多),http通信过程,https的通信过程(非对称加密生成对称秘钥,使用对称秘钥加密、解密请求数据)
7. Nginx(1)Nginx 监听端口号的进程是 master 还是 work?
7.1.1. 操作系统不允许多个对一个已经被监听的端口再次发起监听
7.1.2. linux fork 出来的子进程继承父进程的资源。这个操作:"父进程监听端口 A,父进程 fork 出 4 个子进程",这四个子进程继承了父进程的监听资源
7.1.3. 当连接到来,完成三次握手后(TCP),四个子进程都能获取到这个连接,这就是一个连接惊动了所有监听的进程,也叫做 "惊群"
7.1.4.nginx 使用锁,获取锁的进程,才 accept 到来的连接。
1. chan 关闭时,有数据会怎么样,往关闭的 chan 写数据会怎么样
(1)给一个 nil channel 发送数据,造成永远阻塞
(2)从一个 nil channel 接收数据,造成永远阻塞
(3)给一个已经关闭的 channel 发送数据,引起 panic
(4)从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值
(3)PHP 垃圾回收,什么时候进行垃圾回收,怎么处理循环引用
(5)nginx 如何与 fpm 通信,fpm 接到请求如何处理
(8)mysql 事务隔离级别,如何实现,redo log ,undo log 作用,mvcc 实现细节
(4)redis 持久化,AOF + BG,mysql 是否有类的持久化
(7)kafka at last one at most 如何实现
(10)一致性 hash 算法,redis 集群如何保证分段均匀
(11)mysql gap 锁 非主键 where,普通索引 where 怎么锁的
(4)分布式锁 redis,zookpeeer,(redis,进程运行时间过长怎么办,zookeeper 羊群效应,是否是可重入的)
(7)上亿的key:value(用户:推送配置,如何加快查询)
(2)Nginx 监听端口号的进程是master还是work
一、算法
1. LRU算法(最晚使用算法)
1
2. 头条(算法特别难,8 皇后问题)
1
3. 其他公司(mid)
1
4. 判断字符串的括号时候正确
1
5. 最大回文字段
1
6. 二分查找
7. 将int转换成罗马数组
1
8.二叉树(前序、中序、后续遍历,递归、循环,层次遍历)
1
9. dfs + 剪枝
10.动态规划+回溯算法(剑指 offer)
1
二、系统设计
1. 设计一个短网址服务,(mysql + redis ,key + url, 不重复随机字符串,)
1
2. 比如说会议室预定或12306抢票,都属于高并发的场景,在这种场景下怎么样保证一个时间段内有限的数量被有限的人抢到,避免冲突和超卖呢?----- 2(页面静态化+url动态化)+2(服务降级+rpc调用)+4(redis判重+令牌桶限流(令牌桶/布隆过滤器)+校验库存与时间+消息队列)
(1)设计会议室预定系统。设计库表,解决冲突(A, B, C, 5:00 --- 6:00)
(2)设计 12306 订票系统,如何快速查询邮票车次、座位(性能)
高并发看头部图片:高并发面试必考题:如何设计秒杀架构 - 知乎
(1)令牌桶
一般流量大而资源有限的情况下,可以用令牌桶方式限流,过滤可承受的请求量进行处理,同时用户交互上第一时间可以自己能抢到还是已经卖完了。
关于消息队列常见作用是削峰填谷。例如银行转账时候,需要等待6s,因为转账处理涉及事务逻辑复杂,一般不会实时请求处理,而是通过mq进行解藕,达到异步处理保护核心服务的目的。
至于mysql锁和mvcc,是事务数据一致性的范畴。
C++实现令牌桶限流: https://blog.csdn.net/hubei_dxx/article/details/117598035
(2)布隆过滤器 或 有效用户检测
布隆过滤器是禁止无效请求的,也到达了限流的效果。
3. 小米(几十亿的用户配置数据key:value,如何存储,如何快速查询)
我的思路:数据量级不大,用db存,量大用es/habase/hadoop
热点key,比如有20W个,可以放在redis中,采用lru算法作为汰换策略
4. 排名 top10(reidis, zset)
1
5. 如何提高系统稳定性:故障预防与避免+故障预案与演练+故障监控与恢复+复盘与改进
(1)故障预防与避免:
CodeReview + 需求与技术的评审 + 标准与流程 + 测试与预发环境
(2)故障预案与演练:
预案:备份容灾 + 风险预案
演练:线上全链路压测 + 定期扩容演练 + 多活建设
(3)故障监控与恢复:
监控:流量 + 延迟耗时 + 失败率
恢复:SOP标准手册 + 自动修复机制
(4)复盘与改进:
所有规避措施应该是自动执行的机制,而不能是人的良好意愿
规范团队操作习惯,及时消灭日常小隐患
6. 如何提高单机吞吐量(QPS/TPS):增加并发数+减少平均响应时间(限流削峰 + 减少调用链 + 优化代码/数据库)
(QPS/TPS) = 并发数 / 平均相应时间
(1)增加并发数:增加并发连接数
(2)减少平均响应时间:限流削峰 + 减少调用链 + 优化代码/数据库
7. 如何设计RPC(远程调用)框架:服务注册与发现(etcd/zookeeper)+服务入口+序列化(grpc/json)+扩展集群
如何设计一个RPC框架 - 简书
(1)服务注册与发现(etcd/zookeeper):
系统很多的话,不可能让每个系统都知道其他系统的地址,肯定要找一个便捷的方式能够发现其他的服务。
(2)服务入口:
网络传输,序列化反序列化也是必不可少
(3)序列化(grpc/json):
远程调用,我们不可能把每个服务接口都暴露在外面,而是一个入口接受参数,再由这个入口分发到系统内部的某个服务,调用后返回结果。
(4)扩展集群:
5种负载均衡,服务不可用的重试机制+服务降级熔断
8. 一台机器负载高,如何排查:top查机器负载+sar查机器的io读写和网络+ps查哪个进程有占用资源高
如何快速排查机器负载过高的问题_有想法的工程师的博客-CSDN博客_机器负载高原因排查
(1)机器的基本情况,top命令
(2)机器的io读写和网络情况,sar命令
<1> sar -d 1 10 查看磁盘读写情况,检查项:rd_sec和wr_sec
<2> sar -n DEV 1 3 查看网络情况
(3)查看具体是哪个进程有占用资源高的问题,ps命令
<1> cpu占用排行靠前的10条进程,查看command项
ps aux | head -n 1;ps aux| awk '{if($8 == "R") print $0}'|sort -k3 | head -n 10
<2> 调出这个command命令的父程序
ps -ef | grep 命令| awk '{print $3}'| xargs ps -f| head -n 10
(注意:ps -ef 的第三列就是父程序的pid,然后传给 ps -f去查是什么)
9. 写多读少的系统怎么设计(比如滴滴在线查看汽车位置,每秒搜集经纬度信息,读频率低,写的 tps 到达几十万):读多写少-mysql/mysql集群 + 写多地少-mysql/nosql/tokudb + 读多写多-nosql
https://blog.csdn.net/lzf2284466/article/details/106354072
读写频率 | 解决方案 | 使用场景 |
读多写少 | mysql集群 | 电商/新闻/论坛/在线教育系统 |
写多读少 | mysql集群 + nosql集群(如tokudb) tokuDB的写入速度是innoDB的9~20倍 | 滴滴/食堂刷卡机 |
读写都多 | nosql集群 | 微信、QQ PS:需要存储许多离线消息,并且用户上线还需要读取离线消息 |
10. 缓存 DB 一致性怎么保证
https://baijiahao.baidu.com/s?id=1710566894419278870
缓存的读写
(1)写请求依旧只写数据库
(2)读请求先读缓存,如果缓存不存在,则从数据库读取,并写入缓存,缓存设置失效时间
ps:缓存中不经常访问的数据会逐渐过期淘汰掉,保留的都是热数据
一致性保证
数据更新:先更新数据库,后删除缓存
ps:很多情况下,写到缓存中的值,并不是与数据库中的值一一对应的,很有可能是先查询数据库,再经过一系列计算得出一个值,才把这个值才写到缓存中。
其中,删除缓存采用缓存延迟双删策略,经验延迟1-5秒
引入缘由:读写分离+主从复制延迟情况下:
线程 A 更新主库 X = 2(原值 X = 1)
线程 A 删除缓存
线程 B 查询缓存,没有命中,查询「从库」得到旧值(从库 X = 1)
从库「同步」完成(主从库 X = 2)
线程 B 将「旧值」写入缓存(X = 1)
最终 X 的值在缓存中是 1(旧值),在主从库中是 2(新值),也发生不一致。
问题的核心在于:缓存都被回种了「旧值」
程序在执行过程中发生异常?
方案1)使用消息队列:丢到消息队列,在另外一个服务中有专门的消费者去异步重试。
方案2)不想用消息队列:订阅数据库变更日志,再操作缓存。当一条数据发生修改时,MySQL 就会产生一条变更日志(Binlog),我们可以订阅这个日志,拿到具体操作的数据,然后再根据这条数据,去删除对应的缓存。
11. 滴滴如何设计消息网关(给百万级别的用户发送消息,包括定时、实时、定期发送,支持随时取消,可查看成功失败、状态,可重试)
https://zhuanlan.zhihu.com/p/29174733
1、架构定位:
公司级的基础服务层。主要职责:受理投递、频次控制、尽力发送、反馈统计、削峰匹配慢速信道。
2、模块拆解:
消息发送 = 逻辑消息网关 + 物理发送渠道
1)消息网关:消息发送的总入口,对接上游各个业务系统
2)发送渠道:下游对接各个物理投递渠道,对接第三方信道提供方(如电话,邮件,短信等)
3、功能模块
1)消息的受理和分发
2)面向业务友好的接口
访问配置好模板的统一接口
3)频次控制
4)用户订阅
5)失败重试
6)反馈统计
4、技术选型
Venus框架是一个去中心化的RPC调用框架,Client端对Server端的调用由proxy进行转发。Client到LocalProxy,以及Local Proxy到Server端保持TCP长连接
5、监控和降级
12. 淘宝下单系统,怎么没有分布式系统,单机的,如何设计库表接口和查询
我做的【办公用品领取】的设计思路即可
三、基础知识
1. mysql
(1)索引,B+为什么、聚簇索引区别、二级索引、覆盖查询、回表,查询覆盖查询、回表
1
(2)锁,有哪些锁
server 层 lock table
innodb 表,record, gap,意向锁,表锁
(3)主从同步(bin/log)redo log/undo log
1
(4)mvvc
1
(5)mysql架构server + 引擎
1
(6)mysql 是怎么运行的
1
2. redis + 分布式锁
(1)用过哪些 redis 的数据结构。跳表(zset 底层数据结构),SDS(简单字符串,小string 的底层数据)
1
(2)分布式锁
**** redis 实现(死锁问题,进程运行时间过长,锁自动释放怎么办,redis 的锁是否是可重入, hash map(计数)) ,主从问题(redlock https://www.zhihu.com/question/300767410/answer/1749442787 https://www.zhihu.com/question/300767410/answer/1749442787)
**** zookeeper 分布式锁(分布式一致性组件),临时顺序节点,(什么是羊群效应)
** redis hash 渐进式rehash
** redis 热 key 处理
1
3. 分布式一致性理论(cap,base,paxio,raft,zlib)
cap ,base,分布协议(paxxio,raft(多租户问题),zlib)
4. kafka
(1)提高吞吐量(partiion,page cache,零拷贝)
1
(2)提高可靠性(副本机制、iso结合、HW高水位)
1
(3)分区重新分配。什么时候发生(增减消费者+新增topic+topic新增分区),有几个算法(Round Robin + Range + Sticky)
http://www.elecfans.com/d/1204449.html
https://blog.csdn.net/u4110122855/article/details/103616791
PS:分区重分配,也叫:再平衡
1、kafka的再平衡:在kafka consumer所订阅的topic发生变化时发生的一种分区重分配机制。
2、3种情况会触发再平衡:
(1)增减消费者
consumer group中的新增或删除某个consumer,导致其所消费的分区需要分配到组内其他的consumer上
(2)新增topic
consumer订阅的topic发生变化,比如订阅的topic采用的是正则表达式的形式,如test-*此时如果有一个新建了一个topic test-user,那么这个topic的所有分区也是会自动分配给当前的consumer的,此时就会发生再平衡;
(3)topic新增分区
consumer所订阅的topic发生了新增分区的行为,那么新增的分区就会分配给当前的consumer,此时就会触发再平衡。
3、3种再平衡策略:
Round Robin,Range,Sticky,默认使用Range。
这三种分配策略的主要区别在于:
(1)Round Robin:会采用轮询的方式将当前所有的分区依次分配给所有的consumer;
(2)Range:首先会计算每个consumer可以消费的分区个数,然后按照顺序将指定个数范围的分区分配给各个consumer;
(3)Sticky:这种分区策略是最新版本中新增的一种策略,Sticky是“粘性的”,可以理解为分配结果是带“粘性的”——每一次分配变更相对上一次分配做最少的变动(上一次的结果是有粘性的)
其主要实现了两个目的:
<3.1>分区的分配尽量的均衡
将现有的分区尽可能均衡的分配给各个consumer,存在此目的的原因在于Round Robin和Range分配策略实际上都会导致某几个consumer承载过多的分区,从而导致消费压力不均衡;
<3.2>每一次重分配的结果尽量与上一次分配结果保持一致
如果发生再平衡,那么重新分配之后在前一点的基础上会尽力保证当前未宕机的consumer所消费的分区不会被分配给其他的consumer上
当这两个目标发生冲突时,优先保证第一个目标。第一个目标是每个分配算法都尽量尝试去完成的,而第二个目标才真正体现出StickyAssignor特性的。
5. 网络
(1)tcp 三次握手,四次挥手,tcp头有哪些字段
1
(2)4月份tcp拥塞算法
1
(3)http2,http3(问的多),http通信过程,https的通信过程(非对称加密生成对称秘钥,使用对称秘钥加密、解密请求数据)
http:客户端(如Web浏览器)从服务器(如Web服务器)请求资源时用到的协议
(1)http1.1
基于文本的协议。
网站地址以http://开头
(2)http2
基于二进制协议。解决了1.1版本的性能问题。优点:易解析,少错误,多路复用。
HTTP/2的通过支持请求与响应的[多路复用]来减少延迟,通过[压缩HTTP首部]字段将协议开销降至最低,同时[增加对请求优先级和服务器端推送的支持]。
网站地址以http://开头,或者 https://开头
(3)http3
QUIC的基于UDP的传输之上(而不是HTTP1.1和HTTP2的基于TCP的协议)。
(PS:QUIC=Quick UDP Internet Connections;是一种新的默认加密的互联网通信协议)
网站地址以https://开头
(4)https
一种加密HTTP的方式。一般使用SSL/TLS将HTTP消息包装为加密格式。
(4)tcp timewait的原因和解决办法
1
6. 操作系统
(1)进程、线程、协程区别
1
(2)多路复用(select、poll、epoll)
1
(3)进程间通信方式
1
(4)一台机器长链接数目:2^48
一台主机的最大TCP连接数是多少? - 小小小南瓜 - 博客园
socket的包含5元组:协议+服务端地址+服务端端口号+客户端地址+客户端端口号 去唯一标识一个链接。所以,限制单机TCP最大连接数的因素=ip地址范围*端口范围,连接数最多是(2^32)*(2^16)=2^48
(5)虚拟地址
1
7. Nginx
(1)Nginx 监听端口号的进程是 master 还是 work?
7.1.1. 操作系统不允许多个对一个已经被监听的端口再次发起监听
7.1.2. linux fork 出来的子进程继承父进程的资源。这个操作:"父进程监听端口 A,父进程 fork 出 4 个子进程",这四个子进程继承了父进程的监听资源
7.1.3. 当连接到来,完成三次握手后(TCP),四个子进程都能获取到这个连接,这就是一个连接惊动了所有监听的进程,也叫做 "惊群"
7.1.4.nginx 使用锁,获取锁的进程,才 accept 到来的连接。
nginx多个进程(worker)监听一个端口 - autumn0304 - 博客园
【高并发中的惊群效应】
链接:
什么是惊群,如何有效避免惊群? - 知乎
1、定义:
惊群效应(thundering herd)是指多进程(多线程)在同时阻塞等待同一个事件的时候(休眠状态),如果等待的这个事件发生,那么他就会唤醒等待的所有进程(或者线程),但是最终却只能有一个进程(线程)获得这个时间的“控制权”,对该事件进行处理,而其他进程(线程)获取“控制权”失败,只能重新进入休眠状态,这种现象和性能浪费就叫做惊群效应
2、解决:
(1)Linux 2.6版本
通过引入一个标记位WQ_FLAG_EXCLUSIVE,解决掉了accept惊群效应。
(2)Epoll
epoll 的惊群效应分为两种情况:
<1> epoll_create在fork之前创建
解决:思路和accept一致
<2> epoll_create在fork之后创建
解决:epoll 对惊群效应的修复,是建立在共享在同一个epoll结构上的。epoll_create在fork之后执行每个进程有单独的epoll红黑树,等待队列,ready事件列表。
因此,惊群效应再次出现了。有时候唤醒所有进程,有时候唤醒部分进程,可能是因为事件已经被某些进程处理掉了,因此不用在通知另外还未通知到的进程了。
(3)Nginx的锁
锁的实现分为两种情况:
<1> 一种是支持原子操作的情况,也就是由NGX_HAVE_ATOMIC_OPS这个宏来进行控制的。
解决:直接使用mmap,然后lock就保存mmap的内存区域的地址
<2> 一种是不支持原子操作,这是是使用文件锁来实现。
解决:使用文件锁来实现
(2)fast-cgi cgi 区别
1
8. ci + cd(gitlab + Jenkins)
9. 持续发布、持续交付
1
10. k8s
1
四、GO
1. chan 关闭时,有数据会怎么样,往关闭的 chan 写数据会怎么样
(1)给一个 nil channel 发送数据,造成永远阻塞
1
(2)从一个 nil channel 接收数据,造成永远阻塞
1
(3)给一个已经关闭的 channel 发送数据,引起 panic
1
(4)从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值
1
2. GO 协程泄露
五、大厂面试
1、滴滴面试
(1)lru算法
力扣,LRU原理和Redis实现——一个今日头条的面试题 - 知乎
(2)从数组 nums 里面取三个接近 target 的值
(3)PHP 垃圾回收,什么时候进行垃圾回收,怎么处理循环引用
1
(4)Fpm 如何管理进程,什么时候拉起新的进程
1
(5)nginx 如何与 fpm 通信,fpm 接到请求如何处理
1
(6)零拷贝如何实现,sendfile 如何实现
1
(7)kafka 如何支持高并发
1
(8)mysql 事务隔离级别,如何实现,redo log ,undo log 作用,mvcc 实现细节
1
2、高德面试
(1)算法:反转链表
1
(2)https 的建立过程
1
(3)tcp 拥塞算法和限流算法
(4)对称加密和非对称加密的用法
1
(5)设计消息队列,有哪些模块,有什么难点,如何解决
1
3、腾讯
(1)系统设计
1
(2)设计短网址服务,hash 冲突怎么办
1
(3)mysql 备份机制,冷备、热备
1
(4)redis 持久化,AOF + BG,mysql 是否有类的持久化
1
(5)mysql 数据同步过程,如何进行同步
1
(6)redis key 扩容机制
1
(7)kafka at last one at most 如何实现
1
(8)mysql IOC 项目为什么不用分布表分区表
1
(9)mysql 缓存如何实现的,是不是用的 LRU
1
(10)一致性 hash 算法,redis 集群如何保证分段均匀
1
(11)mysql gap 锁 非主键 where,普通索引 where 怎么锁的
1
4、shopee
(1)http2
1
(2)虚拟内存
1
(3)进程间通信
1
(4)堆排序
1
(5)raft 协议,多租户。cap,base 是什么?
1
(6)进程、线程、协程区别
1
5、小米
(1)如何提高系统稳定性
1
(2)如何提高单机吞吐量
1
(3)如何设计 RPC 框架
1
(4)分布式锁 redis,zookpeeer,(redis,进程运行时间过长怎么办,zookeeper 羊群效应,是否是可重入的)
1
(5)raft 多租户
1
(6)如何设计系统,计算top10 排名
1
(7)上亿的key:value(用户:推送配置,如何加快查询)
1
(8)tcp 协议头字段
1
(9)一台机器长链接数目
1
(10)如何设计会议室预定系统
1
(11)如何实现12306火车篇预定系统
1
6、百度
(1)Mysql 主从同步过程
1
(2)Nginx 监听端口号的进程是master还是work
1
7、2021.10-字节跳动面试
1、结合项目中的追问
2、N个button,每天有点击量
(1)绘制3天内各button的点击量折线图
答:mysql+redis,每个按钮每小时的点击量放在redis里,redisKey=buttonN+年月日时,
mysql月表(clicks_202110):button,年月日,点击数,假如button数=1万个,1w*24*30=720w
(2)部分button废弃不再有点击,又有新的button产生新的点击。如果保证热点button的点击数被统计到
redis的集合,记录每小时的button
3、敏感词过滤是如何实现的?-trie树
https://www.jianshu.com/p/d87d030081c7