Fullstack 面试复习笔记:操作系统 / 网络 / HTTP / 设计模式梳理
Fullstack 面试复习笔记:操作系统 / 网络 / HTTP / 设计模式梳理
面试周期就是要根据JD调整准备内容(挠头),最近会混合复习针对全栈这块的内容,目前是根据受伤的JD,优先选择一些基础的操作系统、Java、Node和React部分,毕竟找的项目基本上都是强前端,弱后端,然后React+Spring+Node的搭配
纯前端感觉真的是4得不能再4了……
操作系统
线程 vs 进程
整体总结&表格对比如下:
进程(Process) | 线程(Thread) | |
---|---|---|
定义 | 操作系统资源分配的最小单位 | 程序执行的最小单位 |
内存空间 | 拥有 独立的内存空间(代码段、数据段、堆、栈) | 共享进程的内存空间(代码段、堆),但有自己独立的栈 |
开销 | 创建和切换的开销 较大 | 创建和切换开销 较小 |
调度 | 操作系统内核调度器 (Scheduler) | |
颗粒度: 整个 process level | 操作系统+ 用户级调度 | |
颗粒度:整个 thread level,特别是multi-thread 的程序中 | ||
通信方式 | 进程间通信(IPC)复杂,如 Pipe、Socket、共享内存等 | 线程间通信方便,因共享内存可直接读写 |
崩溃影响 | 一个进程崩溃不会影响其他进程 | 线程崩溃可能影响整个进程(因为共用地址空间) |
-
调度算法
-
先来先服务(First-Come, First-Served)
-
时间片轮转调度(Round-Robin)
每个process获取固定的时间,等到时间过去后下一个process开始执行
适合time-sharing system,不容易出现starvation的情况
-
优先级调度(Priority Scheduling)
容易造成starvation的问题 → 可以采取 aging 策略,即当一个任务等待时间太长,那么就自动增加该任务的priority
-
多级队列调度 (Multilevel Feedback Queue Scheduling)
总结一下就是Round Robin + Priority Scheduling + dynamic feedback mechanism
- 每个queue中的任务都是按照RR的方式进行调度
- 每个queue有自己的priority,high priority 的queue会被优先调度 (preemptive)
- feedback mechanism类似于aging,当进程耗费时间太久,还没有完成任务,那么该queue的priority就会下降。反之如果当前queue的反应良好,那么priority就会增加
-
高响应比优先调度 (Highest Response Ratio Next)
response ratio指的是等待时间与预计完成时间的一个比例,当这个response ratio很高,意味着:
- 等了很久
- 耗时很短就能完成
-
… 其他
-
-
NodeJS中的Event Loop
整体流程如下:
┌──────────────────────────────┐│ Call Stack (Sync) │└──────────────────────────────┘↓┌──────────────────────────────┐│ Web APIs / libuv thread ││ pool (handles async ops) │└──────────────────────────────┘↓┌──────────────────────────────┐│ Callback / Task Queue │└──────────────────────────────┘↓┌──────────────────────────────┐│ Event Loop │└──────────────────────────────┘↓┌──────────────────────────────┐│ Back into Call Stack │└──────────────────────────────┘
JS中,主任务,是一个 synced call stack,遇到 async 的任务就会推到 task queue(任务队列) 中,完成后再通过 event loop (事件池)回到 cal stack 中
Linux 指令
一些自己用过的常用指令:
类型 | 命令 | 用途简述 |
---|---|---|
文件/目录管理 | ls , cd , mkdir , rm -rf , cp , mv , touch | 基础目录操作 |
文件查看 | cat , less , head , tail -f , grep , find , xargs | 查看日志、过滤关键字、实时追踪日志 |
历史回顾 | history , !! , !123 | 快速复用指令、排查历史操作 |
进程管理 | ps aux , top , htop , kill , kill -9 PID , pkill | 查服务/挂掉进程、定位问题资源占用 |
Docker 相关 | docker ps , docker logs , docker-compose up -d , docker-compose down , docker exec -it | 启停容器、查看日志、进入容器调试 |
网络相关 | curl , ping , netstat , lsof -i | 查看服务通不通、端口占用情况 |
权限操作 | chmod , chown , sudo | 文件权限修改(读写执行) |
常用工具 | which , whoami , df -h , du -sh , env | 系统状态或环境检查 |
Node/JS 项目运维 | npm run build , npm start , yarn dev , pm2 logs , pm2 restart | 项目管理(配合前端服务部署) |
计算机网络知识点
四层网络模型
传统 C/S 架构更多的用四层模型
层级 | 名称 | 功能说明 | 对应协议 |
---|---|---|---|
4 | 应用层 (Application) | 提供应用服务(如浏览网页、发邮件) | HTTP, HTTPS, FTP, DNS |
3 | 传输层 (Transport) | 提供端到端通信,负责数据分段、重传等 | TCP, UDP |
2 | 网络层 (Internet) | 实现跨主机路由和寻址 | IP, ICMP |
1 | 网络接口层 (Link/Network Access) | 控制物理传输,封装为帧 | Ethernet, WiFi, ARP |
七层网络模型
现在SaaS更多的让开发注重 4-7 层,其他的则由cloud platform自己消化了
层级 | 名称(英文) | 作用描述 | 举例 |
---|---|---|---|
7 | 应用层 (Application) | 用户直接交互的数据服务层 | HTTP, SMTP, FTP |
6 | 表示层 (Presentation) | 处理格式、加密、压缩等 | SSL/TLS, JPEG |
5 | 会话层 (Session) | 管理会话,维持连接状态 | NetBIOS, RPC |
4 | 传输层 (Transport) | 数据分段、传输可靠性 | TCP, UDP |
3 | 网络层 (Network) | 寻址与路由 | IP, ICMP |
2 | 数据链路层 (Data Link) | 帧结构与错误检测 | Ethernet, MAC |
1 | 物理层 (Physical) | 比特传输 | 电缆、网卡、光纤 |
HTTP协议
HTTP(HyperText Transfer Protocol,超文本传输协议) 是一种位于OSI模型第七层的应用层协议,用于 Web 浏览器与服务器之间的数据通信。它是客户端-服务器架构的典型代表,定义了客户端如何请求资源,以及服务器如何响应,通常基于TCP传输协议
- 常见规范,如Method、Header、Cookies & 常见状态码
-
Method → 对 RESTful API相当重要
Method 中文含义 常见用途 是否幂等 是否安全 请求体支持 常见成功状态码示例 GET
获取资源 查询列表、获取详情 ✅ 是 ✅ 是 ❌ 不支持 200 OK POST
新建资源 创建数据、提交表单、登录 ❌ 否 ❌ 否 ✅ 支持 201 Created PUT
更新资源(整体) 全量更新对象 ✅ 是 ❌ 否 ✅ 支持 200 OK / 204 No Content PATCH
更新资源(部分) 局部修改 ❌ 否(一般认为是) ❌ 否 ✅ 支持 200 OK / 204 No Content DELETE
删除资源 删除单项或集合 ✅ 是 ❌ 否 ✅(可选) 200 OK / 204 No Content / 404 Not Found OPTIONS
查询通信选项 (preflight) CORS 预检、支持的方法查询 ✅ 是 ✅ 是 ❌ 不常用 204 No Content HEAD
获取响应头 与 GET 类似但不返回 body ✅ 是 ✅ 是 ❌ 不支持 200 OK 补充一下:
- 所有的请求都有可能返回 404/3XX/4XX HTTP Code
POST
/PUT
/PATCH
可能会出现 400 Bad RequestPUT
/PATCH
返回 200 还是 204 取决于团队,一般返回200的同时会返回修改过的内容,204则不会- 实际项目中,很多 REST API 并不完全遵循规范,可能出现例如
POST
返回200
(不推荐但常见),或者DELETE
返回200 + 删除详情
的情况。具体实现还是取决团队的期约,理想条件下是遵从 RESTful 最好
-
Header
一些常见的header:
- Strict-Transport-Security
- 强制客户端仅通过 HTTPS 访问,启用 HSTS(HTTP Strict Transport Security);
- 示例:
Strict-Transport-Security: max-age=63072000; includeSubDomains
- Content-Security-Policy
- 功能:限制网页可以加载哪些资源(脚本、图片、样式等),用于防止 XSS 攻击;
- 示例:
Content-Security-Policy: default-src 'self'
- X-Content-Type-Options
- 功能:防止浏览器根据内容推断 MIME 类型,避免 MIME 类型混淆攻击;
- 示例:
X-Content-Type-Options: nosniff
- X-Frame-Options
- 功能:防止网页被嵌入在 iframe 中,从而防御点击劫持攻击(Clickjacking);
- 示例:
X-Frame-Options: DENY
或SAMEORIGIN
- X-XSS-Protection
- 功能:启用浏览器内建的 XSS 过滤器(现代浏览器已逐步废弃);
- 示例:
X-XSS-Protection: 1; mode=block
- Referrer-Policy
- 功能:控制浏览器在请求时是否发送 Referer 信息,可减少隐私泄露;
- 示例:
Referrer-Policy: no-referrer
- Permissions-Policy(旧名:Feature-Policy)
- 功能:控制网页能否使用浏览器的高权限功能(如摄像头、麦克风、地理位置等);
- 示例:
Permissions-Policy: geolocation=(), camera=()
这个其实真的要修改还是得具体看业务场景,现在这个项目之前就会因为InfoSec查出缺少一些security header然后报错,修改完了之后又会影响iframe的功能……
legacy项目做任何的修改都要小心
- Strict-Transport-Security
-
Cookies
基本用途就是保存session id/jwt token这种的,其他的还有广告追踪、语言偏好、主题设置等,当然偏好设置也可以通过local storage去实现。现在最多的还是session 相关的控制,以及一些网站会要权限推送广告……
HttpOnly
为true
时,JS无法通过document.cookie
访问,可以有效避免 XSS攻击- 设置
Secure
会仅在 HTTPS 下发送,更加单圈 SameSite
的设置可以限制跨站请求是否携带cookie,可有效预防 CSRF- 可以通过设置
Expres
/Max-Age
控制过期时间
-
常见状态码
-
200 上面提过了,都是成功码
-
300 负责重定向
状态码 含义 说明 301 Moved Permanently 资源永久移动,新地址应写入响应头 Location
302 Found (Moved Temporarily) 资源暂时移动,客户端应使用响应头 Location
303 See Other 重定向到另一个 URI,通常用于 POST
成功后的重定向304 Not Modified 用于缓存控制,客户端可使用本地副本 -
400 客户端错误,有一部分上面提过了……?
状态码 含义 常见触发场景 400 Bad Request 请求格式不正确 / 参数校验失败(尤其是 POST
、PUT
、PATCH
)401 Unauthorized 用户未登录或 Token 失效(认证失败) 403 Forbidden 无权限访问资源(权限不足) 404 Not Found 请求资源不存在(接口路径错误或资源不存在) 405 Method Not Allowed 请求方式错误,比如用 GET
调用只支持POST
的接口409 Conflict 资源冲突,比如创建重复资源(常见于注册、写入冲突) 422 Unprocessable Entity 校验通过但业务语义不合法(常见于表单验证、字段冲突) 429 Too Many Requests 被限流,超过 API 调用频率限制 -
500 服务器错误
状态码 含义 常见触发场景 500 Internal Server Error 服务端异常,可能是未捕获的异常或代码错误 502 Bad Gateway 网关收到无效响应(常出现在反向代理或微服务) 503 Service Unavailable 服务不可用(可能维护中或资源耗尽) 504 Gateway Timeout 上游服务响应超时(常见于调用链或外部依赖慢)
-
-
HTTPS 简介(HTTP over SSL/TLS)
HTTPS(HyperText Transfer Protocol Secure)是 HTTP 协议在 SSL/TLS 层上的加密封装版本,本质上是:
HTTPS = HTTP + SSL/TLS
在 HTTP 的基础上,通过 SSL/TLS 提供:
- 对称加密(传输内容加密)
- 非对称加密(交换密钥)
- 摘要校验(验证内容完整性)
- 证书认证(验证服务器/客户端身份)
实现了:
- 防窃听:请求和响应内容会被加密,避免被中间人窃取。
- 防篡改:即使截取了数据,也无法修改内容而不被发现。
- 身份认证:通过证书确认服务器身份,防止伪装攻击(如钓鱼网站)。
基础握手流程为:
- 客户端请求
https://
页面,发起 TLS 握手 - 服务端返回证书,客户端验证证书合法性
- 客户端生成对称密钥,并通过公钥加密发送给服务器
- 双方使用该密钥加密通信内容,建立加密信道
TCP 协议
TCP(Transmission Control Protocol)传输控制协议 是一种面向连接、可靠传输的协议,位于 OSI 七层模型第四层的 传输层,用于保障数据从一台主机准确无误地传输到另一台主机。
核心特性包括:
-
面向连接(connection-oriented):传输数据前需要先建立链接,再进行传输
-
可靠性保障(reliable):通过三次握手、四次挥手、重传、校验、排序等机制
-
有序传输(ordered):TCP是基于字节流(byte stream)的协议,每个字节都分配了一个序号,接收方会根据需要进行排序确认(ACK)。因此,就算自数据的接受顺序是乱的,依旧可以保证有序重组
-
流量控制(flow control):通过滑动窗口协议(sliding window protocol)避免发送端“冲爆”接收端
每次通信中,receiver会告知sender自己还能接受多少数据(窗口大小)
-
拥塞控制(congestion control):控制网络整体负载
- 慢启动(slow start)
- 拥塞避免(congestion avoidance)
- 快速重传(fast retransmit)
- 快速恢复(fast recovery)
‼️ 可以缓解网络拥堵,但是无法防御DDoS
-
Nagle 算法:合并小包提高网络传输数据
-
ACK延迟机制:在接收到数据后稍作延迟(几十ms后)再发ACK,起到减少ACK包的数量,提高效率
需要注意的是,Nagel算法搭配ACK延迟可能会发生互相等待的问题,即Nagel等ACK发包,ACK又处在延迟阶段,就会造成相互延迟,造成用户体验感不顺
-
Keep Alive:每隔一段时间(默认2小时)发送探测包,测试对方链接是否还存活。若几次链接都无响应,那么TCP链接就会失效关闭
-
三次握手
三次握手就发送了三次SYN报文
-
client → server
client向server发送SYN报文,请求连接,并且提供初始SYN序列号
x
这时候client处于 SYN-SENT 的状态,即等待服务器响应
感觉就像加好友的状态,你找到了别人的微信号,然后发送了个好友请求
-
server → client
server接受到信息后,进入准备阶段(SYN Received),并回应SYN-ARK消息,也就是恢复自己的SYN序列号
y
,同时ACK客户端的x+1
这里表示server端同意建立联系,并传递对应的信息
对方获得了你的好友请求,并同意了好友请求,并发送了一条消息
-
client → server
接受到来自server的消息后,client进入ESTABLISH的状态,这时候client需要发送最后一个确认消息,这样server端也能进入ESTABLISHED的状态,从而正式建立联系
主意,这个时候的序列号已经成了
x+1
,也就是对方的 ack 成了下一个 seq id,这时候也要顺势增加ack,这样下一轮server方的seq id也会顺势增加你接受到了对方的消息,最终确认二人好友关系连接成功
-
-
四次挥手
四次挥手的逻辑其实也差不多:
-
client → server
client 向 server发送报文,发起关闭连接的请求,这时候向 server 发送一个 FIN 包,表示我没有任何信息要继续传输,并进入FIN-WAIT-1
这个感觉就像你要离职了,跟老板打了个离职报告
-
server → client
server向client发送报文,表示已知,把最后可能有的数据传送给client,并且进入CLOSE-WAIT阶段
就像公司知道你要离职了,最后还是会丢点东西给你去收尾/交接——当然,作为打工人最后的倔强就是摸最后一段时间,该用的年假都用了,摸完最后一个里程
-
server → client
server 向 client发送报文,这里也会发送一个FIN信号,同时进入LAST-CHECK的阶段
这里就像公司那里走完流程了,最后日期也下来了,就等着你把security badge/电脑还回去
-
client → server
client向server发送最后一个报文,回复ARK,并且进入最终的TIME-WAIT阶段。当server接到这个报文,就会自动关闭连接
这个就想到了最后一步了,security。badge/电脑都交了,等着确定最后一个月工资发了就拍拍屁股走了
-
设计模式
之前面试React的时候都碰到了一个设计模式……我自己觉得是答对了两个,一个Singleton,另一个Factory,最后一个不确定是不是Adapter……这里也趁机好好复习一下
下面会列举常见的23个Java设计模式,来源自GoF(Gang of Four),也就是这本 设计模式:可复用面向对象软件的基础 中提出来的经典分类:
分类 | 模式中文名 | 模式英文名 | 核心思想简介 |
---|---|---|---|
创建型 | 工厂方法模式 | Factory Method | 定义一个创建对象的接口,但让子类决定要实例化哪一个类。 |
抽象工厂模式 | Abstract Factory | 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 | |
单例模式 | Singleton | 保证一个类仅有一个实例,并提供一个全局访问点。 | |
建造者模式 | Builder | 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 | |
原型模式 | Prototype | 通过复制已有的实例来创建新对象,而不是通过实例化类。 | |
结构型 | 适配器模式 | Adapter | 将一个类的接口转换成客户希望的另外一个接口,解决接口不兼容的问题。 |
装饰器模式 | Decorator | 动态地给对象添加一些额外的职责,就像“包装”一样增加功能。 | |
代理模式 | Proxy | 为其他对象提供一种代理以控制对这个对象的访问。 | |
外观模式 | Facade | 为子系统中的一组接口提供一个一致的高层接口,使得子系统更容易使用。 | |
桥接模式 | Bridge | 将抽象部分与实现部分分离,使它们可以独立地变化。 | |
组合模式 | Composite | 将对象组合成树形结构以表示“部分-整体”的层次结构,使用户对单个对象和组合对象的使用具有一致性。 | |
享元模式 | Flyweight | 运用共享技术有效地支持大量细粒度对象的复用。 | |
行为型 | 策略模式 | Strategy | 定义一系列算法,把它们一个个封装起来,并且使它们可以互换。 |
模板方法模式 | Template Method | 定义一个操作中的算法框架,而将一些步骤延迟到子类中实现。 | |
观察者模式 | Observer | 定义对象间的一种一对多依赖关系,当一个对象改变状态时,所有依赖者都会收到通知并自动更新。 | |
迭代器模式 | Iterator | 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。 | |
责任链模式 | Chain of Responsibility | 使多个对象都有机会处理请求,将这些对象连成一条链,直到有对象处理它为止。 | |
命令模式 | Command | 将一个请求封装为一个对象,从而让用户使用不同的请求、队列或日志请求。 | |
备忘录模式 | Memento | 在不破坏封装性的前提下,捕获一个对象的内部状态,并在之后恢复它。 | |
状态模式 | State | 允许对象在其内部状态改变时改变其行为,使其看起来像是修改了其类。 | |
访问者模式 | Visitor | 在不改变数据结构的前提下,定义作用于结构中元素的新操作。 | |
中介者模式 | Mediator | 用一个中介对象封装对象之间的交互,减少对象之间的耦合。 | |
解释器模式 | Interpreter | 给定一种语言,定义它的文法表示,并构建一个解释器解释语言中的句子。 |
常见的设计模式及使用场景
-
单例模式(Singleton Pattern)
- 核心思想:确保一个类只有一个实例,提供全局访问点
- 常见场景:全局配置、日志系统、Redux store
Java 示例:
public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) instance = new Singleton();return instance;} }
JS 示例:
const Config = (function () {let instance;return {getInstance: () => instance || (instance = { env: 'prod' })}; })();
-
工厂模式(Factory Pattern)
- 核心思想:将对象的创建过程封装在一个工厂方法中,由传参决定创建哪个子类
- 常见场景:创建 Spring Bean、数据库连接池、axios 实例
Java 示例:
public interface Animal { void speak(); }public class Dog implements Animal { public void speak() { System.out.println("Woof"); } }public class AnimalFactory {public static Animal getAnimal(String type) {return "dog".equals(type) ? new Dog() : null;} }
JS 示例:
function createUser(role) {if (role === 'admin') return { role, permission: 'all' };return { role, permission: 'limited' }; }
-
代理模式(Proxy Pattern)
- 核心思想:控制对目标对象的访问,可添加缓存、权限、日志等
- 常见场景:RPC 封装、防抖、懒加载、AOP
Java 示例:
public class ServiceProxy implements Service {private final Service impl = new RealService();public void doSomething() {System.out.println("Log before call");impl.doSomething();} }
JS 示例:
const target = { msg: "secret" }; const proxy = new Proxy(target, {get: (obj, prop) => (prop === 'msg' ? '***' : obj[prop]) });
-
责任链模式(Chain of Responsibility Pattern)
- 核心思想:请求沿着链条传递,每个节点有机会处理
- 常见场景:Koa/Express 中间件、日志处理链
JS 示例(中间件组合):
const middlewares = [next => console.log("auth") || next(), next => console.log("log") || next()]; const composed = middlewares.reduceRight((next, fn) => () => fn(next), () => {}); composed();
-
观察者模式(Observer Pattern)
- 核心思想:一对多依赖,状态变化时通知所有观察者
- 常见场景:事件总线、发布订阅、Vue 响应式系统
Java 示例:
Observable obs = new Observable(); obs.addObserver((o, arg) -> System.out.println("Updated")); obs.notifyObservers();
JS 示例(简化版 EventEmitter):
class Emitter {constructor() { this.events = {}; }on(event, fn) { (this.events[event] ||= []).push(fn); }emit(event) { this.events[event]?.forEach(fn => fn()); } }
-
适配器模式(Adapter Pattern)
- 核心思想:将一个接口转成另一个接口,使不兼容的接口协同工作
- 常见场景:日志框架(SLF4J)、前端 API 包装器
JS 示例:
function oldRequest(url, data) { /* legacy logic */ }function adapterNewRequest(config) {const { endpoint, payload } = config;return oldRequest(endpoint, payload); }
-
装饰器模式(Decorator Pattern)
- 核心思想:在不修改原对象的前提下,动态添加新功能
- 常见场景:React 高阶组件、AOP、权限校验
JS 示例:
function withLog(fn) {return (...args) => {console.log("Calling:", fn.name);return fn(...args);}; }
-
策略模式(Strategy Pattern)
- 核心思想:封装不同算法并可动态切换
- 常见场景:表单校验、支付渠道选择、动态排序
JS 示例:
const sorters = {asc: arr => arr.sort((a, b) => a - b),desc: arr => arr.sort((a, b) => b - a) }; sorters['asc']([3, 1, 2]); // [1, 2, 3]
-
模板方法模式(Template Method Pattern)
- 核心思想:定义算法骨架,子类实现部分步骤
- 常见场景:构建流程、pipeline、表单处理
Java 示例:
abstract class DataParser {public final void parseData() {readData(); processData(); writeData();}abstract void readData();abstract void processData();abstract void writeData(); }
-
构造者模式(Builder Pattern)
- 核心思想:将复杂对象构建过程拆分为多个步骤
- 常见场景:配置生成器、PB 构建器、React 组件属性组装
JS 示例:
class UserBuilder {constructor() { this.user = {}; }setName(name) { this.user.name = name; return this; }setAge(age) { this.user.age = age; return this; }build() { return this.user; } }
-
原型模式(Prototype Pattern)
- 核心思想:通过拷贝现有对象创建新对象,而不是通过类实例化
- 常见场景:性能优化、对象复用、克隆功能
JS 示例:
const template = { type: 'person', greet() { console.log("Hi"); } }; const alice = Object.create(template); alice.name = 'Alice';