Java应用OOM排查:面试通关“三部曲”心法
开篇点题:OOM——Java应用的“内存爆仓”警报
-
OOM (OutOfMemoryError) 是啥病?想象一下,你的Java应用程序是一个大仓库,内存就是仓库的存储空间。如果货物(程序运行时创建的对象)越来越多,超出了仓库的容量,仓库管理员(JVM)就会大喊:“放不下了!爆仓了!”——这就是“OutOfMemoryError”(OOM内存溢出)。一旦发生OOM,应用轻则响应缓慢、功能异常,重则直接“罢工”崩溃,用户体验直线下降。
-
为啥面试官爱问这个?
- 核心挑战: OOM是Java应用中最常见也最致命的问题之一,能有效考察候选人处理线上危急状况的能力。
- JVM理解深度: 排查OOM需要对JVM内存模型、垃圾回收机制有深入理解。
- 问题定位与分析能力: OOM的根源可能多种多样(内存泄漏、配置不当、瞬时大对象等),考察候选人系统性的分析和诊断技能。
- 工具运用与实践经验: 是否熟练使用MAT、jmap、jstat以及分析GC日志等工具。
- 系统优化与预防思维: 能否从根本上解决问题并提出预防措施,体现架构和设计能力。
核心思路:三大黄金法则傍身 (整体大局观)
在应对“内存爆仓”的紧急情况时,心中牢记三大法则:
-
法则一:救火优先,保全现场!
- 大白话: “仓库爆了”,首要任务是赶紧恢复运作(比如重启),但同时务必抢救出“货物清单”和“监控录像”(Heap Dump、GC日志),这是事后查明“事故原因”的关键证据!
- 对应行动: 快速恢复服务是第一要务,但在此过程中,有意识地、优先地收集和保全所有能用于事后分析的诊断信息。
-
法则二:由表及里,深挖根源!
- 大白话: 不能只满足于让“仓库”重新开门,必须搞清楚是“货物”(对象)太多放不下,还是“仓库管理”(GC、内存配置)出了问题,或者是“有人在偷偷囤积居奇”(内存泄漏)。
- 对应行动: 利用诊断工具(MAT、GC日志分析等)层层深入,从现象到本质,定位OOM的真正原因。
-
法则三:标本兼治,长效预防!
- 大白 jornalista: 找到“爆仓”真凶后,不仅要“清理门户”,还要“改造仓库”、“升级管理制度”,确保以后不再轻易“爆仓”。
- 对应行动: 彻底修复问题(代码优化、JVM调优),并完善监控、告警、容量规划和流程规范,建立长效预防机制。
行动总纲:OOM排查“三部曲” (先有总纲,再看细节)
我们的OOM“救火与探案”行动路线图清晰明了,严格分为三步:
-
第一部曲:十万火急!应急响应与现场保护 (事中应急)
- 目标: 以最快速度恢复服务,最大限度降低业务损失,同时务必保全OOM相关的诊断信息(如Heap Dump、GC日志)以供后续分析。
-
第二部曲:刨根问底!诊断分析与定位真凶 (事中诊断)
- 目标: 在服务初步稳定或隔离环境下,利用收集到的诊断信息,通过专业工具和分析方法,深入排查,定位导致OOM的根本原因。
-
第三部曲:亡羊补牢!彻底修复与长效预防 (事后根治与预防)
- 目标: 针对根本原因进行彻底修复(代码层面、JVM参数层面、架构层面),并建立和完善长效的监控、预警、容量规划和规范流程,防止OOM问题再次发生。
各个击破:三部曲详解 (局部细节展开)
第一部曲:十万火急!应急响应与现场保护 (事中应急)
监控告警显示JVM内存使用率飙升至100%,或者应用日志中出现 java.lang.OutOfMemoryError!你是“仓库救火队长”,每一秒都至关重要!
-
火速定位“爆仓”类型与范围!(快速信息收集与评估)
-
OOM类型确认(监控/日志是“CCTV”和“报警器”):
-
日志里是哪种OOM?
- java.lang.OutOfMemoryError: Java heap space:最常见,堆内存不足。
- java.lang.OutOfMemoryError: Metaspace:元空间不足(JDK 8+),通常是加载的类太多或元空间配置太小。
- java.lang.OutOfMemoryError: GC overhead limit exceeded:GC占用了绝大部分CPU时间(通常超过98%),但回收效果甚微(如回收了不到2%的堆),说明内存极度紧张,JVM认为继续GC已无意义。
- 其他类型如 Unable to create new native thread(无法创建新线程,可能是系统线程数限制或内存不足以分配给线程栈)、Direct buffer memory(直接内存不足)。
-
-
影响范围: 是单台服务器上的应用实例OOM,还是集群大面积OOM?(查看负载均衡状态、实例健康检查、APM告警)。
-
业务影响: 哪些核心业务受到了冲击?用户请求是不是大量失败或超时?错误率是否飙升?
-
关联近期“可疑操作”:
- 最近有代码上线吗?(特别是涉及大量数据处理、缓存、集合操作、第三方库引入或升级的代码,重大嫌疑!)
- 有配置变更吗?(比如JVM内存参数调整、业务配置导致数据量突增)
- 是不是有预期外的大流量冲击,或者某个批处理任务/定时任务在不合适的时间运行了?
-
-
检查JVM是否留下“遗书”?(关键诊断信息保全意识)
-
Heap Dump (堆转储文件) - “黑匣子”:
- 检查JVM启动参数是否配置了自动生成Heap Dump:-XX:+HeapDumpOnOutOfMemoryError 和 -XX:HeapDumpPath=/path/to/dump/。
- 如果配置了,OOM时会自动在指定路径生成一个 .hprof 文件。这是分析内存问题的最最关键的物证!
-
GC日志:
- 是否开启了GC日志?(如 JDK 8用 -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps;JDK 9+用 -Xlog:gc*:file=gc.log:time,level,tags)。
- GC日志能反映OOM前内存的详细回收情况和趋势。
-
hs_err_pid<PID>.log (JVM致命错误日志):
- OOM有时可能引发更严重的JVM崩溃,此时会生成此文件,包含JVM崩溃时的线程、内存、库等信息。
-
-
紧急“清场”或“扩容”,恢复仓库运作!(核心应急止损措施)
-
目标: 尽快让应用实例恢复服务能力,将业务损失降到最低。
-
行动1:重启“爆仓”的应用实例!
-
对于已发生OOM的实例,重启是快速释放内存、恢复该实例服务能力的最直接有效的方法。
-
⚠️ 重启前,务必抢救“黑匣子” (如果JVM没自动生成或你想在特定时刻抓取):
- 确保已生成的Heap Dump和GC日志被妥善保存,不要被重启过程覆盖或删除。立即从服务器上拷贝出来。
- 如果JVM未配置自动生成Heap Dump,或者你想在OOM发生但进程还未完全死掉时手动抓取,可以尝试使用 jmap -dump:format=b,file=heapdump_<PID>_$(date +%s).hprof <PID> 命令。但这可能会让应用暂时完全卡住,甚至直接崩溃,需谨慎评估风险并快速操作。
-
-
行动2:隔离“问题仓库”!
- 如果某个实例反复OOM,或暂时无法恢复,立即将其从负载均衡器中摘除(或使其在服务发现中下线),避免新的用户请求流向它,保证其他健康实例的服务质量。
-
行动3:紧急“版本回滚”!
- 如果高度怀疑是近期上线的代码(比如引入了内存泄漏或不合理的内存使用)导致的OOM,且有成熟的回滚方案,果断执行代码版本回滚到上一个稳定版本。
-
行动4:临时“扩建仓库”(谨慎调整JVM内存参数)!
- 如果初步判断是真实业务量增长导致内存需求增加(而非泄漏),且服务器物理内存尚有较多余量,可以考虑临时、小幅地调大JVM的 -Xmx (最大堆内存) 和可能的 -XX:MaxMetaspaceSize 参数。
- ⚠️ 注意:这是双刃剑! 如果根源是内存泄漏,盲目增大堆内存只会延迟OOM的发生,并可能导致更长时间的Full GC停顿,反而影响性能。此操作必须非常谨慎,并密切观察调整后的GC情况和内存使用。通常不作为首选,除非有较强把握。
-
行动5 (根据具体OOM类型):
- 如果是 Metaspace OOM,除了考虑调大 -XX:MaxMetaspaceSize,还要排查是否有动态类加载过多、反射滥用等问题。
- 如果是 Unable to create new native thread,需要检查系统线程数限制(ulimit -u)、JVM分配给线程栈的内存(-Xss 是否过大导致总内存需求过高)、以及是否有线程泄漏。
-
-
全员戒备,信息同步!
- 立即将故障情况、影响范围、已采取的应急措施、初步判断等信息同步给团队(开发、运维/SRE)、上级以及其他相关方。保持沟通透明。
“事中应急”的核心:不是让你当场变成内存分析专家,而是要你利用运维手段(重启、隔离、回滚、临时调整参数)快速恢复业务,同时有强烈的意识去保全用于事后分析的关键诊断信息(Heap Dump、GC日志)。
第二部曲:刨根问底!诊断分析与定位真凶 (事中诊断)
当服务通过应急手段暂时稳定下来后(比如重启后暂时没再OOM,或已回滚到稳定版本),现在才是仔细“盘点仓库”,找出为什么会“爆仓”的时候。
-
最重要的物证:分析Heap Dump (堆转储文件)
-
工具: Eclipse Memory Analyzer Tool (MAT) 是首选,功能强大。JVisualVM(JDK自带)也提供简单的堆分析功能。
-
MAT使用步骤概要:
- 打开OOM时生成的 .hprof 文件。
- 查看“Leak Suspects Report”(泄漏疑点报告): MAT会自动分析并给出可能的内存泄漏点、问题描述以及相关对象的引用链,这是非常有价值的起点。
- 查看“Dominator Tree”(支配树): 找出哪些对象及其子对象占据了最大的内存块(Shallow Heap vs. Retained Heap)。重点关注那些Retained Heap大的对象,以及这些大对象的GC Roots引用链,即它们被谁持有而无法被GC回收。
- 查看“Histogram”(直方图): 按类名列出所有对象的实例数量和总大小,可以发现哪些类型的对象实例过多或过大。可以结合正则表达式过滤。
- 对比Heap Dumps (如果获取了多次): 如果在不同时间点(如OOM前和OOM后,或应用运行一段时间后)获取了Heap Dump,对比它们可以帮助识别哪些对象在持续增长,这是定位泄漏的有效手段。
-
分析目标: 找出是内存泄漏(对象用完后没有被释放,仍被某个GC Root可达的路径持续引用),还是确实是业务需要创建了大量对象但内存配置不足,或者是某个大对象集合一次性加载了过多数据。
-
-
关键旁证:分析GC日志
-
GC日志记录了每一次垃圾回收的详细信息,包括回收类型(Young GC, Full GC/Old GC)、回收前后各内存区域(Eden, Survivor, Old Gen, Metaspace)的大小、GC耗时、单次暂停时间(STW)、总暂停时间等。
-
关注点:
- Full GC的频率和耗时: OOM前通常会伴随着频繁且耗时很长的Full GC。如果Full GC后老年代内存回收效果不佳(回收后老年代占用率依然很高),则极有可能是老年代内存泄漏或即将耗尽。
- 老年代(Old Gen)的使用情况: 是否持续增长,步步逼近上限?
- Metaspace的使用情况: 如果是Metaspace OOM,看这块区域是否持续增长。
- Young GC后晋升到老年代的对象大小和速率。
- 是否存在大量的Finalization操作或软/弱/虚引用处理耗时。
-
工具: GCEasy.io (在线分析), GCViewer (本地工具)。
-
-
应用日志中的线索:
- 再次确认OOM的具体类型和发生时的堆栈信息(虽然OOM的堆栈有时不直接指向泄漏源,但可能提供业务操作的上下文)。
- OOM发生前是否有其他异常日志,或者大量特定操作的日志(比如某个接口被频繁调用、某个大查询被执行)。
-
代码审查:“可疑货物”的来源 (结合Heap Dump和GC日志分析结果)
- 集合类使用不当: List, Map, Set 等集合类如果无限制地添加元素而没有清理机制(例如,作为缓存但没有淘汰策略),很容易导致内存泄漏。特别是静态(static)集合,其生命周期与JVM相同,是内存泄漏的重灾区。
- 自定义缓存滥用或未清理: 自己实现的内存缓存如果没有合理的过期策略(如TTL、TTI)、大小限制(如最大条目数、最大内存占用)和淘汰算法(如LRU、LFU),会持续消耗内存。
- 资源未关闭: 数据库连接(Connection)、语句(Statement, PreparedStatement)、结果集(ResultSet)、文件流(InputStream, OutputStream)、网络连接(Socket)等资源使用完毕后没有在 finally 块中或通过try-with-resources语句确保其 close() 方法被调用,可能导致相关对象和底层操作系统资源无法释放。
- 长生命周期对象持有短生命周期对象的引用: 例如,一个单例对象或静态成员变量持有一个用户会话级别的对象引用,导致会话结束后该对象也无法被回收。
- ThreadLocal使用不当: 如果在线程池中复用线程,而ThreadLocal变量在使用后没有及时调用 remove() 方法清理,当线程被归还到池中时,ThreadLocal中存储的对象就可能无法被回收(因为ThreadLocalMap的Entry中的Key是ThreadLocal的弱引用,但Value是强引用,在Key被回收后,如果ThreadLocal本身不被回收,Value可能泄漏)。
- 大量创建临时大对象: 在循环中或高频调用的方法里创建大的byte数组、String对象、或者一次性从数据库加载过多数据到内存中的集合。
- 不当的CGLIB/动态代理使用: 动态生成类过多可能导致Metaspace OOM。
- 第三方库的Bug或不当使用。
-
JVM参数配置检查:
- 再次核对 -Xmx (最大堆内存)、-Xms (初始堆内存)、-XX:MaxMetaspaceSize (最大元空间大小,如果未设置则受限于本地内存)、-Xss (每个线程的栈大小,过大会导致总内存占用过高,过小可能StackOverflowError) 等参数配置是否合理,是否远小于应用的实际内存需求或服务器物理内存。
- GC收集器的选择及相关参数是否适合当前应用场景。
第三部曲:亡羊补牢!彻底修复与长效预防 (事后根治与预防)
找到“爆仓”的根源后,就要进行彻底的“仓库改造”和“管理升级”,防止仓库再次告急。
-
修复“设计缺陷”或“管理漏洞” (代码与配置层面)
- 修复内存泄漏: 根据定位到的泄漏点,修改代码逻辑,确保不再需要的对象能够被GC及时回收(例如,断开不必要的强引用、从集合中移除不再使用的元素、正确关闭资源、在线程池中使用ThreadLocal后及时remove())。
- 优化数据结构和算法: 使用更节省内存的数据结构(如用数组替代某些场景的List,或使用优化的集合库如Eclipse Collections, Trove4j等),优化代码逻辑,减少不必要的对象创建和内存占用。例如,对于大批量数据处理,考虑流式处理或分批处理,而不是一次性加载到内存。
- 合理调整JVM内存参数: 根据应用的实际内存使用模式、GC表现和服务器可用物理资源,科学地、逐步地调整堆大小、元空间大小、新生代和老年代的比例、GC策略及相关参数(如G1的IHOP、MaxGCPauseMillis等)。调整后务必进行充分测试和监控验证。
- 引入弱引用/软引用/虚引用: 对于一些非核心的缓存数据或元数据,如果希望它们在内存紧张时能被GC优先回收,可以考虑使用 SoftReference 或 WeakReference 来包装。
- 对于Metaspace OOM: 除了调整-XX:MaxMetaspaceSize,还要排查是否有过多的类加载(如动态代理、脚本引擎频繁编译)、或者类加载器无法被卸载导致其加载的类也无法卸载。
-
升级“库存管理系统” (监控与告警体系完善)
- 精细化JVM监控: 对JVM的堆内存各区域(Eden, Survivor, Old Gen)使用率、Metaspace使用率、GC次数(Young GC, Full GC)、GC耗时、GC后内存回收量、线程数、类加载数量等关键指标进行持续、细粒度的监控。
- 设置合理的、多梯度的告警阈值: 在内存使用接近危险水位、GC活动异常(如Full GC过于频繁或耗时过长)时能提前预警,而不是等到OOM发生后才知晓。
- Heap Dump和GC日志自动化: 确保生产环境所有JVM实例都配置了OOM时自动生成Heap Dump和持续记录GC日志的参数,并确保这些日志能被集中收集和管理。
-
进行“仓库压力测试”与“容量规划”
- 定期进行压力测试: 模拟线上高峰流量和预期增长后的流量,评估应用在不同负载下的内存表现,尽早发现潜在的OOM风险和内存瓶颈。
- 容量规划: 根据业务增长趋势、用户量增长、数据量增长,合理预估未来的内存需求,提前进行服务器资源和JVM内存配置的规划与扩容。
-
加强“管理员培训”与流程规范 (团队能力与制度建设)
- 经验文档化与共享: 将OOM的排查经验、典型案例、处理流程、分析方法等文档化,进行团队内部分享和培训。
- 提升团队技能: 加强团队成员对Java内存管理(堆、栈、元空间、直接内存)、GC原理(各种收集器特性与适用场景)、内存分析工具(MAT、jstat、jmap等)使用的培训。
- Code Review规范: 在代码审查(Code Review)流程中,将内存使用、资源管理、集合类使用、并发安全等作为重点关注项。
- 上线检查清单: 对于有较大内存分配模式变更或引入新依赖的上线,应有专门的检查点评估其内存影响。
💡 面试小贴士:如何让面试官眼前一亮?
- 思路清晰,逻辑严谨: 严格按照“应急恢复 -> 诊断定位 -> 根治预防”的思路展开,层次分明。
- 突出应急处理的专业性: 强调快速恢复业务和保全诊断信息(尤其是Heap Dump和GC日志)的同等重要性。能说出jmap等手动dump命令及其风险。
- 熟练掌握诊断工具: 清晰阐述如何使用MAT分析Heap Dump(如Leak Suspects, Dominator Tree, Histogram),如何解读GC日志的关键指标。
- 深入理解OOM类型与原因: 不仅知道Java heap space,还能提及Metaspace, GC overhead limit exceeded, Unable to create new native thread等,并能分析其可能原因。
- 展现解决问题的闭环能力: 不仅能定位和修复问题,更能从架构、流程、规范层面提出预防措施,体现Owner意识。
- 关注细节,例如: ThreadLocal泄漏、静态集合的风险、资源未关闭、合理配置JVM参数(不仅仅是-Xmx)。
- 表达自信,有条不紊: 即使是复杂问题,也能清晰、有条理地阐述。
相关文章:
Java应用OOM排查:面试通关“三部曲”心法
开篇点题:OOM——Java应用的“内存爆仓”警报 OOM (OutOfMemoryError) 是啥病?想象一下,你的Java应用程序是一个大仓库,内存就是仓库的存储空间。如果货物(程序运行时创建的对象)越来越多,超出了…...

R语言的专业网站top5推荐
李升伟 以下是学习R语言的五个顶级专业网站推荐,涵盖教程、社区、资源库和最新动态: 1.R项目官网 (r-project.org) R语言的官方网站,提供软件下载、文档、手册和常见问题解答。特别适合初学者和高级用户,是获取R语言核心资源的…...
设计模式系列(03):设计原则(二):DIP、ISP、LoD
本文为设计模式系列第3篇,聚焦依赖倒置、接口隔离、迪米特法则三大设计原则,系统梳理定义、实际业务场景、优缺点、最佳实践与常见误区,适合系统学习与团队协作。 目录 1. 引言2. 依赖倒置原则(DIP)3. 接口隔离原则(ISP)4. 迪米特法则(LoD)5. 常见误区与反例6. 最佳实…...
Java Socket编程完全指南:从基础到实战应用
Socket编程是构建网络应用的基石,Java通过java.net包提供了强大的Socket API。本文将深入解析Java Socket类的核心用法,涵盖TCP/UDP协议实现、多线程通信及性能优化技巧,助您快速掌握网络编程精髓。 一、Socket编程核心概念 1.1 网络通信模型…...

[训练和优化] 3. 模型优化
👋 你好!这里有实用干货与深度分享✨✨ 若有帮助,欢迎: 👍 点赞 | ⭐ 收藏 | 💬 评论 | ➕ 关注 ,解锁更多精彩! 📁 收藏专栏即可第一时间获取最新推送🔔…...
基于FPGA的车速检测系统仿真设计与实现
标题:基于FPGA的车速检测系统仿真设计与实现 内容:1.摘要 本文旨在设计并实现基于FPGA的车速检测系统仿真。随着汽车行业的快速发展,精确的车速检测对于车辆的安全性和性能评估至关重要。本研究采用FPGA作为核心处理单元,结合传感器数据采集与处理技术进…...

无人设备遥控器之无线通讯技术篇
无人设备遥控器的无线通讯技术是确保遥控操作准确、稳定、高效进行的关键。以下是对无人设备遥控器无线通讯技术的详细解析: 一、主要无线通讯技术类型 Wi-Fi通讯技术 原理:基于IEEE 802.11标准,通过无线接入点(AP)…...
Redis(2):Redis + Lua为什么可以实现原子性
Redis 作为一款高性能的键值对存储数据库,与 Lua 脚本相结合,为实现原子性操作提供了强大的解决方案,本文将深入探讨 Redis Lua 实现原子性的相关知识 原子性概念的厘清 在探讨 Redis Lua 的原子性之前,我们需要明确原子性的概念…...

PyTorch LSTM练习案例:股票成交量趋势预测
文章目录 案例介绍源码地址代码实现导入相关库数据获取和处理搭建LSTM模型训练模型测试模型绘制折线图主函数 绘制结果 案例介绍 本例使用长短期记忆网络模型对上海证券交易所工商银行的股票成交量做一个趋势预测,这样可以更好地掌握股票买卖点,从而提高…...

CK3588下安装linuxdeployqt qt6 arm64
参考资料: Linux —— linuxdeployqt源码编译与打包(含出错解决) linux cp指令报错:cp: -r not specified; cp: omitting directory ‘xxx‘(需要加-r递归拷贝) CMake Error at /usr/lib/x86_64…...

木马查杀引擎—关键流程图
记录下近日研究的木马查杀引擎,将关键的实现流程图画下来 PHP AST通道实现 木马查杀调用逻辑 模型训练流程...

二程运输的干散货船路径优化
在二程运输中,干散货船需要将货物从一个港口运输到多个不同的目的地港口。路径优化的目标是在满足货物运输需求、船舶航行限制等条件下,确定船舶的最佳航行路线,以最小化运输成本、运输时间或其他相关的优化目标。 影响因素 港口布局与距离:各个港口之间的地理位置和距离…...

华为数字政府与数字城市售前高级专家认证介绍
华为数字政府与数字城市售前高级专家认证面向华为合作伙伴售前高级解决方案专家、华为数字政府与数字城市行业解决方案经理(VSE)。 通过认证验证的能力 您将了解数字政府、数字城市行业基础知识,了解该领域内的重点场景;将对华…...
在VSCode中接入DeepSeek的指南
本文将介绍三种主流接入方式,涵盖本地模型调用和云端API接入方案。 一、环境准备 1.1 基础要求 VSCode 1.80+Node.js 16.x+Python 3.8+(本地部署场景)已部署的DeepSeek服务(本地或云端)1.2 安装必备插件 # 打开VSCode插件面板(Ctrl+Shift+X) 搜索并安装: - DeepSeek Of…...

【docker】--容器管理
文章目录 容器重启--restart 参数选项及作用**对比 always 和 unless-stopped****如何查看容器的重启策略?** 容器重启 –restart 参数选项及作用 重启策略 no:不重启(默认)。on-failure:失败时重启(可限…...

基于OpenCV的人脸微笑检测实现
文章目录 引言一、技术原理二、代码实现2.1 关键代码解析2.1.1 模型加载2.1.2 图像翻转2.1.3 人脸检测 微笑检测 2.2 显示效果 三、参数调优建议四、总结 引言 在计算机视觉领域,人脸检测和表情识别一直是热门的研究方向。今天我将分享一个使用Python和OpenCV实现…...
使用PEFT库将原始模型与LoRA权重合并
使用PEFT库将原始模型与LoRA权重合并 步骤如下: 基础模型加载:需保持与LoRA训练时相同的模型配置merge_and_unload():该方法会执行权重合并并移除LoRA层保存格式:合并后的模型保存为标准HuggingFace格式,可直接用于推…...

2025-5-15Vue3快速上手
1、setup和选项式API之间的关系 (1)vue2中的data,methods可以与vue3的setup共存 (2)vue2中的data可以用this读取setup中的数据,但是反过来不行,因为setup中的this是undefined (3)不建议vue2和vue3的语法混用…...

【金仓数据库征文】从生产车间到数据中枢:金仓数据库助力MES系统国产化升级之路
目录 前言一、金仓数据库:国产数据库的中坚力量二、制造业MES系统:数据驱动的生产智能MES系统的核心价值MES系统关键模块与数据库的关系1. BOM管理2. 生产工单与订单管理3. 生产排产与资源调度4. 生产报工与实时数据采集 5. 采购与销售管理 三、从MySQL到…...

HTML17:表单初级验证
表单初级验证 常用方式 placeholder 提示信息 <p>名字:<input type"text" name"username" maxlength"8" size"30" placeholder"请输入用户名"></p>required 非空判断 <p>名字:<input type"…...

从卡顿到丝滑:JavaScript性能优化实战秘籍
引言 在当今的 Web 开发领域,JavaScript 作为前端开发的核心语言,其性能表现对网页的加载速度、交互响应以及用户体验有着举足轻重的影响。随着 Web 应用的复杂度不断攀升,功能日益丰富,用户对于网页性能的期望也越来越高。从电商…...
How Sam‘s Club nudge customers into buying more
Here’s how Sam’s Club (or similar warehouse memberships) nudge customers into buying more: It’s a classic psychological strategy rooted in sunk cost fallacy and loss aversion. 1. Prepaid Membership Creates a “Sunk Cost” Once you’ve paid the annual …...

ORB特征点检测算法
角点是图像中灰度变化在两个方向上都比较剧烈的点。与边缘(只有一个方向变化剧烈)或平坦区域(灰度变化很小)不同,角点具有方向性和稳定性。 tips:像素梯度计算 ORB算法流程简述 1.关键点检测(使用FAST…...

快速通关单链表秘籍
1.单链表概念与结构 1.1 概念 链表是一种逻辑结构连续,物理结构不连续的存储结构,数据结构的逻辑顺序是通过链表中的指针链接次序实现。 光看定义有点不好理解,我们举个简单例子! 我们都看过火车吧,我们看到的火车…...

springboot+vue实现在线书店(图书商城)系统
今天教大家如何设计一个图书商城 , 基于目前主流的技术:前端vue,后端springboot。 同时还带来的项目的部署教程。 视频演示 在线书城 图片演示 一. 系统概述 商城是一款比较庞大的系统,需要有商品中心,库存中心,订单…...
C++二项式定理:原理、实现与应用
背景 鉴于复习,问了问清言二项式定理的应用…只好多找些资源…肝要死了… 一、引言 二项式定理是数学中一个基本定理,主要用于展开二项式的幂次。在C编程中,理解并实现二项式定理及其拓展具有重要意义,可以解决组合数学、概率论…...
使用GmSSL v3.1.1实现SM2证书认证
1、首先使用gmssl命令生成根证书、客户端公私钥,然后使用根证书签发客户端证书; 2、然后编写代码完成认证功能,使用根证书验证客户端证书是否由自己签发,然后使用客户端证书验证客户端私钥对随机数的签名是否正确。 第一部分生成根…...
远程实时控制安卓模拟器技术scrcpy
先运行模拟器 ~/Library/Android/sdk/emulator/emulator -avd Medium_Phone_API_25 再检查adb device /Users/xmkjsoft/Downloads/scrcpy-macos-x86_64-v3.2/adb devices 再开始实时获取模拟器画面 /Users/xmkjsoft/Downloads/scrcpy-macos-x86_64-v3.2/scrcpy --video-cod…...

Spring AI(6)——向量存储
向量数据库是一种特殊类型的数据库,在 AI 应用中发挥着至关重要的作用。 在向量数据库中,查询与传统关系型数据库不同。它们执行的是相似性搜索,而非精确匹配。当给定一个向量作为查询时,向量数据库会返回与该查询向量“相似”的…...
Spring Data Elasticsearch 中 ElasticsearchOperations 构建查询条件的详解
Spring Data Elasticsearch 中 ElasticsearchOperations 构建查询条件的详解 前言一、引入依赖二、配置 Elasticsearch三、创建模型类(Entity)四、使用 ElasticsearchOperations 进行 CRUD 操作1. 保存数据(Create)2. 获取数据&am…...