高并发?
一、形容并发的参数有哪些?
在系统性能和高并发场景中,以下参数是核心指标,用于描述系统的并发处理能力:
1. QPS(Queries Per Second)
- 定义:每秒处理的请求数量(查询类操作)。
- 适用场景:Web服务、搜索引擎、API接口等读操作较多的场景。
- 示例:
- 普通网站:QPS ≥ 1000 为高并发。
- 电商促销:QPS 可达数百万(如京东“双十一”峰值 QPS 几百万)。
2. TPS(Transactions Per Second)
- 定义:每秒处理的事务数量(事务类操作,包含读+写+逻辑处理)。
- 适用场景:数据库操作、支付系统、订单处理等涉及事务的场景。
- 示例:
- 传统 OLTP 系统:TPS ≥ 1000 为高并发。
- 分布式数据库:TPS 可达数万到数十万(如 Cassandra、MongoDB 集群)。
3. 并发数(Concurrency)
- 定义:系统同时处理的请求数量或事务数。
- 公式:
并发数 = QPS × 平均响应时间 \text{并发数} = \text{QPS} \times \text{平均响应时间} 并发数=QPS×平均响应时间 - 示例:
若系统 QPS = 1000,平均响应时间 = 0.5 秒,则并发数 = 500。
4. 响应时间(Response Time, RT)
- 定义:请求从发起至返回结果的时间(单位:毫秒/秒)。
- 关键指标:
- 平均响应时间(Average RT)
- P99 响应时间(99% 请求的响应时间 ≤ 该值)
- 影响因素:CPU、内存、网络延迟、数据库性能等。
5. 吞吐量(Throughput)
- 定义:单位时间内处理的数据量或事务量(如 MB/s、TPS、QPS)。
- 示例:
一个视频流媒体平台的吞吐量可能是 100 GB/s(即每秒传输 100GB 数据)。
6. 错误率(Error Rate)
- 定义:请求失败的比例(如 500 错误、超时等)。
- 高并发下的要求:通常需控制在 1% 以内。
7. 资源利用率
- 关键资源:CPU、内存、磁盘 I/O、网络带宽。
- 监控意义:资源利用率过高可能导致系统瓶颈(如 CPU 95% 持续运行)。
8. 最大连接数(Max Connections)
- 定义:服务器可同时支持的最大客户端连接数。
- 限制因素:操作系统参数(如
max_connections)、硬件资源。
二、怎么算高并发?(高并发的标准)
高并发的标准因行业和场景而异,以下是一些常见领域的参考:
1. Web 应用
- 普通网站:QPS ≥ 1000 为高并发。
- 电商网站:
- 日常:QPS 5000–10000 为高并发。
- 促销活动:QPS 数百万(如天猫双 11 订单峰值 58.3 万笔/秒)。
- 社交媒体:
- QPS ≥ 10,000 为高并发(如微博、朋友圈动态刷新)。
2. 金融系统
- 银行系统:TPS ≥ 1000 为高并发。
- 证券交易系统:TPS ≥ 5000 为高并发。
3. 在线游戏
- 大型多人在线游戏(MMORPG):QPS ≥ 5000–20,000 为高并发。
4. 流媒体服务
- 视频平台:QPS ≥ 100,000 为高并发(如 YouTube、Netflix)。
5. API 网关和微服务
- API 网关:QPS ≥ 10,000 为高并发。
- 微服务:单服务 QPS ≥ 1000,整体系统 QPS ≥ 10,000 为高并发。
三、如何计算高并发?
1. 基于日活量(DAU)估算
-
公式:
平均并发用户数 = DAU × 平均会话时长 一天总时间 \text{平均并发用户数} = \frac{\text{DAU} \times \text{平均会话时长}}{\text{一天总时间}} 平均并发用户数=一天总时间DAU×平均会话时长
峰值并发用户数 = 平均并发用户数 + 3 × 平均并发用户数 \text{峰值并发用户数} = \text{平均并发用户数} + 3 \times \sqrt{\text{平均并发用户数}} 峰值并发用户数=平均并发用户数+3×平均并发用户数 -
示例:
DAU = 400,平均会话时长 = 2 小时,一天总时间 = 24 小时。
平均并发用户数 = (400 × 2) / 24 ≈ 33.33。
峰值并发用户数 ≈ 33.33 + 3 × √33.33 ≈ 48.95。
2. 基于 PV(页面浏览量)估算
-
公式:
QPS = PV × 80 % 高峰时间(秒) \text{QPS} = \frac{\text{PV} \times 80\%}{\text{高峰时间(秒)}} QPS=高峰时间(秒)PV×80%
并发数 = QPS × 平均响应时间 \text{并发数} = \text{QPS} \times \text{平均响应时间} 并发数=QPS×平均响应时间 -
示例:
网站每天 PV = 1000 万,80% 的访问集中在 4.8 小时(20% 的时间)。
QPS ≈ (1000 万 × 80%) / (4.8 × 3600) ≈ 493.84。
并发数 ≈ 493.84 × 0.5 秒(假设平均响应时间)= 247。
四、企业中的高并发解决方案
1. 负载均衡
- 工具:Nginx、HAProxy、LVS。
- 策略:轮询、加权轮询、最小连接数、IP 哈希。
2. 缓存优化
- 工具:Redis、Memcached。
- 场景:缓存热门数据(如商品详情页、用户会话)。
3. 数据库优化
- 分库分表:水平拆分(如按用户 ID 分片)。
- 读写分离:主库写,从库读。
4. 消息队列
- 工具:Kafka、RabbitMQ。
- 场景:削峰填谷(如秒杀、支付异步处理)。
5. 分布式架构
- 微服务:拆分单体应用为多个独立服务。
- 服务治理:熔断、限流、降级(如 Hystrix、Sentinel)。
六、总结
| 参数 | 定义 | 高并发标准示例 |
|---|---|---|
| QPS | 每秒查询数 | 电商促销 QPS 数百万 |
| TPS | 每秒事务数 | 金融系统 TPS ≥ 1000 |
| 并发数 | 同时处理的请求数 | QPS × 响应时间 |
| 响应时间 | 请求处理耗时 | P99 ≤ 100ms(高性能场景) |
| 吞吐量 | 单位时间处理的数据量 | 视频平台 100GB/s |
| 错误率 | 请求失败比例 | < 1%(高并发下) |
HR面试以BOSS为例
你有什么优势?
1、不仅理论知识充足,而且对不同维度的技术也能很快上手,具有一定的实践能力。
2、团队协作能力强,在团队项目和过往实习中顺利对接需求,解决问题。
为什么选择我们?
首先我非常认同贵公司价值观(提前看),并且您的业务线/产品线非常有前景,在和您的面试过程中感受到了良好的团队氛围,有挑战性的任务,相信我能收获很多。
业务Sense?
参考文章
业务 sense 是感知业务价值的能力,是我判断和评估我做这件事 ROI 的底层逻辑。
背景?实际问题?客户是谁,C端用户、商家?产品是否能用他的 PRD 说服我这样做真的可以解决这个问题?我有没有更好、更优的解决方案?我的上下游都有谁?完成后有没有继续跟进上线后的效果,数据是怎样的?有没有优化的空间?
为什么需要业务Sense?
为了区分人才。
面经
HashMap的put过程
hash,然后解决冲突。 / 扩容,重新计算下标
HashMap1.8之后数据结构是什么
加了红黑树
为什么1.7头插法,1.8改成尾插法?
避免环,保持插入的相对顺序
什么时候树化和退化
>=8,<=6,中间缓冲
红黑树特点
自平衡二叉树,增删改查复杂度接近logn
ConcurrentHashMap是如何解决线程安全的?
分段锁
ConcurrentHashMap的1.7和1.8分别锁的是什么?
Segament,synchornized关键字锁Node,如果Node为null则CAS
MySQL索引结构
InnoDB:主键索引,二级索引。B+树 。
如何建立索引?
场景分析:
- 查询条件为
WHERE a = ? AND b = ?,其中a是INT类型(范围 1-5),b是VARCHAR类型(长度 1-10 随机)。 - 目标:优化该查询的性能。
索引设计建议:
-
联合索引(Composite Index):
- 建立
(a, b)的联合索引。 - 原因:
- 联合索引可以覆盖
WHERE a = ? AND b = ?的条件。 - 如果
b的选择性(唯一值比例)高于a,可以调整字段顺序为(b, a)(但需结合实际数据分布验证)。
- 联合索引可以覆盖
- SQL 语句:
CREATE INDEX idx_a_b ON your_table(a, b);
- 建立
-
覆盖索引(Covering Index):
- 如果查询的字段都在索引中(如
SELECT a, b FROM ...),可以避免回表操作,进一步提升性能。 - 示例:
CREATE INDEX idx_a_b_cover ON your_table(a, b);
- 如果查询的字段都在索引中(如
-
是否需要单独索引?
- 不建议:单独为
a或b建立索引会导致查询时只能使用其中一个字段,无法利用联合索引的最左前缀匹配特性。 - 例外:如果
a的取值范围极小(如 1-5),而b的选择性极高(如唯一值多),可以尝试建立(b, a)联合索引。
- 不建议:单独为
什么样的字段适合建立索引?
适合建立索引的字段:
- 频繁出现在
WHERE、JOIN、ORDER BY、GROUP BY子句中的字段。 - 高选择性的字段(唯一值比例高,如用户ID、订单号)。
- 外键字段(用于关联其他表)。
- 需要排序或分组的字段。
- 唯一性约束的字段(如邮箱、身份证号)。
- 覆盖索引的字段组合(减少回表操作)。
不适合建立索引的字段:
- 大字段(如
TEXT、BLOB)。 - 频繁更新的字段(索引维护成本高)。
- 高度重复的字段(如性别、状态)。
- 非查询条件的字段(如审计字段
create_time)。 - 函数或计算字段(如
WHERE YEAR(date) = 2024)。
数据库分过表吗?
回答:
- 未达到分表条件:当前表未达到 500 万行或 10GB 数据量,无需分表。
- 了解过水平分表/垂直分表:
- 水平分表:按行拆分(如按用户ID哈希分表)。
- 垂直分表:按列拆分(如将大字段拆分到独立表)。
- ShardingSphere:支持分库分表和读写分离的中间件。
水平分表怎么分?
常见分表策略:
-
按哈希分片(Hash Sharding):
- 根据某个字段(如用户ID)的哈希值分配到不同表。
- 示例:
-- 分表规则:user_id % 4 CREATE TABLE user_0 (...); CREATE TABLE user_1 (...); CREATE TABLE user_2 (...); CREATE TABLE user_3 (...);
-
按范围分片(Range Sharding):
- 根据字段值的范围分配(如按时间、ID区间)。
- 示例:
-- 分表规则:order_id 1-1000 -> order_0, 1001-2000 -> order_1...
-
按业务逻辑分表:
- 根据业务场景拆分(如按地区、渠道)。
- 示例:
-- 按销售渠道拆分:sales_channel_1, sales_channel_2...
滚动分表/更新
滚动分表(Rolling Sharding):
- 按时间分表(如按天、月)。
- 示例:
CREATE TABLE orders_202406 (...); CREATE TABLE orders_202407 (...); - 优点:便于归档旧数据,提升查询性能。
数据更新同步:
- 方案:
- 应用层维护:在插入/更新时根据分表规则路由到对应分表。
- 中间件支持:使用 ShardingSphere 自动路由。
- 触发器同步:通过触发器将主表的修改同步到分表(需谨慎,可能影响性能)。
拆分过程中的数据修改如何同步到分表?
场景:
- 主表存在,分表后需要将历史数据迁移并同步后续修改。
解决方案:
-
离线迁移:
- 使用脚本将主表数据按分表规则迁移。
- 示例:
INSERT INTO user_0 SELECT * FROM main_user WHERE user_id % 4 = 0;
-
实时同步:
- 方案一:日志解析:
- 解析 MySQL 的 binlog,将变更同步到分表。
- 工具:Debezium、Canal。
- 方案二:触发器:
- 在主表上定义触发器,将修改同步到分表。
- 示例:
CREATE TRIGGER sync_to_shard AFTER INSERT ON main_table FOR EACH ROW BEGIN IF NEW.user_id % 4 = 0 THEN INSERT INTO user_0 VALUES (NEW.*); END IF; END;
- 方案一:日志解析:
-
中间件支持:
- 使用 ShardingSphere 的分片策略自动路由数据。
切换分表的逻辑:
- 规则引擎:在应用层或中间件中实现分表规则(如
user_id % N)。 - 动态配置:通过配置文件或数据库表动态调整分表规则。
总结
| 问题 | 解答 |
|---|---|
| 如何建立索引? | 创建 (a, b) 联合索引,覆盖查询条件。 |
| 适合建立索引的字段 | 高频查询、高选择性、排序/分组字段。 |
| 水平分表策略 | 哈希分片、范围分片、按业务逻辑分表。 |
| 滚动分表 | 按时间分表(如按天/月)。 |
| 数据同步 | 使用日志解析、触发器或中间件同步。 |
如果需要具体代码示例或更详细的分表策略,请随时提问!
类加载过程
双亲委派机制
JVM调优命令知道哪些
G1:ST时间,大小,-XX
youngGC,fullGC执行频率和时间?fullGC会影响性能吗?
Linux排查命令
top pid | grep -a
线程池过程
创建核心,阻塞队列,最大,拒绝策略
项目中怎么用的线程池
ThreadPoolTaskExecutor
核心线程数和最大线程数怎么设置的
CPU核心+1,最大一致
请求处理多长时间,有哪些指标
见上文
项目里面算法效率提升率怎么算的
看压测
锁升级过程
被禁止的默认偏向锁(15+ : 无锁)->CAS轻量级锁->有竞争(自旋次数过多/多个线程竞争)重量级锁
锁粗化/锁消除
你的描述 基本正确,但可以更精确一些。以下是详细分析和补充:
1. 锁粗化(Lock Coarsening)
- 核心目的:减少锁的获取和释放次数,从而降低锁切换的开销。
- 触发条件:
- 多个 连续且无竞争 的同步块(或循环中频繁加锁/解锁的操作)。
- JVM 检测到这些同步块对 同一对象 进行加锁。
- 示例代码:
JIT 优化后:for (int i = 0; i < 100; i++) { synchronized (lock) { // 操作... } }synchronized (lock) { for (int i = 0; i < 100; i++) { // 操作... } } - 关键点:
- 锁切换的开销:每次加锁/解锁都需要修改对象头的 Mark Word,涉及 CAS 操作。锁粗化通过合并操作减少这些开销。
- 适用场景:循环体内的频繁加锁、多个相邻的同步块。
2. 锁消除(Lock Elimination)
- 核心目的:完全移除不必要的锁操作,消除冗余同步。
- 触发条件:
- 通过 逃逸分析(Escape Analysis) 判断某个对象 不会被其他线程访问(即未逃逸出当前线程或方法)。
- 即使代码中显式使用了
synchronized,JVM 也会在运行时自动移除这些锁。
- 示例代码:
JIT 优化后:public String concatenate(String s1, String s2) { StringBuffer sb = new StringBuffer(); sb.append(s1); // StringBuffer 是线程安全的 sb.append(s2); return sb.toString(); }sb对象仅在当前方法内使用,JVM 会 消除append方法的锁操作,因为不存在线程竞争。
- 关键点:
- 锁消除的前提:逃逸分析必须开启(JDK 8 默认开启)。
- 性能提升:完全避免了锁的获取和释放,甚至包括偏向锁、轻量级锁的升级过程。
3. JIT 的优化逻辑
- 锁粗化 vs. 锁消除:
- 锁粗化:保留锁,但减少锁切换次数(适用于锁竞争较少的场景)。
- 锁消除:直接移除锁(适用于锁完全无意义的场景)。
- JIT 的作用:
- 热点代码识别:通过解释执行收集统计信息(如调用频率、循环次数),确定需要优化的代码段。
- 即时编译:将热点代码编译为本地机器码,并应用锁粗化/锁消除等优化策略。
4. 你的描述的正确性总结
| 描述 | 正确性 | 补充说明 |
|---|---|---|
| “减少锁切换所以有粗化/删除” | ✅ | 正确,但需区分 锁粗化(减少切换次数)和 锁消除(完全移除锁)。 |
| “JIT 在优化时减少锁切换” | ✅ | 锁粗化通过合并锁范围减少切换;锁消除通过移除锁彻底消除切换。 |
| “锁粗化/锁消除” | ✅ | 术语正确,但需明确两者的触发条件和优化目标。 |
5. 锁优化的实际影响
- 性能提升:
- 锁粗化:减少锁切换的开销(如 CAS 操作、对象头更新)。
- 锁消除:完全避免锁相关的开销(如偏向锁撤销、轻量级锁自旋)。
- 适用场景:
- 锁粗化:适用于频繁加锁/解锁但无竞争的场景(如循环、连续同步块)。
- 锁消除:适用于局部对象无逃逸的场景(如
StringBuffer在方法内部使用)。
6. 示例对比
锁粗化前 vs. 后
// 原始代码(未优化)
for (int i = 0; i < 100; i++) {
synchronized (lock) {
// 操作...
}
}
// JIT 优化后
synchronized (lock) {
for (int i = 0; i < 100; i++) {
// 操作...
}
}
锁消除前 vs. 后
// 原始代码(未优化)
public String concatenate(String s1, String s2) {
StringBuffer sb = new StringBuffer();
synchronized (sb) { sb.append(s1); } // 显式同步
synchronized (sb) { sb.append(s2); }
return sb.toString();
}
// JIT 优化后
public String concatenate(String s1, String s2) {
StringBuffer sb = new StringBuffer();
sb.append(s1); // 锁消除
sb.append(s2); // 锁消除
return sb.toString();
}
7. 如何验证锁优化?
- JIT 编译参数:
-XX:+PrintCompilation:查看哪些方法被 JIT 编译。-XX:+PrintInlining:查看方法内联和锁消除的详细信息。-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly:输出汇编代码(需安装hsdis库)。
结论:
- 锁粗化 是 减少锁切换次数,而 锁消除 是 完全移除锁。
- 两者均依赖 JIT 的热点探测和逃逸分析,且需结合代码结构和运行时行为。
CMS过程
初始标记,并发标记,并发收集,重新收集
CAS过程和ABA问题怎么解决
自旋,预期,内存值。版本号
volatile作用,为什么会存在指令重排
可见性,禁重排。JVM优化
代理实现方式,动态代理静态代理的区别
JDK/CGLIB
订单号用雪花算法。发生时间回拨怎么办?
外部时间同步
短时间订单高峰,递增序列号不够怎么办?
- 问题:数据库自增ID(如MySQL的
AUTO_INCREMENT)在高并发下可能达到上限或性能瓶颈。 - 解决方案:
- 分布式ID生成器:使用如Snowflake算法生成全局唯一ID(64位,包含时间戳、节点ID、序列号等),避免单点瓶颈。
- 分库分表:将订单表按业务逻辑分片(如按用户ID哈希分表),每个分片独立生成自增ID。
- 调整自增步长:在MySQL中设置
auto_increment_increment和auto_increment_offset,多实例分配不同步长(如实例1从1开始步长2,实例2从2开始步长2),避免冲突。 - 预分配ID池:由中心服务预先分配ID段给各业务节点,减少数据库压力。
事件驱动思想怎么应用?
- 核心:通过事件(Event)解耦系统模块,按需响应变化。
- 应用示例:
- 订单系统:下单后触发
OrderCreatedEvent,库存系统监听事件扣减库存,物流系统监听事件安排配送。 - 异步处理:将耗时操作(如短信发送)通过事件队列(如Kafka)异步执行,提升响应速度。
- 状态机:订单状态变更时发布事件(如
OrderPaidEvent),其他模块监听并更新相关业务逻辑。
- 订单系统:下单后触发
DDD(领域驱动设计)了解过吗?
- 核心概念:
- 战略设计:划分领域(Domain)和子域(Subdomain),定义限界上下文(Bounded Context),解决复杂业务问题的“分而治之”。
- 战术设计:通过实体(Entity)、值对象(Value Object)、聚合根(Aggregate Root)、仓储(Repository)等实现代码结构化。
- 优势:明确业务边界,提升代码可维护性,适应复杂业务需求。
JDK9模块系统有哪些影响?
- 模块化(JPMS):
- 封装性:通过
module-info.java声明模块依赖和导出包,限制外部访问未公开的类。 - 依赖管理:显式声明模块间依赖,减少类路径冲突。
- 性能优化:JVM启动时仅加载所需模块,减少内存占用。
- 封装性:通过
- 挑战:遗留代码迁移复杂,需兼容非模块化JAR。
线上大表分成100张表,如何平滑迁移?
- 步骤:
- 预建新表:创建
user00到user99共100张新表,结构与原表一致。 - 修改查询逻辑:所有查询先查新表,未命中再查旧表(如按用户ID哈希分表)。
- 数据迁移:分批次将旧表数据迁移到新表,确保迁移期间服务可用。
- 切换流量:验证无误后,删除旧表。
- 预建新表:创建
- 关键:迁移脚本需处理数据一致性,避免重复或遗漏。
虚拟线程原理?如何评估是否使用?
- 原理:
- 轻量级:虚拟线程堆栈按需分配(几百字节),由JVM调度而非操作系统。
- M:N调度:一个平台线程(内核线程)可管理数万个虚拟线程,阻塞时不消耗资源。
- 适用场景:
- I/O密集型:如Web请求、数据库查询(虚拟线程阻塞时,平台线程可处理其他任务)。
- 避免线程池:无需维护线程池,直接创建虚拟线程。
- 评估:
- 替代异步编程:用同步代码风格实现异步效果。
- 避免CPU密集型任务:虚拟线程不适合计算密集型任务(平台线程更适合)。
Volatile原理?如何保证可见性?
- 可见性:通过内存屏障(Memory Barrier)确保写操作对其他线程立即可见。
- 写操作:插入
StoreStore和StoreLoad屏障,强制刷新缓存到主内存。 - 读操作:插入
LoadLoad和LoadStore屏障,强制从主内存读取。
- 写操作:插入
- 重排序:禁止编译器和CPU对
volatile变量的读写进行重排序,确保有序性。 - 不保证原子性:
i++等复合操作仍需加锁或使用AtomicInteger。
延迟队列时序问题
- 问题:传统TTL+DLX方案存在时序混乱(如后发消息优先级低)。
- 解决方案:
- RabbitMQ延迟插件:基于时间轮算法(Timing Wheel),精确控制消息到期时间。
- Redisson延迟队列:使用Redis的ZSET存储延迟消息,到期后转移至目标队列。
RabbitMQ延迟插件原理
- 核心:通过
x-delayed-message交换器,内部使用时间轮算法管理消息到期时间。 - 流程:
- 生产者发送消息时指定延迟时间。
- 插件将消息存入内部队列,按到期时间排序。
- 到期后转发到目标队列供消费者消费。
- 优势:支持高精度延迟(毫秒级),解决TTL+DLX的时序问题。
延迟插件实现延迟关单
- 步骤:
- 订单支付后,发送延迟消息(如30分钟后关闭订单)到RabbitMQ。
- 消费者监听延迟队列,到期后执行关单逻辑。
- 关键:确保消息持久化和消费者幂等性(防重复消费)。
JWT的优点和缺点
- 优点:
- 无状态:服务端无需存储会话,适合分布式系统。
- 跨域支持:Token可通过Header传递,天然支持跨域。
- 缺点:
- 不可控:Token在有效期内无法主动失效(需配合黑名单)。
- CSRF风险:需结合SameSite、CSRF Token等防护。
- 体积大:JWT头和签名增加传输开销。
域名解析类型有哪些?
- 常见类型:
- A记录:域名解析到IPv4地址(如
example.com -> 192.168.1.1)。 - CNAME记录:别名解析(如
www.example.com -> example.com)。 - MX记录:邮件服务器地址(用于邮箱服务)。
- TXT记录:存储文本信息(如SPF、DKIM验证)。
- NS记录:指定域名的DNS服务器。
- A记录:域名解析到IPv4地址(如
- DNS解析流程:本地缓存 -> 递归DNS -> 根DNS -> 顶级域DNS -> 权威DNS -> 返回IP。
域名怎么配置?
- 正确方法:
- A记录:将域名指向负载均衡器的IP地址(如Nginx、SLB)。
- CNAME记录:若使用CDN或云服务,配置CNAME到服务提供商的域名。
- TTL设置:设置较短TTL(如300秒)以便快速生效。
- 负载均衡:通过DNS解析到多个IP,负载均衡器分配流量到后端服务器。
NAT模式 vs 桥接模式
- NAT模式:
- 虚拟机共享宿主机IP,通过NAT访问外网。
- 宿主机可访问虚拟机,但虚拟机对外不可见。
- 桥接模式:
- 虚拟机拥有独立IP,与宿主机平级,直接接入物理网络。
- 外部网络可直接访问虚拟机。
- 选择:需要外网访问选桥接,仅需内网通信选NAT。
RBAC和ABAC鉴权模式
- RBAC(基于角色):
- 特点:用户绑定角色,角色绑定权限(如
admin角色有delete权限)。 - 适用:权限结构固定的企业系统(如ERP)。
- 特点:用户绑定角色,角色绑定权限(如
- ABAC(基于属性):
- 特点:根据用户属性(如部门、时间)、资源属性(如敏感等级)动态判断权限。
- 适用:复杂策略场景(如政府系统、医疗数据)。
代码提交到公网的流程
- 典型流程:
- 代码提交:推送代码到Git仓库(如GitHub、GitLab)。
- CI/CD触发:自动触发构建(如Jenkins、GitHub Actions)。
- 测试:运行单元测试、集成测试。
- 部署:
- 容器化:使用Docker打包应用。
- Kubernetes:部署到K8s集群,自动扩缩容。
- 配置管理:通过ConfigMap或环境变量注入配置。
- 监控:集成Prometheus、Grafana监控服务状态。
- 灰度发布:逐步将流量切换到新版本,确保稳定性。
代码手撕
写一个result通用返回类
@Data
public class Result<T>{
//code
private Integer code;
//msg
private String message;
//data
private T data;
public Result(){}
private static <T> Result<T> build(T body,Integer code,String message){
Result<T> result = new Result<>();
if(data!=null){
result.setData(data)
}
result.setCode(code);
result.setMessage(message);
}
public static<T> Result<T> ok(T data){
Result.build
}
}
6658

被折叠的 条评论
为什么被折叠?



