精华内容
下载资源
问答
  • 网络编程面试题(2020最新版)

    万次阅读 多人点赞 2020-03-16 17:36:28
    TCP/IP 协议族应用层运输层网络层数据链路层物理层TCP/IP 协议族TCP的三次握手四次挥手TCP报文的头部结构三次握手四次挥手常见面试题为什么TCP连接的时候是3次?2次不可以吗?为什么TCP连接的时候是3次,关闭的时候...

    大家好,我是CSDN的博主ThinkWon,“2020博客之星年度总评选"开始啦,希望大家帮我投票,每天都可以投多票哦,点击下方链接,然后点击"最大”,再点击"投TA一票"就可以啦!
    投票链接:https://bss.csdn.net/m/topic/blog_star2020/detail?username=thinkwon
    在技术的世界里,ThinkWon将一路与你相伴!创作出更多更高质量的文章!2020为努力奋斗的你点赞👍,️新的一年,祝各位大牛牛气冲天,牛年大吉!😊😊

    计算机网络体系结构

    在计算机网络的基本概念中,分层次的体系结构是最基本的。计算机网络体系结构的抽象概念较多,在学习时要多思考。这些概念对后面的学习很有帮助。

    网络协议是什么?

    在计算机网络要做到有条不紊地交换数据,就必须遵守一些事先约定好的规则,比如交换数据的格式、是否需要发送一个应答信息。这些规则被称为网络协议。

    为什么要对网络协议分层?

    • 简化问题难度和复杂度。由于各层之间独立,我们可以分割大问题为小问题。
    • 灵活性好。当其中一层的技术变化时,只要层间接口关系保持不变,其他层不受影响。
    • 易于实现和维护。
    • 促进标准化工作。分开后,每层功能可以相对简单地被描述。

    网络协议分层的缺点: 功能可能出现在多个层里,产生了额外开销。

    为了使不同体系结构的计算机网络都能互联,国际标准化组织 ISO 于1977年提出了一个试图使各种计算机在世界范围内互联成网的标准框架,即著名的开放系统互联基本参考模型 OSI/RM,简称为OSI。

    OSI 的七层协议体系结构的概念清楚,理论也较完整,但它既复杂又不实用,TCP/IP 体系结构则不同,但它现在却得到了非常广泛的应用。TCP/IP 是一个四层体系结构,它包含应用层,运输层,网际层和网络接口层(用网际层这个名字是强调这一层是为了解决不同网络的互连问题),不过从实质上讲,TCP/IP 只有最上面的三层,因为最下面的网络接口层并没有什么具体内容,因此在学习计算机网络的原理时往往采用折中的办法,即综合 OSI 和 TCP/IP 的优点,采用一种只有五层协议的体系结构,这样既简洁又能将概念阐述清楚,有时为了方便,也可把最底下两层称为网络接口层。

    四层协议,五层协议和七层协议的关系如下:

    • TCP/IP是一个四层的体系结构,主要包括:应用层、运输层、网际层和网络接口层。
    • 五层协议的体系结构主要包括:应用层、运输层、网络层,数据链路层和物理层。
    • OSI七层协议模型主要包括是:应用层(Application)、表示层(Presentation)、会话层(Session)、运输层(Transport)、网络层(Network)、数据链路层(Data Link)、物理层(Physical)。

    在这里插入图片描述

    注:五层协议的体系结构只是为了介绍网络原理而设计的,实际应用还是 TCP/IP 四层体系结构。

    TCP/IP 协议族

    应用层

    应用层( application-layer )的任务是通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。

    对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如域名系统 DNS,支持万维网应用的 HTTP 协议,支持电子邮件的 SMTP 协议等等。

    运输层

    运输层(transport layer)的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务。应用进程利用该服务传送应用层报文。

    运输层主要使用一下两种协议

    1. 传输控制协议-TCP:提供面向连接的,可靠的数据传输服务。
    2. 用户数据协议-UDP:提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。
    UDP TCP
    是否连接 无连接 面向连接
    是否可靠 不可靠传输,不使用流量控制和拥塞控制 可靠传输,使用流量控制和拥塞控制
    连接对象个数 支持一对一,一对多,多对一和多对多交互通信 只能是一对一通信
    传输方式 面向报文 面向字节流
    首部开销 首部开销小,仅8字节 首部最小20字节,最大60字节
    场景 适用于实时应用(IP电话、视频会议、直播等) 适用于要求可靠传输的应用,例如文件传输

    每一个应用层(TCP/IP参考模型的最高层)协议一般都会使用到两个传输层协议之一:

    运行在TCP协议上的协议:

    • HTTP(Hypertext Transfer Protocol,超文本传输协议),主要用于普通浏览。
    • HTTPS(HTTP over SSL,安全超文本传输协议),HTTP协议的安全版本。
    • FTP(File Transfer Protocol,文件传输协议),用于文件传输。
    • POP3(Post Office Protocol, version 3,邮局协议),收邮件用。
    • SMTP(Simple Mail Transfer Protocol,简单邮件传输协议),用来发送电子邮件。
    • TELNET(Teletype over the Network,网络电传),通过一个终端(terminal)登陆到网络。
    • SSH(Secure Shell,用于替代安全性差的TELNET),用于加密安全登陆用。

    运行在UDP协议上的协议:

    • BOOTP(Boot Protocol,启动协议),应用于无盘设备。
    • NTP(Network Time Protocol,网络时间协议),用于网络同步。
    • DHCP(Dynamic Host Configuration Protocol,动态主机配置协议),动态配置IP地址。

    运行在TCPUDP协议上:

    • DNS(Domain Name Service,域名服务),用于完成地址查找,邮件转发等工作。

    网络层

    网络层的任务就是选择合适的网间路由和交换结点,确保计算机通信的数据及时传送。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在 TCP/IP 体系结构中,由于网络层使用 IP 协议,因此分组也叫 IP 数据报 ,简称数据报。

    互联网是由大量的异构(heterogeneous)网络通过路由器(router)相互连接起来的。互联网使用的网络层协议是无连接的网际协议(Intert Prococol)和许多路由选择协议,因此互联网的网络层也叫做网际层或 IP 层。

    数据链路层

    数据链路层(data link layer)通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。

    在两个相邻节点之间传送数据时,数据链路层将网络层交下来的 IP 数据报组装成帧,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。

    在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。

    一般的web应用的通信传输流是这样的:

    img

    发送端在层与层之间传输数据时,每经过一层时会被打上一个该层所属的首部信息。反之,接收端在层与层之间传输数据时,每经过一层时会把对应的首部信息去除。

    物理层

    在物理层上所传送的数据单位是比特。 物理层(physical layer)的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。

    TCP/IP 协议族

    在互联网使用的各种协议中最重要和最著名的就是 TCP/IP 两个协议。现在人们经常提到的 TCP/IP 并不一定是单指 TCP 和 IP 这两个具体的协议,而往往是表示互联网所使用的整个 TCP/IP 协议族。

    img

    互联网协议套件(英语:Internet Protocol Suite,缩写IPS)是一个网络通讯模型,以及一整个网络传输协议家族,为网际网络的基础通讯架构。它常被通称为TCP/IP协议族(英语:TCP/IP Protocol Suite,或TCP/IP Protocols),简称TCP/IP。因为该协定家族的两个核心协定:TCP(传输控制协议)和IP(网际协议),为该家族中最早通过的标准。

    划重点:

    TCP(传输控制协议)和IP(网际协议) 是最先定义的两个核心协议,所以才统称为TCP/IP协议族

    TCP的三次握手四次挥手

    TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的“连接”,其实是客户端和服务端保存的一份关于对方的信息,如ip地址、端口号等。

    TCP可以看成是一种字节流,它会处理IP层或以下的层的丢包、重复以及错误问题。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放在TCP头部。

    一个TCP连接由一个4元组构成,分别是两个IP地址和两个端口号。一个TCP连接通常分为三个阶段:连接、数据传输、退出(关闭)。通过三次握手建立一个链接,通过四次挥手来关闭一个连接

    当一个连接被建立或被终止时,交换的报文段只包含TCP头部,而没有数据

    TCP报文的头部结构

    在了解TCP连接之前先来了解一下TCP报文的头部结构。

    TCPHeader.png

    上图中有几个字段需要重点介绍下:

    (1)序号:seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。

    (2)确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。

    (3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:

    • ACK:确认序号有效。
    • FIN:释放一个连接。
    • PSH:接收方应该尽快将这个报文交给应用层。
    • RST:重置连接。
    • SYN:发起一个新连接。
    • URG:紧急指针(urgent pointer)有效。

    需要注意的是:

    • 不要将确认序号ack与标志位中的ACK搞混了。
    • 确认方ack=发起方seq+1,两端配对。

    三次握手

    三次握手的本质是确认通信双方收发数据的能力

    首先,我让信使运输一份信件给对方,对方收到了,那么他就知道了我的发件能力和他的收件能力是可以的

    于是他给我回信,我若收到了,我便知我的发件能力和他的收件能力是可以的,并且他的发件能力和我的收件能力是可以

    然而此时他还不知道他的发件能力和我的收件能力到底可不可以,于是我最后回馈一次,他若收到了,他便清楚了他的发件能力和我的收件能力是可以的

    这,就是三次握手,这样说,你理解了吗?

    三次握手.png

    • 第一次握手:客户端要向服务端发起连接请求,首先客户端随机生成一个起始序列号ISN(比如是100),那客户端向服务端发送的报文段包含SYN标志位(也就是SYN=1),序列号seq=100。
    • 第二次握手:服务端收到客户端发过来的报文后,发现SYN=1,知道这是一个连接请求,于是将客户端的起始序列号100存起来,并且随机生成一个服务端的起始序列号(比如是300)。然后给客户端回复一段报文,回复报文包含SYN和ACK标志(也就是SYN=1,ACK=1)、序列号seq=300、确认号ack=101(客户端发过来的序列号+1)。
    • 第三次握手:客户端收到服务端的回复后发现ACK=1并且ack=101,于是知道服务端已经收到了序列号为100的那段报文;同时发现SYN=1,知道了服务端同意了这次连接,于是就将服务端的序列号300给存下来。然后客户端再回复一段报文给服务端,报文包含ACK标志位(ACK=1)、ack=301(服务端序列号+1)、seq=101(第一次握手时发送报文是占据一个序列号的,所以这次seq就从101开始,需要注意的是不携带数据的ACK报文是不占据序列号的,所以后面第一次正式发送数据时seq还是101)。当服务端收到报文后发现ACK=1并且ack=301,就知道客户端收到序列号为300的报文了,就这样客户端和服务端通过TCP建立了连接。

    四次挥手

    四次挥手的目的是关闭一个连接

    四次挥手.jpeg

    比如客户端初始化的序列号ISA=100,服务端初始化的序列号ISA=300。TCP连接成功后客户端总共发送了1000个字节的数据,服务端在客户端发FIN报文前总共回复了2000个字节的数据。

    • 第一次挥手:当客户端的数据都传输完成后,客户端向服务端发出连接释放报文(当然数据没发完时也可以发送连接释放报文并停止发送数据),释放连接报文包含FIN标志位(FIN=1)、序列号seq=1101(100+1+1000,其中的1是建立连接时占的一个序列号)。需要注意的是客户端发出FIN报文段后只是不能发数据了,但是还可以正常收数据;另外FIN报文段即使不携带数据也要占据一个序列号。
    • 第二次挥手:服务端收到客户端发的FIN报文后给客户端回复确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=1102(客户端FIN报文序列号1101+1)、序列号seq=2300(300+2000)。此时服务端处于关闭等待状态,而不是立马给客户端发FIN报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完。
    • 第三次挥手:服务端将最后数据(比如50个字节)发送完毕后就向客户端发出连接释放报文,报文包含FIN和ACK标志位(FIN=1,ACK=1)、确认号和第二次挥手一样ack=1102、序列号seq=2350(2300+50)。
    • 第四次挥手:客户端收到服务端发的FIN报文后,向服务端发出确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=2351、序列号seq=1102。注意客户端发出确认报文后不是立马释放TCP连接,而是要经过2MSL(最长报文段寿命的2倍时长)后才释放TCP连接。而服务端一旦收到客户端发出的确认报文就会立马释放TCP连接,所以服务端结束TCP连接的时间要比客户端早一些。

    常见面试题

    为什么TCP连接的时候是3次?2次不可以吗?

    因为需要考虑连接时丢包的问题,如果只握手2次,第二次握手时如果服务端发给客户端的确认报文段丢失,此时服务端已经准备好了收发数(可以理解服务端已经连接成功)据,而客户端一直没收到服务端的确认报文,所以客户端就不知道服务端是否已经准备好了(可以理解为客户端未连接成功),这种情况下客户端不会给服务端发数据,也会忽略服务端发过来的数据。

    如果是三次握手,即便发生丢包也不会有问题,比如如果第三次握手客户端发的确认ack报文丢失,服务端在一段时间内没有收到确认ack报文的话就会重新进行第二次握手,也就是服务端会重发SYN报文段,客户端收到重发的报文段后会再次给服务端发送确认ack报文。

    为什么TCP连接的时候是3次,关闭的时候却是4次?

    因为只有在客户端和服务端都没有数据要发送的时候才能断开TCP。而客户端发出FIN报文时只能保证客户端没有数据发了,服务端还有没有数据发客户端是不知道的。而服务端收到客户端的FIN报文后只能先回复客户端一个确认报文来告诉客户端我服务端已经收到你的FIN报文了,但我服务端还有一些数据没发完,等这些数据发完了服务端才能给客户端发FIN报文(所以不能一次性将确认报文和FIN报文发给客户端,就是这里多出来了一次)。

    为什么客户端发出第四次挥手的确认报文后要等2MSL的时间才能释放TCP连接?

    这里同样是要考虑丢包的问题,如果第四次挥手的报文丢失,服务端没收到确认ack报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是2MSL,所以需要等这么长时间来确认服务端确实已经收到了。

    如果已经建立了连接,但是客户端突然出现故障了怎么办?

    TCP设有一个保活计时器,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

    什么是HTTP,HTTP 与 HTTPS 的区别

    HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范

    区别 HTTP HTTPS
    协议 运行在 TCP 之上,明文传输,客户端与服务器端都无法验证对方的身份 身披 SSL( Secure Socket Layer )外壳的 HTTP,运行于 SSL 上,SSL 运行于 TCP 之上, 是添加了加密和认证机制的 HTTP
    端口 80 443
    资源消耗 较少 由于加解密处理,会消耗更多的 CPU 和内存资源
    开销 无需证书 需要证书,而证书一般需要向认证机构购买
    加密机制 共享密钥加密和公开密钥加密并用的混合加密机制
    安全性 由于加密机制,安全性强

    常用HTTP状态码

    HTTP状态码表示客户端HTTP请求的返回结果、标识服务器处理是否正常、表明请求出现的错误等。

    状态码的类别:

    类别 原因短语
    1XX Informational(信息性状态码) 接受的请求正在处理
    2XX Success(成功状态码) 请求正常处理完毕
    3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
    4XX Client Error(客户端错误状态码) 服务器无法处理请求
    5XX Server Error(服务器错误状态码) 服务器处理请求出错

    常用HTTP状态码:

    2XX 成功(这系列表明请求被正常处理了)
    200 OK,表示从客户端发来的请求在服务器端被正确处理
    204 No content,表示请求成功,但响应报文不含实体的主体部分
    206 Partial Content,进行范围请求成功
    3XX 重定向(表明浏览器要执行特殊处理)
    301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
    302 found,临时性重定向,表示资源临时被分配了新的 URL
    303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源(对于301/302/303响应,几乎所有浏览器都会删除报文主体并自动用GET重新请求)
    304 not modified,表示服务器允许访问资源,但请求未满足条件的情况(与重定向无关)
    307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求
    4XX 客户端错误
    400 bad request,请求报文存在语法错误
    401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
    403 forbidden,表示对请求资源的访问被服务器拒绝,可在实体主体部分返回原因描述
    404 not found,表示在服务器上没有找到请求的资源
    5XX 服务器错误
    500 internal sever error,表示服务器端在执行请求时发生了错误
    501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
    503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求

    GET和POST区别

    说道GET和POST,就不得不提HTTP协议,因为浏览器和服务器的交互是通过HTTP协议执行的,而GET和POST也是HTTP协议中的两种方法。

    HTTP全称为Hyper Text Transfer Protocol,中文翻译为超文本传输协议,目的是保证浏览器与服务器之间的通信。HTTP的工作方式是客户端与服务器之间的请求-应答协议。

    HTTP协议中定义了浏览器和服务器进行交互的不同方法,基本方法有4种,分别是GET,POST,PUT,DELETE。这四种方法可以理解为,对服务器资源的查,改,增,删。

    • GET:从服务器上获取数据,也就是所谓的查,仅仅是获取服务器资源,不进行修改。
    • POST:向服务器提交数据,这就涉及到了数据的更新,也就是更改服务器的数据。
    • PUT:英文含义是放置,也就是向服务器新添加数据,就是所谓的增。
    • DELETE:从字面意思也能看出,这种方式就是删除服务器数据的过程。

    GET和POST区别

    1. Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的。 但是这种做法也不时绝对的,大部分人的做法也是按照上面的说法来的,但是也可以在get请求加上 request body,给 post请求带上 URL 参数。

    2. Get请求提交的url中的数据最多只能是2048字节,这个限制是浏览器或者服务器给添加的,http协议并没有对url长度进行限制,目的是为了保证服务器和浏览器能够正常运行,防止有人恶意发送请求。Post请求则没有大小限制。

    3. Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集。

    4. Get执行效率却比Post方法好。Get是form提交的默认方法。

    5. GET产生一个TCP数据包;POST产生两个TCP数据包。

      对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

      而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

    什么是对称加密与非对称加密

    对称密钥加密是指加密和解密使用同一个密钥的方式,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方;

    而非对称加密是指使用一对非对称密钥,即公钥和私钥,公钥可以随意发布,但私钥只有自己知道。发送密文的一方使用对方的公钥进行加密处理,对方接收到加密信息后,使用自己的私钥进行解密。
    由于非对称加密的方式不需要发送用来解密的私钥,所以可以保证安全性;但是和对称加密比起来,非常的慢

    什么是HTTP2

    HTTP2 可以提高了网页的性能。

    在 HTTP1 中浏览器限制了同一个域名下的请求数量(Chrome 下一般是六个),当在请求很多资源的时候,由于队头阻塞当浏览器达到最大请求数量时,剩余的资源需等待当前的六个请求完成后才能发起请求。

    HTTP2 中引入了多路复用的技术,这个技术可以只通过一个 TCP 连接就可以传输所有的请求数据。多路复用可以绕过浏览器限制同一个域名下的请求数量的问题,进而提高了网页的性能。

    Session、Cookie和Token的主要区别

    HTTP协议本身是无状态的。什么是无状态呢,即服务器无法判断用户身份。

    什么是cookie

    cookie是由Web服务器保存在用户浏览器上的小文件(key-value格式),包含用户相关的信息。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户身份。

    什么是session

    session是依赖Cookie实现的。session是服务器端对象

    session 是浏览器和服务器会话过程中,服务器分配的一块储存空间。服务器默认为浏览器在cookie中设置 sessionid,浏览器在向服务器请求过程中传输 cookie 包含 sessionid ,服务器根据 sessionid 获取出会话中存储的信息,然后确定会话的身份信息。

    cookie与session区别

    • 存储位置与安全性:cookie数据存放在客户端上,安全性较差,session数据放在服务器上,安全性相对更高;
    • 存储空间:单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie,session无此限制
    • 占用服务器资源:session一定时间内保存在服务器上,当访问增多,占用服务器性能,考虑到服务器性能方面,应当使用cookie。

    什么是Token

    Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。

    Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。

    使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。

    Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位

    session与token区别

    • session机制存在服务器压力增大,CSRF跨站伪造请求攻击,扩展性不强等问题;
    • session存储在服务器端,token存储在客户端
    • token提供认证和授权功能,作为身份认证,token安全性比session好;
    • session这种会话存储方式方式只适用于客户端代码和服务端代码运行在同一台服务器上,token适用于项目级的前后端分离(前后端代码运行在不同的服务器下)

    Servlet是线程安全的吗

    Servlet不是线程安全的,多线程并发的读写会导致数据不同步的问题。

    解决的办法是尽量不要定义name属性,而是要把name变量分别定义在doGet()和doPost()方法内。虽然使用synchronized(name){}语句块可以解决问题,但是会造成线程的等待,不是很科学的办法。

    注意:多线程的并发的读写Servlet类属性会导致数据不同步。但是如果只是并发地读取属性而不写入,则不存在数据不同步的问题。因此Servlet里的只读属性最好定义为final类型的。

    Servlet接口中有哪些方法及Servlet生命周期探秘

    在Java Web程序中,Servlet主要负责接收用户请求HttpServletRequest,在doGet()doPost()中做相应的处理,并将回应HttpServletResponse反馈给用户。Servlet可以设置初始化参数,供Servlet内部使用。

    Servlet接口定义了5个方法,其中前三个方法与Servlet生命周期相关

    • void init(ServletConfig config) throws ServletException
    • void service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException
    • void destory()
    • java.lang.String getServletInfo()
    • ServletConfig getServletConfig()

    生命周期:

    Web容器加载Servlet并将其实例化后,Servlet生命周期开始,容器运行其init()方法进行Servlet的初始化;

    请求到达时调用Servlet的service()方法,service()方法会根据需要调用与请求对应的doGet或doPost等方法;

    当服务器关闭或项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的destroy()方法

    init方法和destory方法只会执行一次,service方法客户端每次请求Servlet都会执行。Servlet中有时会用到一些需要初始化与销毁的资源,因此可以把初始化资源的代码放入init方法中,销毁资源的代码放入destroy方法中,这样就不需要每次处理客户端的请求都要初始化与销毁资源。

    如果客户端禁止 cookie 能实现 session 还能用吗?

    Cookie 与 Session,一般认为是两个独立的东西,Session采用的是在服务器端保持状态的方案,而Cookie采用的是在客户端保持状态的方案。

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

    假定用户关闭Cookie的情况下使用Session,其实现途径有以下几种:

    1. 手动通过URL传值、隐藏表单传递Session ID。
    2. 用文件、数据库等形式保存Session ID,在跨页过程中手动调用。
    展开全文
  • 网络编程面试题

    千次阅读 2019-11-10 17:39:17
    网络编程面试题 1、tcp和udp的区别 TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时...
    网络编程面试题 
     
    1、tcp和udp的区别
    TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
    UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快
     
    2、流量控制和拥塞控制
    拥塞控制 --- 网络拥塞现象是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信业务陷入停顿,即出现死锁现象。拥塞控制是处理网络拥塞现象的一种机制。
    流量控制 --- 数据的传送与接收过程当中很可能出现收方来不及接收的情况,这时就需要对发方进行控制,以免数据丢失。流量控制用于防止在端口阻塞的情况下丢帧,这种方法是当发送或接收缓冲区开始溢出时通过将阻塞信号发送回源地址实现的。流量控制可以有效的防止由于网络中瞬间的大量数据对网络带来的冲击,保证用户网络高效而稳定的运行。
     
    3、多线程如何同步
    windows --- 线程同步有四种方式:临界区、内核对象、互斥量、信号量。
    Linux --- 线程同步有最常用的是:互斥锁、条件变量和信号量。
     
    4、进程间通讯的方式有哪些,各有什么优缺点
    Linux 进程间通信(IPC)以下以几部分发展而来:UNIX进程间通信、基于System V进程间通信、基于Socket进程间通信和POSIX进程间通信。
    UNIX进程间通信方式包括:管道、FIFO、信号。
    System V进程间通信方式包括:System V消息队列、System V信号灯、System V共享内存
    POSIX进程间通信包括:posix消息队列、posix信号灯、posix共享内存。
    现在linux使用的进程间通信方式:
    (1)管道(pipe)和有名管道(FIFO)
    (2)信号(signal)
    (3)消息队列
    (4)共享内存
    (5)信号量
    (6)套接字(socket)
     
    管道:
    优点是所有的UNIX实现都支持, 并且在最后一个访问管道的进程终止后,管道就被完全删除;
    缺陷是管道只允许单向传输或者用于父子进程之间
    系统IPC:
    优点是功能强大,能在毫不相关进程之间进行通讯;
    缺陷是关键字KEY_T使用了内核标识,占用了内核资源,而且只能被显式删除,而且不能使用SOCKET的一些机制,例如select,epoll等.
    socket可以跨网络通讯,其他进程间通讯的方式都不可以,只能是本机进程通讯。
     
    5、tcp连接建立的时候3次握手,断开连接的4次握手的具体过程
    三次握手 --- 第一次握手是客户端connect连接到server,server accept client的请求之后,向client端发送一个消息,相当于说我都准备好了,你连接上我了,这是第二次握手,第3次握手就是client向server发送的,就是对第二次握手消息的确认。之后client和server就开始通讯了。
    四次握手 --- 断开连接的一端发送close请求是第一次握手,另外一端接收到断开连接的请求之后需要对close进行确认,发送一个消息,这是第二次握手,发送了确认消息之后还要向对端发送close消息,要关闭对对端的连接,这是第3次握手,而在最初发送断开连接的一端接收到消息之后,进入到一个很重要的状态time_wait状态,这个状态也是面试官经常问道的问题,最后一次握手是最初发送断开连接的一端接收到消息之后。对消息的确认。
     
    6、epoll与select的区别
    1)select在一个进程中打开的最大fd是有限制的,由FD_SETSIZE设置,默认值是2048。不过 epoll则没有这个限制,它所支持的fd上限是最大可以打开文件的数目,这个数字一般远大于2048,一般来说内存越大,fd上限越大,1G内存都能达到大约10w左右。
    2)select的轮询机制是系统会去查找每个fd是否数据已准备好,当fd很多的时候,效率当然就直线下降了,epoll采用基于事件的通知方式,一旦某个fd数据就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,而不需要不断的去轮询查找就绪的描述符,这就是epoll高效最本质的原因。
    3)无论是select还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的,而select则做了不必要的拷贝
     
    7、epoll中et和lt的区别与实现原理
    LT:水平触发,效率会低于ET触发,尤其在大并发,大流量的情况下。但是LT对代码编写要求比较低,不容易出现问题。LT模式服务编写上的表现是:只要有数据没有被获取,内核就不断通知你,因此不用担心事件丢失的情况。
    ET:边缘触发,效率非常高,在并发,大流量的情况下,会比LT少很多epoll的系统调用,因此效率高。但是对编程要求高,需要细致的处理每个请求,否则容易发生丢失事件的情况。
     
    8、connect方法会阻塞,请问有什么方法可以避免其长时间阻塞?
    最通常的方法最有效的是加定时器;也可以采用非阻塞模式。
    或者考虑采用异步传输机制,同步传输与异步传输的主要区别在于同步传输中,如果调用recvfrom后会一致阻塞运行,从而导致调用线程暂停运行;异步传输机制则不然,会立即返回。
     
    9、网络中,如果客户端突然掉线或者重启,服务器端怎么样才能立刻知道?
    答:若客户端掉线或者重新启动,服务器端会收到复位信号,每一种tcp/ip得实现不一样,控制机制也不一样。

    10、在子网210.27.48.21/30种有多少个可用地址?分别是什么?
    简: 30表示的是网络号(network number)是30位,剩下2位中11是广播(broadcast)地址,00是multicast地址,只有01和10可以作为host address。
    详: 210.27.48.21/30代表的子网的网络号是30位,即网络号是210.27.48.21 & 255.255.255.251=210.27.48.20,此子网的地址空间是2位,即可以有4个地址:210.27.48.20, 210.27.48.21, 210.27.48.22, 210.27.48.23。第一个地址的主机号(host number/id)是0,而主机号0代表的是multicast地址。最后一个地址的最后两位是11,主机号每一位都为1代表的是广播(broadcast)地址。所以只有中间两个地址可以给host使用。其实那个问题本身不准确,广播或multicast地止也是可以使用的地址,所以回答4也应该正确,当然问的人也可能是想要你回答2。我个人觉得最好的回答是一个广播地址,一个multicast地址,2个unicast地址。

    11、TTL是什么?有什么用处,通常那些工具会用到它?(ping? traceroute? ifconfig? netstat?)
    简: TTL是Time To Live,一般是hup count,每经过一个路由就会被减去一,如果它变成0,包会被丢掉。它的主要目的是防止包在有回路的网络上死转,浪费网络资源。ping和traceroute用到它。
    详: TTL是Time To Live,目前是hup count,当包每经过一个路由器它就会被减去一,如果它变成0,路由器就会把包丢掉。IP网络往往带有环(loop),比如子网A和子网B有两个路由器相连,它就是一个loop。TTL的主要目的是防止包在有回路的网络上死转,因为包的TTL最终后变成0而使得此包从网上消失(此时往往路由器会送一个ICMP包回来,traceroute就是根据这个做的)。ping会送包出去,所以里面有它,但是ping不一定非要不可它。traceroute则是完全因为有它才能成的。ifconfig是用来配置网卡的,netstat -rn 是用来列路由表的,所以都用不着它

    12、路由表示做什么用的?在linux环境中怎么来配置一条默认路由?
    简: 路由表是用来决定如何将包从一个子网传送到另一个子网的,换局话说就是用来决定从一个网卡接收到的包应该送的哪一张网卡上的。在Linux上可以用“route add default gw <默认路由器IP>”来配置一条默认路由。
    详: 路由表是用来决定如何将包从一个子网传送到另一个子网的,换局话说就是用来决定从一个网卡接收到的包应该送的哪一张网卡上的。路由表的每一行至少有目标网络号、netmask、到这个子网应该使用的网卡。当路由器从一个网卡接收到一个包时,它扫描路由表的每一行,用里面的netmask和包里的目标IP地址做并逻辑运算(&)找出目标网络号,如果此网络号和这一行里的网络号相同就将这条路由保留下来做为备用路由,如果已经有备用路由了就在这两条路由里将网络号最长的留下来,另一条丢掉,如此接着扫描下一行直到结束。如果扫描结束任没有找到任何路由,就用默认路由。确定路由后,直接将包送到对应的网卡上去。在具体的实现中,路由表可能包含更多的信息为选路由算法的细节所用。题外话:路由算法其实效率很差,而且不scalable,解决办法是使用IP交换机,比如MPLS。
    在Linux上可以用“route add default gw <默认路由器IP>”来配置一条默认路由。

    13、在网络中有两台主机A和B,并通过路由器和其他交换设备连接起来,已经确认物理连接正确无误,怎么来测试这两台机器是否连通?如果不通,怎么来判断故障点?怎么排除故障?
    答:测试这两台机器是否连通:从一台机器ping另一台机器,如果ping不通,用traceroute可以确定是哪个路由器不能连通,然后再找问题是在交换设备/hup/cable等。

    14、网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别? 
    答案一:
    1)进程:子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。
    2)线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
    两者都可以提高程序的并发度,提高程序运行效率和响应时间。
    线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

    答案二:
    根本区别就一点:用多进程每个进程有自己的地址空间(address space),线程则共享地址空间。所有其它区别都是由此而来的:
    1)速度:线程产生的速度快,线程间的通讯快、切换快等,因为他们在同一个地址空间内。
    2)资源利用率:线程的资源利用率比较好也是因为他们在同一个地址空间内。
    3)同步问题:线程使用公共变量/内存时需要使用同步机制还是因为他们在同一个地址空间内。
     
    15、 网络编程的一般步骤
    对于TCP连接:
    1.服务器端1)创建套接字create;2)绑定端口号bind;3)监听连接listen;4)接受连接请求accept,并返回新的套接字;5)用新返回的套接字recv/send;6)关闭套接字。
    2.客户端1)创建套接字create; 2)发起建立连接请求connect; 3)发送/接收数据send/recv;4)关闭套接字。
    TCP总结:
    Server端:create -- bind -- listen--  accept--  recv/send-- close
    Client端:create------- conncet------send/recv------close.
     
    对于UDP连接:
    1.服务器端:1)创建套接字create;2)绑定端口号bind;3)接收/发送消息recvfrom/sendto;4)关闭套接字。
    2.客户端:1)创建套接字create;2)发送/接收消息sendto/recvfrom;3)关闭套接字.
    UDP总结:
    Server端:create----bind ----recvfrom/sendto----close
    Client端:create----  sendto/recvfrom----close.
     
    16、TCP的重发机制是怎么实现的?
    1)滑动窗口机制,确立收发的边界,能让发送方知道已经发送了多少(已确认)、尚未确认的字节数、尚待发送的字节数;让接收方知道(已经确认收到的字节数)。
    2)选择重传,用于对传输出错的序列进行重传。
     
    17、TCP为什么不是两次连接?而是三次握手?
    如果A与B两个进程通信,如果仅是两次连接。可能出现的一种情况就是:A发送完请报文以后,由于网络情况不好,出现了网络拥塞,即B延时很长时间后收到报文,即此时A将此报文认定为失效的报文。B收到报文后,会向A发起连接。此时两次握手完毕,B会认为已经建立了连接可以通信,B会一直等到A发送的连接请求,而A对失效的报文回复自然不会处理。依次会陷入B忙等的僵局,造成资源的浪费。
     
    18、C++模板的作用。 
    将算法与具体对象分离,与类型无关,通用,节省精力
     
    19、socket编程,如果client断电了,服务器如何快速知道???
    使用定时器(适合有数据流动的情况); 使用socket选项SO_KEEPALIVE(适合没有数据流动的情况); 
     
    20、fork()一子进程程后 父进程癿全局变量能不能使用???
    fork后子进程将会拥有父进程的几乎一切资源,父子进程的都各自有自己的全局变量。不能通用,不同于线程。对于线程,各个线程共享全局变量。
     
    21、4G的long型整数中找到一个最大的,如何做????
    要找到最大的肯定要遍历所有的数的,而且不能将数据全部读入内存,可能不足。算法的时间复杂度肯定是O(n)
    感觉就是遍历,比较。。。。还能怎么改进呢????
    可以改进的地方,就是读入内存的时候,一次多读些。。。。
    需要注意的就是每次从磁盘上尽量多读一些数到内存区,然后处理完之后再读入一批。减少IO次数,自然能够提高效率。而对于类快速排序方法,稍微要麻烦一些: 分批读入,假设是M个数,然后从这M个数中选出n个最大的数缓存起来,直到所有的N个数都分批处理完之后,再将各批次缓存的n个数合并起来再进行一次类快 速排序得到最终的n个最大的数就可以了。在运行过程中,如果缓存数太多,可以不断地将多个缓存合并,保留这些缓存中最大的n个数即可。由于类快速排序的时 间复杂度是O(N),这样分批处理再合并的办法,依然有极大的可能会比堆和败者树更优。当然,在空间上会占用较多的内存。 
     
    此题还有个变种,就是寻找K个最大或者最小的数。有以下几种算法:
    容量为K的最大堆/最小堆,假设K可以装入内存;
    如果N个数可以装入内存,且都小于MAX,那么可以开辟一个MAX大的数组,类似计数排序。。。从数组尾部扫描K个最大的数,头部扫描K个最小的数。
     
    22、有千万个string在内存怎么高速查找,插入和删除???
    对千万个string做hash,可以实现高速查找,找到了,插入和删除就很方便了。
     
    23、tcp三次握手的过程,accept发生在三次握手哪个阶段?
    client 的 connect  引起3次握手
    server 在socket, bind, listen后,阻塞在accept,三次握手完成后,accept返回一个fd,因此accept发生在三次握手之后。。。。。。
     
    24、Tcp流, udp的数据报,之间有什么区别,为什么TCP要叫做数据流?
    TCP本身是面向连接的协议,S和C之间要使用TCP,必须先建立连接,数据就在该连接上流动,可以是双向的,没有边界。所以叫数据流 ,占系统资源多
    UDP不是面向连接的,不存在建立连接,释放连接,每个数据包都是独立的包,有边界,一般不会合并。
    TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证
     
    25、volatile的含义。
    变量可能在编译器的控制或监控之外改变,告诉编译器不要优化该变量,如被系统时钟更新的变量。
     
    26、OFFSETOF(s, m)的宏定义,s是结构类型,m是s的成员,求m在s中的偏移量。
    #define OFFSETOF(s, m) size_t(&((s*)0)->m)
     
    27、socket在什么情况下可读?
    1. 接收缓冲区有数据,一定可读
    2. 对方正常关闭socket,也是可读
    3. 对于侦听socket,有新连接到达也可读
    4.socket有错误发生,且pending
     
    28、流量控制与拥塞控制的区别,节点计算机怎样感知网络拥塞了???
    拥塞控制是把整体看成一个处理对象的,流量控制是对单个的节点。
    感知的手段应该不少,比如在TCP协议里,TCP报文的重传本身就可以作为拥塞的依据。依据这样的原理, 应该可以设计出很多手段。
     
    29、C++虚函数是如何实现的???
    使用虚函数表。 C++对象使用虚表, 如果是基类的实例,对应位置存放的是基类的函数指针;如果是继承类,对应位置存放的是继承类的函数指针(如果在继承类有实现)。所以 ,当使用基类指针调用对象方法时,也会根据具体的实例,调用到继承类的方法。 
     
    30、C++的虚函数有什么作用? ??
    虚函数作用是实现多态,更重要的,虚函数其实是实现封装,使得使用者不需要关心实现的细节。在很多设计模式中都是这样用法,例如Factory、Bridge、Strategy模式。 
     
    31、 TCP通讯中,select到读事件,但是读到的数据量是0,为什么,如何解决????
    select 返回0代表超时。select出错返回-1。
    select到读事件,但是读到的数据量为0,说明对方已经关闭了socket的读端。本端关闭读即可。
    当select出错时,会将接口置为可读又可写。这时就要通过判断select的返回值为-1来区分。
     
    32、给出float与“零值”比较的 if 语句(假设变量名为var)???
    const float EPSINON = 0.00001;
    if ((x >= - EPSINON) && (x <= EPSINON)
     
    展开全文
  • 爬虫及网络编程面试题.pdf
  • java网络编程面试题

    万次阅读 2017-08-08 11:59:26
    java网络编程面试题

    1.网络编程时的同步、异步、阻塞、非阻塞?

    同步:函数调用在没得到结果之前,没有调用结果,不返回任何结果。
    异步:函数调用在没得到结果之前,没有调用结果,返回状态信息。
    阻塞:函数调用在没得到结果之前,当前线程挂起。得到结果后才返回。
    非阻塞:函数调用在没得到结果之前,当前线程不会挂起,立即返回结果。

    2.Java如何实现无阻塞方式的Socket编程?

    NIO有效解决了多线程服务器存在的线程开销问题。

    NIO中使用多线程主要目的不是为了应对每个客户端请求而分配独立的服务线程,

    而是通过多线程充分利用多个CPU的处理能力和处理中的等待时间,达到提高服务能力的目的。

    3.什么是java 的序列化(串行化)

    简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),

    并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。

    4.什么情况下需要序列化?序列化的注意事项,如何实现java 序列化(串行化)

    · 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;

    · 当你想用套接字在网络上传送对象的时候;

    · 当你想通过RMI传输对象的时候;

    序列化注意事项

    1、如果子类实现Serializable接口而父类未实现时,父类不会被序列化,但此时父类必须有个无参构造方法,否则会抛InvalidClassException异常。

    2、静态变量不会被序列化,那是类的,不是对象的。串行化保存的是对象的状态,即非静态的属性,即实例变量。不能保存类变量。

    3transient关键字修饰变量可以限制序列化。对于不需要或不应该保存的属性,应加上transient修饰符。要串行化的对象的类必须是公开的(public)。

    4、虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID是否一致,就是 private static final long serialVersionUID = 1L

    5Java 序列化机制为了节省磁盘空间,具有特定的存储规则,当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用。反序列化时,恢复引用关系。

    6、序列化到同一个文件时,如第二次修改了相同对象属性值再次保存时候,虚拟机根据引用关系知道已经有一个相同对象已经写入文件,因此只保存第二次写的引用,所以读取时,都是第一次保存的对象。

    5.java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?

    JDK提供的流继承了四大类:

    InputStream(字节输入流)OutputStream(字节输出流),Reader(字符输入流),Writer(字符输出流)。

    按流向分类:

    输入流: 程序可以从中读取数据的流。
    输出流: 程序能向其中写入数据的流。

    按数据传输单位分类:

    字节流:以字节(8位二进制)为单位进行处理。主要用于读写诸如图像或声音的二进制数据。
    字符流:以字符(16位二进制)为单位进行处理。
    都是通过字节流的方式实现的。字符流是对字节流进行了封装,方便操作。在最底层,所有的输入输出都是字节形式的。
    后缀是Stream是字节流,而后缀是ReaderWriter是字符流。

    按功能分类:

    节点流:从特定的地方读写的流类,如磁盘或者一块内存区域。
    过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或者输出流连接创建的。

    6.JAVA SOCKET 编程,读服务器几个 字符,再写入本地显示。

    客户端向服务器端发送连接请求后,就被动地等待服务器的响应。

    典型的TCP客户端要经过下面三步操作:

    1、创建一个Socket实例:构造函数向指定的远程主机和端口建立一个TCP连接;
    2通过套接字的I/O流与服务端通信;
    3、使用Socket类的close方法关闭连接。

     

    服务端的工作是建立一个通信终端,并被动地等待客户端的连接。

    典型的TCP服务端执行如下两步操作:

    1、创建一个ServerSocket实例并指定本地端口,用来监听客户端在该端口发送的TCP连接请求;
    2、重复执行:
    1)调用ServerSocketaccept()方法以获取客户端连接,并通过其返回值创建一个Socket实例;
    2)为返回的Socket实例开启新的线程,并使用返回的Socket实例的I/O流与客户端通信;
    3)通信完成后,使用Socket类的close()方法关闭该客户端的套接字连接。

    7.TCP/IP在连接时有几次握手?释放时有几次握手?

    TCP三次握手连接的建立过程:


    TCP四次挥手的释放过程:


     

    展开全文
  • Java网络编程面试题

    2019-09-24 07:31:04
    Java网络编程面试题 1、tcp和udp的区别1 2、tcp连接建立的时候3次握手,断开连接的4次握手的具体过程1 3、什么是同步?什么是异步?2 4、.什么是阻塞?什么是非阻塞?5 5、什么是阻塞IO?什么...

     

    1、tcp和udp的区别 1

    2、tcp连接建立的时候3次握手,断开连接的4次握手的具体过程 1

    3、什么是同步?什么是异步? 2

    4、.什么是阻塞?什么是非阻塞? 5

    5、什么是阻塞IO?什么是非阻塞IO? 6

    6、什么是同步IO?什么是异步IO? 7

    7、 IO模型有几种?分别是什么? 8

    8、 Reactor和Proactor IO设计模式是什么? 13

    9、Java NIO 中的Buffer是什么?如何使用? 16

    10、Nio buffer 的内部结构是什么? 17

    11、Java NIO 中的 Channel是什么?有什么特点? 18

    12、Java NIO中的Selector是什么? 21

    13、简单讲一下文件IO中的Path和Files 22

    14、select、poll和epoll的区别 23

    15、网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别? 29

    15、网络编程的一般步骤 29

    16、TCP的全称是? 31

    17、UDP的全称是? 31

    18、请说出TCP和UDP的区别? 31

    19、TCP为什么不是两次连接?而是三次握手? 33

    20、说明socket是什么? 34

    21、为什么需要端口?端口是真实存在的还是虚拟的概念? 35

    22、Java中,端口使用两个字节表示,可以表示多少个端口? UDP和TCP端口是各自独立的吗? 35

    23、URL类有什么作用? 35

    24、基于TCP的Socket网络编程的主要步骤是什么? 36

    25、【上机】写出建立TCP服务器ServerSocket的代码。并说明accept方法有什么特点? 37

    26、【上机】写出建立TCP客户端Socket的代码。并说明建立Socket后,通过什么方法Socket获得流对象? 37

    27、基于UDP的Socket网络编程的主要步骤是什么? 37

    28、【上机】使用UDP的方式,完成对象的传递。 38

    29、HTTPClient相关问题 39

    30、NIO 和传统 BIO区别是什么? 40

    31、Java NIO 的几个核心组成部分是什么?作用分别是什么? 41

    32、简单说一下http协议? 47

    33、http协议下客户端请求报文是什么? 48

    34、描述一下http协议服务器响应报文有哪些? 49

    35、HTTP协议中常用的请求方法有哪些 50

    36、常见的HTTP状态码有哪些 51

    37、HTTP 协议中content-type指的是什么? 55

    38、网络传输协议本质和作用是什么? 65

    39、可以实现一个简单的网络协议吗? 65

     

     

    1tcp和udp的区别 

    TCP:是面向连接的流传输控制协议,具有高可靠性,确保传输数据的正确性,有验证重发机制,因此不会出现丢失或乱序。

    UDP:是无连接的数据报服务,不对数据报进行检查与修改,无须等待对方的应答,会出现分组丢失、重复、乱序,但具有较好的实时性,UDP段结构比TCP的段结构简单,因此网络开销也小。

    2、tcp连接建立的时候3次握手,断开连接的4次握手的具体过程

    1. 建立连接采用的3次握手协议,具体是指:

    l 第一次握手是客户端connect连接到server

    l 第二次server accept client的请求之后,向client端发送一个消息,相当于说我都准备好了,你连接上我了

    l 第三次 就是client向server发送的,就是对第二次握手消息的确认。之后client和server就开始通讯了。

    2.断开连接的4次握手,具体如下:

    l 断开连接的一端发送close请求是第一次握手

    l 另外一端接收到断开连接的请求之后需要对close进行确认,发送一个消息,这是第二次握手

    l 发送了确认消息之后还要向对端发送close消息,要关闭对对端的连接,这是第3次握手

    l 而在最初发送断开连接的一端接收到消息之后,进入到一个很重要的状态time_wait状态,这个状态也是面试官经常问道的问题,最后一次握手是最初发送断开连接的一端接收到消息之后。对消息的确认。

    3、什么是同步?什么是异步?

    同步:

    如果有多个任务或者事件要发生,这些任务或者事件必须逐个地进行,一个事件或者任务的执行会导致整个流程的暂时等待,这些事件没有办法并发地执行;

    异步:

    如果有多个任务或者事件发生,这些事件可以并发地执行一个事件或者任务的执行不会导致整个流程的暂时等待。

    这就是同步和异步。

    举个简单的例子,假如有一个任务包括两个子任务A和B,对于同步来说,当A在执行的过程中,B只有等待,直至A执行完毕,B才能执行;而对于异步就是A和B可以并发地执行,B不必等待A执行完毕之后再执行,这样就不会由于A的执行导致整个任务的暂时等待。

     

    如果还不理解,可以先看下面这2段代码:

    void fun1() {

    }

     

    void fun2() {

    }

     

    void function(){

        fun1();

        fun2()

        .....

        .....

    }

    这段代码就是典型的同步,在方法function中,fun1在执行的过程中会导致后续的fun2无法执行,fun2必须等待fun1执行完毕才可以执行。

     

    接着看下面这段代码:

    void fun1() {

    }

     

    void fun2() {

    }

     

    void function(){

        new Thread(){

        public void run() {

            fun1();

        }

    }.start();

     

    new Thread(){

        public void run() {

            fun2();

        }

    }.start();

    .....

    .....

    }

    这段代码是一种典型的异步,fun1的执行不会影响到fun2的执行,并且fun1和fun2的执行不会导致其后续的执行过程处于暂时的等待。

     

    事实上,同步和异步是一个非常广的概念,它们的重点在于多个任务和事件发生时,一个事件的发生或执行是否会导致整个流程的暂时等待。我觉得可以将同步和异步与Java中的synchronized关键字联系起来进行类比。当多个线程同时访问一个变量时,每个线程访问该变量就是一个事件,对于同步来说,就是这些线程必须逐个地来访问该变量,一个线程在访问该变量的过程中,其他线程必须等待;而对于异步来说,就是多个线程不必逐个地访问该变量,可以同时进行访问。

     

    同步和异步可以表现在很多方面,但是记住其关键在于多个任务和事件发生时,一个事件的发生或执行是否会导致整个流程的暂时等待。一般来说,可以通过多线程的方式来实现异步,但是千万记住不要将多线程和异步画上等号,异步只是宏观上的一个模式,采用多线程来实现异步只是一种手段,并且通过多进程的方式也可以实现异步。同步和异步着重点在于多个任务的执行过程中,一个任务的执行是否会导致整个流程的暂时等待

    4、.什么是阻塞?什么是非阻塞?

    阻塞:

    当某个事件或者任务在执行过程中,它发出一个请求操作,但是由于该请求操作需要的条件不满足,那么就会一直在那等待,直至条件满足;

    非阻塞:

    当某个事件或者任务在执行过程中,它发出一个请求操作,如果该请求操作需要的条件不满足,会立即返回一个标志信息告知条件不满足,不会一直在那等待

    举个简单的例子:

    假如我要读取一个文件中的内容,如果此时文件中没有内容可读,对于同步来说就是会一直在那等待,直至文件中有内容可读;而对于非阻塞来说,就会直接返回一个标志信息告知文件中暂时无内容可读。

    阻塞和非阻塞着重点在于发出一个请求操作时,如果进行操作的条件不满足是否会返会一个标志信息告知条件不满足。理解阻塞和非阻塞可以同线程阻塞类比地理解,当一个线程进行一个请求操作时,如果条件不满足,则会被阻塞,即在那等待条件满足。

     

    5、什么是阻塞IO?什么是非阻塞IO?

    在了解阻塞IO和非阻塞IO之前,先看下一个具体的IO操作过程是怎么进行的。

    通常来说,IO操作包括:对硬盘的读写、对socket的读写以及外设的读写。

    当用户线程发起一个IO请求操作(本文以读请求操作为例),内核会去查看要读取的数据是否就绪,对于阻塞IO来说,如果数据没有就绪,则会一直在那等待,直到数据就绪;对于非阻塞IO来说,如果数据没有就绪,则会返回一个标志信息告知用户线程当前要读的数据没有就绪。当数据就绪之后,便将数据拷贝到用户线程,这样才完成了一个完整的IO读请求操作,也就是说一个完整的IO读请求操作包括两个阶段:

    1)查看数据是否就绪;

    2)进行数据拷贝(内核将数据拷贝到用户线程)。

    那么阻塞(blocking IO)和非阻塞(non-blocking IO)的区别就在于第一个阶段,如果数据没有就绪,在查看数据是否就绪的过程中是一直等待,还是直接返回一个标志信息

    Java中传统的IO都是阻塞IO,比如通过socket来读数据,调用read()方法之后,如果数据没有就绪,当前线程就会一直阻塞在read方法调用那里,直到有数据才返回;

    而如果是非阻塞IO的话,当数据没有就绪,read()方法应该返回一个标志信息,告知当前线程数据没有就绪,而不是一直在那里等待。

    6、什么是同步IO?什么是异步IO?

    我们先来看一下同步IO和异步IO的定义,在《Unix网络编程》一书中对同步IO和异步IO的定义是这样的:

    A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes.

    An asynchronous I/O operation does not cause the requesting process to be blocked.

    从字面的意思可以看出:同步IO即 如果一个线程请求进行IO操作,在IO操作完成之前,该线程会被阻塞;而异步IO为 如果一个线程请求进行IO操作,IO操作不会导致请求线程被阻塞。

    事实上,同步IO和异步IO模型是针对用户线程和内核的交互来说的:

    对于同步IO:当用户发出IO请求操作之后,如果数据没有就绪,需要通过用户线程或者内核不断地去轮询数据是否就绪,当数据就绪时,再将数据从内核拷贝到用户线程;

    而异步IO:只有IO请求操作的发出是由用户线程来进行的,IO操作的两个阶段都是由内核自动完成,然后发送通知告知用户线程IO操作已经完成。也就是说在异步IO中,不会对用户线程产生任何阻塞。

    这是同步IO和异步IO关键区别所在,同步IO和异步IO的关键区别反映在数据拷贝阶段是由用户线程完成还是内核完成。所以说异步IO必须要有操作系统的底层支持

    注意同步IO和异步IO与阻塞IO和非阻塞IO是不同的两组概念

    阻塞IO和非阻塞IO是反映在当用户请求IO操作时,如果数据没有就绪,是用户线程一直等待数据就绪,还是会收到一个标志信息这一点上面的。

    也就是说,阻塞IO和非阻塞IO是反映在IO操作的第一个阶段,在查看数据是否就绪时是如何处理的。

    7、 IO模型有几种?分别是什么?

    在《Unix网络编程》一书中提到了五种IO模型

    分别是:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。

    下面就分别来介绍一下这5种IO模型的异同。

    1.阻塞IO模型

    最传统的一种IO模型,即在读写数据过程中会发生阻塞现象。

    当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block状态。

    典型的阻塞IO模型的例子为:

    data = socket.read();

    如果数据没有就绪,就会一直阻塞在read方法。

    2.非阻塞IO模型

    当用户线程发起一个read操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。

    所以事实上,在非阻塞IO模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞IO不会交出CPU,而会一直占用CPU

     

    典型的非阻塞IO模型一般如下:

    伪代码

    while(true){

      new MyThread(socket)

    }

    class MyThread{

        data = socket.read();

        if(data!= error){

            处理数据

            break;

        }

     

    但是对于非阻塞IO就有一个非常严重的问题,在while循环中需要不断地去询问内核数据是否就绪,这样会导致CPU占用率非常高,因此一般情况下很少使用while循环这种方式来读取数据。

     

    3.多路复用IO模型

    多路复用IO模型是目前使用得比较多的模型。Java NIO实际上就是多路复用IO。

    在多路复用IO模型中,会有一个线程不断去轮询多个socket的状态,只有当socket真正有读写事件时,才真正调用实际的IO读写操作。因为在多路复用IO模型中,只需要使用一个线程就可以管理多个socket,系统不需要建立新的进程或者线程,也不必维护这些线程和进程,并且只有在真正有socket读写事件进行时,才会使用IO资源,所以它大大减少了资源占用。

      

    在Java NIO中,是通过selector.select()去查询每个通道是否有到达事件,如果没有事件,则一直阻塞在那里,因此这种方式会导致用户线程的阻塞。

    也许有朋友会说,我可以采用 多线程+ 阻塞IO 达到类似的效果,但是由于在多线程 + 阻塞IO 中,每个socket对应一个线程,这样会造成很大的资源占用,并且尤其是对于长连接来说,线程的资源一直不会释放,如果后面陆续有很多连接的话,就会造成性能上的瓶颈。

    而多路复用IO模式,通过一个线程就可以管理多个socket,只有当socket真正有读写事件发生才会占用资源来进行实际的读写操作。因此,多路复用IO比较适合连接数比较多的情况。

    另外多路复用IO为何比非阻塞IO模型的效率高是因为在非阻塞IO中,不断地询问socket状态时通过用户线程去进行的,而在多路复用IO中,轮询每个socket状态是内核在进行的,这个效率要比用户线程要高的多。

    不过要注意的是,多路复用IO模型是通过轮询的方式来检测是否有事件到达,并且对到达的事件逐一进行响应。因此对于多路复用IO模型来说,一旦事件响应体很大,那么就会导致后续的事件迟迟得不到处理,并且会影响新的事件轮询。

     

    4.信号驱动IO模型

    在信号驱动IO模型中,当用户线程发起一个IO请求操作,会给对应的socket注册一个信号函数,然后用户线程会继续执行,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用IO读写操作来进行实际的IO请求操作。

    5.异步IO模型

    异步IO模型才是最理想的IO模型,在异步IO模型中,当用户线程发起read操作之后,立刻就可以开始去做其它的事。

    而另一方面,从内核的角度,当它受到一个asynchronous read之后,它会立刻返回,说明read请求已经成功发起了,因此不会对用户线程产生任何block。

    然后,内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它read操作完成了。

    也就说用户线程完全不需要实际的整个IO操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示IO操作已经完成,可以直接去使用数据了。

    也就说在异步IO模型中,IO操作的两个阶段都不会阻塞用户线程,这两个阶段都是由内核自动完成,然后发送一个信号告知用户线程操作已完成。

    用户线程中不需要再次调用IO函数进行具体的读写。

    这点是和信号驱动模型有所不同的

    在信号驱动模型中,当用户线程接收到信号表示数据已经就绪,然后需要用户线程调用IO函数进行实际的读写操作;而在异步IO模型中,收到信号表示IO操作已经完成,不需要再在用户线程中调用iO函数进行实际的读写操作。

    注意,异步IO是需要操作系统的底层支持,在Java 7中,提供了Asynchronous IO。也就是java中的AIO

     

    前面四种IO模型实际上都属于同步IO,只有最后一种是真正的异步IO,因为无论是多路复用IO还是信号驱动模型,IO操作的第2个阶段都会引起用户线程阻塞,也就是内核进行数据拷贝的过程都会让用户线程阻塞。

    8、 Reactor和Proactor IO设计模式是什么?

    在传统的网络服务设计模式中,有两种比较经典的模式:一种是 多线程,一种是线程池。

    对于多线程模式,也就说来了client,服务器就会新建一个线程来处理该client的读写事件,如下图所示:

     

    这种模式虽然处理起来简单方便,但是由于服务器为每个client的连接都采用一个线程去处理,使得资源占用非常大。因此,当连接数量达到上限时,再有用户请求连接,直接会导致资源瓶颈,严重的可能会直接导致服务器崩溃。

     

    因此,为了解决这种一个线程对应一个客户端模式带来的问题提出了采用线程池的方式,也就说创建一个固定大小的线程池,来一个客户端,就从线程池取一个空闲线程来处理,当客户端处理完读写操作之后,就交出对线程的占用。因此这样就避免为每一个客户端都要创建线程带来的资源浪费,使得线程可以重用。

    但是线程池也有它的弊端,如果连接大多是长连接,因此可能会导致在一段时间内,线程池中的线程都被占用,那么当再有用户请求连接时,由于没有可用的空闲线程来处理,就会导致客户端连接失败,从而影响用户体验。因此,线程池比较适合大量的短连接应用。

    因此便出现了下面的两种高性能IO设计模式:Reactor和Proactor。

     

    Reactor模式中,会先对每个client注册感兴趣的事件,然后有一个线程专门去轮询每个client是否有事件发生,当有事件发生时,便顺序处理每个事件,当所有事件处理完之后,便再转去继续轮询,如下图所示:

     

    多路复用IO就是采用Reactor模式。注意,上面的图中展示的 是顺序处理每个事件,当然为了提高事件处理速度,可以通过多线程或者线程池的方式来处理事件。

     

    Proactor模式中,当检测到有事件发生时,会新起一个异步操作,然后交由内核线程去处理,当内核线程完成IO操作之后,发送一个通知告知操作已完成,可以得知,异步IO模型采用的就是Proactor模式。

    9、Java NIO 中的Buffer是什么?如何使用?

    Buffer(缓冲区):

    Java NIO Buffers用于和NIO Channel交互。 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels;

    Buffer本质上就是一块内存区;

    一个Buffer有三个属性是必须掌握的,分别是:capacity容量、position位置、limit限制。

    Buffer的常见方法

    Buffer clear()

    Buffer flip()

    Buffer rewind()

    Buffer position(int newPosition)

    Buffer的使用方式/方法介绍:

    分配缓冲区(Allocating a Buffer):

    ByteBuffer buf = ByteBuffer.allocate(28);//以ByteBuffer为例子

    写入数据到缓冲区(Writing Data to a Buffer)

    写数据到Buffer有两种方法:

    1.从Channel中写数据到Buffer

    int bytesRead = inChannel.read(buf); //read into buffer.

    2.通过put写数据:

    buf.put(127);

    10、Nio buffer 的内部结构是什么?

     

    一个 buffer 主要由 position,limit,capacity 三个变量来控制读写的过程。此三个变量的含义见如下表格:

    参数

    写模式   

    读模式

    position

    当前写入的单位数据数量。

    当前读取的单位数据位置。

    limit

    代表最多能写多少单位数据和容量是一样的。

    代表最多能读多少单位数据,和之前写入的单位数据量一致。

    capacity

    buffer 容量

    buffer 容量

    Buffer 常见方法:

    flip(): 写模式转换成读模式

    rewind() :将 position 重置为 0 ,一般用于重复读。

    clear() :清空 buffer ,准备再次被写入 (position 变成 0 , limit 变成 capacity) 。

    compact(): 将未读取的数据拷贝到 buffer 的头部位。

    mark() 、 reset():mark 可以标记一个位置, reset 可以重置到该位置。

    Buffer 常见类型: ByteBuffer 、 MappedByteBuffer 、 CharBuffer 、 DoubleBuffer 、 FloatBuffer 、 IntBuffer 、LongBuffer 、 ShortBuffer 。

    channel 常见类型 :FileChannel 、 DatagramChannel(UDP) 、 SocketChannel(TCP) 、 ServerSocketChannel(TCP)

    11、Java NIO 中的 Channel是什么?有什么特点?

    Channel

    Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。

    可以通过以下2种方式创建SocketChannel:

    1. 打开一个SocketChannel并连接到互联网上的某台服务器。
    2. 一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。

    打开 SocketChannel  下面是SocketChannel的打开方式:  

    SocketChannel socketChannel = SocketChannel.open();

    socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));

    关闭 SocketChannel  

    当用完SocketChannel之后调用SocketChannel.close()关闭SocketChannel:   socketChannel.close();

    从 SocketChannel 读取数据  

    要从SocketChannel中读取数据,调用一个read()的方法之一。

    ByteBuffer buf = ByteBuffer.allocate(48);

    int bytesRead = socketChannel.read(buf);

    非阻塞模式

    可以设置 SocketChannel 为非阻塞模式(non-blocking mode).设置之后,就可以在异步模式下调用connect(), read() 和write()了。

    如果SocketChannel在非阻塞模式下,此时调用connect(),该方法可能在连接建立之前就返回了。为了确定连接是否建立,可以调用finishConnect()的方法。

    像这样:

    socketChannel.configureBlocking(false);

    socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));

     

    while(! socketChannel.finishConnect() ){

        //wait, or do something else...

    }

    Java NIO Channel通道和流非常相似,主要有以下几点区别:

    l 通道可以读也可以写,流一般来说是单向的(只能读或者写,所以之前我们用流进行IO操作的时候需要分别创建一个输入流和一个输出流)。

    l 通道可以异步读写。

    l 通道总是基于缓冲区Buffer来读写。

    Java NIO中最重要的几个Channel的实现:

    l FileChannel: 用于文件的数据读写

    l DatagramChannel: 用于UDP的数据读写

    l SocketChannel: 用于TCP的数据读写,一般是客户端实现

    l ServerSocketChannel: 允许我们监听TCP链接请求,每个请求会创建会一个SocketChannel,一般是服务器实现

    类层次结构

     

    12、Java NIO中的Selector是什么?

    Selector(选择器):

    Selector 一般称 为选择器 ,当然你也可以翻译为 多路复用器 。

    它是Java NIO核心组件中的一个,用于检查一个或多个NIO Channel(通道)的状态是否处于可读、可写。

    如此可以实现单线程管理多个channels,也就是可以管理多个网络链接。

    使用Selector的好处在于: 使用更少的线程来就可以来处理通道了, 相比使用多个线程,避免了线程上下文切换带来的开销。

    Selector(选择器)的使用方法介绍

    Selector的创建

    Selector selector = Selector.open();

    注册Channel到Selector(Channel必须是非阻塞的)

    channel.configureBlocking(false);

    SelectionKey key = channel.register(selector, Selectionkey.OP_READ);

    SelectionKey介绍

    一个SelectionKey键表示了一个特定的通道对象和一个特定的选择器对象之间的注册关系。

    从Selector中选择channel(Selecting Channels via a Selector)

    选择器维护注册过的通道的集合,并且这种注册关系都被封装在SelectionKey当中.

    停止选择的方法

    wakeup()方法 和close()方法。

    13、简单讲一下文件IO中的Path和Files

    文件I/O基石:Path:

    创建一个Path

    File和Path之间的转换,File和URI之间的转换

    获取Path的相关信息

    移除Path中的冗余项

    Files类:

    Files.exists() 检测文件路径是否存在

    Files.createFile() 创建文件

    Files.createDirectories()和Files.createDirectory()创建文件夹

    Files.delete()方法 可以删除一个文件或目录

    Files.copy()方法可以吧一个文件从一个地址复制到另一个位置

    获取文件属性

    遍历一个文件夹

    Files.walkFileTree()遍历整个目录

     

    14、select、poll和epoll的区别

    在linux 没有实现epoll事件驱动机制之前,我们一般选择用select或者poll等IO多路复用的方法来实现并发服务程序。在大数据、高并发、集群等一些名词唱得火热之年代,select和poll的用武之地越来越有限,风头已经被epoll占尽。

    select的缺点:

    1. 单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,当然可以更改数量,但由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;

    在linux内核头文件中,有这样的定义:

    #define __FD_SETSIZE    1024

    1. 内核 / 用户空间内存拷贝问题,select需要复制大量的句柄数据结构,产生巨大的开销;
    2. select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件;
    3. select的触发方式是水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作,那么之后每次select调用还是会将这些文件描述符通知进程。

    相比select模型,poll使用链表保存文件描述符,因此没有了监视文件数量的限制,但其他三个缺点依然存在。

     

    拿select模型为例,假设我们的服务器需要支持100万的并发连接,则在__FD_SETSIZE 为1024的情况下,则我们至少需要开辟1k个进程才能实现100万的并发连接。

    除了进程间上下文切换的时间消耗外,从内核/用户空间大量的无脑内存拷贝、数组轮询等,是系统难以承受的。

    因此,基于select模型的服务器程序,要达到10万级别的并发访问,是一个很难完成的任务。

     

    epoll的实现机制与select/poll机制完全不同,上面所说的 select的缺点在epoll上不复存在。

    设想一下如下场景:

    有100万个客户端同时与一个服务器进程保持着TCP连接。而每一时刻,通常只有几百上千个TCP连接是活跃的(事实上大部分场景都是这种情况)。如何实现这样的高并发?

     

    在select/poll时代,服务器进程每次都把这100万个连接告诉操作系统(从用户态复制句柄数据结构到内核态),让操作系统内核去查询这些套接字上是否有事件发生,轮询完后,再将句柄数据复制到用户态,让服务器应用程序轮询处理已发生的网络事件,这一过程资源消耗较大,因此,select/poll一般只能处理几千的并发连接。

     

    epoll的设计和实现与select完全不同。

    epoll通过在Linux内核中申请一个简易的文件系统

    (文件系统一般用什么数据结构实现?B+树)

    把原先的select/poll调用分成了3个部分:

    1)调用epoll_create()建立一个epoll对象(在epoll文件系统中为这个句柄对象分配资源)

    2)调用epoll_ctl向epoll对象中添加这100万个连接的套接字

    3)调用epoll_wait收集发生的事件的连接

     

    如此一来,要实现上面说是的场景,只需要在进程启动时建立一个epoll对象,然后在需要的时候向这个epoll对象中添加或者删除连接。同时,epoll_wait的效率也非常高,因为调用epoll_wait时,并没有一股脑的向操作系统复制这100万个连接的句柄数据,内核也不需要去遍历全部的连接。

     

    下面来看看Linux内核具体的epoll机制实现思路。

     

    当某一进程调用epoll_create方法时,Linux内核会创建一个eventpoll结构体,这个结构体中有两个成员与epoll的使用方式密切相关。eventpoll结构体如下所示:

    struct eventpoll{    

    ....    

    /*红黑树的根节点,这颗树中存储着所有添加到epoll中的需要监控的事件*/    

    struct rb_root  rbr;

    /*双链表中则存放着将要通过epoll_wait返回给用户的满足条件的事件*/   

    struct list_head rdlist;  

      ....

    };

    每一个epoll对象都有一个独立的eventpoll结构体,用于存放通过epoll_ctl方法向epoll对象中添加进来的事件。这些事件都会挂载在红黑树中,如此,重复添加的事件就可以通过红黑树而高效的识别出来(红黑树的插入时间效率是lgn,其中n为树的高度)。

    所有添加到epoll中的事件都会与设备(网卡)驱动程序建立回调关系,也就是说,当相应的事件发生时会调用这个回调方法。这个回调方法在内核中叫ep_poll_callback,它会将发生的事件添加到rdlist双链表中。

    在epoll中,对于每一个事件,都会建立一个epitem结构体,如下所示:

    struct epitem{    

    struct rb_node  rbn;//红黑树节点    

    struct list_head    rdllink;//双向链表节点    

    struct epoll_filefd  ffd;  //事件句柄信息    

    struct eventpoll *ep;    //指向其所属的eventpoll对象    

    struct epoll_event event; //期待发生的事件类型

    }

    当调用epoll_wait检查是否有事件发生时,只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可。如果rdlist不为空,则把发生的事件复制到用户态,同时将事件数量返回给用户。

     

    通过红黑树和双链表数据结构,并结合操作系统底层回调机制,造就了epoll的高效

    epoll的用法

    第一步:epoll_create()系统调用。此调用返回一个句柄,之后所有的使用都依靠这个句柄来标识。

    第二步:epoll_ctl()系统调用。通过此调用向epoll对象中添加、删除、修改感兴趣的事件,返回0标识成功,返回-1表示失败。

    第三部:epoll_wait()系统调用。通过此调用收集收集在epoll监控中已经发生的事件。

    15、网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别? 

    1,进程:

    子进程是父进程的复制品。

    子进程获得父进程数据空间、堆和栈的复制品。
    2,线程:

    相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

    两者都可以提高程序的并发度,提高程序运行效率和响应时间。
    线程和进程在使用上各有优缺点:

    线程执行开销小,但不利于资源管理和保护;而进程正相反。

    同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

    SMP的全称是"对称多处理"(Symmetrical Multi-Processing)技术,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。

     

     

    15、网络编程的一般步骤

    对于TCP连接:

    1.服务器端

    1)创建套接字create;

    2)绑定端口号bind;

    3)监听连接listen;

    4)接受连接请求accept,并返回新的套接字;

    5)用新返回的套接字recv/send;

    6)关闭套接字。

    2.客户端

    1)创建套接字create;

    2)发起建立连接请求connect;

    3)发送/接收数据send/recv;

    4)关闭套接字。

    TCP总结:

    Server端:create – bind – listen–  accept–  recv/send– close

    Client端:create——- conncet——send/recv——close.

     

    对于UDP连接:

    1.服务器端:

    1)创建套接字create;

    2)绑定端口号bind;

    3)接收/发送消息recvfrom/sendto;

    4)关闭套接字。

    2.客户端:

    1)创建套接字create;

    2)发送/接收消息sendto/recvfrom;

    3)关闭套接字.

    UDP总结:

    Server端:create—-bind —-recvfrom/sendto—-close

    Client端:create—-  sendto/recvfrom—-close.

    函数原型int recv( _In_ SOCKET s, _Out_ char *buf, _In_ int len, _In_ int flags);

     

    16、TCP的全称是?

            Transfer Control Protocol。

    17、UDP的全称是?

            User Datagram Protocol。

    18、请说出TCP和UDP的区别?

    TCP:

    一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协议 。

    特点:

    面向连接;

    点到点的通信;

    高可靠性;

    占用系统资源多、效率低;

     

    UDP:

    一种无连接的、提供面向事务的简单不可靠信息传送服务的传输层通信协议。

    特点:

    非面向连接

    传输不可靠,可能丢失

    发送不管对方是否准备好,接收方收到也不确认

    可以广播发送

    非常简单的协议,开销小

     

     TCP—传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

    UDP—用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快

     

    19TCP为什么不是两次连接?而是三次握手?

    如果A与B两个进程通信,如果仅是两次连接。

    可能出现的一种情况

    就是:A发送完请求报文以后,由于网络情况不好,出现了网络拥塞,即B延时很长时间后收到报文,即此时A将此报文认定为失效的报文。

    B收到报文后,会向A发起连接。此时两次握手完毕

    B会认为已经建立了连接可以通信,B会一直等到A发送的连接请求

    而A对失效的报文回复自然不会处理。

    因此会陷入B忙等的僵局,造成资源的浪费。

    20、说明socket是什么?

     

    从上图可以看到:底层的东西已经被内核实现了,即我们通常意义上的内核协议栈(传输层,网络层,链路层)

    最上面的Application(应用层)是我们用户所要实现的,它是属于用户进程的一部分,工作在用户空间,那么用户空间的程序要想访问内核,使用内核的服务,就需要一个接口,去访问所需要的服务

    对于网络编程来说,这个接口就是套接口(Socket)。

           Socket:可以看作用户进程和内核网络协议栈编程(交互)接口

           Socket:不仅可以在同一台主机上进行通信,也可以在网络上不同的主机间进行通信,也可以异构(软硬件平台不同)进行通信(手机qq和PC机上的qq进行通信,手机的系统是ARM,而PC机是x86)

    21、为什么需要端口?端口是真实存在的还是虚拟的概念? 

    IP地址用来标志一台计算机,但是一台计算机上可能提供多种网络应用程序,使用端口来区分这些应用程序。

    端口是虚拟的概念,并不是说在主机上真的有若干个端口。通过端口,可以在一个主机上运行多个网络应用程序。

    端口范围0---65535,16位整数。

    22、Java中,端口使用两个字节表示,可以表示多少个端口? UDP和TCP端口是各自独立的吗?

    端口范围0---65535,16位整数。

    由于TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独立,如TCP有一个255号端口,UDP也可以有一个255号端口,二者并不冲突。 

     

    23、URL类有什么作用?

    URL:Uniform Resource Locator,统一资源定位器;俗称“网址”,如:

    "http://www.baidu.com:80/index.html#aa?cansu=bjsxt“

    由4部分组成:

    l 协议: http;

    l 存放资源的主机域名:www.baidu.com;

    l 端口号:80;

    l 资源文件名: index.html#aa?cansu=bjsxt;

     

    URL是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。

    24、基于TCP的Socket网络编程的主要步骤是什么?

     

    基于TCP协议的Socket编程的主要步骤

    服务器端(server):

    1. 构建一个ServerSocket实例,指定本地的端口。这个socket就是用来监听指定端口的连接请求的。

    2.重复如下几个步骤:

    a. 调用socket的accept()方法来获得下面客户端的连接请求。通过accept()方法返回的socket实例,建立了一个和客户端的新连接。

    b.通过这个返回的socket实例获取InputStream和OutputStream,可以通过这两个stream来分别读和写数据。

    c.结束的时候调用socket实例的close()方法关闭socket连接。

     

    客户端(client):

    1.构建Socket实例,通过指定的远程服务器地址和端口来建立连接。

    2.通过Socket实例包含的InputStream和OutputStream来进行数据的读写。

    3.操作结束后调用socket实例的close方法,关闭。

     

    25、【上机】写出建立TCP服务器ServerSocket的代码。并说明accept方法有什么特点?

    //服务器监听请求;

    ServerSocket ss=new ServerSocket(9999);

    //接受请求:创建了socket;

    Socket socket=ss.accept();

            详见课上示例。

    26、【上机】写出建立TCP客户端Socket的代码。并说明建立Socket后,通过什么方法Socket获得流对象?

    //客户端向服务器端发送请求;

    Socket socket=new Socket("127.0.0.1",9999);

    //建好连接后,开始传输数据;

    OutputStream os=socket.getOutputStream();

     

            详见课上示例。

    27、基于UDP的Socket网络编程的主要步骤是什么?

    基于UDP协议的Socket编程的主要步骤

    服务器端(server):

    1. 构造DatagramSocket实例,指定本地端口。

    2. 通过DatagramSocket实例的receive方法接收DatagramPacket.DatagramPacket中间就包含了通信的内容。

    3. 通过DatagramSocket的send和receive方法来收和发DatagramPacket.

    客户端(client):

    1. 构造DatagramSocket实例。

    2.通过DatagramSocket实例的send和receive方法发送DatagramPacket报文。

    3.结束后,调用DatagramSocket的close方法关闭。

     

    28、【上机】使用UDP的方式,完成对象的传递。

    (1)客户端向服务器端传送对象信息;

    DatagramSocket ds=new DatagramSocket(9999);

             //构建数据包;

            Scanner input=new Scanner(System.in);

            System.out.println("请输入用户名:");

            String username=input.nextLine();

            System.out.println("请输入密码:");

            String password=input.nextLine();

     //事先要创建好User类;

            User user=new User(username,password);

            //字节流;在内存开辟缓冲区;

            ByteArrayOutputStream baos=new ByteArrayOutputStream();

            ObjectOutputStream oos=new ObjectOutputStream(baos);

            oos.writeObject(user);

     

            byte buf[]=baos.toByteArray();

            DatagramPacket dp=new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 8888);//DatagramPacket只用byte[]数组;

                 //发送数据;

            ds.send(dp);

     

    (2)服务器端从客户端接收对象信息;

    //服务器定义DatagramSocket以接收数据;

    DatagramSocket ds=new DatagramSocket(8888);

     

    //定义一个数据包来接收数据;

    //数据包里是byte数组,所以还得定义一个byte数组;

    byte buf[]=new byte[1024];

    DatagramPacket dp=new DatagramPacket(buf, buf.length);

             //接收客户端发过来的数据;

    ds.receive(dp);

     

            //用字节流和对象流读取对象信息;

    ByteArrayInputStream bais=new ByteArrayInputStream(buf);

    ObjectInputStream ois=new ObjectInputStream(bais);

     

    User user=(User)ois.readObject();

            System.out.println(user);

     

    详见课上示例。

    29、HTTPClient相关问题

    1. 什么是httpClient?
    2. 什么是HttpClient不能做的?
    3. HttpClient有哪些特性?
    4. HttpClient怎样发送带参数的GET请求?
    5. HttpClient怎样发送带参数的POST请求?
    6. HttpClient怎样获取响应状态?
    7. HttpClient怎样获取响应内容?
    8. HttpClient怎样上传文件?

    30NIO 和传统 BIO区别是什么? 

     NIO vs BIO之间的理念上面的区别(NIO将阻塞交给了后台线程执行)

    IO是面向流的,NIO是面向缓冲区的

    Java BIO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方;

    NIO则能前后移动流中的数据,因为是面向缓冲区的 BIO流是阻塞的,NIO流是不阻塞的 Java IO的各种流是阻塞的。

    这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。

    该线程在此期间不能再干任何事情了 Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。

    NIO可让您只使用一个(或几个)单线程管理多个通道(网络连接或文件),但付出的代价是解析数据可能会比从一个阻塞流中读取数据更复杂。 

    非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。

    选择器

    Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

     

    31Java NIO 几个核心组成部分是什么?作用分别是什么?

    l Channels

    l Buffers

    l Selectors

    基本上,所有的 IO 在NIO 中都从一个Channel 开始。

    Channel 有点象流。

    数据可以从Channel读到Buffer中,也可以从Buffer 写到Channel中。

    Channel的实现: 

    (涵盖了UDP 和 TCP 网络IO,以及文件IO)  

    l FileChannel

    l DatagramChannel

    l SocketChannel

    l ServerSocketChannel

    读数据:  

    int bytesRead = inChannel.read(buf);

    写数据:  

    int bytesWritten = inChannel.write(buf);  

     

    Buffer  

    Buffer实现: (byte,  char、short, int, long, float, double )  

    l ByteBuffer

    l CharBuffer

    l DoubleBuffer

    l FloatBuffer

    l IntBuffer

    l LongBuffer

    l ShortBuffer

    Buffer使用  

    l 读数据 flip()方法:

    buf.flip();  

    将Buffer从写模式切换到读模式 调用flip()方法会将position设回0,并将limit设置成之前position的值。

    l (char) buf.get()

    读取数据

    l Buffer.rewind()

    将position设回0,所以你可以重读Buffer中的所有数据 limit保持不变,仍然表示能从Buffer中读取多少个元素(byte、char等)

    l Buffer.mark()方法,

    可以标记Buffer中的一个特定position。

    之后可以通过调用 Buffer.reset()方法,恢复到Buffer.mark()标记时的position

    一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。

    l clear()方法:

    清空整个缓冲区。 position将被设回0,limit被设置成 capacity的值

    l compact()方法:

     只会清除已经读过的数据;任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。

    将position设到最后一个未读元素正后面,limit被设置成 capacity的值 写数据 buf.put(127);    

    Buffer的三个属性  

    capacity:

    l 表示容量

    l Buffer的一个固定的大小值;

    l Buffer满了需要将其清空才能再写;

    l ByteBuffer.allocate(48);该buffer的capacity为48byte CharBuffer.allocate(1024);该buffer的capacity为1024个char 

    position:

    含义取决于Buffer处在读模式还是写模式(初始值为0,写或者读操作的当前位置)

    写数据时,初始的position值为0;

    其值最大可为capacity-1

    将Buffer从写模式切换到读模式,position会被重置为0

    limit:

    含义取决于Buffer处在读模式还是写模式(写limit=capacity;读limit等于最多可以读取到的数据)

    写模式下,limit等于Buffer的capacity 切换Buffer到读模式时, limit表示你最多能读到多少数据;  

    Selector  

    Selector允许单线程处理多个 Channel。

    如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。

    例如,在一个聊天服务器中。    

    要使用Selector,得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。

    一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新连接进来,数据接收等。 

    使用  

    创建:

    Selector selector = Selector.open();   注册通道: channel.configureBlocking(false);   //与Selector一起使用时,Channel必须处于非阻塞模式 

    //这意味着不能将FileChannel与Selector一起使用,因为FileChannel不能切换到非阻塞模式(而套接字通道都可以)

    SelectionKey key = channel.register(selector, Selectionkey.OP_READ);  //第二个参数表明Selector监听Channel时对什么事件感兴趣

    //SelectionKey.OP_CONNECT  SelectionKey.OP_ACCEPT  SelectionKey.OP_READ SelectionKey.OP_WRITE //可以用或操作符将多个兴趣组合一起

    SelectionKey 包含了interest集合 、ready集合 、Channel 、Selector 、附加的对象(可选)

    int interestSet = key.interestOps();

    可以进行类似interestSet & SelectionKey.OP_CONNECT的判断

    select():

    阻塞到至少有一个通道在你注册的事件上就绪了

    selectNow():

    不会阻塞,不管什么通道就绪都立刻返回

    selectedKeys():

    访问“已选择键集(selected key set)”中的就绪通道

    close():

    使用完selector需要用其close()方法会关闭该Selector,且使注册到该Selector上的所有SelectionKey实例无效  

    Set selectedKeys = selector.selectedKeys();  

    Iterator keyIterator = selectedKeys.iterator();  

    while(keyIterator.hasNext()) {       

    SelectionKey key = keyIterator.next();       

    if(key.isAcceptable()) {           

    // a connection was accepted by a ServerSocketChannel.       

    } else if (key.isConnectable()) {          

     // a connection was established with a remote server.       

    } else if (key.isReadable()) {          

     // a channel is ready for reading       

    } else if (key.isWritable()) {           

    // a channel is ready for writing       

    }     

    keyIterator.remove();//注意这里必须手动remove;

    表明该selectkey我已经处理过了;

    }

     

    32、简单说一下http协议?

    HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

    HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

    HTTP 工作原理

    HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。

    Web服务器有:Apache服务器,Nginx,IIS服务器(Internet Information Services)等。

    Web服务器根据接收到的请求后,向客户端发送响应信息。

    HTTP默认端口号为80,但是你也可以改为8080或者其他端口。

    HTTP三点注意事项:

    l HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

    l HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。

    l HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

     

     

    33、http协议下客户端请求报文是什么?

    客户端发送一个HTTP请求到服务器的请求消息包括以下格式:

    l 请求行(request line)

    l 请求头部(header)

    l 空行

    l 请求数据

    四个部分组成

    下图给出了请求报文的一般格式。

     

    客户端请求:

    GET /hello.txt HTTP/1.1

    User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3

    Host: www.example.com

    Accept-Language: en, mi

    34、描述一下http协议服务器响应报文有哪些?

    HTTP响应也由四个部分组成,分别是:

    l 状态行

    l 消息报头

    l 空行

    l 响应正文

     

    HTTP/1.1 200 OK

    Date: Mon, 27 Jul 2009 12:28:53 GMT

    Server: Apache

    Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT

    ETag: "34aa387-d-1568eb00"

    Accept-Ranges: bytes

    Content-Length: 51

    Vary: Accept-Encoding

    Content-Type: text/plain

    35HTTP协议中常用的请求方法有哪些

    根据HTTP标准,HTTP请求可以使用多种请求方法。

    HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。

    HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

    序号

    方法

    描述

    1

    GET

    请求指定的页面信息,并返回实体主体。

    2

    HEAD

    类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头

    3

    POST

    向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。

    POST请求可能会导致新的资源的建立和/或已有资源的修改。

    4

    PUT

    从客户端向服务器传送的数据取代指定的文档的内容。

    5

    DELETE

    请求服务器删除指定的页面。

    6

    CONNECT

    HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

    7

    OPTIONS

    允许客户端查看服务器的性能。

    8

    TRACE

    回显服务器收到的请求,主要用于测试或诊断。

    36、常见的HTTP状态码有哪些

    当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。

    HTTP状态码的英文为HTTP Status Code。

    下面是常见的HTTP状态码:

    l 200 - 请求成功

    l 301 - 资源(网页等)被永久转移到其它URL

    l 404 - 请求的资源(网页等)不存在

    l 500 - 内部服务器错误

    HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:

    HTTP状态码分类

    分类

    分类描述

    1**

    信息,服务器收到请求,需要请求者继续执行操作

    2**

    成功,操作被成功接收并处理

    3**

    重定向,需要进一步的操作以完成请求

    4**

    客户端错误,请求包含语法错误或无法完成请求

    5**

    服务器错误,服务器在处理请求的过程中发生了错误

    HTTP状态码列表:

    HTTP状态码列表

    状态码

    状态码英文名称

    中文描述

    100

    Continue

    继续。客户端应继续其请求

    101

    Switching Protocols

    切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议

     

    200

    OK

    请求成功。一般用于GET与POST请求

    201

    Created

    已创建。成功请求并创建了新的资源

    202

    Accepted

    已接受。已经接受请求,但未处理完成

    203

    Non-Authoritative Information

    非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本

    204

    No Content

    无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档

    205

    Reset Content

    重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域

    206

    Partial Content

    部分内容。服务器成功处理了部分GET请求

     

    300

    Multiple Choices

    多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择

    301

    Moved Permanently

    永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替

    302

    Found

    临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI

    303

    See Other

    查看其它地址。与301类似。使用GET和POST请求查看

    304

    Not Modified

    未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源

    305

    Use Proxy

    使用代理。所请求的资源必须通过代理访问

    306

    Unused

    已经被废弃的HTTP状态码

    307

    Temporary Redirect

    临时重定向。与302类似。使用GET请求重定向

     

    400

    Bad Request

    客户端请求的语法错误,服务器无法理解

    401

    Unauthorized

    请求要求用户的身份认证

    402

    Payment Required

    保留,将来使用

    403

    Forbidden

    服务器理解请求客户端的请求,但是拒绝执行此请求

    404

    Not Found

    服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面

    405

    Method Not Allowed

    客户端请求中的方法被禁止

    406

    Not Acceptable

    服务器无法根据客户端请求的内容特性完成请求

    407

    Proxy Authentication Required

    请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权

    408

    Request Time-out

    服务器等待客户端发送的请求时间过长,超时

    409

    Conflict

    服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突

    410

    Gone

    客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置

    411

    Length Required

    服务器无法处理客户端发送的不带Content-Length的请求信息

    412

    Precondition Failed

    客户端请求信息的先决条件错误

    413

    Request Entity Too Large

    由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息

    414

    Request-URI Too Large

    请求的URI过长(URI通常为网址),服务器无法处理

    415

    Unsupported Media Type

    服务器无法处理请求附带的媒体格式

    416

    Requested range not satisfiable

    客户端请求的范围无效

    417

    Expectation Failed

    服务器无法满足Expect的请求头信息

     

    500

    Internal Server Error

    服务器内部错误,无法完成请求

    501

    Not Implemented

    服务器不支持请求的功能,无法完成请求

    502

    Bad Gateway

    充当网关或代理的服务器,从远端服务器接收到了一个无效的请求

    503

    Service Unavailable

    由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中

    504

    Gateway Time-out

    充当网关或代理的服务器,未及时从远端服务器获取请求

    505

    HTTP Version not supported

    服务器不支持请求的HTTP协议的版本,无法完成处理

    37HTTP 协议中content-type指的是什么?

    Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些Asp网页点击的结果却是下载到的一个文件或一张图片的原因。

     

    文件扩展名

    Content-Type(Mime-Type)

    文件扩展名

    Content-Type(Mime-Type)

    .*( 二进制流,不知道下载文件类型)

    application/octet-stream

    .tif

    image/tiff

    .001

    application/x-001

    .301

    application/x-301

    .323

    text/h323

    .906

    application/x-906

    .907

    drawing/907

    .a11

    application/x-a11

    .acp

    audio/x-mei-aac

    .ai

    application/postscript

    .aif

    audio/aiff

    .aifc

    audio/aiff

    .aiff

    audio/aiff

    .anv

    application/x-anv

    .asa

    text/asa

    .asf

    video/x-ms-asf

    .asp

    text/asp

    .asx

    video/x-ms-asf

    .au

    audio/basic

    .avi

    video/avi

    .awf

    application/vnd.adobe.workflow

    .biz

    text/xml

    .bmp

    application/x-bmp

    .bot

    application/x-bot

    .c4t

    application/x-c4t

    .c90

    application/x-c90

    .cal

    application/x-cals

    .cat

    application/vnd.ms-pki.seccat

    .cdf

    application/x-netcdf

    .cdr

    application/x-cdr

    .cel

    application/x-cel

    .cer

    application/x-x509-ca-cert

    .cg4

    application/x-g4

    .cgm

    application/x-cgm

    .cit

    application/x-cit

    .class

    java/*

    .cml

    text/xml

    .cmp

    application/x-cmp

    .cmx

    application/x-cmx

    .cot

    application/x-cot

    .crl

    application/pkix-crl

    .crt

    application/x-x509-ca-cert

    .csi

    application/x-csi

    .css

    text/css

    .cut

    application/x-cut

    .dbf

    application/x-dbf

    .dbm

    application/x-dbm

    .dbx

    application/x-dbx

    .dcd

    text/xml

    .dcx

    application/x-dcx

    .der

    application/x-x509-ca-cert

    .dgn

    application/x-dgn

    .dib

    application/x-dib

    .dll

    application/x-msdownload

    .doc

    application/msword

    .dot

    application/msword

    .drw

    application/x-drw

    .dtd

    text/xml

    .dwf

    Model/vnd.dwf

    .dwf

    application/x-dwf

    .dwg

    application/x-dwg

    .dxb

    application/x-dxb

    .dxf

    application/x-dxf

    .edn

    application/vnd.adobe.edn

    .emf

    application/x-emf

    .eml

    message/rfc822

    .ent

    text/xml

    .epi

    application/x-epi

    .eps

    application/x-ps

    .eps

    application/postscript

    .etd

    application/x-ebx

    .exe

    application/x-msdownload

    .fax

    image/fax

    .fdf

    application/vnd.fdf

    .fif

    application/fractals

    .fo

    text/xml

    .frm

    application/x-frm

    .g4

    application/x-g4

    .gbr

    application/x-gbr

    .

    application/x-

    .gif

    image/gif

    .gl2

    application/x-gl2

    .gp4

    application/x-gp4

    .hgl

    application/x-hgl

    .hmr

    application/x-hmr

    .hpg

    application/x-hpgl

    .hpl

    application/x-hpl

    .hqx

    application/mac-binhex40

    .hrf

    application/x-hrf

    .hta

    application/hta

    .htc

    text/x-component

    .htm

    text/html

    .html

    text/html

    .htt

    text/webviewhtml

    .htx

    text/html

    .icb

    application/x-icb

    .ico

    image/x-icon

    .ico

    application/x-ico

    .iff

    application/x-iff

    .ig4

    application/x-g4

    .igs

    application/x-igs

    .iii

    application/x-iphone

    .img

    application/x-img

    .ins

    application/x-internet-signup

    .isp

    application/x-internet-signup

    .IVF

    video/x-ivf

    .java

    java/*

    .jfif

    image/jpeg

    .jpe

    image/jpeg

    .jpe

    application/x-jpe

    .jpeg

    image/jpeg

    .jpg

    image/jpeg

    .jpg

    application/x-jpg

    .js

    application/x-javascript

    .jsp

    text/html

    .la1

    audio/x-liquid-file

    .lar

    application/x-laplayer-reg

    .latex

    application/x-latex

    .lavs

    audio/x-liquid-secure

    .lbm

    application/x-lbm

    .lmsff

    audio/x-la-lms

    .ls

    application/x-javascript

    .ltr

    application/x-ltr

    .m1v

    video/x-mpeg

    .m2v

    video/x-mpeg

    .m3u

    audio/mpegurl

    .m4e

    video/mpeg4

    .mac

    application/x-mac

    .man

    application/x-troff-man

    .math

    text/xml

    .mdb

    application/msaccess

    .mdb

    application/x-mdb

    .mfp

    application/x-shockwave-flash

    .mht

    message/rfc822

    .mhtml

    message/rfc822

    .mi

    application/x-mi

    .mid

    audio/mid

    .midi

    audio/mid

    .mil

    application/x-mil

    .mml

    text/xml

    .mnd

    audio/x-musicnet-download

    .mns

    audio/x-musicnet-stream

    .mocha

    application/x-javascript

    .movie

    video/x-sgi-movie

    .mp1

    audio/mp1

    .mp2

    audio/mp2

    .mp2v

    video/mpeg

    .mp3

    audio/mp3

    .mp4

    video/mpeg4

    .mpa

    video/x-mpg

    .mpd

    application/vnd.ms-project

    .mpe

    video/x-mpeg

    .mpeg

    video/mpg

    .mpg

    video/mpg

    .mpga

    audio/rn-mpeg

    .mpp

    application/vnd.ms-project

    .mps

    video/x-mpeg

    .mpt

    application/vnd.ms-project

    .mpv

    video/mpg

    .mpv2

    video/mpeg

    .mpw

    application/vnd.ms-project

    .mpx

    application/vnd.ms-project

    .mtx

    text/xml

    .mxp

    application/x-mmxp

    .net

    image/pnetvue

    .nrf

    application/x-nrf

    .nws

    message/rfc822

    .odc

    text/x-ms-odc

    .out

    application/x-out

    .p10

    application/pkcs10

    .p12

    application/x-pkcs12

    .p7b

    application/x-pkcs7-certificates

    .p7c

    application/pkcs7-mime

    .p7m

    application/pkcs7-mime

    .p7r

    application/x-pkcs7-certreqresp

    .p7s

    application/pkcs7-signature

    .pc5

    application/x-pc5

    .pci

    application/x-pci

    .pcl

    application/x-pcl

    .pcx

    application/x-pcx

    .pdf

    application/pdf

    .pdf

    application/pdf

    .pdx

    application/vnd.adobe.pdx

    .pfx

    application/x-pkcs12

    .pgl

    application/x-pgl

    .pic

    application/x-pic

    .pko

    application/vnd.ms-pki.pko

    .pl

    application/x-perl

    .plg

    text/html

    .pls

    audio/scpls

    .plt

    application/x-plt

    .png

    image/png

    .png

    application/x-png

    .pot

    application/vnd.ms-powerpoint

    .ppa

    application/vnd.ms-powerpoint

    .ppm

    application/x-ppm

    .pps

    application/vnd.ms-powerpoint

    .ppt

    application/vnd.ms-powerpoint

    .ppt

    application/x-ppt

    .pr

    application/x-pr

    .prf

    application/pics-rules

    .prn

    application/x-prn

    .prt

    application/x-prt

    .ps

    application/x-ps

    .ps

    application/postscript

    .ptn

    application/x-ptn

    .pwz

    application/vnd.ms-powerpoint

    .r3t

    text/vnd.rn-realtext3d

    .ra

    audio/vnd.rn-realaudio

    .ram

    audio/x-pn-realaudio

    .ras

    application/x-ras

    .rat

    application/rat-file

    .rdf

    text/xml

    .rec

    application/vnd.rn-recording

    .red

    application/x-red

    .rgb

    application/x-rgb

    .rjs

    application/vnd.rn-realsystem-rjs

    .rjt

    application/vnd.rn-realsystem-rjt

    .rlc

    application/x-rlc

    .rle

    application/x-rle

    .rm

    application/vnd.rn-realmedia

    .rmf

    application/vnd.adobe.rmf

    .rmi

    audio/mid

    .rmj

    application/vnd.rn-realsystem-rmj

    .rmm

    audio/x-pn-realaudio

    .rmp

    application/vnd.rn-rn_music_package

    .rms

    application/vnd.rn-realmedia-secure

    .rmvb

    application/vnd.rn-realmedia-vbr

    .rmx

    application/vnd.rn-realsystem-rmx

    .rnx

    application/vnd.rn-realplayer

    .rp

    image/vnd.rn-realpix

    .rpm

    audio/x-pn-realaudio-plugin

    .rsml

    application/vnd.rn-rsml

    .rt

    text/vnd.rn-realtext

    .rtf

    application/msword

    .rtf

    application/x-rtf

    .rv

    video/vnd.rn-realvideo

    .sam

    application/x-sam

    .sat

    application/x-sat

    .sdp

    application/sdp

    .sdw

    application/x-sdw

    .sit

    application/x-stuffit

    .slb

    application/x-slb

    .sld

    application/x-sld

    .slk

    drawing/x-slk

    .smi

    application/smil

    .smil

    application/smil

    .smk

    application/x-smk

    .snd

    audio/basic

    .sol

    text/plain

    .sor

    text/plain

    .spc

    application/x-pkcs7-certificates

    .spl

    application/futuresplash

    .spp

    text/xml

    .ssm

    application/streamingmedia

    .sst

    application/vnd.ms-pki.certstore

    .stl

    application/vnd.ms-pki.stl

    .stm

    text/html

    .sty

    application/x-sty

    .svg

    text/xml

    .swf

    application/x-shockwave-flash

    .tdf

    application/x-tdf

    .tg4

    application/x-tg4

    .tga

    application/x-tga

    .tif

    image/tiff

    .tif

    application/x-tif

    .tiff

    image/tiff

    .tld

    text/xml

    .top

    drawing/x-top

    .torrent

    application/x-bittorrent

    .tsd

    text/xml

    .txt

    text/plain

    .uin

    application/x-icq

    .uls

    text/iuls

    .vcf

    text/x-vcard

    .vda

    application/x-vda

    .vdx

    application/vnd.visio

    .vml

    text/xml

    .vpg

    application/x-vpeg005

    .vsd

    application/vnd.visio

    .vsd

    application/x-vsd

    .vss

    application/vnd.visio

    .vst

    application/vnd.visio

    .vst

    application/x-vst

    .vsw

    application/vnd.visio

    .vsx

    application/vnd.visio

    .vtx

    application/vnd.visio

    .vxml

    text/xml

    .wav

    audio/wav

    .wax

    audio/x-ms-wax

    .wb1

    application/x-wb1

    .wb2

    application/x-wb2

    .wb3

    application/x-wb3

    .wbmp

    image/vnd.wap.wbmp

    .wiz

    application/msword

    .wk3

    application/x-wk3

    .wk4

    application/x-wk4

    .wkq

    application/x-wkq

    .wks

    application/x-wks

    .wm

    video/x-ms-wm

    .wma

    audio/x-ms-wma

    .wmd

    application/x-ms-wmd

    .wmf

    application/x-wmf

    .wml

    text/vnd.wap.wml

    .wmv

    video/x-ms-wmv

    .wmx

    video/x-ms-wmx

    .wmz

    application/x-ms-wmz

    .wp6

    application/x-wp6

    .wpd

    application/x-wpd

    .wpg

    application/x-wpg

    .wpl

    application/vnd.ms-wpl

    .wq1

    application/x-wq1

    .wr1

    application/x-wr1

    .wri

    application/x-wri

    .wrk

    application/x-wrk

    .ws

    application/x-ws

    .ws2

    application/x-ws

    .wsc

    text/scriptlet

    .wsdl

    text/xml

    .wvx

    video/x-ms-wvx

    .xdp

    application/vnd.adobe.xdp

    .xdr

    text/xml

    .xfd

    application/vnd.adobe.xfd

    .xfdf

    application/vnd.adobe.xfdf

    .xhtml

    text/html

    .xls

    application/vnd.ms-excel

    .xls

    application/x-xls

    .xlw

    application/x-xlw

    .xml

    text/xml

    .xpl

    audio/scpls

    .xq

    text/xml

    .xql

    text/xml

    .xquery

    text/xml

    .xsd

    text/xml

    .xsl

    text/xml

    .xslt

    text/xml

    .xwd

    application/x-xwd

    .x_b

    application/x-x_b

    .sis

    application/vnd.symbian.install

    .sisx

    application/vnd.symbian.install

    .x_t

    application/x-x_t

    .ipa

    application/vnd.iphone

    .apk

    application/vnd.android.package-archive

    .xap

    application/x-silverlight-app

     

    38、网络传输协议本质和作用是什么?

    协议本质是双方约定好的一种传输规则,为了让传输数据的双方节点能建立连接,按照约定去传输和解析数据

    39、可以实现一个简单的网络协议吗?

    posted on 2019-05-27 18:09 shoshana~ 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/shoshana-kong/p/10932221.html

    展开全文
  • linux c网络网络编程面试题收集.doc

    热门讨论 2012-05-31 15:54:08
    linux c网络网络编程面试题收集.doc
  • Socket网络编程面试题

    2020-08-28 22:12:28
    Socket网络编程面试题1、TCP和UDP的区别:2、流量控制和拥塞控制的实现机制:3、重传机制:4、滑动窗口机制:5、多线程如何同步:6、进程和线程的区别:7、进程间通讯的方式有哪些,各有什么优缺点:9、tcp断开连接...
  • java网络编程常见面试题,包含,多线程,路由器,网络编程
  • 《UNIX环境高级编程》是2006年由人民邮电出版社出版的图书,作者是(美)理查德·史蒂文斯、(美)拉戈,译者是张亚英、戚正伟。文档中含有常见的unix高级编程面试题,带详细答案。
  • title: Go全栈面试题(5) -网络编程面试题 tags: go author: Clown95 网络面试题 说一下五层协议 应用层 :为特定应用程序提供数据传输服务,例如 HTTP、DNS 等协议。数据单位为报文。 传输层 :为进程提供...
  • 360 腾讯 迅雷Windows编程 网络编程面试题及答案
  • 常见的网络编程面试题汇总 一、前言 上篇文章为大家介绍先目前后台开发岗位的一些要求,请查看:后端开发岗位要求汇总,希望能帮助到大家; 今天这篇常见网络面试题是不对前面介绍岗位的网络部分的一个补充,这些...
  • IT公司笔试\linux c网络网络编程面试题收集 ,很全面的,我师兄传给我的
  • 这几道Java网络编程面试题都看不懂,怎么拿高薪!1、tcp和udp的区别TCP:是面向连接的流传输控制协议,具有高可靠性,确保传输数据的正确性,有验证重发机制,因此不会出现丢失或乱序。UDP:是无连接的数据报服务,...
  • 网络编程面试题(1)

    2021-04-19 22:12:19
    网络编程面试题(1) 1、TCP(Transmission Control Protocol) TCP传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。通讯双方建立一次tcp连接,需要经过三次步骤: 1、客户端发送syn包(syn=...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,756
精华内容 702
关键字:

网络编程面试题