• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

Java后端开发面试问题总结(下)

技术杂谈 勤劳的小蚂蚁 3个月前 (01-06) 95次浏览 已收录 0个评论 扫描二维码


本文主要涉及下面10个【数据结构与算法】问题以及15个【计算机网络】问题

  • 数据结构与算法
    • 1、二叉树的遍历方式?它们属于深搜还是广搜?
    • 2、什么是平衡二叉树,它的好处是什么?被应用在哪些场景中?
    • 3、数组和链表的区别?
    • 4、冒泡和快排的区别,最差和平均的时间复杂度?
    • 5、说说常用的散列方法?解决哈希冲突的方法有哪些?
    • 6、堆排序的过程说一下?
    • 7、堆排序和快排应用场景的?时间复杂度和空间复杂度各是多少?
    • 8、双向链表,给你Node a,在其后插入Node c?
    • 9、写并查集?
    • 10、HashMap存了若干(name, age)这样的键值对,现在想按照年龄排序,打印出姓名?
  • 计算机网络
    • 1、HTTP有哪些请求方法?它们的作用或者说应用场景?
    • 2、GET和POST的对比,或者说区别?
    • 3、TCP三次握手?四次挥手?
    • 4、TCP为什么需要三次握手?两次不行吗?
    • 5、四次握手,为什么客户端发送确认后还需要等待2MSL?
    • 6、cookie和session区别和联系?
    • 7、为何使用session?session的原理?
    • 8、网络的7层模型了解吗?
    • 9、有了传输层为什么还需要网络层?或者说网络层和传输层是如何协作的?
    • 10、TCP和UDP的区别?
    • 11、传输层的可靠传输指的是什么?是如何实现的?
    • 12、主机A向主机B发送数据,在这个过程中,传输层和网络层做了什么?
    • 13、TCP序号的作用?怎么保证可靠传输的?
    • 14、浏览器发起HTTP请求后发生了什么?越详细越好。
    • 15、DNS域名解析的请求过程?
    • 16、HTTP是基于TCP还是UDP的?
    • 17、HTTP请求和响应的报文结构(格式)?
    • 18、HTTP常见的状态码?


数据结构与算法

1、二叉树的遍历方式?它们属于深搜还是广搜?

  • 先序遍历。父结点 -> 左子结点 -> 右子结点
  • 中序遍历。左子结点 -> 父结点 -> 右子结点
  • 后序遍历。左子结点 -> 右子结点 -> 父结点
  • 层序遍历。一层一层自上而下,从左往右访问。
其中,先序、中序、后序遍历属于深度优先搜索(DFS),层序遍历属于广度优先搜索(BFS)

2、什么是平衡二叉树,它的好处是什么?被应用在哪些场景中?

平衡二叉树首先是一棵二叉查找树,其次它需要满足其左右两棵子树的高度之差不超过1,且子树也必须是平衡二叉树,换句话说对于平衡二叉树的每个结点,要求其左右子树高度之差都不超过1。
二叉查找树在最坏情况下,退化成链表,查找时间从平均O(lg n)降到O(n),平衡二叉树使树的结构更加平衡,提高了查找的效率;但是由于插入和删除后需要重新恢复树的平衡,所以插入和删除会慢一些。
应用场景比如在HashMap中用到了红黑树(平衡二叉树的特例),数据库索引中的B+树等。

3、数组和链表的区别?

  • 数组是一段连续的内存空间,所以支持随机访问,可以通过下标以O(1)的时间进行查找。链表中的元素在内存中不是连续的,可以分散在内存中各个地方。因此它不支持随机访问,查找效率是O(n)
  • 数组的插入和删除元素时间是O(n),插入和删除后要移动元素;而链表只需断开结点链接再重新连上,所以链表的删除和插入时间是O(1)
  • 数组必须指定初始大小,达到最大容量如果不扩容就不能再存入新的元素;而链表没有容量的限制
应用场景:数组适合读多写少、事先知道元素大概个数的情况;链表适合写多读少的情况。

4、冒泡和快排的区别,最差和平均的时间复杂度?

  • 冒泡:相邻元素进行两两比较,将最大值推动到最右边。重复以上过程。时间复杂度平均 O(N^2)最差 O(N^2),空间复杂度 O(1)
  • 快排:选择数组中第一个元素作为基准,从左边向右找到第一个大于等于基准的元素,从右边向左找到第一个小于等于基准的元素,交换这两个元素,最后基准左边的元素都小于等于基准,基准右边的元素都大于等于基准。然后固定基准元素,对其左边和右边采取同样的做法。典型的分治思想。时间复杂度平均 O(N lgN)最差 O(N^2),基于递归的实现由于用到了系统栈,所以平均情况下空间复杂度为 O(lgN)
  • 冒泡排序是稳定的排序算法,快速排序不是稳定的排序算法。
排序中所说的稳定是指,对于两个相同的元素,在排序后其相对位置没有发生变化。
常见的稳定排序有,冒泡、插入、归并、基数排序。选择、希尔、快排、堆排序都不是稳定的。

5、说说常用的散列方法?解决哈希冲突的方法有哪些?

  • 最常用的除留余数法(取余),大小为M的数组,key的哈希值为k,那么k % M的值一定是落在0-M-1之间的。
  • 直接定址法。用一个函数对key作映射得到哈希值。如线性函数: hash(key)=a*key+b
  • 其他(略)
解决哈希冲突的方法:
  • 开放定址法:采用M大小的数组存放N个键值对,其中M > N。开放定址中最简单的是线性探测法,当发生碰撞时,直接检查散列表中的下一个位置。如果到了数组末尾,折回到索引0处继续查找。
  • 链地址法:采用链表数组实现,当发生哈希冲突时,将冲突键值以头插或者尾插的方式插入数组下标所在的链表,HashMap中正是使用了这种方法。
  • 再哈希法:当发生哈希冲突时,换一个散列函数重新计算哈希值。
  • 公共溢出区法:建立一个基本表和溢出表,所有冲突的键值都存放到溢出表中。在查找时,先在基本表中查,相等,查找成功,如不相等则去溢出表中进行顺序查找。

6、堆排序的过程说一下?

堆排序使用了最大堆/最小堆,拿数组升序排序来说,需要建立一个最大堆,基于数组实现的二叉堆可以看作一棵完全二叉树,其满足堆中每个父结点它左右两个结点值都大,且堆顶的元素最大。
  • 将堆顶元素和数组最后一个元素交换,最大元素被交换数组最后一个位置,同时从堆中删除原来处于堆顶的最大元素
  • 被交换到堆顶的元素一般会打破堆结构的定义,因此需要进行堆的调整(下沉)。将堆顶的元素和其左右两个结点比较,将三者中的最大的交换到堆顶,然后继续跟踪此结点,循环上述过程,直到他比左右两个结点都大时停止调整,此时堆调整完毕,再次满足堆结构的定义
  • 重复以上两个过程。直到堆中只剩一个元素,此时排序完成
每次调整堆的平均时间为O(lg N),因此对大小为N的数组排序,时间复杂度最差和平均都 O(N lg N).

7、堆排序和快排应用场景的?时间复杂度和空间复杂度各是多少?

快排序在平均情况下,比绝大多数排序算法都快些。很多编程语言的sort默认使用快排,像Java的Array.sort()就采用了双轴快速排序 。堆排序使用堆实现,空间复杂度只有O(1)。堆排序使用堆的结构,能以O(1)的时间获得最大/最小值,在处理TOP K问题时很方便,另外堆还可以实现优先队列。
时间复杂度:
  • 快排,平均O(N lg N) ,最差O(N^2),这种情况发生在数组本身就有序,这样每次切分元素都是数组中的最小值,切分得就极为不平衡。
  • 堆排序,平均和最差都是O(N lgN)。因为每次调整堆结构都是O(lg N),因此对大小为N的数组排序,时间复杂度最差和平均都 O(N lg N).
空间复杂度:
  • 快排,一般基于递归实现,需要使用系统栈O(lg N)
  • 堆排序,额外空间复杂度O(1)
放一张神图

8、双向链表,给你Node a,在其后插入Node c?

  1. c.next = a.next;
  2. a.next = c;
  3. c.prev = a;
  4. // 如果a不是最后一个结点,就有下面一句
  5. c.next.prev = c;

9、写并查集?

  1. publicclassUnionFind{
  2.    // id相同的分量是连通的
  3.    privateint[] id;
  4.    //连通分量的个数
  5.    privateint count;

  6.    publicUnionFind(int n){
  7.        count = n;
  8.        id =newint[n];
  9.        for(int i =0; i < n; i++){
  10.            id[i]= i;
  11.        }
  12.    }
  13.    // 所属连通分量的id
  14.    publicint find(int p){
  15.        return id[p];
  16.    }
  17.    // 将和p同一个连通分量的结点全部归到和q一个分量中,即将p所在连通分量与q所在连通分量合并。
  18.    // 反过来也可以
  19.    // if (id[i] == qID) {
  20.    // id[i] = pID;
  21.    // }
  22.    publicvoidunion(int p,int q){
  23.        int pId = find(p);
  24.        int qId = find(q);
  25.        if(pId == qId)return;
  26.        for(int i =0; i < id.length; i++){
  27.            if(id[i]== pId){
  28.                id[i]= qId;
  29.            }
  30.        }
  31.        // 合并后,连通分量减少1
  32.        count--;
  33.    }

  34.    publicboolean connected(int p,int q){
  35.        return find(p)== find(q);
  36.    }
  37. }
还可以有优化的写法,一个连通分量看成是一棵树。同一个连通分量其树的根结点相同。
  1. publicclassUnionFind{
  2.    privateint[] parentTo;
  3.    privateint count;

  4.    publicUnionFind(int n){
  5.        count = n;
  6.        parentTo =newint[n];
  7.        for(int i =0; i < n; i++){
  8.            parentTo[i]= i;
  9.        }
  10.    }

  11.    publicint find(int p){
  12.        // 向上一直到根结点
  13.        // p = parentTo[p]说明到达树的根结点,返回根结点
  14.        while(p != parentTo[p]){
  15.            p = parentTo[p];
  16.        }
  17.        return p;
  18.    }
  19.    // 这行的意思就是q所在连通分量和q所在连通分量合并
  20.    // 从树的角度来看,p树的根结点成为了q树根结点的孩子结点
  21.    // 反过来也可以,parentTo[qRoot] = pRoot;
  22.    publicvoidunion(int p,int q){
  23.        int pRoot = find(p);
  24.        int qRoot = find(q);
  25.        if(pRoot == qRoot)return;
  26.        parentTo[pRoot]= qRoot;
  27.        count--;
  28.    }

  29.    publicboolean connected(int p,int q){
  30.        return find(p)== find(q);
  31.    }
  32. }

10、HashMap存了若干(name, age)这样的键值对,现在想按照年龄排序,打印出姓名?

因为人类的年龄在一个固定范围内,假设0~100吧。可以设置101个桶,每个桶中放的是该年龄的所有用户名。
  1.    publicstaticvoid printNameOrderByAge(Map<String,Integer> map){
  2.        LinkedList<String>[] bucket =newLinkedList[101];
  3.        for(String name : map.keySet()){
  4.            int age = map.get(name);
  5.            if(bucket[age]==null){
  6.                bucket[age]=newLinkedList<>();
  7.            }
  8.            bucket[age].add(name);
  9.        }

  10.        for(int i =0;i < bucket.length;i++){
  11.            if(bucket[i]!=null){
  12.                System.out.print(i +" : ");
  13.                System.out.println(bucket[i]);
  14.            }
  15.        }
  16.    }

  17.    publicstaticvoid main(String[] args)throwsInterruptedException{
  18.        Map<String,Integer> map =newHashMap<>();
  19.        map.put("Alice",20);
  20.        map.put("Bob",20);
  21.        map.put("Tim",19);
  22.        map.put("Joker",19);
  23.        map.put("Carlos",18);
  24.        map.put("XiaoMing",22);
  25.        printNameOrderByAge(map);
  26.    }
打印如下内容
  1. 18:[Carlos]
  2. 19:[Joker,Tim]
  3. 20:[Bob,Alice]
  4. 22:[XiaoMing]

计算机网络

1、HTTP有哪些请求方法?它们的作用或者说应用场景?

  • GET: 请求指定的页面信息,并返回实体主体。
  • HEAD: 和GET类似,只不过不返回报文主体,只返回响应首部。可用于确认URI的有效性及资源更新的日期时间;
  • POST: 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
  • PUT: 用来传输文件,要求请求报文的主体中包含文件内容,然后保存到请求URI指定的位置。
  • DELETE: 和PUT相反,按请求URI删除指定的资源。
  • OPTIONS: 用来查询针对请求URI指定的资源支持的方法。如果请求成功,会有一个Allow的头包含类似“GET,POST”这样的信息
  • TRACE: 让服务端将之前的请求通信返回给客户端的方法(因此客户端可以得知请求是怎么一步步到服务端的)。主要用于测试或诊断。
  • CONNECT: 使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输。

2、GET和POST的对比,或者说区别?

  • GET用于获取数据,POST用于提交数据;
  • GET的参数长度有限制(不同的浏览器和服务器限制不同),POST没有限制
  • GET把参数包含在URL中,POST通过封装参数到请求体中发送;
  • GET请求只能进行url编码,而POST支持多种编码方式。
  • GET可以发送的参数只能是ASCII类型,POST没有限制,甚至可以传输二进制。
  • GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息;
  • GET刷新无害,而POST会再次提交数据
  • 还有GET请求会被保存浏览器历史记录,可以被收藏为书签,而POST请求不能等等
GET和POST本质都是TCP连接。不过GET产生一个TCP数据包;POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200 OK(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 OK(返回数据)。

3、TCP三次握手?四次挥手?

三次握手
  • 请求先由客户端发起。客户端发送SYN = 1和客户端序号c给服务端,同时进入SYN-SENT状态
  • 服务端收到SYN后需要做出确认,于是发送ACK = 1,同时自己也发送SYN = 1、服务端序号s,还有确认号c + 1,表示想收到的下一个序号。此时服务端进入SYN-RCVD状态
  • 客户端收到服务端的SYN和ACK,做出确认,发送ACK = 1,以及序号c +1,同时发送确认号s + 1,表示客户端想收到下一个序号。此时客户端和服务端进入ESTABLISHED状态,连接已建立!
四次挥手
  • 关闭连接也是先有客户端发起。客户端发送FIN = 1和序号c向服务端请求断开连接。此时客户端进入FIN-WAIT-1状态
  • 服务端收到FIN后做出确认,发送ACK = 1和服务端序号,还有确认号c + 1表示想要收到的下一个序号。服务端此时还可以向客户端发送数据。此时服务端进入CLOSE-WAIT状态,客户端进入FIN-WAIT-2状态
  • 服务端没有数据发送时,它向客户端发送FIN= 1、ACK = 1请求断开连接,同时发送服务端序号s以及确认号c + 1。此时服务端进入LAST-ACK状态
  • 客户端收到后进行确认,发送ACK = 1,以及需要c + 1和确认号s + 1。此时客户端进入TIME-WAIT状态。客户端需要等待2MSL,确保服务端收到了ACK,若这期间客户端没有收到服务端的消息,便可认为服务端收到了确认,此时可以断开连接。客户端和服务端进入CLOSED状态。

4、TCP为什么需要三次握手?两次不行吗?

两次握手的话,只要服务端发出确认就建立连接了。有一种情况是客户端发出了两次连接请求,但由于某种原因,使得第一次请求被滞留了。第二次请求先到达后建立连接成功,此后第一次请求终于到达,这是一个失效的请求了,服务端以为这是一个新的请求于是同意建立连接,但是此时客户端不搭理服务端,服务端一直处于等待状态,这样就浪费了资源。假设采用三次握手,由于服务端还需要等待客户端的确认,若客户端没有确认,服务端就可以认为客户端没有想要建立连接的意思,于是这次连接不会生效。

5、四次握手,为什么客户端发送确认后还需要等待2MSL?

因为第四次握手客户端发送ACK确认后,有可能丢包了,导致服务端没有收到,服务端就会再次发送FIN = 1,如果客户端不等待立即CLOSED,客户端就不能对服务端的FIN = 1进行确认。等待的目的就是为了能在服务端再次发送FIN = 1时候能进行确认。如果在2MSL内客户端都没有收到服务端的任何消息,便认为服务端收到了确认。此时可以结束TCP连接。

6、cookie和session区别和联系?

  • Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;
  • Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
  • session的运行依赖session id,而session id是存在cookie中的,也就是说,如果浏览器禁用了cookie ,同时session也会失效(但是可以通过url重写,即在url中传递session_id)

7、为何使用session?session的原理?

比如网上购物,每个用户有自己的购物车,当点击下单时,由于HTTP协议无状态,并不知道是哪个用户操作的,所以服务端要为特定的用户创建特定的Session,用于标识这个用户,并且跟踪用户。
Session原理:浏览器第一次访问服务器时,服务器会响应一个cookie给浏览器。这个cookie记录的就是sessionId,之后每次访问携带着这个sessionId,服务器里查询该sessionId,便可以识别并跟踪特定的用户了。
Cookie原理:第一次访问服务器,服务器响应时,要求浏览器记住一个信息。之后浏览器每次访问服务器时候,携带第一次记住的信息访问。相当于服务器识别客户端的一个通行证。Cookie不可跨域,浏览览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie,换句话说Google只能操作Google的Cookie。

8、网络的7层模型了解吗?

即OSI参考模型。
  • 应用层。针对特定应用的协议,为应用程序提供服务。如电子邮件、远程登录、文件传输等协议。
  • 表示层。主要负责数据格式的转换,把不同表现形式的信息转换成适合网络传输的格式。
  • 会话层。通信管理,负责建立和断开通信连接。即何时建立连接、何时断开连接以及保持多久的连接。
  • 传输层。在两个通信结点之间负责数据的传输,起着可靠传输的作用。
  • 网络层。路由选择。在多个网络之间转发数据包,负责将数据包传送到目标地址。
  • 数据链路层。负责物理层面上互联设备之间的通信传输。例如与一个以太网相连的两个节点之间的通信。是数据帧与1、0比特流之间的转换。
  • 物理层。主要是1、0比特流与电子信号的高低电平之间的转换。
还有一种TCP/IP五层模型,就是把应用层、表示层、会话层统一归到应用层。借用一张图。

9、有了传输层为什么还需要网络层?或者说网络层和传输层是如何协作的?

网络层是针对主机与主机之间的服务。而传输层针对的是不同主机进程之间的通信。传输层协议将应用进程的消息传送到网络层,但是它并不涉及消息是怎么在网络层之间传送(这部分是由网络层的路由选择完成的)。网络层真正负责将数据包从源IP地址转发到目标IP地址,而传输层负责将数据包再递交给主机中对应端口的进程。
打个比方。房子A中的人要向房子B中的人写信。房子中都有专门负责将主人写好的信投递到邮箱,以及从邮箱接收信件后交到主人手中的管家。那么:
  • 房子 = 主机
  • 信的内容 = 应用程序消息
  • 信封 = 数据包,带有源端口、目的端口、源IP地址、目的IP地址。
  • 邮递员 = 网络层协议,知道信从哪个房子开始发的,以及最后要送到哪个具体的房子。
  • 管家 = 传输层协议,负责将信投入到信箱中、以及从信箱中接收信件。知道这封信是谁写的以及要送到谁手上(具体端口号)
以上只是个人理解,如有误请联系更正。

10、TCP和UDP的区别?

  • TCP面向连接,传输数据之前要需要建立会话。UDP是无连接的。
  • TCP提供可靠传输,保证数据不丢包、不重复且按顺序到达;UDP只尽努力交付,不保证可靠交付
  • TCP提供了拥塞控制;UDP不提供
  • TCP是面向字节流的;UDP面向报文。
  • TCP只支持点到点通信;UDP支持一对一、一对多、多对多的交互通信。
  • TCP首部开销大20字节,UDP首部开销小8字节。

11、传输层的可靠传输指的是什么?是如何实现的?

可靠传输是指
  • 传输的信道不产生差错
  • 保证传输数据的正确性,无差错、不丢失、不重复且按顺序到达。
TCP如何实现可靠传输:
  • 应用数据被分割成TCP认为最适合发送的块进行传输
  • 超时重传,TCP发出一个分组后,它启动一个定时器,等接收方确认收到这个分组。如果发送方不能及时收到一个确认,将重传给接收方。
  • 序号,用于检测丢失的分组和冗余的分组。
  • 确认,告知对方已经正确收到的分组以及期望的下一个分组
  • 校验和,校验数据在传输过程中是否发生改变,如校验有错则丢弃分组;
  • 流量控制,使用滑动窗口,发送窗口的大小由接收窗口和拥塞窗口的的大小决定(取两者中小的那个),当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。
  • 拥塞控制:当网络拥塞时,减少数据的发送。

12、主机A向主机B发送数据,在这个过程中,传输层和网络层做了什么?

当TCP连接建立之后,应用程序就可使用该连接进行数据收发。应用程序将数据提交给TCP,TCP将数据放入自己的缓存,数据会被当做字节流并进行分段,然后加上TCP头部并提交给网络层。再加上IP头后被网络层提交给到目的主机,目的主机的IP层会将分组提交给TCP,TCP根据报文段的头部信息找到相应的socket,并将报文段提交给该socket,socket是和应用关联的,于是数据就提交给了应用。
对于UDP会简单些,UDP面向报文段。传输层加上UDP头部递交给网络层,再加上IP头部经路由转发到目的主机,目的主机将分组提交给UDP,UDP根据头部信息找到相应的socket,并将报文段提交给该socket,socket是和应用关联的,于是数据就提交给了应用。

13、TCP序号的作用?怎么保证可靠传输的?

序号和确认号是实现可靠传输的关键。
  • 序号:当前数据包的首个字节的顺序号。
  • 确认号:表示下一个想要接收的字节序号,同时确认号表示对发送方的一个确认回应,表示已经正确收到确认号之前的字节了。
通信双方通过序号和确认号,来判断数据是否丢失、是否按顺序到达、是否冗余等,以此决定要不要进行重传丢失的分组或丢弃冗余的分组。换句话说,因为有了序号、确认号和重传机制,保证了数据不丢失、不重复、有序到达。

14、浏览器发起HTTP请求后发生了什么?越详细越好。

当在浏览器输入网址www.baidu.com并敲下回车后:
  • DNS域名解析,将域名www.baidu.com解析成IP地址
  • 发起TCP三次握手,建立TCP连接。浏览器以一个随机端口(1024~65535)向服务器的80端口发起TCP连接。
  • TCP连接建立后,发起HTTP请求。
  • 服务端响应HTTP请求,将html代码返回给浏览器。
  • 浏览器解析html代码,请求html中的资源
  • 浏览器对页面进行渲染呈现给用户

15、DNS域名解析的请求过程?

  • 先在浏览器自身的DNS缓存中搜索
  • 如上述步骤未找到,浏览器搜索操作系统本身的DNS缓存
  • 如果在系统DNS缓存中未找到,则尝试读取hosts文件,寻找有没有该域名对应的IP
  • 如果hosts文件中没找到,浏览器会向本地配置的首选DNS服务器发起域名解析请求 。运营商的DNS服务器首先查找自身的缓存,若找到对应的条目且没有过期,则解析成功。如果没有找到,运营商的DNS代我们的浏览器,以根域名->顶级域名->二级域名->三级域名这样的顺序发起迭代DNS解析请求。

16、HTTP是基于TCP还是UDP的?

HTTP协议是基于TCP协议的,客户端向服务端发送一个HTTP请求时,需要先与服务端建立TCP连接(三次握手),握手成功以后才能进行数据交互。

17、HTTP请求和响应的报文结构(格式)?

HTTP请求的报文格式:
  • 请求行:包括请求方法、URL、HTTP协议版本号
  • 请求头:若干键值对组成
  • 请求空行:告诉服务器请求头的键值对已经发送完毕
  • 请求主体
HTTP响应的报文格式:
  • 响应行:HTTP协议版本号、状态码、状态码描述
  • 响应头:若干键值对表示
  • 响应空行:标识响应头的结束
  • 响应主体

18、HTTP常见的状态码?

  • 1XX:信息性状态码,表示接收的请求正在处理
  • 2XX:成功状态码,表示请求正常处理完毕
  • 3XX:重定向状态码,表示需要进行附加操作以完成请求
  • 4XX:客户端错误状态码,表示服务器无法处理请求
  • 5XX:服务端错误状态码,表示服务器处理请求出错
常见的状态码有:
  • 200 OK,请求被正常处理
  • 301 Move Permanently,永久性重定向
  • 302 Found,临时性重定向
  • 400 Bad Request,请求报文中存在语法错误
  • 403 Forbidden,对请求资源的访问被服务器拒绝
  • 404 Not Found,在服务器上不能找到请求的资源
  • 500 Internal Server Error,服务器内部错误

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:Java后端开发面试问题总结(下)
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00