常见JAVA面试题总结<2020 java面试必备>(五) 网络

网络

BIO、NIO、AIO分别是什么

BIO(Blocking IO)同步并阻塞

      服务端创建一个`ServerSocket`,客户端用一个Socket去连接服务端,实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,属于同步阻塞式的通信
      这种方式最大的坑在于,每次一个客户端接入,都是要在服务端创建一个线程来服务这个客户端的,这会导致服务端的线程数量可能达到几千甚至几万,几十万,服务器端程序的负载过高,最后崩溃死掉
      如果是搞一个线程池,固定线程数量来处理请求,但是高并发请求的时候,还是可能会导致各种排队和延时,因为没那么多线程来处理

NIO(No Blocking IO) 同步非阻塞

JDK 1.4中引入了NIO,这是一种同步非阻塞的IO,基于Reactor模型
NIO中有一些概念
Buffer,缓冲区的概念,一般都是将数据写入Buffer中,然后从Buffer中读取数据,有IntBuffer、LongBuffer、CharBuffer等很多种针对基础数据类型的Buffer
Channel,NIO中都是通过Channel来进行数据读写的
Selector,这是多路复用器,selector会不断轮询注册的channel,如果某个channel上发生了读写事件,selector就会将这些channel获取出来,我们通过SelectionKey获取有读写事件的channel,就可以进行IO操作。一个Selector就通过一个线程,就可以轮询成千上万的channel,这就意味着你的服务端可以接入成千上万的客户端
这块其实相当于就是一个线程处理大量的客户端的请求,通过一个线程轮询大量的channel,每次就获取一批有事件的channel,然后对每个请求启动一个线程处理即可。
这里的核心就是非阻塞,就那个selector一个线程就可以不停轮询channel,所有客户端请求都不会阻塞,直接就会进来,大不了就是等待一下排着队而已。

AIO(Asynchronous IO)异步非阻塞

      每个连接发送过来的请求,都会绑定一个buffer,然后通知操作系统去异步完成读,此时你的程序是会去干别的事儿的,等操作系统完成数据读取之后,就会回调你的接口,给你操作系统异步读完的数据。
      总结来说就是你的工作线程在发起读和写时都是异步的,不会卡在那,我可以去干别的事情,然后操作系统读完或者写完以后,会回调通知你

TCP 和 UDP 的区别和优缺点

TCP面向连接,UDP是无连接的
​TCP提供可靠的服务,UDP尽最大努力交付,即不保证可靠交付
​UDP具有较好的实时性,工作效率比TCP高
​TCP对系统资源要求较多,UDP对系统资源要求较少
每一条TCP连接只能是点到点的,UDP支持一对一,一对多,多对一和多对多的交互通信。

说一下 TCP 粘包/拆包原理及解决方案?

TCP粘包是什么?
image

      一个数据包中包含了客户端发送的两个数据包的信息,这种现象即为粘包。因为TCP连接是不会出现丢包的,所以对服务端来说只收到了一个数据包,并不知道这两个数据包的界限,所以对服务端来说很难处理 

TCP拆包是什么?

image

      服务端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包又发生了粘包。这两种情况如果不加特殊处理,对于服务端同样是不好处理的

为什么会发生TCP粘包、拆包?

客户端写入的数据大于或小于套接字缓冲区大小,这都将会发生拆包或粘包情况。
服务端不及时读取套接字缓冲区数据,这将发生粘包。

粘包、拆包解决办法

1、客户端给每个数据包添加包首部,首部中应该至少包含数据包的长度,服务端通过读取包首部的长度字段,便知道每一个数据包的实际长度了。
2、客户端将每个数据包封装为固定长度(不够的可以通过补0填充),服务端每次从缓冲区中读取固定长度的数据,自然而然的把每个数据包拆分开来。
3、可以在数据包之间设置边界,如添加特殊符号,这样,接收端通过这个边界就可以将不同的数据包拆分开。

TCP的三次握手与四次挥手

tcp建立连接三次握手过程

      通过传输层的tcp协议建立网络连接的时候,其实走的是三次握手的过程,建立三次握手的时候,TCP报头用到了下面几个东西,ACK、SYN、FIN
      其实三次握手说白了,就是来回来去三次请求,每次请求带上一堆TCP报文头,根据报文头是否正确,就约定好的协议来建立连接
第一次握手
      客户端发送连接请求报文,将SYN置1、ACK=0,表示希望建立连接,seq = x,接着客户端处于SYN_SEND状态,等待服务器响应
第二次握手
      服务端收到SYN=1的请求报文,建立连接请求,然后返回一个确认报文给客户端,`ACK = x + 1,SYN=1,ACK = 1,seq = y`,然后自己处于SYN_RECV状态
第三次握手
      客户端收到服务器的SYN+ACK确认报文后,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手

TCP为什么要三次握手,两次或者四次、五次不行吗

保持信息对等。
防止请求超时导致脏连接。
假设是两次握手就,客户端第一次握手过去,结果卡在某个地方了,没到服务端;完了客户端再次重试发送了第一次握手过去,服务端收到了,ok了
然后之前卡在那的第一次握手发到了服务器,服务器直接就返回一个第二次握手,但是呢?客户端根本就不会理睬这个发回去的二次握手,因为此时客户端的状态不是SYN_SENT,之前都通信过了,所以会直接丢弃服务器传来的确认数据,导致最后只是服务器单方面建立了连接
但是如果是三次握手,那个二次握手发回去,客户端发现根本不对,就会发送个复位的报文过去,让服务器撤销开辟的资源,别等着了。
如果是4次或者5次那是浪费资源了,所以3次足够了

TCP关闭连接的四次挥手

第一次挥手

客户端发送想要关闭连接报文给服务器,然后客户端进入FIN-WAIT-1状态

第二次挥手

服务器应答告诉客户端可以断开,但是要等我把数据发送完。这时客户端进入FIN_WAIT_2状态

第三次挥手

服务器将数据发送完后发送FIN+ACK给客户端,告诉客户端OK了,然后服务器进入CLOSE_WAIT状态
第四次挥手
客户端收到后,给服务器发送ACK确认收到,然后自己进入TIME_WAIT状态

为什么建立连接是三次握手,关闭连接却是四次握手

      因为关闭连接时,当服务器端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的关闭连接报文我收到了"
      只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手

网络连接中的长连接和短链接

http本身没什么所谓的长连接短连接之说,其实说白了都是http下层的tcp连接是长连接还是短连接
tcp短连接:每个请求都是先tcp三次握手,然后发送请求,获取响应,然后tcp四次挥手断开连接;
tcp长连接:tcp三次握手,建立了连接,然后该连接会一直保持,直到一方关闭连接,然后tcp四次挥手断开连接

在浏览器中输入网址之后执行会发生什么?

(1)找DNS服务器,DNS服务器解析域名之后,返回一个ip地址
(2)客户端发起http/https请求,然后交给传输层
(3)传输层将请求分成报文段,添加目标源和端口,并随机用一个本地接口封装进报头,然后交给网络层。
(4)网络层加上双方的ip地址信息,并负责路由分发。
(5)链路层中,包通过链路层发送到路由器,通过邻居协议查找给定IP地址的MAC地址,然后发送ARP请求查找目的地址,如果得到回应后就可以使用ARP的请求应答交换的IP数据包进行传输了,然后发送IP数据包到达服务器的地址。

说一下 JSONP 实现原理?

jsonp 即 json+padding,动态创建script标签,利用script标签的src属性可以获取任何域下的js脚本
​通过这个特性(也可以说漏洞),服务器端不在返回json格式
​而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域

HTTP与HTTPS有什么区别?

HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
  HTTPS和HTTP的区别主要如下:
  1、https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
  2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
  3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

HTTP常见的状态码及含义

200 请求成功
400 客户端请求的语法错误,服务器无法理解
401 请求要求用户的身份认证
403 服务器理解请求客户端的请求,但是拒绝执行此请求
404 服务器无法根据客户端的请求找到资源(网页)
405 客户端请求中的方法被禁止
500 服务器内部错误,无法完成请求
501 服务器不支持请求的功能,无法完成请求
502 从远端服务器接收到了一个无效的请求

GET 与 POST 方式的区别

GET

使用GET方法时,查询字符串(键值对)被附加在URL地址后面一起发送到服务器:
/test/demo_form.jsp?name1=value1&name2=value2
特点:
· GET请求能够被缓存
· GET请求会保存在浏览器的浏览记录中
· 以GET请求的URL能够保存为浏览器书签
· GET请求有长度限制
· GET请求主要用以获取数据

POST

使用POST方法时,查询字符串在POST信息中单独存在,和HTTP请求一起发送到服务器:
name1=value1&name2=value2
特点:
· POST请求不能被缓存下来
· POST请求不会保存在浏览器浏览记录中
· 以POST请求的URL无法保存为浏览器书签
· POST请求没有长度限制

session 与 cookie 的区别?

session保存在服务器,客户端不知道其中的信息;cookie保存在客户端,服务端可以知道其中的信息
session中保存的是对象,cookie中保存的是字符串
session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到;而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的
session是需要借助cookie才能正常工作的,如果客户端完全禁止cookie,session将失效

为什么禁用Cookie就不能得到Session呢?

因为Session是用Session ID来确定当前对话所对应的服务器Session,
​而Session ID是通过Cookie来传递的,禁用Cookie相当于失去了Session ID,也就得不到Session了

LocalStorage SessionStorage Cookie区别

数据的生命期

Cookie:一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效
LocalStorage:除非被清除,否则永久保存
SessionStorage:仅在当前会话下有效,关闭页面或浏览器后被清除

存放数据大小

Cookie:4K左右
LocalStorage、SessionStorage:一般为5MB

与服务器端通信

Cookie:每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题
LocalStorage、SessionStorage:仅在客户端(即浏览器)中保存,不参与和服务器的通信

什么是 XSS 攻击,如何避免

      XSS的全称是Cross Site Script,就是跨站点脚本攻击,意思就是说,黑客恶意篡改你的网页的前端代码,在里面注入一些他自己的html+javascript的脚本和代码,然后你比如在访问那个网站的网页的时候,他注入的那些恶意脚本就会运行了

XSS 攻击场景

      第一种XSS攻击是反射型攻击,让你点击一个URL链接,在这个URL链接里就嵌入他自己的恶意脚本,你点击那个URL链接之后,那个URL指向的是黑客自己的服务器上的一段恶意脚本
     另外一种XSS攻击是叫做持久型攻击,比如是个什么论坛、或者社交网站之类的系统,黑客可以在里面写一段恶意脚本然,然后把恶意脚本混杂在评论内容里提交到你的网站的数据库里去

如何避免 XSS

      内容转义,比如说把>转义为&gt之类的,这样就可以把恶意脚本里的html标签、js代码之类的东西,都给转义掉,让这些恶意脚本失效
      在浏览器里存放cookie的时候,可以设置一个HttpOnly属性,这样的话,在浏览器里运行的js脚本是被禁止访问这些HttpOnly cookie的,他就无法窃取你在浏览器里存储的cookie了​

什么是SQL注入攻击,如何避免

       系统在数据库里执行SQL语句的时候,可能存在漏洞,导致黑客把一些恶意的SQL语句注入进去让你的系统在你的数据库来执行这样子
      比如这个请求:http://www.xxx.com/goods?goodsSkuNo=xxxxx’;drop table eshop_goods_sku;
      执行到后台 select * from eshop_goods_sku where goods_sku_no=’xxxxx’; drop table eshop_goods_sku; 这样就导致恶意删库效果了

如何避免 SQL注入

     平时开发系统,一定要注意关闭web服务器错误回显,因为要造成恶意删库必须要知道表名,如果直接把错误信息返回给页面,没有经过处理,很可能就会将表名暴露出来
     mybatis的预编译,就是说把黑客在参数里混进来来的SQL语句当做一个参数,而绝对不会作为独立的SQL语句去执行,这就避免了SQL注入攻击了

什么是 CSRF 攻击,如何避免

       CSRF 被称为跨站请求伪造。一般来说,攻击者通过伪造用户的浏览器的请求,向访问一个用户自己曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令。常用于盗取账号、转账、发送虚假消息等。

防止cookie被窃取

       可以给你的网站的cookie设置HttpOnly属性,禁止被别人的script脚本窃取,那么别人就无法伪造用户登录请求了

验证 HTTP Referer 字段

      这个是http请求里有一个referer请求头,带有这个请求的来源,你可以验证一下这个请求是不是从自己的页面里来的,如果是的话才执行,否则就不要执行了

使用验证码

     关键操作页面加上验证码,后台收到请求后通过判断验证码可以防御CSRF。但这种方法对用户不太友好

随机token

      每次返回一个页面给你的时候,都生成一个随机token附加在页面的隐藏元素里,同时在你的redis里可以存以下,然后页面发送请求的时候附加随机token,验证通过才能执行请求,你要是自己用postman构造请求就不知道随机token是什么了

如果你们的系统允许用户上传文件,可能会遭到什么样的黑客攻击

      如果我们的网站允许别人上传文件,那么文件可能是可执行的脚本,可能是病毒或者木马文件,其实这个是非常危险的,如果是脚本的话,可能会在服务器执行,搞很多破坏,比如黑客黑掉你的服务器,勒索你给他比特币之类的,比如把自己的文件后缀改成.jpg、.txt之类的东西,来上传,其实本质病毒文件

避免上传文件的攻击

       对于文件上传这块,核心的就是要进行白名单校验,限制上传文件的类型,只能是我们指定的,而且要限制文件的大小,还要对文件重命名,限制文件类型不能简单的根据后缀来判断,可能后缀被篡改了,要根据文件二进制数据的开头几个字节代表的magic number来判断文件的类型
       读取这个文件的二进制数据流,读取开头的几个字节,提取这个文件的魔数,根据魔数的值去判断他是什么类型的
       FFD8FF:JEPG,89504E47:PNG

===================================================
传送门:
常见JAVA面试题总结<2020 java面试必备>(四)设计模式
常见JAVA面试题总结<2020 java面试必备>(三)JVM
常见JAVA面试题总结<2020 java面试必备>(二)多线程
常见JAVA面试题总结<2020 java面试必备>(一)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值