分页解析
第 7 页面试题
筛选题目 公司、岗位、知识点
公司
公司岗位
岗位
标签
select、poll 和 epoll 有什么区别?
这道题考察 Linux I/O 多路复用的核心差异:它们都解决单线程或少量线程同时管理多个文件描述符的问题,但在内核接口、数据结构、事件通知方式、拷贝成本、遍历成本和高并发可扩展性上差异很大。面试回答不能只背“epoll 更快”,还要说明为什么在大量连接、少量活跃的典型网络服务场景下 epoll 更合适,以及为什么在连接数很少或跨平台场景下 select、poll 仍然可能足够。
数组和链表、队列和栈有什么区别?
数组和链表是两种底层线性存储结构,差异主要体现在内存布局、随机访问、插入删除、缓存局部性和扩容成本。队列和栈是两种抽象数据类型,差异主要体现在访问顺序和操作约束:队列先进先出,栈后进先出。高质量回答要把这两层概念分开:数组和链表是实现材料,队列和栈是使用规则,队列和栈都可以用数组或链表实现。
图像特征处理用什么网络?
图像特征处理没有单一固定网络,核心是根据任务目标、数据规模、实时性和部署环境选择特征提取骨干网络、任务头和训练策略。传统通用选择是 CNN 骨干,如 ResNet、EfficientNet、MobileNet;如果数据规模较大、需要全局建模或与文本对齐,可以选择 ViT、Swin Transformer 或 CLIP 类多模态编码器;如果是检测、分割、OCR 等结构化任务,还需要 FPN、YOLO、Faster R-CNN、Mask R-CNN、OCR encoder-decoder 等任务头。
如何确保cookie不重复?
确保 cookie 不重复,不能只理解为 cookie 名字不要重复。浏览器实际以 name、Domain、Path 作为主要唯一键;同一组键再次 Set-Cookie 会覆盖旧值,但同名 cookie 如果 Domain 或 Path 不同,可以同时存在,并在请求时一起进入 Cookie 请求头。面试中应回答:统一 cookie 的 name、Domain、Path,更新时使用相同属性覆盖;清理历史重复项时按旧 Domain/Path 组合逐个过期;服务端用高熵随机值和存储层唯一约束保证 sessionId/token 唯一。
如何从后端角度控制cookie的域?
从后端角度控制 cookie 的域,核心是在 HTTP 响应头 Set-Cookie 中设置 Domain 属性。后端只能把 cookie 设置到当前请求主机本身,或其合法父域,不能随意设置到无关域名。是否能被后续请求携带,还受 Domain、Path、Secure、SameSite、浏览器公共后缀规则以及跨站请求策略共同影响。
常见 HTTP 状态码有哪些?
HTTP 状态码是服务端对一次请求处理结果的标准化表达,面试中不能只背 200、404、500,而要按 1xx、2xx、3xx、4xx、5xx 五大类理解语义,再结合协议升级、缓存协商、重定向差异、REST 创建与删除语义、限流和网关故障来回答。真正高质量的答案应能说明状态码由谁返回、客户端应如何处理、是否影响缓存、是否改变请求方法,以及在排查线上问题时如何从状态码判断责任边界。
计算机网络: HTTP为什么说是无状态的?
HTTP 被称为无状态协议,核心含义是协议本身不会在服务端自动保存两次请求之间的业务上下文。每个请求都应携带足够的信息,让服务端独立理解并处理它。登录态、购物车、个性化配置等连续业务能力并不是 HTTP 天生具备的,而是通过 Cookie、Session、JWT、数据库或缓存等应用层机制补上的。
TCP 四次挥手的流程是什么?
TCP 四次挥手本质上是连接两端分别关闭各自发送方向的过程。由于 TCP 是全双工协议,一端发出 FIN 只表示自己不再发送数据,但仍能接收对端数据;对端确认后,也可能还要继续发送剩余数据,等发送完成再发自己的 FIN。因此面试回答要讲清 FIN 和 ACK 的含义、半关闭边界、双方状态迁移,以及 TIME_WAIT、CLOSE_WAIT、FIN_WAIT、LAST_ACK 等状态背后的工程意义。
JVM 堆内存通常如何分区?
JVM 堆可以从两条线理解:按对象生命周期分为年轻代和老年代,年轻代内部又分 Eden 和两个 Survivor;按具体垃圾收集器实现,传统分代收集器更强调连续代空间,G1、ZGC、Shenandoah 等更强调 region 或分区化管理。回答时要特别说明:元空间和线程栈不属于堆,TLAB 是 Eden 中给线程预分配的私有分配缓冲区,大对象可能直接进入老年代或被特殊 region 管理。
TopK,如果k很小,n很大,用什么方法?
当 k 很小、n 很大时,TopK 的标准精确解通常是维护大小为 k 的堆,而不是全排序。求最大 TopK 用小顶堆,求最小 TopK 用大顶堆,复杂度 O(n log k)、空间 O(k)。如果数据可放入内存且允许原地修改,可以补充 quickselect;如果值域小、数据海量或允许近似,还要分别考虑计数桶、分片合并和近似频率算法。
堆上的元素满了会发生什么?
JVM 堆满通常指堆内存中可用于对象分配的空间不足。对象分配失败后,虚拟机会先尝试触发 Young GC 或 Full GC 回收空间;如果回收后仍无法满足分配,或者老年代晋升失败、连续 GC 效率过低,就可能抛出 OutOfMemoryError。回答时要围绕对象分配、GC 尝试、晋升失败、OOM 类型、排查与预防展开,不要误讲成优先队列里的堆元素满了。
用zk做注册中心,那zk数据结构是怎样的?
ZooKeeper 做注册中心时,核心数据结构不是表或哈希,而是一个层级命名空间的 znode 树。每个服务、分组、版本和实例都可以映射成路径节点,服务实例通常用临时节点或临时顺序节点表示。客户端通过 watch 订阅子节点变化,实例会话失效后节点自动删除,从而实现服务发现与上下线通知。
数组和链表有什么区别?
数组和链表都是线性表,但底层组织方式不同:数组用连续内存存放元素,链表用离散节点通过引用连接。这个差异决定了数组随机访问快、缓存友好,但插入删除和扩容成本可能高;链表插入删除在已定位节点时很快,但查找慢、缓存局部性差、额外指针开销大。工程上不能只背复杂度,要说明复杂度成立的前提,并结合 Java 的 ArrayList 和 LinkedList 对照。
同题还出现在 1 个公司岗位
红黑树和平衡二叉树的区别?
红黑树和平衡二叉树都是为了避免普通二叉搜索树退化成链表而设计的自平衡二叉搜索树,核心区别在于平衡标准和维护成本。面试中说的平衡二叉树通常特指 AVL 树:它要求每个节点左右子树高度差最多为 1,平衡非常严格,所以查询路径更短;红黑树用颜色规则约束黑色节点数量和红色节点相邻关系,允许一定程度的不完全平衡,因此插入、删除时旋转和调整更少,更适合频繁更新的工程场景。
A/B 实验如何设计和评估?
A/B 实验的核心是用随机分流把策略变化与其他干扰因素隔离开,再用预先定义的指标体系和统计检验判断新方案是否真的带来增益。完整回答应覆盖实验目标、假设、实验单元、分流机制、指标设计、样本量与周期、过程监控、显著性检验、分层分析、风险控制和最终决策。
cpp的虚函数以及实现原理?
虚函数是 C++ 实现运行时多态的核心机制。它允许通过基类指针或引用调用派生类重写后的函数,把调用哪个函数的决定从编译期推迟到运行期。主流编译器通常通过虚函数表和对象中的虚表指针实现:多态类有虚表,对象保存指向虚表的指针,虚调用时先取虚表指针,再按固定槽位找到函数地址并间接调用。
C++多态怎么实现?
C++ 多态本质上是同一接口在不同类型上表现出不同行为。它分为编译期多态和运行期多态:编译期多态由函数重载、运算符重载、模板等在编译阶段完成选择;运行期多态依赖 virtual 虚函数、继承、重写以及基类指针或引用,在程序运行时根据对象真实类型进行动态绑定。回答不能只停留在虚函数表四个字,还要讲清楚触发条件、对象内存模型、构造析构规则、虚析构必要性、对象切片和多继承下的边界问题。
Redis的List底层实现原理?
Redis List 的底层实现经历过从 ziplist 与 linkedlist 的组合,到 quicklist 统一承载的演进。核心目标不是单纯追求某一种操作最快,而是在两端插入删除、内存占用、缓存友好性和中间位置修改之间做平衡。回答时要讲清:List 是有序、可重复、按插入顺序组织的线性结构,适合队列、栈、简单消息流等场景,但索引访问和中间元素定位不是它的强项。
为什么要用redis?
Redis 的核心价值不是更快的数据库,而是把高频、低延迟、可短期容忍一致性差异的数据放到内存侧处理,从而缩短读写链路、削峰填谷、降低关系型数据库压力,并利用丰富数据结构、原子命令、过期机制和高可用能力支撑缓存、计数、排行榜、限流、会话、队列等典型场景。
Redis 缓存淘汰策略有哪些?
这题要先区分两个概念:过期删除是针对设置了 TTL 的键,缓存淘汰是 Redis 在内存达到 maxmemory 限制后,为了腾出空间而选择删除哪些键。回答时不能只背策略名称,还要说明 allkeys 与 volatile 的区别、LRU/LFU/TTL/random/noeviction 的选择逻辑,以及这些策略在读多写多、冷热数据明显、TTL 管理严格等场景下的取舍。
Redis 为什么高可用?
Redis 的高可用不是单一能力,而是复制、故障检测、自动切换、分片容灾、持久化、客户端重连和监控治理共同组成的体系。主从复制提升读扩展和副本冗余,哨兵负责发现主节点故障并自动完成主从切换,Cluster 通过分片和多主多从避免单机容量与单点问题,AOF/RDB 持久化降低进程或机器故障后的数据损失。真正回答这道题时,要同时说明 Redis 能恢复服务、能减少数据丢失,但不能承诺在所有极端场景下零丢失,尤其要讲清复制延迟、脑裂和一致性取舍。
为什么Redis的速度这么快?
Redis 快不是单一原因,而是数据结构、内存访问、事件模型、网络处理和工程取舍共同作用的结果。面试回答时不能只说“因为它是内存数据库”或“因为单线程”,更关键的是说明:绝大多数请求走内存,核心命令复杂度低;单线程事件循环减少锁竞争和上下文切换;I/O 多路复用提升并发连接处理能力;协议和数据结构实现轻量;同时 Redis 也通过持久化、复制、集群等机制在速度与可靠性之间做取舍。
集群环境怎么更新本地缓存?
集群环境更新本地缓存的核心是把进程内缓存视为性能优化层,而不是共享事实源。常见方案是数据库作为最终事实源,Redis 作为跨节点共享缓存,本地缓存作为单机热点加速层;数据变更后通过可靠事件广播删除各实例本地缓存,并用 TTL、版本号和补偿机制兜底。
Redis是否支持事务?
Redis 支持事务,但它的事务更像“命令批量排队并按顺序一次性执行”的机制,而不是关系型数据库里带自动回滚、强一致约束检查的事务。面试回答要强调 MULTI、EXEC、DISCARD、WATCH 的作用,以及入队错误和执行期错误的处理差异。
缓存的 key 是什么?
缓存的 key 不是随手拼接的字符串,而是后端系统把业务对象、查询条件、租户环境、版本语义和一致性边界映射到缓存空间的唯一标识。一个好的缓存 key 需要同时解决可定位、可隔离、可失效、可观测、可扩展和可治理的问题,否则很容易出现串数据、删不准、热点集中、基数爆炸和线上排查困难。
热点数据怎么保证redis和db中的一致?
热点数据的 Redis 与数据库一致性,核心不是追求所有场景下绝对强一致,而是先明确业务可接受的一致性等级,再选择缓存模式、写入顺序、失效策略和补偿机制。高频面试答案应围绕 Cache Aside、先更新数据库再删除缓存、删除失败补偿、TTL 兜底、版本号防乱序、binlog/CDC 异步修复、热点保护与强一致场景降级到串行化读写展开。
redis的gossip机制?
Redis Cluster 的 Gossip 机制是集群节点之间交换状态信息的一套去中心化通信机制。每个节点不依赖中心协调者,而是通过定期向其他节点发送 PING、PONG、MEET 等消息,携带自己已知的节点元数据、槽位信息、配置纪元和故障判断结果,使整个集群逐步达成状态收敛,并用于节点发现、拓扑维护、故障疑似与故障确认。
Redis解决了什么问题?
Redis 本质上解决的是把需要极低延迟、高并发访问、临时状态管理和轻量计算的数据,从慢路径中抽出来的问题。它不是关系型数据库的替代品,而是用内存读写、丰富数据结构、过期机制、原子操作、持久化和集群能力,帮助系统降低数据库压力、提升响应速度、承载热点流量,并处理计数、排行榜、会话、限流、分布式锁等高频场景。
Redis的过期策略?
Redis 的过期策略本质上是在性能、内存回收及时性和主线程延迟之间做平衡:它不会为每个带 TTL 的键单独启动定时器,而是通过 TTL 元数据记录过期时间,再结合访问时惰性删除和后台周期性主动抽样删除来清理过期键。回答时要区分过期删除与内存淘汰,并补充持久化、复制、过期风暴和热 Key 场景下的工程治理。
说一下数据库底层数据结构B+数据,为什么用,与二叉平衡树区别 Redis怎么用的?
数据库索引常用 B+ 树,核心原因不是“查找复杂度看起来是 O(log n)”,而是它非常适合磁盘和页式存储:节点扇出高,树高低,单次查询需要的页访问次数少;叶子节点按键有序并通过链表连接,范围查询、排序扫描、分页扫描都很高效。二叉平衡树如 AVL、红黑树更适合内存中的动态查找结构,节点扇出低、树高大、局部性差,如果直接用于磁盘索引会产生大量随机 I/O。
还知道哪些缓存中间件?
缓存中间件不只有 Redis。可以按部署位置和能力分为远程内存缓存、进程内本地缓存、分布式缓存、CDN/HTTP 缓存、数据库内部缓存,以及用于削峰和结果复用的消息缓存、结果缓存。回答这题的关键不是罗列产品名,而是说明 Redis、Memcached、Caffeine、Ehcache、Hazelcast、Ignite、CDN、数据库 Buffer Pool 等分别解决什么问题,以及选型时如何比较数据结构、持久化、一致性、延迟和运维复杂度。
Redis的过期机制和删除机制是什么?
Redis 过期机制用于处理设置了生存时间的 key,核心数据结构是 expires 过期字典;删除过期 key 主要依赖惰性删除和定期主动过期。过期机制解决的是 key 到期后如何消失,内存淘汰解决的是内存不够时牺牲哪些 key,二者不能混淆。
过去经历中怎么应对高并发或高性能场景的?
高并发或高性能场景不是考单点技术名词,而是考候选人能否把真实工程问题讲成闭环:先明确业务目标和容量指标,再通过压测和可观测性找到瓶颈,随后从流量、应用、缓存、队列、数据库、线程池、连接池、锁竞争、水平扩展和稳定性预案等层面治理,最后用结果指标证明方案有效。
锁的实现原理是什么?
锁的实现原理可以概括为:用一个可被原子修改的状态表示锁是否被占用,用所有者信息判断谁持有锁,用等待队列管理竞争失败的线程,用阻塞与唤醒降低空转成本,并通过内存屏障建立临界区内外的可见性与有序性保证。理解锁不能只停留在“加锁和解锁”两个动作,而要能讲清互斥、状态变更、线程挂起、唤醒、公平性、重入、超时、中断和竞争优化之间的关系。
可重入锁的原理?
可重入锁的核心原理是:锁不仅记录有没有被占用,还记录被哪个线程占用以及同一线程重复进入了多少次。当持有锁的线程再次请求同一把锁时,不会被自己阻塞,而是把重入计数加一;退出时计数减一,只有计数归零才真正释放锁并唤醒后续等待线程。Java 中 synchronized 和 ReentrantLock 都支持可重入,但实现层次不同:synchronized 由 JVM 管理监视器和锁记录,ReentrantLock 主要基于 AQS 的 state、独占线程 owner、等待队列、CAS 和 park/unpark 实现。
读写锁怎么实现?
读写锁的核心是把访问分成共享读和独占写:多个读线程可以同时进入,写线程进入时必须排斥所有读线程和其他写线程。Java 的 ReentrantReadWriteLock 基于 AQS 实现,用同一个 state 同时记录读锁和写锁计数,并支持可重入、公平策略、锁降级等语义。
Redis 分布式锁如何实现?
Redis 分布式锁的核心不是用一个 key 表示占用,而是要同时解决互斥、死锁、误删、超时、续期、主从切换和业务兜底。标准实现通常是 SET key token NX PX ttl 获取锁,用唯一 token 标识持有者,用 Lua 脚本先比较 token 再删除来释放锁。
分布式锁的使用场景?
分布式锁用于解决多个进程、多个实例、多个节点同时争抢同一份业务资源时的互斥问题,典型场景包括库存扣减、定时任务去重、幂等控制和资源抢占。面试回答不能只说“防止并发”,还要讲清锁的粒度、过期时间、唯一 token、续期、释放校验、可重入、公平性,以及 Redis、ZooKeeper、数据库方案在性能、一致性和故障边界上的取舍。
线程锁锁的到底是什么?
线程锁并不是把某个线程本身锁住,也不是直接把一段代码或一个变量物理锁住。更准确地说,锁是一种同步协议:它通过某个可竞争的同步状态,约束多个线程进入临界区的顺序,从而保护共享资源及其不变量。Java 中 synchronized 竞争的是对象监视器或类对象监视器,ReentrantLock 竞争的是基于 AQS 维护的同步状态;操作系统层面的 mutex、semaphore 等竞争的是内核或用户态维护的同步状态。
分布式锁代码逻辑里如果发生异常 catch 的时候需要做什么?
分布式锁保护的业务逻辑发生异常时,catch 的重点不是立刻解锁,而是让失败可见、记录足够上下文、决定补偿或重试。锁释放应统一放在 finally,并在释放前确认当前请求仍然持有锁,避免锁泄漏、误删他人锁和异常被吞导致的数据不一致。
MySQL 底层数据结构?
MySQL 底层数据结构在 InnoDB 中主要围绕“页、B+树索引、聚簇索引、二级索引、Buffer Pool、事务日志”展开。真正决定查询性能的不是某一个抽象结构,而是这些结构如何协同:数据按页组织,索引以 B+树维护有序访问路径,主键索引叶子节点保存完整行记录,二级索引叶子节点保存主键值,内存中的 Buffer Pool 缓存热点页,变更再通过 redo log、undo log 等机制保证事务与崩溃恢复。理解这些内容,才能解释为什么 MySQL 不直接使用普通二叉树、红黑树或单纯哈希表作为主要索引结构。
mysql慢查询优化方案?
这道题考察的不是背几个索引原则,而是候选人能否把“发现慢查询、判断瓶颈、制定优化方案、验证效果、防止回退”串成闭环。优秀回答应覆盖慢查询日志与监控定位、EXPLAIN 执行计划分析、索引设计、SQL 改写、表结构与数据规模治理、分页与排序优化、锁等待排查、缓存与业务链路优化,以及上线后的持续观测。
内存资源很宝贵,为什么不能直接访问数据库表?
不能直接访问数据库表的原因是,表不是应用进程里可随意读取的一块内存数组,而是数据库引擎管理的持久化数据结构。应用需要通过 SQL、连接、权限、索引、事务和数据库协议访问数据;数据库内部再决定从磁盘、Buffer Pool、索引页或缓存中读取哪些页。绕过数据库引擎或把全表搬到内存,会破坏一致性、并发控制、恢复能力、安全边界和资源隔离。
InnoDB 和 MyISAM 区别?
InnoDB 和 MyISAM 的核心区别不是简单的谁快谁慢,而是存储引擎目标不同。InnoDB 面向事务一致性、崩溃恢复和高并发 OLTP,支持事务、行级锁、MVCC、外键、聚簇索引和可靠恢复;MyISAM 是早期非事务引擎,主要使用表级锁,不支持事务和外键,恢复能力弱,适合范围非常有限。
后端通过什么连接到数据库?
后端连接数据库的核心链路通常是:业务代码通过 ORM 或数据访问框架发起数据库操作,框架从连接池拿到连接,连接池底层使用数据库驱动,驱动按照数据库协议与数据库实例、代理或中间件建立 TCP 连接,并完成认证、参数协商、SQL 发送、结果解析、事务控制和连接复用。以 Java 后端连接 MySQL 为例,常见链路是 Service/DAO -> MyBatis/JPA/JdbcTemplate -> DataSource/HikariCP/Druid -> JDBC Driver/MySQL Connector/J -> MySQL 协议 -> MySQL Server 或数据库代理。
MySQL事务的四种特性,分别解释?
MySQL 事务的四种特性是 ACID:原子性、一致性、隔离性、持久性。在 InnoDB 中,原子性主要依赖 undo log 回滚;隔离性依赖 MVCC、ReadView 和锁;持久性主要依赖 redo log 及刷盘机制;一致性不是某一个日志单独保证的,而是由数据库约束、事务语义、隔离控制、崩溃恢复和应用正确性共同保证。
索引下推是什么?
索引下推(Index Condition Pushdown,ICP)是 MySQL 优化器把部分原本由 server 层判断的 WHERE 条件,下推到存储引擎层,在扫描二级索引时先利用索引记录中的列做过滤,再决定是否回表读取完整行。它的核心价值不是减少索引扫描本身,而是减少无效回表次数,尤其适合联合索引中部分条件不能继续用于定位范围、但仍包含在索引列里的场景。
Spring 事务失效有哪些常见场景?
Spring 事务失效不要只背 @Transactional 场景清单,核心要答出声明式事务的运行条件:方法调用必须进入 Spring AOP 代理,由 TransactionInterceptor 配合 TransactionManager 在调用前后开启、提交或回滚事务;常见失效本质上分为三类:没有经过代理、异常没有触发回滚、真实数据库资源没有加入同一个事务。