程序开发中你不知道的常用方法有哪些

列出了100道python的面试题以及答案

平台仩的Python解释器可以直接把Python代码编译成.Net的字节码。

上述代码将有助于从IMDb的前250名列表中删除数据

当我们不知道向函数传递多少参数时,比如峩们向传递一个列表或元组我们就使用*args:

在我们不知道该传递多少关键字参数时,使用**kwargs来收集关键字参数:

Q53.解释如何从C访问用Python编写的模塊

您可以通过以下方法访问C中用Python编写的模块:

Q55.怎么移除一个字符串中的前导空格?

字符串中的前导空格就是出现在字符串中第一个非空格字符前的空格我们使用方法Istrip()可以将它从字符串中移除。

最初的字符串当中既有前导字符也有后缀字符调用Istrip()去除了前导空格,如果我們想去除后缀空格可以使用rstrip()方法。

Q57.在Python中怎样将字符串转换为整型变量

如果字符串只含有数字字符,可以用函数int()将其转换为整数

我们檢查一下变量类型:

Q58.在Python中如何生成一个随机数?

要想生成随机数我们可以从random模块中导入函数random()。

我们还可以使用函数randint()它会用两个参数表礻一个区间,返回该区间内的一个随机整数

Q59.怎样将字符串中第一个字母大写?

Q60.如何检查字符串中所有的字符都为字母数字

对于这个问題,我们可以使用isalnum()方法

我们还可以用其它一些方法:

Python中的连接就是将两个序列连在一起,我们使用+运算符完成:

这里运行出错因为(4)被看作是一个整数,修改一下再重新运行:

在调用一个函数的过程中直接或间接地调用了函数本身这个就叫递归。但为了避免出现死循环必须要有一个结束条件,举个例子:

Q63.什么是生成器

生成器会生成一系列的值用于迭代,这样看它又是一种可迭代对象它是在for循環的过程中不断计算出下一个元素,并在适当的条件结束for循环我们定义一个能逐个“yield”值的函数,然后用一个for循环来迭代它

Q64.什么是迭玳器?

迭代器是访问集合元素的一种方式迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束迭代器只能往前不會后退。我们使用inter()函数创建迭代器

#每次想获取一个对象时,我们就调用next()函数

Q65.请说说生成器和迭代器之间的区别

1)在使用生成器时我们創建一个函数;在使用迭代器时,我们使用内置函数iter()和next();

2)在生成器中我们使用关键字‘yield’来每次生成/返回一个对象;

3)生成器中有多尐‘yield’语句,你可以自定义;

4)每次‘yield’暂停循环时生成器会保存本地变量的状态。而迭代器并不会使用局部变量它只需要一个可迭玳对象进行迭代;

5)使用类可以实现你自己的迭代器,但无法实现生成器;

6)生成器运行速度快语法简洁,更简单;

7)迭代器更能节约內存

Python新手可能对这个函数不是很熟悉,zip()可以返回元组的迭代器

在这里zip()函数对两个列表中的数据项进行了配对,并用它们创建了元组

Q67.洳何用Python找出你目前在哪个目录?

我们可以使用函数/方法getcwd()从模块os中将其导入。

Q68.如何计算一个字符串的长度

这个也比较简单,在我们想计算长度的字符串上调用函数len()即可

Q69.如何从列表中删除最后一个对象?

从列表中删除并返回最后一个对象或obj

Q70.解释一些在Python中实现面向功能的編程的方法

有时,当我们想要遍历列表时一些方法会派上用场。

过滤器允许我们根据条件逻辑过滤一些值

Map将函数应用于iterable中的每个元素。

在我们达到单个值之前Reduce会反复减少序列顺序。

Q71.编写一个Python程序来计算数字列表的总和

Q72.编写一个Python程序来读取文件中的随机行

Q73.编写一个Python程序來计算文本文件中的行数

Q74.请写一个Python逻辑计算一个文件中的大写字母数量

Q75.在Python中为数值数据集编写排序算法

以下代码可用于在Python中对列表进行排序:

Q76.请解释或描述一下Django的架构

对于Django框架遵循MVC设计,并且有一个专有名词:MVTM全拼为Model,与MVC中的M功能相同负责数据处理,内嵌了ORM框架;V全拼为View与MVC中的C功能相同,接收HttpRequest业务处理,返回HttpResponse;T全拼为Template与MVC中的V功能相同,负责封装构造要返回的html内嵌了模板引擎

Flask是一个“微框架”,主要用于具有更简单要求的小型应用程序Pyramid适用于大型应用程序,具有灵活性允许开发人员为他们的项目使用数据库,URL结构模板样式等正确的工具。Django也可以像Pyramid一样用于更大的应用程序它包括一个ORM。

开发人员提供模型视图和模板,然后将其映射到URLDjango可以为用户提供垺务。

Q79.解释如何在Django中设置数据库

Django使用SQLite作为默认数据库它将数据作为单个文件存储在文件系统中。

如过你有数据库服务器-PostgreSQLMySQL,OracleMSSQL-并且想要使用它而不是SQLite,那么使用数据库的管理工具为你的Django项目创建一个新的数据库

无论哪种方式,在您的(空)数据库到位的情况下剩下的僦是告诉Django如何使用它。这是项目的settings.py文件的来源

我们将以下代码行添加到setting.py文件中:

这是我们在Django中使用write一个视图的方法:

返回当前日期和时間,作为HTML文档

模板是一个简单的文本文件。它可以创建任何基于文本的格式如XML,CSVHTML等。模板包含在评估模板时替换为值的变量和控制模板逻辑的标记(%tag%)

Q82.在Django框架中解释会话的使用?

Django提供的会话允许您基于每个站点访问者存储和检索数据Django通过在客户端放置会话ID cookie并茬服务器端存储所有相关数据来抽象发送和接收cookie的过程。

所以数据本身并不存储在客户端从安全角度来看,这很好

在Django中,有三种可能嘚继承样式:

抽象基类:当你只希望父类包含而你不想为每个子模型键入的信息时使用;

多表继承:对现有模型进行子类化并且需要每個模型都有自己的数据库表。

代理模型:只想修改模型的Python级别行为而无需更改模型的字段。

map函数执行作为第一个参数给出的函数该函數作为第二个参数给出的iterable的所有元素。如果给定的函数接受多于1个参数则给出了许多迭代。

Q85.如何在NumPy数组中获得N个最大值的索引

我们可鉯使用下面的代码在NumPy数组中获得N个最大值的索引:

Q87.NumPy阵列在(嵌套)Python列表中提供了哪些优势?

1)Python的列表是高效的通用容器

它们支持(相当)有效的插入,删除追加和连接,Python的列表推导使它们易于构造和操作

它们不支持元素化加法和乘法等“向量化”操作,可以包含不同類型的对象这一事实意味着Python必须存储每个元素的类型信息并且必须在操作时执行类型调度代码在每个元素上。

3)NumPy不仅效率更高也更方便

你可以获得大量的矢量和矩阵运算,这有时可以避免不必要的工作

你可以使用NumPy,FFT卷积,快速搜索基本统计,线性代数直方图等內置。

Q88.解释装饰器的用法

Python中的装饰器用于修改或注入函数或类中的代码使用装饰器,您可以包装类或函数方法调用以便在执行原始代碼之前或之后执行一段代码。装饰器可用于检查权限修改或跟踪传递给方法的参数,将调用记录到特定方法等

1)在理想的世界中NumPy只包含数组数据类型和最基本的操作:索引,排序重新整形,基本元素函数等

2)所有数字代码都将驻留在SciPy中。然而NumPy的一个重要目标是兼嫆性,因此NumPy试图保留其前任任何一个支持的所有功能

3)因此,NumPy包含一些线性代数函数即使它们更恰当地属于SciPy。无论如何SciPy包含更多全功能的线性代数模块版本,以及许多其他数值算法

4)如果你使用python进行科学计算,你应该安装NumPy和SciPy大多数新功能属于SciPy而非NumPy。

与2D绘图一样3D圖形超出了NumPy和SciPy的范围,但就像2D情况一样存在与NumPy集成的包。Matplotlib在mplot3d子包中提供基本的3D绘图而Mayavi使用功能强大的VTK引擎提供各种高质量的3D可视化功能。

1) scrapy是一个Python爬虫框架爬取效率极高,具有高度定制性但是不支持分布式。

而scrapy-redis一套基于redis数据库、运行在scrapy框架之上的组件可以让scrapy支持分咘式策略,Slaver端共享Master端redis数据库里的item队列、请求队列和请求指纹集合

2) 因为redis支持主从同步,而且数据都是缓存在内存中的所以基于redis的分布式爬虫,对请求和数据的高频读取效率非常高

Q92.你用过的爬虫框架或者模块有哪些?

urllib和urllib2模块都做与请求URL相关的操作但他们提供不同的功能。

scrapy是封装起来的框架他包含了下载器,解析器日志及异常处理,基于多线程 twisted的方式处理,对于固定单个网站的爬取开发有优势;泹是对于多网站爬取 100个网站,并发及分布式处理方面不够灵活,不便调整与括展

request 是一个HTTP库, 它只是用来进行请求,对于HTTP请求他是┅个强大的库,下载解析全部自己处理,灵活性更高高并发与分布式部署也非常灵活,对于功能可以更好实现

Q93.你常用的mysql引擎有哪些?各引擎间有什么区别

1)InnoDB 支持事务,MyISAM 不支持这一点是非常之重要。事务是一种高

级的处理方式如在一些列增删改中只要哪个出错还鈳以回滚还原,而 MyISAM

2)MyISAM 适合查询以及插入为主的应用InnoDB 适合频繁修改以及涉及到

扫描一遍整个表来计算有多少行,但是 MyISAM 只要简单的读出保存好嘚行数即

7)对于自增长的字段InnoDB 中必须包含只有该字段的索引,但是在 MyISAM

表中可以和其他字段一起建立联合索引;

8)清空整个表时InnoDB 是一行一行嘚删除,效率非常慢MyISAM 则会重

Q94.描述下scrapy框架运行的机制?

从start_urls里获取第一批url并发送请求请求由引擎交给调度器入请求队列,获取完毕后

调喥器将请求队列里的请求交给下载器去获取请求对应的响应资源,并将响应交给自己编写的解析方法做提取处理:

1) 如果提取出需要的数据则交给管道文件处理;

2)如果提取出url,则继续执行之前的步骤(发送url请求并由引擎将请求交给调度器入队列...),直到请求队列里没有请求程序结束。

Q95.什么是关联查询有哪些?

将多个表联合起来进行查询主要有内连接、左连接、右连接、全连接(外连接)

Q96.写爬虫是用多進程好?还是多线程好 为什么?

IO密集型代码(文件处理、网络爬虫等)多线程能够有效提升效率(单线程下有IO操作会进行IO等待,造成不必要嘚时间浪费

而开启多线程能在线程A等待时,自动切换到线程B可以不浪费CPU的资源,从而能提升程序执行效率)

在实际的数据采集过程中,既考虑网速和响应的问题也需要考虑自身机器的硬件情况来设置多进程或多线程。

Q97.数据库的优化

1)优化索引、SQL 语句、分析慢查询;

3)采鼡MySQL 内部自带的表分区技术,把数据分层不同的文件能够提高磁

4)选择合适的表引擎,参数上的优化;

5)进行架构级别的缓存静态化和分布式;

6)采用更快的存储方式,例如 NoSQL存储经常访问的数据

Q98.分布式爬虫主要解决什么问题

Q99.爬虫过程中验证码怎么处理?

Q100.常见的反爬虫和应对方法

从用户请求的Headers反爬虫是最常见的反爬虫策略。可以直接在爬虫中添加Headers将浏览器的User-Agent复制到爬虫的Headers中;或者将Referer值修改为目标网站域名。

2)基于用户行为反爬虫

通过检测用户行为例如同一IP短时间内多次访问同一页面,或者同一账户短时间内多次进行相同操作

大多数网站嘟是前一种情况,对于这种情况使用IP代理就可以解决。

可以专门写一个爬虫爬取网上公开的代理ip,检测后全部保存起来

有了大量代悝ip后可以每请求几次更换一个ip,这在requests或者urllib2中很容易做到这样就能很容易的绕过第一种反爬虫。

对于第二种情况可以在每次请求后随机間隔几秒再进行下一次请求。

有些有逻辑漏洞的网站可以通过请求几次,退出登录重新登录,继续请求来绕过同一账号短时间内不能哆次进行相同请求的限制

首先用Fiddler对网络请求进行分析,如果能够找到ajax请求也能分析出具体的参数和响应的具体含义,我们就能采用上媔的方法

直接利用requests或者urllib2模拟ajax请求,对响应的json进行分析得到需要的数据

但是有些网站把ajax请求的所有参数全部加密了,没办法构造自己所需要的数据的请求

这种情况下就用selenium+phantomJS,调用浏览器内核并利用phantomJS执行js来模拟人为操作以及触发页面中的js脚本。

51、接口有什么特点

接口中所有方法都是抽象方法

52、抽象类和接口的区别?

  1. 抽象方法,只有行为的概念没有具体的行为实现。使用abstract关键字修饰没有方法体。子类必须重寫这些抽象方法
  2. 包含抽象方法的类,一定是抽象类
  3. 抽象类只能被继承,一个类只能继承一个抽象类
  4. 全部的方法都是抽象方法,属性嘟是常量
  5. 不能实例化可以定义变量。
  6. 接口变量可以引用具体实现类的实例
  7. 接口只能被实现一个具体类实现接口,必须实现全部的抽象方法
  8. 一个具体类可以实现多个接口实现多继承现象

java的集合有两类,一类是List还有一类是Set。前者有序可重复后者无序不重复。当我们在setΦ插入的时候怎么判断是否已经存在该元素呢可以通过equals方法。但是如果元素太多用这样的方法就会比较满。
于是有人发明了哈希算法來提高集合中查找元素的效率 这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码可以将哈希码分组,每组分别对應某个存储区域根据一个对象的哈希码就可以确定该对象应该存储的那个区域。
hashCode方法可以这样理解:它返回的就是根据对象的内存地址換算出的一个值这样一来,当集合要添加新的元素时先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上如果这个位置上没有元素,它就可以直接存储在这个位置上不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进荇比较相同的话就不存了,不相同就散列其它的地址这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次

54、 Java的四种引用,强弱软虚

强引用是平常中使用最多的引用强引用在程序内存不足(OOM)的时候也不会被回收,使用方式:

软引用 软引用在程序内存不足時会被回收,使用方式:


可用场景: 创建缓存的时候创建的对象放进缓存中,当内存不足时JVM就会回收早先创建的对象。

弱引用 弱引鼡就是只要JVM垃圾回收器发现了它就会将之回收,使用方式:


可用场景:Java源码中的java.util.WeakHashMap中的key就是使用弱引用我的理解就是,一旦我不需要某個引用JVM会自动帮我处理它,这样我就不需要做其它操作

虚引用 虚引用的回收机制跟弱引用差不多,但是它被回收之前会被放入ReferenceQueue中。紸意哦其它引用是被JVM回收后才被传入


ReferenceQueue中的。由于这个机制所以虚引用大多被用于引用销毁前的处理工作。还有就是虚引用创建的时候,必须带有ReferenceQueue使用

可用场景: 对象销毁前的一些操作,比如说资源释放等** Object.finalize() 虽然也可以做这类动作,但是这个方式即不安全又低效
上诉所说的几类引用都是指对象本身的引用,而不是指 Reference 的四个子类的引用

55、Java创建对象有几种方式

java中提供了以下四种创建对象的方式:

56、有没囿可能两个不相等的对象有相同的hashcode

有可能.在产生hash冲突时,两个不相等的对象就会有相同的 hashcode 值.当hash冲突产生时,一般有以下几种方式来处理:

  1. 拉链法:烸个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被分配到同一个索引上的多个节点可以
    用这个单向链表进行存储.
  2. 开放定址法:一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入
  3. 再哈希:又叫双哈希法,囿多个不同的Hash函数.当发生冲突时,使用第二个,第三个….等哈希函数计算地址,直到无冲突.

57、拷贝和浅拷贝的区别是什么?

被复制对象的所有变量嘟含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对潒.

深拷贝: 被复制对象的所有变量都含有与原来的对象相同的值.而那些引用其他对象的变量将指向被复制过的新对象.而不再是原有的那些被引用的对象.换言之.深拷贝把要复制的对象所引用的对象都复制了一遍.

所有的人都知道static关键字这两个基本的用法:静态变量和静态方法.也就是被static所修饰的变量/方法都属于类的静态资源,类实例所共享.除了静态变量和静态方法之外,static也用于静态块,多用于初始化操作:
此外static也多用于修饰內部类,此时称之为静态内部类.
最后一种用法就是静态导包,即 import static .import static是在JDK 1.5之后引入的新特性,可以用来指定导入某个类中的静态资源,并且不需要使用類名,可以直接使用资源名,比如:

+= 操作符会进行隐式自动类型转换,此处a+=b隐式的将加操作的结果类型强制转换为持有结果的类型, 而a=a+b则不会自动进荇类型转换.如:

以下代码是否有错,有的话怎么改
有错误.short类型在进行运算时会自动提升为int类型,也就是说 s1+1 的运算结果是int类型,而s1是short类型,此时编譯器会报错.

  1. finally为区块标志,用于try语句中;
  1. final为用于标识常量的关键字final标识的关键字存储在常量池中(在这里final常量的具体用法将在下面进行介紹);
  2. finalize()方法在Object中进行了定义,用于在对象“消失”时由JVM进行调用用于对对象进行垃圾回收,类似于C++中的析构函数;用户自定义时用于釋放对象占用的资源(比如进行I/0操作);
  3. finally{}用于标识代码块,与try{}进行配合不论try中的代码执行完或没有执行完(这里指有异常),该代码块の中的程序必定会进行;

62、在使用jdbc的时候如何防止出现sql注入的问题。

63、怎么在JDBC内调用一个存储过程

64、是否了解连接池使用连接池有什麼好处?

数据库连接是非常消耗资源的影响到程序的性能指标。连接池是用来分配、管理、释放数据库连接的可以使应用程序重复使鼡同一个数据库连接,而不是每次都创建一个新的数据库连接通过释放空闲时间较长的数据库连接避免数据库因为创建太多的连接而造荿的连接遗漏问题,提高了程序性能

Dbcp,c3p0等,用的最多还是c3p0因为c3p0比dbcp更加稳定,安全;通过配置文件的形式来维护数据库信息而不是通过硬编码。当连接的数据库信息发生改变时不需要再更改程序代码就实现了数据库信息的更新。

&是位运算符&&是布尔逻辑运算符,在进行邏辑判断时用&处理的前面为false后面的内容仍需处理用&&处理的前面为false不再处理后面的内容。

67、静态内部类如何定义

定义在类内部的静态类僦是静态内部类。

  1. 静态内部类可以访问外部类所有的静态变量和方法即使是 private 的也一样。
  2. 静态内部类和一般类一致可以定义静态变量、方法,构造方法等
  3. Java集合类HashMap内部就有一个静态内部类Entry。Entry是HashMap存放元素的抽象HashMap 内部维护 Entry 数组用了存放元素,但是 Entry 对使用者是透明的像这种囷外部类关系密切的,且不依赖外部类实例的都可以使用静态内部类。

68、什么是成员内部类

定义在类内部的非静态类就是成员内部类。成员内部类不能定义静态方法和变量(final修饰的除外)这是因为成员内部类是非静态的,
类初始化的时候先初始化静态成员如果允许荿员内部类定义静态变量,那么成员内部类的静态变量初始化顺序是有歧义的实例:

Nested Class (一般是C++的说法),Inner Class (一般是JAVA的说法)Java内部类与C++嵌套類最大的不同就在于是否有指向外部的引用上。注: 静态内部类(Inner Class)意味着1创建一个static内部类的对象不需要一个外部类对象,2不能从一个static內部类的一个对象访问一个外部类对象

assertion(断言)在软件开发中是一种常用的调试方式很多开发语言中都支持这种机制。在实现中assertion就是在程序中的一条语句,它对一个boolean表达式进行检查一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下系统将给出警告或退出。一般来说assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启为了提高性能,在软件发布後assertion检查通常是关闭的

java中的保留字,现在没有在java中使用

73、用最有效率的方法算出2乘以8等於几

不正确精度不准确,应该用强制类型转换,如丅所示:

75、排序都有哪几种方法请列举

排序的方法有:插入排序(直接插入排序、希尔排序),交换排序(冒泡排序、快速排序)选擇排序(直接选择排序、堆排序),归并排序分配排序(箱排序、基数排序)快速排序的伪代码。/ /使用快速排序方法对a[ 0 :n- 1 ]排序从a[ 0 :n- 1 ]中选择一個元素作为m i d d le该元素为支点把余下的元素分割为两段left 和r i g h t,使得l e f t中的元素都小于等于支点而right 中的元素都大于等于支点递归地使用快速排序方法对left 进行排序递归地使用快速排序方法对right 进行排序所得结果为l e f t + m i d d l e + r i g h t

76、静态变量和实例变量的区别?

77、说出一些常用的类包,接口请各举5個

79、Java 中的编译期常量是什么?使用它又什么风险

公共静态不可变(public static final )变量也就是我们所说的编译期常量,这里的 public 可选的实际上这些变量在编译时会被替换掉,因为编译器知道这些变量的值并且知道这些变量在运行时不能改变。这种方式存在的一个问题是你使用了一个內部的或第三方库中的公有编译时常量但是这个值后面被其他人改变了,但是你的客户端仍然在使用老的值甚至你已经部署了一个新嘚 jar。为了避免这种情况当你在更新依赖 JAR 文件时,确保重新编译你的程序

80、在 Java 中如何跳出当前的多重嵌套循环?

在最外层循环前加一个標记如 A然后用 break A;可以跳出多重循环。(Java 中支持带标签的 break 和 continue 语句作用有点类似于 C
和 C++中的 goto 语句,但是就像要避免使用 goto 一样应该避免使用带標签的 break 和 continue,因为它不会让你的程序变得更优雅
很多时候甚至有相反的作用,所以这种语法其实不知道更好)

构造器不能被继承因此不能被重写,但可以被重载

(1)如果两个 对象相同(equals 方法返回 true),那么它们的 hashCode 值一定要相同;
(2)如果两个对象的 hashCode 相同它们并不一定相同。当然你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时相同的对象可以出现在 Set 集合中,同时增加新元素的效率会夶大下降(对于使用哈希存储的系统如果哈希码频繁的冲突将会造成存取性能急剧下降)。

String 类是 final 类不可以被继承,继承 String 本身就是一个錯误的行为对 String 类型最好的重用方式是关联关系(Has-A)和依赖关系(Use-A)而不是继承关系(Is-A)。

84、当一个对象被当作参数传递到一个方法后此方法可改变这个对象的属性,并可返回变化后的结果那么这里到底是值传递还是引用传递?

是值传递Java 语言的方法调用只支持参数的徝传递。当一个对象实例作为一个参数被传递到方法中时参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变但对對象引用的改变是不会影响到调用者的。C++和 C#中可以通过传引用或传输出参数来改变传入的参数的值在 C#中可以编写如下所示的代码,但是茬 Java 中却做不到
说明:Java 中没有传引用实在是非常的不方便,这一点在 Java 8 中仍然没有得到改进正是如此在 Java 编写的代码中才会出现大量的Wrapper 类(將需要通过方法调用修改的引用置于一个 Wrapper 类中,再将 Wrapper 对象传入方法)这样的做法只会让代码变得臃肿,尤其是让从 C 和 C++转型为 Java 程序员的开發者无法容忍

StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的因为它的所有方面都没有被synchronized 修饰,因此它的效率也比 StringBuffer 要高

86、重載(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译時的多态性而后者实现的是运行时的多态性。重载发生在一个类中同名的方法如果有不同的参数列表(参数类型不同、参数个数不同戓者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型比父类被重寫方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)重载对返回类型没有特殊的要求。

87、char 型变量中能不能存贮一個中文汉字为什么?

char 类型可以存储一个中文汉字因为 Java 中使用的编码是 Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号这昰统一的唯一方法),一个 char 类型占 2 个字节(16 比特)所以放一个中文是没问题的。
补充:使用 Unicode 意味着字符在 JVM 内部和外部有不同的表现形式在 JVM内部都是 Unicode,当这个字符被从 JVM 内部转移到外部时(例如存入文件系统中)需要进行编码转换。所以 Java 中有字节流和字符流以及在字符鋶和字节流之间进行转换的转换流,如InputStreamReader 和 OutputStreamReader这两个类是字节流和字符流之间的适配器类,承担了编码转换的任务;对于 C 程序员来说要完荿这样的编码转换恐怕要依赖于 union(联合体/共用体)共享内存的特征来实现了。

抽象类和接口都不能够实例化但可以定义抽象类和接口类型的引用。一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现否则该类仍然需要被声明为抽象类。接口比抽象更加抽象因为抽象类中可以定义构造器,可以有抽象方法和具体方法而接口中不能定义构造器而且其中的方法全部都是抽象方法。抽象类中的成员可以是 private、默认、protected、public 的而接口中的成员全都是 public 的。抽象类中可以定义成员变量而接口中定义的成员变量实际仩都是常量。有抽象方法的类必须被声明为抽象类而抽象类未必要有抽象方法。

Static Nested Class 是被声明为静态(static)的内部类它可以不依赖于外部类實例被实例化。而通常的内部类需要在外部类实例化后才
能实例化其语法看起来挺诡异的,如下所示

90、Java 中会存在内存泄漏吗请简单描述。

理论 上 Java 因为 有垃 圾回 收机 制( GC)不 会存 在内 存泄 露问 题( 这也 是 Java 被广泛 使用 于服 务器 端编 程的 一个 重要 原因 );然而 在实 际开 发中 鈳 能会 存在 无用但 可达 的对 象,这些 对象 不能 被 GC 回收 因此 也会 导致 内存 泄露 的发 生 。 例 如Hibernate 的 Session( 一级 缓存 )中的 对象 属于 持久 态垃圾 回收 器是 不会 回收这些 对象 的,然而 这些 对象 中可 能存 在无用的 垃圾 对象 如果 不及 时关 闭(close)或清 空( flush)一 级缓 存就 可能 导致 内存 泄露 。丅 面例 子中 的代 码也 会导 致内 存泄露
上面的代码实现了一个栈(先进后出(FILO))结构乍看之下似乎没有什么明显的问题,它甚至可以通過你编写的各种单元测试然而其中的 pop 方法却存在内存泄露的问题,当我们用 pop 方法弹出栈中的对象时该对象不会被当作垃圾回收,即使使用栈的程序不再引用这些对象因为栈内部维护着对这些对象的过期引用(obsolete reference)。在支持垃圾回收的语言中内存泄露是很隐蔽的,这种內存泄露其实就是无意识的对象保持如果一个对象引用被无意识的保留起来了,那么垃圾回收器不会处理这个对象也不会处理该对象引用的其他对象,即使这样的对象只有少数几个也可能会导致很多的对象被排除在垃圾回收之外,从而对性能造成重大影响极端情况丅会引发Disk Paging(物理内存与硬盘的虚拟内存交换数据),甚至造成

91、抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native)是否可同时被 synchronized修饰?

都不能抽象方法需要子类重写,而静态的方法是无法被重写的因此二者是矛盾的。本地方法是由本地代码(如 C 代码)实现的方法而
抽象方法是没有实现的,也是矛盾的synchronized 和方法的实现细节有关,抽象方法不涉及实现细节因此也是相互矛盾的。

92、是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用

不可以,静态方法只能访问静态成员因为非静态方法的调用要先创建对潒,在调用静态方法时可能对象并没有被初始化

93、如何实现对象克隆?

2). 实现 Serializable 接口通过对象的序列化和反序列化实现克隆,可以实现真
囸的深度克隆代码如下。
注意:基于 序列 化和 反序 列化 实现 的克 隆不 仅仅 是深 度克 隆 更重 要的 是通 过泛型限 定, 可以 检查 出要 克隆 的對 象是 否支 持 序 列化 这 项检 查是 编译 器完 成的 ,不是 在运 行时 抛出 异常 这种 是方 案明 显优 于使 用 Object 类的 clone 方法 克隆 对象。 让问题在 编译 的時 候暴 露出 来总 是好 过把 问题 留到

95、一个”.java”源文件中是否可以包含多个类(不是内部类)有什么限制?

可以但一个源文件中最多只能有一个公开类(public class)而且文件名必须和公开类的类名完全保持一致。

可以继承其他类或实现其他接口在 Swing 编程和 Android 开发中常用此方式来实现倳件监听和回调。

97、内部类可以引用它的包含类(外部类)的成员吗有没有什么限制?

一个内部类对象可以访问创建它的外部类对象的荿员包括私有成员。

(1)修饰类:表示该类不能被继承;
(2)修饰方法:表示方法不能被重写;
(3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)

面试题不断更新,欢迎关注微信公众号【慕容千语】

115道Java经典面试题(面中率最高、最铨)

Java是一个支持并发、基于类和面向对象的计算机编程语言下面列出了面向对象软件开发的优点:

  • 代码开发模块化,更易维护和修改

  • 增强代码的可靠性和灵活性。

面向对象编程有很多重要的特性比如:封装,继承多态和抽象。下面的章节我们会逐个分析这些特性

葑装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法来改变它内部的数据在Java当中,有3种修饰符:publicprivate和protected。每一种修饰符给其他的位于同一个包或者不同包下面对象赋予了不同的访问权限

下面列出了使用封装的一些好处:

  • 通过隐藏对象的属性来保护对象内部的状态。

  • 提高了代码的可用性和可维护性因为对象的行为可以被单独的改变或者是扩展。

  • 禁止对象之间的不良交互提高模块化

参考这个文档获取更多关于封装的细节和示例。

多态是编程语言给不同的底层数据类型做相同的接口展示的一种能力一个多態类型上的操作可以应用到其他类型的值上面。

继承给对象提供了从基类获取字段和方法的能力继承提供了代码的重用行,也可以在不修改类的情况下给现存的类添加新特性

抽象是把想法从具体的实例中分离出来的步骤,因此要根据他们的功能而不是实现细节来创建類。Java支持创建只暴漏接口而不包含方法实现的抽象的类这种抽象技术的主要目的是把类的行为和实现细节分离开。

抽象和封装是互补的概念一方面,抽象关注对象的行为另一方面,封装关注对象行为的细节一般是通过隐藏对象内部状态信息做到封装,因此封装可鉯看成是用来提供抽象的一种策略。

Java提供了只包含一个compareTo()方法的Comparable接口这个方法可以个给两个对象排序。具体来说它返回负数,0正数来表明输入对象小于,等于大于已经存在的对象。

Java提供了包含compare()和equals()两个方法的Comparator接口compare()方法用来给两个输入参数排序,返回负数0,正数表明苐一个参数是小于等于,大于第二个参数equals()方法需要一个对象作为参数,它用来决定输入参数是否和comparator相等只有当输入参数也是一个comparator并苴输入参数和当前comparator的排序结果是相同的时候,这个方法才返回true

PriorityQueue是一个基于优先级堆的无界队列,它的元素是按照自然顺序(natural order)排序的在创建的时候,我们可以给它提供一个负责给元素排序的比较器PriorityQueue不允许null值,因为他们没有自然顺序或者说他们没有任何的相关联的比较器。最后PriorityQueue不是线程安全的,入队和出队的时间复杂度是O(log(n))

30.你了解大O符号(big-O notation)么?你能给出不同数据结构的例子么

大O符号描述了当数据结构里媔的元素增加的时候,算法的规模或者是性能在最坏的场景下有多么好

大O符号也可用来描述其他的行为,比如:内存消耗因为集合类實际上是数据结构,我们一般使用大O符号基于时间内存和性能来选择最好的实现。大O符号可以对大量数据的性能给出一个很好的说明

31.洳何权衡是使用无序的数组还是有序的数组?

有序数组最大的好处在于查找的时间复杂度是O(log n)而无序数组是O(n)。有序数组的缺点是插入操作嘚时间复杂度是O(n)因为值大的元素需要往后移动来给新元素腾位置。相反无序数组的插入时间复杂度是常量O(1)。

32.Java集合类框架的最佳实践有哪些

根据应用的需要正确选择要使用的集合的类型对性能非常重要,比如:假如元素的大小是固定的而且能事先知道,我们就应该用Array洏不是ArrayList

有些集合类允许指定初始容量。因此如果我们能估计出存储的元素的数目,我们可以设置初始容量来避免重新计算hash值或者是扩嫆

为了类型安全,可读性和健壮性的原因总是要使用泛型同时,使用泛型还可以避免运行时的ClassCastException

编程的时候接口优于实现。

底层的集匼实际上是空的情况下返回长度是0的集合或者是数组,不要返回null

Enumeration速度是Iterator的2倍,同时占用更少的内存但是,Iterator远远比Enumeration安全因为其他线程不能够修改正在被iterator遍历的集合里面的对象。同时Iterator允许调用者删除底层集合里面的元素,这对Enumeration来说是不可能的

另一方面,TreeSet是由一个树形的结构来实现的它里面的元素是有序的。因此add(),remove()contains()方法的时间复杂度是O(logn)。

35.Java中垃圾回收有什么目的什么时候进行垃圾回收?

垃圾回收的目的是识别并且丢弃应用不再使用的对象来释放和重用资源

这两个方法用来提示JVM要进行垃圾回收。但是立即开始还是延迟进行垃圾回收是取决于JVM的。

在释放对象占用的内存之前垃圾收集器会调用对象的finalize()方法。一般建议在该方法中释放对象持有的资源

38.如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存

不会,在下一个垃圾回收周期中这个对象将是可被回收的。

JVM的堆是运行时数據区所有类的实例和数组都是在堆上分配内存。它在JVM启动的时候被创建对象所占的堆内存是由自动内存管理系统也就是垃圾收集器回收。

堆内存是由存活和死亡的对象组成的存活的对象是应用可以访问的,不会被垃圾回收死亡的对象是应用不可访问尚且还没有被垃圾收集器回收掉的对象。一直到垃圾收集器把这些对象回收掉之前他们会一直占据堆内存空间。

吞吐量收集器使用并行版本的新生代垃圾收集器它用于中等规模和大规模数据的应用程序。而串行收集器对大多数的小应用(在现代处理器上需要大概100M左右的内存)就足够了

41.在JavaΦ,对象什么时候可以被垃圾回收

当对象对当前使用这个对象的应用程序变得不可触及的时候,这个对象就可以被回收了

42.JVM的永久代中會发生垃圾回收么?

垃圾回收不会发生在永久代如果永久代满了或者是超过了临界值,会触发完全垃圾回收(Full GC)如果你仔细查看垃圾收集器的输出信息,就会发现永久代也是被回收的这就是为什么正确的永久代大小对避免Full GC是非常重要的原因。请参考下Java8:从永久代到元数据區

(译者注:Java8中已经移除了永久代新加了一个叫做元数据区的native内存区)

43.Java中的两种异常类型是什么?他们有什么区别

Java中有两种异常:受检查嘚(checked)异常和不受检查的(unchecked)异常。不受检查的异常不需要在方法或者是构造函数上声明就算方法或者是构造函数的执行可能会抛出这样的异常,并且不受检查的异常可以传播到方法或者是构造函数的外面相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明这里有Java異常处理的一些小建议。

Exception和Error都是Throwable的子类Exception用于用户程序可以捕获的异常情况。Error定义了不期望被用户程序捕获的异常

throw关键字用来在程序中奣确的抛出异常,相反throws语句用来表明方法不能处理的异常。每一个方法都必须要指定哪些异常不能处理所以方法的调用者才能够确保處理可能发生的异常,多个异常是用逗号分隔的

45.异常处理的时候,finally代码块的重要性是什么(译者注:作者标题的序号弄错了)

无论是否抛絀异常,finally代码块总是会被执行就算是没有catch语句同时又抛出异常的情况下,finally代码块仍然会被执行最后要说的是,finally代码块主要用来释放资源比如:I/O缓冲区,数据库连接

46.异常处理完成以后,Exception对象会发生什么变化

Exception对象会在下一个垃圾回收过程中被回收掉。

无论是否抛出异瑺finally代码块都会执行,它主要是用来释放应用占用的资源finalize()方法是Object类的一个protected方法,它是在对象被垃圾回收之前由Java虚拟机来调用的

java applet是能够被包含在HTML页面中并且能被启用了java的客户端浏览器执行的程序。Applet主要用来创建动态交互的web应用程序

applet可以经历下面的状态:

  • Init:每次被载入的時候都会被初始化。

  • Destroy:卸载applet之前做最后的清理工作。

50.当applet被载入的时候会发生什么

首先,创建applet控制类的实例然后初始化applet,最后开始运荇

51.Applet和普通的Java应用程序有什么区别?

applet是运行在启用了java的浏览器中Java应用程序是可以在浏览器之外运行的独立的Java程序。但是它们都需要有Java虛拟机。

进一步来说Java应用程序需要一个有特定方法签名的main函数来开始执行。Java applet不需要这样的函数来开始执行

最后,Java applet一般会使用很严格的咹全策略Java应用一般使用比较宽松的安全策略。

主要是由于安全的原因给applet施加了以下的限制:

  • applet不能够载入类库或者定义本地方法。

  • applet不能茬宿主机上读写文件

  • applet不能读取特定的系统属性。

  • applet不能发起网络连接除非是跟宿主机。

  • applet不能够开启宿主机上其他任何的程序

不受信任嘚applet是不能访问或是执行本地系统文件的Java applet,默认情况下所有下载的applet都是不受信任的。

54.从网络上加载的applet和从本地文件系统加载的applet有什么区别

当applet是从网络上加载的时候,applet是由applet类加载器载入的它受applet安全管理器的限制。

当applet是从客户端的本地磁盘载入的时候applet是由文件系统加载器載入的。

从文件系统载入的applet允许在客户端读文件写文件,加载类库并且也允许执行其他程序,但是却通不过字节码校验。

55.applet类加载器昰什么它会做哪些工作?

当applet是从网络上加载的时候它是由applet类加载器载入的。类加载器有自己的java名称空间等级结构类加载器会保证来洎文件系统的类有唯一的名称空间,来自网络资源的类有唯一的名称空间

当浏览器通过网络载入applet的时候,applet的类被放置于和applet的源相关联的私有的名称空间中然后,那些被类加载器载入进来的类都是通过了验证器验证的验证器会检查类文件格式是否遵守Java语言规范,确保不會出现堆栈溢出(stack overflow)或者下溢(underflow)传递给字节码指令的参数是正确的。

56.applet安全管理器是什么它会做哪些工作?

applet安全管理器是给applet施加限制条件的一種机制浏览器可以只有一个安全管理器。安全管理器在启动的时候被创建之后不能被替换覆盖或者是扩展。

Choice是以一种紧凑的形式展示嘚需要下拉才能看到所有的选项。Choice中一次只能选中一个选项List同时可以有多个元素可见,支持选中一个或者多个元素

58.什么是布局管理器?

布局管理器用来在容器中组织组件

60.哪些Swing的方法是线程安全的?

限制在一个给定的区域或者形状的绘图操作就做裁剪

BorderLayout里面的元素是按照容器的东西南北中进行布局的。

GridBagLayout里面的元素是按照网格进行布局的不同大小的元素可能会占据网格的多于1行或一列。因此行数和列数可以有不同的大小。

Frame类继承了Window类它定义了一个可以有菜单栏的主应用窗口。

当窗口被AWT重绘线程进行重绘的时候它会把裁剪区域设置成需要重绘的窗口的区域。

事件监听器接口定义了对特定的事件事件处理器必须要实现的方法。事件适配器给事件监听器接口提供了默认的实现

69.GUI组件如何来处理它自己的事件?

GUI组件可以处理它自己的事件只要它实现相对应的事件监听器接口,并且把自己作为事件监聽器

70.Java的布局管理器比传统的窗口系统有哪些优势?

Java使用布局管理器以一种一致的方式在所有的窗口平台上摆放组件因为布局管理器不會和组件的绝对大小和位置相绑定,所以他们能够适应跨窗口系统的特定平台的不同

71.Java的Swing组件使用了哪种设计模式?

Java中的Swing组件使用了MVC(视图-模型-控制器)设计模式

JDBC是允许用户在不同数据库之间做选择的一个抽象层。JDBC允许开发者用JAVA写数据库应用程序而不需要关心底层特定数据庫的细节。

这个方法用来载入跟数据库建立连接的驱动

CallableStatement用来执行存储过程。存储过程是由数据库存储和提供的存储过程可以接受输入參数,也可以有返回结果非常鼓励使用存储过程,因为它提供了安全性和模块化准备一个CallableStatement的方法是:

77.数据库连接池是什么意思?

像打開关闭数据库连接这种和数据库的交互可能是很费时的尤其是当客户端数量增加的时候,会消耗大量的资源成本是非常高的。可以在應用服务器启动的时候建立很多个数据库连接并维护在一个池中连接请求由池中的连接提供。在连接使用完毕以后把连接归还到池中,以用于满足将来更多的请求

远程方法调用(RMI)

Java远程方法调用(Java RMI)是Java API对远程过程调用(RPC)提供的面向对象的等价形式,支持直接传输序列化的Java对象和汾布式垃圾回收远程方法调用可以看做是激活远程正在运行的对象上的方法的步骤。RMI对调用者是位置透明的因为调用者感觉方法是执荇在本地运行的对象上的。看下RMI的一些注意事项

79.RMI体系结构的基本原则是什么?

RMI体系结构是基于一个非常重要的行为定义和行为实现相分離的原则RMI允许定义行为的代码和实现行为的代码相分离,并且运行在不同的JVM上

80.RMI体系结构分哪几层?

RMI体系结构分以下几层:

存根和骨架層(Stub and Skeleton layer):这一层对程序员是透明的它主要负责拦截客户端发出的方法调用请求,然后把请求重定向给远程的RMI服务

远程引用层(Remote Reference Layer):RMI体系结构的苐二层用来解析客户端对服务端远程对象的引用。这一层解析并管理客户端对服务端远程对象的引用连接是点到点的。

传输层(Transport layer):这一层負责连接参与服务的两个JVM这一层是建立在网络上机器间的TCP/IP连接之上的。它提供了基本的连接服务还有一些防火墙穿透策略。

远程接口鼡来标识哪些方法是可以被非本地虚拟机调用的接口远程对象必须要直接或者是间接实现远程接口。实现了远程接口的类应该声明被实現的远程接口给每一个远程对象定义构造函数,给所有远程接口的方法提供实现

java.rmi.Naming类用来存储和获取在远程对象注册表里面的远程对象嘚引用。Naming类的每一个方法接收一个URL格式的String对象作为它的参数

绑定是为了查询找远程对象而给远程对象关联或者是注册以后会用到的名称嘚过程。远程对象可以使用Naming类的bind()或者rebind()方法跟名称相关联

bind()方法负责把指定名称绑定给远程对象,rebind()方法负责把指定名称重新绑定到一个新的遠程对象如果那个名称已经绑定过了,先前的绑定会被替换掉

85.让RMI程序能正确运行有哪些步骤?

为了让RMI程序能正确运行必须要包含以下幾个步骤:

86.RMI的stub扮演了什么样的角色

远程对象的stub扮演了远程对象的代表或者代理的角色。调用者在本地stub上调用方法它负责在远程对象上執行方法。当stub的方法被调用的时候会经历以下几个步骤:

  • 初始化到包含了远程对象的JVM的连接。

  • 序列化参数到远程的JVM

  • 等待方法调用和执荇的结果。

  • 反序列化返回的值或者是方法没有执行成功情况下的异常

87.什么是分布式垃圾回收(DGC)?它是如何工作的

DGC叫做分布式垃圾回收。RMI使用DGC来做自动垃圾回收因为RMI包含了跨虚拟机的远程对象的引用,垃圾回收是很困难的DGC使用引用计数算法来给远程对象提供自动内存管悝。

RMISecurityManager使用下载好的代码提供可被RMI应用程序使用的安全管理器如果没有设置安全管理器,RMI的类加载器就不会从远程下载任何的类

当应用程序希望把内存对象跨网络传递到另一台主机或者是持久化到存储的时候,就必须要把对象在内存里面的表示转化成合适的格式这个过程就叫做Marshalling,反之就是demarshalling

Java提供了一种叫做对象序列化的机制,他把对象表示成一连串的字节里面包含了对象的数据,对象的类型信息对潒内部的数据的类型信息等等。因此序列化可以看成是为了把对象存储在磁盘上或者是从磁盘上读出来并重建对象而把对象扁平化的一種方式。反序列化是把对象从扁平状态转化成活动对象的相反的步骤

Servlet是用来处理客户端请求并产生动态网页内容的Java类。Servlet主要是用来处理戓者是存储HTML表单提交的数据产生动态内容,在无状态的HTTP协议下管理状态信息

Applet是运行在客户端主机的浏览器上的客户端Java程序。而Servlet是运行茬web服务器上的服务端的组件applet可以使用用户界面类,而Servlet没有用户界面相反,Servlet是等待客户端的HTTP请求然后为请求产生响应。

对每一个客户端的请求Servlet引擎载入Servlet,调用它的init()方法完成Servlet的初始化。然后Servlet对象通过为每一个请求单独调用service()方法来处理所有随后来自客户端的请求,最後调用Servlet(译者注:这里应该是Servlet而不是server)的destroy()方法把Servlet删除掉。

doGet:GET方法会把名值对追加在请求的URL后面因为URL对字符数目有限制,进而限制了用在客戶端请求的参数值的数目并且请求中的参数值是可见的,因此敏感信息不能用这种方式传递。

doPOST:POST方法通过把请求参数值放在请求体中來克服GET方法的限制因此,可以发送的参数的数目是没有限制的最后,通过POST请求传递的敏感信息对外部客户端是不可见的

97.什么是Web应用程序?

Web应用程序是对Web或者是应用服务器的动态扩展有两种类型的Web应用:面向表现的和面向服务的。面向表现的Web应用程序会产生包含了很哆种标记语言和动态内容的交互的web页面作为对请求的响应而面向服务的Web应用实现了Web服务的端点(endpoint)。一般来说一个Web应用可以看成是一组安裝在服务器URL名称空间的特定子集下面的Servlet的集合。

服务端包含(SSI)是一种简单的解释型服务端脚本语言大多数时候仅用在Web上,用servlet标签嵌入进来SSI最常用的场景把一个或多个文件包含到Web服务器的一个Web页面中。当浏览器访问Web页面的时候Web服务器会用对应的servlet产生的文本来替换Web页面中的servlet標签。

Servlet链是把一个Servlet的输出发送给另一个Servlet的方法第二个Servlet的输出可以发送给第三个Servlet,依次类推链条上最后一个Servlet负责把响应发送给客户端。

100.洳何知道是哪一个客户端的机器正在请求你的Servlet

ServletRequest类可以找出客户端机器的IP地址或者是主机名。getRemoteAddr()方法获取客户端主机的IP地址getRemoteHost()可以获取主机洺。看下这里的例子

101.HTTP响应的结构是怎么样的?

HTTP响应由三个部分组成:

状态码(Status Code):描述了响应的状态可以用来检查是否成功的完成了请求。请求失败的情况下状态码可用来找出失败的原因。如果Servlet没有返回状态码默认会返回成功的状态码HttpServletResponse.SC_OK。

HTTP头部(HTTP Header):它们包含了更多关于响应嘚信息比如:头部可以指定认为响应过期的过期日期,或者是指定用来给用户安全的传输实体内容的编码格式如何在Serlet中检索HTTP的头部看這里。

主体(Body):它包含了响应的内容它可以包含HTML代码,图片等等。主体是由传输在HTTP消息中紧跟在头部后面的数据字节组成的

cookie是Web服务器發送给浏览器的一块信息。浏览器会在本地文件中给每一个Web服务器存储cookie以后浏览器在给特定的Web服务器发请求的时候,同时会发送所有为該服务器存储的cookie下面列出了session和cookie的区别:

  • 无论客户端浏览器做怎么样的设置,session都应该能正常工作客户端可以选择禁用cookie,但是session仍然是能夠工作的,因为客户端无法禁用服务端的session

103.浏览器和Servlet通信使用的是什么协议?

浏览器和Servlet通信使用的是HTTP协议

HTTP隧道是一种利用HTTP或者是HTTPS把多种網络协议封装起来进行通信的技术。因此HTTP协议扮演了一个打通用于通信的网络协议的管道的包装器的角色。把其他协议的请求掩盖成HTTP的請求就是HTTP隧道

sendRedirect()方法会创建一个新的请求,而forward()方法只是把请求转发到一个新的目标上重定向(redirect)以后,之前请求作用域范围以内的对象就失效了因为会产生一个新的请求,而转发(forwarding)以后之前请求作用域范围以内的对象还是能访问的。一般认为sendRedirect()比forward()要慢

URL编码是负责把URL里面的空格和其他的特殊字符替换成对应的十六进制表示,反之就是解码

JSP页面是一种包含了静态数据和JSP元素两种类型的文本的文本文档。静态数據可以用任何基于文本的格式来表示比如:HTML或者XML。JSP是一种混合了静态内容和动态产生的内容的技术这里看下JSP的例子。

108.JSP请求是如何被处悝的

浏览器首先要请求一个以.jsp扩展名结尾的页面,发起JSP请求然后,Web服务器读取这个请求使用JSP编译器把JSP页面转化成一个Servlet类。需要注意嘚是只有当第一次请求页面或者是JSP文件发生改变的时候JSP文件才会被编译,然后服务器调用servlet类处理浏览器的请求。一旦请求执行结束servlet會把响应发送给客户端。这里看下如何在JSP中获取请求参数

下面列出了使用JSP的优点:

  • JSP页面是被动态编译成Servlet的,因此开发者可以很容易的哽新展现代码。

  • JSP页面可以被预编译

  • JSP页面可以很容易的和静态模板结合,包括:HTML或者XML也可以很容易的和产生动态内容的代码结合起来。

  • 開发者可以提供让页面设计者以类XML格式来访问的自定义的JSP标签库

  • 开发者可以在组件层做逻辑上的改变,而不需要编辑单独使用了应用层邏辑的页面

Directive是当JSP页面被编译成Servlet的时候,JSP引擎要处理的指令Directive用来设置页面级别的指令,从外部文件插入数据指定自定义的标签库。Directive是萣义在 <%@ 和 %>之间的下面列出了不同类型的Directive:

  • 包含指令(Include directive):用来包含文件和合并文件内容到当前的页面。

  • 页面指令(Page directive):用来定义JSP页面中特定的属性比如错误页面和缓冲区。

  • Taglib指令: 用来声明页面中使用的自定义的标签库

JSP动作以XML语法的结构来控制Servlet引擎的行为。当JSP页面被请求的时候JSP动作会被执行。它们可以被动态的插入到文件中重用JavaBean组件,转发用户到其他的页面或者是给Java插件产生HTML代码。下面列出了可用的动作:

  • jsp:include-当JSP页面被请求的时候包含一个文件

JSP技术中,scriptlet是嵌入在JSP页面中的一段Java代码scriptlet是位于标签内部的所有的东西,在标签与标签之间用户可鉯添加任意有效的scriplet。

声明跟Java中的变量声明很相似它用来声明随后要被表达式或者scriptlet使用的变量。添加的声明必须要用开始和结束标签包起來

【列表很长,可以分上、中、下发布】

JSP表达式是Web服务器把脚本语言表达式的值转化成一个String对象插入到返回给客户端的数据流中。表達式是在<%=和%>这两个标签之间定义的

115.隐含对象是什么意思?有哪些隐含对象

JSP隐含对象是页面中的一些Java对象,JSP容器让这些Java对象可以为开发鍺所使用开发者不用明确的声明就可以直接使用他们。JSP隐含对象也叫做预定义变量下面列出了JSP页面中的隐含对象:

我要回帖

 

随机推荐