腾讯QQ后端暑期实习二面
面试题目
开场
- 自我介绍
- 读研原因和规划
项目深度拷打
- 最近用了哪些国外大模型,各自有什么区别和特点?
- 你的项目如何防止 DDoS 攻击(除了限流关停、IP 限流以及用户限流的方法以外)?
- 什么是 SQL 注入?描述一下。
- MyBatis 如何防止 SQL 注入?
- 为什么使用 Redis 存储对话记忆(除了比 MySQL 快的原因以外)?
- 介绍一下 Java 中的垃圾回收。
- Java 中垃圾回收的是什么?
- Nginx 和 Tomcat 在你项目中各自的作用?
- 进程和线程的区别?
- 垃圾回收时是创建线程来回收还是进程?为什么?
- HTTPS 和 HTTP 的区别?
- 你的项目是 HTTP 还是 HTTPS 的网站?如何将 HTTP 网站变成 HTTPS?
算法题
- 括号匹配(LeetCode 20)
参考解析
DDoS 防护(除常规限流外)
- 流量清洗:接入云服务商(如腾讯云 DDoS 高防)进行流量牵引与清洗,过滤恶意流量。
- CDN 隐藏源站:通过 CDN 隐藏真实服务器 IP,攻击流量打到 CDN 边缘节点而非源站。
- 黑洞路由:极端情况下由运营商将攻击流量丢弃,保护网络基础设施。
- 验证码 / 人机识别:对高频请求触发 CAPTCHA,区分真实用户与僵尸机器。
SQL 注入
- 攻击者在输入字段中拼入恶意 SQL 片段(如
' OR '1'='1),改变原 SQL 语义,从而绕过验证或拖取数据。 - 防御核心:参数化查询 / 预编译,不将用户输入直接拼接进 SQL 字符串。
MyBatis 如何防止 SQL 注入
- 使用
#{}占位符:MyBatis 底层调用 JDBCPreparedStatement,将参数作为值传入,不会改变 SQL 结构。 - 避免使用
${}:${}是字符串直接替换,会导致注入风险,仅在表名/列名动态拼接时谨慎使用并做白名单校验。
Redis 存储对话记忆(非性能原因)
- 天然的数据结构支持:Redis List/Hash 可方便地维护多轮对话的顺序和结构。
- TTL 过期机制:可以给对话记忆设置自动过期时间,无需额外清理逻辑,符合会话生命周期。
- 原子操作:并发场景下对对话列表的 push/pop 操作是原子的,避免并发写入混乱。
Java 垃圾回收
- 回收对象:堆内存中不可达(无任何引用链可达)的对象。
- 可达性分析:从 GC Roots(栈帧局部变量、静态变量、JNI 引用等)出发,无法到达的对象标记为可回收。
- 常见收集器:Serial、Parallel、CMS(并发标记清除)、G1(分区化,低停顿)、ZGC(超低停顿)。
- 分代模型:堆分为年轻代(Eden + Survivor)和老年代,Minor GC 回收年轻代,Full GC 回收整堆。
- GC 是线程,不是进程——JVM 进程内启动专用 GC 线程(或线程组),共享同一进程的堆内存,无需跨进程通信,效率更高。
Nginx 与 Tomcat 的职责
- Nginx:反向代理 + 负载均衡、静态资源服务、SSL 终止(HTTPS 卸载)、限流等。
- Tomcat:Java Servlet 容器,负责运行 Spring Boot 等 Java Web 应用,处理动态请求。
- 典型部署:客户端 → Nginx(处理静态/SSL) → Tomcat(处理业务逻辑)。
HTTP 转 HTTPS
- 申请 SSL/TLS 证书(Let’s Encrypt 免费,或云厂商签发)。
- 在 Nginx 配置 443 端口,加载证书和私钥。
- 将 80 端口的 HTTP 请求 301 重定向到 HTTPS。
- (可选)开启 HSTS,强制浏览器只用 HTTPS 访问。
括号匹配(LeetCode 20)
- 使用栈:遍历字符串,遇到左括号入栈,遇到右括号时检查栈顶是否为对应左括号,匹配则弹栈,否则返回 false。
- 遍历结束后栈为空则返回 true,否则 false。
- 时间复杂度 O(n),空间复杂度 O(n)。