学习 java面试题(二)

  • BS与CS的联系与区别

c/s:
  vb,c#,JAVA swing/awt等 客户端/服务器构架 (运行在电脑桌面需要安装的程序)
b/s:
  jsp,asp,php:基于浏览器访问的应用。
共同点:
  1.bs是特殊的cs,此时浏览器充当了客户端
  2.基于HTTP协议的
区别:
  1.cs服务器主要就是一个数据库,所有业务逻辑以及界面渲染交给客户度端
bs:把业务逻辑交给服务端完成,客户端只做界面渲染和数据交换,每次升级需要安装,可移植性差。
  2.cs:较安全,用户界面很丰富,用户体验不错
bs:只开发服务端,跨平台,可移植性强,安全性低,用户体验差。
现在的应用综合BS CS的优点:富客户端技术:客户端会处理部分的业务逻辑,也会做界面的渲染和数据交互.界面丰富好比是CS.EasyUI,Flex,Extjs,Java FX等

  • Cookie 和 Session的区别
  1. 由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session.典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的Session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个唯一标识。在服务端保存Session的方法很多,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,一般会有专门的Session服务器集群,用来保存用户会话,这个时候 Session 信息都是放在内存的,使用一些缓存服务比如Memcached之类的来放 Session。2. 思考一下服务端如何识别特定的客户?这个时候Cookie就登场了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用 Cookie 来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在 Cookie 里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。有人问,如果客户端的浏览器禁用了 Cookie 怎么办?一般这种情况下,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。3. Cookie其实还可以用在一些方便用户的场景下,设想你某次登陆过一个网站,下次登录的时候不想再次输入账号了,怎么办?这个信息可以写到Cookie里面,访问网站的时候,网站页面的脚本可以读取这个信息,就自动帮你把用户名给填了,能够方便一下用户。这也是Cookie名称的由来,给用户的一点甜头。所以,总结一下:Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
  • fail-fast 与 fail-safe 机制有什么区别

1.什么是同步修改(并发修改)?

当一个或多个线程正在遍历一个集合Collection的时候,另一个线程修改了该集合的内容,这就是并发修改。

2.了解fail-fast机制

在遍历一个集合的时候,该集合的结构被修改了,会抛出ConcurrentModificationException 异常。

(1)单线程环境

集合被创建后,在遍历它的过程中修改了结构。注意:remove()方法会使execptionModcount与modcount相等,所以不会抛异常。

(2)多线程环境

当一个线程在遍历这个集合的同时,另一个线程修改了这个集合的结构。注意:修改集合的结构指的是这个集合的大小被改变了,例如:插入元素或者删除元素(除了remove()方法)。

注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检测 bug。

3.了解fail-safe机制

任何对集合的修改都要在一个复制的集合上进行。所以不会出现异常。

弊端:

(1)需要复制集合,产生大量无效数据,开销大。

(2)无法保证读取的数据是目前原始数据结构中的数据。

这篇博客讲的比较细
https://blog.csdn.net/ch717828/article/details/46892051

  • get 和 post请求的区别

最普遍的答案

  • GET使用URL或Cookie传参。而POST将数据放在BODY中。
  • GET的URL会有长度上的限制,则POST的数据则可以非常大。
  • POST比GET安全,因为数据在地址栏上不可见。

但是很不幸,这些区别全是错误的,更不幸的是,这个答案还是Google搜索的头版头条,然而我根本没想着这些是答案,因为在我看来他们都是错的。我来一一解释一下。

  1. GET和POST与数据如何传递没有关系

GET和POST是由HTTP协议定义的。在HTTP协议中,Method和Data(URL, Body, Header)是正交的两个概念,也就是说,使用哪个Method与应用层的数据如何传输是没有相互关系的。

HTTP没有要求,如果Method是POST数据就要放在BODY中。也没有要求,如果Method是GET,数据(参数)就一定要放在URL中而不能放在BODY中。

那么,网上流传甚广的这个说法是从何而来的呢?我在HTML标准中,找到了相似的描述。这和网上流传的说法一致。但是这只是HTML标准对HTTP协议的用法的约定。怎么能当成GET和POST的区别呢?

而且,现代的Web Server都是支持GET中包含BODY这样的请求。虽然这种请求不可能从浏览器发出,但是现在的Web Server又不是只给浏览器用,已经完全地超出了HTML服务器的范畴了。

知道这个有什么用?我不想解释了,有时候就得自己痛一次才记得住。

  1. HTTP协议对GET和POST都没有对长度的限制

HTTP协议明确地指出了,HTTP头和Body都没有长度的要求。而对于URL长度上的限制,有两方面的原因造成:

浏览器。据说早期的浏览器会对URL长度做限制。据说IE对URL长度会限制在2048个字符内(流传很广,而且无数同事都表示认同)。但我自己试了一下,我构造了90K的URL通过IE9访问live.com,是正常的。网上的东西,哪怕是Wikipedia上的,也不能信。
服务器。URL长了,对服务器处理也是一种负担。原本一个会话就没有多少数据,现在如果有人恶意地构造几个几M大小的URL,并不停地访问你的服务器。服务器的最大并发数显然会下降。另一种攻击方式是,把告诉服务器Content-Length是一个很大的数,然后只给服务器发一点儿数据,嘿嘿,服务器你就傻等着去吧。哪怕你有超时设置,这种故意的次次访问超时也能让服务器吃不了兜着走。有鉴于此,多数服务器出于安全啦、稳定啦方面的考虑,会给URL长度加限制。但是这个限制是针对所有HTTP请求的,与GET、POST没有关系。

  • 安全不安全和GET、POST没有关系

我觉得这真是中国特色。我讲个小段子,大家应该可以体会出这个说法多么的可笑。

觉得POST数据比GET数据安全的人会说

“防君子不防小人;中国小白多,能防小白用户就行了。”

“哼,”我不以为然,“那你怎么不说,URL参数都Encode过了,或是Base64一下,小白也看不懂啊。”

那人反驳道,“Encode太简单了,聪明点儿的小白很容易就可以Decode并修改掉。”

我笑道,“五十步笑百步耳,再聪明点儿的小白还会截包并重发呢,Opera就有这功能。”

那人阴险地祭出神器——最终解释权,说,“这个不算小白。”

我日啊。

最后一点儿感想
我之前一直做Windows桌面应用,对Web开发无甚了解,直到一年多前转做服务器端开发,才开始接触到HTTP。(注意,我说的是HTTP,不是HTML。服务器开放接口是基于REST理念设计的,使用的协议是HTTP,但是传输的内容不是HTML。这不是Web Server,而是一个Web Service)

所以我对于GET和POST的理解,是纯粹地来源于HTTP协议。他们只有一点根本区别,简单点儿说,一个用于获取数据,一个用于修改数据。具体的请参考RFC文档。

如果一个人一开始就做Web开发,很可能把HTML对HTTP协议的使用方式,当成HTTP协议的唯一的合理使用方式。从而犯了以偏概全的错误。

  • Interface 与 abstract 类的区别

接口和抽象类有什么区别

你选择使用接口和抽象类的依据是什么?

接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对根源的抽象。

抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。

人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它.

所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。

第一点. 接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
第二点. 接口可以多继承,抽象类不行
第三点. 接口定义方法,不能实现,而抽象类可以实现部分方法。
第四点. 接口中基本数据类型为static 而抽类象不是的。

当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。

抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的

所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的

你可能感兴趣的:(java,面试题)