带你感受一次JVM调优实战
本文分成两部分,先了解理论,然后再进行实战。
理论篇
1.1 调优目标
JVM调优的两大目标是:
提高应用程序的性能和吞吐量: 通过优化JVM的垃圾回收机制、调整线程池大小和优化代码,可以提高应用程序的性能和吞吐量。
减少JVM的内存占用和垃圾回收的次数: JVM的内存占用和垃圾回收对系统性能有很大影响,因此通过调整JVM的内存参数,可以减少内存占用和垃圾回收的次数,从而提高系统的稳定性和可靠性。
1.2 调优策略
- 避免过度分配最大堆内存,除非明确需要超出默认最大堆限制。应该根据应用程序的性能目标选择适当大小的堆内存,以满足吞吐量需求。
- 如果堆增长到最大限制且仍未达到预期的吞吐量目标,则最大堆限制可能过小。此时可以尝试将最大堆大小设置为接近物理内存总量的值,但不会导致系统出现交换。再次运行应用程序,如果仍未达到吞吐量目标,则应该重新考虑性能目标是否合理。
- 如果应用程序可以达到吞吐量目标,但暂停时间过长,则需要考虑选择合适的最大暂停时间目标。选择较大的暂停时间目标可能会导致无法满足吞吐量需求,因此需要在吞吐量和暂停时间之间做出权衡。
- 当垃圾收集器尝试满足各种性能目标时,堆的大小通常会发生波动。即使应用程序已经达到稳定状态,也是如此。因此,在满足吞吐量目标(需要较大堆)和最大暂停时间/最小内存占用目标(需要较小堆)之间需要进行权衡。
1.3 影响GC的因素
总堆大小
在虚拟机初始化时,堆内存的全部空间都被保留下来。可以通过 -Xmx 选项指定堆的最大大小。如果 -Xms 参数指定的值小于 -Xmx 参数指定的值,那么不是所有保留的空间都会立即提交给虚拟机。这些未提交的空间在图中被称为“虚拟空间”。
需要注意的是,虚拟空间并不等同于已经分配的堆内存。老年代和新生代是堆的两个不同部分,它们都可以根据需要增长到虚拟空间的最大限制。
因此,建议根据应用程序的内存需求和性能指标来调整 -Xms 和 -Xmx 参数的值,以充分利用可用的系统内存并达到更好的性能表现。
一些参数是堆的一个部分与另一个部分的比例。例如,参数 -XX:NewRatio
表示老一代与年轻一代的相对大小。
年轻代
在考虑垃圾收集性能时,除了可用内存之外,影响因素的第二个重要因素是年轻代的比例。
较大的年轻代可以减少 minor gc 的频率,但对于有限的堆大小,它也会导致老年代变小,从而增加 major gc 的频率。因此,在选择年轻代大小时,需要考虑应用程序中对象的生命周期分布。
为了取得最佳性能,建议进行一些基准测试来确定最佳的年轻代大小,以确保 minor gc 的频率不会对性能造成太大影响,并且 major gc 的频率也能保持在一个合理的范围内。
年轻代大小选项
默认情况下,年轻代大小由选项 -XX:NewRatio
控制。
比如设置 -XX:NewRatio=3
表示年轻代和年老代的比例为 1:3。换句话说,eden区和survivor区的总大小将是总堆大小的四分之一。
选项 -XX:NewSize
和 -XX:MaxNewSize
限制了年轻代的大小。将这些设置为相同的值可以固定年轻代,就像将 -Xms
和 -Xmx
设置为相同的值可以固定总堆大小一样。这对于以比 -XX:NewRatio
允许的整数倍更细的粒度调整年轻代很有用。
幸存者空间大小
调整幸存者空间的大小可以使用 -XX:SurvivorRatio 选项,但通常并不会对性能产生重大影响。
如果幸存者空间过小,则可能会导致对象直接溢出到老年代;如果幸存者空间过大,则会浪费内存空间。虚拟机会在每次垃圾回收时选择一个阈值数,以确保幸存者空间保持在一定的填充率。这个阈值数可以通过配置日志 -Xlog:gc,age 来查看。
对于观察应用程序中对象的生命周期分布,显示这个阈值和新生代对象的年龄非常有用。因此,建议进行一些基准测试来确定最佳的幸存者空间大小,以确保在减少对象溢出老年代的同时,也不会浪费过多的内存空间。
选择垃圾收集器
除非应用程序有相当严格的暂停时间要求,否则使用JVM默认的收集器。
- 如果应用程序的主要目标是低延迟和高吞吐量,可以考虑使用并行收集器(Parallel)或CMS收集器。
- 如果应用程序的主要目标是低延迟和对暂停时间敏感,可以考虑使用G1收集器。
- 如果应用程序的主要目标是最小化内存占用,并且可以接受更长的暂停时间,则可以考虑使用串行收集器(Serial)或CMS收集器。
- 如果应用程序的工作负载是长时间运行的,则可能需要考虑使用CMS或G1收集器,以便在垃圾回收期间最小化暂停时间。
- 如果应用程序需要处理大量大型对象,则可以考虑使用G1收集器。
- 如果应用程序的主要目标是实现最高的吞吐量,可以尝试使用ZGC或Shenandoah等新型收集器,这些收集器使用了更先进的算法和技术,可以在更高的吞吐量下保持更短的暂停时间。
1.4 一些推荐参数
- 应将
-Xms
与-Xmx
设置为同一值,无论扩展还是缩小空间都会进行Full GC。 -Xmx
需要根据系统的配置来确定,要给操作系统和JVM本身留下一定的剩余空间。 推荐配置系统或容器里可用内存的 70-80% 最好。-Xmn
可以方便指定新生代空间的初始值和最大值。- Xms, -Xmx:在堆大小上放置边界以增加垃圾收集的可预测性。副本服务器中的堆大小受到限制,因此即使 Full GC 也不会触发 SIP 重传。Xms设置起始大小以防止堆扩展引起的暂停。
- XX:+UseG1GC:使用垃圾优先 (G1) 收集器。
- XX:MaxGCPauseMillis:设置最大 GC 暂停时间的目标。这是一个软目标,JVM 将尽最大努力实现它。
- XX:ParallelGCThreads:设置垃圾收集器并行阶段使用的线程数。默认值因运行 JVM 的平台而异。
- XX:ConcGCThreads:并发垃圾收集器将使用的线程数。默认值因运行 JVM 的平台而异。
- XX:InitiatingHeapOccupancyPercent:启动并发 GC 周期的(整个)堆占用百分比。基于整个堆的占用率而不只是其中一代(包括 G1)的占用率触发并发 GC 周期的 GC 使用此选项。值 0 表示“执行恒定的 GC 循环”。默认值为 45。
- -XX:+InitiatingHeapOccupancyPercent(简称 IHOP):G1 内部并行回收循环启动的阈值,默认为 Java Heap 的 45%。这个可以理解为老年代使用大于等于 45% 的时候,JVM 会启动垃圾回收。这个值非常重要,它决定了在什么时间启动老年代的并行回收。
- -XX:MaxGCPauseMills:预期 G1 每次执行 GC 操作的暂停时间,单位是毫秒,默认值是 200 毫秒,G1 会尽量保证控制在这个范围内。
- -XX:G1NewSizePercent (默认:5) Young region 最小值 -XX:G1MaxNewSizePercent (默认: 60) Young region 最大值
○ 正常来说,大部分在 Young 的对象都不会存活很长时间。如果不符合这个规则 (大部分在 Young 的对象都不会存活很长时间),你可能需要调整一下 Young 区域占比。来降低 Young 对象的拷贝时间。
1.5 JVM调优步骤
-
监测JVM性能:使用工具,如JConsole、VisualVM或Java Mission Control来监测JVM的性能,包括内存使用、垃圾收集频率和时间、线程使用等指标。
-
分析数据:收集JVM性能数据后,需要进行分析,识别性能瓶颈和潜在的问题,例如频繁的Full GC或长时间的暂停。
-
优化JVM设置:根据性能数据分析结果和应用程序的特性,可以调整JVM设置来优化性能。例如,增加内存大小、调整垃圾收集器、优化线程数等。
-
优化应用程序代码:除了调整JVM设置,还可以通过优化应用程序代码来提高性能。例如,减少对象的创建、缓存数据、避免使用同步等。
-
测试和验证:进行JVM调优后,需要进行测试和验证,确保调优的结果能够满足性能需求,并且不会引入新的问题或风险。
-
监控和维护:在应用程序运行期间,需要继续监控JVM性能,以便及时发现和解决问题,并进行维护,例如定期清理日志文件、备份数据等。
实战篇
2.1 发现问题
在某一天线上服务的grafna监控突然发出告警,显示服务器的CPU负载产生了异常上升,服务的接口耗时也开始突增,针对这种情况,立刻开始了排查。
2.2 定位问题
查看火焰图
火焰图如何解读可以参考:性能分析利器:火焰图。查看了CPU的火焰图看了一下,发现GC相关的函数占了一半的CPU调用,然后查看了JVM的监控,发现实例出现了频繁的Full GC,此时基本上可以确定是GC导致的问题。
重新部署了一遍,发现还是有问题,说明很可能和代码应该有关系,和部署的机器关系不大。接下来开始定位JVM的具体问题并进行优化。
分析GC日志
在JVM启动的时候添加以下参数,就可以将GC日志打印出来:
-XX:+PrintGCDetails 打印GC日志细节
-XX:+PrintGCTimeStamps 打印GC日志时间
-Xloggc:gc.log 将GC日志输出到指定的磁盘文件上去,这里会把gc.log输出到项目根路径
其中一个日志内容如下:
2022-05-17T11:35:04.163+0800: [GC pause (G1 Evacuation Pause) (young) (to-space exhausted), 1.46786732 secs][Parallel Time: 1205.9 ms, GC Workers: 20][GC Worker Start (ms): Min: 5038821026.8, Avg: 5038821026.9, Max: 5038821027.0, Diff: 0.2][Ext Root Scanning (ms): Min: 0.7, Avg: 1.0, Max: 2.6, Diff: 1.8, Sum: 13.6][Update RS (ms): Min: 12.4, Avg: 13.8, Max: 14.7, Diff: 2.3, Sum: 179.6][Processed Buffers: Min: 71, Avg: 87.8, Max: 106, Diff: 35, Sum: 1141][Scan RS (ms): Min: 0.0, Avg: 0.2, Max: 0.3, Diff: 0.3, Sum: 2.8][Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0][Object Copy (ms): Min: 1094.0, Avg: 1094.5, Max: 1094.7, Diff: 0.7, Sum: 22728.8][Termination (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 1.5][Termination Attempts: Min: 1, Avg: 1.1, Max: 2, Diff: 1, Sum: 14][GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.3][GC Worker Total (ms): Min: 609.6, Avg: 609.7, Max: 609.9, Diff: 0.2, Sum: 7926.6][GC Worker End (ms): Min: 5038821636.6, Avg: 5038821636.6, Max: 5038821636.6, Diff: 0.1][Code Root Fixup: 0.0 ms][Code Root Purge: 0.0 ms][Clear CT: 0.4 ms][Other: 320.7 ms][Evacuation Failure: 315.7 ms][Choose CSet: 0.0 ms][Ref Proc: 0.5 ms][Ref Enq: 0.0 ms][Redirty Cards: 0.5 ms][Humongous Register: 0.1 ms][Humongous Reclaim: 3.5 ms][Free CSet: 0.6 ms][Eden: 2176.0M(2360.0M)->0.0B(1920.0M) Survivors: 96.0M->0.0B Heap: 3764.9M(4096.0M)->1750.9M(4096.0M)][Times: user=6.67 sys=2.00, real=1.53 secs]
另一个日志内容:
通过观察GC日志,发现了两个异常GC的场景,但是这两种场景都出现了to space exhausted的问题。打开谷歌查询了一下具体含义:
- 第一张图显示是因为大对象分配提前触发了young gc
- 另一次是因为eden区中的对象,在一次young gc后存活的对象,因为升级到Survivor区空间不够,进而升级到old区空间也不够而触发的
因此可以初步得出结论:服务的GC出现了问题,具体是因为出现了大量的大对象的分配造成的。在服务中新建了大量的大对象被分配到老年区,导致了老年区空间过度碎片化,而且老年区的垃圾回收只发生在mix gc和full gc,而当触发了young gc的时候,eden区存活下来的对象,升级到old区又没有足够空间用来存放,从而导致 to space exhausted。(补充说明:G1中,新创建的大对象,是直接分配到old区的,不会分配在eden区中)
堆栈分析
现在以及基本能够确认是由于大对象引起的GC问题,导致JVM频繁的被触发FULL GC。接下来需要通过heap dump来确认这个大对象到底是个什么玩意。
使用命令行来下载服务的堆栈dump信息:
jmap -dump:format=b,file=[文件名].hprof [pid]
- [pid]:是指你要分析的服务进程id
- [文件名]:就是dump下来的堆栈文件的名字
- 举个例子:jmap -dump:format=b,file=test1234.hprof 14123
- 可以添加’live’,来只dump存活数据 -> jmap -dump:live,format=b,file=[文件名].hprof [pid]
- 注意在生产环境执行jmap的时候,选择低峰期执行,jmap的时候,会导致你所有的应用暂时停止,停止的时间随着你当前内存越大,而时间越长,一般都是几s-几十s的影响
上图以类的维度做的统计(就是这个类在当前内存中创建的对象占用空间大小),我发现perf打点的这个类,在本服务当前内存中占比最高,且它在之前的图里确实显示产生了大对象,所以现在它成了重大嫌疑犯。
但是嫌疑犯,归嫌疑犯,毕竟没有确凿证据,且因为别的组的服务也引入的perf打点,但是他们的服务确没有问题,所以我没信心说它就是凶手。反而我更加怀疑是我heap dump的时机不对,在我dump堆栈的时候,大对象真凶是不是已经被回收了。(非OOM自动dump,所以自己主动dump的时候,可能出现dump的时机不好,导致找不到原因)
当前服务打印出的gc日志,已经不能够给我提供更多的信息了,于是我想到打印出更多的gc日志,来观察现象。新增启动参数“-XX:+PrintAdaptiveSizePolicy”。
发现大量的concurrent Cycles阶段的原因是:humongous allocation,且发现申请的大对象size 都是4210784byte,和4194329byte,并且每5s就会发生一次这样的大对象分配。到这里,可以肯定造成本次gc问题的,大对象凶手有两个,且都是同时期先后分配的。
解决方案
per团队修改代码:从原来每一次聚合perf打点信息,都新创建一次对象 -> 每一次聚合perf打点信息复用同一个对象(就是首次使用创建一次对象,后面再用一直复用这个空间)
同时临时修改jvm参数,试图解决问题。
调整前的关键jvm参数:Xmx8G -Xms4G -XX:InitiatingHeapOccupancyPercent=50
调整后的关键jvm参数:Xmx8G -Xms8G -XX:InitiatingHeapOccupancyPercent=40 -XX:+UnlockExperimentalVMOptions -XX:G1MaxNewSizePercent=25
Xmx8G -Xms4G -> Xmx8G -Xms8G :锁死内存,不允许内存波动,减少消耗资源。
-XX:InitiatingHeapOccupancyPercent=50 -> 40 : 提前触发并发gc周期
新增-XX:+UnlockExperimentalVMOptions -XX:G1MaxNewSizePercent=25:限制新生区的大小上限不超过内存的25%,这样能尽量保证old区有足够的空间来存储每次young gc后存活的对象。
结论
无论是gc次数,还是gc时间,都很明显得到了极大改善。
相关文章:

带你感受一次JVM调优实战
本文分成两部分,先了解理论,然后再进行实战。 理论篇 1.1 调优目标 JVM调优的两大目标是: 提高应用程序的性能和吞吐量: 通过优化JVM的垃圾回收机制、调整线程池大小和优化代码,可以提高应用程序的性能和吞吐量。…...

ALG和STUN
目录 ALG 应用层网关讲解 Client1使用FTP主动模式建立FTP Client1使用FTP被动模式建立FTP STUN讲解 ALG 应用层网关讲解 用来替换应用层信息 Client1使用FTP主动模式建立FTP 主动模式:服务器收到客户端发来的请求FTP的地址和端口 服务器使用20端口直接向客户端建…...
原生HTML放大镜
该放大区域用背景图片放大 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compat…...

C++——模板
文章目录1 泛型编程2 函数模板2.1 函数模板概念2.2 函数模板格式2.3 函数模板的实例化2.3.1 隐式实例化2.3.1.1 定义2.3.1.2 代码演示2.3.1.3 运行结果2.3.1.4 缺点2.3.2 显式实例化2.3.2.1 格式2.3.2.2 代码演示2.3.2.3 运行结果2.4 模板参数的匹配原则2.4.12.4.22.4.33 类模板…...

Chapter2.1:线性表基础
该系列属于计算机基础系列中的《数据结构基础》子系列,参考书《数据结构考研复习指导》(王道论坛 组编),完整内容请阅读原书。 1.线性表的定义和基本操作 1.1 线性表的定义 线性表是具有相同数据类型的n(n≥0)n(n≥0)n(n≥0)个数据元素的有限序列&…...

Spring源码解析-Spring 循环依赖
Spring源码解析简图: Spring 如何解决循环依赖,⽹上的资料很多,但是感觉写得好的极少,特别是源码解读⽅⾯,我就⾃⼰单独出⼀ 篇,这篇⽂章绝对肝! 文章目录: 一. 基础知识 1.1 什么…...

从零开始学架构——架构设计的目的
软件架构的历史背景 软件架构真正流行是从20世纪90年代开始的,由于在Rational和Microsoft内部的相关活动,软件架构的概念开始越来越流行。 卡内基梅隆高校的玛丽肖(Mary Shaw)和戴维加兰 (David Garlan)对软件架构做了许多讨论,他们在 1994 年的一篇文章…...

Python 异步: 异步生成器(16)
动动发财的小手,点个赞吧! 生成器是 Python 的基本组成部分。生成器是一个至少有一个“yield”表达式的函数。它们是可以暂停和恢复的函数,就像协程一样。 实际上,Python 协程是 Python 生成器的扩展。Asyncio 允许我们开发异步生…...

.net6 web api使用EF Core,根据model类自动生成表
1.安装EF Core和mysql数据库的nuget包 Microsoft.EntityFrameworkCore Pomelo.EntityFrameworkCore.MySql 2.创建models文件夹,在文件夹下创建实体类 public class Users{public int Id { get; set; }[Column(TypeName "varchar(200)"), Required]publ…...

计算机科学导论笔记(五)
目录 七、操作系统 7.1 引言 7.1.1 操纵系统 7.1.2 自举过程 7.2 演化 7.3 组成部分 7.3.1 用户界面 7.3.2 内存管理器 7.3.3 进程管理器 7.3.4 设备管理器 7.3.5 文件管理器 7.4 操作系统 7.4.1 UNIX 7.4.2 Linux 7.4.3 Windows 七、操作系统 7.1 引言 计算机…...

通过命令打Java可执行jar包
文章目录1.背景2.操作步骤2.1. 准备好java源文件2.2 确认java源文件中是否有包名2.3 编译java文件2.4 初步打包2.5 解压jar包,得到MANIFEST.MF文件2.6 修改MANIFEST.MF文件2.7 再次打包3.验证4.打包参数参考5.参考文章1.背景 今天,无意中翻出了N年之前年…...

java基础系列(九) 接口和抽象类
一. 接口 简单的说,接口就是一种被规范的标准,只要符合这个标准都可以通用,接口的表现 在于对行为的抽象. 1.1 创建接口的格式 格式1: public interface 接口名 格式2: interface 接口名 1.2 在JDK1.8之后, 在接口中可以定义实现的方…...

Docker启动问题docker is starting…
环境window 10 家庭最新版直接上官网安装的 Docker DeskTop问题启动应用后setting打开一直转圈圈;主界面一直显示 docker is starting…解决方案3.1 先确定hyper-v是否开启搜hyper-v,点击启动或关闭Windows功能如下,选中Hyper-V服务3.2 进入任务管理期&a…...

Django/Vue实现在线考试系统-03-开发环境搭建-MySQL安装
1.概述 MySQL是一种关系型数据库管理系统,所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型和大型网站的开发都选择 MySQL 作为网站数据库…...

python实现波士顿房价预测
波士顿房价预测 目标 这是一个经典的机器学习回归场景,我们利用Python和numpy来实现神经网络。该数据集统计了房价受到13个特征因素的影响,如图1所示。 对于预测问题,可以根据预测输出的类型是连续的实数值,还是离散值ÿ…...

Pinia不酸,保甜
为什么是Pinia 怎么说呢,其实在过往的大部分项目里面,我并没有引入过状态管理相关的库来维护状态。因为大部分的业务项目相对来说比较独立,哪怕自身功能复杂的时候,可能也仅仅是通过技术栈自身的提供的状态管理能力来处理业务场景…...

uniapp生命周期
uniapp生命周期 uniapp生命周期不同于vue生命周期,uniapp生命周期分为: 应用生命周期 页面生命周期 组件生命周期 应用生命周期(官网) 注意 应用生命周期仅可在App.vue中监听,在其它页面监听无效。 onlaunch里进行页面跳转,如遇白…...

经典卷积模型回顾11—Xception实现图像分类(matlab)
Xception是一种深度卷积神经网络,它采用了分离卷积来实现深度神经网络的高准确性和高效率。Xception的名称来自“extreme inception”,意思是更加极致的Inception网络。 在传统的卷积神经网络中,每个卷积层都有若干个滤波器(即卷…...

移动App性能测试包含哪些内容?App性能测试工具有哪些?
随着互联网高科技的蓬勃发展,移动app的的需求量和供给量都较大。但一款好app的成功上线以及为用户带来高效体验,性能测试起着关键性的作用。性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试࿰…...

AI测试的迷思
近年来,我一直关注AI相关的测试,并积极参与多个全国性测试社区和社群。在这些社区中,我与不同公司和领域的测试专家交流探讨AI测试相关话题,包括业界顶尖公司的专家和国内知名测试学者。我也参加了多个大会,聆听了许多…...

[ 红队知识库 ] 一些常用bat文件集合
🍬 博主介绍 👨🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...

Qt广告机服务器(上位机)
目录功能结构adSever.promain.cpptcp_MSG.h 共用Tcp传输信息adsever.h 服务器adsever.cpp 服务器addate.h 时间处理addate.cpp 时间处理adtcp.h 客户端Socket处理adtcp.cpp 客户端Socket处理client.h 客户端信息类client.cpp 客户端信息类admsglist.h 信息记录模块admsglist.cp…...

SOA架构的理解
1. SOA概述 SOA(Service-Oriented Architecture,面向服务的架构)是一种在计算机环境中设计、开发、部署和管理离散模型的方法。SOA不是一种新鲜事物,它是在企业内部IT系统重复构建以及效率低下的背景下提出的。在SOA模型中&#x…...

如何选择一款数据库?
1主流数据库技术介绍常见的数据库模型主要分为SQL关系型数据库和NoSQL非关系型数据库。其中关系型数据库分为传统关系数据库和大数据数据库,非关系型数据库分为键值存储数据库、列存储数据库、面向文档数据库、图形数据库、时序数据库、搜索引擎存储数据库及其他&am…...

week2
蓝桥2 递归*树的遍历约数之和分形之城并查集亲戚连通块中点的数量*食物链银河英雄传说哈希笨拙的手指模拟散列表单调队列剪裁序列滑动窗口最大子序和KMP周期递归 *树的遍历 中序遍历: 遍历左子树,根节点,右子树 后序遍历:遍历左子树,右子树,根节点 一个二叉树,树中每个…...

JavaScript的学习
一、引言 1.1 JavaScript简介 JavaScript一种解释性脚本语言,是一种动态类型、弱类型、基于原型继承的语言,内置支持类型。它的解释器被称为JavaScript引擎,作为浏览器的一部分,广泛用于客户端的脚本语言,用来给HTML网…...

用gin写简单的crud后端API接口
提要使用gin框架(go的web框架)来创建简单的几个crud接口)使用技术: gin sqlite3 sqlx创建初始工程新建文件夹,创建三个子文件夹分别初始化工程 go mod如果没有.go文件,执行go mod tidy可能报错(warning: "all" matched no packages), 可以先不弄,只初始化模块就行(…...

CF大陆斗C战士(三)
文章目录[C. Good Subarrays](https://codeforces.com/problemset/problem/1398/C)题目大意题目分析code[C. Boboniu and Bit Operations](https://codeforces.com/problemset/problem/1395/C)题目大意题目分析code[C. Rings](https://codeforces.com/problemset/problem/1562/…...

TTS | 语音合成论文概述
综述系列2021_A Survey on Neural Speech Synthesis论文:2106.15561.pdf (arxiv.org)论文从两个方面对神经语音合成领域的发展现状进行了梳理总结(逻辑框架如图1所示):核心模块:分别从文本分析(textanalysi…...

HTML第5天 HTML新标签与特性
新标签与特性文档类型设定前端复习帮手W3Schoool常用新标签datalist标签,与input元素配合,定义选项列表fieldset元素新增input表单文档类型设定 document – HTML: 开发环境输入html:4s – XHTML: 开发环境输入html:xt – HTML5: 开发环境输入html:5 前…...