Java垃圾回收的隐性杀手:过早晋升的识别与优化实战
目录
一、现象与症状
二、过早晋升的成因
(一)Young区(Eden区)配置过小
(二)分配速率过高
(三)晋升年龄阈值(MaxTenuringThreshold)配置不当
三、动态晋升阈值的调整
(一)动态调整机制的原理
(二)HotSpot的compute_tenuring_threshold方法
(三)为什么采用动态调整晋升阈值?
(四)动态调整的实现机制
四、优化策略与实践
(一)优化Young/Eden区大小
(二)优化内存分配速率
(三)调整MaxTenuringThreshold值
(四)综合调优与监控
五、总结与展望
(一)优化目标
(二)优化方法的综合应用
(三)展望
干货分享,感谢您的阅读!
在Java虚拟机(JVM)的垃圾回收机制中,有一个潜在的性能陷阱常常被忽视,那就是“过早晋升”。当对象未能完成其预定的生命周期就被提前晋升到Old区时,垃圾回收的效率和系统性能都会受到严重影响。特别是在高负载或长期运行的应用中,过早晋升现象会导致频繁的Full GC,增加停顿时间,并降低吞吐量。本文将深入探讨过早晋升的成因、症状以及如何通过调整JVM参数和内存分配策略来有效优化垃圾回收,避免这一问题的发生,从而提升系统的稳定性和性能。
历史主要基本文章回顾:
涉猎内容 | 具体链接 |
Java GC 基础知识快速回顾 | Java GC 基础知识快速回顾-CSDN博客 |
垃圾回收基本知识内容 | Java回收垃圾的基本过程与常用算法_java垃圾回收过程-CSDN博客 |
CMS调优和案例分析 | CMS垃圾回收器介绍与优化分析案列整理总结_cms 对老年代的回收做了哪些优化设计-CSDN博客 |
G1调优分析 | Java Hotspot G1 GC的理解总结_java g1-CSDN博客 |
ZGC基础和调优案例分析 | 垃圾回收器ZGC应用分析总结-CSDN博客 |
从ES的JVM配置起步思考JVM常见参数优化 | 从ES的JVM配置起步思考JVM常见参数优化_es jvm配置-CSDN博客 |
深入剖析GC问题:如何有效判断与排查 | 深入剖析GC问题:如何有效判断与排查_排查java堆中大对象触发gc-CSDN博客 |
动态扩缩容引发的JVM堆内存震荡调优指南 | 动态扩缩容引发的JVM堆内存震荡:从原理到实践的GC调优指南 |
显式 GC 的使用:留与去,如何选择? | 显式 GC 的使用:留与去,如何选择? |
高效解决MetaSpace OOM 问题 | 深入剖析 MetaSpace OOM 问题:根因分析与高效解决策略 |
高频面试题汇总 | JVM高频基本面试问题整理_jvm面试题-CSDN博客 |
一、现象与症状
在Java虚拟机的垃圾回收(GC)机制中,“过早晋升”是指对象在尚未达到晋升至Old区的适当生命周期时,便由于不当的内存管理策略被提前晋升到Old区。这一现象多发于使用分代收集器(如G1或CMS)的JVM中,通常与Young区配置不合理或内存分配速率过高等因素密切相关。
Java的垃圾回收机制采用分代收集器模型,堆内存被划分为Young区和Old区。Young区主要用于存储新生对象,而Old区存储存活时间较长的对象。理论上,只有经过多次Young GC且存活的对象,才会晋升到Old区。然而,在“过早晋升”情况下,生命周期较短的对象未经过充分的GC便被错误地晋升,导致多个性能问题。
常见的“过早晋升”症状包括:
- 分配速率与晋升速率接近,对象晋升的年龄较小。
- GC日志中常见类似“Desired survivor size 107347968 bytes, new threshold 1(max 6)”的信息,表明对象在经历一次GC后便晋升到Old区。
- Full GC频繁,且Old区空间的变化异常大。例如,Old区大小为2.1GB,经过一次Full GC后回收至300MB,说明大量短期对象被错误地晋升。
这些现象的影响通常包括:
- 频繁的Young GC:导致吞吐量下降,系统响应性能受损。
- 频繁的Full GC:可能引发较长的停顿时间,增加系统延迟。
- Old区膨胀:引发频繁的Major GC,进一步加重GC负担。
在我以往的工作中,这样的时间一共遇到到两次,一次是为部门新创建的敏感词系统,一次是为商品中台上线商品审核系统,两次上线后在一段时间内都呈现出了上面的情况,当时使用的是CMS垃圾回收器。
二、过早晋升的成因
过早晋升现象的发生,通常与以下几个关键因素密切相关。每个因素都会影响JVM的垃圾回收行为,导致不必要的对象提前晋升到Old区,从而降低GC效率。
(一)Young区(Eden区)配置过小
Young区的大小直接影响着对象从Young区到Old区的晋升过程。JVM的垃圾收集器使用分代收集策略,将堆内存划分为Young区、Old区和Metaspace区。Young区包括Eden区和两个Survivor区,主要用于存储新生的对象。在GC过程中,Eden区的对象如果经过若干轮的GC仍然存活,就会被晋升到Survivor区,并最终晋升到Old区。
若Young区的内存配置过小,Eden区空间不足,短期存活的对象容易在经过较少次数的Young GC后,提前晋升到Survivor区,甚至直接晋升到Old区。这是因为,空间不足的Eden区会使得对象的存活时间过短,未能经历足够次数的GC,直接跳过了应有的回收过程,增加了晋升的风险。
这种不合理的晋升过程加大了Young GC的频率和时间开销。具体来说,Young GC采用了复制算法(Copying),每次GC时,存活对象会被从Eden区复制到Survivor区。复制过程的开销相对较高,因此若Eden区过小,未及时回收的对象增加了复制的负担,导致Young GC的时间延长,进一步影响系统性能,尤其是在频繁触发GC时。
(二)分配速率过高
分配速率指的是应用程序创建新对象的频率。如果分配速率过高,JVM可能无法及时回收不再使用的对象,导致大量短期对象不断晋升至Old区。分配速率的过高可能源自于程序中大量的对象创建操作,如缓存机制、频繁的集合操作、无效的数据预加载等。
在分配速率过高的情况下,JVM无法有效回收Young区的空间,导致对象未能在Young区内完成预定的生命周期。随着大量短期对象不断进入Old区,Old区的空间占用迅速增加,从而导致Full GC频繁发生。过早晋升的一个明显信号是,Young GC的次数增加,同时Old区的空间使用率异常升高。
尤其是在内存分配过载的情况下,JVM的垃圾收集器无法及时进行有效的内存回收,造成Eden区空间的填充速度远超JVM的回收能力。这时候,Young区就会被迫频繁触发GC,甚至导致短期对象提前晋升到Old区,失去分代回收的意义,严重影响系统吞吐量和响应时间。
(三)晋升年龄阈值(MaxTenuringThreshold)配置不当
JVM使用-XX:MaxTenuringThreshold
参数来控制对象的晋升年龄。在每次Young GC中,JVM会根据存活对象的年龄来决定是否将其晋升到Old区。每经过一次GC,存活对象的年龄会增加1,当对象的年龄达到MaxTenuringThreshold
时,它会被晋升到Old区。该阈值的大小直接影响到对象晋升的速度。
-
阈值设置过小:如果
MaxTenuringThreshold
值设置过小,意味着对象会在比较短的时间内就达到晋升到Old区的条件。此时,JVM可能会错误地将短期对象过早地晋升至Old区,导致Old区空间迅速增加,并且无法充分利用Young区进行对象回收。结果是,Full GC变得频繁,Old区的空间得不到有效清理,严重影响GC性能。 -
阈值设置过大:另一方面,如果
MaxTenuringThreshold
设置过大,则对象在Young区内存积累的时间过长,可能导致Survivor区溢出。当Survivor区空间不足时,原本应该晋升到Old区的对象会被迫滞留在Young区,直到溢出发生。一旦发生溢出,JVM就会将所有Eden区和Survivor区的对象直接晋升到Old区,从而失去了Young区作为缓冲区的作用,导致频繁的Full GC,影响系统性能。
因此,MaxTenuringThreshold的合理配置是避免过早晋升的关键。合理的晋升阈值应该基于应用的对象生命周期分布和堆内存的配置,确保长期存活的对象能够顺利晋升到Old区,而短期存活的对象能够有效地被Young GC回收,避免不必要的晋升。
三、动态晋升阈值的调整
为了应对过早晋升带来的问题,HotSpot JVM引入了动态计算晋升阈值的机制。通过动态调整MaxTenuringThreshold
,JVM能够根据实时的堆内存使用情况和Survivor区的占用比例来自动优化晋升阈值。这种动态机制使得JVM能够更加灵活地应对不同应用场景下对象生命周期的变化,从而避免因过早晋升带来的资源浪费和频繁的GC。
(一)动态调整机制的原理
JVM在运行过程中会根据堆内存的实时使用情况,动态计算晋升阈值。具体来说,HotSpot JVM会根据以下两个主要参数来调整MaxTenuringThreshold
:
-
目标Survivor区占用比例:JVM根据该比例来计算Survivor区的理想占用大小,默认值通常为50%。这一比例意味着JVM希望在每次GC之后,Survivor区的空间能够被合理占用,从而为存活对象提供足够的空间,而不至于发生溢出。
-
动态计算晋升阈值:JVM会遍历所有存活对象,根据其年龄来计算对象的累积大小。当累积的对象空间大于目标Survivor区的理想占用大小时,当前年龄
n
即成为新的晋升阈值。如果n
大于MaxTenuringThreshold
的最大限制,则JVM将采用MaxTenuringThreshold
作为实际的晋升阈值。
(二)HotSpot的compute_tenuring_threshold
方法
在HotSpot JVM中,compute_tenuring_threshold
方法负责动态计算和更新晋升阈值。其具体过程如下:
-
目标Survivor区大小的计算:HotSpot会根据当前堆的大小和Survivor区的目标占用比例,计算出理想的Survivor区空间。默认情况下,目标占用比例是50%,即希望Survivor区的存活对象总空间占Survivor区的50%。
-
遍历所有存活对象:JVM遍历Survivor区内所有年龄为
n
的存活对象,并累计它们所占的空间。此时,JVM会根据每个年龄段的对象大小逐步计算累积空间,直到总空间大于目标Survivor区的理想大小为止。 -
阈值调整:当对象年龄累积到某个值
n
,并且累积空间达到目标Survivor区的大小时,JVM会选择n
作为新的晋升阈值。如果该值超过了MaxTenuringThreshold
,则最终晋升阈值被限定为MaxTenuringThreshold
。
(三)为什么采用动态调整晋升阈值?
动态调整晋升阈值的机制能够根据JVM实际运行时的内存情况灵活应对对象生命周期的变化。这样可以有效地避免过早晋升带来的问题,例如:
-
减少不必要的频繁Full GC:通过动态调整晋升阈值,JVM能够根据Survivor区的实际空间使用情况来决定是否晋升对象,避免过早晋升带来的Old区膨胀,从而减少频繁的Full GC。
-
提高内存利用率:通过调整晋升阈值,JVM能够确保对象在Young区内有足够的时间进行回收,只有那些长期存活的对象才会晋升到Old区。这不仅能够节省Old区的空间,还能够确保Young区的回收效率。
-
灵活适应负载变化:由于应用的负载和对象生命周期可能在不同时间发生变化,动态调整晋升阈值能够使JVM根据应用的实际需求自动优化回收策略,从而避免静态阈值配置无法适应负载变化的问题。
动态调整的优势
自适应性能优化:JVM能够根据堆内存使用情况和对象存活率实时调整晋升阈值,优化内存回收策略。这种自适应机制大大提升了JVM的垃圾回收性能,使其能够在不同工作负载下保持较高的效率。
避免资源浪费:动态晋升阈值的调整有效避免了由于静态阈值设置过小或过大的问题,确保资源得到合理利用。例如,避免大量短期对象提前晋升到Old区,造成内存空间浪费和频繁的Major GC。
降低停顿时间:通过合理调整晋升阈值,JVM能够有效减少Old区的垃圾积累,从而避免Full GC的频繁发生,降低了系统停顿时间,提升了响应速度。
(四)动态调整的实现机制
HotSpot中的compute_tenuring_threshold
方法就是实现动态晋升阈值调整的关键。其具体实现依赖于JVM内部的数据结构和算法,这些算法会根据GC周期中Survivor区的实际空间情况,实时更新晋升阈值。通过这一机制,JVM能够在系统运行时不断优化GC的行为,确保垃圾回收过程的高效性。
四、优化策略与实践
针对过早晋升问题,可以采取一系列优化策略来有效缓解并提升垃圾回收的效率。
(一)优化Young/Eden区大小
Young区(尤其是Eden区)的大小直接影响到垃圾回收的效率。通过调整Young区的大小,可以显著减缓过早晋升现象,尤其是在Young区频繁触发GC时。
-
不增加堆内存的情况下优化:在不扩展堆内存的前提下,可以调整Young区和Old区的大小比例。通常,Old区的大小应为活跃对象的2~3倍,剩余的内存可以分配给Young区。这一调整的核心目的是增加Young区的空间,以便有更多的短期对象在Young区内完成回收,从而减少它们提前晋升到Old区的机会。
-
分配比例调整:例如,如果系统的总堆内存为8GB,Old区的大小可以设置为4GB左右,这样剩余的4GB内存就可以分配给Young区。这种调整可以确保Young区有足够的空间来容纳更多的短期对象,从而延长它们在Young区内的生命周期,避免过早晋升。
-
提升Young GC效率:增加Young区的空间后,Young GC的频率通常会降低,因为Young区能容纳更多的对象,减少了频繁GC的发生。这可以显著降低Full GC的发生频率,提高整体吞吐量。
案例分析:
文章一开始提到的敏感词系统和商品审核系统就是一个典型过早晋升优化案例,初始配置为Young 1.2G + Old 2.8G
。通过观察CMS GC日志,发现活跃对象大约为300~400MB,远低于Old区的2.8GB,因此决定调整Old区和Young区的大小。最终调整方案为:
- 将Old区调整至1.5GB,剩余的2.5GB分配给Young区。
- 调整后的结果表明,仅通过调整Young区大小(使用
-Xmn
参数),JVM的性能得到了显著改善:- Young GC次数从每分钟26次降至11次,表明Young区的回收效率大幅提升。
- 每次Young GC的时间并未增加,整体GC时间从1100ms减少至500ms,体现了回收的高效性。
- CMS GC的次数从每40分钟左右一次,减少到每7小时30分钟一次,表明Full GC的频率大幅下降。
该案例表明,合理调整Young/Eden区的大小可以有效减少Young GC的频率,降低Full GC的发生率,从而提升JVM的整体性能。
(二)优化内存分配速率
分配速率(对象创建的频率)过高是导致过早晋升的重要原因之一。如果程序频繁地创建大量短期对象,JVM无法及时回收内存,导致Young区频繁GC并将大量短期对象不合理地晋升到Old区。
-
分析分配速率:可以通过GC日志分析应用程序的内存分配速率,观察内存分配的趋势。特别是
-XX:+PrintGCDetails
和-XX:+PrintGCDateStamps
等GC日志参数,可以帮助开发人员了解GC发生的频率和内存使用情况,判断是否存在分配速率过高的问题。 -
减少不必要的对象创建:优化代码逻辑,避免在高频繁调用的业务流程中创建大量短期对象。尤其是在循环中或递归调用中,尽量重用对象,避免每次调用时都创建新的对象。例如,可以使用对象池技术来复用对象,减少内存分配的压力。
-
优化数据结构和算法:选择合适的数据结构和算法也有助于减少不必要的内存分配。对于需要频繁操作的集合类(如
List
、Map
等),可以预先设置适当的初始容量,以避免动态扩容导致的额外内存分配。 -
监控分配速率:对于高内存负载的应用,定期检查内存分配速率,并对内存使用量进行监控,确保分配速率不会因为某些业务场景异常而过高。
(三)调整MaxTenuringThreshold
值
JVM通过-XX:MaxTenuringThreshold
来控制对象的晋升年龄。每次Young GC后,存活的对象会根据其年龄不断增加,一旦达到MaxTenuringThreshold
,对象就会晋升到Old区。
-
阈值配置的重要性:
MaxTenuringThreshold
的合理设置非常重要。如果该值设置得过小,可能会导致短期对象过早晋升到Old区,浪费Old区空间,增加Full GC的频率。如果阈值设置过大,则会导致对象在Survivor区滞留过久,直到Survivor区溢出,进而失去合理的晋升机制。 -
动态调整阈值:为了避免过早晋升,可以适当增大
MaxTenuringThreshold
值,使对象能够根据其实际存活时间灵活晋升。具体的调整幅度需要根据实际应用场景进行实验,建议通过GC日志查看对象在Young区的生命周期,确保短期对象不会被过早晋升。 -
具体的调整建议:一般情况下,
MaxTenuringThreshold
的默认值是15。若系统发现过早晋升现象明显,建议逐步增加MaxTenuringThreshold
的值(例如,尝试设置为20或更高),这样可以让短期对象多经历几轮Young GC,确保只有存活较长时间的对象才会被晋升到Old区。 -
与动态晋升阈值结合使用:可以结合HotSpot JVM的动态晋升阈值机制,动态调整
MaxTenuringThreshold
值,避免人为设定静态值导致的优化效果不佳。动态计算晋升阈值能够根据Survivor区的空间使用情况和对象存活时间,灵活地调整晋升策略。
(四)综合调优与监控
除了上述具体的调整策略,系统的性能监控和综合调优也是非常重要的。
-
综合内存调优:通过综合调整Young/Eden区大小、
MaxTenuringThreshold
值以及优化分配速率,可以构建一个合理的垃圾回收策略,避免过早晋升导致的资源浪费和频繁的GC。 -
监控GC日志与系统性能:通过定期监控GC日志和系统性能(如GC停顿时间、吞吐量等),可以及时发现问题并调整优化策略。尤其是通过
-XX:+PrintGCDetails
和-XX:+PrintGCDateStamps
等GC日志选项,分析GC的发生频率、堆内存使用情况和对象晋升情况,帮助开发人员精确定位过早晋升问题。 -
性能测试与回归:在进行优化后,建议通过性能测试工具(如JMH)进行回归测试,验证优化策略是否有效。通过多次迭代和优化,逐步提升系统的GC效率和整体性能。
通过合理优化Young/Eden区的大小、调整分配速率、配置MaxTenuringThreshold
,以及综合应用动态调整机制,可以有效避免过早晋升问题。优化GC性能不仅需要调整JVM参数,还需要通过代码优化和内存管理来实现系统级的性能提升。通过持续的监控和优化,能够实现更高效的垃圾回收机制,提升系统的稳定性和响应速度。
五、总结与展望
过早晋升是JVM垃圾回收中的一个潜在问题,虽然在短期内可能不容易察觉,但随着时间的推移,其对系统性能的影响将逐渐显现。尤其是在高负载或长期运行的应用中,过早晋升会导致频繁的Full GC + 增加停顿时间 + 吞吐量下降,及时识别并优化过早晋升问题,是确保应用程序高效运行、提高系统性能的关键,总结来看:
(一)优化目标
针对过早晋升问题,优化的目标是:
- 减少Young GC频率:通过增加Young区的空间,让更多短期对象在Young区内回收,从而减少频繁的Young GC,并延缓对象的晋升。
- 减少Full GC频率:通过合理调整Old区的大小和晋升阈值,避免大量对象过早晋升,减少Old区的垃圾积累,降低Full GC的频率。
- 提高回收效率:优化对象的晋升策略,让对象在适当的阶段晋升至Old区,确保垃圾回收过程中的资源利用最大化,同时保持较低的停顿时间。
(二)优化方法的综合应用
通过调整Young区大小、优化内存分配策略、合理设置MaxTenuringThreshold,JVM能够更好地适应不同负载下的垃圾回收需求,优化资源的使用。具体方法包括:
- 合理分配堆内存:在总内存不变的情况下,适当调整Young区和Old区的大小比例,确保Young区有足够的空间容纳短期对象,同时避免Old区空间的过度膨胀。
- 优化对象分配速率:通过分析应用程序的内存分配模式,减少不必要的对象创建,降低内存分配速率,从根本上减轻GC压力。
- 灵活调整晋升阈值:根据对象的实际存活时间动态调整晋升阈值,确保对象在适当的时间晋升到Old区,避免过早晋升导致的内存浪费和Full GC。
这些优化措施综合使用后,不仅能够显著改善GC性能,还能够提高系统的吞吐量和响应时间,保证系统在高负载情况下的稳定性和高效性。
(三)展望
尽管通过调整JVM参数和优化内存管理可以有效缓解过早晋升问题,但随着应用程序规模的增大和负载的多变,JVM垃圾回收的优化仍然是一个持续的过程。未来的优化方向可以从以下几个方面着手:
-
智能化GC策略:随着JVM技术的不断发展,越来越多的智能化垃圾收集器(如G1、ZGC、Shenandoah)应运而生,它们能够根据应用程序的内存使用模式动态优化垃圾回收策略。未来,GC的优化将更加智能化,能够自动根据负载的变化调整回收策略,减少人为干预。
-
更精细的内存管理:随着多核和分布式环境的普及,JVM可能需要在更大规模的内存管理中提供更细粒度的控制。例如,结合内存隔离技术和垃圾回收优化策略,能够在分布式系统中更高效地进行内存回收,避免资源冲突和不必要的GC操作。
-
持续优化JVM参数调优工具:通过更加智能化的工具和监控系统,能够实时监测JVM的内存和GC状况,提供自动化的调优建议,帮助开发人员及时发现和解决过早晋升等问题。
总之,过早晋升是JVM垃圾回收中的一个复杂问题,虽然其影响可能在短期内不明显,但长期来看,它对系统性能的影响是显著的。通过综合调优和优化,可以有效避免过早晋升问题,提升系统的整体性能。随着JVM技术和优化工具的不断发展,未来我们可以期待更加智能、高效的垃圾回收机制,进一步提升Java应用的性能和稳定性。
相关文章:
Java垃圾回收的隐性杀手:过早晋升的识别与优化实战
目录 一、现象与症状 二、过早晋升的成因 (一)Young区(Eden区)配置过小 (二)分配速率过高 (三)晋升年龄阈值(MaxTenuringThreshold)配置不当 三、动态晋…...
2noise团队开源ChatTTS,支持多语言、流式合成、语音的情感、停顿和语调控制
简介 ChatTTS 是一个开源的文本转语音(Text-to-Speech, TTS)项目,由 2noise 团队开发,专门为对话场景设计。它在 GitHub 上广受欢迎,因其自然流畅的语音合成能力和多功能性而备受关注。 项目背景 目标:设计…...
企业级防火墙与NAT网关配置
实训背景 某公司需部署一台Linux网关服务器,要求实现以下功能: 基础防火墙:仅允许SSH(22)、HTTP(80)、HTTPS(443)入站,拒绝其他所有流量。共享上网…...
AI数据分析的正道是AI+BI,而不是ChatBI
一、AI大模型在数据分析中的应用现状与局限 当前用户直接上传PDF、Excel等原始数据至AI大模型进行自动分析的趋势显著,但其技术成熟度与落地效果仍需审慎评估。 1.主流AI大模型的数据分析能力对比 GPT-4/Claude 3系列:在通用数据分析任务中表现突出&a…...
C++设计模式优化实战:提升项目性能与效率
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle…...
G1学习打卡
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 import argparse import os import numpy as np import torchvision.transforms as transforms from torchvision.utils import save_image from torch.utils.…...
8.2 对话框2
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的 8.2.3 FolderBrowserDialog(文件夹对话框) 组件 FolderBrowserDialog组件,用于选择文件夹 Folder…...
Java中的列表(List):操作与实现详解
引言 列表(List)是Java集合框架中最基础且使用最频繁的线性数据结构。它允许有序存储元素,支持重复值和快速访问。本文将深入探讨Java列表的核心操作方法,并剖析两种经典实现类(ArrayList和LinkedList)的底…...
在kotlin的安卓项目中使用dagger
在 Kotlin 的 Android 项目中使用 Dagger(特别是 Dagger Hilt,官方推荐的简化版)进行依赖注入(DI)可以大幅提升代码的可测试性和模块化程度。 1. 配置 Dagger Hilt 1.1 添加依赖 在 bu…...
MongoDB常见面试题总结(上)
MongoDB 基础 MongoDB 是什么? MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂…...
leetcode6.Z字形变换
题目说是z字形变化,但其实模拟更像n字形变化,找到字符下标规律就逐个拼接就能得到答案 class Solution {public String convert(String s, int numRows) {if(numRows1)return s;StringBuilder stringBuilder new StringBuilder();for (int i 0; i <…...
VSCode中选择Anaconda的Python环境
1、安装Anaconda 2、安装VSCode 一、创建创建新的 Conda 环境 conda create --name myenv python3.8 conda activate myenv 二、在 VSCode 中配置 Conda 环境 1、打开 VSCode,安装 Python 插件。 2、按 CtrlShiftP 打开命令面板,输入并选择 Pytho…...
【基于规则】基于距离的相似性度量
基于点:设时两条序曲线分别为X,Y,在曲线上选取点Xx和Yy,计算点之间的距离,用来度量两条曲线的相似性。这类算法的精确度取决于选点的规则,以及距离的计算方式 欧几里得距离:不允许时间偏移,直接计算两个时序数据点之间的距离,适用于长度相同的序列 dtw:优化了选点的方…...
Python 序列构成的数组(当列表不是首选时)
当列表不是首选时 虽然列表既灵活又简单,但面对各类需求时,我们可能会有更好的选 择。比如,要存放 1000 万个浮点数的话,数组(array)的效率要高 得多,因为数组在背后存的并不是 float 对象&…...
LeetCode零钱兑换(动态规划)
题目描述 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无…...
vscode+wsl 运行编译 c++
linux 的 windows 子系统(wsl)是 windows 的一项功能,可以安装 Linux 的发行版,例如(Ubuntu,Kali,Arch Linux)等,从而可以直接在 windows 下使用 Linux 应用程序…...
C++学习之libevent ②
目录 1.连接服务器函数bufferevent_socket_connect() 2.bufferevent缓冲区的读写函数bufferevent_write() bufferevent_read() 3.给bufferevent设置回调函数bufferevent_setcb() 4.bufferevent回调函数的函数原型 5.基于bufferevent的套接字客户端处…...
彩色路径 第32次CCF-CSP计算机软件能力认证
应该用dp做的但是我太懒懒得看题解了 留到考试的时候看 超时20分代码: #include<bits/stdc.h> using namespace std; int N, M, L, K; struct Edge {int to, length;Edge(int to, int length) :to(to), length(length) {} }; vector<int> color;//颜色…...
第1章 绪论
自1946年,第一台计算机问世以来,计算机产业飞速发展。为了编写出一个好得程序,必须分析待处理的对象的特征以及各处理对象之间存在的关系。这就是数据结构这门学科形成和发展的背景。 1.1什么是数据结构 数据结构是计算机科学中组织和存储数…...
SpringCloud微服务(一)Eureka+Nacos
一、认识 微服务技术对比: SpringCloud: 版本匹配: 二、服务拆分以及远程调用 消费者与提供者: Eureka: 搭建EurekaServer: Ribbon负载均衡: 实现原理: IRule:规则接口…...
Python 字典和集合(子类化UserDict)
本章内容的大纲如下: 常见的字典方法 如何处理查找不到的键 标准库中 dict 类型的变种set 和 frozenset 类型 散列表的工作原理 散列表带来的潜在影响(什么样的数据类型可作为键、不可预知的 顺序,等等) 子类化UserDict 就创造自…...
时区转换工具+PWA离线网页
时区转换工具PWA离线网页 一、时区转换工具对比 工具说明Date原生 JS API,有限的时区支持,无法指定时区,仅使用本地时区。Intl.DateTimeFormat原生格式化显示,可指定时区,但不能修改时区逻辑。luxon强烈推荐…...
Hadoop序列化与反序列化具体实践
首先创建两个类 两个类的代码 Student类: import org.apache.hadoop.io.Writable;import java.io.DataInput; import java.io.DataOutput; import java.io.IOException;public class Student implements Writable {public Student(String name, int age) {this.n…...
Github AI开发者生态最新动态今日速览(20250408)
以下是截至2025年4月8日的GitHub AI开发者生态最新动态速览,结合技术更新、工具发布及行业趋势: 1. GitHub Copilot 重大升级与生态扩展 Agent Mode全量发布:Copilot在VS Code中启用Agent模式,可自主完成多文件代码重构、测试驱动…...
通过扣子平台将数据写入飞书多维表格
目录 1.1 创建飞书开放平台应用 1.2 创建飞书多维表格 1.3 创建扣子平台插件 1.1 创建飞书开放平台应用 1.1.1 打开地址:飞书开放平台,点击创建应用 注:商店应用需要申请ISV资质,填写企业主体信息,个人的话&#x…...
WEB安全--内网渗透--Kerberos之AS_REQAS_REP
一、前言 之前的文章提到过,在内网的域环境中,服务器之间默认使用的是Kerberos协议。 光了解NTLM协议是远远不够的,为了内网渗透,我后面将详细介绍Kerberos协议的原理以及漏洞的利用。 二、Kerberos协议 Kerberos是一种网络身份…...
【Hadoop入门】Hadoop生态之MapReduce简介
1 MapReduce核心原理 MapReduce是一种分布式计算框架,专为处理大规模数据集设计。其核心理念是将复杂计算任务分解为两个核心阶段: Map阶段:将输入数据分割为独立片段,并行处理生成中间键值对Reduce阶段:对Map阶段输出…...
使用Scrapy编写图像下载程序示例
最近闲来无事想要用Scrapy库来编写一个图像下载程序。首先,我得回忆一下Scrapy的基本结构。Scrapy是一个强大的爬虫框架,适合用来抓取网页数据,包括图片。不过,用户可能不太熟悉Scrapy的具体用法,特别是图片下载的部分…...
Linux/树莓派网络配置、远程登录与图形界面访问实验
一.准备工作 1.修改网络适配器(选择本机网卡) 2.创建一个新的用户。 3.使用新用户登录,使用ip a指令查看IP(现代 Linux 发行版(如 Ubuntu、Debian、CentOS、Fedora 等))。 通过sudo arp-sca…...
01-Redis-基础
1 redis诞生历程 redis的作者笔名叫做antirez,2008年的时候他做了一个记录网站访问情况的系统,比如每天有多少个用户,多少个页面被浏览,访客的IP、操作系统、浏览器、使用的搜索关键词等等(跟百度统计、CNZZ功能一样)。最开始存储…...
MCP-Playwright: 赋予AI模型操控浏览器的能力
在人工智能快速发展的时代,我们一直在寻找让AI与现实世界更好地交互的方式。今天我想向大家介绍一个强大的开源项目:MCP-Playwright,它正在改变AI模型与Web环境交互的方式。 源码地址:https://github.com/executeautomation/mcp-…...
Scala集合计算高级函数及案例
一、说明 1.过滤:遍历集合,获取满足指定条件的元素组成新集合 2.转化 / 映射(map):将集合中的每个元素映射到某一个函数 List(1, 2, 3, 4, 5, 6, 7, 8, 9)中每个元素加 1,得到List(2, 3, 4, 5, 6, 7, 8,…...
如何测试一个API接口?从原理到实践详解
在微服务架构和前后端分离的现代软件开发中,API接口是系统的“血管”,承担着数据传输与逻辑处理的核心功能。本文将用通俗的语言,结合实例,系统讲解API接口测试的原理、方法及工具,助你掌握这一关键技能。 目录 …...
弹簧质点系统(C++实现)
本文实现一个简单的物理算法:弹簧质点系统(Mass-Spring System)。这是一个经典的物理模拟算法,常用于模拟弹性物体(如布料、弹簧等)的行为。我们将使用C来实现这个算法,并结合链表数据结构来管理…...
java设计模式-代理模式
代理模式(proxy) 基本介绍 1、代理模式:为一个对象提供一个替身,一控制对这个对象的访问。即通过代理对象访问目标对象。这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,及扩展目标对象的功能。 2、被…...
【比赛编排软件的设计与实现】
有个朋友想要一个比赛编排软件,闲来无事,花几个晚上的时间帮忙编写了一下,主要本人也比较喜欢看NBA,想尝试实现类似的功能。最终实现功能展示如下: 】Reactor
核心代码 Epoller.hpp #pragma once#include "nocopy.hpp" #include <cerrno> #include <sys/epoll.h> #include <unistd.h> #include <string.h> #include "Log.hpp"class Epoller : public nocopy //类Epoller继承自nocopy类&a…...
山东大学计算机网络第五章习题解析
参考教材:计算机网络:自顶向下方法:原书第 8 版 / (美)詹姆斯F. 库罗斯(James F. Kurose),(美)基恩W. 罗斯(Keith W. Rose)著…...
openexr-2.3.0-windows编译
本文操作按照《c&c开源库编译指南》中内容规范编写,编译环境配置、工具下载、目录规划,及更多其他开源库编译方法请参考该文章。 c&c开源库编译指南:https://blog.csdn.net/binary0006/article/details/144086155 本文章中的源代码已…...
【NLP 面经 8】
目录 一、文本生成任务 模型架构方面 训练数据方面 生成策略方面 二、命名实体识别任务NER 模型架构方面 特征工程方面 训练优化方面 三、情感分析任务 模型架构方面 训练数据方面 超参数调整方面 四、计算余弦相似度并添加符合条件结果 提示: 思路与算法 任由深渊的…...
Qt项目——记事本
目录 前言工程文档一、功能介绍二、界面预览三、UI设计师工具四、给三个按钮设置贴图五、信号与槽六、实现文件打开功能代码实现代码实现 七、实现文件保存代码内容 八、实现文件关闭代码实现 九、显示高亮和行列位置代码实现 十、实现快捷功能代码实现 总结 前言 这个项目就是…...
WHAT - React 惰性初始化
目录 在 React 中如何使用惰性初始化示例:常规初始化 vs. 惰性初始化1. 常规初始化2. 惰性初始化 为什么使用惰性初始化示例:从 localStorage 获取值并使用惰性初始化总结 在 React 中,惰性初始化(Lazy Initialization)…...
HOW - 如何测试 React 代码
目录 一、使用 React 测试库:testing-library/react二、使用测试演练场:testing-playground.com三、使用 Cypress 或 Playwright 进行端到端测试四、使用 MSW 在测试中模拟网络请求 一、使用 React 测试库:testing-library/react testing-li…...
React 条件渲染
开发环境:Reacttsantd 通常你的组件会需要根据不同的情况显示不同的内容。在 React 中,你可以通过使用 JavaScript 的 if 语句、&& 和 ? : 运算符来选择性地渲染 JSX。 例子 我们在满足 isPacked{true} 条件的物品清单旁加上一个勾选符号✔。…...
使用 Canal 实现 MySQL 与 ES 数据同步的技术实践
前言 本文将详细讲解如何使用阿里的 Canal 工具,实现 MySQL 向 ES(Elasticsearch)的数据同步。 数据同步有多种方式,双写同步数据方式因性能慢、存在分布式事务及数据一致性问题、业务耦合度高且难以扩展,不适合采用…...
《实战AI智能体》什么是 Scrum 项目管理及为什么需要它
Scrum 项目管理是一种敏捷项目管理方法,强调团队合作、迭代开发和客户参与。它的核心概念包括 Scrum 团队、产品待办事项列表、Sprint、每日站立会议、Sprint 回顾会议等。Scrum 团队由产品负责人、Scrum 主管和开发团队组成,他们共同负责项目的规划、执行和交付: 产品待办事…...
智能硬件开发革命:低代码平台+物联网
物联网和低代码开发 初识物联网 物联网的概念 20 世纪末,随着计算机网络和通信技术的兴起,互联网开始走进并融入人们的生活。传统互联网通常以人作为主体,数据的产生和传输都在人的控制下进行,数据的应用结果也在具体的人身上得…...
「合诚」携手企企通共建新材料和健康产业采购数智化新生态
在科技革命与产业变革深度融合的时代背景下,新材料与健康产业正迎来数字化、智能化的快速发展。 技术突破与消费升级的双重驱动,推动着行业不断创新,同时也对企业的供应链管理提出了更高要求。 1、合诚:聚焦新材料与健康产业&am…...