SLF4J的介绍与使用(有logback和log4j2的具体实现案例)

目录

1.日志门面的介绍

常见的日志门面 :

常见的日志实现:

日志门面和日志实现的关系:

2.SLF4J 的介绍

业务场景(问题):

SLF4J的作用

SLF4J 的基本介绍

 日志框架的绑定(重点)

桥接旧的日志框架

SLF4J原理解析

3.SLF4J 的使用

非Springboot项目

 Springboot项目(重点)

Springboot中使用logback

Springboot中使用log4j2


1.日志门面的介绍

当我们的系统变的更加复杂的时候,我们的日志就容易发生混乱。随着系统开发的进行,可能会更新不同的日志框架,造成当前系统中存在不同的日志依赖,让我们难以统一的管理和控制。就算我们强制要 求所有的模块使用相同的日志框架,系统中也难以避免使用其他类似spring,mybatis等其他的第三方框 架,它们依赖于我们规定不同的日志框架,而且他们自身的日志系统就有着不一致性,依然会出来日志 体系的混乱。

所以我们需要借鉴JDBC的思想,为日志系统也提供一套门面,那么我们就可以面向这些接口规范来开 发,避免了直接依赖具体的日志框架。这样我们的系统在日志中,就存在了日志的门面和日志的实现。

常见的日志门面 :

JCL、slf4j

常见的日志实现:

JUL、log4j、logback、log4j2

日志门面和日志实现的关系:

通过这关系图,就大概知道了其实日志门面就类似于一套标准的接口,然后不同的日志实现框架基于这套标准的接口去实现具体的功能。 

简单来说,它仅仅是一个为Java程序提供日志输出的统一接口,并不是一个具体的日志实现方案,就比如JDBC一样,只是一种规则而已。所以单独的slf4j是不能工作的,必须搭配其他具体的日志实现方案

日志框架出现的历史顺序:

log4j -->JUL-->JCL--> slf4j --> logback --> log4j2

2.SLF4J 的介绍

业务场景(问题):

现在开发项目都是使用maven进行构建开发,假设架构师a开发了一个通用组件A,他在程序中使用的是log4j组件进行日志输出;程序员b自己之前一直在开发自己的业务模块,并且他在程序中使用的是logback日志组件,突然有一天程序员b需要在自己的业务系统中使用架构师a的通用组件A,这个时候问题就出现了,由于两套程序使用了不同的日志组件,程序员b除了要维护自己的logback日志组件配置,还需要维护通用组件A的日志配置,如何让他们的日志输出整合到一起,这个问题是很头疼的。这时候,使用slf4j就可以完美解决问题

SLF4J的作用

* 1. 使用SLF4J框架,可以在部署时迁移到所需的日志记录框架。

* 2. SLF4J提供了对所有流行的日志框架的绑定,例如log4j,JUL,Simple logging和NOP。因此可以 在部署时切换到任何这些流行的框架。

* 3. 无论使用哪种绑定,SLF4J都支持参数化日志记录消息。由于SLF4J将应用程序和日志记录框架分离, 因此可以轻松编写独立于日志记录框架的应用程序。而无需担心用于编写应用程序的日志记录框架。

* 4. SLF4J提供了一个简单的Java工具,称为迁移器。使用此工具,可以迁移现有项目,这些项目使用日志 框架(如Jakarta Commons Logging(JCL)或log4j或Java.util.logging(JUL))到SLF4J。

SLF4J 的基本介绍

简单日志门面(Simple Logging Facade For Java) SLF4J主要是为了给Java日志访问提供一套标准、规范 的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如log4j和logback等。 当然slf4j自己也提供了功能较为简单的实现,但是一般很少用到。对于一般的Java项目而言,日志框架 会选择slf4j-api作为门面,配上具体的实现框架(log4j、logback等),中间使用桥接器完成桥接。

官方网站: https://www.slf4j.org/

SLF4J是目前市面上最流行的日志门面。现在的项目中,基本上都是使用SLF4J作为我们的日志系统。

SLF4J日志门面主要提供两大功能:

1. 日志框架的绑定

2. 日志框架的桥接

 日志框架的绑定(重点)

如前所述,SLF4J支持各种日志框架。SLF4J发行版附带了几个称为“SLF4J绑定”的jar文件,每个绑定对应 一个受支持的框架。

 要切换日志框架,只需替换类路径上的slf4j绑定。例如,要从java.util.logging切换到log4j,只需将 slf4j-jdk14-1.7.27.jar替换为slf4j-log4j12-1.7.27.jar即可。

SLF4J不依赖于任何特殊的类装载。实际上,每个SLF4J绑定 在编译时 都是硬连线的 , 以使用一个且只有一个特定的日志记录框架。例如,slf4j-log4j12-1.7.27.jar绑定在编译时绑定以使用log4j。在您的代码 中,除了slf4j-api-1.7.27.jar 之外 ,您只需将您选择的一个且只有一个绑定放到相应的类路径位置。不要在类路径上放置多个绑定。以下是一般概念的图解说明。

 

注意点:在springboot项目中,如果项目中有多个实现类的话,项目是会直接报错,无法运行,如下图

桥接旧的日志框架

通常,您依赖的某些组件依赖于SLF4J以外的日志记录API。您也可以假设这些组件在不久的将来不会切 换到SLF4J。为了解决这种情况,SLF4J附带了几个桥接模块,这些模块将对log4j,JCL和 java.util.logging API的调用重定向,就好像它们是对SLF4J API一样。

桥接解决的是项目中日志的遗留问题,当系统中存在之前的日志API,可以通过桥接转换到slf4j的实现

1. 先去除之前老的日志框架的依赖

2. 添加SLF4J提供的桥接组件

3. 为项目添加SLF4J的具体实现

迁移的方式:

如果我们要使用SLF4J的桥接器,替换原有的日志框架,那么我们需要做的第一件事情,就是删除掉原 有项目中的日志框架的依赖。然后替换成SLF4J提供的桥接器。

注意问题:

1. jcl-over-slf4j.jar和 slf4j-jcl.jar不能同时部署。前一个jar文件将导致JCL将日志系统的选择委托给 SLF4J,后一个jar文件将导致SLF4J将日志系统的选择委托给JCL,从而导致 无限循环 。

2. log4j-over-slf4j.jar和slf4j-log4j12.jar不能同时出现

3. jul-to-slf4j.jar和slf4j-jdk14.jar不能同时出现

4. 所有的桥接都只对Logger日志记录器对象有效,如果程序中调用了内部的配置类或者是 Appender,Filter等对象,将无法产生效果。

桥接其实就是原来项目是使用的其他日志门面或者框架作为日志管理,现在像切换到使用slf4j来作为日志门面好做统一的日志管理,在不修改代码的前提下,提出了桥接这种方式来兼容原来的老项目

SLF4J原理解析

1. SLF4J通过LoggerFactory加载日志具体的实现对象。

2. LoggerFactory在初始化的过程中,会通过performInitialization()方法绑定具体的日志实现。

3. 在绑定具体实现的时候,通过类加载器,加载org/slf4j/impl/StaticLoggerBinder.class

4. 所以,只要是一个日志实现框架,在org.slf4j.impl包中提供一个自己的StaticLoggerBinder类,在 其中提供具体日志实现的LoggerFactory就可以被SLF4J所加载

3.SLF4J 的使用

非Springboot项目

建项目

导入依赖

<!--slf4j core 使用slf4j必須添加-->  
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.27</version>
 </dependency>
 <!--slf4j 自带的简单日志实现 -->
 <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.27</version>
 </dependency>

 编写代码

public void testQuick() throws Exception {//打印日志信息LOGGER.error("error");LOGGER.warn("warn");LOGGER.info("info");LOGGER.debug("debug");LOGGER.trace("trace");// 使用占位符输出日志信息String name = "jack";Integer age = 18;LOGGER.info("用户:{},{}", name, age);// 将系统异常信息写入日志try {int i = 1 / 0;} catch (Exception e) {// e.printStackTrace();LOGGER.info("出现异常:", e);}
}

 输出结果

这种非springboot的项目大概流程是这样子,具体更多的使用细节这里我就不做讲解了,在开发中更多的是springboot项目,我重点介绍springboot项目

 Springboot项目(重点)

知识铺垫:

SpringBoot支持多种日志框架,包括Logback、Log4j2和Java Util Logging(JUL)。默认情况下,如果你使用SpringBoot的starters启动器,它将使用Logback作为日志框架。

  • Logback:Logback是SpringBoot默认的日志框架,它是Log4j的继任者,提供了更好的性能和可靠性。你可以通过在资源目录下创建一个logback-spring.xml文件来配置Logback。
  • Log4j2:Log4j2是Log4j的升级版,它在性能和功能上都有所提升,支持异步日志和插件机制。如果你想在SpringBoot中使用Log4j2,你需要添加相应的依赖并在配置文件中指定Log4j2作为日志框架。
  • Java Util Logging(JUL):JUL是Java SE的默认日志框架,SpringBoot可以配置使用JUL作为日志框架,但一般不推荐使用,因为它的性能和灵活性相对较差。

简单来说就是springboot项目已经帮我们内置好的日志框架,默认实现是SLF4J+logback

所以如果我们项目中没有做任何关于日志框架的处理,那么就会使用默认的组合

但在实际的开发中,往往需要对项目日志框架进行处理。开发中常用日志门面是SLF4J,常用到日志实现是logback和log42这二个具体的实现类。因为springboot项目默认使用的就是SLF4J,所以我们不需要在引入依赖的,只需要针对实现类做处理。

Springboot中使用logback

springboot项目默认的日志实现就是logback,所以我们不需要在引入依赖,如何配置logback相关的配置,有二种方式,一种在项目的配置文件种配置,一种是单独建一个文件配置(方便管理)。我这里采用单独第二种

logback会依次读取以下类型配置文件:

logback.groovy

logback-test.xml

logback.xml 如果均不存在会采用默认配置

这里我建一个logback.xml的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration><!--日志输出格式:%-5level%d{yyyy-MM-dd HH:mm:ss.SSS}日期%c类的完整名称%M为method%L为行号%thread线程名称%m或者%msg为信息%n换行--><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%-5level] %c %M %L [%thread] %m%n"/><!--Appender: 设置日志信息的去向,常用的有以下几个ch.qos.logback.core.ConsoleAppender (控制台)ch.qos.logback.core.rolling.RollingFileAppender (文件大小到达指定尺寸的时候产生一个新文件)ch.qos.logback.core.FileAppender (文件)--><appender name="console" class="ch.qos.logback.core.ConsoleAppender"><!--输出流对象 默认 System.out 改为 System.err--><target>System.out</target><!--日志格式配置--><encoderclass="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>${pattern}</pattern></encoder></appender><!-- 日志文件存放目录 --><property name="log_dir" value="./logs"></property><!--日志文件输出appender对象--><appender name="file" class="ch.qos.logback.core.FileAppender"><!--日志格式配置--><encoderclass="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>${pattern}</pattern></encoder><!--日志输出路径--><file>${log_dir}/logback.log</file></appender><!-- 生成html格式appender对象 --><appender name="htmlFile" class="ch.qos.logback.core.FileAppender"><!--日志格式配置--><encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layout class="ch.qos.logback.classic.html.HTMLLayout"><pattern>%level%d{yyyy-MM-ddHH:mm:ss}%c%M%L%thread%m</pattern></layout></encoder><!--日志输出路径--><file>${log_dir}/logback.html</file></appender><!-- 日志文件拆分和归档的appender对象--><appender name="rollFile"class="ch.qos.logback.core.rolling.RollingFileAppender"><!--日志格式配置--><encoderclass="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>${pattern}</pattern></encoder><!--日志输出路径--><file>${log_dir}/roll_logback.log</file><!--指定日志文件拆分和压缩规则--><rollingPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!--通过指定压缩文件名称,来确定分割文件方式--><fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-dd}-%i.log</fileNamePattern><!--文件拆分大小--><maxFileSize>50MB</maxFileSize></rollingPolicy></appender><!--用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。<loger>仅有一个name属性,一个可选的level和一个可选的addtivity属性name:用来指定受此logger约束的某一个包或者具体的某一个类。level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和OFF,如果未设置此属性,那么当前logger将会继承上级的级别。additivity:是否向上级loger传递打印信息。默认是true。<logger>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger--><!--也是<logger>元素,但是它是根logger。默认debuglevel:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和 OFF,<root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger。--><root level="INFO"><appender-ref ref="console"/><appender-ref ref="rollFile"/></root>
</configuration>

编写测试类

public class LogbackTest {public static final Logger LOGGER = LoggerFactory.getLogger(Slf4jTest.class);@Testpublic void logbackTest(){LOGGER.error("error");  //错误信息,不会影响程序运行LOGGER.warn("warn");    //警告信息,表示系统运行可能出现的异常LOGGER.info("info");    //提示信息,记录系统运行,io操作等LOGGER.debug("debug");  //调试信息,一般在开发中使用LOGGER.trace("trace");  //追踪信息,记录程序所有的流程信息// 占位符输出日志String name = "jack";Integer age = 18;LOGGER.info("用户姓名:{},年龄:{}",name,age);int i = 1;try {i = i/0;} catch (Exception e) {LOGGER.info("出现异常",e);}}
}

运行效果:

未配置logback.xml前的输出效果

配置后的输出效果

总结:在springboot 使用logback非常的简单,你只需要通过配置文件去配置它就好了

Springboot中使用log4j2

 因为springboot项目内置日志实现是logback,所以如果我们要使用log42的话,需要移除默认的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!--排除默认spring-boot-starter-logging启动器-->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

加入 log4j2的依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

 

在src/main/resources目录下创建一个名为log4j2-spring.xml的配置文件,Spring Boot会默认加载这个配置文件。Spring Boot官方推荐优先使用带有-spring的文件名作为日志配置。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN"><!-- 定义全局变量,日志文件路径和格式 --><Properties><Property name="log.path">./dev</Property><Property name="log.name">log4j2</Property><Property name="file.pattern">%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{50} - %msg%n</Property></Properties><!-- 控制台输出配置 --><Appenders><Console name="STDOUT" target="SYSTEM_OUT"><PatternLayout pattern="${file.pattern}"/><ThresholdFilter level="DEBUG"/></Console><!-- 文件输出配置 --><RollingFile name="INFO_FILE" fileName="${log.path}/${log.name}.log4j2.log"filePattern="${log.path}/%d{yyyy-MM-dd}/${log.name}.info.%d{yyyy-MM-dd}-%i.log"><PatternLayout pattern="${file.pattern}"/><LevelMatchFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/><!-- 每个文件最大10MB --><SizeBasedTriggeringPolicy size="10MB"/><!-- 最多保留30天的历史记录 --><DefaultRolloverStrategy max="30"/></RollingFile><!-- 文件输出配置 --><RollingFile name="ERROR_FILE" fileName="${log.path}/${log.name}.error.log"filePattern="${log.path}/%d{yyyy-MM-dd}/${log.name}.error.%d{yyyy-MM-dd}-%i.log"><PatternLayout pattern="${file.pattern}"/><LevelMatchFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/><!-- 每个文件最大10MB --><SizeBasedTriggeringPolicy size="10MB"/><!-- 最多保留30天的历史记录 --><DefaultRolloverStrategy max="30"/></RollingFile></Appenders><!-- 设置root logger --><Loggers><Root level="INFO"><AppenderRef ref="STDOUT"/><AppenderRef ref="INFO_FILE"/><AppenderRef ref="ERROR_FILE"/></Root></Loggers>
</Configuration>

 运行效果

 如何是出现如上图,就代表使用的是log4j2这个日志实现了

总的来说,推荐使用Logback,配置简单,性能也还不错,而且是SpringBoot的默认日志框架

这里对于logback和log4j2的使用只是基本的使用,对于更多的使用细节,后续我会分别出对应实现框架的文章,文章到这里就结束了,如有不足,欢迎指正

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

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

相关文章

Influxdb中,Flux常用的函数

目录 一、Flux常用的函数及其简要描述 1. 数据源和筛选函数 2. 聚合函数 3. 时间序列操作函数 4. 转换和映射函数 5. 窗口函数 6. 其他常用函数 注意事项 二、使用方法举例 1. 数据源和筛选 2. 聚合 3. 时间序列操作 4. 窗口函数 5. 转换和映射 注意事项 三、…

跨越界限的温柔坚守

跨越界限的温柔坚守 —— 郑乃馨与男友的甜蜜抉择在这个光怪陆离、瞬息万变的娱乐圈里&#xff0c;每一段恋情像是夜空中划过的流星&#xff0c;璀璨短暂。然而&#xff0c;当“郑乃馨与男友甜蜜约会”的消息再次跃入公众视野&#xff0c;它不仅仅是一段简单的爱情故事&#xf…

iOS中多个tableView 嵌套滚动特性探索

嵌套滚动的机制 目前的结构是这样的&#xff0c;整个页面是一个大的tableView, Cell 是整个页面的大小&#xff0c;cell 中嵌套了一个tableView 通过测试我们发现滚动的时候&#xff0c;系统的机制是这样的&#xff0c; 我们滑动内部小的tableView, 开始滑动的时候&#xff0c…

C/C++ 代码注释规范及 doxygen 工具

参考 谷歌项目风格指南——注释 C doxygen 风格注释示例 ubuntu20 中 doxygen 文档生成 doxygen 官方文档 在 /Doxygen/Special Command/ 章节介绍 doxygen 的关键字 注释说明 注释的目的是提高代码的可读性与可维护性。 C 风格注释 // 单行注释/* 多行注释 */ C 风格注…

设置某些路由为公开访问,不需要登录状态即可访问

在单页面应用&#xff08;SPA&#xff09;框架中&#xff0c;如Vue.js&#xff0c;路由守卫是一种非常有用的功能&#xff0c;它允许你控制访问路由的权限。Vue.js 使用 Vue Router 作为其官方路由管理器。路由守卫主要分为全局守卫和组件内守卫。 以下是如何设置路由守卫以允…

k8s 部署RuoYi-Vue-Plus之mysql搭建

1.直接部署一个pod 需要挂载存储款, 可参考 之前文章设置 https://blog.csdn.net/weimeibuqieryu/article/details/140183843 2.部署yaml 先创建命名空间ruoyi kubectl create namespace ruoyi创建部署文件 mysql-deploy.yaml --- apiVersion: v1 kind: PersistentVolume …

【论文阅读笔记】Meta 3D AssetGen

【论文阅读笔记】Meta 3D AssetGen: Text-to-Mesh Generation with High-Quality Geometry, Texture, and PBR Materials Info摘要引言创新点 相关工作T23D基于图片的3d 重建使用 PBR 材料的 3D 建模。 方法文本到图像:从文本中生成阴影和反照率图像Image-to-3D:基于pbr的大型重…

搭建NEMU与QEMU的DiffTest环境(动态库方式)

搭建NEMU与QEMU的DiffTest环境&#xff08;动态库方式&#xff09; 1 DiffTest原理简述2 编译NEMU3 编译qemu-dl-difftest3.1 修改NEMU/scripts/isa.mk3.2 修改NEMU/tools/qemu-dl-diff/src/diff-test.c3.3 修改NEMU/scripts/build.mk3.4 让qemu-dl-difftest带调试信息3.5 编译…

C语言实现字符串排序

如果只有英文字符且不区分大小写的话按照字典序排序可以用strcmp函数&#xff0c;两个字符串自左向右逐个字符相比&#xff08;按ASCII值大小相比较&#xff09; strcmp(s1,s2) 当s1<s2时&#xff0c;返回为负数&#xff1b; 当s1s2时&#xff0c;返回值 0&#xff1b; …

安卓的组件

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

【Linux】打包命令——tar

打包和压缩 虽然打包和压缩都涉及将多个文件组合成单个实体&#xff0c;但它们之间存在重要差异。 打包和压缩的区别&#xff1a; 打包是将多个文件或目录组合在一起&#xff0c;但不对其进行压缩。这意味着打包后的文件大小可能与原始文件相同或更大。此外&#xff0c;打包…

Win10精英控制器2代青春版 设备删除失败,蓝牙连接断断续续

前提 更新了主板rog z790带WiFi、蓝牙&#xff0c;但是精英控制器连上老师断断续续。 过程 在设备管理中尝试了卸载、重装主板对应的蓝牙驱动&#xff0c;怎么都不行&#xff0c;都已经想放弃了。 但是想起来之前主板没有蓝牙&#xff0c;用的是绿联的USB蓝牙接收器&#xf…

Ubuntu24.04修改系统的环境变量

apache/tomcat配置要用到JDK&#xff0c;使用torch有时也会用到系统库&#xff0c;涉及到环境变量 1. 查看环境变量 cat /etc/environment2. 新建环境变量 sudo nano /etc/environment在文件底部添加新的环境变量 MY_VARIABLE"your_value"3. 修改环境变量 临时—…

数字化精益生产系统--APS 排程管理系统

APS&#xff08;Advanced Planning and Scheduling&#xff09;排程管理系统&#xff0c;即高级生产计划与排程系统&#xff0c;是一种高度智能化的计划和排程系统。它通过整合各种生产和供应链数据&#xff0c;运用先进的算法和数据模型&#xff0c;根据各种约束条件&#xff…

MySQL篇三:数据类型

文章目录 前言1. 数值类型1.1 tinyint类型1.2 bit类型1.3 小数类型1.3.1 float1.3.2 decimal 2. 字符串类型2.1 char2.2 varchar2.3 char和varchar比较 3. 日期类型4. enum和set 前言 数据类型分类&#xff1a; 1. 数值类型 1.1 tinyint类型 在MySQL中&#xff0c;整型可以指…

排队系统、Head and Tail of the Queue 题目

题目 JAVA40 排队系统描述输入描述&#xff1a;输出描述&#xff1a; 分析&#xff1a;代码&#xff1a; JAVA41 Head and Tail of the Queue&#xff08;队列的头和尾&#xff09;描述输入描述&#xff1a;输出描述&#xff1a; 示例:分析&#xff1a;代码&#xff1a;大佬代码…

【Java13】包

“包”这个机制&#xff0c;类似于分组。主要作用是区分不同组内的同名类。例如&#xff0c;高三三班有一个“王五”&#xff0c;高二八班也有一个“王五”。高三三班和高三八班就是两个不同的包。 Java中的包&#xff08;package&#xff09;机制主要提供了类的多层命名空间&…

MISRA C2012学习笔记(6)-Rules 8.11

文章目录 8.11 指针类型转换(Pointer type conversions)Rule 11.1 不能在函数指针和任何其他类型指针之间进行转换Rule 11.2 不得在指向不完整类型的指针和其他任何类型间进行转换Rule 11.3 不得在指向不同对象类型的指针之间执行强制转换Rule 11.4 不得在指向对象的指针和整数…

HTTP长连接

长连接优点 HTTP为什么要开启长连接呢? 主要是为了节省建立的时间,请求可以复用同一条TCP链路,不用重复进行三握+四挥 如果没有长连接,每次请求都做三握+四挥 如果有长链接,在一个 TCP 连接中可以持续发送多份数据而不会断开连接,即请求可以复用TCP链路 长连接缺点 …

第六十八回 东平府误陷九纹龙 宋公明义释双枪将-文心大模型ernie-speed免费使用方法

宋江和卢俊义抓阄儿&#xff0c;宋江打东平府&#xff0c;卢俊义打东昌府&#xff0c;谁先打下谁做梁山泊主。宋江带领林冲、花荣、刘唐等二十八人&#xff0c;卢俊义带领吴用、公孙胜、关胜等二十八人。 宋江等人到了东平府外安山镇&#xff0c;郁保四和王定六自告奋勇去下战…