日志
日志定义:
计算机用于记录所有操作程序或者工具(错误,记录等等)
日志的作用:
就好像一个日记,记录程序操作的信息,出现警告的位置,或者记录什么时候出现错误,从而追踪到具体的数据 也可以方便记录到具体的位置,比如:控制台或者文件中
常见的日志框架:
日期框架: 基于Slf4j的logback实现
日志级别: 不同的级别显示不同的信息,(不同框架支持的日志基本可能不同)
日志级别优先级:(由低到高)(A<T<D<I<W<E<F<O)
ALL: 显示所有日志信息
TRACE: 追踪, 指明程序运行轨迹(一般不用), 能够显示trace和trace以上的日志
DEBUG: 调试 ,应用程序中(自己开发的软件)最低日志级别, 用于程序调试, 暴露运行细节,能显示debug和debug以上的日志
INFO: 信息, 程序正常运行时, 记录信息, 能够显示info和info以上的日志
WARN: 警告, 程序可以运行,但是可能会出错, 能够显示warn和warn以上的日志
ERROR: 错误, 程序报错, 无法自动解决, 能够显示error和error以上的日志
FATAL: 致命, 无法挽回的错, 能够显示fatal和fatal以上的日志
OFF:关闭所有日志信息
(注:黄色的内容最常用)
logback入门代码实现:
logback日志框架为例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestLog {
//每个类,都需要有一个之日记录器
private static Logger logger = LoggerFactory.getLogger("TestLog");
public static void main(String[] args) {
//默认debug
//不同日志阶级别的信息显示
logger.trace("追踪");
logger.debug("调试");
logger.info("信息");
logger.warn("警告");
logger.error("错误");
}
}
修改配置文件
Logback提供了一个核心配置文件logback.xml (一定要在src目录下使用)
日志框架在记录日志时会读取配置文件中的配置信息,从而记录日志的形式。具体可以做哪些配置呢?
1. 可以配置日志输出的位置是文件、还是控制台
2. 可以配置日志输出的格式
3. 还可以配置日志关闭和开启、以及哪些日志输出哪些日志不输出。
- 如下图所示,控制日志往文件中输出,还是往控制台输出
- 如下图所示,控制日志的输出的格式
日志格式是由一些特殊的符号组成,可以根据需要删减不想看到的部分。比如不想看到线程名那就不要[%thread]。但是不建议同学们更改这些格式,因为这些都是日志很基本的信息。
logback.xml源文件代码:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--输出流对象 默认 System.out 改为 System.err-->
<target>System.out</target>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度
%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] : %msg%n</pattern>
</encoder>
</appender>
<!-- File是输出的方向通向文件的 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!--日志输出路径-->
<file>D:/log/itheima-data.log</file>
<!--指定日志文件拆分和压缩规则-->
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--通过指定压缩文件名称,来确定分割文件方式-->
<fileNamePattern>D:/log/itheima-data-%i-%d{yyyy-MM-dd}-.log.gz</fileNamePattern>
<!--文件拆分大小-->
<maxFileSize>1MB</maxFileSize>
</rollingPolicy>
</appender>
<!--
1、控制日志的输出情况:如,开启日志,取消日志
-->
<root level="debug">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE" />
</root>
</configuration>
线程
进程:计算机中一个软件运行起来,就需要一个进程
线程:一个程序(进程)内部,独立运行的单元就是一个线程
总结: 一个进程,可以拥有多个线程,称为多线程开发
创建线程:
三种方式:
Thread子类
Runnable接口实现类
Callable接口实现类
匿名内部类
具体代码如下:
Thread子类
Runnable接口实现类
Callable接口实现类
匿名内部类
创建线程的三种方式对比总结:
请看: 主页-> java面试题汇总 -> 创建线程有几种方式(必会)
单元测试
所谓单元测试,就是针对最小的功能单元,编写测试代码对其进行正确性测试。
比如说我们写了一个学生管理系统,有添加学生、修改学生、删除学生、查询学生等这些功能。要对这些功能这几个功能进行测试,我们是在main方法中编写代码来测试的。
为了测试更加方便,有一些第三方的公司或者组织提供了很好用的测试框架,给开发者使用。这里给同学们介绍一种Junit测试框架。
Junit是第三方公司开源出来的,用于对代码进行单元测试的工具(IDEA已经集成了junit框架)
Junit
1.实现导包
package Junit;
import org.junit.Test;
public class TestJunit {
/**
* 单元测试方法要求:
* 1.不能私有,必须 public
* 2.非静态,不能使用 static关键字修饰
* 3.没有返回值 void
* 4.方法名任意
* 5.无参
*/
@Test
public void info(){
System.out.println("info");
}
@Test
public void show(){
System.out.println("show");
}
}
Junit框架的常用注解
同学们,刚才我们以及学习了@Test注解,可以用来标记一个方法为测试方法,测试才能启动执行。
除了@Test注解,还有一些其他的注解,我们要知道其他注解标记的方法什么时候执行,以及其他注解在什么场景下可以使用。
单元测试断言
接下来,我们学习一个单元测试的断言机制。所谓断言:意思是程序员可以预测程序的运行结果,检查程序的运行结果是否与预期一致。
我们在StringUtil类中新增一个测试方法
public static int getMaxIndex(String data){
if(data == null){
return -1;
}
return data.length();
}
接下来,我们在StringUtilTest类中写一个测试方法
public class StringUtilTest{
@Test
public void testGetMaxIndex(){
int index1 = StringUtil.getMaxIndex(null);
System.out.println(index1);
int index2 = StringUtil.getMaxIndex("admin");
System.out.println(index2);
//断言机制:预测index2的结果
Assert.assertEquals("方法内部有Bug",4,index2);
}
}
运行结果: