JVM社招面试题:队列和栈是什么?有什么区别?我在面试现场讲了个故事…



"小米,你面试那家十八线大厂的 JVM 题都问了啥?"

"栈和队列!你猜我怎么答的?我直接讲了个日常故事,面试官听完都笑了------然后就让我进二面了!"

社招面试现场,小米又被问到"老问题"

事情发生在不久前的某次 JVM 社招面试中。作为一个写 Java 写了快十年的开发者,我对 JVM 这块多少还是有点底气的。可没想到,刚坐下,面试官的第一个问题却不是问 GC,也不是类加载,而是:

"你能说说什么是栈和队列吗?它们在 JVM 里有什么应用,区别又在哪里?"

你是不是也觉得这题太基础了?但我告诉你------越基础的题目,越能看出候选人的基本功和表达能力。

我当时没有急着丢概念,而是笑着说:

"那我就给您讲个故事吧,栈和队列的故事,就像生活中我们排队买奶茶和叠衣服的过程一样。"

从生活场景讲起:奶茶店和衣柜

故事一:排队买奶茶------这是"队列"Queue

想象一下你中午和同事去奶茶店,人太多了,你只能排队。

每来一个人,都排在你后面;而奶茶店做完一个奶茶,是先给最前面那位顾客,对吧?这就是典型的先进先出(FIFO) 的规则:

  • 谁先来,谁先拿;
  • 后来的人只能等前面的人拿完;
  • 加塞是禁止的(当然现实可能会有,但数据结构中不允许)。

所以,我们可以说:"排队买奶茶",就是队列 Queue的生活版写照!

故事二:叠衣服进衣柜------这是"栈"Stack

再来看另一个场景:你周末打扫卫生,把衣服一件件折好往柜子里叠。

每一件新衣服,都放在上一件的上面;而你下次想拿衣服,肯定是从最上面拿,对吧?也就是最后放进去的,最先拿出来。

这就是后进先出(LIFO) 的规则。

  • 谁最后放进去,谁最先拿出来;
  • 如果你想拿最下面的那件衣服,是不是还得先拿出上面所有的衣服?这很麻烦,但这就是的特性。

所以我们说,叠衣服进柜子 ,就是栈 Stack的生活版写照!

从生活回到技术:栈和队列的定义与区别

故事讲完了,面试官已经笑出了声。我乘胜追击,马上补充了技术定义:

栈(Stack)

  • 定义 :一种受限的线性表,只允许在一端进行插入和删除操作。
  • 操作方向:只能在"栈顶"操作。
  • 顺序特性:后进先出(LIFO)。
  • 常用操作
    • push():压栈
    • pop():出栈
    • peek():查看栈顶元素但不移除

队列(Queue)

  • 定义 :一种受限的线性表,只允许在一端插入、另一端删除
  • 操作方向:插入在"队尾",删除在"队头"。
  • 顺序特性:先进先出(FIFO)。
  • 常用操作
    • offer() / add():入队
    • poll() / remove():出队
    • peek() / element():查看队头元素

栈 vs 队列 核心区别

JVM 中的栈和队列:不仅仅是数据结构

聊完概念,我补了一句:"其实 JVM 里,'栈'和'队列'都无处不在!"

面试官点点头,于是我开始举例:

1. 栈在 JVM 中的应用:Java 虚拟机栈

JVM 中的每个线程都会分配一个 虚拟机栈(Java Virtual Machine Stack) ,这个栈里保存的是:

  • 栈帧(Stack Frame) :代表一个方法的调用;
  • 每个栈帧包括局部变量表、操作数栈、方法返回地址等。

每次方法调用,就会压入栈帧 ;方法执行结束,就会弹出栈帧

是不是就像我们上面说的"叠衣服"?调用链越深,衣服堆得越高;异常时如果不处理,直接堆栈溢出,就是"StackOverflowError"。

2. 队列在 JVM 中的应用:线程池任务调度

再说说队列的使用,最典型的就是线程池:

线程池中的任务,不可能同时执行,怎么办?就用阻塞队列(如 LinkedBlockingQueue) 来排队!

比如你提交了 10 个任务,但只有 5 个线程,前 5 个任务会立即执行,后 5 个会排在队列中等待调度。

队列的设计让线程池调度更高效,也避免了线程频繁创建销毁。

面试官继续追问:"那你用过哪些实现类?"

这个问题就涉及 Java 里提供的数据结构了,我也提前准备过,直接开讲:

栈的实现类:

  • Stack:古老的类,继承 Vector,线程安全,但已不推荐;
  • 推荐使用:Deque 接口的 ArrayDeque 作为栈的替代方案,效率更高。

队列的实现类:

  • LinkedList:实现了 Queue 接口,可作为普通队列;
  • PriorityQueue:优先队列,元素会按优先级排列;
  • ArrayDeque:双端队列,高效无锁;
  • ConcurrentLinkedQueue:并发无锁队列,适合多线程场景;
  • BlockingQueue(接口):
    • 实现类如 LinkedBlockingQueue、ArrayBlockingQueue、PriorityBlockingQueue 等;
    • 支持线程阻塞等待入队或出队,广泛用于线程池。

面试官最后一问:如果你来设计一个栈,怎么实现?

我一笑,说:"我就拿数组模拟一个栈,每次 push 就往后放,pop 就返回最后一个元素,当然还得处理溢出和动态扩容。"

并简单描述了代码逻辑,用 ArrayList 或 LinkedList 都可以轻松实现。

面试官点头:"你讲得很有条理,故事化地解释也挺好,二面通知等 HR 吧。"

我心里暗自窃喜:讲技术,不一定非得干巴巴。讲故事、类比生活,有时更打动人。

总结:栈和队列,基础但不简单

写到这里,咱们来回顾一下:

  • 栈:后进先出(叠衣服)
  • 队列:先进先出(买奶茶)
  • JVM 中栈用于方法调用,队列用于线程调度;
  • 面试不仅考你会不会,还考你"讲不讲得清"!

最后的小米叮咛

"基础不牢,地动山摇。"

栈和队列是最基础的数据结构,但千万别轻视它。你能把它讲清楚、讲有趣,才能让面试官眼前一亮。

你也可以试试讲讲:

  • 浏览器的"后退"按钮是怎么用栈实现的?
  • Kafka、消息队列中的"消费逻辑"是不是也是队列?
  • Spring 的责任链模式用的是哪种结构?

END

欢迎评论区留言,一起交流!你还遇到过哪些看似简单却被问懵的面试题?

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号"软件求生",获取更多技术干货!

相关推荐
码熔burning2 分钟前
JVM 面试精选 20 题(续)
jvm·面试·职场和发展
刘一说2 分钟前
CentOS 系统 Java 开发测试环境搭建手册
java·linux·运维·服务器·centos
Victor3567 分钟前
Redis(14)Redis的列表(List)类型有哪些常用命令?
后端
Victor3568 分钟前
Redis(15)Redis的集合(Set)类型有哪些常用命令?
后端
卷福同学9 分钟前
来上海三个月,我在马路边上遇到了阿里前同事...
java·后端
bingbingyihao2 小时前
多数据源 Demo
java·springboot
在努力的前端小白7 小时前
Spring Boot 敏感词过滤组件实现:基于DFA算法的高效敏感词检测与替换
java·数据库·spring boot·文本处理·敏感词过滤·dfa算法·组件开发
bobz9659 小时前
小语言模型是真正的未来
后端
一叶飘零_sweeeet9 小时前
从繁琐到优雅:Java Lambda 表达式全解析与实战指南
java·lambda·java8
DevYK9 小时前
企业级 Agent 开发实战(一) LangGraph 快速入门
后端·llm·agent