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

字节golang后端二面

前端接口使用restful格式,post与get的区别是什么?

在这里插入图片描述

HTTP网络返回的状态码有哪些?

在这里插入图片描述

go语言切片与数组的区别是什么?

在这里插入图片描述

MySQL实现并发安全避免两个事务同时对一个记录写操作的手段有哪些?

在这里插入图片描述

如何实现业务的幂等性(在golang代码中如何避免消息重复或处理已出现的消息重复)?

在这里插入图片描述

如何设置redis分布式锁?

在这里插入图片描述
SETNX 是 Redis 中的一个命令,全称为 “SET if Not eXists”。它的作用是在键不存在时设置键的值。具体来说,SETNX 的功能如下:

语法

SETNX key value

返回值

  • 1: 如果键成功设置(即键不存在)。
  • 0: 如果键已经存在,设置失败。

用法示例

1. 设置一个键
SETNX my_key "some_value"
  • 如果 my_key 不存在,则它的值被设置为 "some_value",返回 1。
  • 如果 my_key 已经存在,则不做任何操作,返回 0。
2. 用于分布式锁

SETNX 常用于实现分布式锁,因为它可以确保只有一个进程可以获得锁。例如:

import redis# 连接到 Redis
client = redis.StrictRedis(host='localhost', port=6379, db=0)# 尝试获取锁
if client.setnx("my_lock", "some_unique_value"):print("Lock acquired")# 执行临界区代码# 释放锁client.delete("my_lock")
else:print("Lock already acquired")

注意事项

  • 不适合复杂操作: SETNX 只能用于简单的键值设置,不能用于复杂的条件判断。
  • 锁的有效性: 在实现分布式锁时,结合使用 SETNX 和设置过期时间可以防止死锁。

在这里插入图片描述

ThreadLocal

ThreadLocal 是 Java 中的一个类,用于提供线程局部变量。每个使用 ThreadLocal 的线程都可以独立地存储和访问自己的变量副本,而不会与其他线程共享。以下是关于 ThreadLocal 的详细解释:

1. 基本概念

  • 线程局部变量: 每个线程在访问 ThreadLocal 变量时,会得到自己独立的副本。这意味着一个线程对 ThreadLocal 变量的修改不会影响其他线程。
  • 存储位置: ThreadLocal 变量存储在每个线程的 ThreadLocalMap 中。

2. 使用方法

2.1 创建 ThreadLocal 变量
ThreadLocal<String> threadLocalVar = new ThreadLocal<>();
2.2 设置值

使用 set() 方法将值存储到当前线程的 ThreadLocal 变量中。

threadLocalVar.set("Hello, ThreadLocal!");
2.3 获取值

使用 get() 方法从当前线程的 ThreadLocal 变量中获取值。

String value = threadLocalVar.get(); // 返回 "Hello, ThreadLocal!"
2.4 清除值

使用 remove() 方法可以清除当前线程的 ThreadLocal 变量值。

threadLocalVar.remove();

3. 示例代码

以下是一个使用 ThreadLocal 的简单示例:

public class ThreadLocalExample {private static ThreadLocal<Integer> threadLocalValue = ThreadLocal.withInitial(() -> 0);public static void main(String[] args) {Runnable task = () -> {Integer value = threadLocalValue.get();value++;threadLocalValue.set(value);System.out.println(Thread.currentThread().getName() + ": " + threadLocalValue.get());};Thread thread1 = new Thread(task);Thread thread2 = new Thread(task);thread1.start();thread2.start();}
}

4. 适用场景

  • 用户会话信息: 在 Web 应用中,可以使用 ThreadLocal 存储每个请求的用户信息。
  • 数据库连接: 每个线程可以持有自己的数据库连接,避免共享连接导致的线程安全问题。
  • 性能优化: 减少对象的创建和销毁,避免频繁的上下文传递。

5. 注意事项

  • 内存泄漏: 如果不调用 remove() 方法,线程局部变量可能会导致内存泄漏,尤其在使用线程池时。
  • 不适合跨线程使用: ThreadLocal 变量仅在创建它的线程中可见,其他线程无法访问。
  • 调试困难: 使用 ThreadLocal 可能会让调试变得复杂,因为变量的状态依赖于线程的生命周期。

总结

ThreadLocal 是一个强大的工具,适用于需要线程隔离的数据存储场景。合理使用可以提高性能和简化代码,但也需要注意内存管理和线程安全问题。

超卖问题怎么解决?

  • redis使用lua脚本判断和扣减库存
  • 使用redis队列避免数据不一致的问题(先将数据存入redis队列中,从redis队列中取出记录添加到数据库)

后端如何对一个请求鉴权?为什么JWT要双签发?被截获了怎么办?如果人为地想要禁止某个用户的访问应该怎么做?

一、后端请求鉴权流程

后端通常通过以下步骤验证请求合法性:

  1. Token 提取
    从请求头(如 Authorization: Bearer <token>)或 Cookie 中获取 JWT。
  2. 签名验证
    用预设密钥验证 JWT 签名是否被篡改(例如使用 HMAC 或 RSA 算法)。
  3. 有效期检查
    校验 exp(过期时间)和 nbf(生效时间)字段。
  4. 业务逻辑鉴权
    • 从 JWT 解析用户角色/权限(如 role: admin)。
    • 对比请求资源所需的权限(如 RBAC 模型)。
  5. 敏感操作二次验证
    关键操作(如支付)要求重新输入密码或 2FA 验证。
# Python 伪代码示例(使用 PyJWT)
def verify_request(request):token = request.headers.get("Authorization").split("Bearer ")[1]try:payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])if payload["role"] != "admin":raise PermissionError("无权访问")return Trueexcept jwt.ExpiredSignatureError:raise Unauthorized("Token过期")

二、JWT 双签发机制及作用

双签发(Dual-Issuer) 指同时使用两个密钥签发 Token:

  1. 主密钥(Primary Key)
    • 用于签发长期有效的 访问令牌(Access Token)(如有效期 1 小时)。
  2. 从密钥(Secondary Key)
    • 用于签发短期有效的 刷新令牌(Refresh Token)(如有效期 7 天)。

✔ 核心目的:安全性隔离

  • 访问令牌泄露风险高:频繁在网络传输,暴露概率大。
  • 刷新令牌严格保护:仅用于获取新访问令牌,存储于安全环境(如 HttpOnly Cookie)。
  • 攻击窗口最小化:即使 Access Token 被截获,有效期短且无法直接获取新 Token。

三、JWT 被截获的应对措施

攻击类型防御方案示例
中间人窃听强制 HTTPS + HSTS 头服务器配置 TLS 1.3
客户端脚本窃取HttpOnly Cookie 存储 + XSS 防护设置 Set-Cookie: HttpOnly; Secure
Token 泄露短期有效期 + 刷新令牌轮转Access Token 有效期 ≤15 分钟
重放攻击JTI(JWT ID)唯一标识 + 服务端黑名单使用 Redis 记录已使用的 JTI

刷新令牌轮转示例
每次用 Refresh Token 获取新 Access Token 时,同步生成新 Refresh Token 并作废旧令牌。这样即使旧刷新令牌被截获,攻击者只能使用一次。


四、禁止特定用户访问的解决方案

1. 短期封禁:令牌黑名单(Token Blacklist)
  • 适用场景:立即踢出已登录用户。
  • 实现方式
    • 用户注销或封禁时,将 JWT 的 jti(唯一ID)加入 Redis 黑名单。
    • 鉴权时校验 jti 是否在黑名单中。
  • 优点:实时生效。
  • 缺点:增加数据库查询开销。
# 封禁用户时
redis.set(f"blacklist:{jti}", "1", ex=ACCESS_TOKEN_EXPIRE)# 鉴权时检查
if redis.exists(f"blacklist:{jti}"):raise Forbidden("用户已被封禁")
2. 长期封禁:用户状态标记
  • 适用场景:永久禁止访问。
  • 实现方式
    • 在用户数据库添加 is_active 字段。
    • 鉴权时查询用户状态(注意缓存用户信息避免频繁查库)。
  • 优点:一劳永逸。
  • 缺点:状态变更后需等待 Token 自然过期。
3. 强制令牌失效:刷新令牌回收
  • 封禁用户时,删除该用户的刷新令牌
  • 用户 Access Token 过期后无法续签,自动退出。

五、最佳实践总结

  1. 双签发必要性
    ✅ 隔离高风险令牌(Access Token)与高价值令牌(Refresh Token)。
  2. 防截获组合拳
    ✅ HTTPS + 短有效期 + HttpOnly Cookie + 刷新令牌轮转。
  3. 封禁用户策略
    • 紧急场景:令牌黑名单(实时生效)。
    • 永久封禁:标记用户状态 + 回收刷新令牌
  4. 性能优化
    • 黑名单用 Redis 存储并设置自动过期(与 Token 有效期对齐)。
    • 用户状态变化时清理缓存(如 Redis 中的用户信息)。

关键原则:JWT 本身无状态,需通过黑名单/用户状态引入必要状态控制,在安全性和性能间取得平衡。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

相关文章:

  • 用dayjs解析时间戳,我被提了bug
  • 在IIS上无法使用PUT等请求
  • 基于机器学习的心脏病预测模型构建与可解释性分析
  • 西瓜书第十章——聚类
  • buuctf-web
  • unix/linux source 命令,其历史争议、兼容性、生态、未来展望
  • 在Flutter中定义全局对象(如$http)而不需要import
  • JVM学习(七)--JVM性能监控
  • Tomcat优化篇
  • ASP.NET Core SignalR 身份认证集成指南(Identity + JWT)
  • Axure组件即拖即用:垂直折叠菜单(动态展开/收回交互)
  • APM32主控键盘全功能开发实战教程:软件部分
  • 【Java基础】Java入门教程
  • DeepSeek 赋能智慧消防:以 AI 之力筑牢城市安全 “防火墙”
  • 归一化相关
  • 大模型备案中语料安全详细说明
  • Ubuntu终端性能监视工具
  • 进阶日记(一)—LLMs本地部署与运行(更新中)
  • uni-app学习笔记十八--uni-app static目录简介
  • 人工智能100问☞第38问:什么是多模态模型?
  • 合肥网站建/百度新闻头条
  • 诸城做网站的公司/今日要闻新闻
  • 衡水哪个公司做网站好/网站排名优化师
  • 国外好看的教育类网站模板下载/网络营销推广外包服务
  • 凡客诚品售后服务有哪些/seo优化工具软件
  • 政府网站栏目架构/今日热点新闻事件2022