日志搞不定?手把手教你如何使用Log4j2

系列文章目录

从零开始,手把手教你搭建Spring Boot后台工程并说明
Spring框架与SpringBoot的关联与区别
SpringBean生成流程详解 —— 由浅入深(附超精细流程图)
Spring监听器用法与原理详解
Spring事务畅谈 —— 由浅入深彻底弄懂 @Transactional注解
面试热点详解 ——BeanFactory 和 FactoryBean 的关联与区别
忽视日志吃大亏,手把手教你学习Spring Boot日志



在这里插入图片描述
上一次我们介绍了Springboot 下的几种常用日志插件,今天我们就专注讲解其中一个最年轻的日志插件,即Log4j2。Log4j2目前应用非常广泛,各方面较之前辈Log4j 都有不小的提升,不过要想利用好他,还得经过一定的学习,尤其是搞清楚它的种种配置,下面就让我们开始今天的进阶之旅。

📕作者简介:战斧,从事金融IT行业,有着多年一线开发、架构经验;爱好广泛,乐于分享,致力于创作更多高质量内容
📗本文收录于 Spring全家桶 专栏,有需要者,可直接订阅专栏实时获取更新
📘高质量专栏 云原生、RabbitMQ、Spring全家桶 等仍在更新,欢迎指导
📙Zookeeper Redis kafka docker netty等诸多框架,以及架构与分布式专题即将上线,敬请期待


一、引入依赖

我们可以使用以下依赖为我们项目引入Log4j2框架

<!--Log4j2自带的日志门面-->
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.13.3</version>
</dependency>
<!--Log4j2具体的日志实现-->
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.13.3</version>
</dependency>

当然,像上期所说,我更建议直接使用以下log4j-slf4j-impl

<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.13.3</version>
</dependency>

该包包含Log4j2的实现,也能对接SLF4J,更适合在项目中应用。
在这里插入图片描述

二、配置文件示例

我们看如下一份配置文件:log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG" monitorInterval="30"><!-- 输出格式 --><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} - [%t] %-5level %logger{36} - %msg%n"/><Appenders><!-- 控制台输出 --><Console name="Console" target="SYSTEM_OUT"><!-- 过滤器 --><ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/><!-- 缓冲bufferSize,默认值为256,可调整至1-256之间 --><Buffered mode="ONCE" bufferSize="256"/></Console><!-- 文件输出 --><RollingFile name="RollingFile" fileName="/path/to/logs/test.log" filePattern="/path/to/logs/$${date:yyyy-MM}/test-%d{yyyy-MM-dd}-%i.log"><ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/><!-- 输出格式 --><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/><!-- 触发策略 --><Policies><!-- 按时间滚动 --><TimeBasedTriggeringPolicy/><!-- 按文件大小滚动,这里设置10MB --><SizeBasedTriggeringPolicy size="10MB"/></Policies><!-- 滚动策略 --><DefaultRolloverStrategy max="10"/></RollingFile></Appenders><Loggers><!-- 默认日志 --><Root level="INFO"><AppenderRef ref="Console"/><AppenderRef ref="RollingFile"/></Root><!-- 指定包名的日志 --><Logger name="com.example" level="DEBUG" additivity="false"><AppenderRef ref="Console"/><AppenderRef ref="RollingFile"/></Logger></Loggers>
</Configuration>

三、PatternLayout

PatternLayout是一种日志输出格式,用于设置日志输出的布局格式。该格式使用一系列特定的占位符,每个占位符都代表一种日志信息,例如输出日志事件的时间、线程名、日志级别、日志内容等

  • %d:输出日志事件的时间戳
  • %t:输出线程名
  • %-5level:输出日志级别,包括5个字符位置(例如,DEBUG、INFO、WARN、ERROR、FATAL),将小于5个字符的级别左对齐
  • %logger{36}:输出日志记录器的名称,最多36个字符
  • %msg:输出日志内容
  • %n:输出平台相关的行分隔符
  • %M:输出产生日志事件的方法名
  • %L:输出语句在源文件中出现的行号
  • %l:输出语句的精确位置,包含类、方法和行号
  • %c:输出日志事件相关的类名

我们举两个例子,假如我们配置文件这么写

<PatternLayout pattern="%d{ISO8601} [%t] %-5level %logger{36} - %msg%n" />
输出的结果就为
2023-08-23T19:34:26,068 [main] INFO  com.zhanfu.Main - This is a Main info message.

如果配置文件如下

<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} |-%-5level [%t] %c{1.} %M [%L] -| %msg%n"/>
输出的结果就为
2023-08-23 20:18:06.833 |-INFO  [main] c.z.Main main [11] -| This is a Main info message.

其中,%c{1.} 表示输出日志事件相关的类名,只取最右边的类名,前面的层级,只输出一个字母;如果配置文件如下

<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} |-%-5level [%t] %c{2.} [%l] -| %msg%n"/>
输出的结果就为
2023-08-23 20:21:00.753 |-INFO  [main] co.zh.Main [com.zhanfu.Main.main(Main.java:11)] -| This is a Main info message.

四、Appenders

Appenders是指日志输出的目的地。它定义了日志事件要被输出到哪些地方,例如控制台、文件、数据库等,其下可以配置不同类型的Appender,我们罗列其中常见的一些:

  • Console:向控制台输出日志。
  • File:将日志记录到文件中。
  • RollingFile:将日志记录到指定大小的文件中,并支持文件滚动。
  • Socket:将日志发送到远程 Socket 服务器
  • Kafka:将日志发送到 Kafka 消息队列。
  • Redis:将日志发送到 Redis 服务器。
  • Jdbc:将日志记录到数据库中

对于单机应用来说,ConsoleFile 是最为常用的,但对于集群,通常需要进行日志采集,此时也会通过SocketKafka等将日志发送至其他位置

五、Console

Console标签是用于将日志输出到控制台的标签,其有以下可配置的属性:

  • name:配置Console标签的名称。
  • target:配置Console标签输出的目标,可以是System.out或System.err,默认为System.out。
  • follow:配置Console标签,控制台是否跟随日志进行滚动,默认为false。
  • immediateFlush:配置Console标签的输出是否立即刷新,默认为true

Console标签可以包含以下子标签

  • PatternLayout:上文已经介绍过,可以自定义输出的格式。此标签有以下可配置的属性:pattern。
  • ThresholdFilter:指定哪些日志级别应该被输出或被拒绝。此标签有以下可配置的属性:
    • level - 匹配的可用的日志级别。
    • onMatch - 当匹配或高于指定日志等级时的动作,可以为 ACCEPT、DENY、NEUTRAL 之一,默认为 NEUTRAL
    • onMismatch - 当低于指定日志等级时的动作,可以为 ACCEPT、DENY、NEUTRAL ,默认为 DENY
  • RegexFilter:使用正则表达式来计算哪些日志消息应该被过滤。

1. Filter 过滤器

比如我们可以做出如下配置

<Console name="console" target="SYSTEM_OUT"><PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/><ThresholdFilter level="WARN" onMatch="NEUTRAL " onMismatch="DENY"/><RegexFilter regex=".*\[(main|AsyncLogger)\].*"/>
</Console>

我们可以发现 ThresholdFilter 的设置为 level=“WARN” onMatch="NEUTRAL " onMismatch=“DENY”,这种设置的意思就是当日志等级高于或等于 WARN 时,就通过了级别过滤器,但还需要经过后续过滤器如的进一步筛选。而低于 WARN 则直接拒绝打印。

比如我们有这样的过滤设置

<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<ThresholdFilter level="warn" onMatch="DENY" onMismatch="DENY"/>

第一个过滤器否决打印error级别,第二个过滤器接收大于info级别,并且否决低于info级别的,那最终只能打印info 和 warn 级别了。此处的第三个过滤器实际上没被用到
在这里插入图片描述

六、RollingFile

RollingFile标签用于配置滚动日志输出到文件的方式,什么叫滚动日志,就是日志输出在一个文件中,当某个事件发生时(如文件达到一定大小),会把这个文件进行归档封存,然后新建一个文件,再向新建的文件中输出日志,有点像现代的饮料生产线,灌满一瓶立即灌下一瓶
在这里插入图片描述

以下是RollingFile标签的常用属性:

  • name:指定RollingFile的名称,用于标识该Appender。
  • fileName:指定日志文件的路径和名称。
  • filePattern:指定日志文件备份的命名模式,使用%符号指定日期、数字等占位符。

RollingFile 可以包含下列子标签

  • policies:指定日志滚动策略,包括时间、大小等,可以使用TimeBasedTriggeringPolicySizeBasedTriggeringPolicy等标签。
  • PatternLayout:指定日志输出格式,上面已经说过。

我们可以以下面的配置为例子进行进一步解释

<Appenders><RollingFile name="RollingFile"fileName="/logs/app.log"filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log"><PatternLayout><pattern>%d %p %c{1.} [%t] %m%n</pattern></PatternLayout><Policies><TimeBasedTriggeringPolicy interval="1" modulate="true"/><SizeBasedTriggeringPolicy size="10 MB"/></Policies><DefaultRolloverStrategy max="5"/></RollingFile>
</Appenders>

该示例配置了一个名为“RollingFile”的RollingFile Appender,将日志记录到“/logs/app.log”文件中。文件名模式为“/logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz”

1. filePattern 文件样板

filePattern是RollingFile Appender的一个属性,用于指定根据何种模式生成归档滚动日志文件的名称。filePattern可以使用一些特定的占位符,以便在滚动时自动生成新的日志文件名

filePattern占位符:

  • %d - 日期格式化器的格式化日期。例如:2018-09-19
  • %i - 滚动文件的索引编号,从1开始。
  • %n - 系统的行分隔符
  • %m - 文件名

比如我们设置的

filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log"

filePattern中的时间占位符%d在滚动时会自动更新为当前时间,索引号%i也会自动递增以避免覆盖先前的日志,所以最终会生成以下的归档文件名

app-2021-08-30-15-1.log
app-2021-08-30-15-2.log
app-2021-08-30-15-3.log

2. Policies 文件原则

Policies用于定义何时触发滚动动作以生成新的日志文件,可以定义TimeBased和SizeBased两种类型的触发策略。

  • TimeBasedTriggeringPolicy
    TimeBasedTriggeringPolicy是基于时间的触发策略,当指定的时间间隔过去时,将会触发滚动动作
    属性:

    • interval:时间间隔,单位为filePattern中的最小时间单位,如%d{yyyy-MM-dd-HH}代表最小时间为小时,默认数值为1。
    • modulate:是否调节,即使用0时0分作为起点,当开启时,下一次生成日志文件的时间为0时0分 + n 个interval
  • SizeBasedTriggeringPolicy
    SizeBasedTriggeringPolicy是基于日志文件大小的触发策略,当日志文件大小达到指定的大小时,将会触发滚动动作
    属性:
    -size:指定的日志文件大小,单位为字节,默认值为10MB

需要注意的是,
1.若modulate=true, 则封存时间将以0点为边界进行偏移计算。比如,modulate=true,interval=4hours,那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,之后的封存时间依次为08:00,12:00,16:00…如果modulate=false,则代表不调整,封存时间严格遵循离上次间隔4小时,则封存时间依次为07:00,11:00,15:00…

2.Policies可以同时指定多个触发策略,从而满足多种情况下的滚动需求,例如

<RollingFile name="example"fileName="logs/logfile.log"filePattern="logs/logfile-%d{yyyy-MM-dd_HH}.log"><Policies><TimeBasedTriggeringPolicy interval="5" modulate="true"/><SizeBasedTriggeringPolicy size="100 MB"/></Policies><DefaultRolloverStrategy max="5"/>
</RollingFile>

以上配置将在每隔五小时或100M时将生成一个新的日志文件,文件名会包含时间戳

3. DefaultRolloverStrategy

DefaultRolloverStrategy是一个滚动策略,可以设置滚动文件数量以及删除策略,它有以下几个属性:

  • max:最大日志文件数量,默认为7。
  • min:最小日志文件数量,默认为1。
  • fileIndex:日志文件序号的格式,默认为%s。
  • compressionLevel:压缩级别,默认为6

同时,它也支持以下子标签:

  • Delete:用于配置何时删除过期的日志文件。
  • CustomDelete:用于自定义删除过期日志文件的行为。

比如以下设置

<DefaultRolloverStrategy max="10" min="2" fileIndex="max"><Delete basePath="logs" maxDepth="2"><IfFileName glob="*.log" /><IfLastModified age="14d" /></Delete>
</DefaultRolloverStrategy>

这代表日志文件最多保留10个,最少保留2个,日志文件序号格式为max,同时配置了Delete子标签,用于删除14天前的logs文件夹下,两层路径以内的所有.log文件。其中,Delete子标签中的IfFileName和IfLastModified子标签用于指定删除条件,只有同时满足两个条件才进行删除操作

需要注意的是,文件的多少与我们设置的 filePattern 也有关系,其限制的其实是%i的最大数值:

比如
filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log
这代表文件归档最小单位为小时,如果我们的 DefaultRolloverStrategy max="10" ,那么一个小时内最多保留10个文件,
当产生第11个文件时,将会删除本小时最早的日志文件

七、Loggers

LoggersLogger标签是用来配置日志记录器的。Loggers标签是定义所有Logger的容器标签,而Logger标签则是具体的记录器配置,Logger 标签有以下属性:

  • name:指定Logger的名称,名称可以是类名、包名或自定义的名称。例如,如果设置为com.example.MyLogger,则日志内容将包含该名称。
  • level:指定Logger的日志级别,如果不指定则将继承Loggers标签中的默认级别。例如,如果设置为INFO,则只会记录INFO及以上级别的日志。
  • additivity:指定Logger是否继承它的父Logger的Appender。如果不指定,则将继承Loggers标签中的默认值。
  • includeLocation:指定是否包含日志输出的调用位置信息。如果设置为true,则输出的日志将包括文件名、方法名和行号等信息。
  • suppressExceptions:指定是否屏蔽日志输出中的异常信息。如果设置为false,则将在日志输出中包含异常信息

Logger标签还包括AppenderRef子标签,用于指定Logger所要使用的Appender。可以在Logger标签中指定多个AppenderRef,这样就可以将同一个Logger的日志输出到多个Appender中

下面是一个典型的Loggers与Logger的例子:

<Appenders><RollingFile name="MyAppender"fileName="/logs/app.log"filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log"><PatternLayout><pattern>%d %p %c{1.} [%t] %m%n</pattern></PatternLayout><Policies><TimeBasedTriggeringPolicy interval="1" modulate="true"/><SizeBasedTriggeringPolicy size="10 MB"/></Policies><DefaultRolloverStrategy max="5"/></RollingFile><Console name="Console" target="SYSTEM_OUT"><ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/><Buffered mode="ONCE" bufferSize="256"/></Console>
</Appenders>
<Loggers><Logger name="com.example.MyLogger" level="info"><AppenderRef ref="MyAppender"/></Logger><Root level="error"><AppenderRef ref="Console"/></Root>
</Loggers>

这个例子中定义了两个Logger:com.example.MyLogger和Root。com.example.MyLogger的级别是INFO,只会记录INFO及以上级别的日志,并且使用MyAppender作为输出目的地;Root的级别是ERROR,将所有ERROR及以上级别的日志输出到Console中

八、异步日志

1. 基础使用

我们上面讲解的其实都是同步输出的日志,而Log4j2 的一大特性就是其异步输出能力,我们可以参考如下配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN"><Appenders><File name="File" fileName="logs/app.log"><PatternLayout><Pattern>%d %p %C{1.} [%t] %m%n</Pattern></PatternLayout></File><Async name="Async"><AppenderRef ref="File"/></Async></Appenders><Loggers><Logger name="com.example" level="debug"/><Root level="info"><AppenderRef ref="Async"/></Root></Loggers>
</Configuration>
  1. 首先,定义了一个文件输出的Appender,文件名为logs/app.log,并且在PatternLayout中指定了日志输出的格式。
  2. 接着,定义了一个异步的Appender,它的AppenderRef指向了文件输出的Appender。
  3. 最后,将Root Logger的级别设为info,并让它的AppenderRef指向了异步的Appender。

这个配置可以实现将日志异步输出到logs/app.log文件中,并且可以指定日志输出的格式

我们可以做一个测试,分别用同步和异步的方式进行运行:

    public static void main(String[] args) {long startTime = System.currentTimeMillis();for (int i = 0; i < 1000000; i++) {log.info("This is a debug message. Count is "+i);}long endTime = System.currentTimeMillis();log.info("Total time: "+(endTime - startTime)+"ms");}

在这里插入图片描述
在这里插入图片描述
可以看到,异步确实能节约很多时间。

2. 详细配置

在这里插入图片描述

我们注意到最后一个阻塞队列的信息,其实不难想象,这里的日志异步依赖的就是高性能队列,不仅log4j2,像Netty等对性能有极高要求的框架,在队列的选择上都是精益求精的。log4j2支持四种阻塞队列,如下:

在这里插入图片描述
比如我们如果想指定一种阻塞队列,可以这么设置:

<Configuration name="LinkedTransferQueueExample"><Appenders><List name="List"/><Async name="Async" bufferSize="262144"><AppenderRef ref="List"/><AsyncQueueFullPolicy type="Discard"/><!-- 指定阻塞队列 --><LinkedTransferQueue/></Async></Appenders><Loggers><Root><AppenderRef ref="Async"/></Root></Loggers>
</Configuration>

当然,如果你想使用 DisruptorBlockingQueue,那还需要引入 disruptor 包,注意版本兼容,log4j-2.17.1 对应了disruptor-3.4.0

<dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.4.0</version>
</dependency>

总结

本次我们比较详细的介绍了Log4j2框架的种种配置,虽然没有讲原理,但解释了不少配置并给出示例,相信即便是新手,阅读完也能应对大部分使用场景了。希望大家能够举一反三,灵活运用。当然,有问题也可以直接去官方文档进行查阅和学习,点此直达log4j2 手册

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

装备制造企业如何执行精益管理?

导 读 ( 文/ 2358 ) 精益管理是一种以提高效率、降低成本和优化流程为目标的管理方法。装备制造行业具备人工参与度高&#xff0c;产成品价值高&#xff0c;质量要求高的特点。 在装备制造企业中实施精益管理可以帮助企业提高竞争力、提升生产效率并提供高质量的产品。本文将…

边缘计算节点BEC典型实践:如何快速上手PC-Farm服务器?

百度智能云边缘计算节点BEC&#xff08;Baidu Edge Computing&#xff09;基于运营商边缘节点和网络构建&#xff0c;一站式提供靠近终端用户的弹性计算资源。边缘计算节点在海外覆盖五大洲&#xff0c;在国内覆盖全国七大区、三大运营商。BEC通过就近计算和处理&#xff0c;大…

【算法日志】贪心算法刷题:单调递增数列,贪心算法总结(day32)

代码随想录刷题60Day 目录 前言 单调递增数列 贪心算法总结 前言 今天是贪心算法刷题的最后一天&#xff0c;今天本来是打算刷两道题&#xff0c;其中的一道hard题做了好久都没有做出来(主要思路错了)。然后再总结一下。 单调递增数列 int monotoneIncreasingDigits(int n…

Wlan——STA上线流程与802.11MAC帧讲解以及报文转发路径

目录 802.11MAC帧基本概念 802.11帧结构 802.11MAC帧的分类 管理帧 控制帧 数据帧 STA接入无线网络流程 信号扫描—管理帧 链路认证—管理帧 用户关联—管理帧 用户上线 不同802.11帧的转发路径 802.11MAC帧基本概念 802.11协议在802家族中的角色位置 其中802.3标…

Linux内核学习(八)—— 内存管理(基于Linux 2.6内核)

目录 一、页&#xff08;page&#xff09; 二、区&#xff08;zone&#xff09; 三、页操作 四、kmalloc() 五、vmalloc() 六、slab 分配器 七、在栈上的静态分配 一、页&#xff08;page&#xff09; 内核把物理页作为内存管理的基本单位。尽管处理器的最小可寻 …

网工内推 | 锐捷招云工程师,HCIE、CCIE、RHCE优先,25k*13薪

01 锐捷网络 招聘岗位&#xff1a;云方案工程师 职责描述&#xff1a; 1、负责云数据中心方案项目方案设计撰写、项目实施交付、故障处理、业务割接、客户培训、现场保障、网络优化、网络巡检等技术相关业务 2、负责云数据中心方案新技术文档沉淀、体系建设、工具开发等标准化…

使用element-plus组件,默认显示英文 转换为中文

最近在边写项目边学习vue3 所以这几天没有更新 找机会把vue3的知识也统计一下吧 先说今天遇到的问题 最近做项目的时候使用element-plus分页组件时发现&#xff0c;显示的不是中文的了&#xff0c;是英文的 解决方法 在app.vue里面配置 <template><el-config-provi…

Pyqt5打开电脑摄像头进行拍照

目录 1、设计UI界面 2、设计逻辑代码&#xff0c;建立连接显示窗口 3、结果 1、设计UI界面 将ui界面转为py文件后获得的逻辑代码为&#xff1a;&#xff08;文件名为 Camera.py&#xff09; # -*- coding: utf-8 -*-# Form implementation generated from reading ui file …

【算法专题突破】双指针 - 移动零(1)

目录 写在前面 1. 题目解析 2. 算法原理 3. 代码编写 写在最后&#xff1a; 写在前面 在进行了剑指Offer和LeetCode hot100的毒打之后&#xff0c; 我决心系统地学习一些经典算法&#xff0c;增强我的综合算法能力。 1. 题目解析 题目链接&#xff1a;283. 移动零 - 力…

centos7.9和redhat6.9 离线升级OpenSSH和openssl (2023年的版本)

升级注意事项&#xff01; 1、多开几个连接窗口&#xff08;xshell&#xff09;&#xff0c;避免升级openssh失败无法再次连接终端&#xff0c;否则要跑机房了。 2、可开启telnet服务、vnc服务、打快照。多几个“保命”的路数。一、centos7.9的信息 [rootnode2 ~]# openssl v…

学会Mybatis框架:一文掌握MyBatis与GitHub插件分页的完美结合【三.分页】

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Mybatis的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Mybatis分页 1. Mybatis自带分页 2…

AIGC如何借AI Agent落地?TARS-RPA-Agent破解RPA与LLM融合难题

文/王吉伟 大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;的持续爆发&#xff0c;让AIGC一直处于这股AI风暴最中央&#xff0c;不停席卷各个领域。 在国内&#xff0c;仍在雨后春笋般上新的大语言模型&#xff0c;在持续累加“千模大战”大模型数量的…

Linux之基础IO文件系统讲解

基础IO文件系统讲解 回顾C语言读写文件读文件操作写文件操作输出信息到显示器的方法stdin & stdout & stderr总结 系统文件IOIO接口介绍文件描述符fd文件描述符的分配规则C标准库文件操作函数简易模拟实现重定向dup2 系统调用在minishell中添加重定向功能 FILE文件系统…

什么是Pytorch?

当谈及深度学习框架时&#xff0c;PyTorch 是当今备受欢迎的选择之一。作为一个开源的机器学习库&#xff0c;PyTorch 为研究人员和开发者们提供了一个强大的工具来构建、训练以及部署各种深度学习模型。你可能会问&#xff0c;PyTorch 是什么&#xff0c;它有什么特点&#xf…

为什么需要单元测试?

为什么需要单元测试&#xff1f; 从产品角度而言&#xff0c;常规的功能测试、系统测试都是站在产品局部或全局功能进行测试&#xff0c;能够很好地与用户的需要相结合&#xff0c;但是缺乏了对产品研发细节&#xff08;特别是代码细节的理解&#xff09;。 从测试人员角度而言…

Mysql简短又易懂

MySql 连接池:的两个参数 最大连接数&#xff1a;可以同时发起的最大连接数 单次最大数据报文&#xff1a;接受数据报文的最大长度 数据库如何存储数据 存储引擎&#xff1a; InnoDB:通过执行器对内存和磁盘的数据进行写入和读出 优化SQL语句innoDB会把需要写入或者更新的数…

Java如何调用接口API并返回数据(两种方法)

Java如何调用接口API并返回数据&#xff08;两种方法&#xff09; java处理请求接口后返回的json数据-直接处理json字符串 处理思路&#xff1a; 将返回的数据接收到一个String对象中&#xff08;有时候需要自己选择性的取舍接收&#xff09; 再将string转换为JSONObject对象 …

Go 语言在 Windows 上的安装及配置

1. Go语言的下载 Golang官网&#xff1a;All releases - The Go Programming Language Golang中文网&#xff1a;Go下载 - Go语言中文网 - Golang中文社区 两个网站打开的内容只有语言不同而已&#xff0c;网站上清晰的标注了不同操作系统需要对应安装哪个版本&#xff0c;其中…

港联证券|燃气板块午后走高,美能能源涨停,水发燃气大幅拉升

燃气板块21日午后快速拉升&#xff0c;到发稿&#xff0c;美能动力涨停&#xff0c;水发燃气涨超7%&#xff0c;蓝天燃气涨超5%&#xff0c;贵州燃气涨逾4%。 消息面上&#xff0c;受澳大利亚LNG工厂罢工忧虑影响&#xff0c;欧洲基准天然气价格一度大涨18%。 有报导称&#x…

npm报错:xxx packages are looking for funding run `npm fund` for details(解决办法)

报错信息&#xff1a;30 packages are looking for funding run npm fund for details 报错原因&#xff1a;这里是开发者捐赠支持的提示&#xff0c;打开一个github的链接之后&#xff0c;会显示是否需要打赏捐赠的信息。 解决方案&#xff1a;这个打赏是资源的&#xff0c;因…