【futu测试案例】性能测试中常见的问题汇总

1、有下面两张表,user(用户表)和thread(帖子表),假设有100W用户,500W帖子,写一条SQL,显示前十名发帖最多的用户的名字及帖子数量,并针对该语句指出如何设计合理的索引字段。
如何确认你写的sql会用到哪个索引,另外请说明下你写的SQL是否是最优解
表名 字段
user uid, username, password, create_time
thread tid, uid, title, content, create_time

解答:

SELECT u.username, COUNT(t.user_id) AS post_count FROM user uJOIN thread t ON u.id = t.user_idGROUP BY u.idORDER BY post_count DESCLIMIT 10;

2、innodb一次主键查询、普通索引查询、无索引查询的区别是什么?
innodb关系型存储引擎

javascript 复制代码
总体概况
-- 创建普通索引示例
CREATE TABLE user (
    id INT PRIMARY KEY,           -- 聚簇索引
    username VARCHAR(50),
    email VARCHAR(100),
    age INT,
    INDEX idx_username (username),  -- 普通索引
    INDEX idx_age_email (age, email) -- 复合普通索引
);

基础介绍

  • 缓冲池:遵循"检查点"和"写回"机制,而不是每次修改都写盘,常使用LRU管理页的淘汰
  • 写缓冲 :优化""非唯一"二级索引更新操作而设计,当需要更新一个二级索引页,而该页又不在缓冲池时,这个改动不会立即从磁盘加载索引页,而是先记录到写缓冲中 。待未来该页被读取时,再合并改动。这减少了大量的随机磁盘I/O
    自适应哈希索引:发现某些索引值被非常频繁地用等值查询(=)访问,它会在内存中基于缓冲池的B+树页,为其建立一个哈希索引。下次查询可直接通过哈希O(1)定位,无需从B+树根开始查找。
javascript 复制代码
eg:domo案例分析
-- 1.测试中发现锁竞争
SHOW ENGINE INNODB STATUS\G     检查引擎状态
-----当SEMAPHORES部分显示大量等待时
2.SELECT IF(@ENABLE_Detailed_semaphore),
'信息量详细信息:',
 '跳过详细信号量检查') AS check_point;
3.监控当前锁情况
SELECT IF(@enable_lock_wait_info,
    CONCAT('当前时间: ', NOW(), ' - 锁等待监控'),
    '锁等待监控已禁用') AS lock_monitor;
-- ----创建死锁监控表
   CREATE TABLE deadlock_monitor (
        id BIGINT AUTO_INCREMENT PRIMARY KEY,
        deadlock_time DATETIME DEFAULT CURRENT_TIMESTAMP,
        victim_trx_id BIGINT,
        details TEXT,
        resolved_by ENUM('timeout', 'detection') DEFAULT 'detection'
      );
4. 定期检查死锁统计
SELECT 
    DATE(deadlock_time) as day,
    HOUR(deadlock_time) as hour,
    COUNT(*) as deadlock_count,
    GROUP_CONCAT(DISTINCT resolved_by) as resolution_types
FROM deadlock_monitor
GROUP BY DATE(deadlock_time), HOUR(deadlock_time)
ORDER BY day DESC, hour DESC;

3、请用尽可能少的代码实现一个函数,用于计算用户一个月共计交费多少港元。(代码请写的尽量清晰简洁,我们希望能够看到你的编码风格和习惯)
用户在富途的平台上进行交易,需要交平台使用费。平台使用费的梯度收费方案如下:
每月累计订单数 每笔订单(港元)
梯度1:1-5笔 => 30.00
梯度2:6-20笔 => 15.00
梯度3:21-50笔 => 10.00
梯度4:51笔及以上 => 1.00
假设一个用户,一个月交易了6笔订单,则在梯度1交费共计: 30港元*5=150港元,在梯度二交费:15港元,一共交费165港元。

javascript 复制代码
```python
在这里插入代码片def calculate_fee(order_count: int) -> float:
    """
    计算用户月度平台使用费
    
    Args:
        order_count: 月度订单总数
        
    Returns:
        总费用(港元)
    """
    # 梯度费率表:每笔订单费用(港元)
    fee_rates = [
        (5, 30.00),   # 梯度1: 1-5笔
        (15, 15.00),  # 梯度2: 6-20笔(累计到20笔)
        (30, 10.00),  # 梯度3: 21-50笔(累计到50笔)
        (float('inf'), 1.00)  # 梯度4: 51笔及以上
    ]
    
    total_fee = 0.0
    remaining_orders = order_count
    
    for threshold, rate in fee_rates:
        if remaining_orders <= 0:
            break
            
        # 当前梯度的订单数量
        orders_in_tier = min(remaining_orders, threshold)
        
        # 如果是第一个梯度,直接用全部数量
        if threshold == 5:  # 梯度1
            orders_in_tier = min(remaining_orders, 5)
        else:
            # 其他梯度需要减去前一个梯度的阈值
            orders_in_tier = min(remaining_orders, threshold) - sum(
                t for t, _ in fee_rates[:fee_rates.index((threshold, rate))]
            )
        
        # 确保订单数为非负数
        orders_in_tier = max(0, orders_in_tier)
        total_fee += orders_in_tier * rate
        
        # 更新剩余订单数
        remaining_orders -= orders_in_tier
    
    return round(total_fee, 2)


# 测试用例
def test_calculate_fee():
    """测试函数"""
    test_cases = [
        (0, 0.0),      # 无订单
        (3, 90.0),     # 只梯度1
        (5, 150.0),    # 梯度1满额
        (6, 165.0),    # 梯度1+梯度2
        (20, 150 + 15*15),  # 梯度1+梯度2满额
        (21, 150 + 15*15 + 10*1),  # 进入梯度3
        (50, 150 + 15*15 + 10*30),  # 梯度3满额
        (51, 150 + 15*15 + 10*30 + 1*1),  # 进入梯度4
        (100, 150 + 15*15 + 10*30 + 1*50),  # 大量订单
    ]
    
    for orders, expected in test_cases:
        result = calculate_fee(orders)
        status = "✓" if abs(result - expected) < 0.01 else "✗"
        print(f"{status} 订单数:{orders:3d} 预期:{expected:7.2f} 实际:{result:7.2f}")


if __name__ == "__main__":
    test_calculate_fee()```

4、假设给定两个int类型的有序数组A和有序数组B,并且每个数组中都可能存在重复的数字,现在要求给出一个算法判断A是否为B的子集(给出思路即可,不用写代码)
例如:
若A为【1, 1, 2, 3】,B为【1, 1, 1, 2, 2, 3】,则A为B的子集
若A为【1, 2, 2, 3】,B为【1, 1,2, 3, 3】,则A不为B的子集

选择双指针方案
初始化两个指针:
i = 0 指向数组A
j = 0 指向数组B

遍历A中每个元素:

  1. 对于A[i],统计它在A中的连续出现次数 countA 在B中从当前位置j开始,
  2. 统计相同元素的出现次数 countB 比较:
  3. 如果countA > countB,则A不是B的子集
    如果 countA ≤ countB,继续处理A中的下一个元素

5、假设现在需要让你实现一个限频的需求,限制任意一个登录用户任意5分钟内不能发帖超过10次,

请给出详细的技术方案。

6.在进行商城购物车架构并发测试过程中常见的性能问题,进行性能测试的基础配置(衍生相关的解决方案及架构)

一、测试环境配置:
二、解决方案:全量数据库读写 &缓冲池缓冲 &分布式架构

test:

environment:
# 硬件配置

server:

cpu: 8核心

memory: 32GB

disk: SSD 500GB
# 中间件配置

middleware:

redis:

mode: cluster # 集群模式

nodes: 3主3从 # 6节点

memory: 8GB/node # 每节点内存

maxmemory-policy: volatile-lru

mysql:

version: 8.0

connection: 200 # 最大连接数
buffer-pool: 16GB # InnoDB缓冲池

kafka:

partitions: 12 # 分区数

replication: 2 # 副本数

# 压测工具配置

jmeter:

threads: 1000 # 并发线程数

ramp-up: 60 # 启动时间(秒)

duration: 300 # 压测时长(秒)

loop: forever # 循环次数

# 监控配置

monitoring:

prometheus:

scrape-interval: 5s # 采集间隔

grafana:

dashboards:

  • redis -performance

  • mysql-performance

  • application-metrics

拓展解决并发问题方案:
分布式架构

python 复制代码
购物车服务实例(每个Pod):
├── Web容器层
│   ├── RESTful API端点
│   ├── GRPC接口
│   └── WebSocket连接
├── 业务逻辑层
│   ├── 购物车管理器
│   ├── 库存检查器
│   ├── 价格计算器
│   └── 促销应用器
├── 数据访问层
│   ├── 缓存客户端
│   ├── 数据库客户端
│   └── 消息生产者
└── 协调层
    ├── 配置客户端
    ├── 服务发现客户端
    └── 分布式锁客户端

数据存储架构

python 复制代码
第一层:本地缓存(L1)
├── 存储:热点用户购物车数据
├── 技术:Caffeine/Guava Cache
├── 容量:每实例10,000用户
├── 过期:5分钟
└── 特点:极速读取,减少网络开销

第二层:分布式缓存(L2)
├── 存储:全量购物车数据
├── 技术:Redis Cluster
├── 分片:按用户ID hash分片
├── 结构:Hash存储购物车项
├── 容量:支持千万级用户
└── 特点:高可用,支持故障转移

第三层:持久化存储(L3)
├── 存储:购物车操作日志
├── 技术:MySQL分库分表
├── 分片:按用户ID range分片
├── 备份:实时同步到备库
└── 特点:数据持久化,支持审计

库存扣减架构

python 复制代码
库存管理策略:
1. 预扣库存
   - 加入购物车时预扣
   - 设置预扣超时时间(15分钟)
   - 超时自动释放
2. 真实库存与可售库存分离
   - 真实库存:物理库存
   - 可售库存 = 真实库存 - 预扣库存
   - 展示给用户可售库存
3. 库存分层次管理
   - 总仓库存
   - 区域仓库存
   - 门店库存
   - 虚拟库存(预售)

7.在进行第三方接口联通过程中,会遇到的联调问题,如何解决用户 → 商城下单 → 调用第三方支付 → 等待回调 → 状态不一致(超时/接口异常、数据不一致、重复处理等)情况

常见表现介绍:
调用超时:支付接口调用耗时过长,系统无法判断调用结果
回调丢失:第三方支付回调未到达或处理失败
数据不一致:商城状态与第三方支付状态存在差异
重复处理:因重试机制导致的重复支付或重复退款

通常 情况下使用的设置多个集群及对应设置多个节点

清晰总架构图方案(在进行第三方支付时,会进入支付回调服务):

解决方案及对应架构图展示:
业务核心逻辑层 :包含内容如下:
业务接入层 :接收用户支付请求,基础验证与参数处理

支付服务层:支付状态管理器:维护支付状态机,确保状态流转合法

幂等性检查器:防止重复支付的关键组件

分布式事务协调器:处理跨服务的原子性操作

渠道适配器:统一对接不同的第三方支付平台
数据存储层(多级存储策略)

热点数据:Redis缓存,毫秒级响应

业务数据:MySQL分库分表,支持高并发写入

历史数据:归档存储,降低成本

审计日志:独立存储,满足合规要求
监控告警层 **(建立思维监控体系)**:

业务监控:支付成功率、转化率等

性能监控:接口响应时间、系统吞吐量

可用性监控:服务健康状态、依赖组件状态

一致性监控:数据一致性检查、异常告警

实际实施方案:

1.支付创建流程

请求接收---->幂等性检查----->参数验证---->状态流转--->调用第三方------>结果处理
2.支付回调处理

签证验证--->幂等性验证--->状态一致性检查--->业务处理--->异步确认
3.超时订单处理

对于长时间未收到回调的订单

定时扫描----->主动查询--->状态同步--->异步处理

预防措施:

1.分布式状态机

子状态细化:("支付中"为"调用接口中"、"等待回调中"、"主动查询中"),同一支付单状态变更获取分布式锁,防止并发更新

2.智能重试机制

设置重试时间机条件,在网络异常、超时异常需要重试**,智能重试平衡了成功率和响应时间,避免无效重试**

3.数据对账

数据准备(本地 vs 第三方)账单----->数据匹配(流水号、金额、时间多维度匹配)---->差异分析---->处理差异----》对账报告

8.商品秒杀倒计时的数据存储方式,是否有做缓存,从商品架构到支付整个链路的数据流介绍,整个商城的架构情况

基本介绍缓存处理策略:
Redis集群配置

  1. 多级缓存:本地缓存(Caffeine) + 分布式缓存(Redis)
  2. 缓存穿透:布隆过滤器 + 空值缓存
  3. 缓存雪崩:随机过期时间 + 热点数据永不过期
  4. 缓存一致性:双写模式 + 失效模式 + 异步更新
    适用场景介绍:
    缓存击穿/雪崩:执行(大量缓存key)key失效,采取并发请求(大量请求集体)穿透数据库
    并发缓存:分布式缓存、本地锁+标记位
    Redis数据结构选择
  • String: 简单缓存、计数器
  • Hash: 对象存储、购物车
  • List: 消息队列、最新列表
  • Set: 标签、共同好友
  • SortedSet: 排行榜、延迟队列

整个链路的数据流详情如下:


相关推荐
zt1985q2 小时前
本地部署静态网站生成工具 Vuepress 并实现外部访问
运维·服务器·网络·数据库·网络协议
瀚高PG实验室2 小时前
数据库日志过大
数据库·瀚高数据库
2401_857683542 小时前
使用Kivy开发跨平台的移动应用
jvm·数据库·python
yangSnowy2 小时前
MySQL 分布式锁实现方案
数据库·分布式·mysql
倔强的石头1062 小时前
关系数据库替换用金仓:从 Oracle 到 KingbaseES 的迁移实战
数据库·oracle·kingbase
Leo.yuan2 小时前
制造业五大模式解析:OEM、ODM、OBM、JDM、CMT
大数据·数据库·信息可视化
铬仁2 小时前
kettle 9.2 连接达梦DM Database Server 64 V8
数据库·etl
松涛和鸣2 小时前
69、Linux字符设备驱动实战
linux·服务器·网络·arm开发·数据库·驱动开发
2501_941982052 小时前
企微自动化开发:安全与效率的平衡术
数据库·mysql·企业微信