⽹络
腾讯云智 Java ⾯试
腾讯云智是 腾讯的⼦公司,主要负责 是腾讯云相关的业务,所以负责 的项⽬就是腾讯云的项⽬,
在腾讯csig ⼯作的同学也跟我说,经常跟腾讯云智的同事对接⼯作。
腾讯云智公司主要在⼆线城市,总部是西安,然后⻓沙、武汉都有办公地点。
这次我们来看看 25 届「腾讯云智」开发岗的校招薪资情况。

1/12 14.5k x 16 + 1k x 12 (房补) + 2.4w 签字费,同学 bg 本科,base 武汉
14k x 16 + 1k x 12 (房补) + 2.4w 签字费,同学 bg 硕⼠ 211 ,base 西安
13k x 16 + 2w 签字费 + 1k x 12 (房补),同学 bg 本科,base 西安
12k x 16 + 2w 签字费 + 1k x 12 (房补),同学 bg 本科,base 武汉
普通档的 offer 整体年包在 22 〜24w ,sp offer 年包在 26w 〜27w ,在⼆线城市的话,还算不错
的。
那腾讯云智的⾯试难度如何?
这次我们来看看 腾讯云智后端开发的校招⾯经,⾯试⻛格挺类似腾讯,喜欢问计算机基础多⼀
些,然后每个常⽤的后端组件拷打⼏个问题,也是有算法题,所以想冲腾讯云智的同学,算法还
是得多刷刷 。

3/12 操作系统
堆区和栈区的区别
分配⽅式:堆是动态分配内存,由程序员⼿动申请和释放内存,通常⽤于存储动态数据结构和
对象。栈是静态分配内存,由编译器⾃动分 配和释放内存,⽤于存储函数的局部变量和函数调
⽤信息。
内存管理:堆需要程序员⼿动管理内存的分配和释放,如果管理不当可能会导致内存泄漏或内
存溢出。栈由编译器⾃动管理内存,遵循后进先出的原则,变量的⽣命周 期由其作⽤域决定,
函数调⽤时分配内存,函数返回时释放内存。
⼤⼩和速度:堆通常⽐栈⼤,内存空间较⼤,动态分配和释放内存需要时间开销。栈⼤⼩有
限,通常⽐较⼩,内存分配和释放速度较快,因为是编译器⾃动管理。
为什么临 时变量放在栈⾥⾯,对象放在堆,为什么不 能反过来?
临时变量放在栈上的原因:
⽣命周 期管理简单:栈上的内存管理是⾃动的,遵循后进先出(LIFO )的原则。时变量的⽣命周期通常与其作⽤域相关,当作⽤域结束时,栈上的内存会⾃动释放。
访问速度快:栈内存的访问速度通常⽐堆内存快,因为栈内存的分配和释放是连续的,不需要
复杂的指针操作。
对象放在堆上的原因:
动态⼤⼩:对象的⼤⼩在编译时通常是未知的,需要在运⾏时动态分配内存。堆内存允许动态
分配任意⼤⼩的内存块,适合存储对象。
** 共享和持久性:** 堆上的对象可以被多个变量引⽤,实现对象的共享。堆上的对象可以在函数
调⽤结束后仍然存在,适合需要持久化的数据。
为什么不 能反过来?
** 栈内存的局限性:** 栈内存的⼤⼩有限,如果将⼤对象或动态⼤⼩的对象放在栈上,可能会导
致栈溢出。栈内存的分配和释放是连续的,不适合频繁的动态内存管理。
对象⽣命周 期管理的复杂性:如果将对 象放在栈上,对象的⽣命周 期将与其作⽤域绑定,这会
限制对象的共享和持久性。需要⼿动管理对象的⽣命周 期,增加了编程的复杂性和出错的可能
性。
性能问题:栈内存的访问速度虽然快,但如果频繁地在 栈上进⾏⼤对象的分配和释放,会导致
栈内存碎⽚化,影响性能。堆内存的分配和释放虽然相对较慢,但可以通过内存池等技术进⾏
优化。
多进程和多线程区别?
资源占⽤与共享的区别:
多进程是每个进程拥有独⽴的内存空间和系统资源。进程间的数据共享复杂且开销较⼤,通常
需要使⽤IPC (进程间通信)机制如管道、消息队列、共享内存等。
多线程是所有线程共享同⼀进程的内存空间和资源,线程间的数据共享简单⾼效,可以直接通
过内存访问,但这也带来了同步和互斥的问题,需要使⽤锁、信号量等机制来避免竞争条件。
调度与切换的区别:
进程是是 操作系统资源分配的基本单位,调度开销相对较⼤,进程间的切换需要保存和恢复更
多的上下 ⽂信息。
线程是CPU 调度的基本单位,调度开销较⼩。线程间的切换只需保存和恢复较少的寄存 器和栈
信息。
稳定性与安全性:
在多进程中,⼀个进程崩溃通常不会影响其他进程,具有较好的隔离性和容错性。
在多线程中,⼀个线程出错可能导致整个进程崩溃,需要更加谨慎地处理异常和同 步问题。
线程和协程区别?
⾸先,我们来谈谈 进程。进程是操作系统中进⾏资源分配和调度的基本单位,它拥有⾃⼰的独
⽴内存空间和系统资源。每个进程都有独⽴的堆和栈,不与 其他进程共享。进程间通信需要通
过特定的机制,如管道、消息队列、信号量等。由于进程拥有独⽴的内存空间,因此其稳定性
和安全性相对较⾼,但同时上下 ⽂切换的开销也较⼤,因为需要保存和恢复整个进程的状态。
接下来是线程。线程是进程内的⼀个执⾏单元,也是CPU 调度和分派的基本单位。与进程不
同,线程共享进程的内存空间,包括堆和全局变量。线程之间通信更加⾼效,因为它们可以直
接读写共 享内存。线程的上下 ⽂切换开销较⼩,因为只需要保存和恢复线程的上下 ⽂,⽽不是
整个进程的状态。然⽽,由于多个线程共享内存空间,因此存在数据竞争和线程安全的问题,
需要通过同步和互斥机制来解决。
最后是协程。协程是⼀种⽤⼾态的轻量级线 程,其调度完全由⽤⼾程序控制,⽽不需要内核的
参与。协程拥有⾃⼰的寄存 器上下 ⽂和栈,但与其他协程共享堆内存。协程的切换开销⾮常
⼩,因为只需要保存和恢复协程的上下 ⽂,⽽⽆需进⾏内核级的上下 ⽂切换。这使得协程在处
理⼤量并发任务时具有⾮常⾼的效率。然⽽,协程需要程序员显式地进⾏调度和管理,相对于
线程和进程来说,其编程模型更为复杂。
进程切换和线程切换哪个快?
线程切换更快⼀些,线程切换⽐进程切换快是因为线程共享同⼀进程的地址 空间和资源,线程切
换时只需切换堆栈和程序计数器等少量信息,⽽不需要切换地址 空间,避免了进程切换时需要切
换内存映射表等⼤量资源的开销,从⽽节省了时间和系统资源。
⽹络
DNS ⼯作流程?
- 客⼾端⾸先会发出⼀个 DNS 请求,问 http://www.server.com 的 IP 是啥,并发给本地 DNS 服
务器( 也就是客⼾端的 TCP/IP 设置中填写的 DNS 服务器地址 )。
- 本地域 名服务器收到客⼾端的请求后,如果缓存⾥的表格能找到 http://www.server.com ,则
它直接返回 IP 地址 。如果没有,本地 DNS 会去问它的根域名服务器:“⽼⼤, 能告诉我
http://www.server.com 的 IP 地址 吗?” 根域名服务器是最⾼层次的,它不直接⽤于域名解
析,但能指明⼀条道路。
- 根 DNS 收到来⾃本地 DNS 的请求后,发现后置是 .com ,说:“ http://www.server.com 这个
域名归 .com 区域管理”,我给你 .com 顶级域名服务器地址 给你,你去问问 它吧。”
- 本地 DNS 收到顶级域名服务器的地址 后,发起请求问“⽼⼆, 你能告诉我
http://www.server.com 的 IP 地址 吗?”
- 顶级域名服务器说:“我给你负责 http://www.server.com 区域的权威 DNS 服务器的地址 ,你
去问它应该能问到”。
- 本地 DNS 于是转向问权威 DNS 服务器:“⽼三, http://www.server.com 对应的IP 是啥呀?”
http://www.server.com 的权威 DNS 服务器, 它是域名解析结果的原出处。为啥叫权威呢?就
是我的域名我做主。
权威 DNS 服务器查询后将对 应的 IP 地址 X.X.X.X 告诉本地 DNS 。
本地 DNS 再将 IP 地址 返回客⼾端,客⼾端和⽬标建⽴连接。
⾄此,我们完成了 DNS 的解析过程。现在总结⼀下,整个过程我画成了⼀个图。

访问DNS 服务器⽤的什么 协议?
DNS 基于UDP 协议实现,DNS 使⽤UDP 协议进⾏域名解析和数据传输。因为基于UDP 实现DNS 能
够提供低 延迟、简单快速、轻量级的特性,更适合DNS 这种需要快速响应的域名解析服 务。
低延迟: UDP 是⼀种⽆连接的协议,不需要在数据传输前建⽴连接,因此可以减少传输时延,
适合DNS 这种需要快速响应的应⽤场景。
简单快速: UDP 相⽐于TCP 更简单,没有TCP 的连接管理和流量控制机制,传输效率更⾼,适合
DNS 这种需要快速传输数据的场景。
轻量级:UDP 头部较⼩,占⽤较少的⽹络资源,对于⼩型请求和响 应来说更加轻量级,适合
DNS 这种频繁且短⼩的数据交换。
UDP 可靠性不⾼是怎么解决了
尽管 UDP 存在丢包和数据包损坏的⻛险,但在 DNS 的设计 中,这些⻛险是可以被容忍的。DNS
使⽤了⼀些机制来提⾼可靠性,例如查询超时重传、请求重试、缓存等,以确保数据传输的可靠
性和正确性。
ping ⽤的什么 协议,为什么不 ⽤UDP ,要⽤ICMP ?
ping 使⽤ ICMP ⽽不是 UDP 的主要原因是 ICMP 是专⻔为⽹络诊断和错误报告设计 的协议,具
有简单性、内置的错误处理机制和⼴泛的⽀持。
UDP 是⼀个⽆连接的协议,不提供内置的错误报告机制,如果使⽤ UDP 进⾏类似 ping 的操
作,需要应⽤程序⾃⼰实现错误检测和报告逻辑。
ICMP 提供了内置的错误处理机制,如⽬标不可达、超时等。这使得 ping 命令能够⾃动处理这
些错误,并提供有⽤的诊断信息。 ping 命令只需要发送⼀个 ICMP Echo 请求数据包,并等待相
应的 Echo 回应数据包。
MySQL
MySQL 索引为什么 ⽤ b+ 树?
B+Tree vs B Tree :B+Tree 只在叶⼦节点存储数据,⽽ B 树 的⾮叶⼦节点也要存储数据,所以
B+Tree 的单个节点的数据量更⼩,在相同的磁盘 I/O 次数下,就能查询更多的节点。另外,
B+Tree 叶⼦节点采⽤的是双链表连接,适合 MySQL 中常⻅的基于范围的顺序查找,⽽ B 树⽆
法做到这⼀点。
B+Tree vs ⼆叉树:对于有 N 个叶⼦节点的 B+Tree ,其搜索复杂度为O(logdN) ,其中 d 表⽰节点允许的最⼤⼦节点个数为 d 个。在实际的应⽤当中, d 值是⼤于100 的,这样就保证了,即
使数据达到千万级别时,B+Tree 的⾼度依然维持在 3〜4 层左右,也就是说⼀次数据查询操作
只需要做 3〜4 次的磁盘 I/O 操作就能查询到⽬标数据。⽽⼆叉树的每个⽗节点的⼉⼦节点个数
只能是 2 个,意味着其搜索复杂度为 O(logN) ,这已经⽐ B+Tree ⾼出不少,因此⼆叉树检 索到⽬标数据所经历的磁盘 I/O 次数要更多。
B+Tree vs Hash :Hash 在做等值查询的时候效率贼快,搜索复杂度为 O(1) 。但是 Hash 表不适合做范围查询,它更适合做等值的查询,这也是 B+Tree 索引要⽐ Hash 表索引有着更⼴泛的适
⽤场景的原因
MySQL ⾏锁和表锁介绍⼀下?
在 MySQL ⾥,根据加锁的范围,可以分为全局锁、表级锁和⾏锁三类。

全局锁:通过flush tables with read lock 语句会将整个数据库就处于只读状态了,这时其他线程
执⾏以下操作,增删改或者表结构修改都会阻塞。全局锁主要应⽤于做全库逻辑备份,这样在
备份数据库期间,不会因为数据或表结构的更新,⽽出现备份⽂件的数据与预期的不⼀样。
表级锁:MySQL ⾥⾯表级别的锁有这⼏种:
表锁:通过lock tables 语句可以对表加表锁,表锁除了会限制别 的线程的读写外,也会限制
本线程接下来的读写操作。
元数据锁:当我们对数据库表进⾏操作时,会⾃动给这个表加上 MDL ,对⼀张表进⾏ CRUD
操作时,加的是 MDL 读锁;对⼀张表做结构变更操作的时候,加的是 MDL 写锁;MDL 是
为了 保证当⽤⼾对表执⾏ CRUD 操作时,防⽌其他线程对这个表结构做了变更。
意向锁:当执⾏插⼊、更新、删除操作,需要先对表加上「意向独占锁」,然后对该记 录加独
占锁。意向锁的⽬的是为了 快速判断表⾥是否有记录被加锁。
⾏级锁:InnoDB 引擎是⽀持⾏级锁的,⽽ MyISAM 引擎并不⽀持⾏级锁。
记录锁,锁住的是⼀条记录。⽽且记录锁是有 S 锁和 X 锁之分的,满⾜读写互斥,写写 互斥
间隙 锁,只存在于可重复读隔离级别,⽬的是为了 解决可重复读隔离级别下幻读的现象。
Next-Key Lock 称为临 键锁 ,是 Record Lock + Gap Lock 的组合,锁定⼀个范围,并且锁定记
录本⾝。
Redis
Redis 为什么 快
官⽅使⽤基准测试的结果是,单线程的 Redis 吞吐 量可以达到 10W/ 每秒,如下图所⽰:

之所以 Redis 采⽤单线程(⽹络 I/O 和执⾏命令)那么快,有如下⼏个原因:
Redis 的⼤部分操作都在内存中完成,并且采⽤了⾼效的数据结构,因此 Redis 瓶颈可能是机器
的内存或者⽹络带宽,⽽并⾮ CPU ,既然 CPU 不是瓶颈,那么⾃然就采⽤单线程的解决⽅案
了;
Redis 采⽤单线程模型可以避免了多线程之间的竞争,省去了多线程切换带来的时间和性能上的
开销,⽽且也不 会导致死锁问题。
Redis 采⽤了 I/O 多路复⽤机制处理⼤量的客⼾端 Socket 请求,IO 多路复⽤机制是指⼀个线程
处理多个 IO 流,就是我们经常听到的 select/epoll 机制。简单来说,在 Redis 只运⾏单线程的
情况下,该机制允许内核中,同时存在多个监听 Socket 和已连接 Socket 。内核会⼀直监听这些
Socket 上的连接请求或数据请求。⼀旦有请求到达,就会交给 Redis 线程处理,这就实现了⼀
个 Redis 线程处理多个 IO 流的效果。
kafka
kafka 怎么做的吞吐 量那么⼤
** 顺序写⼊优化:**Kafka 将消息顺序写⼊磁盘,减少了磁盘的 寻道时间。这种⽅式⽐随机写⼊
更⾼效,因为磁盘读写头在顺序写⼊时只需移动⼀次。
批量处理技术:Kafka ⽀持批量发送消息,这意味着⽣产者在发送消息时可以等待直到有⾜够的
数据积累到⼀定量,然后再发送。这种⽅法减少了⽹络开销和磁盘I/O 操作的次数,从⽽提⾼了
吞吐 量。
零拷⻉技术:Kafka 使⽤零拷⻉技术,可以直接将数据从磁盘发送到⽹络套接字,避免了在⽤⼾
空间和内核空间之间的多次数据拷 ⻉。这⼤幅降低了CPU 和内存的负载,提⾼了数据传输效
率。
压缩技术:Kafka ⽀持对消息进⾏压缩,这不仅 减少了⽹络传输的数据量,还提⾼了整体的吞吐
量。
docker
docker 底层是怎么实现的??
基于 Namespace 的视图隔离:Docker 利⽤Linux 命名 空间(Namespace )来实现不同容器之间
的隔离。每个容器都运⾏在⾃⼰的⼀组命名 空间中,包括PID (进程)、⽹络、挂载点、IPC (进
程间通信)等。这样,容器中的进程只能看到⾃⼰所在命名 空间内的进程,⽽不会影响其他容
器中的进程。
基于 cgroups 的资源隔离** :cgroups 是Linux 内核的⼀个功能,允许在进程组之间分配、限制
和优先处理系统资源,如CPU 、内存和磁盘I/O 。它们提供了⼀种机制,⽤于管理和隔离进程集
合的资源使⽤,有助于资源限制、⼯作负载隔离以及在不同进程组之间进⾏资源优先处理。
算法题
区间合并
