面试总结------2024/04/04

1.面试官提问:你说你在项目中使用springsecurity + jwt 实现了登录功能,能简单讲一下怎么实现的吗?

在这里插入图片描述

2.使用RabbitMQ实现订单超时取消功能

在这里插入图片描述

  1. 订单状态定义
    首先,我们需要定义订单的不同状态。在这个示例中,我们可以定义以下订单状态:

    WAITING_FOR_PAYMENT:待支付状态,表示用户已下单但尚未完成支付。
    PAID:支付成功状态,表示用户已成功完成支付。
    CANCELLED:已取消状态,表示订单已被取消。

  2. 发送订单消息到队列
    当用户下单时,我们需要将订单信息发送到RabbitMQ队列中。在发送订单消息时,我们需要设置消息的TTL为30分钟,以便在30分钟后触发超时取消订单的逻辑。

java

@Component
public class OrderProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendOrderMessage(String orderId) {
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setOrderId(orderId);
        orderMessage.setStatus(OrderStatus.WAITING_FOR_PAYMENT);

        rabbitTemplate.convertAndSend("order.exchange", "order.routingKey", orderMessage, message -> {
            message.getMessageProperties().setExpiration("1800000"); // 设置消息的TTL为30分钟
            return message;
        });
    }
}
  1. 创建订单状态转换的消费者
    创建一个消费者,监听DLX所指定的交换机,并根据订单状态的不同进行相应的处理。在这个示例中,我们将根据订单状态执行不同的逻辑,如果订单在30分钟内未支付,则执行取消订单的操作。

java

@Component
public class OrderConsumer {

    @RabbitListener(queues = "order.dead-letter.queue")
    public void processExpiredOrder(OrderMessage orderMessage) {
        if (orderMessage.getStatus() == OrderStatus.WAITING_FOR_PAYMENT) {
            // 30分钟后未支付,取消订单
            cancelOrder(orderMessage.getOrderId());
        }
    }

    private void cancelOrder(String orderId) {
        // 执行取消订单的逻辑
        System.out.println("Canceling order: " + orderId);
        // 更新订单状态为已取消
        // orderService.cancelOrder(orderId);
    }
}
  1. 配置RabbitMQ
    在RabbitMQ中,我们需要创建一个交换机、一个队列和一个DLX(死信交换机),并将队列绑定到DLX上。同时,我们也需要设置DLX的路由键,以便将超时的订单消息发送到DLX中。

java

@Configuration
public class RabbitMQConfig {

    @Bean
    public DirectExchange orderExchange() {
        return new DirectExchange("order.exchange");
    }

    @Bean
    public Queue orderQueue() {
        return QueueBuilder.durable("order.queue")
                .withArgument("x-dead-letter-exchange", "order.dead-letter.exchange")
                .withArgument("x-dead-letter-routing-key", "order.dead-letter.routing-key")
                .build();
    }

    @Bean
    public DirectExchange orderDeadLetterExchange() {
        return new DirectExchange("order.dead-letter.exchange");
    }

    @Bean
    public Queue orderDeadLetterQueue() {
        return new Queue("order.dead-letter.queue");
    }

    @Bean
    public Binding bindingOrder() {
        return BindingBuilder.bind(orderQueue())
                .to(orderExchange())
                .with("order.routingKey");
    }

    @Bean
    public Binding bindingOrderDeadLetter() {
        return BindingBuilder.bind(orderDeadLetterQueue())
                .to(orderDeadLetterExchange())
                .with("order.dead-letter.routing-key");
    }
}

在以上配置中,我们定义了一个名为order.exchange的直连交换机,以及一个名为order.queue的队列。我们还定义了一个DLX,名为order.dead-letter.exchange,并将队列order.queue绑定到DLX上。当订单消息在30分钟内未被消费时,将会被发送到DLX中。
在这里插入图片描述

3.使用Redis+Lua脚本实现秒杀功能,后期用了Redisson锁进行优化处理。

在这里插入图片描述

public class SeckillService {
    private final RedissonClient redissonClient;
    private final String luaScript;

    public SeckillService(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
        // 加载Lua脚本
        this.luaScript = "local count = redis.call('get', KEYS[1])\n" +
                "if tonumber(count) >= tonumber(ARGV[1]) then\n" +
                "    redis.call('decrby', KEYS[1], ARGV[1])\n" +
                "    return 1\n" +
                "else\n" +
                "    return 0\n" +
                "end";
    }

    public boolean seckill(String productId, int quantity) {
        RLock lock = redissonClient.getLock(productId);
        try {
            // 加锁
            lock.lock();
            // 执行Lua脚本
            RScript script = redissonClient.getScript();
            List<Object> result = script.eval(RScript.Mode.READ_WRITE, luaScript, RScript.ReturnType.INTEGER, Collections.singletonList(productId), String.valueOf(quantity));
            // Lua脚本返回值为1表示秒杀成功,0表示库存不足
            return result != null && result.size() > 0 && (int) result.get(0) == 1;
        } finally {
            // 释放锁
            lock.unlock();
        }
    }
}

构造方法初始化了SeckillService对象,并加载了Lua脚本。

luaScript:这个Lua脚本从Redis获取指定商品的库存数量,如果库存充足,则减少库存数量,并返回1表示秒杀成功;如果库存不足,则返回0表示秒杀失败。

方法:seckill

这个方法用于执行秒杀操作。

public boolean seckill(String productId, int quantity) {
    RLock lock = redissonClient.getLock(productId);
    try {
        // 加锁
        lock.lock();
        // 执行Lua脚本
        RScript script = redissonClient.getScript();
        List<Object> result = script.eval(RScript.Mode.READ_WRITE, luaScript, RScript.ReturnType.INTEGER, Collections.singletonList(productId), String.valueOf(quantity));
        // Lua脚本返回值为1表示秒杀成功,0表示库存不足
        return result != null && result.size() > 0 && (int) result.get(0) == 1;
    } finally {
        // 释放锁
        lock.unlock();
    }
}

方法步骤:
获取分布式锁:使用redissonClient.getLock(productId)获取商品ID对应的分布式锁。
加锁:使用lock.lock()方法加锁,确保秒杀操作的原子性。
执行Lua脚本:使用RScript执行预先加载的Lua脚本,该脚本会检查商品库存是否充足,并进行库存减少操作。
解析Lua脚本返回值:根据Lua脚本的返回值判断秒杀操作是否成功。返回值为1表示秒杀成功,返回值为0表示库存不足。
释放锁:使用lock.unlock()释放锁。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/515297.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[COCI 2011/2012 #5] EKO / 砍树 (二分)不开龙永远的痛!

不开龙long永远的痛&#xff01; 不开龙long永远的痛&#xff01; 不开龙long永远的痛&#xff01; 不开龙long永远的痛&#xff01; 不开龙long永远的痛&#xff01; //应该以最高的树为基准二分 初次尝试&#xff1a; #include<algorithm> #include<iostream&g…

图的深度优先遍历DFS得到各节点的度

在 一文中&#xff0c;我们通过了广度优先搜索来得到图结构中各结点的度&#xff0c;在这一篇文章中&#xff0c;我们要通过深度优先搜索来得到图结构中各结点的度。 初始化 初始化&#xff0c;在下面的代码中&#xff0c;我们创建了一个具有6个结点的图结构&#xff0c;以及…

YOLO电动车检测识别数据集:12617张图像,yolo标注完整

YOLO电动车检测识别数据集&#xff1a;12617张图像&#xff0c;电动车一类&#xff0c;yolo标注完整&#xff0c;部分图像应用增强。 适用于CV项目&#xff0c;毕设&#xff0c;科研&#xff0c;实验等 需要此数据集或其他任何数据集请私信

【调度工具】Azkaban用户手册

目录 一、概述 1.1 Azkaban 是什么 1.2 Azkaban 特点 1.3 Azkaban 与 Oozie 对比 功能 工作流定义 工作流传参 定时执行 资源管理 工作流执行 工作流管理 1.4 Azkaban 运行模式及架构 Azkaban 三大核心组件 Azkaban有两种部署方式 Azkaban Web Server Azkaban …

简约轻量-失信录系统源码

失信录系统-最新骗子收录查询系统源码 首页查询&#xff1a; 举报收录页&#xff1a; 后台管理页&#xff1a; 失信录系统 V1.0.0 更新内容&#xff1a; 1.用户查询,举报功能 2.界面独立开发 3.拥有后台管理功能 4.xss,sql安全过滤 5.平台用户查询 6.用户中心&#xff08;待完…

IO流:字节流、字符流、缓冲流、转换流、数据流、序列化流 --Java学习笔记

目录 IO流 IO流的分类 IO流的体系 字节流&#xff1a; 1、Filelnputstream(文件字节输入流) 2、FileOutputStream(文件字节输出流) 字节流非常适合做一切文件的复制操作 复制案例&#xff1a; try-catch-finally 和 try-with-resource 字符流 1、FileReader(文件字符…

JimuReport 积木报表

一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于 excel 操作风格&#xff0c;通过拖拽完成报表设计…

C#学生信息管理系统

一、引言 学生信息管理系统是现代学校管理的重要组成部分&#xff0c;它能够有效地管理学生的基本信息、课程信息、成绩信息等&#xff0c;提高学校管理的效率和质量。本文将介绍如何使用SQL Server数据库和C#语言在.NET平台上开发一个学生信息管理系统的课程设计项目。 二、项…

前端学习<四>JavaScript基础——02-JavaScript入门:hello world

开始写第一行 JavaScript&#xff1a;hello world JS 代码的书写位置在哪里呢&#xff1f;这个问题&#xff0c;也可以理解成&#xff1a;引入 JS 代码&#xff0c;有哪几种方式&#xff1f;有三种方式&#xff1a;&#xff08;和 CSS 的引入方式类似&#xff09; 行内式&…

msyql 查看和修改字符集的方法

在插入或修改数据的时候&#xff0c;报字符集的错误&#xff0c;中文的无法进行插入修改。比如&#xff1a; update users set user_name关羽 where user_id2; 报错信息&#xff1a; ERROR 1366 (HY000): Incorrect string value: /xB9/xD8/xD3/xF0 for column user_name at …

2024年学浪视频下载器

学浪视频官方没有提供下载选项&#xff0c;但又有很多人需要学浪视频下载器&#xff0c;于是我就开发了这么一款软件&#xff0c;学浪视频下载器:小浪助手.exe 我把学浪下载器打包成压缩包&#xff0c;有需要的自己取一下 链接&#xff1a;https://pan.baidu.com/s/1y7vcqILT…

Google Chrome 常用设置

Google Chrome 常用设置 References 转至网页顶部 快捷键&#xff1a;Home 转至内容设置 chrome://settings/content 清除浏览数据 历史记录 -> 清除浏览数据 关于 Chrome 设置 -> 关于 Chrome chrome://settings/help References [1] Yongqiang Cheng, https:/…

保健品wordpress外贸模板

保健品wordpress外贸模板 健康保养保健品wordpress外贸模板&#xff0c;做大健康行业的企业官方网站模板。 https://www.jianzhanpress.com/?p3514

NucleiStudio下longan nano烧录官方例程

longan nano烧录官方例程 一、准备工作二、编译程序三、器件连接四、烧录程序 IDE:NucleiStudio202009 开发板:longan nano gd32vf103c8t6 一、准备工作 1、下载IDE 芯来科技官网下载NucleiStudio 2、下载烧录器 https://dl.sipeed.com/shareURL/LONGAN/LonganPi3H 网盘链接 …

达梦配置ODBC连接

达梦配置ODBC连接 基础环境 操作系统&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) 数据库版本&#xff1a;DM Database Server 64 V8 架构&#xff1a;单实例1 下载ODBC包 下载网址&#xff1a;https://www.unixodbc.org/ unixODBC-2.3.0.tar.gz2 编译并…

【Qt 学习笔记】认识QtSDK中的重要工具

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 认识QtSDK中的重要工具 文章编号&#xff1a;Qt 学习笔记 / 03 文章目…

MySQL安装卸载-Linux

目录 1.概述 2.安装 2.1.上传 2.2.解压 ​​​​​​​2.3.安装 ​​​​​​​2.4.启动服务 ​​​​​​​2.5.查询临时密码 ​​​​​​​2.6.修改临时密码 ​​​​​​​2.7.创建用户 ​​​​​​​2.8.分配权限 ​​​​​​​2.9.重新链接 3.卸载 3.1.停…

A53 cache的架构解读

快速链接: 【精选】ARMv8/ARMv9架构入门到精通-[目录] &#x1f448;&#x1f448;&#x1f448; 引流关键词:缓存,高速缓存,cache, CCI,CMN,CCI-550,CCI-500,DSU,SCU,L1,L2,L3,system cache, Non-cacheable,Cacheable, non-shareable,inner-shareable,outer-shareable, optee、…

【C++】C++11类的新功能

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 默认成员函数 类成…

shell的编写

文章目录 1.框架2.命令行3.获取用户命令字符串4.命令行字符串分割5.执行命令和内建命令6.完整代码&#xff1a; 1.框架 我们知道shell是一直存在的&#xff0c;所以首先我们第一步就是要搭建一个框架&#xff0c;使其一直存在。 那么也很简单&#xff0c;一个while循环就可以完…