腾讯后台开发暑期实习一面|讲解|0312
最近腾讯火力全开,收到面试邀请的同学也很多,没有收到面试的同学也不用太焦虑,暑期实习说是金3银4,但根据往年状态来看,56月都是有机会的,很多同学也在那个时候才找到实习的。所以不用焦虑,随时做好准备就行, 大家加油~~
那我们今天继续挑选一篇腾讯的后台开发实习一面,给大家做讲解分析,参考回答和学习资料指引,期望对大家有所帮助~
考察重点:Redis+计算机网络
![]()
感谢这位同学的分享,预祝顺利offer!!
1.Redis:说一下如何解决缓存穿透,缓存击穿(缓存雪崩)
解析: 缓存本省是一个优化利器,也是面试当中的重点。引入缓存之后,缓存本身也会带来一些问题,缓存穿透、缓存击穿就是需要解决的问题。
参考回答:
缓存穿透:指查询一个一定不存在的数据,由于缓存不命中时需要从数据库查询,而数据库中也无此数据,因此无法写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,给数据库带来压力。对于恶意利用此漏洞的攻击,甚至可能压垮数据库。其解决方案包括但不限于:
- 对查询的key进行合法性校验,比如长度、格式等,对不合法的key直接拒绝服务。
- 对不存在的key也进行缓存,设置一个较短的过期时间即可。
- 使用布隆过滤器,将所有可能存在的key预先加载到过滤器中,在查询前先进行过滤,如果不存在则直接返回,避免对数据库的查询。
缓存雪崩:当缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。解决方案包括:
- 给缓存的失效时间加上一个随机值,避免集体失效。
- 使用互斥锁,当缓存失效的时候,不是立即去load db,而是先使用缓存工具的某个机制,比如Redis的SETNX去设置一个锁,当操作返回成功时,再去load db并放入缓存;否则,就重试获取缓存值。
- 采用双缓存策略,即设置两级缓存,原始缓存和拷贝缓存,原始缓存失效时,可以访问拷贝缓存,原始缓存与拷贝缓存,定期同步数据,保证一致。
缓存击穿:是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。其解决方案包括:
- 设置热点数据永远不过期。
- 使用互斥锁,当缓存失效的时候,不是立即去load db,而是通过缓存工具的某个机制(如Redis的SETNX)去设置一个锁,当操作返回成功时,再去load db并放入缓存;否则,就重试获取缓存值。
学习指引
面试学习: 《小林Coding》|什么是缓存雪崩、击穿、穿透?
2.Mysql:项目中用到了数据库分区,讲一下分区分表
- 你知道idb,frm都存储什么吗?
- 分区类型有哪些?
- 分区的优缺点? 解析: 考察Mysql分区分表,需要掌握,另外还有分库等相关概念也要一起掌握。 参考回答:
讲一下分区分表
1. 分区
- 概念: 分区是将一个大表在物理上分割成多个较小的、更易于管理的片段,但从逻辑上来看,它们仍然被视为同一个表。
- 类比理解: 你可以想象一个大书架,上面摆满了书,很难管理。如果我们将这些书按照类别(比如小说、历史、科学等)分到不同的小书架上,每个小书架就更容易管理了。这就是分区的基本思想。
- 示例: 假设有一个销售表,记录了多年的销售数据。我们可以按照年份进行分区,这样查询某一年的数据时,只需要扫描该年份的分区即可。
- 实现:在分区策略中,尽管表在物理存储上被分成了多个部分(每个部分有自己的.ibd文件),但在逻辑上它们仍然被视为一个整体,并且只与一个.frm文件相关联(1个.frm文件对应多个.ibd文件)
2. 分表
- 概念: 分表是将一个大表拆分成多个具有相同结构的小表,每个小表存储不同的数据子集。
- 类比理解: 这有点类似于将一个大班级分成多个小班,每个小班管理起来更加容易。
- 示例: 假设有一个用户表,用户数量巨大。我们可以按照用户ID的范围进行分表,比如用户ID 1-1000在表1,用户ID 1001-2000在表2,以此类推。
- 实现:在分表策略中,每个分表都有自己独立的.frm和.ibd文件,这些分表在逻辑和物理存储上都是完全独立的。(1个.frm文件对应1个.ibd文件)
你知道idb,frm都存储什么吗?
- .frm文件用于存储表的结构定义,包括列名、数据类型等
- .ibd文件用于存储表的数据和索引
分区类型有哪些?
- RANGE分区:基于列的值范围来分区。
- LIST分区:基于列的枚举值来分区。
- HASH分区:基于用户定义的表达式的哈希值来分区。
- KEY分区:类似于哈希分区,但基于MySQL提供的哈希函数。
分区的优缺点?
优点:
- 性能提升:通过只查询或操作感兴趣的分区,可以显著提高查询性能。
- 管理便利:可以独立地备份、恢复或优化单个分区,而不是整个表。
- 数据归档:可以轻松地将旧数据移到只读分区中,确保数据安全性同时提高性能。
- 可用性增强:如果某个分区发生故障,其他分区的数据仍然可以访问。
- 存储优化:可以将不同分区放在不同的物理存储上,以优化I/O性能。
缺点:
- 复杂性增加:设计和维护分区策略需要额外的知识和工作。
- 可能的性能问题:如果查询或操作跨多个分区,可能会导致性能下降。
- 管理开销:需要定期监控和维护分区,确保其性能和可用性。
- 数据迁移挑战:在重新分区或更改分区策略时,可能需要大量的数据迁移工作。
学习指引
两篇一起看
3.Redis:数据类型有哪些?
解析:
回答最常用的5种就行,其他数据类型等面试官追问再答也可以。
参考回答:
- String(字符串):这是Redis最基本的数据类型,一个key对应一个value。它是二进制安全的,可以包含任何数据,如jpg图片或序列化的对象。一个键最大能存储512MB的数据。
- Hash(哈希):Redis的哈希是一个键值对集合,是string类型的field和value的映射表。它特别适合用于存储对象,可以像数据库中更新一个属性一样只修改某一项属性值,而不需要取出整个字符串反序列化成对象修改再序列化存回去。
- List(列表):Redis的列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边),它的增删操作非常快,且提供了操作某一段元素的API。
- Set(集合):Redis的Set是string类型的无序集合。它是通过哈希表实现的,添加、删除和查找的时间复杂度都是O(1)。
- Sorted Set(有序集合):与Set相似,但Sorted Set中的每个字符串元素都会关联一个double类型的分数。Redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)可以重复。
除了以上五种基本数据类型,Redis还支持一些其他的数据结构和功能,如Bitmaps(位图)、HyperLogLog(基数统计)、Geospatial(地理位置)和Streams(流)等。
推荐学习: 《小林 coding》Redis 常见数据类型和应用场景
4.Redis: 6.0升级了多线程了解吗?
- 为什么6.0要引入多线程?
- IO多路复用讲解下:select/poll/epoll
分析:
redis单线程/多线程问题是最高频考题之一,并且结合多线程去追问IO多路复用,也是常见套路,大家一定要掌握。
参考回答:
了解吗?: 了解。虽然 Redis 的主要工作(网络 I/O 和执行命令)一直是单线程模型,但是在 Redis 6.0 版本之后,也采用了多个 I/O 线程来处理网络请求。
为什么6.0要引入多线程?
- 这是因为随着网络硬件的性能提升,Redis 的性能瓶颈有时会出现在网络 I/O 的处理上。 所以为了提高网络 I/O 的并行度,Redis 6.0 对于网络 I/O 采用多线程来处理。但是对于命令的执行,Redis 仍然使用单线程来处理,所以大家不要误解 Redis 有多线程同时执行命令。Redis 官方表示,Redis 6.0 版本引入的多线程 I/O 特性对性能提升至少是一倍以上。
IO多路复用讲解下:select/poll/epoll
简要介绍
- select: select允许程序同时监控多个文件描述符的读写状态,但受限于位图大小,且每次调用都需从用户空间向内核空间复制位图,性能开销大。
- poll: poll改进了select,使用数组存储文件描述符,无位图大小限制,可处理更多文件描述符。但同样存在每次调用时的用户空间到内核空间的复制开销。
- epoll: epoll是Linux特有的高效IO多路复用机制,基于事件驱动,无需轮询,通过注册感兴趣的事件并在事件发生时通知应用程序,适合处理大量并发连接,性能优越且资源消耗低。
推荐学习:
面试学习:《小林Coding》|Redis 6.0 之后为什么引入了多线程?
面试学习:《小林Coding》|I/O 多路复用:select/poll/epoll
5.Redis: 持久化了解吗?
- 用户写入时是先写数据库还是先写AOF日志?
- 后写AOF有什么风险?
- 听说过write-ahead logging吗?你对这个有什么想法吗?
分析:
redis持久化是redis 4-5项核心重点知识之一,属于高频考题,必须掌握。
参考回答:
1.持久化介绍:
Redis 共有三种数据持久化的方式:
- AOF 日志:每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里;
- RDB 快照:将某一时刻的内存数据,以二进制的方式写入磁盘;
- 混合持久化方式:Redis 4.0 新增的方式,集成了 AOF 和 RBD 的优点;
2.用户写入时是先写执行命令还是先写AOF日志?
先执行命令,再写AOF日志。
好处:
- 避免额外的检查开销:因为如果先将写操作命令记录到 AOF 日志里,再执行该命令的话,如果当前的命令语法有问题,那么如果不进行命令语法检查,该错误的命令记录到 AOF 日志里后,Redis 在使用日志恢复数据时,就可能会出错。
- 不会阻塞当前写操作命令的执行:因为当写操作命令执行成功后,才会将命令记录到 AOF 日志。
风险
- 数据可能会丢失: 执行写操作命令和记录日志是两个过程,那当 Redis 在还没来得及将命令写入到硬盘时,服务器发生宕机了,这个数据就会有丢失的风险。
- 可能阻塞其他操作: 由于写操作命令执行成功后才记录到 AOF 日志,所以不会阻塞当前命令的执行,但因为 AOF 日志也是在主线程中执行,所以当 Redis 把日志文件写入磁盘的时候,还是会阻塞后续的操作无法执行。
3.听说过write-ahead logging(WAL)吗?你对这个有什么想法吗?
分析:这里估计面试官是想说Mysql redo日志的实现的差别。但是我觉得跟这里redis的更新没有本质差别,也算是WAL
回答::
Mysql:中的redo log相关实现用到了这个WAL策略。WAL 技术指的是, MySQL 的写操作并不是立刻写到磁盘上,而是先写日志,然后在合适的时间再写到磁盘上。(先写内存-->再写日志-->最后更新到磁盘)所以相对写磁盘来说,是先写的日志,叫write-ahead logging
Redis: 我们再看redis的流程:redis是先执行命令,再更新日志,最后持久化到磁盘。(执行命令(写内存)-->写AOF日志-->持久化到磁盘),可以看到,其实没有本质差别的。并不是redis没想到这个策略,应该说它就已经使用了这个策略,那就是在数据持久化到磁盘之前,先写了AOF日志。
推荐学习:
面试学习:《小林Coding》|图解redis|AOF 日志是如何实现的
面试学习:《小林Coding》|图解mysql|为什么需要 redo log
6.计算机网络:HTTP常用状态码?
分析::
不用多说,必须掌握。
参考回答::
- 「200 OK」是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。
- 「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。
学习指引::
面试学习:《小林Coding》|HTTP 常见的状态码有哪些?
7.计算机网络:TCP 三次握手?
分析::
不用多说,必须掌握。
参考回答::
过程:首先客户端向服务器发送连接请求(SYN报文),然后服务器接收到请求后发送确认信息(ACK报文)并同时向客户端发送连接请求(SYN报文),最后客户端接收到服务器的确认和连接请求后,再向服务器发送确认信息(ACK报文)。完成这三次握手后,TCP连接就成功建立,双方可以开始数据传输。
学习指引::
面试学习:《小林Coding》|TCP 三次握手过程是怎样的?
8.计算机网络:平时抓过包吗?
分析:: 了解学习
参考回答::
抓过。参考推荐资料
学习指引::
9.计算机网络:TCP滑动窗口讲一下?
分析:: TCP是面试重点,滑动窗口是TCP的重点,需要掌握
参考回答::
TCP的滑动窗口是一种核心的流量控制机制。它基于窗口的概念,窗口实际上是一个缓冲区,在这个缓冲区内,发送方被允许在未收到确认的情况下连续发送数据。窗口的大小定义了发送方可以发送但还未被确认的数据段的最大数量。
滑动窗口的工作原理可以简要概括为以下几个步骤:
- 建立连接时的窗口大小协商:在TCP三次握手建立连接的过程中,双方会交换窗口大小的信息,以确定初始的窗口大小。
- 数据的发送与确认:发送方根据窗口大小发送数据。每当接收方成功接收到一个数据段,它就会向发送方发送一个确认(ACK)报文,表明已成功接收到数据并准备好接收更多数据。
- 窗口的滑动:随着数据被发送和确认,窗口会“滑动”。具体来说,当发送方收到一个确认报文时,它会将窗口的起始点向前移动到已确认数据的下一个未被确认的数据段。这样,窗口内就包含了新的未发送但可以发送的数据段。
- 窗口大小的调整:滑动窗口的大小可以根据接受放的处理能力来进行流量控制。如果处理能力下降,接收方可能会减小窗口大小;如果状况良好,接收方可能会增大窗口大小,以允许更快的数据传输。
- 数据的重传:如果发送方在一段时间内没有收到某个数据段的确认,它会假设该数据段丢失,并重新发送该数据段。重新发送的触发通常是基于一个计时器,该计时器会在发送数据段时启动,并在未收到确认时超时。
学习指引::
面试学习:《小林Coding》|滑动窗口
10.Spring:Spring IOC讲解下
分析:: Spring IOC/AOP 这两即便你没学过Spring面试都得会吟唱两句才行。
参考回答::
Spring IOC,即Spring的控制反转,是一种设计思想,它将对象的创建权反转给Spring容器来管理。通过IOC,程序实现了对象的解耦合,使得对象与对象之间是低耦合的,提高了程序的灵活性和可维护性。简单来说,Spring IOC就是让开发者不再需要手动创建对象,而是通过配置或注解等方式,让Spring容器来负责对象的创建、管理和依赖关系的注入。
推荐学习::
面试学习:《JavaGuide》|谈谈自己对于 Spring IoC 的了解
本文也是 《热门面经讲解》专栏 系列文章之一,文末尾有专栏链接,大家可以点个关注,我会持续更新~~
#面经##腾讯##实习##暑期实习##后端#挑选近期热门真实后端面经进行讲解分析,给出:个人分析+参考回答+学习资料指引。