49天精通Java,第22天,Java日志框架,Log4j日志级别

Posted 哪 吒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了49天精通Java,第22天,Java日志框架,Log4j日志级别相关的知识,希望对你有一定的参考价值。


目录

一、异常与日志

在理想的国度,用户输入数据的格式都是正确的,选择打开的文件也都是存在的,调用的第三方接口也都是网络稳定,程序的代码也是永远都没有bug的。

不过,在现实的世界里,bug无处不在,用户瞎输入、第三方接口间歇性失败、网络故障、未知错误,太多太多了。

此时,在bug面前,程序的稳定性尤为重要,一遇到bug就死翘翘,一遇到异常就宕机,这…

在遇到上述异常时,及时有效的通知客户、保存现存的所有工作、允许用户安全的退出程序、异常之下,错误日志的有效记录,显得尤为重要。

然而,在实际的工作中,大部分程序员都没有将日志的记录规范化、重点化,都是得过且过的状态。

项目上线后,一天好几百万的业务办理,一个文件日志好几十万行,在Linux中查看日志,没有固定的关键字定位,两眼一码黑,找什么找,怎么找?

拷贝到本地后,也是如此,通过notepad打开日志文件,也是找不到问题所在,只有一个异常日志,具体什么原因不知道,多线程缘故,有的小伙伴连事故的起点都找不到。这种情况下,你要怎么解决?

开发人员一定要在最开始的时候,就养成一种良好的日志记录习惯,哪些日志要记录,哪些日志不用记,都是什么级别的日志。

要想定位问题,通过什么关键字去定位,如何才能做到一模而了然。

二、下面来聊一下,日志的作用

  1. 快速定位问题;
  2. 记录业务流程;
  3. 跟踪数据的变化,做到数据的预测;
  4. 数据统计和性能分析;
  5. 采集运行环境、服务器数据日志;
  6. 根据日志进行结算,这个我还真遇到过;
  7. 相关部门审计要用;

日志最大的用处,还是快速定位问题,快速找到问题原因。

三、记录日志的规范

1、日志的可读性,日志是记录问题的,然后让维护人员看的,规范的、通俗易懂的日志才是王道。

2、日志的性能,不管是记录到文件里,还是记录到数据库里,记录日志肯定是要消耗程序性能的,这样,哪些需要记下,哪些不用记,需要权衡利弊。

3、大的循环中,尽量不要记录日志。

4、日志的级别,一般情况下,程序运行时记录info日志,发生异常时记录error日志,也可以记录警告日志,比如某些参数超过了,但是不影响整体程序的运行。

四、日志的内容

哪些内容需要记录在日志中,日志不是越多越好,越丰满越好,凡是要有一个度。

  1. 日期;
  2. 时间;
  3. 日志级别;
  4. 代码位置;
  5. 线程号;
  6. 日志内容;
  7. 错误码;
  8. 错误信息
  9. 业务描述;
  10. 关键字,比如产品id;
  11. 入参、回参;

总之一句话,你认为哪些参数比较重要,有助于你排查问题,就记录哪些。

五、Log4j

Log4j 是 Apache 的一个开源项目,项目中一般都是通过Log4j来记录日志,可以通过配置文件定义日志输出的级别、格式、存储路径等。

Log4j 中将要输出的 Log 信息定义了 6 种级别,依次为 TRACE、DEBUG、INFO、WARN、ERROR 和 FATAL。

1、TRACE

很低的日志级别,一般不会使用。

2、DEBUG

一般在项目调试阶段使用,记录的日志更细粒化,主要打印开发过程中的一些重要变量。

3、INFO

info日志,是最常用的日志,用于记录正常运行情况下,程序的执行情况,执行轨迹,打印一些比较重要的东西,但不能滥用,避免日记记录过多,维护运维阶段定位问题过于麻烦。

4、WARN

主要用于记录一些警告,比如你的本意是查询某些产品信息,但是没有查到,逻辑上没有错误,但业务上说不通。

5、ERROR

通常在发生异常、程序入参校验失败时,用error级别记录,也会单独产生error文件。

6、FATAL

FATAL 指出每个严重的错误事件将会导致应用程序的退出,这个级别比较高,重大错误,程序无法恢复,必须通过重启程序来解决。

🏆本文收录于Java基础教程(入门篇),包含面向对象、基本数据类型、数组、继承和多态、泛型、枚举等Java基础知识点。

🏆姐妹篇,Java基础教程系列,目前已经700+订阅,CSDN最强Java专栏,包含全部Java基础知识点、Java8新特性、Java集合、Java多线程、Java代码实例,理论结合实战,实现Java的轻松学习。

🏆姐妹进阶篇,Java基础教程(进阶篇),包含Java高并发、Spring、mysql等Java进阶技术栈。

49天精通Java,第7天,GET和POST的区别堆和栈的区别


目录

大家好,我是哪吒。

一、JDK 和 JRE 的区别?

JDK:java development kit (java开发工具)

JRE:java runtime environment (java运行时环境)

JVM:java virtuak machine (java虚拟机)

1、jdk–开发环境(核心)

Java development kit的缩写,意思是Java开发工具,我们写文档做PPT需要office 办公软件,开发当然需要开发工具了,说到开发工具大家肯定会想到Eclipse,但是如果直接安装Eclipse你会发现它是运行不起来 是会报错的,只有安装了JDK,配置好了环境变量和path才可以运行成功。这点相信很多人都深有体会。

jdk主要包含三个部分:

第一部分是Java运行时环境,JVM

第二部分是Java的基础类库,这个类库的数量还是相当可观的

第三部分是Java的开发工具,它们都是辅助你更好地使用Java的利器

2、jre–运行环境

① jdk中的jre

如下图:jdk中包含的jre,在jre的bin目录里有个jvm.dll,既然JRE是运行时环境,那么运行在哪?肯定是JVM虚拟机上了。另,jre的lib目录中放的是一些JAVA类库的class文件,已经打包成jar文件。

② 第二个JRE(独立出来的运行时环境)

如下图,不管是JDK中的JRE还是JRE既然是运行时环境必须有JVM。所以JVM也是有两个的。

3、JVM——转换环境

java virtuak machine (java虚拟机)的缩写。

大家一提到JAVA的优点就会想到:一次编译,随处运行,说白了就是跨平台性好,这点JVM功不可没。

Java的程序也就是我们编译的代码都会编译为class文件,class文件就是在jvm上运行的文件,只有JVM还不能完全支持class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib,而jre包含lib类库。

JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改的运行。

JVM也是一门很深的学问,感兴趣的同学可以深入研究,只有好处,没有坏处。

其实有时候面试官问JDK和JRE的区别的目的不是想让你解释什么名词的,而是想看看你的基础和研究Java的深浅,还有另一方面就是你是不是经常喜欢问为什么。

二、final 与 static 的区别?

  1. 都可以修饰类、方法、成员变量;
  2. static可以修饰类的代码块,final不可以;
  3. static不可以修饰方法内局部变量,final可以;
  4. static修饰表示静态或全局;
  5. static修饰的代码块表示静态代码块,当JVM加载类时,只会被创建一次;
  6. static修饰的变量可以重新赋值;
  7. static方法中不能用this和super关键字
  8. static方法必须被实现,而不能是抽象的abstract
  9. static方法只能被static方法覆盖

因为this代表的是调用这个函数的对象的引用,而静态方法是属于类的,不属于对象,静态方法成功加载后, 对象还不一定存在。 this代表对本类对象的引用,指向本类已创建的对象。 super代表对父类对象的引用,指向父类对象。 静态优先于对象存在,方法被static修饰之后,方法先存在,所需的父类引用对象晚于该方法的出 现,也就是super所指向的对象还没出现,当然就会报错。

  1. final修饰表示常量、一旦创建不可被修改;
  2. final标记的成员变量必须在声明的同时赋值,或在该类的构造方法中赋值,不可重新赋值;
  3. final方法不能被子类重写;
  4. final类不能被继承,没有子类,final类中的方法默认是final的;
  5. final不能用于修饰构造方法;
  6. private类型的方法默认是final类型的;

三、get和post简介

get和post是表单提交的两种方式,get请求数据通过域名后缀URL传送,用户可见,不安全,post请求数据通过在请求报文正文里传输,相对比较安全。get是通过URL传递表单值,post通过URL看不到表单域的值。

get传递的数据量是有限的,如果要传递大数据量不能用get,不如type=“file”上传文章、type=“password”传递密码,get和post是表单提交数据的两种方式,get请求数据通过地域名后缀URL传送,用户可见,不安全,post请求数据通过将在请求报文正文里传输,相对比较安全。

get是通过url传递表单值,post通过url看不到表单域的值;

get传递的数据量是有限的,如果要传递大数据量不能用get,比如type=“file”上传文章、type=“password”传递密码或者< text area >发表大段文章,post则没有这个限制;

post会有浏览器提示重新提交表单的问题,get则没有(加分的回答)

对于Post的表单重新敲地址栏再刷新就不会提示重新提交了,因为重新敲地址就没有偷偷提交的数据了。Post方式的正确的地址很难直接发给别人。

四、get和post的区别

  1. get提交的数据放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456. post方法是把提交的数据放在HTTP包的body中。
  2. get提交的数据大小有限制(因为浏览器对URL的长度有限制),而post方法提交的数据没有限制。
  3. get方式需要使用request.querystring来取得变量的值,而post方式通过request.form来获取变量的值。
  4. get方式提交数据会带来安全问题,比如一个登陆页面,通过get提交数据时,用户名和密码将出现在URL中,如果页面可以被缓存或者其他人可以访问这台机器 ,就可以从历史记录获得该用户的账户和密码。

get是从服务器获取数据,post向服务器传送数据。

get是把参数数据队列加到提交表单的action属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML.header内一起传送到action属性所指的URL地址。用户看不到这个过程。

对于get方式,服务器端用request.querystring获取变量的值,对于post方式,服务器端用request.form获取提交的数据

get传送的数据量较小,不能大于2KB.POST传送的数据量较大,一般被默认为不受限制。但理论上,限制取决于服务器的处理能力。

get安全性较低。post安全性较高。

五、堆和栈的概念和区别

在说堆和栈之前,先说一下JVM(虚拟机)内存的划分:

Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区域,启动时在自己的内存区域中进行更细致的划分,因为虚拟机中每一片内存处理的方法都不同,所以要单独进行管理。

JVM内存的划分有五片:

  1. 寄存器
  2. 本地方法区
  3. 方法区
  4. 栈内存
  5. 堆内存

我们来重点说一下堆和栈:

栈内存:栈内存首先时一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量,for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用于,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的声明周期都很短。

堆内存:存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封存数据,而且是封存多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,也就没有了。堆里的实体虽然不会被释放,但是会被当做垃圾,Java有垃圾回收机制不定时的收取。

下面我们通过一个图例详细讲一下堆和栈:

比如主函数里的语句

int[] arr = new int[3];

在内存中是怎么被定义的:

主函数先进栈,在栈中定义一个变量arr,接下来为arr赋值,但是右边不是一个具体值,是一个实体。实体创建在堆里,在堆里首先通过new关键字开辟一个空间,内存在存储数据的时候都是通过地址来实现的,地址是一块连续的二进制,然后给这个实体分配一个内存地址。数组都有一个索引,数组这个实体在堆内存中产生之后每一个空间都会默认的初始化(这是堆内存的特点,未初始化的数据是不能用的,但是在堆里是可以用的,因为初始化过了,但是栈里没有),不同的类型初始化的值不一样,所以堆和栈里就创建了变量和实体。

那么堆和栈怎么联系起来的呢?

我们刚刚说郭给堆分配一个地址,把堆的地址赋给arr,arr就通过地址只想了数组。所以arr想操作数组时,就通过地址,而不是直接把四蹄都赋给它。这种我们不再叫它基本数据类型,而叫引用数据类型。称为arr引用了堆内存当中的实体。

如果当int[] arr = null;

arr不做任何指向,null的作用就是取消引用数据类型的指向。

当一个实体,没有引用数据类型指向的时候,它在堆内存中不会被释放,而被当作一个垃圾,在不定时的时间内自动回收,因为Java有一个自动回收机制。自动回收机制自动监测堆里是否有垃圾,如果有,就会自动的做垃圾回收的动作,但是什么时候回收不一定。

所以堆和栈的区别很明显:

  1. 栈内存存储的是局部变量而堆内存存储的是实体;
  2. 栈内存的更新速度要快于堆内存,因为局部变量的声明周期很短;
  3. 栈内存存放的变量声明周期一旦结束就会被释放,而堆内存存放的实体会被垃圾啊回收机制不定时的回收。

六、浅谈Java反射机制

1、反射的定义是什么?

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,这种动态获取、调用对象方法的功能成为Java语言的反射机制。

2、反射存在的必要性?

反射机制是很多Java框架的基石。

① 在xml文件或properties里面写好了配置,然后再Java类里面解析xml或properties里面的内容,得到一个字符串,然后用反射机制,根据这个字符串获得某个类的Class实例,这样就可以动态配置一些东西,不用每一次都要在代码里去new或者做其它事情,以后要改的话直接改配置文件,代码维护起来就很方便了。

② 有时候要适应某些需求,Java类里面不一定能直接调用另外的方法,这时候也可以通过反射机制来实现。

3、反射的缺点?

反射的代码比正常调用的代码更多,性能更慢,应避免使用反射。


🏆本文收录于,49天精通Java从入门到就业

全网最细Java零基础手把手入门教程,系列课程包括:基础篇、集合篇、Java8新特性、多线程、代码实战,持续更新中(每周1-2篇),适合零基础和进阶提升的同学。

🏆哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师

以上是关于49天精通Java,第22天,Java日志框架,Log4j日志级别的主要内容,如果未能解决你的问题,请参考以下文章

Java日志第17天 2020.7.22

100天精通Andriod逆向——第6天:Andriod 开发入门

100天精通Andriod逆向——第6天:Andriod 开发入门

100天精通Python(数据分析篇)——第49天:初识numpy模块

100天精通Oracle-实战系列(第10天)ADRCI 简单介绍和基础使用

100天精通Oracle-实战系列(第22天)Oracle 数据泵全库导出导入