面对突如其来的 GC 问题如何下手解决

news2024/12/29 9:55:42

今天我们主要从一个实战案例入手分析面对突如其来的 GC 问题该如何下手解决。

想要下手解决 GC 问题,我们首先需要掌握下面这三种问题。

  • 如何使用 jstat 命令查看 JVM 的 GC 情况?

  • 面对海量 GC 日志参数,如何快速抓住问题根源?

  • 你不得不掌握的日志分析工具。

工欲善其事,必先利其器。我们前面课时讲到的优化手段,包括代码优化、扩容、参数优化,甚至我们的估算,都需要一些支撑信息加以判断。

对于 JVM 来说,一种情况是 GC 时间过长,会影响用户的体验,这个时候就需要调整某些 JVM 参数、观察日志。

另外一种情况就比较严重了,发生了 OOM,或者操作系统的内存溢出。服务直接宕机,我们要寻找背后的原因。

这时,GC 日志能够帮我们找到问题的根源。本课时,我们就简要介绍一下如何输出这些日志,以及如何使用这些日志的支撑工具解决问题。

GC 日志输出

你可能感受到,最近几年 Java 的版本更新速度是很快的,JVM 的参数配置其实变化也很大。就拿 GC 日志这一块来说,Java 9 几乎是推翻重来。网络上的一些文章,把这些参数写的乱七八糟,根本不能投入生产。如果你碰到不能被识别的参数,先确认一下自己的 Java 版本。

在事故出现的时候,通常并不是那么温柔。你可能在半夜里就能接到报警电话,这是因为很多定时任务都设定在夜深人静的时候执行。

这个时候,再去看 jstat 已经来不及了,我们需要保留现场。这个便是看门狗的工作,看门狗可以通过设置一些 JVM 参数进行配置。

那在实践中,要怎么用呢?请看下面命令行。

Java 8

我们先看一下 JDK8 中的使用。

#\!/bin/sh
LOG\_DIR="/tmp/logs"
JAVA\_OPT\_LOG=" -verbose:gc"
JAVA\_OPT\_LOG="\$\{JAVA\_OPT\_LOG\} -XX:+PrintGCDetails"
JAVA\_OPT\_LOG="\$\{JAVA\_OPT\_LOG\} -XX:+PrintGCDateStamps"
JAVA\_OPT\_LOG="\$\{JAVA\_OPT\_LOG\} -XX:+PrintGCApplicationStoppedTime"
JAVA\_OPT\_LOG="\$\{JAVA\_OPT\_LOG\} -XX:+PrintTenuringDistribution"
JAVA\_OPT\_LOG="\$\{JAVA\_OPT\_LOG\} -Xloggc:\$\{LOG\_DIR\}/gc\_\%p.log"
JAVA\_OPT\_OOM=" -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\$\{LOG\_DIR\} -XX:ErrorFile=\$\{LOG\_DIR\}/hs\_error\_pid\%p.log "
JAVA\_OPT="\$\{JAVA\_OPT\_LOG\} \$\{JAVA\_OPT\_OOM\}"
JAVA\_OPT="\$\{JAVA\_OPT\} -XX:-OmitStackTraceInFastThrow"

合成一行。

\-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps 
-XX:+PrintGCApplicationStoppedTime -XX:+PrintTenuringDistribution 
-Xloggc:/tmp/logs/gc\_\%p.log -XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/tmp/logs -XX:ErrorFile=/tmp/logs/hs\_error\_pid\%p.log 
-XX:-OmitStackTraceInFastThrow

然后我们来解释一下这些参数:

参数

意义

-verbose:gc

打印 GC 日志

PrintGCDetails

打印详细 GC 日志

PrintGCDateStamps

系统时间,更加可读,PrintGCTimeStamps 是 JVM 启动时间

PrintGCApplicationStoppedTime

打印 STW 时间

PrintTenuringDistribution

打印对象年龄分布,对调优 MaxTenuringThreshold 参数帮助很大

loggc

将以上 GC 内容输出到文件中

再来看下 OOM 时的参数:

参数

意义

HeapDumpOnOutOfMemoryError

OOM 时 Dump 信息,非常有用

HeapDumpPath

Dump 文件保存路径

ErrorFile

错误日志存放路径

注意到我们还设置了一个参数 OmitStackTraceInFastThrow,这是 JVM 用来缩简日志输出的。

开启这个参数之后,如果你多次发生了空指针异常,将会打印以下信息。

java.lang.NullPointerException java.lang.NullPointerException java.lang.NullPointerException java.lang.NullPointerException

在实际生产中,这个参数是默认开启的,这样就导致有时候排查问题非常不方便(很多研发对此无能为力),我们这里把它关闭,但这样它会输出所有的异常堆栈,日志会多很多。

Java 13

再看下 JDK 13 中的使用。

从 Java 9 开始,移除了 40 多个 GC 日志相关的参数。具体参见 JEP 158。所以这部分的日志配置有很大的变化。

我们同样看一下它的生成脚本。

#\!/bin/sh
LOG\_DIR="/tmp/logs"
JAVA\_OPT\_LOG=" -verbose:gc"
JAVA\_OPT\_LOG="\$\{JAVA\_OPT\_LOG\} -Xlog:gc,gc+ref=debug,gc+heap=debug,gc+age=trace:file=\$\{LOG\_DIR\}/gc\_\%p.log:tags,uptime,time,level"
JAVA\_OPT\_LOG="\$\{JAVA\_OPT\_LOG\} -Xlog:safepoint:file=\$\{LOG\_DIR\}/safepoint\_\%p.log:tags,uptime,time,level"
JAVA\_OPT\_OOM=" -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\$\{LOG\_DIR\} -XX:ErrorFile=\$\{LOG\_DIR\}/hs\_error\_pid\%p.log "
JAVA\_OPT="\$\{JAVA\_OPT\_LOG\} \$\{JAVA\_OPT\_OOM\}"
JAVA\_OPT="\$\{JAVA\_OPT\} -XX:-OmitStackTraceInFastThrow"
echo \$JAVA\_OPT

合成一行展示。

\-verbose:gc -Xlog:gc,gc+ref=debug,gc+heap=debug,gc+age=trace:file
=/tmp/logs/gc\_\%p.log:tags,uptime,time,level -Xlog:safepoint:file=/tmp
/logs/safepoint\_\%p.log:tags,uptime,time,level -XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/tmp/logs -XX:ErrorFile=/tmp/logs/hs\_error\_pid\%p.log 
-XX:-OmitStackTraceInFastThrow

可以看到 GC 日志的打印方式,已经完全不一样,但是比以前的日志参数规整了许多。

我们除了输出 GC 日志,还输出了 safepoint 的日志。这个日志对我们分析问题也很重要,那什么叫 safepoint 呢?

safepoint 是 JVM 中非常重要的一个概念,指的是可以安全地暂停线程的点。

当发生 GC 时,用户线程必须全部停下来,才可以进行垃圾回收,这个状态我们可以认为 JVM 是安全的(safe),整个堆的状态是稳定的。

如果在 GC 前,有线程迟迟进入不了 safepoint,那么整个 JVM 都在等待这个阻塞的线程,会造成了整体 GC 的时间变长。

所以呢,并不是只有 GC 会挂起 JVM,进入 safepoint 的过程也会。这个概念,如果你有兴趣可以自行深挖一下,一般是不会出问题的。

如果面试官问起你在项目中都使用了哪些打印 GC 日志的参数,上面这些信息肯定是不很好记忆。你需要进行以下总结。比如:

“我一般在项目中输出详细的 GC 日志,并加上可读性强的 GC 日志的时间戳。特别情况下我还会追加一些反映对象晋升情况和堆详细信息的日志,用来排查问题。另外,OOM 时自动 Dump 堆栈,我一般也会进行配置”。

GC 日志的意义

我们首先看一段日志,然后简要看一下各个阶段的意义。

  • 1 表示 GC 发生的时间,一般使用可读的方式打印;

  • 2 表示日志表明是 G1 的“转移暂停: 混合模式”,停顿了约 223ms;

  • 3 表明由 8 个 Worker 线程并行执行,消耗了 214ms;

  • 4 表示 Diff 越小越好,说明每个工作线程的速度都很均匀;

  • 5 表示外部根区扫描,外部根是堆外区。JNI 引用,JVM 系统目录,Classloaders 等;

  • 6 表示更新 RSet 的时间信息;

  • 7 表示该任务主要是对 CSet 中存活对象进行转移(复制);

  • 8 表示花在 GC 之外的工作线程的时间;

  • 9 表示并行阶段的 GC 总时间;

  • 10 表示其他清理活动;

  • 11表示收集结果统计;

  • 12 表示时间花费统计。

可以看到 GC 日志描述了垃圾回收器过程中的几乎每一个阶段。但即使你了解了这些数值的意义,在分析问题时,也会感到吃力,我们一般使用图形化的分析工具进行分析。

尤其注意的是最后一行日志,需要详细描述。可以看到 G C花费的时间,竟然有 3 个数值。这个数值你可能在多个地方见过。如果你手头有 Linux 机器,可以执行以下命令:

time ls /

可以看到一段命令的执行,同样有三种纬度的时间统计。接下来解释一下这三个字段的意思。

  • real 实际花费的时间,指的是从开始到结束所花费的时间。比如进程在等待 I/O 完成,这个阻塞时间也会被计算在内;

  • user 指的是进程在用户态(User Mode)所花费的时间,只统计本进程所使用的时间,注意是指多核;

  • sys 指的是进程在核心态(Kernel Mode)花费的 CPU 时间量,指的是内核中的系统调用所花费的时间,只统计本进程所使用的时间。

在上面的 GC 日志中,real < user + sys,因为我们使用了多核进行垃圾收集,所以实际发生的时间比 (user + sys) 少很多。在多核机器上,这很常见。

[Times: user=1.64 sys=0.00, real=0.23 secs]

下面是一个串行垃圾收集器收集的 GC 时间的示例。由于串行垃圾收集器始终仅使用一个线程,因此实际使用的时间等于用户和系统时间的总和:

[Times: user=0.29 sys=0.00, real=0.29 secs]

那我们统计 GC 以哪个时间为准呢?一般来说,用户只关心系统停顿了多少秒,对实际的影响时间非常感兴趣。至于背后是怎么实现的,是多核还是单核,是用户态还是内核态,它们都不关心。所以我们直接使用 real 字段。

GC日志可视化

肉眼可见的这些日志信息,让人非常头晕,尤其是日志文件特别大的时候。所幸现在有一些在线分析平台,可以帮助我们分析这个过程。下面我们拿常用的 gceasy 来看一下。

以下是一个使用了 G1 垃圾回收器,堆内存为 6GB 的服务,运行 5 天的 GC 日志。

(1)堆信息

我们可以从图中看到堆的使用情况。

(2)关键信息

从图中我们可以看到一些性能的关键信息。

吞吐量:98.6%(一般超过 95% 就 ok 了);

最大延迟:230ms,平均延迟:42.8ms;

延迟要看服务的接受程度,比如 SLA 定义 50ms 返回数据,上面的最大延迟就会有一点问题。本服务接近 99% 的停顿在 100ms 以下,可以说算是非常优秀了。

你在看这些信息的时候,一定要结合宿主服务器的监控去看。比如 GC 发生期间,CPU 会突然出现尖锋,就证明 GC 对 CPU 资源使用的有点多。但多数情况下,如果吞吐量和延迟在可接受的范围内,这些对 CPU 的超额使用是可以忍受的。

(3)交互式图表

可以对有问题的区域进行放大查看,图中表示垃圾回收后的空间释放,可以看到效果是比较好的。

(4)G1 的时间耗时

如图展示了 GC 的每个阶段花费的时间。可以看到平均耗时最长的阶段,就是 Concurrent Mark 阶段,但由于是并发的,影响并不大。随着时间的推移,YoungGC 竟然达到了 136485 次。运行 5 天,光花在 GC 上的时间就有 2 个多小时,还是比较可观的。

(5)其他

如图所示,整个 JVM 创建了 100 多 T 的数据,其中有 2.4TB 被 promoted 到老年代。

另外,还有一些 safepoint 的信息等,你可以自行探索。

那到底什么样的数据才是有问题的呢?gceasy 提供了几个案例。比如下面这个就是停顿时间明显超长的 GC 问题。

下面这个是典型的内存泄漏。

上面这些问题都是非常明显的。但大多数情况下,问题是偶发的。从基本的衡量指标,就能考量到整体的服务水准。如果这些都没有问题,就要看曲线的尖峰。

一般来说,任何不平滑的曲线,都是值得怀疑的,那就需要看一下当时的业务情况具体是什么样子的。是用户请求突增引起的,还是执行了一个批量的定时任务,再或者查询了大批量的数据,这要和一些服务的监控一起看才能定位出根本问题。

只靠 GC 来定位问题是比较困难的,我们只需要知道它有问题就可以了。后面,会介绍更多的支持工具进行问题的排解。

为了方便你调试使用,我在 GitHub 上上传了两个 GC 日志。其中 gc01.tar.gz 就是我们现在正在看的,解压后有 200 多兆;另外一个 gc02.tar.gz 是一个堆空间为 1GB 的日志文件,你也可以下载下来体验一下。

GitHub 地址:

jvm-lagou-res: 拉勾课程资源。https://kaiwu.lagou.com/course/courseInfo.htm?courseId=31#/content

另外,GCViewer 这个工具也是常用的,可以下载到本地,以 jar 包的方式运行。

在一些极端情况下,也可以使用脚本简单过滤一下。比如下面行命令,就是筛选停顿超过 100ms 的 GC 日志和它的行数(G1)。

# grep -n real gc.log | awk -F"=| " '{ if($8>0.1){ print }}' 1975: [Times: user=2.03 sys=0.93, real=0.75 secs] 2915: [Times: user=1.82 sys=0.65, real=0.64 secs] 16492: [Times: user=0.47 sys=0.89, real=0.35 secs] 16627: [Times: user=0.71 sys=0.76, real=0.39 secs] 16801: [Times: user=1.41 sys=0.48, real=0.49 secs] 17045: [Times: user=0.35 sys=1.25, real=0.41 secs]

jstat

上面的可视化工具,必须经历导出、上传、分析三个阶段,这种速度太慢了。有没有可以实时看堆内存的工具?

你可能会第一时间想到 jstat 命令。第一次接触这个命令,我也是很迷惑的,主要是输出的字段太多,不了解什么意义。

但其实了解我们在前几节课时所讲到内存区域划分和堆划分之后,再看这些名词就非常简单了。

我们拿 -gcutil 参数来说明一下。

jstat -gcutil $pid 1000

只需要提供一个 Java 进程的 ID,然后指定间隔时间(毫秒)就 OK 了。

S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 0.00 72.03 0.35 54.12 55.72 11122 16.019 0 0.000 16.019 0.00 0.00 95.39 0.35 54.12 55.72 11123 16.024 0 0.000 16.024 0.00 0.00 25.32 0.35 54.12 55.72 11125 16.025 0 0.000 16.025 0.00 0.00 37.00 0.35 54.12 55.72 11126 16.028 0 0.000 16.028 0.00 0.00 60.35 0.35 54.12 55.72 11127 16.028 0 0.000 16.028

可以看到,E 其实是 Eden 的缩写,S0 对应的是 Surivor0,S1 对应的是 Surivor1,O 代表的是 Old,而 M 代表的是 Metaspace。

YGC 代表的是年轻代的回收次数,YGC T对应的是年轻代的回收耗时。那么 FGC 肯定代表的是 Full GC 的次数。

你在看日志的时候,一定要注意其中的规律。-gcutil 位置的参数可以有很多种。我们最常用的有 gc、gcutil、gccause、gcnew 等,其他的了解一下即可。

  • gc: 显示和 GC 相关的 堆信息

  • gcutil: 显示 垃圾回收信息

  • gccause: 显示垃圾回收 的相关信息(同 -gcutil),同时显示 最后一次 或 当前 正在发生的垃圾回收的 诱因

  • gcnew: 显示 新生代 信息;

  • gccapacity: 显示 各个代 的 容量 以及 使用情况

  • gcmetacapacity: 显示 元空间 metaspace 的大小;

  • gcnewcapacity: 显示 新生代大小 和 使用情况

  • gcold: 显示 老年代 和 永久代 的信息;

  • gcoldcapacity: 显示 老年代 的大小;

  • printcompilation: 输出 JIT 编译 的方法信息;

  • class: 显示 类加载 ClassLoader 的相关信息;

  • compiler: 显示 JIT 编译 的相关信息;

如果 GC 问题特别明显,通过 jstat 可以快速发现。我们在启动命令行中加上参数 -t,可以输出从程序启动到现在的时间。如果 FGC 和启动时间的比值太大,就证明系统的吞吐量比较小,GC 花费的时间太多了。另外,如果老年代在 Full GC 之后,没有明显的下降,那可能内存已经达到了瓶颈,或者有内存泄漏问题。

下面这行命令,就追加了 GC 时间的增量和 GC 时间比率两列。

jstat -gcutil -t 90542 1000 | awk 'BEGIN{pre=0}{if(NR>1) {print 12-pre) "\t" 1 ; pre=$12 } else { print $0 "\tGCT_INC\tRate"} }'   Timestamp         S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    GCT_INC Rate            18.7   0.00 100.00   6.02   1.45  84.81  76.09      1    0.002     0    0.000    0.002 0.002 0.0106952            19.7   0.00 100.00   6.02   1.45  84.81  76.09      1    0.002     0    0.000    0.002 0 0.0101523

GC 日志也会搞鬼

顺便给你介绍一个实际发生的故障。

你知道 ElasticSearch 的速度是非常快的,我们为了压榨它的性能,对磁盘的读写几乎是全速的。它在后台做了很多 Merge 动作,将小块的索引合并成大块的索引。还有 TransLog 等预写动作,都是 I/O 大户。

使用 iostat -x 1 可以看到具体的 I/O 使用状况。

问题是,我们有一套 ES 集群,在访问高峰时,有多个 ES 节点发生了严重的 STW 问题。有的节点竟停顿了足足有 7~8 秒。

[Times: user=0.42 sys=0.03, real=7.62 secs]

从日志可以看到在 GC 时用户态只停顿了 420ms,但真实的停顿时间却有 7.62 秒。

盘点一下资源,唯一超额利用的可能就是 I/O 资源了(%util 保持在 90 以上),GC 可能在等待 I/O。

通过搜索,发现已经有人出现过这个问题,这里直接说原因和结果。

原因就在于,写 GC 日志的 write 动作,是统计在 STW 的时间里的。在我们的场景中,由于 ES 的索引数据,和 GC 日志放在了一个磁盘,GC 时写日志的动作,就和写数据文件的动作产生了资源争用。

解决方式也是比较容易的,把 ES 的日志文件,单独放在一块普通 HDD 磁盘上就可以了。

小结

我们主要介绍了比较重要的 GC 日志,以及怎么输出它,并简要的介绍了一段 G1 日志的意义。对于这些日志的信息,能够帮助我们理解整个 GC 的过程,专门去记忆它投入和产出并不成正比,可以多看下 G1 垃圾回收器原理方面的东西。

接下来我们介绍了几个图形化分析 GC 的工具,这也是现在主流的使用方式,因为动辄几百 MB 的 GC 日志,是无法肉眼分辨的。如果机器的 I/O 问题很突出,就要考虑把 GC 日志移动到单独的磁盘。

我们尤其介绍了在线分析工具 gceasy,你也可以下载 gcviewer 的 jar 包本地体验一下。

最后我们看了一个命令行的 GC 回收工具 jstat,它的格式比较规整,可以重定向到一个日志文件里,后续使用 sed、awk 等工具进行分析。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

保密技术基础--北交大实验靶场2

由于第2、第3章的内部章节较少&#xff0c;所以我将其的体验感受一起写在这篇文章当中。 2.1 保密专用网络知识学习 这一小节也是一节的理论知识学习&#xff0c;学习过后有一个小测试&#xff0c;和第一章一样&#xff0c;学的知识和给的题目可以说是毫无关系。这一节的知识更…

VBA技术资料1-182

MF系列VBA技术资料 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff0c;并结合自己的经验总结了这份MF系列VBA技术综合资料&#xff0c;而且开放源码&#xff08;MF04除外&#xff09;&#xff0c;其中MF01-04属于定…

04_kibana 安装和配置指南

04_kibana 安装和配置指南 概述安装配置可能报错环境变量配置 概述 这个是干啥的呢&#xff1f; 目前我理解就是数据的展示 我们安装的目的是 请求访问ES&#xff0c; 如果没有安装完全可以使用postman代替 不过这个调试的时候有提示比较好&#xff0c; 所以我就安装了 安装…

【射频电路基础】第二章-谐振功率放大器

本书所用版本为:《射频电路基础》第二版&#xff08;赵建勋 邓军 著&#xff09; 网课详情见b站:《射频电路基础&#xff08;高频电子线路&#xff09;》 本书的笔记以书本和手写笔记结合为主。 文章目录 第二章 谐振功率放大器1. 谐振功率放大器的工作原理2. 谐振功率放大器…

Android kotlin开源项目-功能标题目录

目录 一、BRVAH二、开源项目1、RV列表动效&#xff08;标题目录&#xff09;2、拖拽与侧滑&#xff08;标题目录&#xff09;3、数据库&#xff08;标题目录&#xff09;4、树形图(多级菜单)&#xff08;标题目录&#xff09;5、轮播图与头条&#xff08;标题目录&#xff09;6…

蓝桥杯 题库 简单 每日十题 day2

01 卡片 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小蓝有很多数字卡片&#xff0c;每张卡片上都是数字 0 到 9。 小蓝准备用这些卡片来拼一些数&#xff0c;他想从 1 开始拼出正整数&#xff0c;每拼一个&a…

红黑树(思维导图详解版)

目录 资源已上传 实现代码 测试代码 资源已上传 部分图片 实现代码 注意判断是否为红黑树的代码实现&#xff0c;实现代码中红黑树的删除 #pragma once #include<iostream> using namespace std;enum Color_Type {Red,Black };template<class K,class V> str…

【计算机视觉】Vision Transformers算法介绍合集(一)

文章目录 一、Vision Transformer二、Swin Transformer三、Detection Transformer四、Data-efficient Image Transformer五、self-DIstillation with NO labels六、Deformable DETR七、Compact Convolutional Transformers八、NesT九、Pyramid Vision Transformer十、Dense Pre…

什么是MQ消息队列及四大主流MQ的优缺点(个人网站复习搬运)

什么是&#xff2d;&#xff31;消息队列及四大主流&#xff2d;&#xff31;的优缺点 小程序要上一个限时活动模块&#xff0c;需要有延时队列&#xff0c;从网上了解到用RabbitMQ可以解决&#xff0c;就了解了下 MQ 并以此做记录。 一、为什么要用 MQ 核心就是解耦、异步和…

算法笔记—多数相加

首先&#xff0c;我们要引入一个一道题目1. 两数之和 - 力扣&#xff08;LeetCode&#xff09; 两数之和 其实这道题很简单&#xff0c;但是&#xff0c;可以使用内嵌循环来进行遍历&#xff0c;找到符合要求的数据&#xff0c;返回下标即可。 但今天提供另一个方法&#xff…

劳务管理 视频监控 项目版智慧工地管理系统源码

智慧工地管理系统将人工智能技术、传感器技术、虚拟现实技术等更多高新技术嵌入到建筑、机器、人员佩戴的设备、工地出入口大门等各种物体中&#xff0c;广泛互联形成“物联网技术”&#xff0c;再与“互联网技术”融合&#xff0c;完成项目管理利益相关者与项目施工现场的融合…

数据仓库模型设计V2.0

一、数仓建模的意义 数据模型就是数据组织和存储方法&#xff0c;它强调从业务、数据存取和使用角度合理存储数据。只有将数据有序的组织和存储起来之后&#xff0c;数据才能得到高性能、低成本、高效率、高质量的使用。 高性能&#xff1a;良好的数据模型能够帮助我们快速查询…

考研算法47天:01背包

问题描述 算法详细步骤 代码随想录 (programmercarl.com) ac代码 #include <iostream> using namespace std; int bag[1001]; int bagMax[1001]; int bagvalue[1001]; int main(){int n,v;cin>>n>>v;for(int i0;i<n;i){cin>>bag[i]>>bagva…

跨站脚本攻击实验-beef

实验目的 学习XSS工具/手工攻击的原理掌握XSS工具/手工攻击的方法学习防御XSS的方法/原理 实验工具 burpsuite Burp Suite 是用于攻击web 应用程序的集成平台。它包含了许多工具&#xff0c;并为这些工具设计了许多接口。所有的工具都共享一个能处理并显示HTTP 消息&#xff…

电路电子技术2电容电感伏安关系 计算电路中某两端电压

1.计算电流 思路&#xff1a;可以知道R1两端的电压&#xff0c;即U1&#xff0c;计算出流过R1的电流。接下来计算R2两端的电压&#xff0c;即US-U1&#xff0c;进而知道流过R2的电流。根据在节点处的KCL&#xff0c;即可求出I。 2.电容电感伏安关系 电容元件与电感元件的伏安…

购买问界M7大五座(自动驾驶走进我们的生活一)

龙龙在两天前下了问界M7大五座的大定&#xff08;5000元&#xff09;&#xff0c;今天周末陪幺姨、姨爹、龙龙在重庆汽博问界4S店谈完了M7大五座的订购事宜。 早上10点到店后&#xff0c;姨爹在问界M5上完成了他的第一次自动驾驶试驾。小唐先开了一段路示范自驾&#xff0c;在回…

机器学习(16)---聚类(KMeans)

聚类 一、聚类概述1.1 无监督学习与聚类算法1.2 sklearn中的聚类算法 二、 KMeans2.1 基本原理2.2 簇内误差平方和 三、sklearn中的KMeans3.1 所用模块3.2 聚类算法的模型评估指标3.3 轮廓系数3.4 CHI(卡林斯基-哈拉巴斯指数) 四、KMeans做矢量量化4.1 概述4.2 案例 一、聚类概…

第二节:利用VBA代码交换三个单元格的值

【分享成果&#xff0c;随喜正能量】经常在做一件事时&#xff0c;一开始动力很足&#xff0c;可时间久了&#xff0c;就会出现意志力消耗殆尽。流水不腐&#xff0c;户枢不蠹。做一件对自己好的小事&#xff0c;养一个好习惯&#xff0c;慢慢坚持&#xff0c;持续去做&#xf…

[abc复盘] abc319 20230909

[abc复盘] abc319 20230909 总结A - Legendary Players1. 题目描述2. 思路分析3. 代码实现 B - Measure1. 题目描述2. 思路分析3. 代码实现 C - False Hope1. 题目描述2. 思路分析3. 代码实现 D - Minimum Width1. 题目描述2. 思路分析3. 代码实现 E - Bus Stops1. 题目描述2.…

k8s pod概念、分类及策略

目录 一.pod相关概念 &#xff12;.Kubrenetes集群中Pod两种使用方式 &#xff13;.pause容器的Pod中的所有容器共享的资源 &#xff14;.kubernetes中的pause容器主要为每个容器提供功能&#xff1a; &#xff16;.Pod分为两类&#xff1a; 二.Pod容器的分类 1.基础容器…