今日学习:怎么算高并发

高并发?

一、形容并发的参数有哪些?

在系统性能和高并发场景中,以下参数是核心指标,用于描述系统的并发处理能力:


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 = ?,其中 aINT 类型(范围 1-5),bVARCHAR 类型(长度 1-10 随机)。
  • 目标:优化该查询的性能。
索引设计建议:
  1. 联合索引(Composite Index)

    • 建立 (a, b) 的联合索引。
    • 原因
      • 联合索引可以覆盖 WHERE a = ? AND b = ? 的条件。
      • 如果 b 的选择性(唯一值比例)高于 a,可以调整字段顺序为 (b, a)(但需结合实际数据分布验证)。
    • SQL 语句
      CREATE INDEX idx_a_b ON your_table(a, b);
      
  2. 覆盖索引(Covering Index)

    • 如果查询的字段都在索引中(如 SELECT a, b FROM ...),可以避免回表操作,进一步提升性能。
    • 示例
      CREATE INDEX idx_a_b_cover ON your_table(a, b);
      
  3. 是否需要单独索引?

    • 不建议:单独为 ab 建立索引会导致查询时只能使用其中一个字段,无法利用联合索引的最左前缀匹配特性。
    • 例外:如果 a 的取值范围极小(如 1-5),而 b 的选择性极高(如唯一值多),可以尝试建立 (b, a) 联合索引。

什么样的字段适合建立索引?
适合建立索引的字段:
  1. 频繁出现在 WHEREJOINORDER BYGROUP BY 子句中的字段
  2. 高选择性的字段(唯一值比例高,如用户ID、订单号)。
  3. 外键字段(用于关联其他表)。
  4. 需要排序或分组的字段
  5. 唯一性约束的字段(如邮箱、身份证号)。
  6. 覆盖索引的字段组合(减少回表操作)。
不适合建立索引的字段:
  1. 大字段(如 TEXTBLOB)。
  2. 频繁更新的字段(索引维护成本高)。
  3. 高度重复的字段(如性别、状态)。
  4. 非查询条件的字段(如审计字段 create_time)。
  5. 函数或计算字段(如 WHERE YEAR(date) = 2024)。

数据库分过表吗?
回答:
  • 未达到分表条件:当前表未达到 500 万行或 10GB 数据量,无需分表。
  • 了解过水平分表/垂直分表
    • 水平分表:按行拆分(如按用户ID哈希分表)。
    • 垂直分表:按列拆分(如将大字段拆分到独立表)。
    • ShardingSphere:支持分库分表和读写分离的中间件。

水平分表怎么分?
常见分表策略:
  1. 按哈希分片(Hash Sharding)

    • 根据某个字段(如用户ID)的哈希值分配到不同表。
    • 示例
      -- 分表规则:user_id % 4
      CREATE TABLE user_0 (...);
      CREATE TABLE user_1 (...);
      CREATE TABLE user_2 (...);
      CREATE TABLE user_3 (...);
      
  2. 按范围分片(Range Sharding)

    • 根据字段值的范围分配(如按时间、ID区间)。
    • 示例
      -- 分表规则:order_id 1-1000 -> order_0, 1001-2000 -> order_1...
      
  3. 按业务逻辑分表

    • 根据业务场景拆分(如按地区、渠道)。
    • 示例
      -- 按销售渠道拆分:sales_channel_1, sales_channel_2...
      

滚动分表/更新
滚动分表(Rolling Sharding):
  • 按时间分表(如按天、月)。
  • 示例
    CREATE TABLE orders_202406 (...);
    CREATE TABLE orders_202407 (...);
    
  • 优点:便于归档旧数据,提升查询性能。
数据更新同步:
  • 方案
    1. 应用层维护:在插入/更新时根据分表规则路由到对应分表。
    2. 中间件支持:使用 ShardingSphere 自动路由。
    3. 触发器同步:通过触发器将主表的修改同步到分表(需谨慎,可能影响性能)。

拆分过程中的数据修改如何同步到分表?
场景:
  • 主表存在,分表后需要将历史数据迁移并同步后续修改。
解决方案:
  1. 离线迁移

    • 使用脚本将主表数据按分表规则迁移。
    • 示例
      INSERT INTO user_0 SELECT * FROM main_user WHERE user_id % 4 = 0;
      
  2. 实时同步

    • 方案一:日志解析
      • 解析 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;
        
  3. 中间件支持

    • 使用 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 检测到这些同步块对 同一对象 进行加锁。
  • 示例代码
    for (int i = 0; i < 100; i++) {
        synchronized (lock) {
            // 操作...
        }
    }
    
    JIT 优化后
    synchronized (lock) {
        for (int i = 0; i < 100; i++) {
            // 操作...
        }
    }
    
  • 关键点
    • 锁切换的开销:每次加锁/解锁都需要修改对象头的 Mark Word,涉及 CAS 操作。锁粗化通过合并操作减少这些开销。
    • 适用场景:循环体内的频繁加锁、多个相邻的同步块。

2. 锁消除(Lock Elimination)

  • 核心目的完全移除不必要的锁操作,消除冗余同步。
  • 触发条件
    • 通过 逃逸分析(Escape Analysis) 判断某个对象 不会被其他线程访问(即未逃逸出当前线程或方法)。
    • 即使代码中显式使用了 synchronized,JVM 也会在运行时自动移除这些锁。
  • 示例代码
    public String concatenate(String s1, String s2) {
        StringBuffer sb = new StringBuffer();
        sb.append(s1);  // StringBuffer 是线程安全的
        sb.append(s2);
        return sb.toString();
    }
    
    JIT 优化后
    • 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 库)。

结论

  1. 锁粗化减少锁切换次数,而 锁消除完全移除锁
  2. 两者均依赖 JIT 的热点探测和逃逸分析,且需结合代码结构和运行时行为。
CMS过程
初始标记,并发标记,并发收集,重新收集
CAS过程和ABA问题怎么解决
自旋,预期,内存值。版本号
volatile作用,为什么会存在指令重排
可见性,禁重排。JVM优化
​代理实现方式,动态代理静态代理的区别
JDK/CGLIB
订单号用雪花算法。发生时间回拨怎么办?
外部时间同步
短时间订单高峰,递增序列号不够怎么办?
  • 问题:数据库自增ID(如MySQL的AUTO_INCREMENT)在高并发下可能达到上限或性能瓶颈。
  • 解决方案
    1. 分布式ID生成器:使用如Snowflake算法生成全局唯一ID(64位,包含时间戳、节点ID、序列号等),避免单点瓶颈。
    2. 分库分表:将订单表按业务逻辑分片(如按用户ID哈希分表),每个分片独立生成自增ID。
    3. 调整自增步长:在MySQL中设置auto_increment_incrementauto_increment_offset,多实例分配不同步长(如实例1从1开始步长2,实例2从2开始步长2),避免冲突。
    4. 预分配ID池:由中心服务预先分配ID段给各业务节点,减少数据库压力。

事件驱动思想怎么应用?
  • 核心:通过事件(Event)解耦系统模块,按需响应变化。
  • 应用示例
    1. 订单系统:下单后触发OrderCreatedEvent,库存系统监听事件扣减库存,物流系统监听事件安排配送。
    2. 异步处理:将耗时操作(如短信发送)通过事件队列(如Kafka)异步执行,提升响应速度。
    3. 状态机:订单状态变更时发布事件(如OrderPaidEvent),其他模块监听并更新相关业务逻辑。

DDD(领域驱动设计)了解过吗?
  • 核心概念
    1. 战略设计:划分领域(Domain)和子域(Subdomain),定义限界上下文(Bounded Context),解决复杂业务问题的“分而治之”。
    2. 战术设计:通过实体(Entity)、值对象(Value Object)、聚合根(Aggregate Root)、仓储(Repository)等实现代码结构化。
  • 优势:明确业务边界,提升代码可维护性,适应复杂业务需求。

JDK9模块系统有哪些影响?
  • 模块化(JPMS)
    1. 封装性:通过module-info.java声明模块依赖和导出包,限制外部访问未公开的类。
    2. 依赖管理:显式声明模块间依赖,减少类路径冲突。
    3. 性能优化:JVM启动时仅加载所需模块,减少内存占用。
  • 挑战:遗留代码迁移复杂,需兼容非模块化JAR。

线上大表分成100张表,如何平滑迁移?
  • 步骤
    1. 预建新表:创建user00user99共100张新表,结构与原表一致。
    2. 修改查询逻辑:所有查询先查新表,未命中再查旧表(如按用户ID哈希分表)。
    3. 数据迁移:分批次将旧表数据迁移到新表,确保迁移期间服务可用。
    4. 切换流量:验证无误后,删除旧表。
  • 关键:迁移脚本需处理数据一致性,避免重复或遗漏。

虚拟线程原理?如何评估是否使用?
  • 原理
    • 轻量级:虚拟线程堆栈按需分配(几百字节),由JVM调度而非操作系统。
    • M:N调度:一个平台线程(内核线程)可管理数万个虚拟线程,阻塞时不消耗资源。
  • 适用场景
    • I/O密集型:如Web请求、数据库查询(虚拟线程阻塞时,平台线程可处理其他任务)。
    • 避免线程池:无需维护线程池,直接创建虚拟线程。
  • 评估
    • 替代异步编程:用同步代码风格实现异步效果。
    • 避免CPU密集型任务:虚拟线程不适合计算密集型任务(平台线程更适合)。

Volatile原理?如何保证可见性?
  • 可见性:通过内存屏障(Memory Barrier)确保写操作对其他线程立即可见。
    • 写操作:插入StoreStoreStoreLoad屏障,强制刷新缓存到主内存。
    • 读操作:插入LoadLoadLoadStore屏障,强制从主内存读取。
  • 重排序:禁止编译器和CPU对volatile变量的读写进行重排序,确保有序性。
  • 不保证原子性i++等复合操作仍需加锁或使用AtomicInteger

延迟队列时序问题
  • 问题:传统TTL+DLX方案存在时序混乱(如后发消息优先级低)。
  • 解决方案
    1. RabbitMQ延迟插件:基于时间轮算法(Timing Wheel),精确控制消息到期时间。
    2. Redisson延迟队列:使用Redis的ZSET存储延迟消息,到期后转移至目标队列。

RabbitMQ延迟插件原理
  • 核心:通过x-delayed-message交换器,内部使用时间轮算法管理消息到期时间。
  • 流程
    1. 生产者发送消息时指定延迟时间。
    2. 插件将消息存入内部队列,按到期时间排序。
    3. 到期后转发到目标队列供消费者消费。
  • 优势:支持高精度延迟(毫秒级),解决TTL+DLX的时序问题。

延迟插件实现延迟关单
  • 步骤
    1. 订单支付后,发送延迟消息(如30分钟后关闭订单)到RabbitMQ。
    2. 消费者监听延迟队列,到期后执行关单逻辑。
  • 关键:确保消息持久化和消费者幂等性(防重复消费)。

JWT的优点和缺点
  • 优点
    1. 无状态:服务端无需存储会话,适合分布式系统。
    2. 跨域支持:Token可通过Header传递,天然支持跨域。
  • 缺点
    1. 不可控:Token在有效期内无法主动失效(需配合黑名单)。
    2. CSRF风险:需结合SameSite、CSRF Token等防护。
    3. 体积大:JWT头和签名增加传输开销。

域名解析类型有哪些?
  • 常见类型
    1. A记录:域名解析到IPv4地址(如example.com -> 192.168.1.1)。
    2. CNAME记录:别名解析(如www.example.com -> example.com)。
    3. MX记录:邮件服务器地址(用于邮箱服务)。
    4. TXT记录:存储文本信息(如SPF、DKIM验证)。
    5. NS记录:指定域名的DNS服务器。
  • DNS解析流程:本地缓存 -> 递归DNS -> 根DNS -> 顶级域DNS -> 权威DNS -> 返回IP。

域名怎么配置?
  • 正确方法
    1. A记录:将域名指向负载均衡器的IP地址(如Nginx、SLB)。
    2. CNAME记录:若使用CDN或云服务,配置CNAME到服务提供商的域名。
    3. TTL设置:设置较短TTL(如300秒)以便快速生效。
  • 负载均衡:通过DNS解析到多个IP,负载均衡器分配流量到后端服务器。

NAT模式 vs 桥接模式
  • NAT模式
    • 虚拟机共享宿主机IP,通过NAT访问外网。
    • 宿主机可访问虚拟机,但虚拟机对外不可见。
  • 桥接模式
    • 虚拟机拥有独立IP,与宿主机平级,直接接入物理网络。
    • 外部网络可直接访问虚拟机。
  • 选择:需要外网访问选桥接,仅需内网通信选NAT。

RBAC和ABAC鉴权模式
  • RBAC(基于角色)
    • 特点:用户绑定角色,角色绑定权限(如admin角色有delete权限)。
    • 适用:权限结构固定的企业系统(如ERP)。
  • ABAC(基于属性)
    • 特点:根据用户属性(如部门、时间)、资源属性(如敏感等级)动态判断权限。
    • 适用:复杂策略场景(如政府系统、医疗数据)。

代码提交到公网的流程
  • 典型流程
    1. 代码提交:推送代码到Git仓库(如GitHub、GitLab)。
    2. CI/CD触发:自动触发构建(如Jenkins、GitHub Actions)。
    3. 测试:运行单元测试、集成测试。
    4. 部署
      • 容器化:使用Docker打包应用。
      • Kubernetes:部署到K8s集群,自动扩缩容。
      • 配置管理:通过ConfigMap或环境变量注入配置。
    5. 监控:集成Prometheus、Grafana监控服务状态。
    6. 灰度发布:逐步将流量切换到新版本,确保稳定性。

代码手撕

写一个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
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~Yogi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值