Tomcat相关面试点

如果你在简历里写了"手写实现简易版 Tomcat",这绝对是一个能和面试官聊上很久的亮点!

这里为你整理了一套**"满分叙述话术"以及"延伸出的高频面试题库"**,建议按照这个逻辑去准备。


一、 🗣️ 面试话术:如何清晰地口述整个 Tomcat 流程?

面试官: "我看你手写了一个 Tomcat,能给我讲讲它的运行工作流程吗?"

🔥 满分叙述模板(建议背诵):

"面试官您好,我手写的 MyTomcat 核心流程主要分为两大阶段:启动初始化阶段请求处理阶段

  1. 首先是启动初始化阶段(类似 Spring 的 IoC 机制):
    Tomcat 启动前,会先执行 ServletConfigMapping 中的一段静态代码块。它利用反射文件遍历 技术,扫描我在指定包下的所有类。只要发现类头上带有 @WebServlet 注解,就会通过反射的 newInstance() 提取把这个 Servlet 实例化成一个单例对象 ,并以注解里的 URL 路径做 Key、对象做 Value,存进一个全局的 HashMap 中。这就建立起了一张**'路由映射表'**。
  2. 其次是服务器监听阶段:
    我在主线程中利用 ServerSocket 绑定了 7788 端口,并开启了一个 while(true) 的死循环,调用 accept() 方法阻塞等待客户端连接。
  3. 最后是请求处理与响应阶段:
    当浏览器发来 HTTP 请求时,连接建立。我取出网络连接的 InputStream,读取字节流转换成字符串(即 HTTP 请求报文)。接着我对字符串进行切割,解析出请求方式(GET/POST)请求路径(如 /first)
    拿到路径后,我去全局的 HashMap 里找对应的 Servlet 实例,如果找到了,就调用它的 service() 方法,最终分发到 doGet()doPost() 里处理业务代码。业务处理完后,再把拼接好的 HTML 字符串通过 OutputStream 按照 HTTP 协议格式写回给浏览器,最后关闭 Socket。这就是一整个完整闭环。"

二、 💼 连环炮:由这个项目引发的核心面试题(深度提问)

当你说完上述流程,面试官大概率会顺着你的项目,切入到底层原理。以下是高频考点分类整理

📝 考点 1:关于 Servlet 的基本功

Q1:Servlet 是单例的还是多例的?它是线程安全的吗?

  • :在 Tomcat 中默认是单例 的(路由表 HashMap 里只存了一个实例)。它不是线程安全的! 若多个用户同时访问,Tomcat 内部会开多线程去调用同一个对象的 service 方法。如果我们在这个 Servlet 类里定义了全局成员变量,就会导致数据混乱。
  • 如何解决:禁止使用全局变量,只在方法内部使用局部变量(局部变量在栈帧中,线程间隔离)。

Q2:说一下 Servlet 的生命周期?

  • :加载实例化 -> init() 初始化(只调用1次) -> service() 处理请求(调用无数次) -> destroy() 销毁(只调用1次)。
🌐 考点 2:关于并发模型与服务器架构 (重点拉开差距)

Q3:你写的这套 Tomcat 代码,它能扛住高并发吗?和真正的 Tomcat 有什么区别?

  • 答(承认不足+指出原理) :我写的版本由于使用的是 ServerSocket.accept() 以及在同一个线程里直接处理流,属于纯粹的 单线程 BIO (同步阻塞) 模型。同一时刻只能处理一个用户的请求,别人只能卡在外面等。
  • 真正的 Tomcat :使用的是 多路复用 NIO + 线程池(多线程) 模型。有一个专门的 Acceptor 线程负责快速接收连接,然后将 I/O 读写和业务处理的工作扔进一个全局线程池(Worker 线程)中异步处理,所以在高并发下完全不会阻塞。
🔍 考点 3:关于 HTTP 协议

Q4:当你通过 InputStream 读取到的那一大串字符串(请求报文),它到底包含哪些结构?

  • :标准的 HTTP 请求报文包含四个切片:
    1. 请求行 :如 GET /first HTTP/1.1
    2. 请求头 (Headers) :各种键值对,比如 HostUser-AgentCookie
    3. 空行:只有回车换行,用来分隔请求头和请求体。
    4. 请求体 (Body):如果是 POST 请求发送的表单数据或 JSON,就放在这里。

Q5:GET 和 POST 到底有什么区别?

  • 大白话总结 :GET 是向服务器**"索要/查询"数据,参数暴露在 URL 地址里,不安全,有长度限制;POST 是向服务器"提交/修改"**数据,参数藏在请求体 (Body) 里,相对安全,没有长度大小限制。
🧠 考点 4:关于设计模式与类加载器 (终极装逼点)

Q6:你知道 Tomcat 打破了双亲委派机制吗?为什么?

  • 通俗解答(杀手锏):在 Java 中原本类加载是双亲委派(儿子先让父亲去加载,保证基础类不被篡改)。但是 Tomcat 作为一个容器,里面可能部署了两个不同的项目,项目 A 用了 Spring 3,项目 B 用了 Spring 5。如果用传统的双亲委派,就会导致只能加载一个版本的 Spring,发生版本冲突。
  • 所以,Tomcat 自定义了 WebAppClassLoader(Web应用类加载器),它打破了委派机制,优先加载自己项目的 WEB-INF/lib 下的依赖。由于不同的项目有不同的类加载器,就实现了类之间的彻底隔离

Q7:你在解析 @WebServlet 时使用到了哪种设计思想?

  • :体现了 控制反转 (IoC) 的思想。以前我们要用什么类都是开发者主动 new,但在 Tomcat 里,是我们贴上注解,框架(Tomcat 容器)负责把对象实例化,并把控制权接管过去,在必要的时候再通过"回调"我们的 HashMap.get() + 反射回调"执行我们的代码。

第二题:手写 MyTomcat 和"MyTomcat 线程池版本"的区别在哪里?

我帮您对比了这两个文件夹的核心源码,本质的区别在于:服务器处理并发请求的模型从"单线程的纯 BIO" 升级到了"伪异步的 BIO (配合线程池)"

1. 版本一:普通版 MyTomcat(路边摊单人服务模式)
  • 运行机制 :在主线程里,serverSocket.accept() 接收到一个浏览器的请求后,直接在当前线程往下执行 读取流、解析请求、处理 Servlet 业务的方法。处理完并断开 Socket 之后,主循环才会进入下一次 accept()
  • 致命缺陷:如果你在代码里遇到一个很耗时的请求(比如下载文件花了10秒),在这 10 秒内,主线程被完全卡死。第二个、第三个人无论怎么发请求,Tomcat 都不会搭理,直接处于假死状态。
2. 版本二:MyTomcat 线程池版本(高级餐厅前后台分离模式)

这是企业级架构重构的第一步!在 myTomcat线程池版本 中,你新增了 HandleSocketServerPool.java 和 ServerThreadReader 类。

  • 运行机制
    • 你在启动时,创建了一个核心线程数2,最大线程数自定义,带阻塞队列的 ThreadPoolExecutor (线程池)
    • 主线程里的 while(true) 现在只干一件事 :专门负责 accept() 迎客。拿到客人的 Socket 对象后,立马把他打包成一个 Runnable 任务对象 (ServerThreadReader),扔给线程池去处理。
    • 然后主线程不管了,瞬间回头继续去门口等下一个客人。
  • 核心优势总结 (面试点)
    • 应对高并发:现在哪怕有某个请求卡了 10 秒,它也只是占用了线程池里的一名"服务员"。主线程依然能极快地接收其他上百个并发请求,把它分发给别的服务员处理,Tomcat 不会阻塞了!
    • 资源可控 :为什么不直接为每个请求 new Thread() 而是用线程池?因为如果瞬间来 10000 个请求,直接 new 一万个线程会把内存撑爆(OOM)。利用通过你代码里的 ArrayBlockingQueue 可以把多出来的请求先放在队列里排队,起到了削峰填谷的缓冲作用。

装逼建议 :如果面试官问"这套代码还有没有优化空间?"

你可以回答:"虽然线程池版本解决了主线程阻塞排队的问题,但它依然是 BIO 阻塞流(InputStream.read 会卡死线程)。如果有 1 万个用户保持连接却不说话(比如做聊天室),就会把线程池的 1 万个线程全占满一直干等着。下一步的究极进化就是改成 **NIO(非阻塞)+ 多路复用(Selector)**的架构,这也是真实 Tomcat 8 之后和 Netty 所采用的终极方案。"

相关推荐
皙然9 小时前
Mybatis面试题目
面试·tomcat·mybatis
gameboy03111 小时前
【异常解决】Unable to start embedded Tomcat Nacos 启动报错
java·tomcat
gameboy03111 小时前
Windows操作系统部署Tomcat详细讲解
java·windows·tomcat
无名-CODING12 小时前
Tomcat 底层核心知识点字典(面试必备)
java·面试·tomcat
liurunlin8881 天前
Linux系统安装部署Tomcat
linux·运维·tomcat
摇滚侠1 天前
从 Tomcat 服务最大连接数角度讲一讲高峰期高考查分网站打不开,服务器的资源是有限的,同一时间大量用户连接服务器,会耗尽服务器的资源,服务器会拒绝新的连接
java·服务器·tomcat
二月夜2 天前
记SpringBoot升级Tomcat引发的两类典型问题及解决方案
spring boot·后端·tomcat
liurunlin8882 天前
Tomcat 都有哪些核心组件
java·tomcat·firefox
这也能行2 天前
Tomcat
java·tomcat