当前位置: 首页 > news >正文

11.4八股

1、限流怎么做?

限流是防止系统过载的关键手段,核心是控制单位时间内的请求量,常见实现方式:

1.固定窗口计数器

原理:将时间划分为固定窗口(如 1 秒),记录窗口内请求数,超过阈值则限流。

优点:简单易实现;缺点:窗口边界可能出现流量突增(如前窗口末尾和当前窗口开头各发阈值请求,瞬间超 2 倍阈值)。

2.滑动窗口计数器

原理:将固定窗口拆分为多个小格子(如 1 秒拆分为 10 个 100ms 格子),滑动统计最近 1 秒内的请求总和,超过阈值则限流。

优化:缓解固定窗口的边界问题,精度取决于格子数量。

3.漏桶算法

原理:请求先进入 “漏桶”,桶以固定速率(如 100QPS)处理请求,超出桶容量则丢弃。

适用:控制输出速率(如 API 网关限制下游服务流量),平滑突发流量。

4.令牌桶算法

原理:系统按固定速率(如 100 个 / 秒)往桶中放令牌,请求需获取令牌才能处理,桶满则令牌溢出。

优势:支持突发流量(桶中积累的令牌可应对短时间峰值),是最常用的限流算法(如 Guava 的 RateLimiter)。

5.分布式限流

场景:多实例部署时,需全局统一限流(如全链路 QPS 限制)。

实现:基于 Redis(如用 INCR+EXPIRE 统计窗口请求,超过阈值则拒绝)或分布式锁。

2、身份证110101200111038313,电话00012062508

3、第三方登录(OAuth2.0协议)

基于 QQ 第三方登录的实际场景示例

以 “某款手游(假设叫「星际冒险」)支持 QQ 登录” 为例,完整还原 OAuth2.0 协议的落地流程:

一、前置准备:游戏平台完成腾讯开放平台注册

  1. 「星际冒险」的开发团队在腾讯开放平台(https://open.tencent.com/)注册开发者账号,提交游戏资质审核。

  1. 审核通过后,获取平台分配的 Client ID=123456(游戏的唯一标识)和 Client Secret=abcdef123456xyz(接口调用密钥,需保密)。

  1. 配置授权回调地址为 https://game.example.com/qq/login/callback(用户授权后,腾讯会跳转至此地址传递授权码),并申请授权范围为 “获取用户昵称、头像、OpenID”。

二、用户实操流程:从点击登录到进入游戏

1. 发起登录请求

用户打开「星际冒险」手游,点击登录界面的 “QQ 登录” 按钮。此时手游客户端会自动跳转到腾讯的 OAuth2.0 授权页面,跳转链接携带关键参数:https://graph.qq.com/oauth2.0/authorize?client_id=123456&redirect_uri=https://game.example.com/qq/login/callback&response_type=code&scope=get_user_info

  • client_id=123456:标识请求来自「星际冒险」游戏;

  • redirect_uri:指定授权后的回调地址;

  • response_type=code:表示需要腾讯返回 Authorization Code;

  • scope=get_user_info:表示需要获取用户的基础信息。

2. 用户同意授权

腾讯授权页面加载后,用户输入自己的 QQ 账号密码登录,随后页面提示 “「星际冒险」请求获取你的昵称、头像”,用户点击 “同意授权”。此时腾讯服务器生成一次性的 Authorization Code=789xyz,并自动重定向到之前配置的回调地址,同时携带该 Code:https://game.example.com/qq/login/callback?code=789xyz

3. 游戏服务器获取 Access Token

「星际冒险」的后端服务器接收到回调请求,提取出 Code=789xyz 后,向腾讯服务器发送请求,兑换 Access Token:请求地址:https://graph.qq.com/oauth2.0/token请求参数:

  • client_id=123456(游戏标识);

  • client_secret=abcdef123456xyz(游戏密钥,验证身份);

  • code=789xyz(授权码);

  • grant_type=authorization_code(表示用授权码兑换令牌);

  • redirect_uri=https://game.example.com/qq/login/callback(需与之前配置一致)。

腾讯服务器验证参数无误后,返回 Access Token:access_token=abc123xyz&expires_in=7200&refresh_token=def456uvw

  • access_token=abc123xyz:访问令牌,后续调用 API 需携带;

  • expires_in=7200:令牌有效期 2 小时;

  • refresh_token:刷新令牌,令牌过期后可用于重新获取 Access Token。

4. 游戏服务器获取用户信息

「星际冒险」后端用 Access Token 调用腾讯开放平台的 “获取用户信息” API:请求地址:https://graph.qq.com/user/get_user_info请求参数:

  • access_token=abc123xyz(访问令牌);

  • oauth_consumer_key=123456(游戏 Client ID);

  • openid=xxx(用户的 QQ 唯一标识,需先通过 Access Token 获取)。

腾讯服务器返回用户信息:

json

{"openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", // 用户唯一标识(不同游戏中该值唯一)"nickname": "游戏小能手", // 用户昵称"figureurl_qq_2": "https://qzonestyle.gtimg.cn/...", // 用户头像"gender": "男"
}

5. 游戏完成登录流程

1.「星际冒险」后端获取到 OpenID 后,查询自家数据库:

  • 若数据库中已存在该 OpenID 对应的游戏账号(用户之前用 QQ 登录过),则直接创建游戏会话,返回登录成功,用户进入游戏;

  • 若不存在该 OpenID(新用户),则自动为用户创建一个游戏账号,绑定该 OpenID,并默认填充昵称、头像等信息,随后返回登录成功,用户直接进入游戏。

三、用户体验总结

用户全程无需注册「星际冒险」的专属账号,仅需通过 QQ 授权即可快速登录,且无需向游戏暴露 QQ 密码,既便捷又安全。这也是 OAuth2.0 协议在第三方登录场景中的核心价值。

4、给你一张贴吧表 post(id, uid, title, like_cnt,comment_cnt,create_time(unix时间戳形式)

4.1 SQL 查询:三十天内评论超 5000、点赞超 500 的前五十条帖子标题 按点赞数降序

SELECT title 
FROM post 
WHERE create_time >= UNIX_TIMESTAMP(NOW() - INTERVAL 30 DAY)  -- 三十天内AND comment_cnt > 5000 AND like_cnt > 500 
ORDER BY like_cnt DESC  -- 按点赞数降序
LIMIT 0, 50;  -- 前五十条

4.2 索引设计及原因

核心索引

  1. 联合索引:idx_create_comment_like (create_time, comment_cnt, like_cnt)
    • 原因:查询条件包含 create_time 范围筛选、comment_cnt 和 like_cnt 等值判断,联合索引可覆盖查询条件,避免全表扫描。
    • 顺序逻辑:create_time 作为范围查询字段放在最前,后续字段在范围筛选后可继续过滤数据。
  2. 覆盖索引:idx_cover_query (create_time, comment_cnt, like_cnt, title)
    • 原因:查询结果仅需 title,覆盖索引可直接从索引中获取数据,无需回表查询,提升效率。

辅助索引

  • 单字段索引:idx_uid (uid):若存在按用户查询帖子的场景,加速 WHERE uid = xxx 的查询。

4.3 表结构优化

  1. 分表策略
    • 按 create_time 分表:如按月分表(post_202501、post_202502),减少单表数据量,提升查询速度。
    • 按 uid 哈希分表:适合高频按用户查询的场景,均衡各表数据分布。
  2. 字段优化
    • like_cnt 和 comment_cnt 采用无符号整数类型(INT UNSIGNED),节省存储空间。
    • create_time 可保留 Unix 时间戳(BIGINT),或转为 DATETIME 类型,便于日期函数直接操作。
  3. 冷热数据分离:将三十天内的热数据保留在主表,历史冷数据迁移至归档表,提升主表查询效率。

4.4 缓存设计:存储五十条目标帖子

缓存方案

  1. 缓存选型:使用 Redis 作为缓存,支持高并发读写和过期淘汰。
  2. 缓存 Key 设计post:top50:hot(标识 “三十天内热门帖子前五十”)。
  3. 缓存 Value 结构:采用 Hash 类型,field 为帖子 id,value 为帖子 JSON 字符串(包含 titlelike_cntcomment_cnt 等字段)。
  4. 缓存更新策略
    • 主动更新:帖子点赞 / 评论数变化时,同步更新缓存中的对应字段。
    • 过期淘汰:设置缓存过期时间为 1 小时,到期后重新查询数据库并刷新缓存,保证数据时效性。
    • 预热加载:系统启动时,自动执行查询 SQL 并将结果存入缓存,避免首次查询耗时过长。

5、枚举类的特征

以 “订单状态” 枚举类 OrderStatus 为例,直观展示枚举类的核心特征:

// 定义订单状态枚举类
public enum OrderStatus {// 枚举常量(实例),必须在类的第一行定义UNPAID("未支付", 1),PAID("已支付", 2),SHIPPED("已发货", 3),RECEIVED("已收货", 4),CANCELLED("已取消", 5);// 自定义属性private final String desc;  // 状态描述private final int code;     // 状态编码// 1. 构造方法默认私有(不可实例化)private OrderStatus(String desc, int code) {this.desc = desc;this.code = code;}// 自定义方法public String getDesc() {return desc;}public int getCode() {return code;}public static void main(String[] args) {// 2. 继承自 Enum 类(可调用 Enum 的方法)System.out.println(OrderStatus.PAID.getClass().getSuperclass()); // 输出:class java.lang.Enum(证明默认继承 Enum)// 3. 线程安全(枚举实例在类加载时初始化,唯一且不可变)OrderStatus s1 = OrderStatus.SHIPPED;OrderStatus s2 = OrderStatus.SHIPPED;System.out.println(s1 == s2);  // 输出:true(单例,地址相同)// 4. 支持 switch 语句OrderStatus status = OrderStatus.RECEIVED;switch (status) {case UNPAID:System.out.println("订单未支付");break;case PAID:System.out.println("订单已支付");break;case RECEIVED:System.out.println("订单已收货");  // 输出此句break;// 其他状态...}// 5. 自带常用方法// values():返回所有枚举实例数组(按定义顺序)OrderStatus[] allStatus = OrderStatus.values();for (OrderStatus s : allStatus) {System.out.print(s + " "); // 输出:UNPAID PAID SHIPPED RECEIVED CANCELLED}// ordinal():返回实例的序号(从 0 开始)System.out.println("\nPAID 的序号:" + OrderStatus.PAID.ordinal());  // 输出:1// valueOf():根据名称获取枚举实例OrderStatus cancel = OrderStatus.valueOf("CANCELLED");System.out.println(cancel.getDesc());  // 输出:已取消}
}

特征对应说明

  1. 不可实例化

    • 构造方法被 private 修饰(即使不写,默认也是 private),无法通过 new OrderStatus(...) 创建实例,只能使用类中定义的 UNPAIDPAID 等常量。
  2. 继承自 Enum 类

    • 无需显式写 extends Enum,但通过 getSuperclass() 可验证父类是 java.lang.Enum
    • 由于 Java 单继承特性,枚举类不能再继承其他类(如 enum OrderStatus extends BaseClass 会报错),但可实现接口(如 enum OrderStatus implements Serializable)。
  3. 线程安全

    • 枚举实例在类加载阶段(ClassLoader 的 loadClass 方法)初始化,且仅初始化一次(单例),不存在多线程并发创建的问题,天然线程安全。
  4. 支持 switch 语句

    • 可直接在 switch 中使用枚举常量(如 case PAID),比用字符串(case "PAID")更高效(底层通过序号判断,而非字符串比较)。
  5. 自带常用方法

    • values():动态获取所有枚举实例(常用于遍历);
    • ordinal():获取实例定义时的顺序(注意:若后续调整定义顺序,此值会变化,谨慎用于业务逻辑);
    • valueOf(String name):将字符串转换为枚举实例(名称必须完全匹配,否则抛 IllegalArgumentException)。

6、前端防刷能解决的问题与局限性

1. 能解决的问题

  • 拦截普通用户的无效操作:防止用户因误操作、重复点击发起大量请求(如 1 秒内点击 10 次 “抢购” 按钮),减少前端到后端的无效流量。
  • 限制未授权的提前请求:通过前端倒计时、按钮置灰,避免用户在活动开始前发起请求,减轻服务器预热阶段的压力。
  • 过滤简单的前端篡改:通过前端校验(如表单参数格式、请求频率),拦截部分未按规则构造的请求(如手动修改请求参数中的 “商品 ID”)。
  • 优化用户体验:通过加载动画、倒计时提示,引导用户规范操作,减少因操作混乱导致的额外请求。

2. 局限性

  • 无法抵御技术型刷量:攻击者可绕过前端(如直接模拟 HTTP 请求、修改前端代码删除限流逻辑),直接向后端发起请求,前端防刷完全失效。
  • 依赖客户端环境:前端代码运行在用户设备上,攻击者可通过浏览器控制台、抓包工具(如 Fiddler、Charles)篡改参数、禁用 JS,突破前端限制。
  • 不具备分布式一致性:前端防刷是 “单机级” 控制(如单浏览器的请求频率限制),无法应对多设备、多 IP 的分布式刷量(如攻击者用 100 台设备同时请求)。
  • 功能兼容性问题:部分前端防刷逻辑(如 JS 加密、Canvas 验证)可能在老旧浏览器或特殊设备上失效,影响正常用户体验。

http://www.dtcms.com/a/569964.html

相关文章:

  • Trae-Agent 使用本地模型
  • 哪个网站开发小程序网站建设与维护的软件
  • Docker(四)_导出容器(不含历史层)
  • GitHub Copilot CLI: How to get started
  • Android ANR的解决方案
  • 亚马逊云科技与OpenAI战略合作深度分析:算力联盟重塑AI产业格局
  • 个人接外包的网站心悦俱乐部官方网站怎么做任务
  • 【Ros2学习】话题的发布与请求
  • 肥猫网站建设广西省河池建设局网站
  • CentOS7安装docker教程
  • 论文网站建设与运营拖曳式网站建设
  • Jenkins持续集成入门指南:自动化构建与部署的最佳实践
  • 山西省建设信息网站汇点远程app下载安装
  • 阿里云手机网站建设打电话拉客户用网站做广告怎么做 好做吗
  • hexo做网站wordpress内容分页在哪改
  • 游戏网站后台建设美橙云建站
  • 数据备份策略:全量 / 增量 / 差异备份、备份周期规划
  • LeetCode 322. 零钱兑换
  • Redis黑马点评 Feed流
  • 域名后缀cn做网站河北手机网站建设
  • U-Net保姆级教程:从原理到医学细胞分割实战(PyTorch版)!
  • mini-bitcask学习笔记
  • 东莞网站建设公司哪家好电商平面设计主要做什么
  • 解决远程调用微服务之后无法通过上下文获取用户id问题
  • 网站代付系统怎么做大型网站seo策略
  • 国家住房城乡建设部网站住房和城乡建设部网站北京
  • 制作网站的程序网站查找工具
  • 网站建设 图片压缩网站开发多少费用
  • React Native App 自动检测版本更新完整实现指南
  • 网站建站是 什么企业网站托管运营