编程术语
Cookie
Cookie 是一种浏览器的缓存机制,在不同的域名下存储了不同的 cookie,当发送请求的时候会将该域名下的 cookie 存储的信息一起发送到服务器之之中。下面是一张浏览器存储 Cookie 的截图:
Cookie 存储的一些元数据信息可以参考下表:
字段名 | 是否必须 | 示例值 | 说明 |
---|---|---|---|
Name=Value | ✅ 是 | login_user=Tomatos | Cookie 的键值对内容,必须有,值是字符串 |
Path | ❌ 否 | / | 表示此 Cookie 对哪个路径有效,默认为当前路径 |
Domain | ❌ 否 | .example.com | 指定可以接收此 Cookie 的域名,默认是当前域 |
Expires | ❌ 否 | Wed, 01 May 2025 12:00:00 GMT | 设置 Cookie 的过期时间(绝对时间) |
Max-Age | ❌ 否 | 86400 (单位:秒) | 设置 Cookie 的有效期(相对时间),优先于 Expires |
Secure | ❌ 否 | 无值(只要写上即可) | 表示此 Cookie 只会在 HTTPS 请求中发送 |
HttpOnly | ❌ 否 | 无值 | 表示此 Cookie 无法被 JavaScript 访问(如 document.cookie ) |
SameSite | ❌ 否 | Strict / Lax / None | 控制跨站请求时是否携带 Cookie,用于防范 CSRF |
**注:**Cookie 存储在浏览器(客户端)之中
Session
Session 是服务器为了保存用户状态而创建的一个特殊的对象
Session 的工作流程
- 客户端浏览器向服务端发起登录请求。
- 登录成功后,服务端将用户信息存储在服务器端Session对象中,并生成一个唯一的 Session 标识符(由服务器决定是否唯一)。
- 服务端将该 Session 标识符返回给客户端,通常通过 Cookie 存储在客户端浏览器中。
- 客户端在后续请求中会携带该 Session 标识符,服务端通过标识符找到对应的会话信息。
TIP
每个用户对应一个 Session,会话信息存储在服务端。
Cookie 与 Session 的对比
特性 | Cookie | Session |
---|---|---|
存储位置 | 客户端浏览器 | 服务器内存 |
安全性 | 较低,可被客户端查看和修改 | 较高,存储在服务器 |
生命周期 | 可持久化存储 | 默认为会话级,可配置超时时间 |
存储容量 | 有限(通常 4KB) | 较大(受服务器内存限制) |
性能 | 每次请求都会传输 | 只传输会话标识符 |
适用场景 | 记住用户名、主题偏好等非敏感信息 | 用户认证状态、购物车等敏感数据 |
Token
Token 是一种身份验证机制,常用于无状态的认证场景。它通过生成一个唯一的字符串来标识用户身份,避免了在每次请求中都需要存储和验证用户的会话信息。
Token 的特点
- 无状态:服务器不需要存储用户的会话信息,减少了服务器的内存开销。
- 跨平台:Token 可以在不同的客户端(如 Web、移动端)之间通用。
- 安全性:通过加密算法生成,难以伪造,但需要注意 Token 的存储和传输安全。
工作流程
- 用户通过用户名和密码向服务器发起登录请求。
- 服务器验证用户信息,验证成功后生成一个 Token 并返回给客户端。
- 客户端将 Token 存储在本地(如 LocalStorage, SessionStorage, Cookie)。
- 客户端在后续的每次请求中将 Token 放入请求头中(通常是
Authorization
字段)。 - 服务器通过解析 Token 验证用户身份并返回相应的资源。
类型
- JWT(JSON Web Token):一种常见的 Token 格式,由三部分组成:Header、Payload 和 Signature。它是自包含的,包含了用户的基本信息和签名。
- OAuth Token:用于授权的 Token,常用于第三方应用访问用户资源。
Token 与 Session 的对比
特性 | Token | Session |
---|---|---|
存储位置 | 客户端 | 服务器内存 |
状态 | 无状态 | 有状态 |
安全性 | 依赖加密和传输安全 | 较高,存储在服务器 |
生命周期 | 通常有过期时间 | 会话级,可配置超时时间 |
适用场景 | 分布式系统、跨平台认证 | 单一服务器的用户会话管理 |
NOTE
Token 的存储需要注意安全性,避免被恶意获取。
Token 存储位置优劣对比
存储在Session
缺点
- 无法防范XSS攻击
存储在LocalStorage
缺点
- 无法防范XSS攻击
存储在Cookie
优点
- 可以防范XSS攻击(通过设置 HttpOnly 属性)
- 可以防范 CSRF 攻击(通过设置 SameSite 属性)
CSRF
跨站请求伪造(Cross-Site Request Forgery)
一个经典的 CSRF 例子如下:
- 用户先在站点 A(受信任站点)登录,服务器通过 Cookie/Session 保持用户已认证状态。
- 攻击者在自己控制的站点 B 中,构造一个指向站点 A 的请求(如 POST 转账、修改资料、删除数据等),并诱导用户访问站点 B。
- 用户访问站点 B 时,浏览器会自动携带对站点 A 的 Cookie,导致站点 A 误以为是用户本人发起了合法请求,从而执行请求中的敏感操作。
Same-Origin Policy
Same-Origin Policy 即浏览器同源策略, 该策略决定了跨域页面无法读取另一个域名下的 Cookie
XSS
XSS(跨站脚本攻击,Cross-Site Scripting)是一种常见的 Web 安全漏洞,攻击者通过在网页中注入恶意脚本代码,使这些代码在其他用户的浏览器中执行。XSS 攻击通常利用网站对用户输入内容缺乏有效过滤,将恶意 JavaScript 代码插入到页面中。
XSS 的危害
- 窃取用户的 Cookie、Session 等敏感信息,导致账号被盗。
- 伪造页面内容,诱导用户进行钓鱼操作。
- 执行任意操作,如冒充用户发起请求、篡改页面数据等。
- 传播蠕虫病毒,进一步攻击其他用户。
如何防范 XSS
- 对用户输入进行严格的过滤和转义,尤其是在将数据输出到 HTML 页面时。
- 启用浏览器的HTTPOnly 属性,防止 JavaScript 读取 Cookie。
- 启用内容安全策略(CSP),限制页面可执行的脚本来源。
- 避免在页面中直接拼接和输出用户输入的数据。
- 定期对网站进行安全检测,修复潜在的 XSS 漏洞。
Cross-Origin Request
跨域请求(Cross-Origin Request)是指浏览器中的 JavaScript 代码发起的请求 URL 与当前页面 URL 的源(Origin)不同。
当以下任一条件不同时,浏览器认为这是一个跨域请求:
- 协议(Protocol):如 HTTP 与 HTTPS
- 域名 or 主机(Domain or Host):如 example.com 与 api.example.com
- 端口(Port):如 example.com:80 与 example.com:8080
工作流程
浏览器发起跨域请求
- 对于简单请求(如GET),直接发请求。
- 对于复杂请求(如带自定义头、PUT/DELETE等),会先发一个OPTIONS预检请求。
后端返回CORS响应头
- 后端根据配置,在响应头中返回如
access-control-allow-origin
、access-control-allow-methods
等字段。
- 后端根据配置,在响应头中返回如
浏览器校验CORS响应头
- 浏览器会自动检查这些CORS头部字段,判断:
access-control-allow-origin
是否包含当前前端页面的域名access-control-allow-methods
是否包含本次请求的方法access-control-allow-headers
是否包含本次请求的自定义头access-control-allow-credentials
是否允许携带cookie等凭证
- 如果全部符合规则,浏览器就会把响应内容交给前端JS代码。
- 如果不符合,浏览器会拦截响应,前端JS拿不到数据,并在控制台报CORS错误。
- 浏览器会自动检查这些CORS头部字段,判断:
TIP
跨域请求产生的原因是浏览器的同源策略(Same-Origin Policy)限制了不同源之间的交互,以保护用户数据的安全。
NOTE
后端服务之间相互调用不受同源策略限制, 因为同源策略是浏览器的安全机制
多线程
并发
并行指系统在同一时间段内能够同时交替行多个任务。强调的任务的“交替进行”
并行
并行指系统在同一时刻能够同时执行多个任务。强调的任务的“同时进行”,通常依赖于多核或多处理器硬件.
乐观锁
乐观锁是一种多线程同步机制,允许多个线程并发访问共享资源,但在更新资源时会进行冲突检测。
悲观锁
悲观锁是一种多线程同步机制,假设会发生冲突,因此在访问共享资源时会先获取锁,确保只有一个线程可以访问到资源, 其他线程需要等待。
公平锁
公平锁是一种多线程同步机制,确保线程按照请求锁的顺序获取锁.
TIP
公平锁会造成一定的性能开销
非公平锁
非公平锁是一种多线程同步机制,允许线程在请求锁时不按照顺序获取锁,这可能导致某些线程长时间等待。
TIP
如果没有顺序要求,使用非公平锁可以提高性能
独占锁和共享锁
根据锁只能被单个线程持有还是能被多个线程共同持有,锁可以分为独占锁和共享锁
TIP
独占锁是也是一种悲观锁, 而共享锁是也是一种乐观锁
可重入锁
可重入锁(Reentrant Lock)是一种允许同一线程多次获取同一把锁的锁机制。它可以避免死锁问题,因为同一线程在持有锁的情况下可以再次获取该锁而不会被阻塞。
自旋锁
当一个线程尝试获取锁时,如果锁已经被其他线程占用,它不会进入阻塞状态,而是通过循环(自旋)不断地检查锁是否可用。只有当锁被释放后,线程才会获得锁并继续执行。
TIP
自旋锁使用 CPU 时间换 取线程阻塞与调度的开销,但是很有可能这些 CPU 时间白白浪费
TIP
自旋锁适用于锁持有时间很短、线程切换开销较大的场景,可以减少线程上下文切换带来的性能损耗。但如果锁竞争激烈或持有时间较长,自旋会浪费大量 CPU 资源。
NOTE
常见的自旋锁实现有 CAS
(Compare And Swap)等原子操作。
CAS
CAS(Compare And Swap)是一种常用的原子操作机制,广泛应用于多线程编程中。它通过比较内存中的某个值是否等于预期值,如果相等则将其更新为新值,否则不做任何操作。CAS 操作通常由硬件(CPU)指令支持,能够保证在多线程环境下的并发安全。
工作原理
- 读取变量的当前值(旧值)。
- 比较当前值与预期值是否相等。
- 如果相等,则将变量更新为新值;否则不做任何操作。
CAS 操作是原子的,不会被其他线程中断,因此可以实现无锁并发。
优点:
- 无需加锁,性能高,避免了线程阻塞和上下文切换。
- 适用于高并发场景。
缺点:
- 可能出现 ABA 问题(即变量值从 A 变为 B 又变回 A,CAS 认为没有变化)。
- 循环重试可能导致性能下降。
NOTE
Java 中Unsafe类
, VarHandle类(JDK 9+)
提供了CAS 操作的支持,如 compareAndSwapInt
、compareAndSwapObject
等方法。
弱一致性
弱一致性(Weak Consistency)指的是系统不保证每次读操作都能获得最新写入的数据. 也就是说,写操作完成后,其他节点或线程可能在一段时间内还看不到最新的数据
强一致性
强一致性(Strong Consistency)指的是系统在每次写操作完成后,所有后续的读操作都能立即读取到最新写入的数据。 也就是说,系统中的所有节点、线程或副本在任何时刻都能看到同样的数据状态,不会出现读到旧数据或不同步数据的情况。
SQL
SQL(Structured Query Language)是一种用于管理关系型数据库的标准查询语言。
DDL
DDL(Data Definition Language) 数据定义语言,用于定义数据库结构和模式。
DML
DML(Data Manipulation Language) 数据操作语言,用于对数据库中的数据进行查询
DQL
DQL(Data Query Language) 数据查询语言,用于从数据库中检索数据。
DCL
DCL(Data Control Language) 数据控制语言,用于控制对数据库的访问权限。
TCL
TCL(Transaction Control Language) 事务控制语言,用于管理数据库事务。
Spring
IOC
对象的创建不再由自己手动创建, 而是从容器之中获取. 这种将控制权交给别人的思想就是所谓的控制反转(Inverse of Control,IOC)
DL
依赖查找(Dependency Lookup), 根据指定的对象名称或对象的所属类型,主动从IOC容器中获取对应的具体对象
DI
非对称加密
非对称加密是一种加密技术,使用一对密钥:公钥和私钥。公钥可以公开分发,而私钥则保密。数据使用公钥加密后,只有持有私钥的人才能解密。非对称加密常用于安全通信和数字签名。
数字签名为什么能够保证身份的可靠性和信息的完整性?
因为数字签名由数据摘要利用秘钥加密得来, 摘要采用了哈希算法(哈希算法是单向的, 不能够从Hash序列中逆推出原信息)保证了原信息的摘要不能够被破解.接收方使用发送方的公钥解密数字签名(无法解密说明被篡改),得到摘要,然后对接收到的数据进行哈希运算得到一个新的摘要, 比较这两个摘要。如果一致,说明数据没有被篡改,且发送方的身份可靠。
NOTE
数据摘要 = 对数据进行哈希运算得到固定长度的序列
数字签名 = 私钥加密摘要
TIP
私钥可用于生成数字签名,和解密公钥加密的数据.
公钥可用于验证数字签名,和加密数据.
NOTE
如果只需要保证数据的机密性,可以使用公钥加密数据, 然后发送给私钥持有者, 这种方式不保证身份可靠性和信息完整性
如果需要保证数据的完整性和身份验证,可以使用私钥对摘要进行加密得到数字签名
位掩码
位掩码是一种用于操作二进制数据的技术。它是一个特定的二进制数,通过与目标数据进行按位运算(通常是与运算 &
),可以“屏蔽”或“提取”数据中的某些位
0101010110 (目标数据)
0011110000 (位掩码)
JIT
JIT(Just-In-Time,实时编译)是一种程序执行优化技术。它在程序运行期间,将字节码或中间代码动态编译为机器码,从而提升程序的执行效率。JIT 编译器常见于 Java、.NET 等虚拟机环境,可以根据实际运行情况进行优化,使得程序既具有解释执行的灵活性,又能获得接近原生代码的性能。
JNI
JNI(Java Native Interface,Java 本地接口)是一种编程框架,允许 Java 代码与其他编程语言(如 C、C++)编写的本地代码进行交互。通过 JNI,Java 程序可以调用本地方法库中的函数,或者让本地代码调用 Java 方法。这种机制使得 Java 应用能够利用现有的本地库和系统资源,从而扩展其功能和性能。
JMM
JMM(Java Memory Model,Java 内存模型)定义了 Java 程序中变量(包括实例字段、静态字段和数组元素)在内存中的访问规则。JMM 规定了多线程环境下,Java 程序如何通过主内存和工作内存来进行变量的读写操作,从而确保线程之间的可见性、有序性和原子性。