精华内容
下载资源
问答
  • 面试/笔试第一弹 —— 计算机网络面试问题集锦

    万次阅读 多人点赞 2017-10-21 14:57:33
    本文对面试/笔试过程中经常会被问到的一些关于计算机网络的问题进行了梳理和总结,一方面方便自己温故知新,另一方面也希望为找工作的同学们提供一个复习参考。关于这块内容的初步了解和掌握,建议大家读一读《图解...

    写在前面:

      找工作告一段落,期间经历了很多事情,也思考了许多问题,最后也收获了一些沉甸甸的东西 —— 成长和一些来自阿里、百度、京东(sp)、华为等厂子的Offer。好在一切又回到正轨,接下来要好好总结一番才不枉这段经历,遂将此过程中笔者的一些笔试/面试心得、干货发表出来,与众共享之。在此特别要感谢CSDN以及广大朋友的支持,我将坚持记录并分享自己所学、所想、所悟,央请大家不吝赐教,提出您宝贵的意见和建议,以期共同探讨提高。


    摘要:

      本文对面试/笔试过程中经常会被问到的一些关于计算机网络的问题进行了梳理和总结,一方面方便自己温故知新,另一方面也希望为找工作的同学们提供一个复习参考。关于这块内容的初步了解和掌握,建议大家读一读《图解HTTP》一书。


    版权声明:

      本文原创作者:书呆子Rico
      作者博客地址:http://blog.csdn.net/justloveyou_/


    1、Http和Https的区别

      Http协议运行在TCP之上,明文传输,客户端与服务器端都无法验证对方的身份;Https是身披SSL(Secure Socket Layer)外壳的Http,运行于SSL上,SSL运行于TCP之上,是添加了加密和认证机制的HTTP。二者之间存在如下不同:

    • 端口不同:Http与Http使用不同的连接方式,用的端口也不一样,前者是80,后者是443;

    • 资源消耗:和HTTP通信相比,Https通信会由于加减密处理消耗更多的CPU和内存资源;

    • 开销:Https通信需要证书,而证书一般需要向认证机构购买;
       
      Https的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。


    2、对称加密与非对称加密

      对称密钥加密是指加密和解密使用同一个密钥的方式,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方;而非对称加密是指使用一对非对称密钥,即公钥和私钥,公钥可以随意发布,但私钥只有自己知道。发送密文的一方使用对方的公钥进行加密处理,对方接收到加密信息后,使用自己的私钥进行解密。

      由于非对称加密的方式不需要发送用来解密的私钥,所以可以保证安全性;但是和对称加密比起来,它非常的慢,所以我们还是要用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去。


    3、三次握手与四次挥手

     (1). 三次握手(我要和你建立链接,你真的要和我建立链接么,我真的要和你建立链接,成功):

    • 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

    • 第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

    • 第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

                  三次握手.png-12.4kB


     (2). 四次挥手(我要和你断开链接;好的,断吧。我也要和你断开链接;好的,断吧):

    • 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

    • 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。此时TCP链接处于半关闭状态,即客户端已经没有要发送的数据了,但服务端若发送数据,则客户端仍要接收。

    • 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

    • 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

                  四次挥手.png-12.6kB


    4、为什么TCP链接需要三次握手,两次不可以么,为什么?

      为了防止 已失效的链接请求报文突然又传送到了服务端,因而产生错误。

      客户端发出的连接请求报文并未丢失,而是在某个网络节点长时间滞留了,以致延误到链接释放以后的某个时间才到达Server。这是,Server误以为这是Client发出的一个新的链接请求,于是就向客户端发送确认数据包,同意建立链接。若不采用“三次握手”,那么只要Server发出确认数据包,新的链接就建立了。由于client此时并未发出建立链接的请求,所以其不会理睬Server的确认,也不与Server通信;而这时Server一直在等待Client的请求,这样Server就白白浪费了一定的资源。若采用“三次握手”,在这种情况下,由于Server端没有收到来自客户端的确认,则就会知道Client并没有要求建立请求,就不会建立链接。


    5、TCP协议如何来保证传输的可靠性

      TCP提供一种面向连接的、可靠的字节流服务。其中,面向连接意味着两个使用TCP的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须先建立一个TCP连接。在一个TCP连接中,仅有两方进行彼此通信;而字节流服务意味着两个应用程序通过TCP链接交换8bit字节构成的字节流,TCP不在字节流中插入记录标识符。

      对于可靠性,TCP通过以下方式进行保证:

    • 数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时TCP发送数据端超时后会重发数据;

    • 对失序数据包重排序:既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。TCP将对失序数据进行重新排序,然后才交给应用层;

    • 丢弃重复数据:对于重复数据,能够丢弃重复数据;

    • 应答机制:当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒;

    • 超时重发:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段;

    • 流量控制:TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP使用的流量控制协议是可变大小的滑动窗口协议。


    6、客户端不断进行请求链接会怎样?DDos(Distributed Denial of Service)攻击?

      服务器端会为每个请求创建一个链接,并向其发送确认报文,然后等待客户端进行确认


    1)、DDos 攻击

    • 客户端向服务端发送请求链接数据包
    • 服务端向客户端发送确认数据包
    • 客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认

    2)、DDos 预防 ( 没有彻底根治的办法,除非不使用TCP )

    • 限制同时打开SYN半链接的数目
    • 缩短SYN半链接的Time out 时间
    • 关闭不必要的服务

    7、Get与POST的区别

      GET与POST是我们常用的两种HTTP Method,二者之间的区别主要包括如下五个方面:

    (1). 从功能上讲,GET一般用来从服务器上获取资源,POST一般用来更新服务器上的资源;

    (2). 从REST服务角度上说,GET是幂等的,即读取同一个资源,总是得到相同的数据,而POST不是幂等的,因为每次请求对资源的改变并不是相同的;进一步地,GET不会改变服务器上的资源,而POST会对服务器资源进行改变;

    (3). 从请求参数形式上看,GET请求的数据会附在URL之后,即将请求数据放置在HTTP报文的 请求头 中,以?分割URL和传输数据,参数之间以&相连。特别地,如果数据是英文字母/数字,原样发送;否则,会将其编码为 application/x-www-form-urlencoded MIME 字符串(如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII);而POST请求会把提交的数据则放置在是HTTP请求报文的 请求体 中。

    (4). 就安全性而言,POST的安全性要比GET的安全性高,因为GET请求提交的数据将明文出现在URL上,而且POST请求参数则被包装到请求体中,相对更安全。

    (5). 从请求的大小看,GET请求的长度受限于浏览器或服务器对URL长度的限制,允许发送的数据量比较小,而POST请求则是没有大小限制的。


    1). GET请求中URL编码的意义

      我们知道,在GET请求中会对URL中非西文字符进行编码,这样做的目的就是为了 避免歧义。看下面的例子,

      针对“name1=value1&name2=value2”的例子,我们来谈一下数据从客户端到服务端的解析过程。首先,上述字符串在计算机中用ASCII吗表示为:

       6E616D6531 3D 76616C756531 26 6E616D6532 3D 76616C756532
       6E616D6531:name1 
       3D:= 
       76616C756531:value1 
       26:&
       6E616D6532:name2 
       3D:= 
       76616C756532:value2 

      服务端在接收到该数据后就可以遍历该字节流,一个字节一个字节的吃,当吃到3D这字节后,服务端就知道前面吃得字节表示一个key,再往后吃,如果遇到26,说明从刚才吃的3D到26子节之间的是上一个key的value,以此类推就可以解析出客户端传过来的参数。

      现在考虑这样一个问题,如果我们的参数值中就包含=或&这种特殊字符的时候该怎么办?比如,“name1=value1”,其中value1的值是“va&lu=e1”字符串,那么实际在传输过程中就会变成这样“name1=va&lu=e1”。这样,我们的本意是只有一个键值对,但是服务端却会解析成两个键值对,这样就产生了歧义。

      那么,如何解决上述问题带来的歧义呢?解决的办法就是对参数进行URL编码:例如,我们对上述会产生歧义的字符进行URL编码后结果:“name1=va%26lu%3D”,这样服务端会把紧跟在“%”后的字节当成普通的字节,就是不会把它当成各个参数或键值对的分隔符。更多关于 URL编码 的内容,请参考我的博文《使用 URLDecoder 和 URLEncoder 对中文字符进行编码和解码》,此不赘述。


    8、TCP与UDP的区别

      TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议,它们之间的区别包括:

    • TCP是面向连接的,UDP是无连接的;

    • TCP是可靠的,UDP是不可靠的;

    • TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多的通信模式;

    • TCP是面向字节流的,UDP是面向报文的;

    • TCP有拥塞控制机制;UDP没有拥塞控制,适合媒体通信;

    • TCP首部开销(20个字节)比UDP的首部开销(8个字节)要大;


    9、TCP的拥塞处理

      计算机网络中的带宽、交换结点中的缓存及处理机等都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就会变坏,这种情况就叫做拥塞。拥塞控制就是 防止过多的数据注入网络中,这样可以使网络中的路由器或链路不致过载。注意,拥塞控制和流量控制不同,前者是一个全局性的过程,而后者指点对点通信量的控制。拥塞控制的方法主要有以下四种:


    1). 慢启动:不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小;


    2). 拥塞避免:拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,这样拥塞窗口按线性规律缓慢增长。

              慢开始与拥塞避免.png-90.3kB


    3). 快重传:快重传要求接收方在收到一个 失序的报文段 后就立即发出 重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。

              快重传.jpg-42.3kB


    4). 快恢复:快重传配合使用的还有快恢复算法,当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半,但是接下去并不执行慢开始算法:因为如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh的大小,然后执行拥塞避免算法。

              快恢复.jpg-52.9kB


    10、从输入网址到获得页面的过程

      (1). 浏览器查询 DNS,获取域名对应的IP地址:具体过程包括浏览器搜索自身的DNS缓存、搜索操作系统的DNS缓存、读取本地的Host文件和向本地DNS服务器进行查询等。对于向本地DNS服务器进行查询,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析(此解析具有权威性);如果要查询的域名不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析(此解析不具有权威性)。如果本地域名服务器并未缓存该网址映射关系,那么将根据其设置发起递归查询或者迭代查询;

      (2). 浏览器获得域名对应的IP地址以后,浏览器向服务器请求建立链接,发起三次握手;

      (3). TCP/IP链接建立起来后,浏览器向服务器发送HTTP请求;

      (4). 服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应的视图返回给浏览器;

      (5). 浏览器解析并渲染视图,若遇到对js文件、css文件及图片等静态资源的引用,则重复上述步骤并向服务器请求这些资源;

      (6). 浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。


    11、Session、Cookie 与 Application

      Cookie和Session都是客户端与服务器之间保持状态的解决方案,具体来说,cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。


    (1). Cookie及其相关API

      Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie,而客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器,服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

               Cookoe-HttpServletResponse.png-38.6kB

               HttpServletrequest-cookie.png-8.6kB


    (2). Session及其相关API

      同样地,会话状态也可以保存在服务器端。客户端请求服务器,如果服务器记录该用户状态,就获取Session来保存状态,这时,如果服务器已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用;如果客户端请求不包含sessionid,则为此客户端创建一个session并且生成一个与此session相关联的sessionid,并将这个sessionid在本次响应中返回给客户端保存。保存这个sessionid的方式可以采用 cookie机制 ,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器;若浏览器禁用Cookie的话,可以通过 URL重写机制 将sessionid传回服务器。

               Session-HttpServletRequest.png-10.1kB


    (3). Session 与 Cookie 的对比

    • 实现机制:Session的实现常常依赖于Cookie机制,通过Cookie机制回传SessionID;

    • 大小限制:Cookie有大小限制并且浏览器对每个站点也有cookie的个数限制,Session没有大小限制,理论上只与服务器的内存大小有关;

    • 安全性:Cookie存在安全隐患,通过拦截或本地文件找得到cookie后可以进行攻击,而Session由于保存在服务器端,相对更加安全;

    • 服务器资源消耗:Session是保存在服务器端上会存在一段时间才会消失,如果session过多会增加服务器的压力。

      Application(ServletContext):与一个Web应用程序相对应,为应用程序提供了一个全局的状态,所有客户都可以使用该状态。


    (4). Application

      Application(Java Web中的ServletContext):与一个Web应用程序相对应,为应用程序提供了一个全局的状态,所有客户都可以使用该状态。


    12、SQL 注入

      SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

    1). SQL注入攻击的总体思路

      (1). 寻找到SQL注入的位置
      (2). 判断服务器类型和后台数据库类型
      (3). 针对不通的服务器和数据库特点进行SQL注入攻击


    2). SQL注入攻击实例

      比如,在一个登录界面,要求输入用户名和密码,可以这样输入实现免帐号登录:

    用户名: ‘or 1 = 1 --
    密 码:

      用户一旦点击登录,如若没有做特殊处理,那么这个非法用户就很得意的登陆进去了。这是为什么呢?下面我们分析一下:从理论上说,后台认证程序中会有如下的SQL语句:String sql = “select * from user_table where username=’ “+userName+” ’ and password=’ “+password+” ‘”; 因此,当输入了上面的用户名和密码,上面的SQL语句变成:SELECT * FROM user_table WHERE username=’’or 1 = 1 – and password=’’。分析上述SQL语句我们知道,
    username=‘ or 1=1 这个语句一定会成功;然后后面加两个-,这意味着注释,它将后面的语句注释,让他们不起作用。这样,上述语句永远都能正确执行,用户轻易骗过系统,获取合法身份。


    3). 应对方法

    (1). 参数绑定

      使用预编译手段,绑定参数是最好的防SQL注入的方法。目前许多的ORM框架及JDBC等都实现了SQL预编译和参数绑定功能,攻击者的恶意SQL会被当做SQL的参数而不是SQL命令被执行。在mybatis的mapper文件中,对于传递的参数我们一般是使用#和$来获取参数值。当使用#时,变量是占位符,就是一般我们使用javajdbc的PrepareStatement时的占位符,所有可以防止sql注入;当使用$时,变量就是直接追加在sql中,一般会有sql注入问题。

    (2). 使用正则表达式过滤传入的参数


    13、 XSS 攻击

      XSS是一种经常出现在web应用中的计算机安全漏洞,与SQL注入一起成为web中最主流的攻击方式。XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些脚本代码嵌入到web页面中去,使别的用户访问都会执行相应的嵌入代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。


    1). XSS攻击的危害

    • 盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号

    • 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力

    • 盗窃企业重要的具有商业价值的资料

    • 非法转账

    • 强制发送电子邮件

    • 网站挂马

    • 控制受害者机器向其它网站发起攻击


    2). 原因解析

      主要原因:过于信任客户端提交的数据!

      解决办法:不信任任何客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理然后方可进行下一步的操作。

      进一步分析细节:客户端提交的数据本来就是应用所需要的,但是恶意攻击者利用网站对客户端提交数据的信任,在数据中插入一些符号以及javascript代码,那么这些数据将会成为应用代码中的一部分了,那么攻击者就可以肆无忌惮地展开攻击啦,因此我们绝不可以信任任何客户端提交的数据!!!


    3). XSS 攻击分类

    (1). 反射性XSS攻击 (非持久性XSS攻击)

      漏洞产生的原因是攻击者注入的数据反映在响应中。一个典型的非持久性XSS攻击包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击),例如,正常发送消息:

    http://www.test.com/message.php?send=Hello,World!

    接收者将会接收信息并显示Hello,World;但是,非正常发送消息:

    http://www.test.com/message.php?send=<script>alert(‘foolish!’)</script>

    接收者接收消息显示的时候将会弹出警告窗口!


    (2). 持久性XSS攻击 (留言板场景)

      XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。也就是说,每当用户使用浏览器打开指定页面时,脚本便执行。与非持久性XSS攻击相比,持久性XSS攻击危害性更大。从名字就可以了解到,持久性XSS攻击就是将攻击代码存入数据库中,然后客户端打开时就执行这些攻击代码。

    例如,留言板表单中的表单域:
    
    <input type=“text” name=“content” value=“这里是用户填写的数据”>

    正常操作流程是:用户是提交相应留言信息 —— 将数据存储到数据库 —— 其他用户访问留言板,应用去数据并显示;而非正常操作流程是攻击者在value填写:

    <script>alert(‘foolish!’);</script> <!--或者html其他标签(破坏样式。。。)、一段攻击型代码-->

    并将数据提交、存储到数据库中;当其他用户取出数据显示的时候,将会执行这些攻击性代码。


    4). 修复漏洞方针

      漏洞产生的根本原因是 太相信用户提交的数据,对用户所提交的数据过滤不足所导致的,因此解决方案也应该从这个方面入手,具体方案包括:

    • 将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能
      获取到cookie了(如果在cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击);

    • 表单数据规定值的类型,例如:年龄应为只能为int、name只能为字母数字组合。。。。

    • 对数据进行Html Encode 处理

    • 过滤或移除特殊的Html标签,例如: <script>, <iframe> , < for <, > for>, &quot for

    • 过滤JavaScript 事件的标签,例如 “οnclick=”, “onfocus” 等等。

        需要注意的是,在有些应用中是允许html标签出现的,甚至是javascript代码出现。因此,我们在过滤数据的时候需要仔细分析哪些数据是有特殊要求(例如输出需要html代码、javascript代码拼接、或者此表单直接允许使用等等),然后区别处理!


    14、OSI网络体系结构与TCP/IP协议模型

      为了更好地了解计算机网络体系结构,笔者以两篇博客的篇幅来介绍这个计算机网络中最为重要的知识点,具体见《计算机网络体系结构综述(上)》《计算机网络体系结构综述(下)》。下面只做简要的总结。

      在《计算机网络体系结构综述(下)》一文中,我们知道TCP/IP与OSI最大的不同在于:OSI是一个理论上的网络通信模型,而TCP/IP则是实际上的网络通信标准。但是,它们的初衷是一样的,都是为了使得两台计算机能够像两个知心朋友那样能够互相准确理解对方的意思并做出优雅的回应。现在,我们对OSI七层模型的各层进行简要的介绍:

              OSI网络体系结构与TCPIP协议模型.png-51.3kB


    1). 物理层

      参考模型的最低层,也是OSI模型的第一层,实现了相邻计算机节点之间比特流的透明传送,并尽可能地屏蔽掉具体传输介质和物理设备的差异,使其上层(数据链路层)不必关心网络的具体传输介质。


    2). 数据链路层(data link layer)

      接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层。这一层在物理层提供的比特流的基础上,通过差错控制、流量控制方法,使有差错的物理线路变为无差错的数据链路,即提供可靠的通过物理介质传输数据的方法。


    3). 网络层

      将网络地址翻译成对应的物理地址,并通过路由选择算法为分组通过通信子网选择最适当的路径。

              数据链路层与网路层.png-58.4kB


    4). 传输层(transport layer)

      在源端与目的端之间提供可靠的透明数据传输,使上层服务用户不必关系通信子网的实现细节。在协议栈中,传输层位于网络层之上,传输层协议为不同主机上运行的进程提供逻辑通信,而网络层协议为不同主机提供逻辑通信,如下图所示。

              网路层与传输层.png-52.8kB

      实际上,网络层可以看作是传输层的一部分,其为传输层提供服务。但对于终端系统而言,网络层对它们而言是透明的,它们知道传输层的存在,也就是说,在逻辑上它们认为是传输层为它们提供了端对端的通信,这也是分层思想的妙处。


    5). 会话层(Session Layer)

      会话层是OSI模型的第五层,是用户应用程序和网络之间的接口,负责在网络中的两节点之间建立、维持和终止通信。


    6). 表示层(Presentation Layer):数据的编码,压缩和解压缩,数据的加密和解密

      表示层是OSI模型的第六层,它对来自应用层的命令和数据进行解释,以确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。


    7). 应用层(Application layer):为用户的应用进程提供网络通信服务


    15、TCP和UDP分别对应的常见应用层协议

    1). TCP对应的应用层协议

    • FTP:定义了文件传输协议,使用21端口。常说某某计算机开了FTP服务便是启动了文件传输服务。下载文件,上传主页,都要用到FTP服务。

    • Telnet:它是一种用于远程登陆的端口,用户可以以自己的身份远程连接到计算机上,通过这种端口可以提供一种基于DOS模式下的通信服务。如以前的BBS是-纯字符界面的,支持BBS的服务器将23端口打开,对外提供服务。

    • SMTP:定义了简单邮件传送协议,现在很多邮件服务器都用的是这个协议,用于发送邮件。如常见的免费邮件服务中用的就是这个邮件服务端口,所以在电子邮件设置-中常看到有这么SMTP端口设置这个栏,服务器开放的是25号端口。

    • POP3:它是和SMTP对应,POP3用于接收邮件。通常情况下,POP3协议所用的是110端口。也是说,只要你有相应的使用POP3协议的程序(例如Fo-xmail或Outlook),就可以不以Web方式登陆进邮箱界面,直接用邮件程序就可以收到邮件(如是163邮箱就没有必要先进入网易网站,再进入自己的邮-箱来收信)。

    • HTTP:从Web服务器传输超文本到本地浏览器的传送协议。


    2). UDP对应的应用层协议

    • DNS:用于域名解析服务,将域名地址转换为IP地址。DNS用的是53号端口。

    • SNMP:简单网络管理协议,使用161号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势。

    • TFTP(Trival File Transfer Protocal):简单文件传输协议,该协议在熟知端口69上使用UDP服务。


    3). 图示

              TCP和UDP分别对应的常见应用层协议.png-41.5kB


    16、网络层的ARP协议工作原理

      网络层的ARP协议完成了IP地址与物理地址的映射。首先,每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。当源主机需要将一个数据包要发送到目的主机时,会首先检查自己ARP列表中是否存在该IP地址对应的MAC地址:如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包里包括源主机的IP地址、硬件地址、以及目的主机的IP地址。网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个ARP响应数据包,告诉对方自己是它需要查找的MAC地址;源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。


    17、IP地址的分类

      IP地址是指互联网协议地址,是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。IP地址编址方案将IP地址空间划分为A、B、C、D、E五类,其中A、B、C是基本类,D、E类作为多播和保留使用,为特殊地址。

      每个IP地址包括两个标识码(ID),即网络ID和主机ID。同一个物理网络上的所有主机都使用同一个网络ID,网络上的一个主机(包括网络上工作站,服务器和路由器等)有一个主机ID与其对应。A~E类地址的特点如下:

    • A类地址:以0开头,第一个字节范围:0~127;

    • B类地址:以10开头,第一个字节范围:128~191;

    • C类地址:以110开头,第一个字节范围:192~223;

    • D类地址:以1110开头,第一个字节范围为224~239;

    • E类地址:以1111开头,保留地址


    1). A类地址:1字节的网络地址 + 3字节主机地址,网络地址的最高位必须是“0”

      一个A类IP地址是指, 在IP地址的四段号码中,第一段号码为网络号码,剩下的三段号码为本地计算机的号码。如果用二进制表示IP地址的话,A类IP地址就由1字节的网络地址和3字节主机地址组成,网络地址的最高位必须是“0”。A类IP地址中网络的标识长度为8位,主机标识的长度为24位,A类网络地址数量较少,有126个网络,每个网络可以容纳主机数达1600多万台。

      A类IP地址的地址范围1.0.0.0到127.255.255.255(二进制表示为:00000001 00000000 00000000 00000000 - 01111110 11111111 11111111 11111111),最后一个是广播地址。A类IP地址的子网掩码为255.0.0.0,每个网络支持的最大主机数为256的3次方-2=16777214台。


    2). B类地址: 2字节的网络地址 + 2字节主机地址,网络地址的最高位必须是“10”

      一个B类IP地址是指,在IP地址的四段号码中,前两段号码为网络号码。如果用二进制表示IP地址的话,B类IP地址就由2字节的网络地址和2字节主机地址组成,网络地址的最高位必须是“10”。B类IP地址中网络的标识长度为16位,主机标识的长度为16位,B类网络地址适用于中等规模的网络,有16384个网络,每个网络所能容纳的计算机数为6万多台。

      B类IP地址地址范围128.0.0.0-191.255.255.255(二进制表示为:10000000 00000000 00000000 00000000—-10111111 11111111 11111111 11111111),最后一个是广播地址。B类IP地址的子网掩码为255.255.0.0,每个网络支持的最大主机数为256的2次方-2=65534台。


    3). C类地址: 3字节的网络地址 + 1字节主机地址,网络地址的最高位必须是“110”

      一个C类IP地址是指,在IP地址的四段号码中,前三段号码为网络号码,剩下的一段号码为本地计算机的号码。如果用二进制表示IP地址的话,C类IP地址就由3字节的网络地址和1字节主机地址组成,网络地址的最高位必须是“110”。C类IP地址中网络的标识长度为24位,主机标识的长度为8位,C类网络地址数量较多,有209万余个网络。适用于小规模的局域网络,每个网络最多只能包含254台计算机。

      C类IP地址范围192.0.0.0-223.255.255.255(二进制表示为: 11000000 00000000 00000000 00000000 - 11011111 11111111 11111111 11111111)。C类IP地址的子网掩码为255.255.255.0,每个网络支持的最大主机数为256-2=254台。


    4). D类地址:多播地址,用于1对多通信,最高位必须是“1110”

      D类IP地址在历史上被叫做多播地址(multicast address),即组播地址。在以太网中,多播地址命名了一组应该在这个网络中应用接收到一个分组的站点。多播地址的最高位必须是“1110”,范围从224.0.0.0到239.255.255.255。


    5). E类地址:为保留地址,最高位必须是“1111”


    18、IP地址与物理地址

      物理地址是数据链路层和物理层使用的地址,IP地址是网络层和以上各层使用的地址,是一种逻辑地址,其中ARP协议用于IP地址与物理地址的对应。


    21、 常见状态码及原因短语

      HTTP请求结构: 请求方式 + 请求URI + 协议及其版本
      HTTP响应结构: 状态码 + 原因短语 + 协议及其版本


    • 1×× : 请求处理中,请求已被接受,正在处理

    • 2×× : 请求成功,请求被成功处理
      200 OK

    • 3×× : 重定向,要完成请求必须进行进一步处理
      301 : 永久性转移
      302 :暂时性转移
      304 : 已缓存

    • 4×× : 客户端错误,请求不合法
      400:Bad Request,请求有语法问题
      403:拒绝请求
      404:客户端所访问的页面不存在


    引用

    浅谈HTTP中Get与Post的区别
    TCP的拥塞控制
    Session简介
    javaweb学习总结(十一)——使用Cookie进行会话管理
    XSS跨站脚本攻击

    展开全文
  • 互联网笔试互联网笔试互联网笔试
  • java_笔试笔试java_笔试笔试java_笔试笔试java_笔试笔试java_笔试笔试
  • 常用应届生Java开发笔试面试题(更新中)

    万次阅读 多人点赞 2018-10-19 20:36:57
    Java笔试面试题 个人经历总结 应届生为主, 本文会逐渐转变为Java知识汇总,不再只是应届生层面 2021 更新中

    Java开发面试题

    Java基础篇

    Java8大基本数据类型

    byteshortintlongfloatdoublecharboolean
    占用空间1字节(B)2字节4字节8字节4字节8字节不定 默认2字节JVM未定义
    初始值00000.00.0空格false

    Java的三大特性

    1. 封装:隐藏内部功能的具体实现,只保留和外部交流数据的接口。例:汽车与发动机,不必知道发动机的实现原理,只需使用汽车给予的接口,插入钥匙。
    2. 继承:一个对象可以从它的父类继承所有的通用的属性和方法,并在无需重新编写原来的类的情况下对这些功能进行扩展;最大的好处是实现代码的高效重用。
    3. 多态:同一个动作作用于不同的对象 所产生不同的行为。例:人会吃饭,中国人用筷子,美国人用叉子。

    面向对象

    1. 面向对象的核心,就是类和对象。Java中的面向对象的思想:万物皆对象。
    2. 类:是对一类事物的描述,是抽象的,看不见,摸不着。
    3. 对象:是实际存在的该类事物的每个个体 也称为实例 是具象的。
    4. 所以面向对象程序设计的重点是类的设计,而不是对象的设计。
    5. 类是对象的描述
      对象叫做类的实例化(Instance)
    6. 类不占内存,对象才占内存。

    如果让你推销一款Java产品,你会怎么推销呢?(java的特点)

    1.Java是面向对象的
    2.Java是跨平台的;一次编译,到处运行
    3.Java是多线程的
    4.Java有GC,简化了开发
    5.Java是分布式的
    6.Java现在运用最广泛(有待商榷,python太猛了)
    7.支持多线程( C++ 语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计,而 Java 语言却提供了多线程支持);
    8.支持网络编程并且很方便( Java 语言诞生本身就是为简化网络编程设计的,因此 Java 语言不仅支持网络编程而且很方便);
    9.编译与解释并存;
    

    JVM与字节码

    JVM:Java虚拟机(JVM)是运行 Java 字节码的虚拟机。
    JVM有针对不同系统的特定实现,目的是使用相同的字节码,它们都会给出相同的结果(一次编译,到处运行)。
    字节码:在 Java 中,JVM可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以 Java 程序运行时比较高效,而且,由于字节码并不针对一种特定的机器,因此,Java程序无须重新编译便可在多种不同操作系统的计算机上运行。

    JDK与JRE

    JDK是Java Development Kit,它是功能齐全的Java SDK。它拥有JRE所拥有的一切,还有编译器(javac)和工具(如javadoc和jdb)。它能够创建和编译程序。

    JRE 是 Java运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java虚拟机(JVM),Java类库,java命令和其他的一些基础构件。但是,它不能用于创建新程序。

    << 位运算符

    // 在hashmap源码中 默认的容量和最大容量 它采用了位运算符
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;	// 其实就是16
    static final int MAXIMUM_CAPACITY = 1 << 30;
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
    
    // 位运算符 相当于二进制中 数值左移4位  00001 --> 10000
    

    函数式接口

    Functional Interface

    函数式接口的定义:任何接口,如果只包含一个抽象方法,那么他就是一个函数式接口

    public interface Runnable{
    	public abstract void run();
    }
    

    对于函数式接口,我们可以通过lambda表达式来创建该接口对象。

    StringBuilder和StringBuffer的区别

    1. 他们都是可变长度的字符串
    2. StringBuffer  线程安全   效率低
    3. StringBuilder  线程不安全  效率高
    

    简单介绍下多态、重载、重写

    多态:同一种事物的多种形态。
    作用:1.不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可,提高可复用性;
    	  2.派生类的功能可以被基类的方法或引用变量所调用,提高可扩展性。
    1. 编译时多态	方法重载overload
    	- 方法名必须相同
    	- 形参列表必须不同(形参的数据类型和形参的个数不同)
    	- 与返回值类型无关
    2. 运行时多态	方法重写overwrite
    	- 必须存在继承关系
    	- 重写的方法、返回值类型、参数列表必须和父类的方法保持一致
    	- 子类的访问修饰符不能低于父类方法的访问修饰符 public
    

    成员变量和局部变量

    • 从语法形式上看:成员变量是属于类的,而局部变量是在⽅法中定义的变量或是方法的参数;
      成员变量可以被 public , private , static 等修饰符所修饰,而局部变量不能被访问控制修饰
      符及 static 所修饰;但是,成员变量和局部变量都能被 final 所修饰
    • 从变量在内存中的存储⽅式来看:如果成员变量是使⽤ static 修饰的,那么这个成员变量是属于类的,如果没有使⽤ static 修饰,这个成员变量是属于实例的。对象存于堆内存,如果局部变量类型为基本数据类型,那么存储在栈内存,如果为引⽤数据类型,那存放的是指向堆内存对象的引用或者是指向常量池中的地址
    • 从变量在内存中的⽣存时间上看:成员变量是对象的⼀部分,它随着对象的创建而存在,而局
      部变量随着⽅法的调用而自动消失
    • 成员变量如果没有被赋初值:则会⾃动以类型的默认值⽽赋值(⼀种情况例外:被 final 修饰
      的成员变量也必须显式地赋值),⽽局部变量则不会⾃动赋值

    自动装箱和拆箱

    装箱:将基本类型用它们对应的引用类型包装起来;
    拆箱:将包装类型转换为基本数据类型;

    String能被继承吗?

    public final class String implements java.io.Serializable, Comparable<String>, CharSequence 
    不能,他是被final修饰的。
    底层是由数组实现,数组长度不可变
    

    简单介绍一下static关键字

    static标记的变量或方法由整个类(所有实例)共享,可不必创建该类对象而直接使用;
    static成员也称类成员或静态成员;
    随着类的加载而加载;
    Java中无静态类。
    1. 修饰属性
    	无论创建多少次对象,都会去共享一个静态属性,存在静态域中和类同一级别
    2. 修饰方法
    	也是存在静态域中,可以使用类名.方法名去访问。
    	静态方法只能访问静态成员,如果是非静态的,应该通过实例化对象的方式
    	静态方法不能以任何方式引用this关键字
    

    super()和this()

    this:1.当成员变量和局部变量重名,用关键字this来区分
    	  2.this代表当前对象,this就是所存函数所属对象的引用(哪个对象调用了this所在的函数,this就代表谁)
    	  3.this(参数列表),调用本类中重载的构造方法,必须放在第一行。
    super:1.使用super调用父类的成员方法和属性
    	  2.可以从子类构造方法中调用父类的构造方法,必须放在第一行。
    

    equals和==

    ==:基本类型比较的是值的大小
    	引用类型比较的是内存地址
    equals:默认比较是否是同一个对象
    	例如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容
    	注意:equals方法不能作用于基本数据类型的变量
    
    // 举例如下
    public class test1 {
        public static void main(String[] args) {
            String a = new String("ab"); // a 为一个引用
            String b = new String("ab"); // b为另一个引用,对象的内容一样
            String aa = "ab"; // 放在常量池中
            String bb = "ab"; // 从常量池中查找
            if (aa == bb) // true
                System.out.println("aa==bb");
            if (a == b) // false,非同一对象
                System.out.println("a==b");
            if (a.equals(b)) // true
                System.out.println("aEQb");
            if (42 == 42.0) { // true
                System.out.println("true");
            }
        }
    }
    

    关于常量池

    当创建 String 类型的对象时,JVM先会在常量池中查找是否已经存在,如果已存在,就把它赋给当前引用。如果没有,就在常量池中重新创建一个 String 对象。

    String a = "xx";
    String b ="xx";
    String c = "xxx";
    System.out.println(a==b);  //true   jvm现在常量池中创建了"xx",a指向"xx", 创建b时,先会看常量池中是否有"xx",如果有 让b 指向"xx";如果没有 则新建一个。
    System.out.println(a==c);  // false
    

    抽象类与接口

    抽象类:1.首先有构造方法
    	   2.含有抽象方法的类必须被声明为抽象类
    	   3.抽象类不能被实例化,子类必须重写父类的抽象方法
    	   4.abstract不能修饰属性、构造器、private、static、final
    	   5.一般类中不能定义抽象方法;抽象类中可以有抽象方法,也可以有非抽象方法;
    	   6.抽象方法只有方法声明,没有方法实现。
    接口:1.特殊的抽象类;
    	   2.接口中包含的方法都是抽象方法,没有方法体;
    	   3.实现接口的类需要实现接口的全部方法(JDK8之前)。
    	   4.属性:static final   ;  方法:public abstract
    	   5.JDK8后接口可以有默认实现
    区别:1.抽象类有构造器;接口没有
    	   2.关键字不同
    	   3.抽象类可以有非抽象方法;接口只能由抽象方法(不准确);
    	   4.抽象类可以定义static方法;接口不行
    	   5.接⼝的⽅法默认是 public ,所有⽅法在接⼝中不能有实现(Java 8 开始接⼝⽅法可以有默认实现),⽽抽象类可以有⾮抽象的⽅法。
    	   6. 接⼝中除了 static 、 final 变量,不能有其他变量,⽽抽象类中则不⼀定
    	   7. 接⼝⽅法默认修饰符是 public ,抽象⽅法可以有 public 、 protected 和 default 这些修饰符(抽象⽅法就是为了被重写所以不能使⽤ private 关键字修饰!)
    	   8. 从设计层⾯来说,抽象是对类的抽象,是⼀种模板设计,⽽接⼝是对⾏为的抽象,是⼀种⾏为的规范
    

    JDK8:接口默认实现,可以不用再impl中具体实现,也可以在impl中具体实现

    public interface TestService{
    	default String test(String str) {
    		if(str==null || "".equals(str)){
                return "入参为空";
            }
            return str;
    	}
    }
    

    Java中的比较器(Comparable、Comparator)

    1. 这两个都是接口。
      内部比较器:Comparable
      外部比较器:Comparator
    2. 排序规则实现的方法不同
      Comparable接口的方法:compareTo(Object o)
      Comparator接口的方法:compare(T o1, To2)
    3. Comparable接口用于在类的设计中使用;设计初期,就实现这个借口,指定排序方式。
      Comparator接口用于类设计已经完成,根据需求新建排序类实现排序。
    // 代码演示
    public class Stu implements Comparable{ // 实体类实现内比较器接口
    	private String name;
    	private int age;
    	public Stu(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    	// get set方法已经省略
    	@Override
    	public String toString() {
    		return "Stu [name=" + name + ", age=" + age + "]";
    	}
    	@Override
    	public int compareTo(Object o) {
    		if (o instanceof Stu) {
    			Stu s = (Stu) o;
    			if (this.age > s.age) {
    				return 1;
    			} else if (this.age == s.age) {
    				return 0;
    			} else {
    				return -1;
    			}
    		}
    		return 0;
    	}
    }
    // 外比较器:重新定义排序类实现外比较器
    public class CompareClass implements Comparator<Stu>{
    	@Override
    	public int compare(Stu s1, Stu s2) {
    		return s1.getAge() - s2.getAge();
    	}
    }
    
    // main
    public class TestMain {
    	public static void main(String[] args) {
    		Stu s1 = new Stu("xzy", 23);
    		Stu s2 = new Stu("jay", 40);
    		Stu[] list = new Stu[2];
    		list[0]=s1;
    		list[1]=s2;
    		Arrays.sort(list);// 通过内比较器排序
    		Arrays.sort(list, new CompareClass());// 通过外比较器 自定义的排序类 CompareClass 排序	
    		System.out.println(Arrays.toString(list));
    	}
    }
    

    Java中的栈与堆

    一、Java中的变量在内存中的分配
    1.类变量(static):在程序加载时系统就为他在堆中开辟了内存,堆中的内存地址存放在栈中,以便于高速访问
    	静态变量的周期持续到系统关闭(静态域)。
    2.实例变量:当使用new时,使在堆中开辟相应的内存空间。当实例变量的引用丢失后,将被GC列入可回收名单。
    3.局部变量:当执行到他的时候,在栈中开辟内存,当局部变量一旦脱离作用域,内存立即释放。
    二、堆内存用来存放由new创建的对象和数组,由GC来管理,然后在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,
    	栈中这个变量就成了数组或对象的引用变量。
    三、总结:基本数据类型,局部变量都是存放在栈内存中,用完就消失,没有默认初始化值。
    	new 创建的实例化对象及数组,是放在堆内存中的,用完之后靠GC不定期自动消除;
    	堆内存中所有实体都有内存地址值,有默认初始化值;实体不再被指向时,GC自动清除。
    	局部变量:存储在栈中,必须显示的赋值;
    	成员变量:存储在堆中,有默认初始值。
    

    final、finally、finalize

    final:
    	1.修饰变量:被声明为final的变量必须在声明时给出变量的初始值,而在以后的引用中只能读取。
    	2.final声明方法:方法不能被重写
    	3.修饰类:不能被继承
    finally:在异常处理中作为一个必定会执行的语句块。
    finalize:java技术允许使用finalize方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作
    

    数组和链表的区别

    1.存储位置上:
    	数组逻辑上相邻的元素在物理存储位置上也相邻,而链表不一定;
    2.存储空间上:
    	数组是连续的一段内存空间;链表存放的内存空间可以是连续的,也可以不连续的
    3.长度可变性:
    	数组长度一旦声明不可变,链表的长度是按照实际需求进行分配的
    数组的优点:随机访问性强;查找速度快;
    

    为什么提出集合框架

    数组的优点:1.长度不可变;2.存放对象的个数不确定
    数组的缺陷:1.插入和删除效率低;2.可能浪费内存;3.必须有足够的内存空间;4.数组大小固定
    链表的优点:1.插入删除速度快;2.内存利用率高;3.可扩展
    链表的缺点:1.不能随机查找,必须从第一个开始遍历,查找效率低
    

    集合的概述以及底层数据结构

    • Collection接口
      • List 有序的 可重复的
        • ArrayList:Object数组
        • LinkedList:双向链表(JDK1.6之前为循环链表,JDK1.7取消了循环)
        • Vector:Object数组
      • Set 存储无序的 不可重复的
        • HashSet: 基于 HashMap 实现的,底层采用 HashMap 来保存元素
        • LinkedHashSet:基于LinkedHashMap 实现
        • TreeSet: 红黑树(自平衡的排序二叉树)
    • Map 接口 key-value键值对
      • HashMap:JDK8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
      • LinkedHashMap: 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑
      • TreeMap:红黑树(自平衡的排序二叉树)
      • Hashtable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的

    并发与并行

    并发:是指同一个时间段内多个任务同时都在执行,并且都没有执行结束。并发任务强调在一个时间段内同时执行,而一个时间段由多个单位时间累积而成,所以说并发的多个任务在单位时间内不一定同时在执行 。
    并行:是说在单位时间内多个任务同时在执行 。

    在多线程编程实践中,线程的个数往往多于CPU的个数,所以一般都称多线程并发编程而不是多线程并行编程。

    sleep和wait的区别

    sleep() 方法是线程类(Thread)的静态方法,让调用线程进入睡眠状态,让出执行机会给其他线程,
    等到休眠时间结束后,线程进入就绪状态和其他线程一起竞争cpu的执行时间。
    因为sleep() 是static静态的方法,他不能改变对象的机锁,当一个synchronized块中调用了sleep() 方法,
    线程虽然进入休眠,但是对象的机锁没有被释放,其他线程依然无法访问这个对象。
    wait()是Object类的方法,当一个线程执行到wait方法时,它就进入到一个和该对象相关的等待池,同时释放对象的机锁,
    使得其他线程能够访问,可以通过notify,notifyAll方法来唤醒等待的线程
    

    线程的生命周期

    新建
    就绪
    运行
    阻塞
    死亡
    

    什么是线程、进程

    进程:是程序的一次执行,是具有一定独立功能的程序关于某个数据集合上的一次运动活动,是操作系统资源分配和调度的最小单位。
    线程:是操作系统能够进行运算调度的最小单位,它包含在进程之中,是进程中实际运作单位。
    两者关系:进程是指程序执行时的一个实例,线程是进程的一个实体;
    	线程必定也只数据一个进程,而进程可以拥有多个线程而且至少拥有一个线程。
    

    线程和进程的区别

    进程:
    	- 拥有独立的堆栈空间和数据段,系统开销大
    	- 由于进程之间是独立的特点 使得进程的安全性比较高 有独立的地址空间 一个进程崩溃 不影响其他进程
    	- 进程的通信机制相对复杂 譬如管道、信号、消息队列、套接字等
    线程:
    	- 线程拥有独立的堆栈空间 但是共享数据段,它们彼此之间使用相同的地址空间,比进程开销小
    	- 线程是一个进程中不同的执行路径 一个线程的死亡就等于整个进程的死亡。
    	- 通信相对方便
    

    图解进程线程

    图解进程线程图解进程线程
    从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的堆方法区 (JDK1.8 之后的元空间)资源,但是每个线程有自己的程序计数器虚拟机栈 本地方法栈

    什么是线程安全、为什么提出线程安全、如何实现?

    当一个线程在操作共享资源时,未执行完毕的情况下,其他线程参与进来,导致共享资源出现安全问题。
    方式一:同步代码块
    synchronized(同步监视器){
    	同步的代码
    }
    同步监视器:可以由任何对象来承担,针对于实现的方式可以用对象,也可以采用this关键字。对于继承方式 只能采用静态的对象。
    方式二:同步方法
    确保当中一个线程执行此方法时 其他线程等待知道当前线程执行完。
    

    Thread 类中的start() 和 run() 方法有什么区别?

    start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。
    当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动;start()方法才会启动新线程。
    

    Java中notify 和 notifyAll有什么区别?

    notify()方法不能唤醒某个具体的线程,所以只有一个线程在等待的时候它才有用武之地。
    而notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。
    

    泛型是什么?为什么使用?

    简单的说一种标签,不确定的类型,用户使用的时候确定类型,是JDK1.5出现的新特性,用于解决安全问题,是一种类型安全机制。
    好处:
    	-将运行时期会可能出现的异常转移到编译期
    	-提高了安全性
    	-避免了强制类型转换的麻烦。
    

    概述反射和序列化

    反射:
    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
    对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
    序列化:
    序列化可以理解成把对象转换为容易传输的格式的过程。
    

    序列化的好处

    方便保存对象。因为对象不能保存,所以可以序列化,将其保存。
    

    使用JDBC的过程

    1.加载JDBC驱动程序
    	Class.forName("com.mysql.jdbc.Driver") ;
    2.提供JDBC连接的URL
    	jdbc:mysql: //localhost:3306/test?useUnicode=true&characterEncoding=utf-8 ;
    3.创建数据库的连接
    	Connection con = DriverManager.getConnection(url , username , password )
    4.实现PreparedStatement
    	PreparedStatement pstmt = con.prepareStatement(sql) ;
    5.执行SQL语句
    6.处理结果 
    	-返回结果集
    	-影响的记录数
    7.关闭JDBC对象
    

    数据库篇

    数据库的基本操作

    可以参考我的另一篇博客 常用的SQL语句及进阶

    MySql底层采用什么数据结构来存储数据?

    B-树、平衡树
    

    分页所用的关键字

    MySQL:

    MySQL中使用 LIMIT
    select * from students limit 0, 10   从第0条开始查,一共查询10条记录。
    

    Oracle:

    Oracle中使用 ROWNUM
    select * from students where rownum >= 1 and rownum <= 10 
    

    SQL实现数据表的复制

    select into from 和 insert into select都是用来复制表.
    两者的主要区别为: 
    select into from 要求目标表不存在,因为在插入时会自动创建
    insert into select from 要求目标表存在
    两者的语法:
    SELECT vale1, value2 into Table2 from Table1
    Insert into Table2(field1,field2,...) select value1,value2,... from Table1
    

    什么是事务

    事务(Transaction)是并发控制的基本单位。所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。
    

    事务的四大特性

    -原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行
    -一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。
    -隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行
    -持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中
    

    什么是存储过程

    存储过程可以说是一个记录集吧,也可以认为是一个方法,它是由一些SQL语句组成的代码块,
    这些SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时候调用他就行了。
    

    简单介绍一下触发器

    触发器是由 INSERT、UPDATE 和 DELETE 等事件来触发某种特定操作。
    满足触发器的触发条件时,数据库系统就会执行触发器中定义的程序语句。这样做可以保证某些操作之间的一致性。
    例如,在执行完一句插入语句时,触发查询所有,保证信息的完整性。
    

    什么是E-R图

     ER图中包含了实体(即数据对象)、关系和属性3种基本成分;
     通常用矩形框代表实体,用连接相关实体的菱形框表示关系,用椭圆形或圆角矩形表示实体(或关系)的属性,并用直线把实体(或关系)与其属性连接起来。
     三种联系:
     	- 1:1 例如,一个部门有一个经理,而每个经理只在一个部门任职,则部门与经理的联系是一对一的
     	- 1:N 例如,某校教师与课程之间存在一对多的联系“教”,即每位教师可以教多门课程,但是每门课程只能由一位教师来教。
     	- M:N 例如,学生与课程间的联系(“学”)是多对多的,即一个学生可以学多门课程,而每门课程可以有多个学生来学。
    

    什么是外连接、内连接?

    内连接:根据连接条件只保留两个表中有对应数据的记录;
    外连接:当一个表中记录在另一个表中没有对应记录时,会生成一条与 NULL 值对应的记录
    

    什么是索引?有什么用?

    索引相当于目录,可以更加方便的用于查询。
    

    范式

    • 第一范式
      • 第一范式(1NF)要求数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值。
      • 若某一列有多个值,可以将该列单独拆分成一个实体,新实体和原实体间是一对多的关系。
      • 在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
    • 第二范式
      • 满足第二范式(2NF)必须先满足第一范式(1NF)
      • 第二范式要求实体中没一行的所有非主属性都必须完全依赖于主键;即:非主属性必须完全依赖于主键。
      • 完全依赖:主键可能由多个属性构成,完全依赖要求不允许存在非主属性依赖于主键中的某一部分属性。若存在哪个非主属性依赖于主键中的一部分属性,那么要将发生部分依赖的这一组属性单独新建一个实体,并且在旧实体中用外键与新实体关联,并且新实体与旧实体间是一对多的关系。
    • 第三范式
      • 满足第三范式(3NF)必须先满足第二范式。
      • 第三范式要求:实体中的属性不能是其他实体中的非主属性。因为这样会出现冗余。即:属性不依赖于其他非主属性。
      • 如果一个实体中出现其他实体的非主属性,可以将这两个实体用外键关联,而不是将另一张表的非主属性直接写在当前表中。

    数据结构篇

    快速排序

    冒泡排序

    假设有一些数字: 10, 20 ,90 , 5, 18, 33, 46, 66
    冒泡排序的规则:依次拿取每个数字进行比较,小的放前面,大的放后面(看需求)。

    第一次: 10 , 20					拿前两个数字进行比较 小的放前面。
    第二次: 10 , 20 , 90				拿 90 依次与 10 ,20 比较,大就放后面。
    第三次: 5, 10 , 20 , 90         5 比 10小 所以放最前。
    第四次: 5, 10 , 18 , 20 , 90
    ...
    最终结果: 5 , 10 , 18 , 20, 33 ,46 ,66 ,90
    
    //冒泡排序	外层循环 N-1 内层循环 N-1-i
    for(int i=0; i<arr.length-1;i++){
    	for(int j=0; j<arr.length-1-i;j++){
    		if(arr[j] > arr[j+1]){
    			int t=arg[j];
    			arr[j]=arr[j+1];
    			arr[j+1]=t;
    		}
    	}
    }
    

    二分查找

    二叉树的遍历

    有三种遍历方式:前序、中序、后序
    具体遍历过程可以参考博客
    

    什么是红黑树

    计算机网络篇

    TCP和UDP

    TCP:面向有连接的,三次握手机制;传输的数据大小无限制;安全可靠协议;效率低,区分客户端和服务器
    UDP:是面向无连接的,发送的数据是通过数据报包的形式,不超过64k;不安全(可靠)协议,效率高;不区分客户端和服务器。(叫发送端和接收端)
    

    三次握手 四次挥手

    三次握手
    三次握手

    	1.进行三次握手,首先向服务器发送一个syn报文,其中syn=1,seq number=1022(随机)2.服务器接收到syn报文,根据syn=1判断客户端请求建立连接,并返回一个syn报文,为第一次握手,
    其中ack number=1023(客户端seq number+1),seq number=2032(随机),syn=1,ack=13.客户端根据服务器的syn报文,确认其ack number是否与上一次发送的seq number+1相等,且ack=1,确认正确,则回应一个ack报文,为第二次握手,
    即ack number=2033(服务器seq number+1),ack=14.服务器根据接收到的ack报文,确认ack number是否与上一次发送的seq number+1相等,并且ack=1,确认正确,则建立连接,
    进入Established状态,为第三次握手。
    

    网络的七层协议

    网络架构

    OSI中的层功能TCP/IP协议族
    应用层文件传输、电子邮件、文件服务等TFTP、HTTP、FTP、SMTP、DNS、Telnet、SNMP
    表示层数据格式化、代码转换、数据加密
    会话层解除或建立与别的结点的联系
    传输层提供端对端的接口TCP、UDP
    网络层为数据包选择路由IP、ICMP、OSPF、BGP、ARP、RARP
    数据链路层传输有地址的帧以及错误检测功能SLIP、CSLIP、PPP、MTU、ARP、RARP
    物理层以二进制数据形式在屋里媒体上传输数据ISO2110、IEEE802、IEEE802.2

    当在浏览器输入栏按下回车会发生什么

    1.回车键按下后,浏览器会对输入的地址数据进行解析
    2.进行DNS(域名服务器 UDP的)递归查询
    3.使用套接字进行数据访问
    4.建立TCP连接(三次握手)
    5.浏览器处理数据
    

    邮件服务器之间传送邮件通常使用什么协议,它们分别使用哪个端口,简述其功能。

     邮件服务器之间常用邮件协议 SMTP POP3 IMAP。
    > SMTP:的一个重要特点是它能够在传送中接力传送邮件,即邮件可以通过不同网络上的主机接力式传送。工作在两种情况下:一是电子邮件从客户机传输到服务器;二是从某一个服务器传输到另一个服务器。SMTP是个请求/响应协议,它监听25号端口,用于接收用户的Mail请求,并与远端Mail服务器建立SMTP连接。
    > POP3:仍采用Client/Server工作模式,当客户机需要服务时,客户端的软件将与POP3服务器建立TCP连接,此后要经过POP3协议的三种工作状态,首先是认证过程,确认客户机提供的用户名和密码,在认证通过后便转入处理状态,在此状态下用户可收取自己的邮件或做邮件的删除,在完成响应的操作后客户机便发出quit命令,此后便进入更新状态,将做删除标记的邮件从服务器端删除掉,到此为止整个POP过程完成。
    > IMAP:主要提供的是通过Internet获取信息的一种协议。IMAP像POP那样提供了方便的邮件下载服务,让用户能进行离线阅读,但IMAP能完成的却远远不只这些。IMAP提供的摘要浏览功能可以让你在阅读完所有的邮件到达时间、主题、发件人、大小等信息后才作出是否下载的决定
    

    web篇

    表单中get和post区别

    get:
    	1.不能传递敏感数据
    	2.不能传递大量的数据,每次只能传递1024B
    	3.不能上传附件
    post:
    	1.相对安全
    	2.可以上传海量数据
    	3.可以上传附件
    

    什么是Ajax,好处是什么

    通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。
    这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
    

    九大内置对象

    PrintWriter out	 输出服务器响应的输出流对象;
    Object page  JSP页面本身;
    PageContext pageContext  通过该对象可以获取其他对象;
    HttpServletRequest request  封装客户端的请求,其中包含来自GET或POST请求的参数;
    HttpServletResponse response  封装服务器对客户端的响应;
    HttpSession session  封装用户会话的对象;
    ServletContext application  封装服务器运行环境的对象--全局变量;
    Exception exception  封装页面抛出异常的对象;
    ServletConfig config  Web应用的配置对象。
    

    转发(Forward)和重定向(Redirect)的区别

    转发是服务器行为,重定向是客户端行为
    转发(Forward) 通过RequestDispatcher对象的forward(HttpServletRequest request,HttpServletResponse response)方法实现的。RequestDispatcher可以通过HttpServletRequest 的getRequestDispatcher()方法获得。例如下面的代码就是跳转到success.jsp页面。

     request.getRequestDispatcher("success.jsp").forward(request, response);
    

    重定向(Redirect) 是利用服务器返回的状态码来实现的。客户端浏览器请求服务器的时候,服务器会返回一个状态码。服务器通过 HttpServletResponse 的 setStatus(int status) 方法设置状态码。如果服务器返回301或者302,则浏览器会到新的网址重新请求该资源。

    从地址栏显示来说
    forward是服务器请求资源,服务器直接访问目标地址的URL,把URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器不知道服务器发送的内容从哪里来的,所以地址栏还是原来的地址. 
    redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
    
    从数据共享来说
    forward:转发页面和转发到的页面可以共享request里面的数据.
    redirect:不能共享数据.
    
    从运用地方来说
    forward:一般用于用户登陆的时候,根据角色转发到相应的模块. 
    redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等
    
    从效率来说
    forward:高. 
    redirect:低.
    

    cookie和session

    cookie:浏览器A访问服务器的时候,服务器就给这个A一个id,浏览器会将这个id 保存到本地 cookie中;由web服务器在http响应头中附带给浏览器;一旦浏览器保存了cookie 每次访问web服务器时,都会在http请求头中将cookie 回传给web服务器
    session:采用的是在服务端保持Http状态信息的方案(保存在服务端);当服务端需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否包含了一个session标识(即JSESSIONID);在服务端的session对象的内容,可以访问到,这些变量信息是存在服务器的中的。

    你了解监听器吗?

    监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。
    java的事件监听机制
    1、事件监听涉及到三个组件:事件源事件对象事件监听器
    2、当事件源上发生某一个动作时,它会调用事件监听器的一个方法,并在调用该方法时把事件对象传递进去,
    开发人员在监听器中通过事件对象,就可以拿到事件源,从而对事件源进行操作。

    框架篇(这里只涉及SSM)

    什么是ORM

    对象关系映射(Object Relational Mapping)模式是一种为了解决面向对象与关系数据库存在的互不匹配的技术 ;
    简单的说, ORM是通过使用描述对象和数据库之间的映射的元数据,将程序中的对象自动持久化到关系数据库中

    MyBatis默认用什么做日志管理

    log4j

    MyBatis动态代理

    开发者只需声明mapper接口(类似dao接口),无需声明实现类 而由mybatis框架通过创建接口的代理对象,就和实现类类似。需要按照一定的规范来开发接口和映射文件。
    动态代理规则
    1.映射文件mapper.xml的名称要和接口的名称一致
    2.映射文件的namespace是 接口的全路径
    3.映射文件的sql statement的id是 接口的方法名称
    4.映射文件的输入参数类型(parameterType)和接口方法的参数类型一致
    5.映射文件的输出结果类型(resultType)和接口方法的返回类型一致

    MyBatis输入输出类型

    输入输出支持类型:
    输入parameterType 支持的类型: java简单类型hashmap 、 自定义pojo对象
    输出1resultType: 支持的类型: java简单类型hashmap 、 自定义pojo对象
    注意:封装到自定义pojo对象的要求:对象的属性名和数据库表的字段名一一对应的!!!
    输出2: resultMap:
    1.可以解决对象属性名和数据库字段名不一致的问题
    2.还可以做一对一 和 一对多

    resultMap的使用

    <resultMap type="order" id="orderResultMap">
            <!-- 定义主键 ,非常重要。如果是多个字段,则定义多个id -->
            <!-- property:主键在pojo中的属性名 -->
            <!-- column:主键在数据库中的列名 -->
            <id property="id" column="id" />
    
            <!-- 定义普通属性 -->
            <result property="userId" column="user_id" />
            <result property="number" column="number" />
    </resultMap>
    
    

    为什么使用Druid(德鲁伊),不使用c3p0

    史上最好的data source,有一个监控面板
    	- 可以监控每条sql语句的使用次数、运行效率,
    	- url的监控,请求时间、并发等,
    	- 也能监控session
    

    简单介绍Spring

    spring是一个轻量级的控制反转和面向切面编程的容器框架
    1.轻量级:spring大小和开销都是轻量级的
    2.非入侵:一般在程序开发中,不需要引入spring包
    3.控制反转(IOC):把对象的创建权力交给容器
    4.面向切面编程(AOP):基于代理的 可以将核心业务和系统服务分开

    Spring的两大特性

    1.控制反转 : 把对象的创建、销毁的权利交给容器框架,由容器来管理对象的生命周期;
    	ioc不是新的技术 只是一种思想或理念。可以实现松耦合!
    	ioc包括依赖注入(DI,核心) 和 依赖查找;
    		DI:依赖注入 就是在spring实例化对象的时候,由容器来设置这些对象的属性值。
    2.面向切面编程:采用横向抽取机制,把分散在各个方法中的相同的代码抽取出来,
    	然后再编译期或者是运行时再把这些代码应用到所需要执行的地方。
    	通知(Advice):aop在切点上执行的增强处理。
    	切点(Pointcut):就是带有通知的连接点。
    	切面(Aspect):通常上就是一个类,里面定义了 通知和切点。
    	AOP=通知+切点
    

    什么是MVC

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写.
    Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
    View(视图)是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
    Controller(控制器)是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
    

    SpringMVC的工作流程

    SpringMVC

    客户端发送url到 前端控制器 DispatcherServlet
    前端控制器把请求url发送给 处理器映射器 HandlerMapping
    处理器映射器 根据请求的url来查找 处理器 Handler,并返回给 前端控制器
    前端控制器 调用 处理器适配器 去执行 处理器,传递需要执行的处理器信息
    处理器适配器 执行 处理器
    处理器 返回一个 ModelAndView 对象
    适配器返回ModelAndView给 前端控制器
    前端控制器 调用 视图解析器 去解析视图
    视图解析器 把逻辑视图解析为真正的视图并且返回给 前端控制器
    前端控制器 对视图进行数据渲染、构建DOM树
    把页面返回给客户端。

    声明

    以上试题均为原题或改编,来自各个企业校招笔试面试(不包含BATJ等大厂),仅供参考学习,落笔不易,多多点赞。

    不知不觉 也已经写了一年了,再次感谢大家的阅读 THANKS XD?

    欢迎大家关注我的公众号【再喝最后一杯珍珠奶茶】,了解更多资讯。

    logo

    展开全文
  • 华为2019年3月27日实习生笔试题及解答

    万次阅读 多人点赞 2019-03-29 22:21:20
    3月27日做了华为笔试,3道题2小时。当时没有拍照,现在凭记忆将题目和代码叙述一遍,方便后人。前面将把三道题分别列一下,供后来者自己做。在后面说明一下自己的写法 第一题:题目说的比较复杂,读懂题意之后大致...

    3月27日做了华为笔试,3道题2小时。当时没有拍照,现在凭记忆将题目和代码叙述一遍,方便后人。前面将把三道题分别列一下,供后来者自己做。在后面说明一下自己的写法

    第一题:题目说的比较复杂,读懂题意之后大致是,9个字符一组,每组的第一个字符是标志位,后面8个字符是地址。如果标志位是0,地址逆序,标志位是1地址不变。输入说明:一个字符串,有多组字符,中间没有空格。输出说明:输出最后的地址,每组地址用空格隔开,最后一个输出不需要空格。时间:C/C++1秒其他2秒

    第二题:简而言之就是TSP问题。蜂巢在坐标(0,0)的位置,有五处花丛,蜜蜂从蜂巢出发,要把五处花丛的花蜜采完再回到蜂巢,最短距离是多少。输入说明:一行输入,10个数分别是五处花丛的坐标(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5),用空格隔开。输出说明:输出最短距离,距离向下取整。时间:C/C++5秒其他10秒

    第三题:切水果游戏。有一个40×50的方格,里面有n(1≤n≤36)个水果,每一刀可以横切,竖切以及左斜切与右斜切四种方式。想要切完所有水果,最少需要多少刀。输入说明:第一行是说过个数n,接下来的n行是水果的横纵坐标。输出说明:输出最少需要的刀数。(PS:原题有图,这里无图解释一下切割方式,横切就是所有x相同的水果可以一刀切完,纵切就是y相同,左斜切就是x-y相同,右斜切就是x+y相同)。时间:C/C++3秒其他6秒

    下面是各题做法和思路:

    第一题:题目说的比较复杂,读懂题意之后大致是,9个字符一组,每组的第一个字符是标志位,后面8个字符是地址。如果标志位是0,地址逆序,标志位是1地址不变。输入说明:一个字符串,有多组字符,中间没有空格。输出说明:输出最后的地址,每组地址用空格隔开,最后一个输出不需要空格。

    解答:第一题很简单,9个一组得读取,判断第一个是0还是1即可。5分钟内即可AC。

    # -*- coding:utf8 -*-
    n = int(input())
    strs = input()
    for i in range(n):
        s = strs[9*i:9*i+9]  # 9个一组得读取
        if s[0] == '0':
            s = s[1:]
            s = s[::-1]  # 逆序
        else:
            s = s[1:]
        print(s, end=' ')  # 空格输出

    第二题:简而言之就是TSP问题。蜂巢在坐标(0,0)的位置,有五处花丛,蜜蜂从蜂巢出发,要把五处花丛的花蜜采完再回到蜂巢,最短距离是多少。输入说明:一行输入,10个数分别是五处花丛的坐标(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5),用空格隔开。输出说明:输出最短距离,距离向下取整。

    解答:一开始就想到了全排列之后贪心算法取最小,虽然觉得方法太low了,但是让我一下子写出蚁群之类的觉得记忆模糊就很纠结。后来发现这道题给了10秒的运行时间,妥妥的决定用全排列了。思路:先用全排列的方式获取蜜蜂访问5个花丛的所有可能顺序,之后计算每个路径长度取最小。

    # -*- coding:utf8 -*-
    from math import sqrt
    line = input().strip().split()
    n = list(map(int, line))
    n = [int(i) for i in line]
    nums = [[0,0], [n[0],n[1]], [n[2],n[3]], [n[4],n[5]], [n[6],n[7]], [n[8],n[9]]]
    # 以下为插入的方式获取全排列的代码。没看过别人的,自己想到的。
    # 后来看网上说,递归获取全排列更常见,有兴趣的可以自己去搜一下。
    order = [[1]]
    for i in range(2,6):
        lens = len(order)
        j = 0
        while j < lens:
            for k in range(i-1):
                tmp = order[j][:]  #
                order.append(tmp)
                order[-1].insert(k, i)
            order[j].append(i)
            j += 1
    # 接下来是制作距离矩阵
    dist = [[0] * 6 for i in range(6)]
    for i in range(6):
        for j in range(6):
            if dist[i][j] == 0:
                dist[i][j] = sqrt((nums[i][0]-nums[j][0])**2 + (nums[i][1]-nums[j][1])**2)
            else:
                dist[i][j] = dist[j][i]
    # 贪心算法取最小
    minVal = 0
    for path in order:
        sums = dist[0][path[0]]
        for i in range(4):
            sums += dist[path[i]][path[i+1]]
        sums += dist[path[4]][0]
        if minVal > sums or minVal == 0:
            minVal = sums
    print(int(minVal))

    第三题:切水果游戏。有一个40×50的方格,里面有n(1≤n≤36)个水果,每一刀可以横切,竖切以及左斜切与右斜切四种方式。想要切完所有水果,最少需要多少刀。输入说明:第一行是说过个数n,接下来的n行是水果的横纵坐标。输出说明:输出最少需要的刀数。(PS:原题有图,这里无图解释一下切割方式,横切就是所有x相同的水果可以一刀切完,纵切就是y相同,左斜切就是x-y相同,右斜切就是x+y相同)。时间:C/C++3秒其他6秒。

    解答:当时用的贪心算法,只通过了70%,后来想到了动态规划算法,虽然没试过但是个人感觉应该可以AC。和LeetCode零钱兑换问题差不多的思路。评论中有人说时间复杂度很高。的确时间复杂度是4的n次方。我尝试了一下,n=15应该没问题,超过15时间就比较久了。期待有大佬给出更好的答案。

    # -*- coding:utf8 -*-
    # 40 * 50的方格
    from random import randint
    # 动态规划算法。对于一个点,四种切法去除被切除的点即可获得下一次的点集。加上1即可
    def dp(points):
        if len(points) <= 1:
            return len(points)
        first = points[0]
        row = [i for i in points if i[0] != first[0]]
        cntRow = dp(row)
        col = [i for i in points if i[1] != first[1]]
        cntCol = dp(col)
        left = [i for i in points if i[2] != first[2]]
        cntLeft = dp(left)
        right = [i for i in points if i[3] != first[3]]
        cntRight = dp(right)
        return 1 + min(cntRow, cntCol, cntLeft, cntRight)
    
    
    # 贪心算法。假设只能选择一种方式切,选择刀数最少的
    def greedyOne(points):
        x = [i[0] for i in points]
        y = [i[1] for i in points]
        l = [i[2] for i in points]
        r = [i[3] for i in points]
        return min(len(set(x)), len(set(y)), len(set(l)), len(set(r)))
    
    
    n = int(input())
    points = []
    for i in range(n):
        line = input().strip().split()
        x = int(line[0])
        y = int(line[1])
        l = y - x
        r = x + y
        points.append([x, y, l, r])
    '''
    # 此部分为随机获取点值,确定自己的动态规划算法是否最优
    n = 15
    for i in range(10):
        points = []
        for j in range(n):
            x = randint(0,40)
            y = randint(0,50)
            l = y - x
            r = x + y
            points.append([x, y, l, r])
        res1 = dp(points)
        res2 = greedyOne(points)
        print('dp is %d, greedy is %d'%(res1, res2))
        if res1 > res2:
            print(points)
    '''

     

    展开全文
  • 工行笔试工行笔试工行笔试工行笔试工行笔试工行笔试
  • 华为VUE笔试预约教程(IE笔试 IP笔试预约方法,点个关注,谢谢
  • 笔试题 c语言 智力题 笔试题 c语言 智力题 笔试题 c语言 智力题
  • 阿里巴巴2014笔试题(客户端)DOC文档

    千次下载 热门讨论 2014-04-09 14:19:38
    阿里巴巴2014笔试题(客户端)
  • 浙江电信笔试浙江电信笔试
  • 中国电信笔试中国电信笔试中国电信笔试中国电信笔试中国电信笔试中国电信笔试
  • 操作系统笔试题及答案操作系统笔试题及答案操作系统笔试题及答案操作系统笔试题及答案操作系统笔试题及答案
  • 2021紫光笔试题IC校招笔试
  • 2020编程笔试,C++编程,笔试笔试
  • 华为Java笔试题.txt java面试笔试题大汇总 java笔试题大集合及答案 可供参考
  • 华为VUE笔试预约教程(IE笔试 IP笔试预约方法 ).pdf-
  • 华信笔试笔试笔试

    热门讨论 2011-02-27 10:48:54
    大连华信去年的笔试题,可以给各位即将工作的同学一些参考
  • java笔试题java笔试题java笔试题java笔试题java笔试题java笔试题java笔试题java笔试题java笔试题java笔试题java笔试题java笔试
  • 中兴笔试题 中兴笔试题 中兴笔试题 中兴笔试题 v中兴笔试题 中兴笔试题 ...中兴笔试题 中兴笔试题 中兴笔试题 中兴笔试题中兴笔试题 中兴笔试题 中兴笔试题 中兴笔试题 中兴笔试题 中兴笔试题 中兴笔试题 中兴笔试
  • java笔试笔试

    2011-07-01 20:13:28
    java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 java笔试题 ...
  • 华为笔试题华为笔试题华为笔试题华为笔试题华为笔试题华为笔试题华为笔试题华为笔试
  • 用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题用友笔试题...
  • accp笔试试题笔试试题

    2010-01-15 16:32:36
    笔试试题笔试试题笔试试题笔试试题笔试试题笔试试题笔试试题笔试试题笔试试题笔试试题笔试试题
  • 常见笔试,基础笔试

    2013-10-27 22:26:19
    找工作的时间到了,需要的自己下吧。 笔试题目,供学习 还有其他的笔试题目,我也有上传 ,看我的资源吧
  • c笔试题c笔试题c笔试题c笔试题c笔试题c笔试
  • 校招笔试

    2017-10-23 21:43:46
    校招笔试题,校招笔试题,校招笔试题,校招笔试题,校招笔试
  • 程序员面试笔试宝典

    千次下载 热门讨论 2014-02-21 11:23:21
    面试笔试必看,讲解数据结构和算法,怎么写简历,面试技巧等等
  • S2复习笔试,附答案 S2复习笔试,附答案 S2复习笔试,附答案 S2复习笔试,附答案
  • 2017年5月13日 恒生电子笔试题 JAVA面试题之恒生电子 2018.8.13 java面试之恒生电子① ...2016恒生电子秋招笔试两道算法题 ...08年恒生电子成都笔试题 ...2011年恒生电子校园招聘笔试...恒生电子的坑爹Java笔试题...

    2019网申渠道已开放,全国行程将在9月份正式开启
    完整流程:网申-笔试-2轮面试(群面+单面)-收到实习录取通知
    笔试流程:通过宣讲会,然后现场笔试。
    一般早上9点开始笔试,笔试时间两小时,大概1个多小时完成答题。笔试后一天或一周,收到人力通知参加面试

    笔试介绍
    1.参加笔试的学生分A-F卷,每套卷子的题目不一样,但题型应该差不多
    2.恒生就一套笔试题,没有专门为不同岗位设计不同的试卷(噗!这就很坑爹了)
    意味着网上能找到的所有恒生电子笔试题我都要准备一下,擦泪
    题型
    ###一、基础题
    #####(一) 选择题(单选或多选)
    ######第一部分(基础)

    1. 软件工程的如白盒黑盒测试
    2. 操作系统的进程
    3. 计算机网络
    4. 测试理论、数据库、c语言基础、tcp/ip协议,算法时间复杂度、遍历方法
    5. 基本涉及到大学的主要科目,题目不难但范围广,要拿高分比较难

    6. ######第二部分(Java/c)
    7. C主要考察指针和引用(通过程序段的运行结果来考察),还有数组和字符串、char类型…
    8. java考察了子类和父类的继承,static修饰符,final、finally、finalize三个关键字的区别,还有protected、private、public关键字的区别…
      #####(二) 大题
      ######第一部分(数据库)
    9. 一道数据库的题目(15分):是一个商店的购买记录,用数据库语言进行如下操作,如查询所有女性购买的商品的前三名,查询某种商品的销售额,增加索引,创建一条新的条目等等,属于基本操作,难度不大。(数据库考得是简单语句,有写过一些数据库代码就不难做。)
      涉及的有查询(包括子查询)、分组、排序、求平均值、添加索引,基本都涉及到数据库的增删改查…
      ######第二部分(算法)
    10. 两道算法的题目:一道相对简单,用数据结构或者基本的逻辑思维可以做,让我们输出螺旋矩阵;一道相对难一些,需要用到算法的知识,击鼓传花算法…
      ######第三部分(编程)
      1.一道现场编程题,一方面要写清楚编程思路,一方面写出程序,需要好好锻炼一下。)用c/java/c++编程,我的这份题目是求100以内的素数
      ###二、逻辑题、性格测试
      #####(一) 推理题,这一部分网上有很多类似的题目
      #####(二) 寻找图像规律的题目,有点像智力测试
      #####(三) 寻找数字规律的题目,这一部分找规律的题目比较难,基本靠蒙……

    以下贴出部分关于恒生电子笔试的blog。
    之后对于网上的恒生电子笔试题,我也会慢慢整理,放在我的博客里,供大家参考
    2017年恒生电子春招笔试题
    2016年恒生电子秋招笔试两道算法题
    2008年恒生电子成都笔试题
    2011年恒生电子校招笔试题
    2015年恒生电子春季校招笔试题
    2016年恒生电子校招编程题
    恒生电子的坑爹Java笔试题

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 224,274
精华内容 89,709
关键字:

笔试