1.字节
1.浏览器输入URL
第一步:URL 解析与缓存检查 (The Check)
-
地址解析: 浏览器先看你输的是啥,是搜索关键字还是 URL。如果是 URL,检查协议(http/https)。
-
HSTS: 如果网站强制 HSTS,浏览器会强制把 http 替换为 https。
-
检查缓存(浏览器缓存 → 系统缓存 → 路由器缓存):
- 如果有缓存且没过期,直接从内存/硬盘读页面,不走网络(状态码 200 from memory cache)。
第二步:DNS 域名解析 (The Map)
如果缓存没找到,就要把域名(https://www.google.com/search?q=google.com)变成 IP 地址(142.250.x.x)。
-
本地 Hosts 文件: 先看电脑本地有没有配置。
-
本地 DNS 服务器(LDNS): 问你家里的路由器或者宽带运营商的 DNS。
-
递归/迭代查询:
-
根域名服务器 (.)
-
顶级域名服务器 (.com)
-
加分项:这里可以提一下 CDN(内容分发网络),如果配置了 CDN,DNS 会返回最近的 CDN 节点 IP。
-
第三步:建立 TCP 连接 (The Road) —— 重点
拿到 IP 后,不能直接发数据,要先修路。
-
三次握手 (3-Way Handshake):
-
客户端发 SYN。
-
服务端回 SYN + ACK。
-
客户端回 ACK。
-
为什么三次?为了防止失效的连接请求突然传到服务端,浪费资源。
-
-
HTTPS 握手 (TLS Handshake): (现在的面试必须加上这个!)
-
如果 URL 是
https,在 TCP 握手后,还要进行 TLS 四次握手。 -
交换证书、验证证书合法性、生成会话密钥 (Session Key)。
-
后续数据传输全部加密。
-
第四步:发送 HTTP 请求 (The Traffic)
路修好了,开始跑车(发数据包)。
-
构建请求: 浏览器封装 HTTP 请求报文(请求行、请求头、空行、请求体)。
-
传输: 数据包通过 TCP 层分割、IP 层寻址、数据链路层传输,最终到达服务器。
第五步:服务器处理 (The Server) —— 你的主场(Java)
这是你作为 Java 程序员最该展开讲的地方!
-
接入层: 请求先到防火墙/负载均衡(Nginx)。
-
应用层: Nginx 反向代理给后端的 Tomcat。
-
Spring Boot 处理:
-
请求进入
DispatcherServlet。 -
路由到具体的
Controller。 -
调用
Service处理业务(可能涉及 Redis、MySQL)。 -
返回数据(JSON 或 HTML 视图)。
-
第六步:浏览器渲染 (The View)
浏览器拿到服务器返回的 HTML 代码,开始画图。
-
解析 HTML 生成 DOM 树。
-
解析 CSS 生成 CSSOM 规则树。
-
合并 生成渲染树 (Render Tree)。
-
布局 (Layout/Reflow): 计算每个元素在屏幕上的位置和大小。
-
绘制 (Paint): 把像素画到屏幕上。
- 加分项:提到 JS 可能会阻塞渲染,以及重排(Reflow)和重绘(Repaint)的区别。
第七步:断开连接 (The End)
-
四次挥手 (4-Way Wave):
- 页面加载完(或者 Keep-Alive 超时后),双方断开 TCP 连接。
2.hashmap 结构,为什么要这样,复杂度
3.hashmap put操作,扩容》?
4.hashmap是线程安全的吗,什么是线程安全的
5.java里还用过什么锁
6.reentraLock 与 synchronized
7.JVM 内存模型讲一下
8.咱们写完代码是.class文件吧,他是怎么运行的
9.InnoDB讲一讲
10.B+树讲一讲
11.平时建立索引需要注意什么?
12.联合索引分析
13.limit 性能分析
14.redis是怎样的存储结构?
15.redis的内存淘汰策略
16.redis指定过期时间后怎么删
17.redis持久化?
18.了解过DNS这些概念吗
19.算法题二选一,String字符串相加,接雨水
20.挑一个项目讲讲
21.有什么要问的
2.网新恒天
1.什么情况下用abstract 什么时候用 interface
| 维度 | 抽象类 (Abstract Class) | 接口 (Interface) |
|---|---|---|
| 核心目的 | 代码复用,构建类的层级 | 解耦,定义功能契约 |
| 关系 | IS-A(是什么) | CAN-DO / HAS-A(有什么能力) |
| 成员变量 | 啥都能写 (普通变量, static, final) | 只能写常量 (public static final) |
| 构造方法 | 有 (供子类创建时调用) | 无 |
| 继承限制 | 只能单继承 | 可以多实现 |
- 什么时候用 抽象类 (Abstract Class)?
当你需要代码复用,并且子类之间有强烈的归属关系时。
-
场景 1:你想让子类继承属性(状态)。
- 比如:所有的
Shape(形状)都有color(颜色)和x, y(坐标)。接口存不了这些变量,必须用抽象类。
- 比如:所有的
-
场景 2:你想写“模板代码”。(模板方法模式)
- 比如:
AbstractController。你写好了“记录日志 → 开启事务 → 执行业务 → 关闭事务”的完整流程,只把“执行业务”这一步留空(设为抽象方法),强制子类去填空。
- 比如:
-
场景 3:你在设计一个框架的底层基类。
- 比如:Spring 里的
AbstractApplicationContext,JDK 里的AbstractList。
- 比如:Spring 里的
- 什么时候用 接口 (Interface)?
当你需要制定标准,或者实现模块解耦时。这是微服务和大型系统中最常用的。
-
场景 1:定义一套纯粹的规范或契约。
- 比如:
UserService接口,里面只有login()和register()。你不需要管它是用 MySQL 存的还是用 Redis 存的。
- 比如:
-
场景 2:你需要让不同类的对象具有同一种行为。
- 比如:
Flyable(会飞的)。鸟和飞机毫无血缘关系,但它们都可以实现Flyable接口。
- 比如:
-
场景 3:你需要实现多重继承。
- 比如:一个类既是
Serializable(可序列化),又是Cloneable(可克隆)。
- 比如:一个类既是