常见面试题及解析

1.HTTP

1.1 常用错误码(必问)

分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误
状态码 描述
200 请求成功
400 客户端请求的语法错误
401 未授权
404 请求的网页不存在
408 请求超时
414 请求的 URI 过长
500 服务内部异常
502 错误网关
503 服务器超时

1.2 HTTP请求响应报文组成(必问)

http请求报文组成:
1、请求行:一般由请求方法+url+http协议版本字段组成。 GET /data/info.html HTTP/1.1
(HTTP/1.0:一次连接只能执行一次请求和响应后就关闭了,没有HOST字段;
  HTTP/1.1 一次连接可以多次请求和响应,且必须要有HOST字段);
2、请求头:Accept、Accept-Encoding、Use-Agent、Content-Type、Content-Length(Post请求必有)、Host、if-modify-since、Cookie、Connection等组成;
3、空行:标志请求头结束;
4、请求数据:若方法字段是GET,则此项为空,没有数据;若方法字段是POST,则通常来说此处放置的就是要提交的数据。

POST方法请求报文如下,它的请求行URL段中一般是没有参数的,参数放在了报文体中。而GET方法的参数直接置于请求行URL中,报文体则为空。

HTTP响应报文:
1、响应行:包含http协议版本+状态码+描述 HTTP/1.1 200 OK;
2、响应头:描述服务器的基本信息:Allow(服务器支持哪些请求方法)、Content-Encoding(如果request.getHeader("Accept-Encoding")支持gzip,则返回gzip压缩后编码格式的文档)、Content-Type、Content-Length、Expires、Last-Modified(只有改动时间迟于指定时间(If-Modified-Since)的文档才会返回,否则返回一个304(Not Modified)状态)、Set-Cookie、Transfer-Encoding:告诉浏览器数据的传送格式、Date等;
3、空行:发送回车符+换行符,标志响应头的结束;
3、响应体:如果是纯数据就是返回纯数据,如果请求的是HTML页面,那么返回的就是HTML代码,如果是JS就是JS代码,如此之类。

常见面试题及解析_第1张图片

HTTP协议解读:HTTP协议-HTTP响应报文 - 掘金

请求方法:

  • POST:用于传输实体的主题

  • GET:获取资源,请求访问已经被URI识别的资源

  • PUT:传输文件,自身不带验证机制,任何人都可以上传文件,存在安全性问题

  • DELETE:删除文件。同样不带验证机制,存在安全性问题。

请求头字段

  • Host

  • Accept:客户端支持接受响应类型

    • text/plain

    • text/csv

    • text/html

    • text/xml

    • application/javascript

    • application/json

    • application/zip

    • application/xml

    • multipart/form-data

    • image/xxx

  • Accept-Charset:请求编码

    • utf-8

  • Accept-Encoding

    • gzip

    • zip

  • Accept-Language:

  • Cookie:jsessionid

  • Cache-Control:响应返回的内容在客户端是否被缓存

    • no-cache

  • Connection:

  • Last-Modified:

  • Content-Type:

  • Content-Lengh:

  • Date

请求头

  • 请求方式+URI+协议版本

  • 请求首部字段:

  • 实体首部字段

  • 其他

请求体

空行

请求数据

http 报文首部 | ProcessOn免费在线作图,在线流程图,在线思维导图

1.3 请求行的组成(必问)

请求方法+URL+协议版本

1.4 GET和POST的区别(必问)

GET POST
请求参数 多个参数以&连接
HTTP协议对URL长度没有限制,但是实际浏览器和服务器存在规范限制,建议最多1KB
数据放在Body中
请求长度无限制
数据类型 只接受ASCII字符 无限制
参数位置 请求头 请求体
参数获取 请求可以携带Body,但是通过Body不能保证数据一定被接收到 无限制
安全性 提交的数据缓存在URL上,页面会被浏览器缓存
明文传输
请求不会缓存,除非手动设置
可明可密
数据传输 产生一个TCP数据包,将请求头和请求体一次性发送。等待响应 产生两个TCP数据包
发送请求头,获取响应
发送请求体,等待响应

1.4.1 关于HTTP请求URL长度的大小限制

服务器限制:

  • Nginx 的配置参数为large_client_header_buffers

  • Tomcat 的请求配置参数为maxHttpHeaderSize

浏览器限制:

  • IE浏览器对URL的长度现限制为2048字节。

  • 360极速浏览器对URL的长度限制为2118字节。

  • Firefox(Browser)对URL的长度限制为65536字节。

  • Safari(Browser)对URL的长度限制为80000字节。

  • Opera(Browser)对URL的长度限制为190000字节。

  • Google(chrome)对URL的长度限制为8182字节。

1.4.2 使用场景

操作方式 数据位置 明文密文 数据安全 长度限制 应用场景
GET HTTP包头 明文 不安全 长度较小 查询数据,无修改
POST HTTP正文 可明可密 安全 支持较大数据传输 修改数据

1.5 http和https的区别

HTTP HTTPS
传输内容 超文本传输,明文形式 具有安全性的ssl加密传输协议
端口 80 443
安全性 连接简单 连接相对复杂,需要C/S之间证书校验

1.6 身份认证方式(加分项)

1.6.1 Cookie、Session、Token、JWT的区别

区别:傻傻分不清之 Cookie、Session、Token、JWT - 掘金

HTTP 是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息 ;不同端口下的cookie可以共享 ,cookie的跨域可以理解为跨域名 ,domain可以设置域名,只要二级域名相同就可以共享,与端口无关。

  • Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。而 Token 是令牌访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息。

Token:关于access_token&refresh_token的作用?access_token与refresh_token之为什么要用refresh_token刷新不重新获取access_token?_Soul_Niz_Kingdom-CSDN博客_为什么要刷新token

概念: 令牌, 是访问资源的凭证。

  • 我有几个疑问。第一你的refresh token和token有什么不一样?生成都一样吗?第二 refresh token存客户端还是服务端?第三 存服务端是不是人人都能拿着去换新的 安全性?我觉得refresh这个东西只是一个最大时间 就允许你在这段时间刷新token 超过了就去登录。

    • 第 一 问: refresh_token是用来刷新access_token的,而access_token是接口调用凭据;第二, 三问: refresh_token存于数据库或者其他安全的地方,在内部调用及使用,保证其安全;最后,你觉得是你觉得,我要我觉得;开个玩笑,因为access_token的有效期是2个小时,这2个小时不会因为你使用它就为你续期,2个小时后你就得重新登录一遍,对用户的体验极差,所以就需要refreshh_token刷新去为其续期,保证用户在连续使用超过2个小时后不用重新登录;如有不对,请纠正;

    • 先说一下去refresh_token安全的问题,取refresh_token是在access_token未过期的时候取出来刷新access_token续命用的,然后如果account_token过期了的话,需要重新登录,用code去获取account_token,这个时候refresh_token也是新的了,所以不存在access_token过去取refresh_token的问题。

    • 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间; 2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。 然后我已经试验过了,refresh_token在执行刷新之后是不会变的;

    • 1、 refresh一次相当于给access_token两个小时 2 、可以在数据库存储每个登录用户的refresh_token,写定时调度,不到两小时的时候调用一次进行续期 。

JWT与Token的区别JWT和token的区别及优缺点 - 涛子17180 - 博客园token**需要查库验证token** 是否有效,而JWT**不用查库或者少查库,直接在服务端进行校验并且不用查库**。因为用户的信息及加密信息在第二部分payload和第三部分签证中已经生成,只要在服务端进行校验就行,并且校验也是JWT自己实现的。

  • JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。

1.6.2 Cookie、Session哪个更安全

cookie分为二种

1,以文件方式存在硬盘空间上的长期性的cookie:登录时选择记住状态,就是将登录的信息以文件的形式存储在客户端的硬盘上。

2,停留在浏览器所占内存中的临时性的cookie

session更安全:存在于服务端保密性强,

1.6.3 防止重复提交的方式

2.容器

2.1 ArrayList和LinkedList从数据结构和内存分配方式说明性能差异的具体原因(必问)

ArrayList:底层是数组结构,查询快:每个数据有对应的index好定位;增删慢:删除一个元素后,后面的数据要移动,量大的话就很慢;

LinkedList:底层是链表结构,查询慢:无索引,增删快:删除元素,只需要改变指针到新的元素即可。两者都不是线程安全的,可以用Vector,读多写少用CopyOnWriteArrayList,读少写多用Collections.synchronizedList()方式

2.2 List和Set的区别(必问)

List的是允许重复元素,有序,Set是不能有重复元素,无序

Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。 

List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。

2.3 Set的去重原理(必问)

先判断hash值是否相同,再判断equal是否相同。

2.4 Queue和Stack的区别

Queue队列:先进先出,

  • add/put:添加元素,如果满了,add就报异常,put会阻塞;

  • remove/poll:移除并返回队列头部的元素,队列为空,remove则抱异常,poll返回null;

  • element/peek:返回队列头部的元素,队列为空,element抱异常,peek返回null。

Stack栈:后进先出,最上面是栈顶,pop、push、empty、peek(查看栈顶的对象,但不移除它)

2.5 集合的排序、遍历

集合比数组好处是长度能变,分为单列(List、Set)和双列集合(Map),排序:Collections.sort()升序,

//降序 Collections.sort(list, new Comparator(){ @Override public int compare(Integer o1,Integer o2){ return o2 - o1; } });

遍历:for循环、forEach、set.iterator() ;while(iterator.hasNext())

Map的遍历:for(Map.Entry m:map.entrySet()) 、for (Integer i : map.keySet()) 、map.entrySet().iterator();

2.6 HashMap数据结构

  • HashMap底层是Entry数组+单链表(JDK1.8前)的结构

  • 数组的初始容量是16,负载因子是0.75,当容量大于12时会自动扩容

  • 存放键值对,键不能相同、不能为null,存放规则是根据键的hashcode值与Entry数组长度取模得到index,位置是随机的,而遍历时nextNode方法的index是自增的,所以无序(与 LinkedHashMap 的区别:LinkedHashMap 是HashMap的子类,底层是双向链表,遍历是nextNode方法中调用是index.after(),所以是有序的,有插入和访问顺序。)

  • 当有hash冲突时,会将元素添加到链表中,JDK1.8后当链表长度大于8且hash桶的容量大于64时会转为红黑树,长度小于6又会变成链表

  • 线程不安全的,所以查询速度快

2.7 线程安全的集合有那些

Vector列表、HashTable、ConCurrentHashMap:将hash表分成16个segment,采用锁分段技术、Stack

2.8 优先级队列的理解和应用场景

2.8.1 概念

普通队列是先进先出,优先队列中存入的每项数据都附带一个数值,与进入的次序无关,以优先级最高的先出;

2.8.2 应用场景

应用场景:当电商出秒杀时,会有很多用户下单,此时即使会员用户在队列中排在普通用户的后面,但可以根据优先级先给会员创建订单。

2.8.3 常用实现

Queue customerPriorityQueue = new PriorityQueue<>(7, idComparator); 
public static Comparator idComparator = new Comparator(){
    @Override
    public int compare(Customer c1, Customer c2) {
        return (int) (c1.getId() - c2.getId());
    }
};    

3.异常处理

3.1 异常处理的目的(必问)

保证程序的健壮性:对可预测的一些可能性问题,提供了处理任何意外或异常情况的方法。通常使用try-catch-finally、try-with-resource以及throws等方式进行处理。

3.2 常见异常举例(必问)

  • NullPointerException: 空指针异常

  • ClassCastException: 类型强制转换异常

  • ClassNotFoundException:类找不到异常

  • ArrayIndexOutOfBoundsException: 数组下标越界异常

  • ArithmeticException:算术运算异常

  • NumberFormatException: 数字格式异常

  • IOExeption:IO异常

    • FileNotFoundException:文件找不到异常

  • InterruptedException:中断异常

  • SQLException:SQL语句异常

4.设计模式

4.1 项目中使用了哪些设计模式(必问)

  • 单例模式

    • 懒汉式

      • 双重检查锁定(double-checked locking) + volatial:因为singleton = new Singleton()不是原子性操作,可能会被重排序。volatial 禁止重排序并且保证了变量的可见性。

      **
       * 功能描述
       * 单例模式:因为被static修饰的类变量在类被加载时就会创建,所以饿汉模式中当类只是调用其他方法时就频繁的创建类会造成损耗,故用懒汉模式
       * 懒汉式-双检锁volatile+synchronized
       *
       * @author cWX1112617
       * @date 2021/12/14
       * @since 2021-12-14
       */
      public class SingleClass {
          /**
           * 多线程并发引起的安全性问题:当多个线程访问共享数据,而cpu切换线程是随机的。
           * 并发编程面临的三个问题:原子性、可见性、时序性。
           * volatile:可以解决可见性和时序性,不能解决原子性
           */
          private static volatile SingleClass singleClass;
      ​
          private SingleClass(){}
      ​
          public SingleClass getInstance() {
              if (singleClass == null) {
                  synchronized (SingleClass.class) {
                      if (singleClass == null) {
                          /* 对象的创建不是原子性操作,加载有三个步骤
                          * 1.在堆中开辟地址空间
                          * 2.在空间中初始化SingleClass对象
                          * 3.将singleClass引用指向地址空间
                          * 但是JVM的指令重排序,由于2.3不存在数据依赖性,可能顺序为1-3-2,
                          * 当执行1-3时singleClass已经不为null,等到出锁会对后面线程判断失误,
                          * 所以应该在SingleClass加上volatile,保证时序性不会出现重排序
                          * */
                          singleClass = new SingleClass();
                      }
                  }
              }
              return singleClass;
          }
      }
      
    • 饿汉式:在类加载的时候就完成了初始化,所以类加载比较慢

      • 静态初始化

    • 静态内部类

      public class SingleClass2 {
          private static class SingleClassHolder {
              private static final SingleClass2 singleClass2 = new SingleClass2();
          }
      ​
          private SingleClass2(){}
      ​
          public SingleClass2 getInstance() {
              return SingleClassHolder.singleClass2;
          }
      }
      
  • 简单工厂模式

  • 抽象工厂模式

  • 观察者模式

4.2 SOLID 6大原则—加分项

  • S(单一职责原则):

  • O(OCP,开闭原则):

  • L(LSP,里氏替换原则):

  • L(LOD,Law of Demeter,迪米特法则):

  • I(ISP,接口隔离原则):

  • D(依赖倒置原则):

4.4 UML建模

​ 用例图、类图、时序图、状态图

5.框架

5.1 Spring

5.1.1 IOC容器(必问)

5.1.2 AOP在项目中的应用(必问)

5.1.3 Spring循环依赖(加分项)

5.2 Spring MVC

5.2.1 MVC 模式

5.2.2 SpringMVC的工作流程

5.2.3 Filter和Interceptor与DispatcherServlet在整个请求中的处理时机

5.3 Springboot

5.3.1 对Springboot的理解(必问),Springboot的概念基础,与Spring的区别

5.3.2 Springboot自动装配流程(加分项)

5.4 Springcloud(简历中提及用Springcloud做为服务开发)

5.4.1 负载均衡:客户端和服务器端负载均衡的区别,负载均衡的常用算法(必问)

5.4.2 微服务调用方式(必问)@FeignClient,@EnableFeignClient

5.4.1 熔断的作用(加分项)

5.5 Mybatis

5.5.1 $和#的区别(必问)

5.5.2 Mybatis接口(XxxMapper)传参到xml有几种方式(必问)

5.5.3 Mybatis Interceptor(加分项)

6.NoSQL

6.1 Redis(用过Redis并在简历里说熟练运用,熟悉)

6.2 几个数据类型:String、List、Hash、Set、Zset(必问)

6.3 持久化机制RDB、AOF,两者应用场景的区别(必问)

6.4 String类型的数据结构(加分项)

6.5 缓存穿透、缓存击穿、缓存雪崩以及解决方案(加分项)

6.6 Redis分布式锁的实现方式(加分项)

7.数据库

7.1 实战经验:关键字、join和left join数据行的区别

7.2 举例:什么场景可能使用不上索引

7.3 事务特性(必问)

7.4 数据库的事务特性

7.5 项目中怎么控制事务

7.6 INNODB 和MYISAM的区别(必问)

7.7 事务隔离级别,以及默认的事务隔离级别(必问)

7.8 执行计划(简历中提及会SQL优化)

7.9 如何从执行计划看出是否使用了索引

7.10 key、possible key的值的区别

7.11 INNODB数据结构(加分项)

7.12 回表、索引覆盖、MVCC(加分项)

7.13 动态数据源(加分项)

8.多线程(简历中提及熟练运用多线程和线程池)

8.1 synchronized和Lock的区别(必问)

1.首先synchronized是java内置关键字,在jvm层面,Lock是个java类;

2.synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;

3.synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁,不会死锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;

4.用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;

5.synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可)

6.Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。

ReentrantLock获取锁 三种方式:

a) lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁

b) tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;

c)tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;

synchronized:是互斥锁:一次只能允许一个线程进入被锁住的代码块;是内置锁/监视器锁,是一种锁的标记,锁住的是对象,对象有自己的对象头,里面有很多信息,其中一个信息标示是被哪个线程持有

重入锁

public class Widget {
    // 锁住了
    public synchronized void doSomething() {
        ...
    }
}
public class LoggingWidget extends Widget {
    // 锁住了
    public synchronized void doSomething() {
        System.out.println(toString() + ": calling doSomething");
        super.doSomething();
    }
}
  1. 当线程A进入到LoggingWidget的doSomething()方法时,此时拿到了LoggingWidget实例对象的锁。

  2. 随后在方法上又调用了父类Widget的doSomething()方法,它又是被synchronized修饰。

  3. 那现在LoggingWidget实例对象的锁还没有释放,进入父类Widget的doSomething()方法还需要一把锁吗?

不需要的!

因为锁的持有者是“线程”,而不是“调用”。线程A已经是有了LoggingWidget实例对象的锁了,当再需要的时候可以继续“开锁”进去的!

这就是内置锁的可重入性。记住,持有锁的是线程

8.2 线程池的配置

8.2.1 7个参数的作用

  • corePoolSize:核心线程数

  • maxPoolSize:最大线程池

  • keeyALiveTime:失效时长

  • timeUnit:时间单位

  • queue:工作队列

  • threadFactory:线程工厂

  • rejectedExecutionHandler:回收策略

8.3 JDK 提供的线程池有哪几种,为什么不推荐 JDK 提供的线程池

8.3.1 newSingleThreadExecutor

只有一个线程处理所有请求,新来的任务均存入无界队列中排队

8.3.2 newCachedThreadPool

来一个请求新建一个线程

8.3.3 newFixedThreadPool

8.4 volatile 作用(加分项)

8.5 AQS 工作原理(加分项)

8.6 CAS

CAS:Compare and Swap, 翻译成比较并交换。 

CAS指令在Intel CPU上称为CMPXCHG指令,它的作用是将指定内存地址的内容与所给的某个值相比,如果相等,则将其内容替换为指令中提供的新值,如果不相等,则更新失败。这一比较并交换的操作是原子的,不可以被中断。初一看,CAS也包含了读取、比较 (这也是种操作)和写入这三个操作,和之前的i++并没有太大区别,是的,的确在操作上没有区别,但CAS是通过硬件命令保证了原子性,而i++没有,且硬件级别的原子性比i++这样高级语言的软件级别的运行速度要快地多。虽然CAS也包含了多个操作,但其的运算是固定的(就是个比较),这样的锁定性能开销很小。

从内存领域来说这是乐观锁,因为它在对共享变量更新之前会先比较当前值是否与更新前的值一致,如果是,则更新,如果不是,则无限循环执行(称为自旋),直到当前值与更新前的值一致为止,才执行更新。


 public final int incrementAndGet() {  
     for (;;) {  
         int current = get();  
         int next = current + 1;  
         if (compareAndSet(current, next))  
                return next;  
     }  
 } 
 
1.取得当前值
2.计算+1后的值
3.如果当前值没有被覆盖的话设置那个+1后的值
4.如果设置没成功, 再从1开始

9.质量意识

9.1 上线要求有那些(必问)

9.2 编码规范

9.3 SQL注入的实现方式,java如何避免SQL注入

9.4 日志注入

9.4.1 日志注入的危害

9.4.2 日志注入的方式以及防范方法

10.算法与数据结构

10.1 二叉树

10.1.1 二叉树数据结构

10.1.2 二叉树的特点

10.1.3 二叉树的分类

11.JVM(简历中提及熟悉、了解JVM)

11.1 JVM的运行时数据区/内存模型(必问)

11.2 堆的分代(必问)

11.3 为什么要分代(加分项)

11.4 垃圾回收算法(必问)

11.5 常用垃圾收集器有那些(加分项)

11.5.1 新生代的收集器

11.5.2 老年代的收集器

11.5.3 回收整个Java堆(新生代和老年代)

11.6 双亲委派机制(加分项)

11.7 JVM的调优实际经验(加分项)

11.7.1 调优流程

11.7.2 使用的工具

12.构建工具与服务器

12.1 Maven 的生命周期

生命周期(lifecycle)主要包括

  • clean

  • resources

  • complie

  • install

  • pacakge

  • testResources

  • testCompile

  • deploy

阶段 处理 描述
验证 validate 验证项目 验证项目是否正确且所有必须信息是可用的
编译 compile 执行编译 源代码编译在此阶段完成
测试 Test 测试 使用适当的单元测试框架(例如JUnit)运行测试。
包装 package 打包 创建JAR/WAR包如在 pom.xml 中定义提及的包
检查 verify 检查 对集成测试的结果进行检查,以保证质量达标
安装 install 安装 安装打包的项目到本地仓库,以供其他项目使用
部署 deploy 部署 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程

12.2 Maven常用指令

模块 描述 备注
maven clean 清理
maven test 测试
maven compile 编译
maven package 打包
maven install 安装项目到本地仓库
mvn deploy 发布项目到远程仓库
mvn dependency:tree 显示maven依赖树
mvn dependency:list 显示maven依赖列表

12.3 mvn compile与mvn install、mvn deploy的区别(加分项)

mvn compile:将源码编译成字节码

mvn package:编译结果打包成Jar包或WAR包

mvn install:将Jar包和War包部署到本地maven仓库

mvn deploy:将Jar包和War包布署到本地maven仓库和远程maven私服仓库

12.4 Tomcat

12.4.1 Tomcat是什么

一个免费的开放源代码的Web应用服务器,属于轻量级WEB应用服务器

12.4.2 Tomcat的缺省端口是多少,怎么修改

默认端口:8080

修改配置文件 server.xml

13.DT

13.1 Junit是什么,常用注解(必问)

JUnit 是一个回归测试框架,用于单元测试

单元测试工具,常用注解:

  • @Test:修饰方法,指定需要测试的方法(public void method())

    • timeout:测试时间超时限制

    • expected:测试是否它抛出了指定的异常

  • @Before:修饰public 方法,在执行每个测试方法之前执行,执行多次

  • @BeforeClass:修饰public static method,执行所有测试方法之前执行,只执行一次

  • @After:修饰public method,在执行每个测试方法之后执行,执行多次

  • @AfterClass:修饰public static method修饰方法,在所有测试结束之后执行,只执行一次

  • @Ignore:修饰public method,忽略测试,注释的测试方法将不会被执行

  • @RunWith:修改类,运行器。

    • Junit4ClassRunner.class:Junit 默认自带

    • SpringJUnit4ClassRunner.class:Spring相关

    • SpringRunner.class:SpringBoot 相关的

    • Suite.class:测试套件,将多个相关的测试类视为一个套件一起测试,通过@Suite.SuiteClasses({xxx.class,xxx.class})指定需要测试的类

      套件中的所有测试类的测试方法都会执行,但是Suite类本身用例则不会执行了

    • Parameterized.class:使用多个参数组合多次执行同一个测试用例

      • @Parameters:注释的公共的静态方法,返回一个对象的集合(数组)来作为测试数据集合

      测试类需要有构造函数

      一个 public static 方法被@Parameters标注,只能返回Iterable类型或数组类型的数据

执行顺序:@BeforeClass -> @Before -> @Test -> @After -> @AfterClass

13.2 @BeforeClass和@Before的区别

@BeforeClass @Before
定义个数 只能包含一个 多个,执行顺序不确定
修饰方法 必须声明为public static 必须声明为public 并且非static
执行次数 在类中只运行一次 在每个测试方法之前都会运行一次
执行顺序 优先@Before 晚于@BeforeClass,早于@Test

13.3 Junit测试方法定义规范(加分项)

类:Test+测试类。首字母大写的驼峰命名。

方法:test+用例操作_状态

13.4 DT 是什么

DT:Developer Test,(别称LLT,LOW LEVER TEST),包括

  • 单元测试(Unit Test)

  • 集成测试(Integration Test)

  • 模块系统测试(Module System Test)

  • 系统集成测试(BBIT)

13.4.1 定义与作用

13.5 DT常用框架有那些

  • Junit

  • Mockito:

  • JMockit

Jmock需要在执行前记录期望行为(expectations),显得很繁琐,而Mockito通过在执行后校验哪些函数已经被调用,消除了对期望行为(expectations)的需要,API非常简洁

你可能感兴趣的:(http,服务器,网络,面试)