【业务编程题】订单的ID生成 📅 发布时间:2026/7/4 3:05:46 👁️ 浏览次数: 文章目录题目要求解题思路1.各个字段的字符串转化2.递增顺序数字的线程安全问题3.订单-订单ID的映射最终代码题目要求在电商项目中订单号是用来跟踪和识别每一个订单的唯一标识。为了保证订单号的唯一性需要设计一个订单号生成器可以根据日期顺序数字和用户ID生成订单号。现已经有订单类(Order)如下privateDatecreateDate;//订单创建时间publicprivateStringorderSerial;//订单顺序数字privateStringuserId;//订单所属用户ID请实现一个订单号生成与查询系统。需要实现 Solution 类中的两个方法publicStringgenerateOrderNumber(Datedate,StringuserID);// 根据日期、顺序数字和用户ID生成订单号publicOrdergetOrder(StringorderNumber);// 根据订单号获取相关的订单信息返回一个Order对象订单号格式三个部分按顺序拼接共 19 位日期8 位 YYYYMMDD顺序数字 5 位每天从 00001 开始递增超过 99999 后重置用户 ID6 位英文字母和数字组成已提供的 Order 类如下classOrder{privateDatecreateDate;// 订单创建时间privateStringorderSerial;// 订单顺序数字privateStringuserID;// 订单所属用户IDpublicOrder(DatecreateDate,StringorderSerial,StringuserID){this.createDatecreateDate;this.orderSerialorderSerial;this.userIDuserID;}publicDategetCreateDate(){returncreateDate;}publicStringgetOrderSerial(){returnorderSerial;}publicStringgetUserID(){returnuserID;}}需要实现的 Solution 类publicclassSolution{publicStringgenerateOrderNumber(Datedate,StringuserID){// TODO: 实现订单号生成逻辑}publicOrdergetOrder(StringorderNumber){// TODO: 实现订单查询逻辑}}补充说明顺序数字每天从 00001 开始格式化为 5 位不足补零超过 99999 后重置userID 保证长度为 6 位由英文字母和数字组成如果获取订单存在异常就抛出 IllegalArgumentException示例如下// 输入: date 2023-11-02, userID ABC123, 输出: 2023110200001ABC123StringorderNumsolution.generateOrderNumber(date,ABC123);Orderordersolution.getOrder(orderNum);order.getCreateDate();// 注意是 Data 格式的 Wed Nov 02 00:00:00 CST 2023order.getOrderSerial();// 00001order.getUserID();// ABC123解题思路1.各个字段的字符串转化Date 转化字符串使用SimpleDateFormat方法privateSimpleDateFormatsdfnewSimpleDateFormat(yyyyMMdd);StringdateStringsdf.format(date);//日期订单顺序数字的生成应根据当天的时间进行递增同一天内进行递增递增到99999就重新循环前置 0 的补全使用String.format(%05d, seq)UserID 字段直接 get()2.递增顺序数字的线程安全问题MapString, Integer线程 A 和 B 同时 get 得到相同的值后递增修改会出现丢失更新的线程不安全问题。A get 1B get 1A put 2B put 2MapString, AtomicIntegerincrementAndGet() 是原子的方法incrementAndGet() 是原子递增的但是获取 Map 中的 AtomicInteger 实例不是原子的。A 执行 getOrDefaultMap 中无键返回新建的 aiA new AtomicInteger(0)在 put 键之前B 执行 getOrDefault同样设置为 0 递增为1后还是出现覆盖问题ConcurrentHashMapString, Integer同样的问题 get 和 put 是分开的同样可能获取到相同值再进行覆盖。ConcurrentHashMapString, AtomicInteger线程A incrementAndGet() 返回 99999内部变为 100000线程 B返回 100000内部变为 100001两个线程同时进入count99999判断内部。ConcurrentHashMapString, Integer配合compute本质上是让获取-判断-覆盖这一整个流程原子化代码如下。3.订单-订单ID的映射每次订单 ID 生成后则 new Order 创建新订单映射到MapString, Order中等到getOrder() 直接从 Map 中查询最终代码classOrder{privateDatecreateDate;//创建订单时间privateStringorderSerial;//顺序数字privateStringuserId;//用户IDpublicOrder(DatecreateDate,StringorderSerial,StringuserId){this.createDatecreateDate;this.orderSerialorderSerial;this.userIduserId;}publicStringgetOrderSerial(){returnorderSerial;}publicStringgetUserId(){returnuserId;}publicDategetCreateDate(){returncreateDate;}}classSolution{//订单号-订单映射privateMapString,OrderordernewHashMap();//日期-订单号顺序计数器每个日期/当天的订单号顺序计数递增privateConcurrentHashMapString,IntegerdailyCounternewConcurrentHashMap();//日期格式化工具类java.text.SimpleDateFormatsdfnewjava.text.SimpleDateFormat(yyyyMMdd);publicSolution(){}publicStringgenerateOrderNumber(Datedate,StringuserID){//Date类型转换为字符串String类型StringdateStringsdf.format(date);//日期//获取当前日期的订单号顺序计数器,当天内由1递增//V compute(K key, BiFunction? super K, ? super V, ? extends V remappingFunction)//Lambda 的返回值就是要放回 Map 中的新值intcountdailyCounter.compute(dateString,(k,v)-{//如果v为null,则返回1,否则返回v1intnext(vnull)?1:v1;returnnext99999?1:next;});//前位置补充0StringorderSerialStringString.format(%05d,count);//拼接StringOrderIddateStringorderSerialStringuserID;//创建新订单OrdernewOrdernewOrder(date,orderSerialString,userID);order.put(OrderId,newOrder);returnOrderId;}publicOrdergetOrder(StringorderNumber){//如果存在异常就抛出IllegalArgumentExceptionif(!order.containsKey(orderNumber)){thrownewIllegalArgumentException(Invalid order number);}returnorder.get(orderNumber);}}
Dify开源LLM应用开发平台:一周上手,构建企业级AI应用 🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 在AI应用开发领域,你是否也曾面临这样的困境:想快速构建一个智能客服、内容生成助手或数据分析工具࿰… 2026/7/4 3:05:46
深入解析pytest_terminal_summary钩子:从原理到实战的测试报告终极定制指南 1. 项目概述:为什么我们需要关注pytest_terminal_summary?如果你用过pytest写过自动化测试,那你肯定对每次运行完测试后,终端里打印的那一大段总结报告不陌生。它告诉你跑了多少用例,通过了多少,失败了几个… 2026/7/4 3:05:46
YOLO目标检测毕业设计:四大改进策略与工程实践指南 🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 1. 背景与核心概念:为什么YOLO是毕业设计的“利器”? 对于许多计算机视觉方向的研究生,尤其是面临… 2026/7/4 3:03:45
永磁同步电机模糊PI控制与SVPWM技术详解 1. 永磁同步电机控制基础与挑战永磁同步电机(Permanent Magnet Synchronous Motor, PMSM)作为现代工业驱动领域的核心部件,其高效节能的特性使其在电动汽车、数控机床等高精度应用场景中占据主导地位。与传统异步电机相比,PMSM的转… 2026/7/4 4:18:08
HardFault 怎么定位?不用仿真器也能找到死机位置 前言写 STM32 程序一定会遇到这种情况:程序跑着跑着就卡死了,或者进入了某个中断出不来了。最常见的结果就是进入 HardFault_Handler——一个死循环。void HardFault_Handler(void) {// CubeMX 生成的默认处理while (1); }大部分人的反应是注释掉 while(… 2026/7/4 4:18:08
ComfyUI IPAdapter plus高级配置实战:5大策略深度解析多模型协同工作流 ComfyUI IPAdapter plus高级配置实战:5大策略深度解析多模型协同工作流 【免费下载链接】ComfyUI_IPAdapter_plus 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI_IPAdapter_plus ComfyUI IPAdapter plus作为ComfyUI中IPAdapter模型的参考实现&#… 2026/7/4 4:14:07
Agent 流程架构三大核心运行机制 现在做大模型相关应用,比拼的核心早就不是模型参数量多大、或是写得多精巧的提示词,真正拉开差距的关键,是你给大模型搭出来的整套运行流程好不好。Agent是依托大语言模型(LLM)搭建的智能系统框架,属于能完… 2026/7/4 4:14:07
Java基础快速入门:JUnit单元测试入门 本文纲要 单元测试概述JUnit 简介与特点JUnit 基本使用步骤代码实践一:基本使用与异常测试核心注解:Before、Test、After代码实践二:测试执行顺序总结 单元测试概述 在传统的Java开发中,我们常常等所有代码编写完成后,… 2026/7/4 4:14:07
最新AI论文写作工具综合榜(2026 优选) 基于功能全面性、学术规范匹配度、用户使用体验及技术稳定性,以下是当前主流 AI 论文写作工具的综合测评榜单,按实际应用价值从高到低排列,并详细标注各工具的核心优势与适用人群。🏆 第一梯队:全流程学术解决方案&… 2026/7/4 4:12:06
STM32F745VG与MC6470 IMU的高性能姿态控制系统设计 1. MC6470与STM32F745VG的黄金组合解析在工业自动化和机器人控制领域,传感器与微控制器的协同工作能力直接决定了系统的响应速度和定位精度。MC6470作为一款6自由度惯性测量单元(6DOF IMU),与STM32F745VG这款基于ARM Cortex-M7内核的高性能微控制器组合&… 2026/7/4 0:00:28
Playwright自动化测试实战:从零搭建现代Web测试框架 1. 项目概述:为什么是 Playwright?如果你正在为现代 Web 应用的自动化测试头疼,尤其是面对那些充斥着动态加载、复杂交互的单页应用(SPA),那么 Playwright 的出现,很可能就是你的解药。我接触过… 2026/7/4 0:00:28
终极指南:如何将JSXBIN二进制文件转换为可读JSX源代码 终极指南:如何将JSXBIN二进制文件转换为可读JSX源代码 【免费下载链接】jsxbin-to-jsx-converter JSXBin to JSX Converter written in C# 项目地址: https://gitcode.com/gh_mirrors/js/jsxbin-to-jsx-converter 你是否曾经面对过Adobe产品的JSXBIN文件感到… 2026/7/4 0:02:28