Java 最全面的面试题675道

面试题 专栏收录该内容
3 篇文章 0 订阅

2019年Java面试675道题
    目录
java基础、语法    30
001_Java跨平台原理(字节码文件、虚拟机)    30
002_Java的安全性    31
003_Java三大版本    32
004_什么是JVM?什么是JDK? 什么是JRE?    32
005_Java三种注释类型    34
006_8种基本数据类型及其字节数    35
007_ i++和++i的异同之处    35
008_&和&&的区别和联系,|和||的区别和联系    36
009_用最有效率的方法算出2乘以8等于多少    37
010_基本数据类型的类型转换规则    37
011_if多分支语句和switch多分支语句的异同之处    38
012_while和do-while循环的区别    38
013_break和continue的作用    39
014_请使用递归算法计算n!    39
015_递归的定义和优缺点    40
016_数组的特征    40
017_请写出冒泡排序代码    41
018_请写出选择排序的代码    42
019_请写出插入排序的代码    43
020_可变参数的作用和特点    44
021_类和对象的关系    45
022_面向过程和面向对象的区别    45
023_this和super关键字的作用    47
024_static关键字的作用    47
025_final和abstract关键字的作用    48
026_final、finally、finalize的区别    49
027_写出java.lang.Object类的六个常用方法    49
028_private/默认/protected/public权限修饰符的区别    50
029_继承条件下构造方法的执行过程    51
031_谈谈Java的多态    52
032_简述Java的垃圾回收机制    52
033_基本数据类型和包装类    53
034_Integer与int的区别    54
036_使用递归算法输出某个目录下所有文件和子目录列表    56
037_关于Java编译,下面哪一个正确()(选择一项)    57
038_下列说法正确的有()(选择一项)    57
039_Java中接口的修饰符可以为()(选择一项)    58
040_给定以下代码,程序将输出 ()(选择一项)    58
041_下列关于关键字的使用说法错误的是()(选择一项)    59
042_下列哪些语句关于内存回收的说法是正确的()(选择一项)    60
043_选出合理的标识符()(选择两项)    60
044_下列说法正确的是()(选择多项)    61
045_定义一个类名为”MyClass.java”的类,并且该类可被一个工程中的所有类访问,那么该类的正确声明为()(选择两项)    61
046_面向对象的特征有哪些方面?请用生活中的例子来描述。    61
047_说明内存泄漏和内存溢出的区别和联系,结合项目经验描述Java程序中如何检测?如何解决?    63
048_什么是Java的序列化,如何实现Java的序列化?列举在哪些程序中见过Java序列化?    63
049_不通过构造函数也能创建对象吗?    64
050_匿名内部类可不可以继承或实现接口。为什么?    64
051_在Java中,为什么基本类型不能做为HashMap的键值,而只能是引用类型,把引用类型做为HashMap的健值,需要注意哪些地方。    65
052_简述Java中如何实现多态    65
053_以下对继承的描述锚误的是 ()    65
054_Java 中 Math.random()/Math.random()值为?    66
055_Java中,如果Manager是Employee的子类,那么Pair<Manager>是Pair<Employee>的子类吗?    66
056_接口和抽象类的区别    66
057_同步代码块和同步方法有什么区别    67
058_静态内部类和内部类有什么区别    68
059_反射的概念与作用    68
060_提供Java存取数据库能力的包是()    69
061_下列运算符合法的是()(多选)    70
062_执行如下程序代码,c的值打印出来是()    71
063_下列哪一种叙述是正确的()    71
064_下列语句正确的是()    72
065_下列哪种说法是正确的()    72
066_Java程序的种类有()(多选)    73
067_下列说法正确的有()(多选)    73
068_下列标识符不合法的有()(多选)    74
069_下列说法错误的有()(多选)    74
070_不能用来修饰interface的有()(多选)    75
071_下列正确的有()(多选)    75
072_下列说法错误的有()(多选)    75
073_下列说法错误的有()(多选)    76
074_下列说法错误的有()(多选)    76
075_请问0.3332的数据类型是()    77
076_Java接口的修饰符可以为()    77
077_不通过构造函数也能创建对象么()    77
078_存在使i+1<i的数么?    78
079_接口可否继承接口?抽象类是否可实现接口?抽象类是否可继承实体类?    78
080_int与Integer有什么区别?    78
081_可序列化对象为什么要定义serialversionUID值?    79
082_写一个Java正则,能过滤出html中的<a href=”url”>titl</a>形式中的链接地址和标题.    79
083_十进制数72转换成八进制数是多少?    80
084_Java程序中创建新的类对象,使用关键字new,回收无用的类对象使用关键字free正确么?    80
085_Class类的getDeclaredFields()方法与getFields()的区别?    80
086_在switch和if-else语句之间进行选取,当控制选择的条件不仅仅依赖于一个x时,应该使用switch结构;正确么?    80
087_描述&和&&的区别。    82
088_使用final关键字修饰符一个变量时,是引用不能变,还是引用的对象不能变?    83
089_请解释以下常用正则含义:\d,\D,\s,.,*,?,|,[0-9]{6},\d+    83
090_已知表达式int m[] = {0,1,2,3,4,5,6}; 下面那个表达式的值与数组的长度相等()    84
091_下面那些声明是合法的?()    84
092_以下选项中选择正确的java表达式()    84
093_下列代码的输出结果是    85
094_以下哪些运算符是含有短路运算机制的?请选择:()    85
095_下面哪个函数是public void example(){....}的重载函数?()    85
096_给定某java程序片段,该程序运行后,j的输出结果为()    85
097_在java中,无论测试条件是什么,下列()循环将至少执行一次。    86
098_打印结果:    86
099_指出下列程序的运行结果    87
100_解释继承、重载、覆盖。    88
101_什么是编译型语言,什么是解释型语言?java可以归类到那种?    89
102_简述操作符(&,|)与操作符(&&,||)的区别    90
103_try{}里面有一个return语句,那么紧跟在这个try后的finally, 里面的语句在异常出现后,都会执行么?为什么?    91
104_有一段java应用程序,它的主类名是al,那么保存它的源文件可以是?()    91
105_Java类可以作为()    92
106_在调用方法时,若要使方法改变实参的值,可以?()    92
107_Java语言具有许多优点和特点,哪个反映了java程序并行机制的()    92
108_下关于构造函数的描述错误是()    93
110_下面代码执行后的输出是什么()    93
111_给出如下代码,如何使成员变量m被函数fun()直接访问()    94
112_下面哪几个函数是public void example(){….}的重载函数()    94
113_请问以下代码执行会打印出什么?    95
114_如果有两个类A、B(注意不是接口),你想同时使用这两个类的功能,那么你会如何编写这个C类呢?    96
115_一个类的构造方法是否可以被重载(overloading),是否可以被子类重写(overrding)?    96
116_Java中byte表示的数值范围是什么?    96
118_不通过构造函数也能创建对象吗()    97
119_下面哪些是对称加密算法()    98
120_下面的代码段,当输入为2的时候返回值是()    98
121_以下Java代码段会产生几个对象    99
122_Math.round(-11.2)的运行结果是。    99
123_十进制数278的对应十六进制数    100
124_Java中int.long占用的字节数分别是    100
125_System.out.println(‘a’+1);的结果是    100
126_下列语句那一个正确()    101
127_下列说法正确的有()    101
128_执行如下程序代码()    101
129_下列哪一种叙述是正确的()    102
130_下列语句正确的是()    102
131_成员变量用static修饰和不用static修饰有什么区别?    103
132_如果变量用final修饰,则怎样?如果方法final修饰,则怎样?    103
133_在二进制数据中,小数点向右移一位,则数据()    104
134_面向对象的特征有哪些方面?    105
135_float f=3.4;是否正确?    106
136_short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?    106
137_Java 有没有goto?    106
138_int 和Integer 有什么区别?    107
139_&和&&的区别?    110
140_Math.round(11.5) 等于多少? Math.round(-11.5)等于多少?    111
141_swtich 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?    111
142_用最有效率的方法计算2乘以8?    111
143_在Java 中,如何跳出当前的多重嵌套循环?    113
144_构造器(constructor)是否可被重写(override)?    113
145_两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?    113
146_当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?    114
147_重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?    115
148_华为的面试题中曾经问过这样一个问题:为什么不能根据返回类型来区分重载,为什么?    115
149_静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?    116
150_抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?    122
151_静态变量和实例变量的区别?    122
152_是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?    123
153_如何实现对象克隆?    123
154_接口是否可继承(extends)接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)?    127
155_一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制?    127
156_Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?    127
157_内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?    127
158_Java 中的final关键字有哪些用法?    128
159_指出下面程序的运行结果:    128
160_说说数据类型之间的转换:    129
161_如何实现字符串的反转及替换?    130
162_怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?    130
163_Java中的日期和时间:    130
164_打印昨天的当前时刻。    131
165_Java反射技术主要实现类有哪些,作用分别是什么?    131
166_Class类的作用?生成Class对象的方法有哪些?    132
167_反射的使用场合和作用、及其优缺点    133
168_面向对象设计原则有哪些    133
Spring相关的    134
169_下面程序的运行结果是()(选择一项)    134
170_Java语言中,String类中的indexOf()方法返回值的类型是()    135
171_给定以下代码,程序的运行结果是 ()(选择一项)    135
172_执行下列代码后,哪个结论是正确的()(选择两项)    136
173_实现String类的replaceAll方法    136
174_在“=”后填写适当的内容:    137
175_是否可以继承String类?    138
176_给定两个字符串s和t,  写一个函数来决定是否t是s的重组词。你可以假设字符串只包含小写字母。    138
177_String s=new String(“abc”);创建了几个String对象。    139
178_输出结果?    139
179_下列程序的输出结果是什么?    139
180_关于java.lang.String类,以下描述正确的一项是()    140
181_下面哪个是正确的()    140
182_已知如下代码:执行结果是什么()    141
183_字符串如何转换为int类型    142
184_写一个方法,实现字符串的反转,如:输入abc,输出cba    142
185_编写java,将“I follow Bill Gate.Tom Gate.John Gate”中的“Gate”全部替换为“Gates”    143
186_String 是最基本的数据类型吗?    143
187_String 和StringBuilder、StringBuffer 的区别?    143
188_String类为什么是final的    145
189_String类型是基本数据类型吗?基本数据类型有哪些    146
191_String s = new String("xyz");创建几个String Object?    148
192_下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d";    148
集合    149
193_Java集合体系结构(List、Set、Collection、Map的区别和联系)    149
194_Vector和ArrayList的区别和联系    150
195_ArrayList和LinkedList的区别和联系    150
196_HashMap和Hashtable的区别和联系    151
197_HashSet的使用和原理(hashCode()和equals())    151
198_TreeSet的原理和使用(Comparable和comparator)    152
199_集合和数组的比较(为什么引入集合)    152
200_Collection和Collections的区别    153
201_下列说法正确的有()(选择一项)    153
202_Java的HashMap和Hashtable有什么区别HashSet和HashMap有什么区别?使用这些结构保存的数需要重载的方法是哪些?    153
203_列出Java中的集合类层次结构?    154
204_List,Set,Map各有什么特点    155
205_ArrayList list=new ArrayList(20);中的list扩充几次()    155
206_List、Set、Map哪个继承自Collection接口,一下说法正确的是()    155
207_合并两个有序的链表    155
208_用递归方式实现链表的转置。    157
209_给定一个不包含相同元素的整数集合,nums,返回所有可能的子集集合。解答中集合不能包含重复的子集。    157
210_以下结构中,哪个具有同步功能()    158
211_以下结构中,插入性能最高的是()    159
212_以下结构中,哪个最适合当作stack使用()    159
213_Map的实现类中,哪些是有序的,哪些是无序的,有序的是如何保证其有序性,你觉得哪个有序性性能更高,你有没有更好或者更高效的实现方式?    160
214_下面的代码在绝大部分时间内都运行得很正常,请问什么情况下会出现问题?根源在哪里?    160
215_TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?    161
216_List里面如何剔除相同的对象?请简单用代码实现一种方法    162
217_Java.util.Map的实现类有    162
218_下列叙述中正确的是()    163
219_List、Set、Map 是否继承自Collection 接口?    163
220_说出ArrayList、Vector、LinkedList 的存储性能和特性?    163
221_List、Map、Set 三个接口,存取元素时,各有什么特点?    164
222_TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?    165
多线程    170
223_下面程序的运行结果()(选择一项)    170
224_下列哪个方法可用于创建一个可运行的类()    171
225_说明类java.lang.ThreadLocal的作用和原理。列举在哪些程序中见过ThreadLocal的使用?    171
226_说说乐观锁与悲观锁    171
227_在Java中怎么实现多线程?描述线程状态的变化过程。    172
228_请写出多线程代码使用Thread或者Runnable,并说出两种的区别。    173
229_在多线程编程里,wait方法的调用方式是怎样的?    174
230_Java线程的几种状态    174
231_在Java多线程中,请用下面哪种方式不会使线程进入阻塞状态()    175
232_volatile关键字是否能保证线程安全?    176
233_请写出常用的Java多线程启动方式,Executors线程池有几种常用类型?    177
234_关于sleep()和wait(),以下描述错误的一项是()    178
235_进程和线程的区别是什么?    178
236_以下锁机机制中,不能保证线程安全的是()    179
237_创建n多个线程,如何保证这些线程同时启动?看清,是“同时”。    179
238_同步和异步有何异同,在什么情况下分别使用它们?    182
239_Java线程中,sleep()和wait()区别    182
240_下面所述步骤中,是创建进程做必须的步骤是()    182
241_无锁化编程有哪些常见方法?()    183
242_sleep()和yield()有什么区别?    183
243_当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法?    184
244_请说出与线程同步相关的方法。    184
245_编写多线程程序有几种实现方式?    192
246_synchronized关键字的用法?    194
247_启动一个线程是用run()还是start()方法?    194
248_什么是线程池(thread pool)?    194
249_线程的基本状态以及状态之间的关系?    195
251_创建线程的两种方式分别是什么,优缺点是什么?    196
252_Java创建线程后,调用start()方法和run()的区别    198
253_线程的生命周期    199
254_如何实现线程同步?    200
255_说说关于同步锁的更多细节    200
256_Java中实现线程通信的三个方法的作用是什么?    202
IO流    202
257_下面哪个流类属于面向字符的输入流()(选择一项)    202
258_要从文件”file.dat”文件中读出第10个字节到变量c中,下列哪个正确()(选择一项)    203
259_新建一个流对象,下面那个选项的代码是错误的?()    203
260_下面哪个流是面向字符的输入流()    204
261_Java类库中,将信息写入内存的类是()    204
262_请写出一段代码,能够完成将字符串写入文件    204
263_下面哪个流类属于面向字符的输入流()    205
264_Java中如何实现序列化,有什么意义?    206
265_Java 中有几种类型的流?    206
266_ 写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。    208
267_输入流和输出流联系和区别,节点流和处理流联系和区别    210
268_字符流字节流联系区别;什么时候使用字节流和字符流?    210
269_列举常用字节输入流和输出流并说明其特点,至少5对。    211
270_说明缓冲流的优点和原理    212
271_序列化的定义、实现和注意事项    212
272_使用IO流完成文件夹复制    213
273_说说BIO、NIO和AIO的区别    216
网络编程    217
274_IP地址和端口号    217
275_介绍OSI七层模型和TCP/IP模型    219
276_TCP协议和UDP协议的比较    220
277_什么是Socket编程    221
278_简述基于TCP和UDP的Socket编程的主要步骤    222
异常处理    224
279_下列哪种异常是检查型异常,需要在编写程序时声明()    224
280_Java出现OutOf MemoryError(OOM 错误)的原因有哪些?出现OOM错误后,怎么解决?    224
281_列举常见的运行时异常    226
282_下面关于 Java.lang.Exception类的说法正确的是()    227
283_Unsupported major.minor version 52是什么异常,怎么造成的,如何解决?    227
284_try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?    227
285_Java 语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?    229
286_运行时异常与受检异常有何异同?    230
287_类ExampleA 继承Exception,类ExampleB 继承ExampleA    230
288_Error和Exception的区别    232
289_Java异常处理try-catch-finally的执行过程    233
290_异常处理中throws和throw的区别    233
WEB相关    234
291_WEB应用中如果有.class和.jar类型的文件一般分别应该放在什么位置?    234
292_元素中有一个输入框(<input type=”text” name=”username”id=”username”value=””/>,请用JavaScript语言写一行代码,取得这个输入框中的值。    234
293_简单描述一下Servlet与JSP的的相同点和区别点。    234
294_请简单描述下几个您熟悉JavaScript库,它们有哪些作用和特点?    235
295_简单描述HTML,CSS,Javascript在Web开发中分别起什么作用?    235
296_当DOM加载完成后要执行的函数,下面哪个是正确的()    236
297_举例说明JAVA中如何解析xml,不同方式有和优缺点?    236
299_一个类可以实现多个接口,但只能继承一个抽象类。    241
300_比较一下Java 和JavaSciprt    243
301_什么时候用assert?    244
302_UML是什么?UML中有哪些图?    245
303_XML 文档定义有几种形式?它们之间有何本质区别?解析XML 文档有哪几种方式?    247
304_你在项目中哪些地方用到了XML?    248
305_用JavaScript实现用正则表达式验证,某个字符串是合法的6位数字的邮编的函数    248
306_请使用JQuery将页面上的所有元素边框设置为2pix宽的虚线?    248
307_如何设定JQuery异步调用还是同步调用?    248
308_说出3条以上firefox和IE的浏览器兼容问题?    249
309_请用Jquery语言写出ajax请求或者post请求代码    249
310_body中的onload()函数和jQuery中document.ready()有什么区别?    249
311_jQuery中有哪几种类型的选择器?    249
312_EasyUI中datagrid刷新当前数据的方法?    250
313_分别写出一个div居中和其中的内容居中的css属性设置    250
314_概述一下session与cookie的区别    250
315_JavaScript 中 null和 undefined 是否有区别?有哪些区别?    251
316_Servlet中的doPost和doGet方法有什么区别?它们在传递和获取参数上有什么区别?    251
317_请写出一段jQuery代码,实现把当前页面中所有的a元索中class 属性为“view-link”的链接都改为在新窗口中打开    251
318_如下JavaScript代码的输出为:    251
319_Jquery中’.get()’与’.eq()’的区别    252
320_如何给weblogic定内存的大小?    252
321_TCP为何采用三次握手来建立连接,若釆用二次握手可以吗,请说明理由?    252
322_以下HTTP相应状态码的含义描述正确的是()    252
323_JSP页面包括哪些元素?()    253
324_Ajax有四种技术组成:DOM,CSS,JavaScript,XmlHttpRequest,其中控制文档结构的是()    253
325_下面关于session的用法哪些是错误的?()    254
326_Jsp九大内置对象    254
327_如何配置一个servlet?    256
328_JavaScript,如何定义含有数值1至8的数组?    256
329_以下JavaScipt语句会产生运行错误的是_()    257
330_在JSP中,下面__()__块中可以定义一个新类:    257
331_HTML含义和版本变化    257
332_什么是锚链接    258
333_HTML字符实体的作用及其常用字符实体    258
334_HTML表单的作用和常用表单项类型    259
335_表格、框架、div三种HTML布局方式的特点    260
336_form中input设置为readonly和disabled的区别    260
337_CSS的定义和作用    260
338_CSS2常用选择器类型及其含义    262
339_引入样式的三种方式及其优先级别    263
340_盒子模型    263
341_JavaScript语言及其特点    265
342_JavaScript常用数据类型有哪些    265
343_html语法中哪条命令用于使一行文本折行,而不是插入一个新的段落?    266
344_Ajax的优点和缺点    266
345_怎样防止表单刷新重复提交问题?(说出思路即可)    267
345_怎样防止表单刷新重复提交问题?(说出思路即可)    267
346_JQuery.get()和JQuery.ajax()方法之间的区别是什么?    268
347_Jquery里的缓存问题如何解决?例如($.ajax()以及$.get())    268
348_Javascript是面向对象的,怎么体现Javascript的继承关系?    269
349_Javascript的有几种种变量。变量范围有什么不同?    269
350_Js如何获取页面的dom对象    269
351_Servlet API中forward() 与redirect()的区别?    270
352_Session域和request域什么区别?    270
353_页面中有一个命名为bankNo的下拉列表,写js脚本获取当前选项的索引值,如果用jquery如何获取    271
354_写出要求11位数字的正则表达式    271
355_分别获取指定name、Id的javascript对象,如果用jquey如何获取    271
356_一个页面有两个form,如何获取第一个form    272
357_如何设置一个层的可见/隐藏    272
358_描述JSP中动态INCLUDE与静态INCLUDE的区别?    272
359_列举JSP的内置对象及方法    272
360_列举jsp的四大作用域    273
361_html和xhtml的区别是什么?    273
362_你做的页面用哪些浏览器测试过?这些测试的内核分别是什么?    275
363_你遇到了哪些浏览器的兼容性问题?怎么解决的?    276
364_你知道的常用的js库有哪些?    276
365_Js中的三种弹出式消息提醒(警告窗口、确认窗口、信息输入窗口)的命令是什么?    277
367_写一段js,遍历所有的li,将每个li的内容逐个alert出来    277
368_页面上如何用JavaScript对多个checkbox全选    278
369_写一个简单的JQuery的ajax    279
370_J s截取字符串abcdefg的efg    280
371_http的请求头信息包含了什么?    280
372_http的响应码200,404,302,500表示的含义分别是?    281
373_Servlet中request对象的方法有?    281
374_JavaScript中获取某个元素的三种方式JavaScript中的三种弹出式消息提醒命令是什么?    283
377_JavaScript操作CSS的两种方式    283
378_静态网页和动态网页的联系和区别    284
379_JSP/ASP/PHP的比较    285
380_CGI/Servlet/JSP的比较    287
381_HTTP协议工作原理及其特点    288
382_get和post的区别    289
384_绝对路径、根路径、相对路径的含义及其区别    290
385_如实现servlet的单线程模式    291
386_Servlet的生命周期    292
387_转发和重定向的区别    292
388_JSP的执行过程    294
389_JSP动作有哪些,简述作用?    294
390_page/request/session/application作用域区别    295
391_JSP和Servlet的区别和联系    295
392_谈谈过滤器原理及其作用?    296
393_jQuery相比JavaScript的优势在哪里    297
394_DOM对象和jQuery对象的区别及其转换    298
395_jQuery中$的作用主要有哪些    298
396_Ajax含义及其主要技术    299
397_Ajax的工作原理    299
398_JSON及其作用    300
399_文件上传组件Common-fileUpload的常用类及其作用?    301
400_说出Servlet的生命周期,并说出Servlet和CGI的区别?    301
401_JSP 和Servlet 有有什么关系?    302
402_JSP中的四种作用域?    303
403_如何实现JSP或Servlet的单线程模式?    303
404_实现会话跟踪的技术有哪些?    303
405_过滤器有哪些作用和用法?    305
406_监听器有哪些作用和用法?    305
407_你的项目中使用过哪些JSTL标签?    306
408_使用标签库有什么好处?如何自定义JSP标签?    306
409_表达式语言(EL)的隐式对象及其作用?    312
410_表达式语言(EL)支持哪些运算符?    312
411_Servlet 3中的异步处理指的是什么?    313
413_简述值栈(Value-Stack)的原理和生命周期    314
414_阐述Session加载实体对象的过程。    314
415_怎么防止重复提交    315
417_写出输出结果    315
418_web项目从浏览器发起交易响应缓慢,请简述从哪些方面如数分析    316
设计模式    316
419_请写出您熟悉的几种设计模式,并做简单介绍。    316
420_写出你用过的设计模式,并至少写出2种模式的类图或关键代码。    317
421_列出除Singleton外的常用的3种设计模式,并简单描述    319
422_Action是单实例还是多实例,为什么?    320
423_写一个单例类    321
424_说说你所熟悉或听说过的设计模式以及你对设计模式的看法    322
425_Java企业级开发中常用的设计模式有哪些?    326
426_你在开发中都用到了那些设计模式?用在什么场合?    328
427_什么是设计模式,设计模式的作用。    329
428_23种经典设计模式都有哪些,如何分类。    329
429_写出简单工厂模式的示例代码    330
430_请对你所熟悉的一个设计模式进行介绍    331
高级框架    334
431_什么是Maven?    334
432_Maven和ANT的区别    335
433_Maven仓库是什么    335
435_Maven常用命令有哪些?    336
436_ ZooKeeper的作用是什么?    336
437_什么是Znode?    338
438_Znode节点类型有哪些?    339
439_什么是Dubbo?    339
440_什么是RPC远程过程调用?    340
441_Dubbo中有哪些角色?    340
442_Dubbo执行流程什么是?    342
443_说说Dubbo支持的协议有哪些?    343
444_Dubbo支持的注册中心有哪些?    343
445_SessionFactory是线程安全的吗?Session是线程安全的吗,两个线程能够共享同一个Session吗?    344
446_Session的load和get方法的区别是什么?    344
447_Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法有什么区别?    345
448_什么是VSFTPD?    346
449_什么是Nginx?    346
450_Nginx有哪些作用?    346
451_什么是正向代理?    346
453_什么是Redis?    347
454_Redis的特点什么是?    347
455_Redis数据类型有哪些?    347
456_Redis中的常用命令哪些?    348
457_Redis的配置以及持久化方案有几种?    350
458_什么是RDB方式?    350
459_什么是AOF方式?    351
462_什么是Solr?    352
463_Solr是由哪两个部分构成?    353
464_什么是正排索引?    353
465_什么是倒排索引?    353
466_什么是ActiveMQ?    354
467_消息服务的应用场景有哪些?    354
468_什么是JMS?    355
469_JMS有哪些模型?    355
470_什么是JsonP?    355
471_什么是跨域?    355
472_什么是同源策略?    356
473_什么是MyCat?    356
474_什么是纵向切分/垂直切分?    356
475_简述Tomcat,Apache,JBoss和WebLogic的区别和联系    357
476_以下可以实现负载均衡的是()    358
477_Tomcat/ WebSphere/WebLogic的作用和特点    358
478_B/S和C/S的含义及其区别    359
479_说说你对容器的理解    360
480_为什么要使用连接池?    360
481_数据库连接池的原理。    361
482_MVC模式及其优缺点    362
483_MVC模式完成分页功能的基本思路是什么?    363
484_常用的Web容器    364
485_Java Web开发的Model 1和Model 2分别指的是什么?    366
486_说说什么是框架:    366
487_简单说一下MVC框架?    367
488_简单讲一下struts2的执行流程    368
489_Struts2中的拦截器,你都用它干什么?    368
490_简单讲一下SpringMVC的执行流程?    369
491_简单说一下struts2和springMVC有什么不同    370
492_说一下Spring中的两大核心    371
493_讲一下Spring的事务的传播特性    372
494_什么是ORM    373
495_Hibernate对象的状态    374
496_介绍一下Hibernate的缓存    374
497_简单讲一下webservice使用的场景    376
498_简单介绍一下activity?    376
499_什么是MyBatis?    376
501_MyBatis与Hibernate有哪些不同?    377
502_简述Mybatis的Xml映射文件和Mybatis内部数据结构之间的映射关系?    377
503_什么是MyBatis的接口绑定,有什么好处?    378
504_Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别?    378
505_MyBatis里面的动态Sql是怎么设定的?用什么语法?    378
506_使用MyBatis的mapper接口调用时有哪些要求?    378
507_Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?    379
508_MyBatis接口绑定有几种实现方式,分别是怎么实现的?    379
509_MyBatis实现一对一有几种方式?具体怎么操作的?    379
510_什么情况下用注解绑定,什么情况下用xml绑定?    380
511_MyBatis的好处是什么?    380
微服务框架:    380
512_Spring Boot有哪些优点?    380
513_如何重新加载Spring Boot上的更改,而无需重新启动服务器?    381
514_常见的系统架构风格有哪些?各有什么优缺点?    381
515_什么是AKF拆分原则?    385
516_什么是Spring Cloud?    385
517_Spring Cloud与Dubbo的区别是什么?    386
518_什么是Eureka注册中心?    386
519_简单谈一下Eureka中的三种角色分别是什么?    386
520_什么是Ribbon    387
521_集中式与进程内负载均衡的区别    387
522_Ribbon的常见负载均衡策略有哪些?    388
523_简单说说什么是Feign?    388
524_什么是声明式,有什么作用,解决什么问题?    388
525_什么是服务的灾难性的雪崩效应?    389
526_如何解决灾难性雪崩效应?    389
527_线程池隔离和信号量隔离的区别    390
528_请回答微服务架构的六种常用设计模式是什么?    390
529_什么是网关服务?    391
530_网关服务中,路由器的4种路由规则方法是什么?    391
531_为什么要使用spring cloud config 配置中心?它解决了什么问题?    391
532_什么是Spring Cloud Bus    392
533_消息驱动Stream解决了什么问题?    392
534_为什么要使用微服务跟踪?它解决了什么问题?    393
535_什么是ELK(ElasticSearch, Logstash, Kibana)    393
537_什么是分布式跟踪 : Zipki?    394
数据库:    394
538_下列属于关系型数据库的是()(选择两项)    394
539_请列出Java常见的开源数据连接池,并对参数做出简单的说明    395
540_储蓄所有多个储户,储户在多个储户所存取款,储蓄所与储户之间是()    395
541_视图是一个“虚表”,视图的构造基于()    396
542_设有关系R(A,B,C,D)及其上的函数相关性集合F={B→A,BC→D},那么关系R最高是()    397
543_什么是DAO模式?    397
544_数据库MySQL,Oracle,SqlServer分页时用的语句    398
545_Oracle完成分页功能的三层子查询语句及其含义?    398
546_问SQL怎么优化执行效率更高    399
547_谈谈数据库去空格的情况    400
548_根据你以往的经验简单叙述一下MYSQL的优化    401
549_以Oracle11R为例简述数据库集群部署    402
550_说一下数据库的存储过程?    403
551_数据库创建索引的缺点?    403
552_有两张表;请用SQL查询,所有的客户订单日期最新的前五条订单记录。(分别注明MySQL. Oracle写法)    404
553_关于HQL与SQL,以下哪些说法正确?()    404
554_下面是学生表(student)的结构说明    405
555_为管理岗位业务培训信息,有如下3个表:    408
556_用Java怎么实现有每天有1亿条记录的DB储存?MySQL上亿记录数据量的数据库如何设计?    409
557_Mysql的引擎有哪些?支持事物么?DB储存引擎有哪些?    410
558_以下是学生考试结果表    412
559_库中已经存在雇用表表名:    413
560_如下表1中的数据,表名为:t_test,记录某场比赛的结果。    413
561_请将如下数据库语句进行优化,使其执行效率更高(提示:…不需要更改)    415
562_请简述如何将Oracle中的数据库转至DB2中,需要保证表结构和数据不变    415
563_学生成绩表    416
564_Oracl数据库中有两张表Stu(学生表)和Grade(分数表),如下图所示:    416
567_下列两个表,需要用一条sql语句把b表中的ID和NAME 字段的数值复制到A表中    420
568_什么是基本表,什么是视图,两者的区别和联系是什么?    420
569_什么是事务?什么是锁?    421
570_Student学生表(学号,姓名、性别、年龄、组织部门),Course 课程表(编号,课程名称),Sc选课表(学号,课程编号,成绩)    422
571_sql查询    422
JVM:    424
572_简述Java内存管理机制,以及垃圾回收的原理和使用过Java调优工具    424
573_描述JVM加载class文件的原理机制    424
574_说说JVM原理?内存泄漏与溢出的区别?何时产生内存泄漏?    425
576_Java的类加载器都有哪些,每个类加载器都有加载那些类,什么是双亲委派模型,是做什么的?    427
577_垃圾回收器(GC)的基本原理是什么?垃圾回收器可以马上回收内存吗?如何通知虚拟机进行垃圾回收?    429
578_Java 中会存在内存泄漏吗,请简单描述。    429
579_GC 是什么?为什么要有GC?    431
580_请写出常用的linux指令不低于10个,请写出linux tomcat启动。    432
Linux操作:    433
581_当使用RMI技术实现远程方法调用时,能为远程对象生成Sub和Skeleton命令的是()    433
583_下面的网络协议中,面向连接的的协议是: ()    435
584_在/etc/fstab 文件中指定的文件系统加载参数中, () 参数一般用于CD-ROM 等移动设备    435
585_Linux 文件权限一共10 位长度,分成四段,第三段表示的内容是 ()    436
586_终止一个前台进程可能用到的命令和操作 ()    436
587_在使用mkdir 命令创建新的目录时,在其父目录不存在时先创建父目录的选项是 ()    437
588_下面关于i 节点描述错误的是 ()    437
589_一个文件名字为rr.Z,可以用来解压缩的命令是: ()    438
590_具有很多C 语言的功能,又称过滤器的是 ()    438
591_一台主机要实现通过局域网与另一个局域网通信,需要做的工作是 ()    439
592_建立动态路由需要用到的文件有 ()    439
593_局域网的网络地址192.168.1.0/24,局域网络连接其它网络的网关地址是192.168.1.1。主机192.168.1.20 访问172.16.1.0/24 网络时,其路由设置正确的是 ()    440
594_下列提法中,不属于ifconfig 命令作用范围的是 ()    440
595_下列关于链接描述,错误的是()    441
596_在局域网络内的某台主机用ping 命令测试网络连接时发现网络内部的主机都可以连同,而不能与公网连通,问题可能是()    441
597_下列文件中,包含了主机名到IP 地址的映射关系的文件是:    442
598_不需要编译内核的情况是()    442
599_在shell 中变量的赋值有四种方法,其中,采用name=12 的方法称 ()    443
600_()命令可以从文本文件的每一行中截取指定内容的数据.    443
601_下列不是Linux 系统进程类型的是()    444
602_在日常管理中,通常CPU 会影响系统性能的情况是: ()    444
603_若一台计算机的内存为128MB,则交换分区的大小通常是    445
604_在安装Linux 的过程中的第五步是让用户选择安装方式,如果用户希望安装部分组件(软件程序),并在选择好后让系统自动安装,应该选择的选项是()    445
605_Linux 有三个查看文件的命令,若希望在查看文件内容过程中可以用光标上下移动来查看文件内容,应使用()命令    446
606_下列信息是某系统用ps –ef 命令列出的正在运行的进程 ()进程是运行Internet 超级服务器,它负责监听Internet sockets 上的连接,并调用合适的服务器来处理接收的信息。    446
607_在TCP/IP 模型中,应用层包含了所有的高层协议,在下列的一些应用协议中, ()是能够实现本地与远程主机之间的文件传输工作    447
608_当我们与某远程网络连接不上时,就需要跟踪路由查看,以便了解在网络的什么位置出现了问题,满足该目的的命令是()    447
609_对名为fido 的文件用chmod 551 fido 进行了修改,则它的许可权是()    448
610_用ls –al 命令列出下面的文件列表,()文件是符号连接文件    448
611_DNS 域名系统主要负责主机名和()之间的解析。    449
612_WWW 服务器是在Internet 上使用最为广泛,它采用的是()结构    449
613_Linux 系统通过()命令给其他用户发消息    450
614_NFS 是()系统。    450
615_()命令可以在Linux 的安全系统中完成文件向磁带备份的工作    451
616_Linux 文件系统的文件都按其作用分门别类地放在相关的目录中,对于外部设备文件,一般应将其放在()目录中    451
617_在重新启动Linux 系统的同时把内存中的信息写入硬盘,应使用()命令实现    452
618_网络管理具备以下几大功能:配置管理、()、性能管理、安全管理和计费管理等    452
619_关闭linux 系统(不重新启动)可使用命令()    453
620_实现从IP 地址到以太网MAC 地址转换的命令为: ()    453
621_在vi 编辑器中的命令模式下,键入()可在光标当前所在行下添加一新行    454
622_在vi 编辑器中的命令模式下,删除当前光标处的字符使用()命令    454
623_在vi 编辑器中的命令模式下,重复上一次对编辑的文本进行的操作,可使用()命令    455
624_删除文件命令为: ()    455
625_退出交互模式的shell,应键入()    456
算法分析及手写代码:    456
626_判断身份证:要么是15位,要么是18位,最后一位可以为字母,并写出程序提出其中年月日。要求:    456
627_对于一个字符串,请设计一个高效算法,找到第一次重复出现的字符保证字符串中有重复的字符,字符串的长度小于等于500.    458
628_写一个完整函数,实现拷贝数组    459
629_写一排序算法,输入10个数字,以逗号分开,可根据参数选择升序或者降序排序,须注明是何种排序算法。    460
630_判断字符串是否是这样的组成的,第一个字母,后面可以是字母、数字、下划线、总长度为5-20。    463
631_已排好序的数组A,一般来说可用二分查找可以很快找到,现有一特殊数组A,它是循环递增的,如a[]={17, 19 ,20, 25, 1, 4, 7, 9},在这样的数组中找一元素,看看是否存在。请写出你的算法,必要时可写伪代码,并分析其空间,时间复杂度。    464
632_请编写一个完整的程序,实现如下功能:从键盘输入数字n,程序自动计算n!并输出。(注1:n!=1*2*3...*n, 注2:请使用递归实现)    466
633_请用递归的方法计算斐波那契数列的同项F(n),已知F0=0,F1=1,F(n)=F(n-1)+F(n-2)(n>=2,n∈N*).    467
634_现在有整数数组{11,66,22,0,55,32},请任意选择一种排序算法,用Java程序实现    468
635_请根据注释,编码实现下面类的方法    470
636_二分法查询(递归实现)    472
637_编写一段Java程序,把一句英语中的每个单词中的字母次序倒转,单词次序保持不变,例入输入为“There is a dog.”,输出结果应该是“erehT si a god.”要求不使用Java的库函数,例如String类的split,reverse方法。    473
638_手写9x9乘法表,冒泡排序    475
639_ 题目: 给定一个整数数组,找到是否该数组包含任何重复数字。你的函数应该返回true只要有任何数字 在该数组中重复出现,否则返回false。    477
640_给定一个数组nums, 写一个函数来移动所有0元素到数组末尾,同时维持数组中非0元素的相对顺序不变。要求不能申请额外的内存空间,并且最小化操作次数。    477
641_给定一颗二叉树,返回节点值得先序遍历,请使用迭代(非递归)方式实现。    479
642_验证一棵树是否为有效的二叉搜索树BST    480
643_从一个链表中删除节点    481
644_二叉搜索树BST中第Kth小的元素 题目:给定⼀个BST,写一个函数kthSmallest来找到第kth小的元素    482
645_题目:给定含有n个整数的数组S,S中是否存在三个元素a,b,c使得a + b + c = 0? 找到所有这样的三元 组,并且结果集中不包含重复的三元组。    484
646_子集问题    489
647_迭代方法实现二叉树的先序遍历:题目: 给定一颗⼆叉树,返回节点值得先序遍历,请使用迭代(非递归)方式实现。    491
648_验证二叉搜索树BST:题目: 验证一棵树是否为有效的二叉搜索树BST比如,二叉树[2, 1, 3],返回true二叉树[1, 2, 3], 返回false    493
649_编辑距离题目: 给定两个单词word1和word2,找到最小的操作步骤使得word1转换成word2,每次操作算作一 步。你可以对单词进行以下三种操作:1)插入一个字符2)删除一个字符3)替换一个字符    494
650_买卖股票问题:题目: 你有一个数组,第i个元素表示第i天某个股票的价格,设计一个算法找到最大的利润,并且你只能最多完成两次交易。    498
651_[编程]任给n个整数和一个整数x。请计算n个整数中有多少对整数之和等于x。    499
652_[编程]请说明快速排序算法的设计思想和时间复杂度,并用高级语言写出对整数数组进行一趟快排的函数实现。    501
653_对于一段形如:1,-1~3,1~15×3的输入    503
654_有两个字符串:目标串S=“s1s2.......sn”,模式串T="t1t2.......tm"。若存在T的每个字符一次和S中的一个连续字符序列相等,则匹配成功,返回T中第一个字符在S中的位置。否则匹配不成功,返回0。写出你的算法,要求线性时间复杂度    506
655_如何生成一个0-100的随机整数?    508
656_请编写一段Java程序将两个有序数组合并成一个有序数组    508
657_在最佳情况下,以下哪个时间复杂度最高(D)    510
658_一个数组,元素为从0到m的整数,判断其中是否有重复元素,使用java语言编写一个方法    510
659_某二叉树的先序遍历是12453,中序遍历是42513,那么其后序遍历是(A)    511
660_设一颗二叉树中有3个叶子节点,有八个度为1的节点,则该二叉树中总的节点数为()    511
661_给出下面的二叉树先序、中序、后序遍历的序列?    512
662_你知道的排序算法都哪些?用Java写一个排序系统    513
663_写一个二分查找(折半搜索)的算法。    525
663_写一个二分查找(折半搜索)的算法。    525
664_一篇英文文章单词个数。    526
665_输入年月日,计算该日期是这一年的第几天    527
666_回文素数:所谓回文数就是顺着读和倒着读一样的数(例如:11,121,1991…),回文素数就是既是回文数又是素数(只能被1和自身整除的数)的数。编程找出11~9999之间的回文素数    528
667_全排列:给出五个数字12345的所有排列。    530
668_对于一个有N个整数元素的一维数组,找出它的子数组(数组中下标连续的元素组成的数组)之和的最大值。    531
669_用递归实现字符串倒转    533
670_输入一个正整数,将其分解为素数的乘积    534
671_一个有n级的台阶,一次可以走1级、2级或3级,问走完n级台阶有多少种走法。    536
672_写一个算法判断一个英文单词的所有字母是否全都不同(不区分大小写)    537
673_有一个已经排好序的整数数组,其中存在重复元素,请将重复元素删除掉,例如,A= [1, 1, 2, 2, 3],处理之后的数组应当为A= [1, 2, 3]。    538
674_给一个数组,其中有一个重复元素占半数以上,找出这个元素。    539
675_编写一个方法求一个字符串的字节长度?    540

java基础、语法
001_Java跨平台原理(字节码文件、虚拟机)
 
C/C++语言都直接编译成针对特定平台机器码。如果要跨平台,需要使用相应的编译器重新编译。
Java源程序(.java)要先编译成与平台无关的字节码文件(.class),然后字节码文件再解释成机器码运行。解释是通过Java虚拟机来执行的。
________________________________________
字节码文件不面向任何具体平台,只面向虚拟机。
 Java虚拟机是可运行Java字节码文件的虚拟计算机。不同平台的虚拟机是不同的,但它们都提供了相同的接口。
Java语言具有一次编译,到处运行的特点。就是说编译后的.class可以跨平台运行,前提是该平台具有相应的Java虚拟机。但是性能比C/C++要低。
    Java的跨平台原理决定了其性能没有C/C++高
________________________________________
 
002_Java的安全性
语言层次的安全性主要体现在:
        Java取消了强大但又危险的指针,而代之以引用。由于指针可进行移动运算,指针可随便指向一个内存区域,而不管这个区域是否可用,这样做是危险的,因为原来这个内存地址可能存储着重要数据或者是其他程序运行所占用的,并且使用指针也容易数组越界。
________________________________________
垃圾回收机制:
        不需要程序员直接控制内存回收,由垃圾回收器在后台自动回收不再使用的内存。避免程序忘记及时回收,导致内存泄露。避免程序错误回收程序核心类库的内存,导致系统崩溃。
异常处理机制:
        Java异常机制主要依赖于try、catch、finally、throw、throws五个关键字。
________________________________________
强制类型转换:
        只有在满足强制转换规则的情况下才能强转成功。
底层的安全性可以从以下方面来说明:
        Java在字节码的传输过程中使用了公开密钥加密机制(PKC)。
在运行环境提供了四级安全性保障机制:
       字节码校验器 -类装载器 -运行时内存布局 -文件访问限制
003_Java三大版本 
Java2平台包括标准版(J2SE)、企业版(J2EE)和微缩版(J2ME)三个版本:
Standard Edition(标准版) J2SE 包含那些构成Java语言核心的类。
比如:数据库连接、接口定义、输入/输出、网络编程 Enterprise Edition(企业版) J2EE 包含J2SE 中的类,并且还包含用于开发企业级应用的类。
比如servlet、JSP、XML、事务控制 Micro Edition(微缩版) J2ME 包含J2SE中一部分类,用于消费类电子产品的软件开发。
比如:呼机、智能卡、手机、PDA、机顶盒
________________________________________
他们的范围是:
        J2SE包含于J2EE中,J2ME包含了J2SE的核心类,但新添加了一些专有类
应用场合,API的覆盖范围各不相同。
004_什么是JVM?什么是JDK? 什么是JRE?
JVM:
        JVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。JVM是Java平台的基础,和实际的机器一样,它也有自己的指令集,并且在运行时操作不同的内存区域。 JVM通过抽象操作系统和CPU结构,提供了一种与平台无关的代码执行方法,即与特殊的实现方法、主机硬件、主机操作系统无关。JVM的主要工作是解释自己的指令集(即字节码)到CPU的指令集或对应的系统调用,保护用户免被恶意程序骚扰。 JVM对上层的Java源文件是不关心的,它关注的只是由源文件生成的类文件(.class文件)。
________________________________________
JRE:
        JRE是java runtime environment(java运行环境)的缩写。光有JVM还不能让class文件执行,因为在解释class的时候JVM需要调用解释所需要的类库lib。在JDK的安装目录里你可以找到jre目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和lib和起来就称为jre。所以,在你写完java程序编译成.class之后,你可以把这个.class文件和jre一起打包发给朋友,这样你的朋友就可以运行你写程序了(jre里有运行.class的java.exe)。JRE是Sun公司发布的一个更大的系统,它里面就有一个JVM。JRE就与具体的CPU结构和操作系统有关,是运行Java程序必不可少的(除非用其他一些编译环境编译成.exe可执行文件……),JRE的地位就象一台PC机一样,我们写好的Win32应用程序需要操作系统帮我们运行,同样的,我们编写的Java程序也必须要JRE才能运行。 
________________________________________
JDK:
        JDK是java development kit(java开发工具包)的缩写。每个学java的人都会先在机器上装一个JDK,那 让我们看一下JDK的安装目录。在目录下面有六个文件夹、一个src类库源码压缩包、和其他几个声明文件。其中,真正在运行java时起作用的是以下四个文件夹:bin、include、lib、jre。现在我们可以看出这样一个关系,JDK包含JRE,而JRE包含JVM。
                bin: 最主要的是编译器(javac.exe)
                include: java和JVM交互用的头文件
                lib:类库      
                jre: java运行环境 
(注意:这里的bin、lib文件夹和jre里的bin、lib是不同的)
        总的来说JDK是用于java程序的开发,而jre则是只能运行class而没有编译的功能。eclipse、idea等其他IDE有自己的编译器而不是用JDK bin目录中自带的,所以在安装时你会发现他们只要求你选jre路径就ok了。
________________________________________
JDK,JRE,JVM三者关系概括如下:
        jdk是JAVA程序开发时用的开发工具包,其内部也有JRE运行环境JRE。JRE是JAVA程序运行时需要的运行环境,就是说如果你光是运行JAVA程序而不是去搞开发的话,只安装JRE就能运行已经存在的JAVA程序了。JDk、JRE内部都包含JAVA虚拟机JVM,JAVA虚拟机内部包含许多应用程序的类的解释器和类加载器等等。
005_Java三种注释类型 
共有单行注释、多行注释、文档注释3种注释类型。
使用如下:
        单行注释,采用“//”方式.只能注释一行代码。如:
                //类成员变量
        多行注释,采用“/*...*/”方式,可注释多行代码,其中不允许出现嵌套。如:
                  /*System.out.println("a");
                System.out.println("b");
                System.out.println("c");*/
________________________________________
文档注释,采用“/**...*/”方式,如:
                /**
                 * 子类  Dog
                 * @author Administrator
                 *
                 */
                public class Dog extends Animal{}
006_8种基本数据类型及其字节数
 
007_ i++和++i的异同之处
    共同点:
    1、i++和++i都是变量自增1,都等价于i=i+1
    2、如果i++,++i是一条单独的语句,两者没有任何区别
   3、i++和++i的使用仅仅针对变量。 5++和++5会报错,因为5不是变量。
    不同点:
   如果i++,++i不是一条单独的语句,他们就有区别
   i++ :先运算后增1。如:

1
2
3
4    int x=5;
int y=x++;
System.out.println("x="+x+", y="+y);
    //以上代码运行后输出结果为:x=6, y=5

 
        ++i : 先增1后运算。如:
 
1
2
3
4    int x=5;
int y=++x;
System.out.println("x="+x+", y="+y);
    //以上代码运行后输出结果为:x=6, y=6

008_&和&&的区别和联系,|和||的区别和联系
&和&&的联系(共同点):
        &和&&都可以用作逻辑与运算符,但是要看使用时的具体条件来决定。
操作数1&操作数2,操作数1&&操作数2,
     表达式1&表达式2,表达式1&&表达式2,

情况2:当上述的表达式结果是boolean类型变量时,&和&&都可以用作逻辑与运算符。
情况1:当上述的操作数是boolean类型变量时,&和&&都可以用作逻辑与运算符。
表示逻辑与(and),当运算符两边的表达式的结果或操作数都为true时,整个运算结果才为true,否则,只要有一方为false,结果都为false。
________________________________________
&和&&的区别(不同点):
        (1)、&逻辑运算符称为逻辑与运算符,&&逻辑运算符称为短路与运算符,也可叫逻辑与运算符。
        对于&:无论任何情况,&两边的操作数或表达式都会参与计算。
        对于&&:当&&左边的操作数为false或左边表达式结果为false时,&&右边的操作数或表达式将不参与计算,此时最终结果都为false。
        综上所述,如果逻辑与运算的第一个操作数是false或第一个表达式的结果为false时,对于第二个操作数或表达式是否进行运算,对最终的结果没有影响,结果肯定是false。推介平时多使用&&,因为它效率更高些。
________________________________________
(2)、&还可以用作位运算符。当&两边操作数或两边表达式的结果不是boolean类型时,&用于按位与运算符的操作。
        |和||的区别和联系与&和&&的区别和联系类似
009_用最有效率的方法算出2乘以8等于多少
        使用位运算来实现效率最高。位运算符是对操作数以二进制比特位为单位进行操作和运算,操作数和结果都是整型数。
        对于位运算符“<<”, 是将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以8只要将其左移3位即可,位运算cpu直接支持的,效率最高。所以,2乘以8等于几的最效率的方法是2 << 3
010_基本数据类型的类型转换规则 
基本类型转换分为自动转换和强制转换。
自动转换规则:
        容量小的数据类型可以自动转换成容量大的数据类型,也可以说低级自动向高级转换。这儿的容量指的不是字节数,而是指类型表述的范围。
 
________________________________________
强制转换规则:
        高级变为低级需要强制转换。
如何转换:
      (1)、赋值运算符“=”右边的转换,先自动转换成表达式中级别最高的数据类型,再进行运算。
      (2)、赋值运算符“=”两侧的转换,若左边级别>右边级别,会自动转换;若左边级别 == 右边级别,不用转换;若左边级别 < 右边级别,需强制转换。
      (3)、可以将整型常量直接赋值给byte, short, char等类型变量,而不需要进行强制类型转换,前提是不超出其表述范围,否则必须进行强制转换。
011_if多分支语句和switch多分支语句的异同之处
相同之处:
        都是分支语句,多超过一种的情况进行判断处理。
不同之处:
        switch更适合用于多分支情况,就是有很多种情况需要判断处理,判断条件类型单一,只有一个入口,在分支执行完后(如果没有break跳出),不加判断地执行下去;而if—elseif---else多分枝主要适用于分支较少的分支结构,判断类型不是单一,只要一个分支被执行后,后边的分支不再执行。
        switch为等值判断(不允许比如>= <=),而if为等值和区间都可以,if的使用范围大。
012_while和do-while循环的区别
        while先判断后执行,第一次判断为false,循环体一次都不执行
        do while先执行 后判断,最少执行1次。
        如果while循环第一次判断为true, 则两种循环没有区别。
013_break和continue的作用
        break: 结束当前循环并退出当前循环体。
        break还可以退出switch语句
        continue: 循环体中后续的语句不执行,但是循环没有结束,继续进行循环条件的判断(for循环还会i++)。continue只是结束本次循环。
014_请使用递归算法计算n!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15    package com.bjsxt;
public class Test {
public int factorial(int n) {  
if (n == 1 || n == 0){
return n;
}else{
return n * factorial(n - 1);
}  
}
public static void main(String[] args) {
Test test = new Test();
System.out.println(test.factorial(6));
}
  
}
015_递归的定义和优缺点
        递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
________________________________________
递归算法解决问题的特点:
        (1) 递归就是在过程或函数里调用自身。
        (2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
        (3) 递归算法解题通常显得很简洁,但运行效率较低。所以一般不提倡用递归算法设计程序。
        (4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
016_数组的特征
        数组是(相同类型数据)的(有序)(集合)
        数组会在内存中开辟一块连续的空间,每个空间相当于之前的一个变量,称为数组的元素element
        元素的表示 数组名[下标或者索引] scores[7]  scores[0]  scores[9]
        索引从0开始
        每个数组元素有默认值  double 0.0 boolean  false  int  0
________________________________________
        数组元素有序的,不是大小顺序,是索引 的顺序
        数组中可以存储基本数据类型,可以存储引用数据类型;但是对于一个数组而言,数组的类型是固定的,只能是一个
        length:数组的长度
        数组的长度是固定的,一经定义,不能再发生变化(数组的扩容)
017_请写出冒泡排序代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36    package com.bjsxt;
  
public class TestBubbleSort {
public static void sort(int[] a) {
int temp = 0;  
// 外层循环,它决定一共走几趟
for (int i = 0; i <a.length-1; ++i) {
//内层循环,它决定每趟走一次
for (int j = 0; j <a.length-i-1 ; ++j) {
//如果后一个大于前一个
if (a[j + 1] < a[j]) {
//换位
temp = a[j];a[j] = a[j + 1];a[j + 1] = temp;
}
}
}
  
public static void sort2(int[] a) {
int temp = 0;
for (int i = 0; i <a.length-1; ++i) {
//通过符号位可以减少无谓的比较,如果已经有序了,就退出循环
int flag = 0;
for (int j = 0; j <a.length-1-i ; ++j) {
if (a[j + 1] < a[j]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
flag = 1;
}
}
if(flag == 0){
break;
}  
}
}
}
018_请写出选择排序的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23    package com.bjsxt;
  
public class TestSelectSort {
public static void sort(int arr[]) {
int temp = 0;
for (int i = 0; i < arr.length - 1; i++) {
// 认为目前的数就是最小的, 记录最小数的下标
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
// 修改最小值的下标
minIndex = j;
}
}
// 当退出for就找到这次的最小值
if (i != minIndex) {
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
}
019_请写出插入排序的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14    package com.bjsxt;
  
public class TestInsertSort {
public static void sort(int arr[]) {
int i, j;
for (i = 1; i < arr.length; i++) {
int temp = arr[i];
for (j = i; j > 0 && temp < arr[j - 1]; j--) {
arr[j] = arr[j - 1];
}
arr[j] = temp;
}
}
}
020_可变参数的作用和特点
总结1:可变参数
        1.可变参数的形式  ...
        2.可变参数只能是方法的形参
        3.可变参数对应的实参可以0,1,2.....个,也可以是一个数组
        4.在可变参数的方法中,将可变参数当做数组来处理
        5.可变参数最多有一个,只能是最后一个
        6.可变参数好处:方便  简单  减少重载方法的数量
        7.如果定义了可变参数的方法,不允许同时定义相同类型数组参数的方法
________________________________________
总结2:
        数组做形参和可变参数做形参联系和区别
联系:
        1.实参都可以是数组;
        2.方法体中,可变参数当做数组来处理
________________________________________
区别:
        1.个数不同 可变参数只能有一个数组参数可以多个
        2.位置不同 可变参数只能是最后一个 数组参数位置任意
        3.实参不同 可变参数实参可以0,1,2.....个,也可以是一个数组,数组的实参只能是数组
021_类和对象的关系
        类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。
________________________________________
        类和对象好比图纸和实物的关系,模具和铸件的关系。
        比如人类就是一个概念,人类具有身高,体重等属性。人类可以做吃饭、说话等方法。
        小明就是一个具体的人,也就是实例,他的属性是具体的身高200cm,体重180kg,他做的方法是具体的吃了一碗白米饭,说了“12345”这样一句话。
022_面向过程和面向对象的区别
        两者都是软件开发思想,先有面向过程,后有面向对象。在大型项目中,针对面向过程的不足推出了面向对象开发思想。
  
________________________________________
比喻:
        蒋介石和毛泽东分别是面向过程和面向对象的杰出代表,这样充分说明,在解决复制问题时,面向对象有更大的优越性。
        面向过程是蛋炒饭,面向对象是盖浇饭。盖浇饭的好处就是“菜”“饭”分离,从而提高了制作盖浇饭的灵活性。饭不满意就换饭,菜不满意换菜。用软件工程的专业术语就是“可维护性”比较好,“饭” 和“菜”的耦合度比较低。
区别:
        编程思路不同: 面向过程以实现功能的函数开发为主,而面向对象要首先抽象出类、属性及其方法,然后通过实例化类、执行方法来完成功能。
        封装性:都具有封装性,但是面向过程是封装的是功能,而面向对象封装的是数据和功能。
面向对象具有继承性和多态性,而面向过程没有继承性和多态性,所以面向对象优势是明显。
________________________________________
方法重载和方法重写(覆盖)的区别:
 
 
023_this和super关键字的作用
        this是对象内部指代自身的引用,同时也是解决成员变量和局部变量同名问题;this可以调用成员变量,不能调用局部变量;this也可以调用成员方法,但是在普通方法中可以省略this,在构造方法中不允许省略,必须是构造方法的第一条语句。,而且在静态方法当中不允许出现this关键字。
________________________________________
        super代表对当前对象的直接父类对象的引用,super可以调用直接父类的成员变量(注意权限修饰符的影响,比如不能访问private成员)
        super可以调用直接父类的成员方法(注意权限修饰符的影响,比如不能访问private成员);super可以调用直接父类的构造方法,只限构造方法中使用,且必须是第一条语句。
024_static关键字的作用
        static可以修饰变量、方法、代码块和内部类
        static属性属于这个类所有,即由该类创建的所有对象共享同一个static属性。可以对象创建后通过对象名.属性名和类名.属性名两种方式来访问。也可以在没有创建任何对象之前通过类名.属性名的方式来访问。
        .static变量和非static变量的区别(都是成员变量,不是局部变量)
________________________________________
1.在内存中份数不同
        不管有多少个对象,static变量只有1份。对于每个对象,实例变量都会有单独的一份
static变量是属于整个类的,也称为类变量。而非静态变量是属于对象的,也称为实例变量
2.在内存中存放的位置不同
        静态变量存在方法区中, 实例变量存在堆内存中 *  
3.访问的方式不同
        实例变量: 对象名.变量名  stu1.name="小明明";
        静态变量:对象名.变量名  stu1.schoolName="西二旗小学"; 不推荐如此使用
                        类名.变量名  Student.schoolName="东三旗小学"; 推荐使用
________________________________________
4.在内存中分配空间的时间不同
        实例变量:创建对象的时候才分配了空间。静态变量:第一次使用类的时候
        Student.schoolName="东三旗小学";或者Student stu1 = new Student("小明","男",20,98);
        static方法也可以通过对象名.方法名和类名.方法名两种方式来访问
        static代码块。当类被第一次使用时(可能是调用static属性和方法,或者创建其对象)执行静态代码块,且只被执行一次,主要作用是实现static属性的初始化。
        static内部类:属于整个外部类,而不是属于外部类的每个对象。不能访问外部类的非静态成员(变量或者方法),.可以访问外部类的静态成员
025_final和abstract关键字的作用
        final和abstract是功能相反的两个关键字,可以对比记忆
        abstract可以用来修饰类和方法,不能用来修饰属性和构造方法;使用abstract修饰的类是抽象类,需要被继承,使用abstract修饰的方法是抽象方法,需要子类被重写。
        final可以用来修饰类、方法和属性,不能修饰构造方法。使用final修饰的类不能被继承,使用final修饰的方法不能被重写,使用final修饰的变量的值不能被修改,所以就成了常量。
________________________________________
      特别注意:final修饰基本类型变量,其值不能改变,由原来的变量变为常量;但是final修饰引用类型变量,栈内存中的引用不能改变,但是所指向的堆内存中的对象的属性值仍旧可以改变。例如:
1
2
3
4
5
6
7
8
9    package com.bjsxt;
  
class Test {
    public static void main(String[] args) {
        final Dog dog = new Dog("欧欧");
        dog.name = "美美";//正确
        dog = new Dog("亚亚");//错误
    }
}
026_final、finally、finalize的区别
        final修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承例如:String类、Math类等。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重写,但是能够重载。 使用final修饰的对象,对象的引用地址不能变,但是对象的值可以变!
________________________________________
        finally在异常处理时提供 finally 块来执行任何清除操作。如果有finally的话,则不管是否发生异常,finally语句都会被执行。一般情况下,都把关闭物理连接(IO流、数据库连接、Socket连接)等相关操作,放入到此代码块中.。
        finalize方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要清理工作。finalize() 方法是在垃圾收集器删除对象之前被调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。 一般情况下,此方法由JVM调用,程序员不要去调用!
027_写出java.lang.Object类的六个常用方法
        (1)public boolean equals(java.lang.Object)比较对象的地址值是否相等,如果子类重写,则比较对象的内容是否相等;
        (2)public native int hashCode() 获取哈希码
        (3)public java.lang.String toString() 把数据转变成字符串
        (4)public final native java.lang.Class getClass() 获取类结构信息
        (5)protected void finalize() throws java.lang.Throwable垃圾回收前执行的方法
        (6)protected native Object clone() throws java.lang.CloneNotSupportedException 克隆
        (7)public final void wait() throws java.lang.InterruptedException多线程中等待功能
        (8)public final native void notify() 多线程中唤醒功能
        (9)public final native void notifyAll() 多线程中唤醒所有等待线程的功能
028_private/默认/protected/public权限修饰符的区别
 
  类的访问权限只有两种:
  public 公共的 可被同一项目中所有的类访问。 (必须与文件名同名)
  default 默认的 可被同一个包中的类访问。
________________________________________
       成员(成员变量或成员方法)访问权限共有四种:
  public 公共的 可以被项目中所有的类访问。(项目可见性)
  protected 受保护的 可以被这个类本身访问;同一个包中的所有其他的类访问;被它的子类(同一个包以及不同包中的子类)访问。(子类可见性)
  default 默认的被这个类本身访问;被同一个包中的类访问。(包可见性)
  private 私有的 只能被这个类本身访问。(类可见性)
029_继承条件下构造方法的执行过程
继承条件下构造方法的调用规则如下:
        情况1:如果子类的构造方法中没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法。在这种情况下,写不写“super();”语句,效果是一样的。
        情况2:如果子类的构造方法中通过super显式调用父类的有参构造方法,那将执行父类相应构造方法,而不执行父类无参构造方法。
________________________________________
        情况3:如果子类的构造方法中通过this显式调用自身的其他构造方法,在相应构造方法中应用以上两条规则。
        特别注意的是,如果存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类应用,一直到执行顶级父类Object类的无参构造方法为止。
030_==和equals的区别和联系
“==”是关系运算符,equals()是方法,同时他们的结果都返回布尔值;
“==”使用情况如下:
            a) 基本类型,比较的是值
            b) 引用类型,比较的是地址
            c) 不能比较没有父子关系的两个对象
________________________________________
equals()方法使用如下:
            a) 系统类一般已经覆盖了equals(),比较的是内容。
            b)  用户自定义类如果没有覆盖equals(),将调用父类的equals(比如是Object),而Object的equals的比较是地址(return (this == obj);)
            c) 用户自定义类需要覆盖父类的equals()
注意:Object的==和equals比较的都是地址,作用相同
031_谈谈Java的多态
实现多态的三个条件(前提条件,向上转型、向下转型)
1、继承的存在;(继承是多态的基础,没有继承就没有多态)
2、子类重写父类的方法。(多态下会调用子类重写后的方法)
3、父类引用变量指向子类对象。(涉及子类到父类的类型转换)
________________________________________
向上转型  Student person = new Student()
        将一个父类的引用指向一个子类对象,成为向上转型,自动进行类型转换。此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,而不是父类的方法此时通过父类引用变量无法调用子类特有的方法.
________________________________________
向下转型    Student stu = (Student)person;
        将一个指向子类对象的引用赋给一个子类的引用,成为向下转型,此时必须进行强制类型转换。向下转型必须转换为父类引用指向的真实子类类型,,否则将出现ClassCastException,不是任意的强制转换.
        向下转型时可以结合使用instanceof运算符进行强制类型转换,比如出现转换异常---ClassCastException.
032_简述Java的垃圾回收机制
        传统的C/C++语言,需要程序员负责回收已经分配内存。
显式回收垃圾回收的缺点:
        1)程序忘记及时回收,从而导致内存泄露,降低系统性能。
        2)程序错误回收程序核心类库的内存,导致系统崩溃。
        Java语言不需要程序员直接控制内存回收,是由JRE在后台自动回收不再使用的内存,称为垃圾回收机制,简称GC;
        1)可以提高编程效率。
        2)保护程序的完整性。
        3)其开销影响性能。Java虚拟机必须跟踪程序中有用的对象,确定哪些是无用的。
________________________________________
垃圾回收机制的特点:
        1)垃圾回收机制回收JVM堆内存里的对象空间,不负责回收栈内存数据。
        2)对其他物理连接,比如数据库连接、输入流输出流、Socket连接无能为力。
        3)垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制执行。
        4)可以将对象的引用变量设置为null,暗示垃圾回收机制可以回收该对象。
        现在的JVM有多种垃圾回收实现算法,表现各异。
        垃圾回收机制回收任何对象之前,总会先调用它的finalize方法(如果覆盖该方法,让一个新的引用变量重新引用该对象,则会重新激活对象)。
________________________________________
        程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定。
        永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用。
033_基本数据类型和包装类
1) 八个基本数据类型的包装类
基本数据类型     包装类
byte    Byte
boolean     Boolean
short    Short
char    Character
int    Integer
long     Long
float    Float
double    Double

2)  为什么为基本类型引入包装类
        2.1、基本数据类型有方便之处,简单、高效。
        2.2、 但是Java中的基本数据类型却是不面向对象的(没有属性、方法),这在实际使用时存在很多的不便(比如集合的元素只能是Object).
        为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行包装,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。
________________________________________
3) 包装类和基本数据类型之间的转换
3.1包装类------ wrapperInstance.xxxValue() ------>基本数据类型
3.2包装类<---new WrapperClass(primitive)
new WrapperClass(string)------基本数据类型
4)自动装箱和自动拆箱
JDK1.5提供了自动装箱(autoboxing)和自动拆箱(autounboxing)功能, 从而实现了包装类和基本数据类型之间的自动转换
5)、包装类还可以实现基本类型变量和字符串之间的转换
基本类型变量------------String.valueof()------------>字符串
基本类型变量<------------WrapperClass.parseXxx(string)------------字符串
034_Integer与int的区别
        int是java提供的8种原始数据类型之一,Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。
        int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。在JSP开发中,Integer的默认为null,所以用el表达式在文本框中显示时,值为空白字符串,而int默认的默认值为0,所以用el表达式在文本框中显示时,结果为0,所以,int不适合作为web层的表单数据的类型。
________________________________________
        在Hibernate中,如果将OID定义为Integer类型,那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,如果将OID定义为了int类型,还需要在hbm映射文件中设置其unsaved-value属性为0。
             另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。
035_java.sql.Date和java.util.Date的联系和区别
  1)、java.sql.Date是java.util.Date的子类,是一个包装了毫秒值的瘦包装器,允许 JDBC 将毫秒值标识为 SQL DATE 值。毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以来经过的毫秒数。 为了与 SQL DATE 的定义一致,由 java.sql.Date 实例包装的毫秒值必须通过将时间、分钟、秒和毫秒设置为与该实例相关的特定时区中的零来“规范化”。 说白了,java.sql.Date就是与数据库Date相对应的一个类型,而java.util.Date是纯java的Date。
________________________________________
  2)、JAVA里提供的日期和时间类,java.sql.Date和java.sql.Time,只会从数据库里读取某部分值,这有时会导致丢失数据。例如一个包含2002/05/22 5:00:57 PM的字段,读取日期时得到的是2002/05/22,而读取时间时得到的是5:00:57 PM. 你需要了解数据库里存储时间的精度。有些数据库,比如MySQL,精度为毫秒,然而另一些数据库,包括Oracle,存储SQL DATE类型数据时,毫秒部分的数据是不保存的。以下操作中容易出现不易被发现的BUG:获得一个JAVA里的日期对象。 从数据库里读取日期 试图比较两个日期对象是否相等。如果毫秒部分丢失,本来认为相等的两个日期对象用Equals方法可能返回false。.sql.Timestamp类比java.util.Date类精确度要高。这个类包了一个getTime()方法,但是它不会返回额外精度部分的数据,因此必须使用...
________________________________________
  总之,java.util.Date 就是Java的日期对象,而java.sql.Date 是针对SQL语句使用的,只包含日期而没有时间部分。
036_使用递归算法输出某个目录下所有文件和子目录列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21    package com.bjsxt;
import java.io.File;
public class $ {
public static void main(String[] args) {
          String path = "D:/301SXT";
          test(path);
      }
      private static void test(String path) {
          File f = new File(path);
          File[] fs = f.listFiles();
          if (fs == null) {
              return;
          }
          for (File file : fs) {
              if (file.isFile()) {
                  System.out.println(file.getPath());
              } else {
                  test(file.getPath());
              }
          }
     }
037_关于Java编译,下面哪一个正确()(选择一项)

A    Java程序经编译后产生machine code
B.    Java程序经编译后会生产byte code
C.    Java程序经编译后会产生DLL
D.    以上都不正确
答案:B
分析: Java是解释型语言,编译出来的是字节码; 因此A不正确,C是C/C++语言编译动态链接库的文件为.DLL; 正确答案为B
038_下列说法正确的有()(选择一项)
A    class中的construtor不可省略
B.    construtor与class同名,但方法不能与class同名
C.    construtor在一个对象被new时执行
D.    一个class只能定义一个construtor
答案:C
分析:A:如果class中的construtor省略不写,系统会默认提供一个无参构造
          B:方法名可以与类名同名,只是不符合命名规范
          D:一个class中可以定义N多个construtor,这些construtor构成构造方法的重载
039_Java中接口的修饰符可以为()(选择一项)
A    private
B.    protected
C.    final
D.    abstract
答案:D
分析:接口中的访问权限修饰符只可以是public或default
          接口中的所有的方法必须要实现类实现,所以不能使用final
          接口中所有的方法默认都是abstract的,所以接口可以使用abstract修饰,但通常abstract可以省略不写
040_给定以下代码,程序将输出 ()(选择一项)

1
2
3
4
5
6
7
8
9
10
11
12
13    class A {
public A(){
System.out.println("A");
}
}
class B extends A{
public B(){
System.out.println("B");
}
public static void main(String[] args) {
B b=new B();
}
}

    
A    不能通过编译
B.    通过编译,输出AB
C.    通过编译,输出B
D.    通过编译,输出A
答案:B
分析:在继承关系下,创建子类对象,先执行父类的构造方法,再执行子类的构造方法。 
041_下列关于关键字的使用说法错误的是()(选择一项)
A.    abstract不能与final并列修饰同一个类
B.    abstract类中可以有private的成员
C.    abstract方法必须在abstract类中
D.    static方法能处理非static的属性
答案:D
分析:因为static得方法在装载class得时候首先完成,比 构造方法早,此时非static得属性和方法还没有完成初始化所以不能调用。
042_下列哪些语句关于内存回收的说法是正确的()(选择一项)
A.    程序员必须创建一个线程来释放内存
B.    内存回收程序负责释放无用内存
C.    内存回收程序允许程序员直接释放内存
D.    内存回收程序可以在指定的时间释放内存对象
答案:B
分析: A. 程序员不需要创建线程来释放内存.
           C. 也不允许程序员直接释放内存.
           D. 不一定在什么时刻执行垃圾回收.

043_选出合理的标识符()(选择两项)
A.    _sysl_111
B.    2 mail
C.    $change
D.    class
答案:AC
分析: 标识符的命令规范,可以包含字母、数字、下划线、$,不能以数字开头,不能是Java关键字
044_下列说法正确的是()(选择多项)
A.    java.lang.Cloneable是类
B.    java.langRunnable是接口
C.    Double对象在java.lang包中
D.    Double a=1.0是正确的java语句
答案:BCD
分析:java.lang.Cloneable是接口 
045_定义一个类名为”MyClass.java”的类,并且该类可被一个工程中的所有类访问,那么该类的正确声明为()(选择两项)
A.    private class MyClass extends Object
B.    class MyClass extends Object 
C.    public class MyClass
D.    public class MyClass extends Object
答案:CD
分析: A 类的访问权限只能是public或default
           B使用默认访问权限的类,只能在本包中访问
046_面向对象的特征有哪些方面?请用生活中的例子来描述。
答: 
面向对象的三大特征:封装、继承、多态。
举例:
 (比如设计一个游戏)我现在创建了一个对象,名叫战士。
战士的属性是—性别,年龄,职业,等级,战斗力,血量。
它的方法—战斗,逃跑,吃饭,睡觉,死。
后来,我又建了一个对象,叫人。
属性:性别,年龄,职业,等级,血量
方法:逃跑,吃饭,睡觉,死。
我让人,成为战士的父类,战士可以直接继承人的属性和方法。
战士修改成—
属性:战斗力。
方法:战斗
看上去战士的资料变少了,实际上没有,我们仍然可以调用方法—战士.死。
而且我们还可以重载战士.死的方法,简称重载死法。
我还建了一个对象—法师,父类也是人。
属性:法力值
方法:施法,泡妞。
        你看,用了继承,创建对象变得更方便了。
        再后来,我又建立了一个对象,叫怪物。
属性:等级,战力,血量。
方法:战斗,死。
        建了个对象,叫白兔怪,父类怪物,可继承怪物所有的属性和方法。
属性:毛色。
方法:卖萌,吃胡萝卜。
047_说明内存泄漏和内存溢出的区别和联系,结合项目经验描述Java程序中如何检测?如何解决?
答:内存溢出out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
memory leak会最终会导致out of memory!
048_什么是Java的序列化,如何实现Java的序列化?列举在哪些程序中见过Java序列化?
        答:Java中的序列化机制能够将一个实例对象(只序列化对象的属性值,而不会去序列化什么所谓的方法。)的状态信息写入到一个字节流中使其可以通过socket进行传输、或者持久化到存储数据库或文件系统中;然后在需要的时候通过字节流中的信息来重构一个相同的对象。一般而言,要使得一个类可以序列化,只需简单实现java.io.Serializable接口即可。
对象的序列化主要有两种用途:
  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
  2) 在网络上传送对象的字节序列。
________________________________________
  在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
  当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
049_不通过构造函数也能创建对象吗?
答:Java创建对象的几种方式(重要):
        1、 用new语句创建对象,这是最常见的创建对象的方法。
        2、 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
        3、 调用对象的clone()方法。
        4、运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
        (1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。
050_匿名内部类可不可以继承或实现接口。为什么?
答:匿名内部类是没有名字的内部类,不能继承其它类,但一个内部类可以作为一个接口,由另一个内部类实现.
        1、由于匿名内部类没有名字,所以它没有构造函数。因为没有构造函数,所以它必须完全借用父类的构造函数来实例化,换言之:匿名内部类完全把创建对象的任务交给了父类去完成。
        2、在匿名内部类里创建新的方法没有太大意义,但它可以通过覆盖父类的方法达到神奇效果,如上例所示。这是多态性的体现。
        3、因为匿名内部类没有名字,所以无法进行向下的强制类型转换,持有对一个匿名内部类对象引用的变量类型一定是它的直接或间接父类类型。
051_在Java中,为什么基本类型不能做为HashMap的键值,而只能是引用类型,把引用类型做为HashMap的健值,需要注意哪些地方。
答:
        (1)在Java中是使用泛型来约束HashMap中的key和value的类型的,即HashMap<K, V>;而泛型在Java的规定中必须是对象Object类型的,也就是说HashMap<K, V>可以理解为HashMap<Object,Object>,很显然基本数据类型不是Object类型的,因此不能作为键值,只能是引用类型。虽然我们在HashMap中可以这样添加数据:“map.put(1, “Java”);”,但实际上是将其中的key值1进行了自动装箱操作,变为了Integer类型。
________________________________________
        (1)引用数据类型分为两类:系统提供的引用数据类型(如包装类、String等)以及自定义引用数据类型。系统提供的引用数据类型中已经重写了HashCode()和equals()两个方法,所以能够保证Map中key值的唯一性;但是自定义的引用数据类型需要自己重写HashCode()和equals()这两个方法,以保证Map中key值的唯一性。
052_简述Java中如何实现多态
答:实现多态有三个前提条件:
        1、 继承的存在;(继承是多态的基础,没有继承就没有多态)。
        2、子类重写父类的方法。(多态下会调用子类重写后的方法)。
        3、父类引用变量指向子类对象。(涉及子类到父类的类型转换)。
        最后使用父类的引用变量调用子类重写的方法即可实现多态。
053_以下对继承的描述锚误的是 ()
A.    Java中的继承允许一个子类继承多个父类
B.    父类更具有通用性,子类更具体
C.    Java中的继承存在着传递性
D.    当实例化子类时会递归调用父类中的构造方法
答案:A
分析:
Java是单继承的,一个类只能继承一个父类。
054_Java 中 Math.random()/Math.random()值为?
答:
        如果除数与被除数均不为0.0的话,则取值范围为[0, +∞]。+∞在Java中显示的结果为Infinity。
        如果除数与被除数均为0.0的话,则运行结果为NaN(Not a Number的简写),计算错误。
055_Java中,如果Manager是Employee的子类,那么Pair<Manager>是Pair<Employee>的子类吗?
答:不是,两者没有任何关联;
        Pair是单独的类,只不过用不同类型的参数(泛型)进行了相应的实例化而已;所以,Pair<Manager>和Pair<Employee>不是子类的关系。
056_接口和抽象类的区别
        答:
相同点
        抽象类和接口均包含抽象方法,类必须实现所有的抽象方法,否则是抽象类
        抽象类和接口都不能实例化,他们位于继承树的顶端,用来被其他类继承和实现
两者的区别主要体现在两方面:语法方面和设计理念方面
        语法方面的区别是比较    低层次的,非本质的,主要表现在:
        接口中只能定义全局静态常量,不能定义变量。抽象类中可以定义常量和变量。
        接口中所有的方法都是全局抽象方法。抽象类中可以有0个、1个或多个,甚至全部都是抽象方法。
        抽象类中可以有构造方法,但不能用来实例化,而在子类实例化是执行,完成属于抽象类的初始化操作。接口中不能定义构造方法。
________________________________________
        一个类只能有一个直接父类(可以是抽象类),但可以充实实现多个接口。一个类使用extends来继承抽象类,使用implements来实现接口。
        二者的主要区别还是在设计理念上,其决定了某些情况下到底使用抽象类还是接口。
        抽象类体现了一种继承关系,目的是复用代码,抽象类中定义了各个子类的相同代码,可以认为父类是一个实现了部分功能的“中间产品”,而子类是“最终产品”。父类和子类之间必须存在“is-a”的关系,即父类和子类在概念本质上应该是相同的。
________________________________________
        接口并不要求实现类和接口在概念本质上一致的,仅仅是实现了接口定义的约定或者能力而已。接口定义了“做什么”,而实现类负责完成“怎么做”,体现了功能(规范)和实现分离的原则。接口和实现之间可以认为是一种“has-a的关系”
057_同步代码块和同步方法有什么区别
答:
相同点:
        同步方法就是在方法前加关键字synchronized,然后被同步的方法一次只能有一个线程进入,其他线程等待。而同步代码块则是在方法内部使用大括号使得一个代码块得到同步。同步代码块会有一个同步的“目标”,使得同步块更加灵活一些(同步代码块可以通过“目标”决定需要锁定的对象)。一般情况下,如果此“目标”为this,那么同步方法和同步代码块没有太大的区别。
________________________________________
区别:
        同步方法直接在方法上加synchronized实现加锁,同步代码块则在方法内部加锁。很明显,同步方法锁的范围比较大,而同步代码块范围要小点。一般同步的范围越大,性能就越差。所以一般需要加锁进行同步的时候,范围越小越好,这样性能更好。
058_静态内部类和内部类有什么区别
答:
        静态内部类不需要有指向外部类的引用。但非静态内部类需要持有对外部类的引用。
        静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。
        非静态内部类能够访问外部类的静态和非静态成员。静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员。
________________________________________
实例化方式不同:
        1) 静态内部类:不依赖于外部类的实例,直接实例化内部类对象
        2) 非静态内部类:通过外部类的对象实例生成内部类对象
059_反射的概念与作用
答:
反射的概念:
        反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。
Java反射可以于运行时加载,探知和使用编译期间完全未知的类.
程序在运行状态中, 可以动态加载一个只有名称的类, 对于任意一个已经加载的类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能调用他的任意一个方法和属性;
l加载完类之后, 在堆内存中会产生一个Class类型的对象(一个类只有一个Class对象), 这个对象包含了完整的类的结构信息,而且这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以被称之为:反射.
java反射使得我们可以在程序运行时动态加载一个类,动态获取类的基本信息和定义的方法,构造函数,域等。
除了检阅类信息外,还可以动态创建类的实例,执行类实例的方法,获取类实例的域值。反射使java这种静态语言有了动态的特性。
________________________________________
反射的作用:
        通过反射可以使程序代码访问装载到JVM 中的类的内部信息
                1) 获取已装载类的属性信息
                2) 获取已装载类的方法
                3) 获取已装载类的构造方法信息
________________________________________
反射的优点:
        增加程序的灵活性。
        如struts中。请求的派发控制。
        当请求来到时。struts通过查询配置文件。找到该请求对应的action。已经方法。
        然后通过反射实例化action。并调用响应method。
        如果不适用反射,那么你就只能写死到代码里了。
        所以说,一个灵活,一个不灵活。
        很少情况下是非用反射不可的。大多数情况下反射是为了提高程序的灵活性。
        因此一般框架中使用较多。因为框架要适用更多的情况。对灵活性要求较高。
060_提供Java存取数据库能力的包是()
A.    java.sql
B.    java.awt
C.    java.lang
D.    java.swing
答案:A
分析:
java.awt和javax.swing两个包是图形用户界面编程所需要的包;java.lang包则提供了Java编程中用到的基础类
061_下列运算符合法的是()(多选)
A.    &&
B.    <>
C.    if
D.    =
答案:AD
分析:
&&是逻辑运算符中的短路与;
<>表示不等于,但是Java中不能这么使用,应该是!=;
if不是运算符;
=是赋值运算符
062_执行如下程序代码,c的值打印出来是()
1
2
3
4
5
6
7
8
9
10
11    public class Test1 {
public static void main(String[] args) {
int a = 0;
int c = 0;
do{
--c;
a = a - 1;
} while (a > 0);
System.out.println(c);
}
}

A.    0
B.    1
C.    -1
D.    死循环
答案:C
分析:
do-while循环的特点是先执行后判断,所以代码先执行--c操作,得到c为-1,之后执行a=a-1的操作,得到a为-1,然后判断a是否大于0,判断条件不成立,退出循环,输出c为-1。
063_下列哪一种叙述是正确的()
A.    abstract修饰符可修饰字段,方法和类
B.    抽象方法的body部分必须用一对大括号{}包住
C.    声明抽象方法,大括号可有可无
D.    声明抽象方法不可写出大括号
答案:D
分析:
abstract只能修饰方法和类,不能修饰字段;
抽象方法不能有方法体,即没有{};
同B。
064_下列语句正确的是()
A.    形式参数可被视为local Variable
B.    形式参数可被所有的字段修饰符修饰
C.    形式参数为方法被调用时,真正被传递的参数
D.    形式参数不可以是对象
答案:A
分析:
local Variable为局部变量,形参和局部变量一样都只有在方法内才会发生作用,也只能在方法中使用,不会在方法外可见;
对于形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误;
真正被传递的参数是实参;
形式参数可是基本数据类型也可以是引用类型(对象)。
065_下列哪种说法是正确的()
A.    实例方法可直接调用超类的实例方法
B.    实例方法可直接调用超类的类方法
C.    实例方法可直接调用其他类的实例方法
D.    实例方法可直接调用本类的类方法
答案:D
分析:
实例方法不可直接调用超类的私有实例方法;
实例方法不可直接调用超类的私有的类方法;
要看访问权限。
066_Java程序的种类有()(多选)
A.    类 (Class)
B.    Applet
C.    Application
D.    Servlet
答案:BCD
分析:
是Java中的类,不是程序;
内嵌于Web文件中,由浏览器来观看的Applet;
可独立运行的 Application;
服务器端的 Servlet。
067_下列说法正确的有()(多选)
A.    环境变量可在编译source code时指定
B.    在編译程序时,所指定的环境变置不包括class path
C.    javac —次可同时编译数个Java 源文件
D.    javac.exe能指定编译结果要置于哪个目录(directory)
答案:BCD
分析:
环境变量一般都是先配置好再编译源文件。
068_下列标识符不合法的有()(多选)
A.    new
B.    $Usdollars
C.    1234
D.    car.taxi
答案:ACD
分析:
new是Java的关键字;
C. 数字不能开头;
D. 不能有“.”。
069_下列说法错误的有()(多选)
A.    数组是—种对象
B.    数组属于一种原生类
C.    int number[]=(31,23,33,43,35,63)
D.    数组的大小可以任意改变
答案:BCD
分析:
B. Java中的原生类(即基本数据类型)有8种,但不包括数组;
C. 语法错误,应该“{···}”,而不是“(···)”;
D. 数组的长度一旦确定就不能修改。
070_不能用来修饰interface的有()(多选)
A.    private
B.    public
C.    protected
D.    static
答案:ACD
分析:
能够修饰interface的只有public、abstract以及默认的三种修饰符。
071_下列正确的有()(多选)
A.    call by value不会改变实际参数的数值
B.    call by reference能改变实际参数的参考地址
C.    call by reference 不能改变实际参数的参考地址
D.    call by reference 能改变实际参数的内容
答案:ACD
分析:
Java中参数的传递有两种,一种是按值传递(call by value:传递的是具体的值,如基础数据类型),另一种是按引用传递(call by reference:传递的是对象的引用,即对象的存储地址)。前者不能改变实参的数值,后者虽然不能改变实参的参考地址,但可以通过该地址访问地址中的内容从而实现内容的改变。
072_下列说法错误的有()(多选)
A.    在类方法中可用this来调用本类的类办法
B.    在类方法中调用本类的类方法时可以直接调用
C.    在类方法中只能调用本类中的类方法
D.    在类方法中绝对不能调用实例方法
答案:ACD
分析:
类方法是在类加载时被加载到方法区存储的,此时还没有创建对象,所以不能使用this或者super关键字;
C. 在类方法中还可以调用其他类的类方法;
D. 在类方法可以通过创建对象来调用实例方法。
073_下列说法错误的有()(多选)
A.    Java面向对象语言容许单独的过栈与函数存在
B.    Java面向对象语言容许单独的方法存在
C.    Java语言中的方法属于类中的成员(member)
D.    Java语言中的方法必定隶属于某一类(对象),调用方法与过程或函数相同
答案:ABC
分析:
B. Java不允许单独的方法,过程或函数存在,需要隶属于某一类中;
C. 静态方法属于类的成员,非静态方法属于对象的成员
074_下列说法错误的有()(多选)
A.    能被java.exe成功运行的java class文件必须有main()方法
B.    J2SDK就是Java API
C.    Appletviewer.exe可利用jar选项运行.jar文件
D.    能被Appletviewer成功运行的java class文件必须有main()方法
答案:BCD
分析:
B. J2SDK是sun公司编程工具,API是指的应用程序编程接口;
C. Appletviewer.exe就是用来解释执行java applet应用程序的,一种执行HTML文件上的Java小程序类的Java浏览器;
D. 能被Appletviewer成功运行的java class文件可以没有main()方法。
075_请问0.3332的数据类型是()
A.    float
B.    double
C.    Float
D.    Double
答案:B
分析:
小数默认是双精度浮点型即double类型的。
076_Java接口的修饰符可以为()
A.    private
B.    protected
C.    final
D.    abstract
答案:D
分析:
能够修饰interface的只有public、abstract以及默认的三种修饰符。
077_不通过构造函数也能创建对象么()
A.    是
B.    否
答案:A
分析:
Java创建对象的几种方式:
(1) 用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法。
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法。
(1)和(2)都会明确的显式的调用构造函数;(3)是在内存上对已有对象的影印,所以不会调用构造函数;(4)是从文件中还原类的对象,也不会调用构造函数。
078_存在使i+1<i的数么?
答:
        存在, int的最大值, 加1后变为负数.
079_接口可否继承接口?抽象类是否可实现接口?抽象类是否可继承实体类?
答:
        接口可以继承接口,抽象类可以实现接口,抽象类可以继承实体类。
080_int与Integer有什么区别?
答:
        int是java提供的8种原始数据类型之一。Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。在JSP开发中,Integer的默认为null,所以用el表达式在文本框中显示时,值为空白字符串,而int默认的默认值为0,所以用el表达式在文本框中显示时,结果为0,所以,int不适合作为web层的表单数据的类型。
________________________________________
        在Hibernate中,如果将OID定义为Integer类型,那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,如果将OID定义为了int类型,还需要在hbm映射文件中设置其unsaved-value属性为0。
        另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。
081_可序列化对象为什么要定义serialversionUID值?
答:
        SerialVersionUid,简言之,其目的是序列化对象版本控制,有关各版本反序列化时是否兼容。如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClassException异常。如果修改较小,比如仅仅是增加了一个属性,我们希望向下兼容,老版本的数据都能保留,那就不用修改;如果我们删除了一个属性,或者更改了类的继承关系,必然不兼容旧数据,这时就应该手动更新版本号,即SerialVersionUid。
082_写一个Java正则,能过滤出html中的<a href=”url”>titl</a>形式中的链接地址和标题.
答:
        <a\b[^>]+\bhref="([^"]*)"[^>]*>([\s\S]*?)</a>
         分组1和分组2即为href和value
083_十进制数72转换成八进制数是多少?
        答: 110
084_Java程序中创建新的类对象,使用关键字new,回收无用的类对象使用关键字free正确么?
答:
        Java程序中创建新的类对象,使用关键字new是正确的; 回收无用的类对象使用关键字free是错误的.
085_Class类的getDeclaredFields()方法与getFields()的区别?
答:
        getDeclaredFields(): 可以获取所有本类自己声明的方法, 不能获取继承的方法
        getFields(): 只能获取所有public声明的方法, 包括继承的方法
086_在switch和if-else语句之间进行选取,当控制选择的条件不仅仅依赖于一个x时,应该使用switch结构;正确么?
答:不正确。
        通常情况下,进行比较判断的处理,switch 和if-else可以互相转换来写;if-else作用的范围比switch-case作用范围要大,但是当switch-case和if-else都可以用的情况下,通常推荐使用switch-case。
比如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20    switch (ch) {
case 'a':
System.out.println("A");
break;
case 'b':
System.out.println("B");
break;
case 'c':
System.out.println("C");
break;
case 'd':
System.out.println("D");
break;
case 'e':
System.out.println("E");
break;
default:
System.out.println("other");
break;
}
换为if-else
1
2
3
4
5
6
7
8
9
10
11
12
13    if (ch == 'a') {
System.out.println("A");
} else if (ch == 'b') {
System.out.println('B');
} else if (ch == 'c') {
System.out.println("C");
} else if (ch == 'd') {
System.out.println("D");
} else if (ch == 'e') {
System.out.println("E");
} else {
System.out.println("Other");
}
087_描述&和&&的区别。
&和&&的联系(共同点):
        &和&&都可以用作逻辑与运算符,但是要看使用时的具体条件来决定。
        操作数1&操作数2,操作数1&&操作数2,
        表达式1&表达式2,表达式1&&表达式2,
        情况1:当上述的操作数是boolean类型变量时,&和&&都可以用作逻辑与运算符。
        情况2:当上述的表达式结果是boolean类型变量时,&和&&都可以用作逻辑与运算符。
        表示逻辑与(and),当运算符两边的表达式的结果或操作数都为true时,整个运算结果才为true,否则,只要有一方为false,结果都为false。
________________________________________
&和&&的区别(不同点):
        (1)、&逻辑运算符称为逻辑与运算符,&&逻辑运算符称为短路与运算符,也可叫逻辑与运算符。
对于&:无论任何情况,&两边的操作数或表达式都会参与计算。
        对于&&:当&&左边的操作数为false或左边表达式结果为false时,&&右边的操作数或表达式将不参与计算,此时最终结果都为false。
        综上所述,如果逻辑与运算的第一个操作数是false或第一个表达式的结果为false时,对于第二个操作数或表达式是否进行运算,对最终的结果没有影响,结果肯定是false。推介平时多使用&&,因为它效率更高些。
        (2)、&还可以用作位运算符。当&两边操作数或两边表达式的结果不是boolean类型时,&用于按位与运算符的操作。
088_使用final关键字修饰符一个变量时,是引用不能变,还是引用的对象不能变?
        final修饰基本类型变量,其值不能改变。
        但是final修饰引用类型变量,栈内存中的引用不能改变,但是所指向的堆内存中的对象的属性值仍旧可以改变。例如
1
2
3
4
5
6
7    class Test {
    public static void main(String[] args) {
          final Dog dog = new Dog("欧欧");
          dog.name = "美美";//正确
          dog = new Dog("亚亚");//错误
    }
}
089_请解释以下常用正则含义:\d,\D,\s,.,*,?,|,[0-9]{6},\d+
        \d: 匹配一个数字字符。等价于[0-9]
        \D: 匹配一个非数字字符。等价于[^0-9]
        \s: 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]
        . :匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
        *:匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
        +:匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
        |:将两个匹配条件进行逻辑“或”(Or)运算
        [0-9]{6}:匹配连续6个0-9之间的数字
        \d+:匹配至少一个0-9之间的数字
090_已知表达式int m[] = {0,1,2,3,4,5,6}; 下面那个表达式的值与数组的长度相等()
A.    m.length()
B.    m.length
C.    m.length()+1   
D.    m.length+1
答案:B
分析:数组的长度是.length
091_下面那些声明是合法的?()
A.    long l = 4990   
B.    int i = 4L
C.    float f = 1.1
D.    double d = 34.4
答案:AD
分析:B int属于整数型应该是int=4 C应该是float f=1.1f
092_以下选项中选择正确的java表达式()
A.    int k=new String(“aa”)  
B.    String str = String(“bb”)
C.    char c=74;
D.    long j=8888;
答案:CD
分析:A需要强制类型转换  B  String str =new String(“bb”)
093_下列代码的输出结果是
System.out.println(""+("12"=="12"&&"12".equals("12")));
(“12”==”12”&&”12”.equals(“12”))
“12”==”12”&&”12”.equals(“12”)
    true
    false
094_以下哪些运算符是含有短路运算机制的?请选择:()
A.    &  
B.    &&
C.    |
D.    ||
答案:BD
分析:A C是逻辑与计算
095_下面哪个函数是public void example(){....}的重载函数?()
A.    private void example(int  m){...}
B.    public int example(){...}
C.    public void example2(){...}
D.    public int example(int  m.float  f){...}
答案:AD
分析:BC定义的是新函数
096_给定某java程序片段,该程序运行后,j的输出结果为() 
1
2
3
4    int  i=1;
  Int  j=i++;
  If((j>++j)&&(i++==j)){j+=i:}
  System.out.println(j);

    
A.    1
B.    2
C.    3
D.    4
答案:B
分析: i++先引用后。++i 先增加后引用 
097_在java中,无论测试条件是什么,下列()循环将至少执行一次。
A.    for
B.    do...while
C.    while
D.    while...do
答案:B
分析: ACD都不一定进行循环
098_打印结果:
package com.bjsxt;
 
public class smaillT{
public static void main(String args[]){
smaillT t=new smaillT();
int b = t.get();
System.out.println(b);
}
     public int get(){
try {
return 1;
}finally{
return 2;
}
}
}
 输出结果:2
099_指出下列程序的运行结果
int i=9;
switch (i) {
default:
System.out.println("default");
case 0:
System.out.println("zero");
break;
case 1:
System.out.println("one");
break;
case 2:
System.out.println("two");
break;}
打印结果:
        default
        zero
100_解释继承、重载、覆盖。
        继承(英语:inheritance)是面向对象软件技术当中的一个概念。如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”。继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。另外,为子类别追加新的属性和方法也是常见的做法。 一般静态的面向对象编程语言,继承属于静态的,意即在子类别的行为在编译期就已经决定,无法在执行期扩充。
________________________________________
        那么如何使用继承呢?用extends关键字来继承父类。
        如上面A类与B类,当写继承语句时, class A类 extends B类{ } 其中A类是子类,B类是父类。
 
101_什么是编译型语言,什么是解释型语言?java可以归类到那种?
      计算机不能直接理解高级语言,只能理解和运行机器语言,所以必须要把高级语言翻译成机器语言,计算机才能运行高级语言所编写的程序。翻译的方式有两种,一个是编译,一个是解释。
     用编译型语言写的程序执行之前,需要一个专门的编译过程,通过编译系统把高级语言翻译成机器语言,把源高级程序编译成为机器语言文件,比如windows下的exe文件。以后就可以直接运行而不需要编译了,因为翻译只做了一次,运行时不需要翻译,所以一般而言,编译型语言的程序执行效率高。
      解释型语言在运行的时候才翻译,比如VB语言,在执行的时候,专门有一个解释器能够将VB语言翻译成机器语言,每个语句都是执行时才翻译。这样解释型语言每执行一次就要翻译一次,效率比较低。
________________________________________
     编译型与解释型,两者各有利弊。前者由于程序执行速度快,同等条件下对系统要求较低,因此像开发操作系统、大型应用程序、数据库系统等时都采用它,像C/C++、Pascal/Object Pascal(Delphi)等都是编译语言,而一些网页脚本、服务器脚本及辅助开发接口这样的对速度要求不高、对不同系统平台间的兼容性有一定要求的程序则通常使用解释性语言,如JavaScript、VBScript、Perl、Python、Ruby、MATLAB 等等。
________________________________________
      JAVA语言是一种编译型-解释型语言,同时具备编译特性和解释特性(其实,确切的说java就是解释型语言,其所谓的编译过程只是将.java文件编程成平台无关的字节码.class文件,并不是向C一样编译成可执行的机器语言,在此请读者注意Java中所谓的“编译”和传统的“编译”的区别)。作为编译型语言,JAVA程序要被统一编译成字节码文件——文件后缀是class。此种文件在java中又称为类文件。java类文件不能再计算机上直接执行,它需要被java虚拟机翻译成本地的机器码后才能执行,而java虚拟机的翻译过程则是解释性的。java字节码文件首先被加载到计算机内存中,然后读出一条指令,翻译一条指令,执行一条指令,该过程被称为java语言的解释执行,是由java虚拟机完成的。
102_简述操作符(&,|)与操作符(&&,||)的区别
&和&&的联系(共同点):
        &和&&都可以用作逻辑与运算符,但是要看使用时的具体条件来决定。
 
        情况1:当上述的操作数是boolean类型变量时,&和&&都可以用作逻辑与运算符。
        情况2:当上述的表达式结果是boolean类型变量时,&和&&都可以用作逻辑与运算符。
        表示逻辑与(and),当运算符两边的表达式的结果或操作数都为true时,整个运算结果才为true,否则,只要有一方为false,结果都为false。
________________________________________
&和&&的区别(不同点):
        (1)、&逻辑运算符称为逻辑与运算符,&&逻辑运算符称为短路与运算符,也可叫逻辑与运算符。
对于&:无论任何情况,&两边的操作数或表达式都会参与计算。
        对于&&:当&&左边的操作数为false或左边表达式结果为false时,&&右边的操作数或表达式将不参与计算,此时最终结果都为false。
         综上所述,如果逻辑与运算的第一个操作数是false或第一个表达式的结果为false时,对于第二个操作数或表达式是否进行运算,对最终的结果没有影响,结果肯定是false。推介平时多使用&&,因为它效率更高些。
        (2)、&还可以用作位运算符。当&两边操作数或两边表达式的结果不是boolean类型时,&用于按位与运算符的操作。
        |和||的区别和联系与&和&&的区别和联系类似
103_try{}里面有一个return语句,那么紧跟在这个try后的finally, 里面的语句在异常出现后,都会执行么?为什么?
        在异常处理时提供 finally 块来执行任何清除操作。
        如果有finally的话,则不管是否发生异常,finally语句都会被执行,包括遇到return语句。
        finally中语句不执行的唯一情况中执行了System.exit(0)语句。
104_有一段java应用程序,它的主类名是al,那么保存它的源文件可以是?()
A.    al.java
B.    al.class
C.    al
D.    都对
答案:A
分析:.class是java的解析文件
105_Java类可以作为()
A    类型定义机制
B.    数据封装机制
C.    类型定义机制和数据封装机制
D.    上述都不对
答案: C
106_在调用方法时,若要使方法改变实参的值,可以?()
A    用基本数据类型作为参数
B.    用对象作为参数
C.    A和B都对
D.    A和B都不对
答案:B
分析:基本数据类型不能改变实参的值
107_Java语言具有许多优点和特点,哪个反映了java程序并行机制的()
A    安全性
B.    多线性
C.    跨平台
D.    可移植
答案:BC
108_下关于构造函数的描述错误是()
A    构造函数的返回类型只能是void型
B.    构造函数是类的一种特殊函数,它的方法名必须与类名相同
C.    构造函数的主要作用是完成对类的对象的初始化工作
D.    一般在创建新对象时,系统会自动调用构造函数
答案:A
分析:构造函数的名字与类的名字相同,并且不能指定返回类型。
110_下面代码执行后的输出是什么()

1
2
3
4
5
6
7
8
9
10
11    package com.bjsxt;
public class Test {
public static void main(String[] args) {
outer: for (int i = 0; i < 3; i++)
inner: for (int j = 0; j < 2; j++) {
if (j == 1)
continue outer;
System.out.println(j + " and " + i);
}
}
}

A    0 and 0
0 and 1
0 and 2
B.    1 and 0
1 and 1
1 and 2
C.    2 and 0
2 and1
2 and 2
答案:A
111_给出如下代码,如何使成员变量m被函数fun()直接访问()
1
2
3
4
5
6
7
8    package com.bjsxt;
public class Test {
private int m;

public static void fun() {
// some code…
}
}

A    将private int m 改为 protected int m
B.    将private int m 改为 public int m
C.    将private int m 改为 static int m
D.    将private int m 改为int m
答案:C
112_下面哪几个函数是public void example(){….}的重载函数()
A    public void example(int m){…}
B.    public int example(int m){…}
C.    public void example2(){…}
D.    public int example(int m,float f){…}
答案:ABD
113_请问以下代码执行会打印出什么?
父类:
1
2
3
4
5
6
7    package com.bjsxt;
  
public class FatherClass {
public FatherClass() {
System.out.println("FatherClassCreate");
}
}

子类:
1
2
3
4
5
6
7
8
9
10
11
12    package com.bjsxt;
  
import com.bjsxt.FatherClass;
public class ChildClass extends FatherClass {
public ChildClass() {
System.out.println("ChildClass Create");
}
public static void main(String[] args) {
FatherClass fc = new FatherClass();
ChildClass cc = new ChildClass();
}
}

执行:C:\>java com.bjsxt.ChildClass
输出结果:?
答:
        FatherClassCreate
        FatherClassCreate
        ChildClass Create
114_如果有两个类A、B(注意不是接口),你想同时使用这两个类的功能,那么你会如何编写这个C类呢?
答:
        因为类A、B不是接口,所以是不可以直接实现的,但可以将A、B类定义成父子类,那么C类就能实现A、B类的功能了。假如A为B的父类,B为C的父类,此时C就能使用A、B的功能。
115_一个类的构造方法是否可以被重载(overloading),是否可以被子类重写(overrding)?
答:
        构造方法可以被重载,但是构造方法不能被重写,子类也不能继承到父类的构造方法
116_Java中byte表示的数值范围是什么?
    答: 范围是-128至127
117_如何将日期类型格式化为:2013-02-18 10:53:10?
1
2
3
4
5
6
7
8
9
10
11
12
13    public class TestDateFormat2 {
public static void main(String[] args) throws Exception {
//第一步:将字符串(2013-02-18 10:53:10)转换成日期Date
DateFormat  sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String sdate="2013-02-18 10:53:10";
Date date=sdf.parse(sdate);
System.out.println(date);
//第二步:将日期Date转换成字符串String
DateFormat  sdf2=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String sdate2=sdf2.format(date);
System.out.println(sdate2);
}
}
118_不通过构造函数也能创建对象吗()
A.    是
B.    否
分析:答案:A
Java创建对象的几种方式(重要):
(1) 用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法。
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。
119_下面哪些是对称加密算法()
A.    DES
B.    MD5
C.    DSA
D.    RSA
答案:A
分析:常用的对称加密算法有:DES、3DES、RC2、RC4、AES
常用的非对称加密算法有:RSA、DSA、ECC
使用单向散列函数的加密算法:MD5、SHA
120_下面的代码段,当输入为2的时候返回值是()
1
2
3
4
5
6
7
8
9
10
11
12    publicstaticint get Value(int i){
int result=0;
switch(i){
case 1:
result=result +i
case 2:
result=result+i*2
case 3:
result=result+i*3
}
return result;
}

A    0
B.    2
C.    4
D.    10
答案:C
分析:result = 0 + 2 * 2;
121_以下Java代码段会产生几个对象
1
2
3
4
5
6
7    publicvoid test(){
String a="a";
String b="b";
String c="c";
c=a+""+b+""+c;
System.out.print(c);
}

122_Math.round(-11.2)的运行结果是。
答案: -11
        分析:
        小数点后第一位=5
        正数:Math.round(11.5)=12
        负数:Math.round(-11.5)=-11
        小数点后第一位<5
        正数:Math.round(11.46)=11
        负数:Math.round(-11.46)=-11
        小数点后第一位>5
        正数:Math.round(11.68)=12
        负数:Math.round(-11.68)=-12
        根据上面例子的运行结果,我们还可以按照如下方式总结,或许更加容易记忆:
        参数的小数点后第一位<5,运算结果为参数整数部分。
        参数的小数点后第一位>5,运算结果为参数整数部分绝对值+1,符号(即正负)不变。
        参数的小数点后第一位=5,正数运算结果为整数部分+1,负数运算结果为整数部分。 
        终结:大于五全部加,等于五正数加,小于五全不加。
123_十进制数278的对应十六进制数
分析:十进制数278的对应十六进制数是116
124_Java中int.long占用的字节数分别是
分析:
        1:“字节”是byte,“位”是bit ;
        2: 1 byte = 8 bit ;
        char 在Java中是2个字节。java采用unicode,2个字节(16位)来表示一个字符。
        short 2个字节
        int 4个字节
        long 8个字节
125_System.out.println(‘a’+1);的结果是
分析:
        'a'是char型,1 是int行,int与char相加,char会被强转为int行,char的ASCII码对应的值是97,所以加一起打印98
126_下列语句那一个正确()
A.    java程序经编译后会产生machine code
B.    java程序经编译后会产生 byte code
C.    java程序经编译后会产生DLL
D.    以上都不正确
答案:B
分析:java程序编译后会生成字节码文件,就是.class文件
127_下列说法正确的有()
A.    class中的constructor不可省略
B.    constructor必须与class同名,但方法不能与class同名
C.    constructor在一个对象被new时执行
D.    一个class只能定义一个constructor
答案:C
128_执行如下程序代码()
a=0;c=0;
do{
——c;
a=a-1;
}while(a>0);
后,c的值是()
A.    0
B.    1
C.    -1
D.    死循环
答案:C  do{...}while(...);语句至少执行一次
129_下列哪一种叙述是正确的()
A.    abstract修饰符可修饰字段、方法和类
B.    抽象方法的body部分必须用一对大括号{}包住
C.    声明抽象方法,大括号可有可无
D.    声明抽象方法不可写出大括号
答案:D
分析: abstract不能修饰字段。既然是抽象方法,当然是没有实现的方法,根本就没有body部分。
130_下列语句正确的是()
A.    形式参数可被视为local variable
B.    形式参数可被字段修饰符修饰
C.    形式参数为方法被调用时,真正被传递的参数
D.    形式参数不可以是对象
答案A:
分析: 
A:形式参数可被视为local variable。形参和局部变量一样都不能离开方法。都只有在方法内才会发生作用,也只有在方法中使用,不会在方法外可见。
B:对于形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误。但是用这个修饰符也有一定的限制,就是在方法中不能对参数做任何修改。 不过一般情况下,一个方法的形参不用final修饰。只有在特殊情况下,那就是:方法内部类。  一个方法内的内部类如果使用了这个方法的参数或者局部变量的话,这个参数或局部变量应该是final。 
C:形参的值在调用时根据调用者更改,实参则用自身的值更改形参的值(指针、引用皆在此列),也就是说真正被传递的是实参。
D:方法的参数列表指定要传递给方法什么样的信息,采用的都是对象的形式。因此,在参数列表中必须指定每个所传递对象的类型及名字。想JAVA中任何传递对象的场合一样,这里传递的实际上也是引用,并且引用的类型必须正确。--《Thinking in JAVA》
131_成员变量用static修饰和不用static修饰有什么区别?
1,两个变量的生命周期不同。
        成员变量随着对象的创建而存在,随着对象的被回收而释放。
        静态变量随着类的加载而存在,随着类的消失而消失。
2,调用方式不同。
        成员变量只能被对象调用。
        静态变量可以被对象调用,还可以被类名调用。
        对象调用:p.country
        类名调用 :Person.country
3,别名不同。
        成员变量也称为实例变量。
        静态变量称为类变量。 
4,数据存储位置不同。
        成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据.
        静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据.
132_如果变量用final修饰,则怎样?如果方法final修饰,则怎样?
1、用final修饰的类不能被扩展,也就是说不可能有子类;
 2、用final修饰的方法不能被替换或隐藏:
        ①使用final修饰的实例方法在其所属类的子类中不能被替换(overridden);
        ②使用final修饰的静态方法在其所属类的子类中不能被重定义(redefined)而隐藏(hidden);
________________________________________
3、用final修饰的变量最多只能赋值一次,在赋值方式上不同类型的变量或稍有不同:
        ①静态变量必须明确赋值一次(不能只使用类型缺省值);作为类成员的静态变量,赋值可以在其声明中通过初始化表达式完成,也可以在静态初始化块中进行;作为接口成员的静态变量,赋值只能在其声明中通过初始化表达式完成;
        ②实例变量同样必须明确赋值一次(不能只使用类型缺省值);赋值可以在其声明中通过初始化表达式完成,也可以在实例初始化块或构造器中进行;
        ③方法参数变量在方法被调用时创建,同时被初始化为对应实参值,终止于方法体(body)结束,在此期间其值不能改变;
________________________________________
        ④构造器参数变量在构造器被调用(通过实例创建表达式或显示的构造器调用)时创建,同时被初始化
   为对应实参值,终止于构造器体结束,在此期间其值不能改变;
        ⑤异常处理器参数变量在有异常被try语句的catch子句捕捉到时创建,同时被初始化为实际的异常对象,终止于catch语句块结束,在此期间其值不能改变;
        ⑥局部变量在其值被访问之前必须被明确赋值;
133_在二进制数据中,小数点向右移一位,则数据()
A.    除以10
B.    除以2
C.    乘以2
D.    乘以10
答案:C
分析:可以看个例子
        101.1  对应的十进制为 2^2*1 + 2^1*0 + 2^0*1 + 2^-1*1 = 5.5
小数点右移一位
        1011 对应的十进制为 2^3*1 + 2^2*0 + 2^1*1 + 2^0*1 = 11
        所以是扩大到原来的2倍
134_面向对象的特征有哪些方面?
答:面向对象的特征主要有以下几个方面:
        1、抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
________________________________________
        2、继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段(如果不能理解请阅读阎宏博士的《Java与模式》或《设计模式精解》中关于桥梁模式的部分)。
________________________________________
        3、封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口(可以想想普通洗衣机和全自动洗衣机的差别,明显全自动洗衣机封装更好因此操作起来更简单;我们现在使用的智能手机也是封装得足够好的,因为几个按键就搞定了所有的事情)。
________________________________________
        4、多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供的服务,那么运行时的多态性可以解释为:当A系统访问B系统提供的服务时,B系统有多种提供服务的方式,但一切对A系统来说都是透明的(就像电动剃须刀是A系统,它的供电系统是B系统,B系统可以使用电池供电或者用交流电,甚至还有可能是太阳能,A系统只会通过B类对象调用供电的方法,但并不知道供电系统的底层实现是什么,究竟通过何种方式获得了动力)。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:1. 方法重写(子类继承父类并重写父类中已有的或抽象的方法);2. 对象造型(用父类型引用引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。
135_float f=3.4;是否正确?
答:不正确。
        3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成float f =3.4F;。
136_short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?
答:
        对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型。而short s1 = 1; s1 += 1;可以正确编译,因为s1+= 1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换。
137_Java 有没有goto?
答: 
        goto 是Java中的保留字,在目前版本的Java中没有使用。(根据James Gosling(Java之父)编写的《The Java Programming Language》一书的附录中给出了一个Java关键字列表,其中有goto和const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉C语言的程序员都知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字)
138_int 和Integer 有什么区别?
        答:Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入不是对象的基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从JDK 1.5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
________________________________________
Java 为每个原始类型提供了包装类型:
        原始类型: boolean,char,byte,short,int,long,float,double
        包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
1
2
3
4
5
6
7
8
9
10    package com.bjsxt;  
public class AutoUnboxingTest {  
    public static void main(String[] args) {  
        Integer a = new Integer(3);  
        Integer b = 3;              // 将3自动装箱成Integer类型  
        int c = 3;  
        System.out.println(a == b); // false 两个引用没有引用同一对象  
        System.out.println(a == c); // true a自动拆箱成int类型再和c比较  
    }  
}
________________________________________
补充:最近还遇到一个面试题,也是和自动装箱和拆箱相关的,代码如下所示:
1
2
3
4
5
6
7    public class Test03 {  
   public static void main(String[] args) {  
       Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;  
        System.out.println(f1 == f2);  
        System.out.println(f3 == f4);  
    }  
}
        如果不明就里很容易认为两个输出要么都是true要么都是false。首先需要注意的是f1、f2、f3、f4四个变量都是Integer对象,所以下面的==运算比较的不是值而是引用。装箱的本质是什么呢?当我们给一个Integer对象赋一个int值的时候,会调用Integer类的静态方法valueOf,如果看看valueOf的源代码就知道发生了什么。
1
2
3
4
5    public static Integer valueOf(int i) {  
       if (i >= IntegerCache.low && i <= IntegerCache.high)  
          return IntegerCache.cache[i + (-IntegerCache.low)];  
       return new Integer(i);  
   }
________________________________________
IntegerCache是Integer的内部类,其代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37    /* Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */   
    private static class IntegerCache {  
        static final int low = -128;  
        static final int high;  
        static final Integer cache[];  
        static {  
            // high value may be configured by property  
            int h = 127;  
            String integerCacheHighPropValue =  
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");  
            if (integerCacheHighPropValue != null) {  
                try {  
                    int i = parseInt(integerCacheHighPropValue);  
                    i = Math.max(i, 127);  
                    // Maximum array size is Integer.MAX_VALUE  
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);  
                } catch( NumberFormatException nfe) {  
                    // If the property cannot be parsed into an int, ignore it.  
                }  
            }  
            high = h;  
            cache = new Integer[(high - low) + 1];  
            int j = low;  
            for(int k = 0; k < cache.length; k++)  
                cache[k] = new Integer(j++);  
            // range [-128, 127] must be interned (JLS7 5.1.7)  
            assert IntegerCache.high >= 127;  
        }  
        private IntegerCache() {}  
}
________________________________________
        简单的说,如果字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面的面试题中f1==f2的结果是true,而f3==f4的结果是false。越是貌似简单的面试题其中的玄机就越多,需要面试者有相当深厚的功力。
139_&和&&的区别?
        答:
        &运算符有两种用法:(1)按位与;(2)逻辑与。&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进行运算。很多时候我们可能都需要用&&而不是&,例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为:username != null &&!username.equals(“”),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
        补充:如果你熟悉JavaScript,那你可能更能感受到短路运算的强大,想成为JavaScript的高手就先从玩转短路运算开始吧。
140_Math.round(11.5) 等于多少? Math.round(-11.5)等于多少?
        答:
        Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后进行下取整。
141_swtich 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?
        答:
        早期的JDK中,switch(expr)中,expr可以是byte、short、char、int。从1.5版开始,Java中引入了枚举类型(enum),expr也可以是枚举,从JDK 1.7版开始,还可以是字符串(String)。长整型(long)是不可以的。
142_用最有效率的方法计算2乘以8?
        答:2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)。
        补充:我们为编写的类重写hashCode方法时,可能会看到如下所示的代码,其实我们不太理解为什么要使用这样的乘法运算来产生哈希码(散列码),而且为什么这个数是个素数,为什么通常选择31这个数?前两个问题的答案你可以自己百度一下,选择31是因为可以用移位和减法运算来代替乘法,从而得到更好的性能。说到这里你可能已经想到了:31 * num <==> (num << 5) - num,左移5位相当于乘以2的5次方(32)再减去自身就相当于乘以31。现在的VM都能自动完成这个优化。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41    package com.bjsxt;  
public class PhoneNumber {  
    private int areaCode;  
    private String prefix;  
    private String lineNumber;  
   
    @Override  
    public int hashCode() {  
        final int prime = 31;  
        int result = 1;  
        result = prime * result + areaCode;  
        result = prime * result  
                + ((lineNumber == null) ? 0 : lineNumber.hashCode());  
        result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());  
        return result;  
    }  
   
    @Override  
    public boolean equals(Object obj) {  
        if (this == obj)  
            return true;  
        if (obj == null)  
            return false;  
        if (getClass() != obj.getClass())  
            return false;  
        PhoneNumber other = (PhoneNumber) obj;  
        if (areaCode != other.areaCode)  
            return false;  
        if (lineNumber == null) {  
            if (other.lineNumber != null)  
                return false;  
        } else if (!lineNumber.equals(other.lineNumber))  
            return false;  
        if (prefix == null) {  
            if (other.prefix != null)  
                return false;  
        } else if (!prefix.equals(other.prefix))  
            return false;  
        return true;  
    }  
}
143_在Java 中,如何跳出当前的多重嵌套循环?
答: 
  在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。(Java中支持带标签的break和continue语句,作用有点类似于C和C++中的goto语句,但是就像要避免使用goto一样,应该避免使用带标签的break和continue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用,所以这种语法其实不知道更好)

144_构造器(constructor)是否可被重写(override)?
        答:构造器不能被继承,因此不能被重写,但可以被重载。
145_两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
        答:不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。Java对于eqauls方法和hashCode方法是这样规定的:(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;(2)如果两个对象的hashCode相同,它们并不一定相同。当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。
________________________________________
        补充:关于equals和hashCode方法,很多Java程序都知道,但很多人也就是仅仅知道而已,在Joshua Bloch的大作《Effective Java》(很多软件公司,《Effective Java》、《Java编程思想》以及《重构:改善既有代码质量》是Java程序员必看书籍,(如果你还没看过,那就赶紧去亚马逊买一本吧)中是这样介绍equals方法的:首先equals方法必须满足自反性(x.equals(x)必须返回true)、对称性(x.equals(y)返回true时,y.equals(x)也必须返回true)、传递性(x.equals(y)和y.equals(z)都返回true时,x.equals(z)也必须返回true)和一致性(当x和y引用的对象信息没有被修改时,多次调用x.equals(y)应该得到同样的返回值),而且对于任何非null值的引用x,x.equals(null)必须返回false。
________________________________________
实现高质量的equals方法的诀窍包括:
        1. 使用==操作符检查“参数是否为这个对象的引用”;
        2. 使用instanceof操作符检查“参数是否为正确的类型”;
        3. 对于类中的关键属性,检查参数传入对象的属性是否与之相匹配;
        4. 编写完equals方法后,问自己它是否满足对称性、传递性、一致性;
        5. 重写equals时总是要重写hashCode;
        6. 不要将equals方法参数中的Object对象替换为其他的类型,在重写时不要忘掉@Override注解。
146_当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
        答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对象的引用是永远不会改变的。C++和C#中可以通过传引用或传输出参数来改变传入的参数的值。
________________________________________
        补充:Java中没有传引用实在是非常的不方便,这一点在Java 8中仍然没有得到改进,正是如此在Java编写的代码中才会出现大量的Wrapper类(将需要通过方法调用修改的引用置于一个Wrapper类中,再将Wrapper对象传入方法),这样的做法只会让代码变得臃肿,尤其是让从C和C++转型为Java程序员的开发者无法容忍。
147_重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
        答:
        Java的三大特征之一,多态机制,包括方法的多态和对象的多态;方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载(overload)发生在同一个类中,相同的方法,如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写(override)发生在子类与父类之间也就是继承机制当中,当父类的方法不能满足子类的要求,此时子类重写父类的方法;要求:方法名、形参列表相同;返回值类型和异常类型,子类小于等于父类;访问权限,子类大于等于父类,切记父类的私有方法以及被final修饰的方法不能被子类重写;重载对返回类型没有特殊的要求。
148_华为的面试题中曾经问过这样一个问题:为什么不能根据返回类型来区分重载,为什么?
        答:
        方法的重载,即使返回值类型不同,也不能改变实现功能相同或类似这一既定事实;同时方法的重载只是要求两同三不同,即在同一个类中,相同的方法名称,参数列表当中的参数类型、个数、顺序不同;跟权限修饰符和返回值类无关
149_静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?
        答:内部类就是在一个类的内部定义的类,内部类中不能定义静态成员(静态成员不是对象的特性,只是为了找一个容身之处,所以需要放到一个类中而已,这么一点小事,你还要把它放到类内部的一个类中,过分了啊!提供内部类,不是为让你干这种事情,无聊,不让你干。我想可能是既然静态成员类似c语言的全局变量,而内部类通常是用于创建内部对象用的,所以,把“全局变量”放在内部类中就是毫无意义的事情,既然是毫无意义的事情,就应该被禁止),内部类可以直接访问外部类中的成员变量,内部类可以定义在外部类的方法外面,也可以定义在外部类的方法体中,
如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21    public class Outer
{
        int out_x  = 0;
        public void method()
              {
               Inner1 inner1 = new Inner1();
               public class Inner2  //在方法体内部定义的内部类
               {
                      public method()
                      {
                             out_x = 3;
                      }
               }
               Inner2 inner2 = new Inner2();
        }
  
        public class Inner1  //在方法体外面定义的内部类
        {
        }
        
}
        在方法体外面定义的内部类的访问类型可以是public,protecte,默认的,private等4种类型,这就好像类中定义的成员变量有4种访问类型一样,它们决定这个内部类的定义对其他类是否可见;对于这种情况,我们也可以在外面创建内部类的实例对象,创建内部类的实例对象时,一定要先创建外部类的实例对象,然后用这个外部类的实例对象去创建内部类的实例对象,代码如下:
Outer outer = new Outer();
Outer.Inner1 inner1 = outer.new Innner1();
        在方法内部定义的内部类前面不能有访问类型修饰符,就好像方法中定义的局部变量一样,但这种内部类的前面可以使用final或abstract修饰符。这种内部类对其他类是不可见的其他类无法引用这种内部类,但是这种内部类创建的实例对象可以传递给其他类访问。这种内部类必须是先定义,后使用,即内部类的定义代码必须出现在使用该类之前,这与方法中的局部变量必须先定义后使用的道理也是一样的。这种内部类可以访问方法体中的局部变量,但是,该局部变量前必须加final修饰符。
        对于这些细节,只要在eclipse写代码试试,根据开发工具提示的各类错误信息就可以马上了解到。
        在方法体内部还可以采用如下语法来创建一种匿名内部类,即定义某一接口或类的子类的同时,还创建了该子类的实例对象,无需为该子类定义名称:
1
2
3
4
5
6
7
8
9
10
11    public class Outer
{
        public void start()
        {
               new Thread(
new Runable(){
                             public void run(){};
}
).start();
        }
}
        最后,在方法外部定义的内部类前面可以加上static关键字,从而成为Static Nested Class,它不再具有内部类的特性,所有,从狭义上讲,它不是内部类。Static Nested Class与普通类在运行时的行为和功能上没有什么区别,只是在编程引用时的语法上有一些差别,它可以定义成public、protected、默认的、private等多种类型,而普通类只能定义成public和默认的这两种类型。在外面引用Static Nested Class类的名称为“外部类名.内部类名”。在外面不需要创建外部类的实例对象,就可以直接创建Static Nested Class,例如,假设Inner是定义在Outer类中的Static Nested Class,那么可以使用如下语句创建Inner类:
Outer.Inner inner = newOuter.Inner();
        由于static Nested Class不依赖于外部类的实例对象,所以,static Nested Class能访问外部类的非static成员变量(不能直接访问,需要创建外部类实例才能访问非静态变量)。当在外部类中访问Static Nested Class时,可以直接使用Static Nested Class的名字,而不需要加上外部类的名字了,在Static Nested Class中也可以直接引用外部类的static的成员变量,不需要加上外部类的名字。
        在静态方法中定义的内部类也是Static Nested Class,这时候不能在类前面加static关键字,静态方法中的Static Nested Class与普通方法中的内部类的应用方式很相似,它除了可以直接访问外部类中的static的成员变量,还可以访问静态方法中的局部变量,但是,该局部变量前必须加final修饰符。
        备注:首先根据你的印象说出你对内部类的总体方面的特点:例如,在两个地方可以定义,可以访问外部类的成员变量,不能定义静态成员,这是大的特点。然后再说一些细节方面的知识,例如,几种定义方式的语法区别,静态内部类,以及匿名内部类。
        Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化,其语法看起来挺诡异的,如下所示。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67    package com.bjsxt;
/**
* 扑克类(一副扑克)
  * @author sxt
  *
 */  
public class Poker {  
    private static String[] suites = {"黑桃", "红桃", "草花", "方块"};  
    private static int[] faces = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};  
          private Card[] cards;  
    /**
      * 构造器
     */  
    public Poker() {  
        cards = new Card[52];  
        for(int i = 0; i < suites.length; i++) {  
              for(int j = 0; j < faces.length; j++) {  
                cards[i * 13 + j] = new Card(suites[i], faces[j]);  
            }  
        }  
    }  
       
    /**
          * 洗牌 (随机乱序)
          */  
    public void shuffle() {  
        for(int i = 0, len = cards.length; i < len; i++) {  
            int index = (int) (Math.random() * len);  
                   Card temp = cards[index];  
            cards[index] = cards[i];  
            cards[i] = temp;  
        }  
    }  
     /**
     * 发牌
     * @param index 发牌的位置
     */  
    public Card deal(int index) {  
        return cards[index];  
    }  
       
    /**
     * 卡片类(一张扑克)
     * [内部类]
     * @author sxt
     */  
    public class Card {  
  private String suite;   // 花色  
        private int face;       // 点数  
  public Card(String suite, int face) {  
            this.suite = suite;  
            this.face = face;  
       }  
        @Override  
        public String toString() {  
            String faceStr = "";  
            switch(face) {  
                  case 1: faceStr = "A"; break;  
            case 11: faceStr = "J"; break;  
            case 12: faceStr = "Q"; break;  
            case 13: faceStr = "K"; break;  
            default: faceStr = String.valueOf(face);  
            }  
            return suite + faceStr;  
        }  
    }  
}
测试类:  
1
2
3
4
5
6
7
8
9
10
11
12
13    package com.bjsxt;
class PokerTest {  
   public static void main(String[] args) {  
        Poker poker = new Poker();  
        poker.shuffle();            // 洗牌  
        Poker.Card c1 = poker.deal(0);  // 发第一张牌  
              // 对于非静态内部类Card  
        // 只有通过其外部类Poker对象才能创建Card对象  
        Poker.Card c2 = poker.new Card("红心", 1);    // 自己创建一张牌  
        System.out.println(c1);     // 洗牌后的第一张  
        System.out.println(c2);     // 打印: 红心A  
    }  
}
150_抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?
        答:都不能。
        抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
151_静态变量和实例变量的区别?
        答:静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它,静态变量可以实现让多个对象共享内存。
        两者的相同点:都有默认值而且在类的任何地方都可以调用。在Java开发中,上下文类和工具类中通常会有大量的静态成员。
152_是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?    
        答:不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,因此在调用静态方法时可能对象并没有被初始化。 
153_如何实现对象克隆?
答:有两种方式:
        1.实现Cloneable接口并重写Object类中的clone()方法;
        2.实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下。
下面是测试代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88    package com.bjsxt;
import java.io.Serializable;  
/**
 * 人类
 * @author sxt 
*/  
class Person implements Serializable {  
    private static final long serialVersionUID = -9102017020286042305L;  
    private String name;    // 姓名  
    private int age;        // 年龄  
    private Car car;        // 座驾  
   
    public Person(String name, int age, Car car) {  
        this.name = name;  
        this.age = age;  
        this.car = car;  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    public int getAge() {  
        return age;  
    }  
    public void setAge(int age) {  
        this.age = age;  
    }  
    public Car getCar() {  
        return car;  
    }  
    public void setCar(Car car) {  
        this.car = car;  
    }  
    @Override  
    public String toString() {  
     return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";  
    }  
  }  
  /**
 * 小汽车类
 * @author sxt
*/  
class Car implements Serializable {  
    private static final long serialVersionUID = -5713945027627603702L;  
    private String brand;       // 品牌  
    private int maxSpeed;       // 最高时速  
   
    public Car(String brand, int maxSpeed) {  
        this.brand = brand;  
        this.maxSpeed = maxSpeed;  
    }  
    public String getBrand() {  
        return brand;  
    }  
    public void setBrand(String brand) {  
        this.brand = brand;  
    }  
    public int getMaxSpeed() {  
        return maxSpeed;  
    }  
   
    public void setMaxSpeed(int maxSpeed) {  
        this.maxSpeed = maxSpeed;  
    }  
   
    @Override  
    public String toString() {  
        return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]";  
    }  
  }  
   
class CloneTest {  
  public static void main(String[] args) {  
        try {  
            Person p1 = new Person("Hao LUO", 33, new Car("Benz", 300));  
            Person p2 = MyUtil.clone(p1);   // 深度克隆  
            p2.getCar().setBrand("BYD");  
            // 修改克隆的Person对象p2关联的汽车对象的品牌属性  
            // 原来的Person对象p1关联的汽车不会受到任何影响  
            // 因为在克隆Person对象时其关联的汽车对象也被克隆了  
            System.out.println(p1);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}
注意:基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用Object类的clone方法克隆对象。
154_接口是否可继承(extends)接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)?
        答:接口可以继承接口。抽象类可以实现(implements)接口,抽象类可以继承具体类。抽象类中可以有静态的main方法。
        备注:只要明白了接口和抽象类的本质和作用,这些问题都很好回答,你想想,如果你是java语言的设计者,你是否会提供这样的支持,如果不提供的话,有什么理由吗?如果你没有道理不提供,那答案就是肯定的了。
         只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstract方法。
155_一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制?
        答:可以,但一个源文件中最多只能有一个公开类(public class)而且文件名必须和公开类的类名完全保持一致。
156_Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?
        答:可以继承其他类或实现其他接口,在Swing编程中常用此方式来实现事件监听和回调。 但是有一点需要注意,它只能继承一个类或一个接口。
157_内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?
        答:一个内部类对象可以访问创建它的外部类对象的成员,包括私有成员。
        如果要访问外部类的局部变量,此时局部变量必须使用final修饰,否则无法访问。
158_Java 中的final关键字有哪些用法?
答:
        (1)修饰类:表示该类不能被继承;
        (2)修饰方法:表示方法不能被重写但是允许重载;
        (3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量);
        (4)修饰对象:对象的引用地址不能变,但是对象的初始化值可以变。
159_指出下面程序的运行结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24    package com.bjsxt;
class A{  
  static{  
        System.out.print("1");  
    }  
  public A(){  
        System.out.print("2");  
    }  
}  
class B extends A{  
  static{  
        System.out.print("a");  
    }  
    public B(){  
        System.out.print("b");  
    }  
}  
   
public class Hello{  
  public static void main(String[] args){  
        A ab = new B();  
        ab = new B();  
    }  
}
        考点:静态代码块优先级   >   构造方法的优先级
        答:执行结果:1a2b2b。创建对象时构造器的调用顺序是:先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器。 
        如果再加一个普通代码块,优先顺序如下:
        静态代码块>普通代码块>构造方法
160_说说数据类型之间的转换:
        1)如何将字符串转换为基本数据类型?
        2)如何将基本数据类型转换为字符串?
        答:
        1)调用基本数据类型对应的包装类中的方法parseXXX(String)或valueOf(String)即可返回相应基本类型;
        2)一种方法是将基本数据类型与空字符串(””)连接(+)即可获得其所对应的字符串;另一种方法是调用String 类中的valueOf(…)方法返回相应字符串 
161_如何实现字符串的反转及替换?
        答:方法很多,可以自己写实现也可以使用String或StringBuffer / StringBuilder中的方法。有一道很常见的面试题是用递归实现字符串反转,代码如下所示:
1
2
3
4
5
6
7
8    package com.bjsxt;
public class A{  
    public static String reverse(String originStr) {  
 if(originStr == null || originStr.length() <= 1)   
     return originStr;  
       return reverse(originStr.substring(1)) + originStr.charAt(0);  
     }  
}
162_怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?
答:代码如下所示:
String s1 = "你好";
String s2 = newString(s1.getBytes("GB2312"), "ISO-8859-1"); 
在String类的构造方法当中,存在一个字符集设置的方法,具体如下:
163_Java中的日期和时间:
        1)如何取得年月日、小时分钟秒?
        2)如何取得从1970年1月1日0时0分0秒到现在的毫秒数?
        3)如何取得某月的最后一天?
        4)如何格式化日期?
答:操作方法如下所示:
        1)创建java.util.Calendar 实例,调用其get()方法传入不同的参数即可获得参数所对应的值
        2)以下方法均可获得该毫秒数:
1
2    Calendar.getInstance().getTimeInMillis();  
System.currentTimeMillis();
        3)示例代码如下:
1
2    Calendar time = Calendar.getInstance();  
time.getActualMaximum(Calendar.DAY_OF_MONTH);
        4)利用java.text.DataFormat 的子类(如SimpleDateFormat类)中的format(Date)方法可将日期格式化。
164_打印昨天的当前时刻。
        答:
1
2
3
4
5
6
7
8
9    package com.bjsxt;
import java.util.Calendar;
public class YesterdayCurrent {  
      public static void main(String[] args){  
           Calendar cal = Calendar.getInstance();  
           cal.add(Calendar.DATE, -1);  
           System.out.println(cal.getTime());  
     }  
}
165_Java反射技术主要实现类有哪些,作用分别是什么?
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中
        1)Class类:代表一个类
        2)Field 类:代表类的成员变量(属性)
        3)Method类:代表类的成员方法
        4)Constructor 类:代表类的构造方法
        5)Array类:提供了动态创建数组,以及访问数组的元素的静态方法
166_Class类的作用?生成Class对象的方法有哪些?
        Class类是Java 反射机制的起源和入口,用于获取与类相关的各种信息,提供了获取类信息的相关方法。Class类继承自Object类
        Class类是所有类的共同的图纸。每个类有自己的对象,好比图纸和实物的关系;每个类也可看做是一个对象,有共同的图纸Class,存放类的  结构信息,能够通过相应方法取出相应信息:类的名字、属性、方法、构造方法、父类和接口
 
167_反射的使用场合和作用、及其优缺点
1)使用场合:
        在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息。
2)主要作用:
        通过反射可以使程序代码访问装载到JVM 中的类的内部信息,获取已装载类的属性信息,获取已装载类的方法,获取已装载类的构造方法信息
3)反射的优点
        反射提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类;反射是其它一些常用语言,如C、C++、Fortran 或者Pascal等都不具备的
4) Java反射技术应用领域很广,如软件测试等;许多流行的开源框架例如Struts、Hibernate、Spring在实现过程中都采用了该技术
5)反射的缺点
        性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此Java反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。
使用反射会模糊程序内部逻辑:程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。
168_面向对象设计原则有哪些
        面向对象设计原则是面向对象设计的基石,面向对象设计质量的依据和保障,设计模式是面向对象设计原则的经典应用
        1)单一职责原则SRP
        2)开闭原则OCP
        3)里氏替代原则LSP
        4)依赖注入原则DIP
        5)接口分离原则ISP
        6)迪米特原则LOD
        7)组合/聚合复用原则CARP
        8)开闭原则具有理想主义的色彩,它是面向对象设计的终极目标。其他设计原则都可以看作是开闭原则的实现手段或方法
Spring相关的
169_下面程序的运行结果是()(选择一项)
1
2
3    String str1="hello";
String str2=new String("hello");
System.out.println(str1==str2);

    
A.    true
B.    false
C.    hello
D.    he
答案:B
分析:str1没有使用new关键字,在堆中没有开辟空间,其值”hello”在常量池中,str2使用new关键字创建了一个对象,在堆中开辟了空间,”==”比较的是对象的引用,即内存地址,所以str1与str2两个对象的内存地址是不相同的
170_Java语言中,String类中的indexOf()方法返回值的类型是()
A.    int16
B.    int32
C.    int
D.    long 
答案:C 
171_给定以下代码,程序的运行结果是 ()(选择一项)
1
2
3
4
5
6
7
8
9
10
11
12
13
14    public class Example {
String str=new String("good");
char [] ch={'a','b','c'};
public static void main(String[] args) {
Example ex=new Example();
ex.change(ex.str, ex.ch);
System.out.print(ex.str+"and");
System.out.print(ex.ch);
}
public void change(String  str,char ch[]){
str="test ok";
ch[0]='g';
}
}

A    goodandabc
B.    goodandgbc
C.    test okandabc
D.    test okandgbc
答案:B
分析:在方法调用时,在change方法中对str的值进行修改,是将str指向了常量江池中的”test ok”,而主方法中的ex.str仍然指向的是常量池中的”good”。字符型数组在方法调用时,将主方法中ex.ch的引用传递给change方法中的ch,指向是堆中的同一堆空间,所以修改ch[0]的时候,ex.ch可以看到相同的修改后的结果。 
172_执行下列代码后,哪个结论是正确的()(选择两项)
String[] s=new String[10];
A.    s[10]为””
B.    s[9]为null
C.    s[0]为未定义
D.    s.length为10
答案:BD
分析: 引用数据类型的默认值均为null
       s.length数组的长度 
173_实现String类的replaceAll方法
        思路说明:replaceAll方法的本质是使用正则表达式进行匹配,最终调用的其实是Matcher对象的replaceAll方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23    import java.util.regex.Matcher;
import java.util.regex.Pattern;
  
public class TestStringReplaceAll {
public static void main(String[] args) {
String str = "a1s2d3f4h5j6k7";
// 将字符串中的数字全部替换为0
System.out.println(replaceAll(str, "\\d", "0"));
}
  
/**
 * @param str:源字符串
 * @param regex:正则表达式
 * @param newStr:替换后的子字符串
 * @return 返回替换成功后的字符串
 */
public static String replaceAll(String str, String regex, String newStr) {
Pattern pattern = Pattern.compile(regex);
Matcher mathcer = pattern.matcher(str);
String reslut = mathcer.replaceAll(newStr);
return reslut;
}
}
174_在“=”后填写适当的内容:
String []a=new String[10];
则:a[0]~a[9]=null;
a.length=10;
如果是int[]a=new int[10];
则:    a[0]~a[9]= (0)
a.length= (10)
175_是否可以继承String类?
答:
        不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。
        public final class String implements java.io.Serializable, 
        Comparable<String>, CharSequence 
176_给定两个字符串s和t,  写一个函数来决定是否t是s的重组词。你可以假设字符串只包含小写字母。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16       public boolean isAnagram(String s, String t) {public class Solution {
        if(s.length()!=t.length())
            return false;
        int bit[] = new int[26];
        for(int i=0;i<s.length();i++){
            bit[s.charAt(i)-'a']++;
        }
  
        for(int i=0;i<s.length();i++){
            if(--bit[t.charAt(i)-'a']<0)
                return false;
        }
        return true;
    }
  
}
177_String s=new String(“abc”);创建了几个String对象。
        两个或一个,”abc”对应一个对象,这个对象放在字符串常量缓冲区,常量”abc”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,它一句那个常量”abc”对象的内容来创建出一个新String对象。如果以前就用过’abc’,这句代表就不会创建”abc”自己了,直接从缓冲区拿
178_输出结果?
1
2
3
4    String str1=“hello”;
Sring str2=“he”+new String(“llo”);
Sysem.out.println(str1==str2));
Sysem.out.println(str.equal(str2));
        false
        true
179_下列程序的输出结果是什么?
1
2
3
4
5
6
7
8
9    import java.util.*;
public class Test 6{
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Integer k=new Integer(i);
System.out.println(k+" Hello world");
}
}
}
0 Hello world
1 Hello world
2 Hello world
3 Hello world
4 Hello world
5 Hello world
6 Hello world
7 Hello world
8 Hello world
9 Hello world
180_关于java.lang.String类,以下描述正确的一项是()
A.    String类是final类故不可继承
B.    String类final类故可以继承
C.    String类不是final类故不可继承
D.    String;类不是final类故可以继承
答案:A
181_下面哪个是正确的()
A.    String temp[ ] = new String{“a”,”b”,”c”};
B.    String temp[ ] = {“a”,”b”,”c”};
C.    String temp= {“a”,”b”,”c”};
D.    String[ ] temp = {“a”,”b”,”c”};
答案:BD
182_已知如下代码:执行结果是什么()
1
2
3
4
5
6
7
8
9
10
11
12
13
14    package com.bjsxt;
public class Test {
public static void main(String[] args) {
String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.print(s1 == s2);
String s3 = "Hello";
String s4 = "Hello";
System.out.print(s3 == s4);
s1 = s3;
s2 = s4;
System.out.print(s1 == s2);
}
}

A    false true true
B.    true false true
C.    true true false
D.    true true false
答案:A
183_字符串如何转换为int类型
1
2
3
4
5
6
7
8
9    public class Test {
public static void main(String[] args) {
         //方式一
         int num=Integer.parseInt("123");
         //方式二
         int num2=Integer.valueOf("123");
         System.out.println(num+"  "+num2);
}
}
184_写一个方法,实现字符串的反转,如:输入abc,输出cba
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15    public class Test {
public static void main(String[] args) {
String result=reverse("abc");
System.out.println(result);
}
public static String reverse(String str){
StringBuilder result=new StringBuilder("");
char[] chArra=str.toCharArray();
for(int i=chArra.length-1;i>=0;i--){
char ch=chArra[i];
result.append(ch);
}
return result.toString();
}
}
185_编写java,将“I follow Bill Gate.Tom Gate.John Gate”中的“Gate”全部替换为“Gates”
1
2
3
4
5
6
7
8    public classDemo1 {
public static void main(String[] args) {
String s="I follow Bill Gate.Tom Gate.John Gate";
System.out.println(s);
s=s.replaceAll("Gate","Gates");
System.out.println(s);
}
}
186_String 是最基本的数据类型吗?
        答:不是。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type)和枚举类型(enumeration type),剩下的都是引用类型(reference type)。
187_String 和StringBuilder、StringBuffer 的区别?
       答:Java 平台提供了两种类型的字符串:String和StringBuffer / StringBuilder,
相同点:
        它们都可以储存和操作字符串,同时三者都使用final修饰,都属于终结类不能派生子类,操作的相关方法也类似例如获取字符串长度等;
不同点:
        其中String是只读字符串,也就意味着String引用的字符串内容是不能被改变的,而StringBuffer和StringBuilder类表示的字符串对象可以直接进行修改,在修改的同时地址值不会发生改变。StringBuilder是JDK 1.5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer略高。在此重点说明一下,String、StringBuffer、StringBuilder三者类型不一样,无法使用equals()方法比较其字符串内容是否一样!
补充1:
        有一个面试题问:有没有哪种情况用+做字符串连接比调用StringBuffer / StringBuilder对象的append方法性能更好?如果连接后得到的字符串在静态存储区中是早已存在的,那么用+做字符串连接是优于StringBuffer / StringBuilder的append方法的。
补充2:下面也是一个面试题,问程序的输出,看看自己能不能说出正确答案。
1
2
3
4
5
6
7
8
9
10
11
12
13    package com.bjsxt;
public class smallT {  
public static void main(String[] args) {  
           String a = "Programming";  
           String b = new String("Programming");  
           String c = "Program" + "ming";  
              System.out.println(a == b);  
              System.out.println(a == c);  
               System.out.println(a.equals(b));  
               System.out.println(a.equals(c));  
               System.out.println(a.intern() == b.intern());  
}  
}
解析:
        String类存在intern()方法,含义如下:返回字符串对象的规范化表示形式。它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
字符串比较分为两种形式,一种使用比较运算符”==”比较,他们比较的是各自的字符串在内存当中的地址值是否相同;一种是使用equals()方法进行比较,比较的是两个字符串的内容是否相同!
 
结果如下:
a == b-->false
a == c-->true
a.equals(b)-->true
a.equals(c)-->true
a.intern() == b.intern()-->true
188_String类为什么是final的
答:
        1)为了效率。若允许被继承,则其高度的 被使用率可能会降低程序的性能。
        2)为了安全。JDK中提供的好多核心类比如String,这类的类的内部好多方法的实现都不是java编程语言本身编写的,好多方法都是调用的操作系统本地的API,这就是著名的“本地方法调用”,也只有这样才能做事,这种类是非常底层的, 和操作系统交流频繁的,那么如果这种类可以被继承的话,如果我们再把它的方法重写了,往操作系统内部写入一段具有恶意攻击性质的代码什么的, 这不就成了核心病毒了么?
        不希望别人改,这个类就像一个工具一样,类的提供者给我们提供了, 就希望我们直接用就完了,不想让我们随便能改,其实说白了还是安全性, 如果随便能改了,那么java编写的程序肯定就很不稳定,你可以保证自己不乱改, 但是将来一个项目好多人来做,管不了别人,再说有时候万一疏忽了呢?他也不是估计的, 所以这个安全性是很重要的,java和C++相比,优点之一就包括这一点; 
189_String类型是基本数据类型吗?基本数据类型有哪些
        1)基本数据类型包括byte、short/char、int、long、float、double、boolean
        2)java.lang.String类是引用数据类型,并且是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类
190_String s="Hello";s=s+"world!";执行后,是否是对前面s指向空间内容的修改?
答:不是对前面s指向空间内容的直接修改。
        因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是 "Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。
        通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。

________________________________________
        同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:

1
2
3
4
5
6
7
8    public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非

1    s = new String("Initial Value");
        后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。

________________________________________
        上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。
至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即 StringBuffer。
191_String s = new String("xyz");创建几个String Object?
        答:两个或一个,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,它一句那个常量”xyz”对象的内容来创建出一个新String对象。如果以前就用过’xyz’,这句代表就不会创建”xyz”自己了,直接从缓冲区拿。
192_下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d";
答:
对于如下代码:
1
2
3
4
5    String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
        第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。
        题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个”abcd”的字符串,所以,上面的代码应该只创建了一个String对象。写如下两行代码,
1
2    String s = "a" + "b" + "c" + "d";
System.out.println(s == "abcd");
        最终打印的结果应该为true。
集合
193_Java集合体系结构(List、Set、Collection、Map的区别和联系)
________________________________________
 
 
1、Collection 接口存储一组不唯一,无序的对象
2、List 接口存储一组不唯一,有序(插入顺序)的对象
3、Set 接口存储一组唯一,无序的对象
4、Map接口存储一组键值对象,提供key到value的映射。Key无序,唯一。value不要求有序,允许重复。(如果只使用key存储,而不使用value,那就是Set)
194_Vector和ArrayList的区别和联系
相同点:
        1)实现原理相同---底层都使用数组
        2)功能相同---实现增删改查等操作的方法相似
        3)都是长度可变的数组结构,很多情况下可以互用
不同点:
        1)Vector是早期JDK版本提供,ArrayList是新版本替代Vector的
        2)Vector线程安全,ArrayList重速度轻安全,线程非安全
        长度需增长时,Vector默认增长一倍,ArrayList增长50%
195_ArrayList和LinkedList的区别和联系
相同点:
        两者都实现了List接口,都具有List中元素有序、不唯一的特点。
不同点:
        ArrayList实现了长度可变的数组,在内存中分配连续空间。遍历元素和随机访问元素的效率比较高;
 
        LinkedList采用链表存储方式。插入、删除元素时效率比较高
 
196_HashMap和Hashtable的区别和联系
相同点:
        实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在很多情况下可以互用
不同点:
        1、Hashtable是早期提供的接口,HashMap是新版JDK提供的接口
        2、Hashtable继承Dictionary类,HashMap实现Map接口
        3、Hashtable线程安全,HashMap线程非安全
        4、Hashtable不允许null值,HashMap允许null值
197_HashSet的使用和原理(hashCode()和equals()) 
        1)哈希表的查询速度特别快,时间复杂度为O(1)。
        2)HashMap、Hashtable、HashSet这些集合采用的是哈希表结构,需要用到hashCode哈希码,hashCode是一个整数值。
        3)系统类已经覆盖了hashCode方法 自定义类如果要放入hash类集合,必须重写hashcode。如果不重写,调用的是Object的hashcode,而Object的hashCode实际上是地址。
        4)向哈希表中添加数据的原理:当向集合Set中增加对象时,首先集合计算要增加对象的hashCode码,根据该值来得到一个位置用来存放当前对象,如在该位置没有一个对象存在的话,那么集合Set认为该对象在集合中不存在,直接增加进去。如果在该位置有一个对象存在的话,接着将准备增加到集合中的对象与该位置上的对象进行equals方法比较,如果该equals方法返回false,那么集合认为集合中不存在该对象,在进行一次散列,将该对象放到散列后计算出的新地址里。如果equals方法返回true,那么集合认为集合中已经存在该对象了,不会再将该对象增加到集合中了。
        5)在哈希表中判断两个元素是否重复要使用到hashCode()和equals()。hashCode决定数据在表中的存储位置,而equals判断是否存在相同数据。
        6) Y=K(X) :K是函数,X是哈希码,Y是地址
198_TreeSet的原理和使用(Comparable和comparator)
        1)TreeSet集合,元素不允许重复且有序(自然顺序)
        2)TreeSet采用树结构存储数据,存入元素时需要和树中元素进行对比,需要指定比较策略。
        3)可以通过Comparable(外部比较器)和Comparator(内部比较器)来指定比较策略,实现了Comparable的系统类可以顺利存入TreeSet。自定义类可以实现Comparable接口来指定比较策略。
        4)可创建Comparator接口实现类来指定比较策略,并通过TreeSet构造方法参数传入。这种方式尤其对系统类非常适用。
199_集合和数组的比较(为什么引入集合)
        数组不是面向对象的,存在明显的缺陷,集合完全弥补了数组的一些缺点,比数组更灵活更实用,可大大提高软件的开发效率而且不同的集合框架类可适用于不同场合。具体如下:
        1)数组的效率高于集合类.
        2)数组能存放基本数据类型和对象,而集合类中只能放对象。
        3)数组容量固定且无法动态改变,集合类容量动态改变。
        4)数组无法判断其中实际存有多少元素,length只告诉了array的容量。
        5)集合有多种实现方式和不同的适用场合,而不像数组仅采用顺序表方式。
        6)集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性调用即可实现各种复杂操作,大大提高软件的开发效率。
200_Collection和Collections的区别
        1)Collection是Java提供的集合接口,存储一组不唯一,无序的对象。它有两个子接口List和Set。
        2)Java中还有一个Collections类,专门用来操作集合类 ,它提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
201_下列说法正确的有()(选择一项)
A.    LinkedList继承自List
B.    AbstractSet继承自Set
C.    HashSet继承自AbstractSet
D.    TreeMap继承自HashMap
答案: C
分析:A:LinkedList实现List接口
      B:AbstractSet实现Set接口
      D:TreeMap继承AbstractMap 
202_Java的HashMap和Hashtable有什么区别HashSet和HashMap有什么区别?使用这些结构保存的数需要重载的方法是哪些?
________________________________________
答:
        HashMap与Hashtable实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在很多情况下可以互用
两者的主要区别如下:
        1、Hashtable是早期JDK提供的接口,HashMap是新版JDK提供的接口
        2、Hashtable继承Dictionary类,HashMap实现Map接口
        3、Hashtable线程安全,HashMap线程非安全
        4、Hashtable不允许null值,HashMap允许null值
________________________________________
HashSet与HashMap的区别:
        1、HashSet底层是采用HashMap实现的。HashSet 的实现比较简单,HashSet 的绝大部分方法都是通过调用 HashMap 的方法来实现的,因此 HashSet 和 HashMap 两个集合在实现本质上是相同的。
        2、HashMap的key就是放进HashSet中对象,value是Object类型的。
        3、当调用HashSet的add方法时,实际上是向HashMap中增加了一行(key-value对),该行的key就是向HashSet增加的那个对象,该行的value就是一个Object类型的常量
203_列出Java中的集合类层次结构?
答:
        Java中集合主要分为两种:Collection和Map。Collection是List和Set接口的父接口;ArrayList和LinkedList是List的实现类;HashSet和TreeSet是Set的实现类;LinkedHashSet是HashSet的子类。HashMap和TreeMap是Map的实现类;LinkedHashMap是HashMap的子类。
图中:虚线框中为接口,实线框中为类。
 
204_List,Set,Map各有什么特点
答:
        List 接口存储一组不唯一,有序(插入顺序)的对象。
        Set 接口存储一组唯一,无序的对象。
        Map接口存储一组键值对象,提供key到value的映射。key无序,唯一。value不要求有序,允许重复。(如果只使用key存储,而不使用value,那就是Set)。
205_ArrayList list=new ArrayList(20);中的list扩充几次()
A    0
B.    1
C.    2
D.    3
答案:A
分析:已经指定了长度, 所以不扩容
206_List、Set、Map哪个继承自Collection接口,一下说法正确的是()
A    List Map
B.    Set Map
C.    List Set
D.    List Map Set
答案:C
分析:Map接口继承了java.lang.Object类,但没有实现任何接口.
207_合并两个有序的链表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24    public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null || l2 == null) {  
                     return l1 != null ? l1 : l2;  
              }  
              ListNode head = l1.val < l2.val ? l1 : l2;  
              ListNode other = l1.val >= l2.val ? l1 : l2;  
              ListNode prevHead = head;  
              ListNode prevOther = other;  
              while (prevHead != null) {  
                    ListNode next = prevHead.next;  
                    if (next != null && next.val > prevOther.val) {  
                            prevHead.next = prevOther;  
                            prevOther = next;  
                    }  
                    if(prevHead.next==null){  
                           prevHead.next=prevOther;  
                           break;  
                    }  
                    prevHead=prevHead.next;  
               }  
               return head;
}
}
208_用递归方式实现链表的转置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18    /**
Definition for singly-linked list.
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseList(ListNode head) {
if(head==null||head.next ==null)
              return head;
            ListNode prev = reverseList(head.next);
            head.next.next = head;
            head.next = null;
            return prev;
}
}
209_给定一个不包含相同元素的整数集合,nums,返回所有可能的子集集合。解答中集合不能包含重复的子集。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22      
public class Solution {
    public List<List<Integer>> subsets (int[] nums) {
        List<List<Integer>> res = new ArrayList<ArrayList<Integer>>();
        List<Integer> item = new ArrayList<Integer>();
        if(nums.length == 0 || nums == null)
            return res;
        Arrays.sort(nums); //排序
        dfs(nums, 0, item, res);  //递归调用
        res.add(new ArrayList<Integer>());  //最后加上一个空集
        return res;
    }
    public static void dfs(int[] nums, int start, List<Integer> item, List<List<Integer>> res){
        for(int i = start; i < nums.length; i ++){
            item.add(nums[i]);
            //item是以整数为元素的动态数组,而res是以数组为元素的数组,在这一步,当item增加完元素后,item所有元素构成一个完整的子串,再由res纳入
            res.add(new ArrayList<Integer>(item));
            dfs(nums, i + 1, item, res);
            item.remove(item.size() - 1);
        }
    }
}
210_以下结构中,哪个具有同步功能()
A.    HashMap
B.    ConcurrentHashMap
C.    WeakHashMap
D.    TreeMap
答案:B
分析:
A,C,D都线程不安全,B线程安全,具有同步功能
211_以下结构中,插入性能最高的是()
A    ArrayList
B.    Linkedlist
C.    tor
D.    Collection
答案:B
分析:
数组插入、删除效率差,排除A
tor不是java里面的数据结构,是一种网络路由技术;因此排除C
Collection 是集合的接口,不是某种数据结构;因此排除D
212_以下结构中,哪个最适合当作stack使用()
A    LinkedHashMap
B.    LinkedHashSet
C.    LinkedList
答案:C
分析:
Stack是先进后出的线性结构;所以链表比较合适;不需要散列表的数据结构
213_Map的实现类中,哪些是有序的,哪些是无序的,有序的是如何保证其有序性,你觉得哪个有序性性能更高,你有没有更好或者更高效的实现方式?
答:
        1.Map的实现类有HashMap,LinkedHashMap,TreeMap
        2.HashMap是有无序的,LinkedHashMap和TreeMap都是有序的(LinkedHashMap记录了添加数据的顺序;TreeMap默认是自然升序)
        3. LinkedHashMap底层存储结构是哈希表+链表,链表记录了添加数据的顺序
        4. TreeMap底层存储结构是二叉树,二叉树的中序遍历保证了数据的有序性
        5. LinkedHashMap有序性能比较高,因为底层数据存储结构采用的哈希表
214_下面的代码在绝大部分时间内都运行得很正常,请问什么情况下会出现问题?根源在哪里?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19    package com.bjsxt;
import java.util.LinkedList;
public class Stack {
LinkedList list = new LinkedList();
public synchronized void push(Object x) {
synchronized (list) {
list.addLast(x);
notify();
}
}
public  synchronized Object pop() throws  Exception{
synchronized(list){
If(list.size()<=0){
wait();
}
return list.removeLast( );
}
}
}
答:
        将if( list.size() <= 0 )  
改成:
        while( list.size() <= 0 )
215_TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
答:
        TreeSet要求存放的对象所属的类必须实现Comparable接口,该接口提供了比较元素的compareTo()方法,当插入元素时会 回调该方法比较元素的大小。TreeMap要求存放的键值对映射的键必须实现Comparable接口从而根据键对元素进行排序。
        Collections 工具类的sort方法有两种重载的形式,第一种要求传入的待排序容器中存放的对象比较实现Comparable接口以实现元素的比较;第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator接口的子类型(需要重写compare方法实现元素的比较),相当于一个临时定义的排序规则,其实就是是通过接口注入比较元素大小的算法,也是对回调模式的应用。
216_List里面如何剔除相同的对象?请简单用代码实现一种方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17    public class Test {
public static void main(String[] args) {
             List<String> li1 = new ArrayList<String>();
             li1.add("8");
             li1.add("8");
             li1.add("9");
             li1.add("9");
li1.add("0");
             System.out.println(li1);
            //方法:将List中数据取出来来存到Set中
            HashSet<String> set = new HashSet<String>();
            for(int i=0;i<li1.size();i++){
                set.add(li1.get(i));
            }
            System.out.println(set);
}
}
217_Java.util.Map的实现类有
分析:Java中的java.util.Map的实现类
        1、HashMap
        2、Hashtable
        3、LinkedHashMap
        4、TreeMap
218_下列叙述中正确的是()
A.    循环队列有队头和队尾两个指针,因此,循环队列是非线性结构
B.    在循环队列中,只需要队头指针就能反映队列中元素的动态变化情况
C.    在循环队列中,只需要队尾指针就能反映队列中元素的动态变化情况
D.    在循环队列中元素的个数是由队头指针和队尾指针共同决定的
答案:D
分析:
循环队列中元素的个数是由队首指针和队尾指针共同决定的,元素的动态变化也是通过队首指针和队尾指针来反映的,当队首等于队尾时,队列为空。
219_List、Set、Map 是否继承自Collection 接口?
答:List、Set 的父接口是Collection,Map 不是其子接口,而是与Collection接口是平行关系,互不包含。
  
Map是键值对映射容器,与List和Set有明显的区别,而Set存储的零散的元素且不允许有重复元素(数学中的集合也是如此),List是线性结构的容器,适用于按数值索引访问元素的情形。 
220_说出ArrayList、Vector、LinkedList 的存储性能和特性?
        答:ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized 方法(线程安全),通常性能上较ArrayList 差,而LinkedList 使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,其实对内存的利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。Vector属于遗留容器(早期的JDK中使用的容器,除此之外Hashtable、Dictionary、BitSet、Stack、Properties都是遗留容器),现在已经不推荐使用,但是由于ArrayList和LinkedListed都是非线程安全的,如果需要多个线程操作同一个容器,那么可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器后再使用(这其实是装潢模式最好的例子,将已有对象传入另一个类的构造器中创建新的对象来增加新功能)。
________________________________________
        补充:遗留容器中的Properties类和Stack类在设计上有严重的问题,Properties是一个键和值都是字符串的特殊的键值对映射,在设计上应该是关联一个Hashtable并将其两个泛型参数设置为String类型,但是Java API中的Properties直接继承了Hashtable,这很明显是对继承的滥用。这里复用代码的方式应该是HAS-A关系而不是IS-A关系,另一方面容器都属于工具类,继承工具类本身就是一个错误的做法,使用工具类最好的方式是HAS-A关系(关联)或USE-A关系(依赖)。同理,Stack类继承Vector也是不正确的。 
221_List、Map、Set 三个接口,存取元素时,各有什么特点?
        答:List以特定索引来存取元素,可有重复元素。
        Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)。Map保存键值对(key-value pair)映射,映射关系可以是一对一或多对一。Set和Map容器都有基于哈希存储和排序树(红黑树)的两种实现版本,基于哈希存储的版本理论存取时间复杂度为O(1),而基于排序树版本的实现在插入或删除元素时会按照元素或元素的键(key)构成排序树从而达到排序和去重的效果。 
222_TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
        答:TreeSet要求存放的对象所属的类必须实现Comparable接口,该接口提供了比较元素的compareTo()方法,当插入元素时会回调该方法比较元素的大小。
        TreeMap要求存放的键值对映射的键必须实现Comparable接口从而根据键对元素进行排序。
        Collections工具类的sort方法有两种重载的形式,第一种要求传入的待排序容器中存放的对象比较实现Comparable接口以实现元素的比较;第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator接口的子类型(需要重写compare方法实现元素的比较),相当于一个临时定义的排序规则,其实就是是通过接口注入比较元素大小的算法,也是对回调模式的应用。
________________________________________
 例子1:
Student.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17    package com.bjsxt;
public class Student implements Comparable<Student> {  
    private String name;        // 姓名  
    private int age;            // 年龄  
    public Student(String name, int age) {  
        this.name = name;  
        this.age = age;  
    }  
    @Override  
    public String toString() {  
        return "Student [name=" + name + ", age=" + age + "]";  
    }  
    @Override  
    public int compareTo(Student o) {  
        return this.age - o.age; // 比较年龄(年龄的升序)  
    }  
  }
Test01.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21    package com.bjsxt;
import java.util.Set;  
import java.util.TreeSet;  
  
class Test01 {  
  public static void main(String[] args) {  
        Set<Student> set = new TreeSet<>();     // Java 7的钻石语法(构造器后面的尖括号中不需要写类型)  
        set.add(new Student("Hao LUO", 33));  
        set.add(new Student("XJ WANG", 32));  
        set.add(new Student("Bruce LEE", 60));  
        set.add(new Student("Bob YANG", 22));  
          for(Student stu : set) {  
            System.out.println(stu);  
        }  
//      输出结果:   
//      Student [name=Bob YANG, age=22]  
//      Student [name=XJ WANG, age=32]  
//      Student [name=Hao LUO, age=33]  
//      Student [name=Bruce LEE, age=60]  
    }  
}
________________________________________
例子2:
Student.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25    package com.bjsxt;
public class Student {  
    private String name;    // 姓名  
    private int age;        // 年龄  
    public Student(String name, int age) {  
        this.name = name;  
        this.age = age;  
    }  
    /**
     * 获取学生姓名
     */  
    public String getName() {  
        return name;  
    }  
    /**
     * 获取学生年龄
     */  
    public int getAge() {  
        return age;  
    }  
    @Override  
    public String toString() {  
        return "Student [name=" + name + ", age=" + age + "]";  
    }  
  }
Test02.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35    package com.bjsxt;
import java.util.ArrayList;  
import java.util.Collections;  
import java.util.Comparator;  
import java.util.List;  
  
  class Test02 {  
   public static void main(String[] args) {  
        List<Student> list = new ArrayList<>();     // Java 7的钻石语法(构造器后面的尖括号中不需要写类型)  
        list.add(new Student("Hao LUO", 33));  
        list.add(new Student("XJ WANG", 32));  
        list.add(new Student("Bruce LEE", 60));  
        list.add(new Student("Bob YANG", 22));  
           
        // 通过sort方法的第二个参数传入一个Comparator接口对象  
        // 相当于是传入一个比较对象大小的算法到sort方法中  
        // 由于Java中没有函数指针、仿函数、委托这样的概念  
        // 因此要将一个算法传入一个方法中唯一的选择就是通过接口回调  
        Collections.sort(list, new Comparator<Student> () {  
         @Override  
            public int compare(Student o1, Student o2) {  
                return o1.getName().compareTo(o2.getName());    // 比较学生姓名  
            }  
        });  
           
        for(Student stu : list) {  
            System.out.println(stu);  
        }  
//      输出结果:   
//      Student [name=Bob YANG, age=22]  
//      Student [name=Bruce LEE, age=60]  
//      Student [name=Hao LUO, age=33]  
//      Student [name=XJ WANG, age=32]  
    }  
}
多线程
223_下面程序的运行结果()(选择一项)
1
2
3
4
5
6
7
8
9
10
11
12    public static void main(String[] args) {
Thread t=new Thread(){ 
public void run(){
pong();
}
};
t.run();
System.out.println("ping");
}
static void pong(){
System.out.println("pong");
}

    
A.    pingpong
B.    pongping
C.    pingpong和pongping都有可能
D.    都不输出
答案:B
分析:启动线程需要调用start()方法,而t.run()方法,则是使用对象名.方法名()并没有启动线程,所以程序从上到下依次执行,先执行run()中的静态方法pong()输出pong然执行打印输出ping 

224_下列哪个方法可用于创建一个可运行的类()
A.    public class X implements Runnable{public void run() {……}}
B.    public class X extends Thread{public void run() {……}}
C.    public class X extends Thread{public int run() {……}}
D.    public class X implements Runnable{protected void run() {……}}
答案:AB
分析: 继承Thread和实现Runable接口
225_说明类java.lang.ThreadLocal的作用和原理。列举在哪些程序中见过ThreadLocal的使用?
作用:
        要编写一个多线程安全(Thread-safe)的程序是困难的,为了让线程共享资源,必须小心地对共享资源进行同步,同步带来一定的效能延迟,而另一方面,在处理同步的时候,又要注意对象的锁定与释放,避免产生死结,种种因素都使得编写多线程程序变得困难。
        尝试从另一个角度来思考多线程共享资源的问题,既然共享资源这么困难,那么就干脆不要共享,何不为每个线程创造一个资源的复本。将每一个线程存取数据的行为加以隔离,实现的方法就是给予每个线程一个特定空间来保管该线程所独享的资源。
比如:在Hibernate中的Session就有使用。
ThreadLocal的原理
        ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。
226_说说乐观锁与悲观锁
答:
        悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
        乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。
        两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。
227_在Java中怎么实现多线程?描述线程状态的变化过程。
        答:当多个线程访问同一个数据时,容易出现线程安全问题,需要某种方式来确保资源在某一时刻只被一个线程使用。需要让线程同步,保证数据安全线程同步的实现方案:同步代码块和同步方法,均需要使用synchronized关键字
同步代码块:
1
2
3    public void makeWithdrawal(int amt) {
synchronized (acct) { }
}
同步方法:
1    public synchronized void makeWithdrawal(int amt) { }
线程同步的好处:解决了线程安全问题
线程同步的缺点:性能下降,可能会带来死锁
228_请写出多线程代码使用Thread或者Runnable,并说出两种的区别。
        方式1:继承Java.lang.Thread类,并覆盖run() 方法。优势:编写简单;劣势:无法继承其它父类
public class ThreadDemo1 {
public static void main(String args[]) {
MyThread1 t = new MyThread1();
t.start();
while (true) {
System.out.println("兔子领先了,别骄傲");
}
}
}
class MyThread1 extends Thread {
public void run() {
while (true) {
System.out.println("乌龟领先了,加油");
}
}
}
        方式2:实现Java.lang.Runnable接口,并实现run()方法。优势:可继承其它类,多线程可共享同一个Thread对象;劣势:编程方式稍微复杂,如需访问当前线程,需调用Thread.currentThread()方法
public class ThreadDemo2 {
public static void main(String args[]) {
MyThread2 mt = new MyThread2();
Thread t = new Thread(mt);
t.start();
while (true) {
System.out.println("兔子领先了,加油");
}
}
}
class MyThread2 implements Runnable {
public void run() {
while (true) {
System.out.println("乌龟超过了,再接再厉");
}
}
}
229_在多线程编程里,wait方法的调用方式是怎样的?
答:
        wait方法是线程通信的方法之一,必须用在 synchronized方法或者synchronized代码块中,否则会抛出异常,这就涉及到一个“锁”的概念,而wait方法必须使用上锁的对象来调用,从而持有该对象的锁进入线程等待状态,直到使用该上锁的对象调用notify或者notifyAll方法来唤醒之前进入等待的线程,以释放持有的锁
230_Java线程的几种状态
答:
        线程是一个动态执行的过程,它有一个从产生到死亡的过程,共五种状态:
新建(new Thread)
        当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。
        例如:Thread  t1=new Thread();
就绪(runnable)
        线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();
运行(running)
        线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。
死亡(dead)
        当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
        自然终止:正常运行run()方法后终止
        异常终止:调用stop()方法让一个线程终止运行
堵塞(blocked)
        由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。
        正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。
        正在等待:调用wait()方法。(调用motify()方法回到就绪状态)
        被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)
231_在Java多线程中,请用下面哪种方式不会使线程进入阻塞状态()
A    sleep()
B.    Suspend()
C.    wait()
D.    yield()
答案:D
分析:
yield会是线程进入就绪状态
232_volatile关键字是否能保证线程安全?
答:
        不能. 虽然volatile提供了同步的机制,但是知识一种弱的同步机制,如需要强线程安全,还需要使用synchronized。
        Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。
________________________________________
一、volatile的内存语义是:
        当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值立即刷新到主内存中。
当读一个volatile变量时,JMM会把该线程对应的本地内存设置为无效,直接从主内存中读取共享变量。
二、volatile底层的实现机制
        如果把加入volatile关键字的代码和未加入volatile关键字的代码都生成汇编代码,会发现加入volatile关键字的代码会多出一个lock前缀指令。
________________________________________
        1 、重排序时不能把后面的指令重排序到内存屏障之前的位置
        2、使得本CPU的Cache写入内存
        3、写入动作也会引起别的CPU或者别的内核无效化其Cache,相当于让新写入的值对别的线程可见。
233_请写出常用的Java多线程启动方式,Executors线程池有几种常用类型?
(1) 继承Thread类
1
2
3
4
5
6
7
8
9    public class java_thread extends Thread{  
    public static void main(String args[]) {  
        new java_thread().run();  
        System.out.println("main thread run ");  
    }  
    public synchronized  void run() {  
        System.out.println("sub thread run ");  
    }  
}
(2) 实现Runnable接口
1
2
3
4
5
6
7
8
9    public class java_thread implements Runnable{  
    public static void main(String args[]) {  
        new Thread(new java_thread()).start();  
        System.out.println("main thread run ");  
    }  
    public void run() {  
        System.out.println("sub thread run ");  
    }  
}
在Executor框架下,利用Executors的静态方法可以创建三种类型的常用线程池:
        1)FixedThreadPool这个线程池可以创建固定线程数的线程池。
        2)SingleThreadExecutor是使用单个worker线程的Executor。
        3)CachedThreadPool是一个”无限“容量的线程池,它会根据需要创建新线程。
234_关于sleep()和wait(),以下描述错误的一项是()
A.    sleep是线程类(Thread)的方法,wait是Object类的方法
B.    Sleep不释放对象锁,wait放弃对象锁
C.    Sleep暂停线程、但监控状态任然保持,结束后会自动恢复
D.    Wait后进入等待锁定池,只针对此对象发出notify方法后获取对象锁进入运行状态。
答案:D
分析:
针对此对象的notify方法后获取对象锁并进入就绪状态,而不是运行状态。另外针对此对象的notifyAll方法后也可能获取对象锁并进入就绪状态,而不是运行状态
235_进程和线程的区别是什么? 
        进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
        线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
区别    进程    线程
根本区别     作为资源分配的单位     调度和执行的单位
开销     每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销。     线程可以看成时轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。 
所处环境     在操作系统中能同时运行多个任务(程序)    在同一应用程序中有多个顺序流同时执行 
分配内存     系统在运行的时候会为每个进程分配不同的内存区域     除了CPU之外,不会为线程分配内存(线程所使用的资源是它所属的进程的资源),线程组只能共享资源 
包含关系     没有线程的进程是可以被看作单线程的,如果一个进程内拥有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的。     线程是进程的一部分,所以线程有的时候被称为是轻权进程或者轻量级进程。 
236_以下锁机机制中,不能保证线程安全的是()
A.    Lock
B.    Synchronized
C.    Volatile
答案:C
237_创建n多个线程,如何保证这些线程同时启动?看清,是“同时”。
        答:用一个for循环创建线程对象,同时调用wait()方法,让所有线程等待;直到最后一个线程也准备就绪后,调用notifyAll(),  同时启动所有线程。
        比如:给你n个赛车,让他们都在起跑线上就绪后,同时出发,Java多线程如何写代码?
思路是,来一辆赛车就加上一把锁,并修改对应的操作数,如果没有全部就绪就等待,并释放锁,直到最后一辆赛车到场后唤醒所有的赛车线程。代码参考如下:
1
2
3
4
5
6    public class CarCompetion {
    // 参赛赛车的数量
    protected final int totalCarNum = 10;
    // 当前在起跑线的赛车数量
    protected int nowCarNum = 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32    public class Car implements Runnable{
    private int carNum;
    private CarCompetion competion = null;
    public Car(int carNum, CarCompetion competion) {
        this.carNum = carNum;
        this.competion = competion;
    }
    @Override
    public void run() {
        synchronized (competion) {
            competion.nowCarNum++;
            while (competion.nowCarNum < competion.totalCarNum) {
                try {
                    competion.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            competion.notifyAll();
        }
        startCar();
    }
    private void startCar() {
        System.out.println("Car num " + this.carNum + " start to run.");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Car num " + this.carNum + " get to the finish line.");
    }
}

1
2
3
4
5
6
7    public static void main(String[] args) {
    CarCompetion carCompetion = new CarCompetion();
    final ExecutorService carPool =
        Executors.newFixedThreadPool(carCompetion.totalCarNum);
    for (int i = 0; i < carCompetion.totalCarNum; i++) {
        carPool.execute(new Car(i, carCompetion));
}
238_同步和异步有何异同,在什么情况下分别使用它们?
答:
        1.如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
        2.当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
        3.举个例子: 打电话是同步 发消息是异步
239_Java线程中,sleep()和wait()区别
答:
        sleep是线程类(Thread)的方法;作用是导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复;调用sleep()不会释放对象锁。
        wait是Object类的方法;对此对象调用wait方法导致本线程放弃对象锁,进入等 待此对象的等待锁定池。只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池,准备获得对象锁进行运行状态。
240_下面所述步骤中,是创建进程做必须的步骤是()
A    由调度程序为进程分配CPU
B.    建立一个进程控制块
C.    为进程分配内存
D.    为进程分配文件描述符
答案:BC
241_无锁化编程有哪些常见方法?()
A    针对计数器,可以使用原子加
B.    只有一个生产者和一个消费者,那么就可以做到免锁访问环形缓冲区(Ring Buffer)
C.    RCU(Read-Copy-Update),新旧副本切换机制,对于旧副本可以采用延迟释放的做法
D.    CAS(Compare-and-Swap),如无锁栈,无锁队列等待
答案:D
分析:
A 这方法虽然不太好,但是常见
B ProducerConsumerQueue就是这个,到处都是
C linux kernel里面大量使用
D 本质上其实就是乐观锁,操作起来很困难。。单生产者多消费者或者多生产者单消费者的情况下比较常见,也不容易遇到ABA问题。
242_sleep()和yield()有什么区别?
答:
        ① sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
        ② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
        ③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
        ④ sleep()方法比yield()方法(跟操作系统相关)具有更好的可移植性。
243_当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法?
        答:不能。其它线程只能访问该对象的非同步方法,同步方法则不能进入。 
        只有等待当前线程执行完毕释放锁资源之后,其他线程才有可能进行执行该同步方法!
        延伸  对象锁分为三种:共享资源、this、当前类的字节码文件对象
244_请说出与线程同步相关的方法。
答:
        1. wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
        2. sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException 异常;
        3. notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;
        4. notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争;
        5. JDK 1.5通过Lock接口提供了显式(explicit)的锁机制,增强了灵活性以及对线程的协调。Lock接口中定义了加锁(lock())和解锁(unlock())的方法,同时还提供了newCondition()方法来产生用于线程之间通信的Condition对象;
        6. JDK 1.5还提供了信号量(semaphore)机制,信号量可以用来限制对某个共享资源进行访问的线程的数量。在对资源进行访问之前,线程必须得到信号量的许可(调用Semaphore对象的acquire()方法);在完成对资源的访问后,线程必须向信号量归还许可(调用Semaphore对象的release()方法)。
________________________________________
        下面的例子演示了100个线程同时向一个银行账户中存入1元钱,在没有使用同步机制和使用同步机制情况下的执行情况。
银行账户类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29    package com.bjsxt;
/**
 * 银行账户
 * @author sxt 
 *
 */  
public class Account {  
    private double balance;     // 账户余额  
    /**
     * 存款
     * @param money 存入金额
     */  
    public void deposit(double money) {  
        double newBalance = balance + money;  
        try {  
            Thread.sleep(10);   // 模拟此业务需要一段处理时间  
        }  
        catch(InterruptedException ex) {  
            ex.printStackTrace();  
        }  
        balance = newBalance;  
    }  
    /**
     * 获得账户余额
     */  
    public double getBalance() {  
        return balance;  
    }  
}
________________________________________
存钱线程类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20    package com.bjsxt;
/**
 * 存钱线程
 * @author sxt李端阳
 *
 */  
public class AddMoneyThread implements Runnable {  
    private Account account;    // 存入账户  
    private double money;       // 存入金额  
   
    public AddMoneyThread(Account account, double money) {  
        this.account = account;  
        this.money = money;  
    }  
   
    @Override  
    public void run() {  
        account.deposit(money);  
    }  
 }
________________________________________
测试类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16    package com.bjsxt;
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
  
 public class Test01 {  
public static void main(String[] args) {  
        Account account = new Account();  
        ExecutorService service = Executors.newFixedThreadPool(100);  
        for(int i = 1; i <= 100; i++) {  
            service.execute(new AddMoneyThread(account, 1));  
        }  
        service.shutdown();  
        while(!service.isTerminated()) {}  
        System.out.println("账户余额: " + account.getBalance());  
    }  
}
        在没有同步的情况下,执行结果通常是显示账户余额在10元以下,出现这种状况的原因是,当一个线程A试图存入1元的时候,另外一个线程B也能够进入存款的方法中,线程B读取到的账户余额仍然是线程A存入1元钱之前的账户余额,因此也是在原来的余额0上面做了加1元的操作,同理线程C也会做类似的事情,所以最后100个线程执行结束时,本来期望账户余额为100元,但实际得到的通常在10元以下。解决这个问题的办法就是同步,当一个线程对银行账户存钱时,需要将此账户锁定,待其操作完成后才允许其他的线程进行操作,代码有如下几种调整方案:
________________________________________
1. 在银行账户的存款(deposit)方法上同步(synchronized)关键字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29    package com.bjsxt;
/**
 * 银行账户
 * @author SXT李端阳
*/  
public class Account {  
    private double balance;     // 账户余额  
    /**
     * 存款
     * @param money 存入金额
     */  
    public synchronized void deposit(double money) {  
        double newBalance = balance + money;  
        try {  
            Thread.sleep(10);   // 模拟此业务需要一段处理时间  
        }  
        catch(InterruptedException ex) {  
            ex.printStackTrace();  
        }  
        balance = newBalance;  
    }  
       
    /**
     * 获得账户余额
     */  
    public double getBalance() {  
        return balance;  
    }  
}
2. 在线程调用存款方法时对银行账户进行同步
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21    package com.bjsxt;
/**
 * 存钱线程
 * @author SXT
 *
 */  
public class AddMoneyThread implements Runnable {  
    private Account account;    // 存入账户  
    private double money;       // 存入金额  
   
    public AddMoneyThread(Account account, double money) {  
        this.account = account;  
        this.money = money;  
    }  
    @Override  
    public void run() {  
        synchronized (account) {  
            account.deposit(money);   
        }  
    }  
}
________________________________________
3. 通过JDK 1.5显示的锁机制,为每个银行账户创建一个锁对象,在存款操作进行加锁和解锁的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42    package com.bjsxt;
import java.util.concurrent.locks.Lock;  
import java.util.concurrent.locks.ReentrantLock;  
   
/**
 * 银行账户
 *  
 * @author SXT李端阳
 *
 */  
public class Account {  
    private Lock accountLock = new ReentrantLock();  
    private double balance; // 账户余额  
   /**
     * 存款
     *  
     * @param money
     *            存入金额
     */  
    public void deposit(double money) {  
        accountLock.lock();  
        try {  
            double newBalance = balance + money;  
            try {  
                Thread.sleep(10); // 模拟此业务需要一段处理时间  
            }  
            catch (InterruptedException ex) {  
                ex.printStackTrace();  
            }  
            balance = newBalance;  
        }  
        finally {  
            accountLock.unlock();  
        }  
    }  
    /**
     * 获得账户余额
     */  
    public double getBalance() {  
        return balance;  
    }  
}
        按照上述三种方式对代码进行修改后,重写执行测试代码Test01,将看到最终的账户余额为100元。 
245_编写多线程程序有几种实现方式?
        答:Java 5以前实现多线程有两种实现方法:一种是继承Thread类;另一种是实现Runnable接口。两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,同时也可以实现资源共享,显然使用Runnable接口更为灵活。
        补充:Java 5以后创建线程还有第三种方式:实现Callable接口,该接口中的call方法可以在线程执行结束时产生一个返回值,代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41    package com.bjsxt;
import java.util.ArrayList;  
import java.util.List;  
import java.util.concurrent.Callable;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Future;  
  
  class MyTask implements Callable<Integer> {  
    private int upperBounds;  
       
    public MyTask(int upperBounds) {  
        this.upperBounds = upperBounds;  
    }  
       
    @Override  
    public Integer call() throws Exception {  
        int sum = 0;   
        for(int i = 1; i <= upperBounds; i++) {  
            sum += i;  
        }  
        return sum;  
    }  
       
}  
   
public class Test {  
  public static void main(String[] args) throws Exception {  
        List<Future<Integer>> list = new ArrayList<>();  
        ExecutorService service = Executors.newFixedThreadPool(10);  
        for(int i = 0; i < 10; i++) {  
        list.add(service.submit(new MyTask((int) (Math.random() * 100))));  
        }  
        int sum = 0;  
        for(Future<Integer> future : list) {  
            while(!future.isDone()) ;  
            sum += future.get();  
        }  
          System.out.println(sum);  
    }  
}
246_synchronized关键字的用法?
            答:synchronized关键字可以将对象或者方法标记为同步,以实现对对象和方法的互斥访问,可以用synchronized(对象) { … }定义同步代码块,或者在声明方法时将synchronized作为方法的修饰符。在第60题的例子中已经展示了synchronized关键字的用法。
247_启动一个线程是用run()还是start()方法?
        答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM 调度并执行,这并不意味着线程就会立即运行。run()方法是线程启动后要进行回调(callback)的方法。 
API解释如下:
 
248_什么是线程池(thread pool)?
        答:在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这就是"池化资源"技术产生的原因。线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。
        Java 5+中的Executor接口定义一个执行线程的工具。它的子类型即线程池接口是ExecutorService。要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,因此在工具类Executors面提供了一些静态工厂方法,生成一些常用的线程池,如下所示:
________________________________________
newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
newFixedThreadPool:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
newCachedThreadPool:创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
newScheduledThreadPool:创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。
newSingleThreadExecutor:创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。
________________________________________
        有通过Executors工具类创建线程池并使用线程池执行线程的代码。如果希望在服务器上使用线程池,强烈建议使用newFixedThreadPool方法来创建线程池,这样能获得更好的性能。 
249_线程的基本状态以及状态之间的关系?
        答: 除去起始(new)状态和结束(finished)状态,线程有三种状态,分别是:就绪(ready)、运行(running)和阻塞(blocked)。其中就绪状态代表线程具备了运行的所有条件,只等待CPU调度(万事俱备,只欠东风);处于运行状态的线程可能因为CPU调度(时间片用完了)的原因回到就绪状态,也有可能因为调用了线程的yield方法回到就绪状态,此时线程不会释放它占有的资源的锁,坐等CPU以继续执行;运行状态的线程可能因为I/O中断、线程休眠、调用了对象的wait方法而进入阻塞状态(有的地方也称之为等待状态);而进入阻塞状态的线程会因为休眠结束、调用了对象的notify方法或notifyAll方法或其他线程执行结束而进入就绪状态。注意:调用wait方法会让线程进入等待池中等待被唤醒,notify方法或notifyAll方法会让等待锁中的线程从等待池进入等锁池,在没有得到对象的锁之前,线程仍然无法获得CPU的调度和执行。
250_简述synchronized 和java.util.concurrent.locks.Lock的异同?
                答:Lock是Java 5以后引入的新的API,和关键字synchronized相比主要相同点:Lock 能完成synchronized所实现的所有功能;主要不同点:Lock 有比synchronized 更精确的线程语义和更好的性能。synchronized 会自动释放锁,而Lock 一定要求程序员手工释放,并且必须在finally 块中释放(这是释放外部资源的最好的地方)。
251_创建线程的两种方式分别是什么,优缺点是什么?
方式1:继承Java.lang.Thread类,并覆盖run() 方法。
优势:编写简单;
劣势:单继承的限制----无法继承其它父类,同时不能实现资源共享。
1
2
3
4
5
6
7
8
9
10
11
12
13  
14
15
16
17
18    package com.bjsxt;
  
public class ThreadDemo1 {
public static void main(String args[]) {
MyThread1 t = new MyThread1();
.start();
while (true) {
System.out.println("兔子领先了,别骄傲");
}
}
}
class MyThread1 extends Thread {
public void run() {
while (true) {
System.out.println("乌龟领先了,加油");
}
}
}
方式2:实现Java.lang.Runnable接口,并实现run()方法。
优势:可继承其它类,多线程可共享同一个Thread对象;
劣势:编程方式稍微复杂,如需访问当前线程,需调用Thread.currentThread()方法 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18    package com.bjsxt;
public class ThreadDemo2 {
public static void main(String args[]) {
MyThread2 mt = new MyThread2();
Thread t = new Thread(mt);
t.start();
while (true) {
System.out.println("兔子领先了,加油");
}
}
}
class MyThread2 implements Runnable {
public void run() {
while (true) {
System.out.println("乌龟超过了,再接再厉");
}
}
}
252_Java创建线程后,调用start()方法和run()的区别
两种方法的区别
1) start方法:用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
2) run():run()方法只是类的一个普通方法而已,如果直接调用run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
________________________________________
        总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。这两个方法应该都比较熟悉,把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run()方法,这是由jvm的内存机制规定的。并且run()方法必须是public访问权限,返回值类型为void。
________________________________________
两种方式的比较 :
        实际中往往采用实现Runable接口,一方面因为java只支持单继承,继承了Thread类就无法再继续继承其它类,而且Runable接口只有一个run方法;另一方面通过结果可以看出实现Runable接口才是真正的多线程。
253_线程的生命周期
        线程是一个动态执行的过程,它也有一个从产生到死亡的过程。
(1)生命周期的五种状态:
新建(new Thread)
        当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。
        例如:Thread  t1=new Thread();
就绪(runnable)
        线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。
        例如:t1.start();
运行(running)
        线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。
死亡(dead)
        当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
        自然终止:正常运行run()方法后终止
        异常终止:调用stop()方法让一个线程终止运行
堵塞(blocked)
        由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。
        正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。
        正在等待:调用wait()方法。(调用motify()方法回到就绪状态)
        被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)
254_如何实现线程同步?
        当多个线程访问同一个数据时,容易出现线程安全问题,需要某种方式来确保资源在某一时刻只被一个线程使用。需要让线程同步,保证数据安全.
        线程同步的实现方案:
            1)同步代码块,使用synchronized关键字
        同步代码块:
             synchronized (同步锁) {
              授课代码;
                }
        同步方法:
            public synchronized void makeWithdrawal(int amt) { }
        线程同步的好处:解决了线程安全问题
        线程同步的缺点:性能下降,可能会带来死锁
        注意:同步代码块,所使用的同步锁可以是三种,
                1、 this      2、 共享资源      3、字节码文件对象
          同步方法所使用的同步锁,默认的是this
255_说说关于同步锁的更多细节
答:
        Java中每个对象都有一个内置锁。
        当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。
        当程序运行到synchronized同步方法或代码块时才该对象锁才起作用。
        一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。这也意味着任何其他线程都不能进入该对象上的synchronized方法或代码块,直到该锁被释放。
        释放锁是指持锁线程退出了synchronized同步方法或代码块。
________________________________________
关于锁和同步,有一下几个要点:
            1)、只能同步方法,而不能同步变量和类;
            2)、每个对象只有一个锁;当提到同步时,应该清楚在什么上同步?也就是说,在哪个对象上同步?
            3)、不必同步类中所有的方法,类可以同时拥有同步和非同步方法。
            4)、如果两个线程要执行一个类中的synchronized方法,并且两个线程使用相同的实例来调用方法,那么一次只能有一个线程能够执行方法,另一个需要等待,直到锁被释放。也就是说:如果一个线程在对象上获得一个锁,就没有任何其他线程可以进入(该对象的)类中的任何一个同步方法。
            5)、如果线程拥有同步和非同步方法,则非同步方法可以被多个线程自由访问而不受锁的限制。
            6)、线程睡眠时,它所持的任何锁都不会释放。
            7)、线程可以获得多个锁。比如,在一个对象的同步方法里面调用另外一个对象的同步方法,则获取了两个对象的同步锁。
            8)、同步损害并发性,应该尽可能缩小同步范围。同步不但可以同步整个方法,还可以同步方法中一部分代码块。
            9)、在使用同步代码块时候,应该指定在哪个对象上同步,也就是说要获取哪个对象的锁。
256_Java中实现线程通信的三个方法的作用是什么?
        Java提供了3个方法解决线程之间的通信问题,均是java.lang.Object类的方法,都只能在同步方法或者同步代码块中使用,否则会抛出异常。
 
IO流
257_下面哪个流类属于面向字符的输入流()(选择一项)
A.    BufferedWriter
B.    FileInputStream
C.    ObjectInputStream
D.    InputStreamReader
答案:D
分析:A:字符输出的缓冲流
      B:字节输入流
      C:对象输入流 
258_要从文件”file.dat”文件中读出第10个字节到变量c中,下列哪个正确()(选择一项)
A.    FileInputStream in=new FileInputStream("file.dat");
in.skip(9);
int c=in.read();
B.    FileInputStream in=new FileInputStream("file.dat");
in.skip(10);
int c=in.read();
C.    FileInputStream in=new FileInputStream("file.dat");
int c=in.read();
D.    RandomAccessFile in=new RandomAccessFile("file.dat");
in.skip(7);
int c=in.readByte();
答案:A
分析: skip(long n)该方法中的n指的是要跳过的字节数
259_新建一个流对象,下面那个选项的代码是错误的?()
A.    new BufferedWriter(new FileWriter(“a.txt”));
B.    new BufferedReader (new FileInputStream(“a.dat”));
C.    new GZIPOutputStream(new FileOutputStream(“a.zip”));
D.    new ObjectInputStream(new FileInputStream(“a.dat”));
答案:B
分析:
BufferedReader类的参数只能是Reader类型的,不能是InputStream类型。
260_下面哪个流是面向字符的输入流()
A    BufferedWriter
B.    FileInputStream
C.    ObjectInputStream
D.    InputStreamReader
答案:D
分析:
以InputStream(输入流)/OutputStream(输出流)为后缀的是字节流;以Reader(输入流)/Writer(输出流)为后缀的是字符流。
261_Java类库中,将信息写入内存的类是()
A    Java.io.FileOutputStream
B.    java.ByteArrayOutputStream
C.    java.io.BufferedOutputStream
D.    java,.io.DataOutputStream
答案:B
分析: ACD都是io到文件
262_请写出一段代码,能够完成将字符串写入文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20    public class test {
public static void main(String[] args) {
String str = "bjsxt";
writeFile(str);
}
  
public static void writeFile(String str) {
File file = new File("c:/test.txt");
PrintStream ps = null;
try {
OutputStream fos = new FileOutputStream(file);
ps = new PrintStream(fos);
ps.print(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
ps.close();
}
}
}
263_下面哪个流类属于面向字符的输入流()
A.    BufferedWriter
B.    FileInputStream
C.    ObjectInputStream
D.    InputStreamReader
答案:D
264_Java中如何实现序列化,有什么意义?
答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。
________________________________________
要实现序列化,需要让一个类实现Serializable接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过writeObject(Object obj)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject方法从流中读取对象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆(参见Java面试题集1-29题) 
265_Java 中有几种类型的流?
答:两种流分别是字节流,字符流。
        字节流继承于InputStream、OutputStream,字符流继承于Reader、Writer。在java.io 包中还有许多其他的流,主要是为了提高性能和使用方便。
补充:关于Java的IO需要注意的有两点:一是两种对称性(输入和输出的对称性,字节和字符的对称性);二是两种设计模式(适配器模式和装潢模式)。另外Java中的流不同于C#的是它只有一个维度一个方向。
________________________________________
补充:下面用IO和NIO两种方式实现文件拷贝,这个题目在面试的时候是经常被问到的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41    package com.bjsxt;
import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.nio.ByteBuffer;  
import java.nio.channels.FileChannel;  
  
public class MyUtil {  
  private MyUtil() {  
        throw new AssertionError();  
    }  
       
    public static void fileCopy(String source, String target) throws IOException {  
        try (InputStream in = new FileInputStream(source)) {  
            try (OutputStream out = new FileOutputStream(target)) {  
                byte[] buffer = new byte[4096];  
                int bytesToRead;  
                while((bytesToRead = in.read(buffer)) != -1) {  
                    out.write(buffer, 0, bytesToRead);  
                }  
            }  
        }  
    }  
       
    public static void fileCopyNIO(String source, String target) throws IOException {  
        try (FileInputStream in = new FileInputStream(source)) {  
            try (FileOutputStream out = new FileOutputStream(target)) {  
                FileChannel inChannel = in.getChannel();  
                FileChannel outChannel = out.getChannel();  
                ByteBuffer buffer = ByteBuffer.allocate(4096);  
                while(inChannel.read(buffer) != -1) {  
                    buffer.flip();  
                    outChannel.write(buffer);  
                    buffer.clear();  
                 }  
            }  
        }  
    }  
}
注意:上面用到Java 7的TWR,使用TWR后可以不用在finally中释放外部资源 ,从而让代码更加优雅。
266_ 写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。
答:代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34    package com.bjsxt;
import java.io.BufferedReader;  
import java.io.FileReader;  
   
public class Account {  
    // 工具类中的方法都是静态方式访问的因此将构造器私有不允许创建对象(绝对好习惯)  
    private Account() {  
        throw new AssertionError();  
    }  
    /**
     * 统计给定文件中给定字符串的出现次数
     * @param filename  文件名
     * @param word 字符串
     * @return 字符串在文件中出现的次数
     */  
    public static int countWordInFile(String filename, String word) {  
        int counter = 0;  
        try (FileReader fr = new FileReader(filename)) {  
            try (BufferedReader br = new BufferedReader(fr)) {  
                String line = null;  
                while ((line = br.readLine()) != null) {  
                    int index = -1;  
                    while (line.length() >= word.length() && (index = line.indexOf(word)) >= 0) {  
                        counter++;  
                        line = line.substring(index + word.length());  
                    }  
                }  
            }  
        } catch (Exception ex) {  
            ex.printStackTrace();  
        }  
        return counter;  
    }  
}
267_输入流和输出流联系和区别,节点流和处理流联系和区别
        首先,你要明白什么是“流”。直观地讲,流就像管道一样,在程序和文件之间,输入输出的方向是针对程序而言,向程序中读入东西,就是输入流,从程序中向外读东西,就是输出流。
        输入流是得到数据,输出流是输出数据,而节点流,处理流是流的另一种划分,按照功能不同进行的划分。节点流,可以从或向一个特定的地方(节点)读写数据。处理流是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
268_字符流字节流联系区别;什么时候使用字节流和字符流?
        字符流和字节流是流的一种划分,按处理照流的数据单位进行的划分。两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream,在字符流中输出主要是使用Writer类完成,输入流主要使用Reader类完成。这四个都是抽象类。
        字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。字节流是最基本的,所有的InputStrem和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的 但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的编码来处理,也就是要进行字符集的转化 这两个之间通过 InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联的。
269_列举常用字节输入流和输出流并说明其特点,至少5对。
答:FileInputStream 从文件系统中的某个文件中获得输入字节。
        FileOutputStream 从程序当中的数据,写入到指定文件。
        ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。
        ObjectOutputStream 和 ObjectInputStream 分别与FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。ObjectInputStream 用于恢复那些以前序列化的对象。其他用途包括使用套接字流在主机之间传递对象,或者用于编组和解组远程通信系统中的实参和形参。
________________________________________
        ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。
FilterInputStream 包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。FilterInputStream 类本身只是简单地重写那些将所有请求传递给所包含输入流的 InputStream 的所有方法。FilterInputStream 的子类可进一步重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。
        StringBufferInputStream此类允许应用程序创建输入流,在该流中读取的字节由字符串内容提供。应用程序还可以使用ByteArrayInputStream 从 byte 数组中读取字节。 只有字符串中每个字符的低八位可以由此类使用。
________________________________________
        ByteArrayOutputStream此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。
        FileOutputStream文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。
FilterOutputStream类是过滤输出流的所有类的超类。这些流位于已存在的输出流(基础 输出流)之上,它们将已存在的输出流作为其基本数据接收器,但可能直接传输数据或提供一些额外的功能。                 FilterOutputStream 类本身只是简单地重写那些将所有请求传递给所包含输出流的 OutputStream 的所有方法。FilterOutputStream 的子类可进一步地重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。
________________________________________
        ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。
        PipedOutputStream可以将管道输出流连接到管道输入流来创建通信管道。管道输出流是管道的发送端。通常,数据由某个线程写入 PipedOutputStream 对象,并由其他线程从连接的 PipedInputStream 读取。不建议对这两个对象尝试使用单个线程,因为这样可能会造成该线程死锁。如果某个线程正从连接的管道输入流中读取数据字节,但该线程不再处于活动状态,则该管道被视为处于毁坏状态。
270_说明缓冲流的优点和原理
不带缓冲的流的工作原理:
它读取到一个字节/字符,就向用户指定的路径写出去,读一个写一个,所以就慢了。
带缓冲的流的工作原理:
读取到一个字节/字符,先不输出,等凑足了缓冲的最大容量后一次性写出去,从而提高了工作效率
优点:减少对硬盘的读取次数,降低对硬盘的损耗。
271_序列化的定义、实现和注意事项
想把一个对象写在硬盘上或者网络上,对其进行序列化,把他序列化成为一个字节流。
实现和注意事项:
        1)实现接口Serializable Serializable接口中没有任何的方法,实现该接口的类不需要实现额外的方法。
        2)如果对象中的某个属性是对象类型,必须也实现Serializable接口才可以,序列化对静态变量无效
        3)如果不希望某个属性参与序列化,不是将其static,而是transient串行化保存的只是变量的值,对于变量的任何修饰符,都不能保存序列化版本不兼容
272_使用IO流完成文件夹复制
(结合递归)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85    package com.bjsxt;
  
import java.io.*;
/**
 * CopyDocJob定义了实际执行的任务,即
 * 从源目录拷贝文件到目标目录
*/
public class CopyDir2 {
public static void main(String[] args) {
try {
copyDirectiory("d:/301sxt","d:/301sxt2");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
 * 复制单个文件
 * @param sourceFile 源文件
 * @param targetFile 目标文件
 * @throws IOException
 */
    private static void copyFile(File sourceFile, File targetFile) throws IOException {
        BufferedInputStream inBuff = null;
        BufferedOutputStream outBuff = null;
        try {
            // 新建文件输入流
            inBuff = new BufferedInputStream(new FileInputStream(sourceFile));
            // 新建文件输出流
            outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
            // 缓冲数组
            byte[] b = new byte[1024 * 5];
            int len;
            while ((len = inBuff.read(b)) != -1) {
                outBuff.write(b, 0, len);
            }
            // 刷新此缓冲的输出流
            outBuff.flush();
        } finally {
            // 关闭流
            if (inBuff != null)
                inBuff.close();
            if (outBuff != null)
                outBuff.close();
        }
    }
  
    /**
     * 复制目录
     * @param sourceDir 源目录
     * @param targetDir 目标目录
     * @throws IOException
     */
    private static void copyDirectiory(String sourceDir, String targetDir) throws IOException {
        // 检查源目录
     File fSourceDir = new File(sourceDir);
     if(!fSourceDir.exists() || !fSourceDir.isDirectory()){
      return;
     }    
     //检查目标目录,如不存在则创建
     File fTargetDir = new File(targetDir);
     if(!fTargetDir.exists()){
      fTargetDir.mkdirs();
     }      
        // 遍历源目录下的文件或目录
        File[] file = fSourceDir.listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 源文件
                File sourceFile = file[i];
                // 目标文件
                File targetFile = new File(fTargetDir, file[i].getName());
                copyFile(sourceFile, targetFile);
            }            
            //递归复制子目录
            if (file[i].isDirectory()) {
                // 准备复制的源文件夹
                String subSourceDir = sourceDir + File.separator + file[i].getName();
                // 准备复制的目标文件夹
                String subTargetDir = targetDir + File.separator + file[i].getName();
                // 复制子目录
                copyDirectiory(subSourceDir, subTargetDir);
            }
        }
    }
}
273_说说BIO、NIO和AIO的区别
        Java BIO :同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
        Java NIO :同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
        Java AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
        NIO比BIO的改善之处是把一些无效的连接挡在了启动线程之前,减少了这部分资源的浪费(因为我们都知道每创建一个线程,就要为这个线程分配一定的内存空间)
        AIO比NIO的进一步改善之处是将一些暂时可能无效的请求挡在了启动线程之前,比如在NIO的处理方式中,当一个请求来的话,开启线程进行处理,但这个请求所需要的资源还没有就绪,此时必须等待后端的应用资源,这时线程就被阻塞了。
________________________________________
适用场景分析:
        BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解,如之前在Apache中使用。
        NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持,如在 Nginx,Netty中使用。
        AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持,在成长中,Netty曾经使用过,后来放弃。
网络编程
274_IP地址和端口号
1)IP地址
        用来标志网络中的一个通信实体的地址。通信实体可以是计算机,路由器等。
2)IP地址分类
        IPV4:32位地址,以点分十进制表示,如192.168.0.1
        IPV6:128位(16个字节)写成8个16位的无符号整数,每个整数用四个十六进制位表示,数之间用冒号(:)分开,如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984
3)特殊的IP地址
        127.0.0.1 本机地址
        192.168.0.0--192.168.255.255私有地址,属于非注册地址,专门为组织机构内部使用。
________________________________________
4)端口:port
        IP地址用来标志一台计算机,但是一台计算机上可能提供多种应用程序,使用端口来区分这些应用程序。 端口是虚拟的概念,并不是说在主机上真的有若干个端口。通过端口,可以在一个主机上运行多个网络应用程序。 端口范围0---65535,16位整数
5)端口分类
        公认端口  0—1023   比如80端口分配给WWW,21端口分配给FTP,22端口分配给SSH,23端口分配给telnet,25端口分配给smtp
        注册端口  1024—49151    分配给用户进程或应用程序
        动态/私有端口 49152--65535
6)理解IP和端口的关系
        IP地址好比每个人的地址(门牌号),端口好比是房间号。必须同时指定IP地址和端口号才能够正确的发送数据
        IP地址好比为电话号码,而端口号就好比为分机号。 
275_介绍OSI七层模型和TCP/IP模型
  
            OSI(Open System Interconnection),开放式系统互联参考模型 。是一个逻辑上的定义,一个规范,它把网络协议从逻辑上分为了7层。每一层都有相关、相对应的物理设备,比如常规的路由器是三层交换设备,常规的交换机是二层交换设备。OSI七层模型是一种框架性的设计方法,建立七层模型的主要目的是为解决异种网络互连时所遇到的兼容性问题,其最主要的功能就是帮助不同类型的主机实现数据传输。它的最大优点是将服务、接口和协议这三个概念明确地区分开来,通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯。
________________________________________
            TCP/IP协议是Internet最基本的协议、Internet国际互联网络的基础,主要由网络层的IP协议和传输层的TCP协议组成。TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。
            ISO制定的OSI参考模型的过于庞大、复杂招致了许多批评。伴随着互联网的流行,其本身所采用的TCP/IP协议栈获得了更为广泛的应用和认可。在TCP/IP参考模型中,去掉了OSI参考模型中的会话层和表示层(这两层的功能被合并到应用层实现)。同时将OSI参考模型中的数据链路层和物理层合并为主机到网络层。
 
276_TCP协议和UDP协议的比较
        TCP和UDP是TCP/IP协议栈中传输层的两个协议,它们使用IP路由功能把数据包发送到目的地,从而为应用程序及应用层协议(包括:HTTP、SMTP、SNMP、FTP和Telnet)提供网络服务。
        TCP的server和client之间通信就好比两个人打电话,需要互相知道对方的电话号码,然后开始对话。所以在两者的连接过程中间需要指定端口和地址。
        UDP的server和client之间的通信就像两个人互相发信。我只需要知道对方的地址,然后就发信过去。对方是否收到我不知道,也不需要专门对口令似的来建立连接。
________________________________________
具体区别如下:
        1)TCP是面向连接的传输。UDP是无连接的传输
        2)TCP有流量控制、拥塞控制,检验数据数据按序到达,而UDP则相反。
        3)TCP的路由选择只发生在建立连接的时候,而UDP的每个报文都要进行路由选择
        4)TCP是可靠性传输,他的可靠性是由超时重发机制实现的,而UDP则是不可靠传输
        5)UDP因为少了很多控制信息,所以传输速度比TCP速度快
        6)TCP适合用于传输大量数据,UDP适合用于传输小量数据
277_什么是Socket编程
Socket编程的定义如下:
        所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
        我们开发的网络应用程序位于应用层,TCP和UDP属于传输层协议,在应用层如何使用传输层的服务呢?在应用层和传输层之间,则是使用套接字来进行分离。
        套接字就像是传输层为应用层开的一个小口,应用程序通过这个小口向远程发送数据,或者接收远程发来的数据;而这个小口以内,也就是数据进入这个口之后,或者数据从这个口出来之前,是不知道也不需要知道的,也不会关心它如何传输,这属于网络其它层次的工作。
________________________________________
        Socket实际是传输层供给应用层的编程接口。传输层则在网络层的基础上提供进程到进程问的逻辑通道,而应用层的进程则利用传输层向另一台主机的某一进程通信。Socket就是应用层与传输层之间的桥梁
        使用Socket编程可以开发客户机和服务器应用程序,可以在本地网络上进行通信,也可通过Internet在全球范围内通信。
  
________________________________________
        生活案例1:如果你想写封邮件发给远方的朋友,如何写信、将信打包,属于应用层。信怎么写,怎么打包完全由我们做主;而当我们将信投入邮筒时,邮筒的那个口就是套接字,在进入套接字之后,就是传输层、网络层等(邮局、公路交管或者航线等)其它层次的工作了。我们从来不会去关心信是如何从西安发往北京的,我们只知道写好了投入邮筒就OK了。
        生活案例2:可以把Socket比作是一个港口码头,应用程序只要将数据交给Socket,就算完成了数据的发送,具体细节由Socket来完成,细节不必了解。同理,对于接收方,应用程序也要创建一个码头,等待数据的到达,并获取数据。
278_简述基于TCP和UDP的Socket编程的主要步骤
        Java分别为TCP和UDP 两种通信协议提供了相应的Socket编程类,这些类存放在java.net包中。与TCP对应的是服务器的ServerSocket和客户端的Socket,与UDP对应的是DatagramSocket。
        基于TCP创建的套接字可以叫做流套接字,服务器端相当于一个监听器,用来监听端口。 服务器与客服端之间的通讯都是输入输出流来实现的。基于UDP的套接字就是数据报套接字,•  两个都要先构造好相应的数据包。
________________________________________
基于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方法,关闭。
 
________________________________________
        2.2 UDP
        服务器端(server):
                1. 构造DatagramSocket实例,指定本地端口。
                2. 通过DatagramSocket实例的receive方法接收DatagramPacket.DatagramPacket中间就包含了通信的内容。
                3. 通过DatagramSocket的send和receive方法来收和发DatagramPacket.
        客户端(client):
                1. 构造DatagramSocket实例。
                2.通过DatagramSocket实例的send和receive方法发送DatagramPacket报文。
                3.结束后,调用DatagramSocket的close方法关闭。
 
异常处理
279_下列哪种异常是检查型异常,需要在编写程序时声明()
A.    NullPointerException
B.    ClassCastException
C.    FileNotFoundException
D.    IndexOutOfBoundsException
答案:C
分析:NullPointerException空指针异常
ClassCastException类型转换异常
IndexOutOfBoundsException索引超出边界的异常    
 以上这些异常都是程序在运行时发生的异常,所以不需要在编写程序时声明
280_Java出现OutOf MemoryError(OOM 错误)的原因有哪些?出现OOM错误后,怎么解决?
答:
OutOf MemoryError这种错误可以细分为多种不同的错误,每种错误都有自身的原因和解决办法,如下所示:
java.lang.OutOfMemoryError: Java heap space
        错误原因:此OOM是由于JVM中heap的最大值不满足需要。
        解决方法:1) 调高heap的最大值,即-Xmx的值调大。2) 如果你的程序存在内存泄漏,一味的增加heap空间也只是推迟该错误出现的时间而已,所以要检查程序是否存在内存泄漏。
________________________________________
 java.lang.OutOfMemoryError: GC overhead limit exceeded
        错误原因:此OOM是由于JVM在GC时,对象过多,导致内存溢出,建议调整GC的策略,在一定比例下开始GC而不要使用默认的策略,或者将新代和老代设置合适的大小,需要进行微调存活率。
        解决方法:改变GC策略,在老代80%时就是开始GC,并且将-XX:SurvivorRatio(-XX:SurvivorRatio=8)和-XX:NewRatio(-XX:NewRatio=4)设置的更合理。
________________________________________
java.lang.OutOfMemoryError: Java perm space
        错误原因:此OOM是由于JVM中perm的最大值不满足需要。
        解决方法:调高heap的最大值,即-XX:MaxPermSize的值调大。
        另外,注意一点,Perm一般是在JVM启动时加载类进来,如果是JVM运行较长一段时间而不是刚启动后溢出的话,很有可能是由于运行时有类被动态加载进来,此时建议用CMS策略中的类卸载配置。如:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled。
________________________________________
java.lang.OutOfMemoryError: unable to create new native thread
        错误原因:当JVM向OS请求创建一个新线程时,而OS却由于内存不足无法创建新的native线程。
        解决方法:如果JVM内存调的过大或者可利用率小于20%,可以建议将heap及perm的最大值下调,并将线程栈调小,即-Xss调小,如:-Xss128k。
________________________________________
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
        错误原因:此类信息表明应用程序(或者被应用程序调用的APIs)试图分配一个大于堆大小的数组。例如,如果应用程序new一个数组对象,大小为512M,但是最大堆大小为256M,因此OutOfMemoryError会抛出,因为数组的大小超过虚拟机的限制。
        解决方法:1) 首先检查heap的-Xmx是不是设置的过小。2) 如果heap的-Xmx已经足够大,那么请检查应用程序是不是存在bug,例如:应用程序可能在计算数组的大小时,存在算法错误,导致数组的size很大,从而导致巨大的数组被分配。
________________________________________
java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space
        错误原因:抛出这类错误,是由于从native堆中分配内存失败,并且堆内存可能接近耗尽。这类错误可能跟应用程序没有关系,例如下面两种原因也会导致错误的发生:1) 操作系统配置了较小的交换区。2)系统的另外一个进程正在消耗所有的内存。
        解决办法:1) 检查os的swap是不是没有设置或者设置的过小。2) 检查是否有其他进程在消耗大量的内存,从而导致当前的JVM内存不够分配。
        注意:虽然有时<reason>部分显示导致OOM的原因,但大多数情况下,<reason>显示的是提示分配失败的源模块的名称,所以有必要查看日志文件,如crash时的hs文件。
281_列举常见的运行时异常
答:
ClassCastException(类转换异常)
        比如 Object obj=new Object(); String s=(String)obj; 
IndexOutOfBoundsException(下标越界异常)
NullPointerException(空指针异常)
ArrayStoreException(数据存储异常,操作数组时类型不一致)
BufferOverflowException(IO操作时出现的缓冲区上溢异常)
InputMismatchException(输入类型不匹配异常)
ArithmeticException(算术异常)
注意:运行时异常都是RuntimeException子类异常。
282_下面关于 Java.lang.Exception类的说法正确的是()
A.    继承自 Throwable
B.    不支持Serializable
C.    继承自 AbstractSet
D.    继承自FitelnputStream
答案:A
分析:
Throwable是Exception和Error的父类,Exception虽然没有实现Serializable接口,但是其父类Throwable已经实现了该接口,因此Exception也支持Serializable。
283_Unsupported major.minor version 52是什么异常,怎么造成的,如何解决?
  答:问题的根本原因是工程中某个jar包的版本(jar包编译时的所用的jdk版本)高于工程build path中jdk的版本,这个是不兼容的! 编程中遇到此异常Unsupported major.minor version 52.0(根据版本号,这里可以为其他数值,52是1.8jdk jar包与 1.8以下低版本jdk不匹配),在将build path中jdk的版本调整与jar包匹配后,解决异常。
284_try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?  
  答:会执行,在方法返回调用者前执行。Java允许在finally中改变返回值的做法是不好的,因为如果存在finally代码块,try中的return语句不会立马返回调用者,而是记录下返回值待finally代码块执行完毕之后再向调用者返回其值,然后如果在finally中修改了返回值,这会对程序造成很大的困扰,C#中就从语法上规定不能做这样的事。
        (也许你的答案是在return之前,但往更细地说,我的答案是在return中间执行,请看下面程序代码的运行结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24    public classTest {
  
    /**
     * @paramargs add by zxx ,Dec 9, 2008
     */
    public static voidmain(String[] args) {
       // TODO Auto-generated method stub
       System.out.println(newTest().test());;
    }
  
    static int test()
    {
       int x = 1;
       try
       {
           returnx;
       }
       finally
       {
           ++x;
       }
    }
    
}
---------执行结果 ---------
1
        运行结果是1,为什么呢?主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。
)
285_Java 语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?
   答:Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java 中,每个异常都是一个对象,它是Throwable 类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java 的异常处理是通过5 个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throw)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理;try用来指定一块预防所有“异常”的程序;catch 子句紧跟在try块后面,用来指定你想要捕捉的“异常”的类型;throw 语句用来明确地抛出一个“异常”;throws用来标明一个成员函数可能抛出的各种“异常”;finally 为确保一段代码不管发生什么“异常”都被执行一段代码;可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try 语句,“异常”的框架就放到栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种“异常”进行处理,栈就会展开,直到遇到有处理这种“异常”的try 语句。
  286_运行时异常与受检异常有何异同?
  答:异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译器要求方法必须声明抛出可能发生的受检异常,但是并不要求必须声明抛出未被捕获的运行时异常。异常和继承一样,是面向对象程序设计中经常被滥用的东西,神作《Effective Java》中对异常的使用给出了以下指导原则:
  · 不要将异常处理用于正常的控制流(设计良好的API不应该强迫它的调用者为了正常的控制流而使用异常)
  · 对可以恢复的情况使用受检异常,对编程错误使用运行时异常
  · 避免不必要的使用受检异常(可以通过一些状态检测手段来避免异常发生)
  · 优先使用标准的异常
  · 每个方法抛出的异常都要有文档
  · 保持异常的原子性
  · 不要在catch中忽略掉捕获到的异常
  (异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。)
287_类ExampleA 继承Exception,类ExampleB 继承ExampleA
有如下代码片断:
1
2
3
4
5
6
7
8    try{  
throw new ExampleB("b")  
}catch(ExampleA e){  
System.out.println("ExampleA");  
}catch(Exception e){  
System.out.println("Exception");  
}  
 }
  补充:比此题略复杂的一道面试题如下所示(此题的出处是《Java编程思想》),说出你的答案吧!
  请问执行此段代码的输出是什么?
  答:输出:ExampleA。(根据里氏代换原则[能使用父类型的地方一定能使用子类型],抓取 ExampleA类型异常的catch块能够抓住try块中抛出的ExampleB类型的异常)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24    package com.bjsxt;
class Annoyance extends Exception {}  
class Sneeze extends Annoyance {}  
 class Human {  
  public static void main(String[] args)   
        throws Exception {  
        try {  
            try {  
                throw new Sneeze();  
            }   
            catch ( Annoyance a ) {  
                System.out.println("Caught Annoyance");  
                throw a;  
            }  
        }   
        catch ( Sneeze s ) {  
            System.out.println("Caught Sneeze");  
            return ;  
        }  
        finally {  
            System.out.println("Hello World!");  
        }  
    }  
}
输出为:
Caught Annoyance
Caught Sneeze
Hello World!
288_Error和Exception的区别
 
        Error类,表示仅靠程序本身无法恢复的严重错误,比如说内存溢出、动态链接异常、虚拟机错误。应用程序不应该抛出这种类型的对象。假如出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以在进行程序设计时,应该更关注Exception类。
        Exception类,由Java应用程序抛出和处理的非严重错误,比如所需文件没有找到、零作除数,数组下标越界等。它的各种不同子类分别对应不同类型异常。可分为两类:Checked异常和Runtime异常
289_Java异常处理try-catch-finally的执行过程
        try-catch-finally程序块的执行流程以及执行结果比较复杂。
基本执行过程如下:
                1)程序首先执行可能发生异常的try语句块。
                2)如果try语句没有出现异常则执行完后跳至finally语句块执行;
                3)如果try语句出现异常,则中断执行并根据发生的异常类型跳至相应的catch语句块执行处理。
                4)catch语句块可以有多个,分别捕获不同类型的异常。
                5)catch语句块执行完后程序会继续执行finally语句块。
        finally语句是可选的,如果有的话,则不管是否发生异常,finally语句都会被执行。需要注意的是即使try和catch块中存在return语句,finally语句也会执行,是在执行完finally语句后再通过return退出。
290_异常处理中throws和throw的区别
1)作用不同:
        throw用于程序员自行产生并抛出异常;
        throws用于声明在该方法内抛出了异常
2) 使用的位置不同:
        throw位于方法体内部,可以作为单独语句使用;
        throws必须跟在方法参数列表的后面,不能单独使用。
3)内容不同:
        throw抛出一个异常对象,且只能是一个;
        throws后面跟异常类,而且可以有多个。
WEB相关
291_WEB应用中如果有.class和.jar类型的文件一般分别应该放在什么位置?
答:
  .class文件放在WEB-INF/classes文件下,.jar文件放在WEB-INF/lib文件夹下
292_元素中有一个输入框(<input type=”text” name=”username”id=”username”value=””/>,请用JavaScript语言写一行代码,取得这个输入框中的值。
答:
        document.getElementById(“username”).value;
293_简单描述一下Servlet与JSP的的相同点和区别点。
区别:
        JSP是在HTML代码里写JAVA代码,框架是HTML;而Servlet是在JAVA代码中写HTML代码,本身是个JAVA类。
        JSP使人们把显示和逻辑分隔成为可能,这意味着两者的开发可并行进行;而Servlet并没有把两者分开。
        Servlet独立地处理静态表示逻辑与动态业务逻辑.这样,任何文件的变动都需要对此服务程序重新编译;JSP允许用特殊标签直接嵌入到HTML页面, HTML内容与JAVA内容也可放在单独文件中,HTML内容的任何变动会自动编译装入到服务程序.
        Servlet需要在web.xml中配置,而JSP无需配置。
        目前JSP主要用在视图层,负责显示,而Servlet主要用在控制层,负责调度
联系:
        都是Sun公司推出的动态网页技术。
        先有Servlet,针对Servlet缺点推出JSP。JSP是Servlet的一种特殊形式,每个JSP页面就是一个Servlet实例——JSP页面由系统翻译成Servlet,Servlet再负责响应用户请求。
294_请简单描述下几个您熟悉JavaScript库,它们有哪些作用和特点?
        JavaScript 高级程序设计(特别是对浏览器差异的复杂处理),通常很困难也很耗时。为了应对这些调整,许多的 JavaScript库应运而生。这些 JavaScript 库常被称为 JavaScript 框架。
jQuery:
        Ext JS - 可定制的 widget,用于构建富因特网应用程序(rich Internet applications)。
        Prototype
        MooTools。
        YUI - Yahoo! User Interface Framework,涵盖大量函数的大型库,从简单的 JavaScript 功能到完整的 internet widget。
295_简单描述HTML,CSS,Javascript在Web开发中分别起什么作用?
        1、什么是HTML(超文本标记语言 Hyper Text Markup Language),HTML 是用来描述网页的一种语言。
        2、CSS(层叠样式表 Cascading Style Sheets),样式定义如何显示 HTML 元素,语法为:selector {property:value} (选择符 {属性:值})
        3、JavaScript是一种脚本语言,其源代码在发往客户端运行之前不需经过编译,而是将文本格式的字符代码发送给浏览器由浏览器解释运行
        对于一个网页,HTML定义网页的结构,CSS描述网页的样子,JavaScript设置一个很经典的例子是说HTML就像 一个人的骨骼、器官,而CSS就是人的皮肤,有了这两样也就构成了一个植物人了,加上javascript这个植物人就可以对外界刺激做出反应,可以思 考、运动、可以给自己整容化妆(改变CSS)等等,成为一个活生生的人。
        如果说HTML是肉身、CSS就是皮相、Javascript就是灵魂。没有Javascript,HTML+CSS是植物人,没有Javascript、CSS是个毁容的植物人。
        如果说HTML是建筑师,CSS就是干装修的,Javascript是魔术师。
296_当DOM加载完成后要执行的函数,下面哪个是正确的()
A    JQuery(expression, [context])
B.    JQuery(html, [ownerDocument])
C.    JQuery(callback)
答案:C
297_举例说明JAVA中如何解析xml,不同方式有和优缺点?
答:
1. DOM(Document Object Model)
        DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。
【优点】
        ①允许应用程序对数据和结构做出更改。
        ②访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。
【缺点】
        ①通常需要加载整个XML文档来构造层次结构,消耗资源大。
________________________________________
2. SAX(Simple API for XML)
        SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。
        选择DOM还是选择SAX? 对于需要自己编写代码来处理XML文档的开发人员来说, 选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX采用的是事件模型。
        DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档,所以对性能和内存的要求比较高,尤其是遇到很大的XML文件的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频繁的改变的服务中。
        SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。
【优势】
        ①不需要等待所有数据都被处理,分析就能立即开始。
        ②只在读取数据时检查数据,不需要保存在内存中。
        ③可以在某个条件得到满足时停止解析,不必解析整个文档。
        ④效率和性能较高,能解析大于系统内存的文档。
【缺点】
        ①需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),文档越复杂程序就越复杂。
        ②单向导航,无法定位文档层次,很难同时访问同一文档的不同部分数据,不支持XPath。
________________________________________
3. JDOM(Java-based Document Object Model)
        JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。
        JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。
        JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。JDOM对于大多数Java/XML应用程序来说当然是有用的,并且大多数开发者发现API比DOM容易理解得多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何在XML中无意义的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习DOM或JDOM接口都更有意义的工作。
        JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档(尽管它还可以将以前构造的DOM表示作为输入)。它包含一些转换器以将JDOM表示输出成SAX2事件流、DOM模型或XML文本文档。JDOM是在Apache许可证变体下发布的开放源码。
【优点】
        ①使用具体类而不是接口,简化了DOM的API。
        ②大量使用了Java集合类,方便了Java开发人员。
【缺点】
        ①没有较好的灵活性。
        ②性能较差。
________________________________________
4. DOM4J(Document Object Model for Java)
        虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始,它就一直处于开发之中。
        为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。
        在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。
        DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J.
【优点】  
        ①大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。  
        ②支持XPath。
        ③有很好的性能。
【缺点】
        ①大量使用了接口,API较为复杂。
________________________________________
 二、比较
        1. DOM4J性能最好,连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J.
        2. JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出,但可移植。在小文档情况下还值得考虑使用DOM和JDOM.虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型相对),所以在某些类型的项目中可能也需要它(如在JavaScript中使用DOM)。
        3. SAX表现较好,这要依赖于它特定的解析方式-事件驱动。一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。
        我的看法:如果XML文档较大且不考虑移植性问题建议采用DOM4J;如果XML文档较小则建议采用JDOM;如果需要及时处理而不需要保存数据则考虑SAX。但无论如何,还是那句话:适合自己的才是最好的,如果时间允许,建议大家讲这四种方法都尝试一遍然后选择一种适合自己的即可。
299_一个类可以实现多个接口,但只能继承一个抽象类。
       下面接着再说说两者在应用上的区别:
        接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码,伪代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25    public abstract classBaseServlet extends HttpServlet{
        public final void service(HttpServletRequest request,HttpServletResponse response) throws IOExcetion,ServletException       {
               记录访问日志
               进行权限判断
if(具有权限){
       try{
              doService(request,response);
}
       catch(Excetpion e)  {
                     记录异常信息
       }
}
        }
        protected abstract void doService(HttpServletRequest request,HttpServletResponse response) throws IOExcetion,ServletException; 
//注意访问权限定义成protected,显得既专业,又严谨,因为它是专门给子类用的
}
  
public class MyServlet1 extendsBaseServlet
{
protected voiddoService(HttpServletRequest request, HttpServletResponse response) throwsIOExcetion,ServletException
        {
               本Servlet只处理的具体业务逻辑代码
        }
  
}
        父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。
        备注:这道题的思路是先从总体解释抽象类和接口的基本概念,然后再比较两者的语法细节,最后再说两者的应用区别。比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性等6个方面逐一去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底。
300_比较一下Java 和JavaSciprt
        答:JavaScript 与Java是两个公司开发的不同的两个产品。Java 是原Sun 公司推出的面向对象的程序设计语言,特别适合于互联网应用程序开发;而JavaScript是Netscape公司的产品,为了扩展Netscape浏览器的功能而开发的一种可以嵌入Web页面中运行的基于对象和事件驱动的解释性语言,它的前身是LiveScript;而Java 的前身是Oak语言。
________________________________________
下面对两种语言间的异同作如下比较:
        1)基于对象和面向对象:Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象;JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。它是一种基于对象(Object-Based)和事件驱动(Event-Driven)的编程语言。因而它本身提供了非常丰富的内部对象供设计人员使用;
        2)解释和编译:Java 的源代码在执行之前,必须经过编译;JavaScript 是一种解释性编程语言,其源代码不需经过编译,由浏览器解释执行;
        3)强类型变量和类型弱变量:Java采用强类型变量检查,即所有变量在编译之前必须作声明;JavaScript中变量声明,采用其弱类型。即变量在使用前不需作声明,而是解释器在运行时检查其数据类型;
        4)代码格式不一样。
________________________________________
补充:上面列出的四点是原来所谓的标准答案中给出的。其实Java和JavaScript最重要的区别是一个是静态语言,一个是动态语言。目前的编程语言的发展趋势是函数式语言和动态语言。在Java中类(class)是一等公民,而JavaScript中函数(function)是一等公民。对于这种问题,在面试时还是用自己的语言回答会更加靠谱。 
301_什么时候用assert?
        答:assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后, assertion检查通常是关闭的。在实现中,断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为true;如果表达式计算为false,那么系统会报告一个AssertionError。
断言用于调试目的:
assert(a > 0); // throws an AssertionError if a <= 0
断言可以有两种形式:
assert Expression1;
assert Expression1 : Expression2 ;
Expression1 应该总是产生一个布尔值。
Expression2 可以是得出一个值的任意表达式;这个值用于生成显示更多调试信息的字符串消息。
断言在默认情况下是禁用的,要在编译时启用断言,需使用source 1.4 标记:
javac -source 1.4 Test.java
要在运行时启用断言,可使用-enableassertions 或者-ea 标记。
要在运行时选择禁用断言,可使用-da 或者-disableassertions 标记。
要在系统类中启用断言,可使用-esa 或者-dsa 标记。还可以在包的基础上启用或者禁用断言。可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过,断言不应该用于验证传递给公有方法的参数,因为不管是否启用了断言,公有方法都必须检查其参数。不过,既可以在公有方法中,也可以在非公有方法中利用断言测试后置条件。另外,断言不应该以任何方式改变程序的状态。 
302_UML是什么?UML中有哪些图?
        答:UML是统一建模语言(Unified Modeling Language)的缩写,它发表于1997年,综合了当时已经存在的面向对象的建模语言、方法和过程,是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持。使用UML可以帮助沟通与交流,辅助应用设计和文档的生成,还能够阐释系统的结构和行为。UML定义了多种图形化的符号来描述软件系统部分或全部的静态结构和动态结构,包括:用例图(use case diagram)、类图(class diagram)、时序图(sequence diagram)、协作图(collaboration diagram)、状态图(statechart diagram)、活动图(activity diagram)、构件图(component diagram)、部署图(deployment diagram)等。在这些图形化符号中,有三种图最为重要,分别是:用例图(用来捕获需求,描述系统的功能,通过该图可以迅速的了解系统的功能模块及其关系)、类图(描述类以及类与类之间的关系,通过该图可以快速了解系统)、时序图(描述执行特定任务时对象之间的交互关系以及执行顺序,通过该图可以了解对象能接收的消息也就是说对象能够向外界提供的服务)。
用例图:
  
类图:
  
时序图:
 
303_XML 文档定义有几种形式?它们之间有何本质区别?解析XML 文档有哪几种方式?
        答:        XML文档定义分为DTD和Schema两种形式;其本质区别在于Schema本身也是一个XML文件,可以被XML解析器解析。对XML的解析主要有DOM(文档对象模型)、SAX、StAX(JDK 1.6中引入的新的解析XML的方式,Streaming API for XML) 等,其中DOM处理大型文件时其性能下降的非常厉害,这个问题是由DOM 的树结构所造成的,这种结构占用的内存较多,而且DOM 必须在解析文件之前把整个文档装入内存,适合对XML 的随机访问(典型的用空间换取时间的策略);SAX是事件驱动型的XML解析方式,它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML 的顺序访问;如其名称所暗示的那样,StAX把重点放在流上。实际上,StAX与其他方法的区别就在于应用程序能够把XML作为一个事件流来处理。将XML作为一组事件来处理的想法并不新颖(事实上 SAX 已经提出来了),但不同之处在于StAX允许应用程序代码把这些事件逐个拉出来,而不用提供在解析器方便时从解析器中接收事件的处理程序。
304_你在项目中哪些地方用到了XML?
        答:XML的主要作用有两个方面:数据交换(曾经被称为业界数据交换的事实标准,现在此项功能在很多时候都被JSON取代)和信息配置。在做数据交换时,XML将数据用标签组装成起来,然后压缩打包加密后通过网络传送给接收者,接收解密与解压缩后再从XML文件中还原相关信息进行处理。目前很多软件都使用XML来存储配置信息,很多项目中我们通常也会将作为配置的硬代码(hard code)写在XML文件中,Java的很多框架也是这么做的。
305_用JavaScript实现用正则表达式验证,某个字符串是合法的6位数字的邮编的函数
1
2
3
4
5
6
7
8    Function testE(ss){
  var reg=/^[1-9][0-9]{5}$/;
  if(req.test(ss)){
    alert(“邮编OK”)
}else{
  alert(“邮编格式不正确”);
}
}
306_请使用JQuery将页面上的所有元素边框设置为2pix宽的虚线?
1    $(“*”).css(“border”,”2px dashed”)
307_如何设定JQuery异步调用还是同步调用?
答案:
        调用jQuery中的ajax函数,设置其async属性来表明是异步还是同步,如下:
1
2
3     $.ajax({
  async:true//表示异步,false表示同步
})
308_说出3条以上firefox和IE的浏览器兼容问题?
答案:
        兼容firefox的 outerHTML,FF中没有outerHtml的方法
        IE下,可以使用()或[]获取集合类对象;Firefox下,只能使用[]获取集合类对象.解决方法:统一使用[]获取集合类对象.
        IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute()获取自定义属性;Firefox下,只能使用getAttribute()获取自定义属性.解决方法:统一通过getAttribute()获取自定义属性
309_请用Jquery语言写出ajax请求或者post请求代码
1
2
3    $.post(“show”,{uname=”张三”,pwd=”123”},function(data){
  alert(data)
})

310_body中的onload()函数和jQuery中document.ready()有什么区别?
        答案:ready 事件的触发,表示文档结构已经加载完成(不包含图片等非文字媒体文件)。onload 事件的触发,表示页面包含图片等文件在内的所有元素都加载完成。
311_jQuery中有哪几种类型的选择器?
答案:
        基本选择器
        层次选择器
        基本过滤选择器
        内容过滤选择器
        可见性过滤选择器
        属性过滤选择器
        子元素过滤选择器
        表单选择器
        表单过滤选择器
312_EasyUI中datagrid刷新当前数据的方法?
        答案:使用reload()即可
313_分别写出一个div居中和其中的内容居中的css属性设置
Div居中:
        margin:auto 0px;
内容居中:
        text-align:center;
314_概述一下session与cookie的区别
答案:
        存储角度:
                Session是服务器端的数据存储技术,cookie是客户端的数据存储技术
        解决问题角度:
        Session解决的是一个用户不同请求的数据共享问题,cookie解决的是不同请求的请求数据的共享问题
        生命周期角度:
        Session的id是依赖于cookie来进行存储的,浏览器关闭id就会失效,Cookie可以单独的设置其在浏览器的存储时间。
315_JavaScript 中 null和 undefined 是否有区别?有哪些区别?
答案:
赋值角度说明:
        null 表示此处没有值,undefined表示此处定义了但是没有赋值
从数据转换角度:
        Null在做数值转换时会被转换为0,undefined会被转换为NaN
316_Servlet中的doPost和doGet方法有什么区别?它们在传递和获取参数上有什么区别?
答案:
        区别:
            doPost用来处理post请求,doGet用来处理get请求
                获取参数:
                        获取的参数是相同的都是HttpServletRequest \HttpServletResponse
317_请写出一段jQuery代码,实现把当前页面中所有的a元索中class 属性为“view-link”的链接都改为在新窗口中打开
答案:
1    $(“a[class=view-link]”).attr(“target”,”_blank”)
318_如下JavaScript代码的输出为:
1
2
3
4
5
6    var scope ="global scope";
function checkscope() {
var scope ="local scope”;
     return function() { return scope}
}
console.log (checkscope()());
        输出:global scope
319_Jquery中’.get()’与’.eq()’的区别
        eq返回的是一个jquery对象   get返回的是一个html 对象
320_如何给weblogic定内存的大小?
        在启动Weblogic的脚本中(位于所在Domian对应服务器目录下的startServerName),增加set MEM_ARGS=-Xms32m -Xmx200m,可以调整最小内存为32M,最大200M
321_TCP为何采用三次握手来建立连接,若釆用二次握手可以吗,请说明理由?
        三次握手是为了防止已失效的连接请求再次传送到服务器端。 二次握手不可行,因为:如果由于网络不稳定,虽然客户端以前发送的连接请求以到达服务方,但服务方的同意连接的应答未能到达客户端。则客户方要重新发送连接请求,若采用二次握手,服务方收到重传的请求连接后,会以为是新的请求,就会发送同意连接报文,并新开进程提供服务,这样会造成服务方资源的无谓浪费
322_以下HTTP相应状态码的含义描述正确的是()
A.    200ok表示请求成功
B.    400不良请求表示服务器未发现与请求URL匹配内容
C.    404未发现表示由于语法错误儿导致服务器无法理解请求信息
D.    500内部服务器错误,无法处理请求
答案:D
分析:
A. 200ok 表示的意思是一切正常。一般用于相应GET和POST请求。这个状态码对servlet是缺省的;如果没有调用setStatus方法的话,就会得到200。
B. 400 表示指出客户端请求中的语法错误
C. 404 客户端所给的地址无法找到任何资源
323_JSP页面包括哪些元素?()
A.    JSP命令
B.    JSP Action
C.    JSP脚本
D.    JSP控件
答案:C
分析:JSP页面元素构成如下,因此ABD错误
 
324_Ajax有四种技术组成:DOM,CSS,JavaScript,XmlHttpRequest,其中控制文档结构的是()
A.     DOM
B.    CSS
C.    JavaScript
D.    XmlHttpRequest
答案:A
325_下面关于session的用法哪些是错误的?()
A.    HttpSession session=new HttpSession();
B.    String haha=session getParameler(:haha”);
C.    session.removeAttribute(“haha”);
D.    session.setAttribute(:haha:);XmlHttpRequest
答案:A
326_Jsp九大内置对象
答案:
1、request对象
        request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。request对象的作用域为一次请求。
________________________________________
2、response对象
        response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域,它只在JSP页面内有效。
________________________________________
3、session对象
        session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据,因此保存数据的格式为 “Key/value”。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。
________________________________________
4、application对象
         application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。
________________________________________
5、out 对象
        out 对象用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。在使用 out 对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。待数据输出完毕后,要及时关闭输出流。
________________________________________
6、pageContext 对象
        pageContext 对象的作用是取得任何范围的参数,通过它可以获取 JSP页面的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,在JSP页面中可以直接使用 pageContext对象。
________________________________________
7、config 对象
        config 对象的主要作用是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。
________________________________________
8、page 对象
        page 对象代表JSP本身,只有在JSP页面内才是合法的。 page隐含对象本质上包含当前 Servlet接口引用的变量,类似于Java编程中的 this 指针。
________________________________________
9、exception 对象
        exception 对象的作用是显示异常信息,只有在包含 isErrorPage="true" 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。excepation对象和Java的所有对象一样,都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。在Java程序中,可以使用try/catch关键字来处理异常情况; 如果在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 exception 对象。
327_如何配置一个servlet?
在web.xml中使用如下标签:
<servlet>
 <servlet-name></servlet-name>
 <servlet-class></servlet-class>
</servlet>
<servlet-mapping>
 <servlet-name></servlet-name>
 <url-pattern></url-pattern>
</servlet-mapping>
或者使用注解方式:
@WebServlet(name="servlet", urlPatterns={"/*"})
328_JavaScript,如何定义含有数值1至8的数组?
答:  var arr=[1,2,3,4,5,6,7,8]
329_以下JavaScipt语句会产生运行错误的是_()
A.    var obj=( );
B.    var obj=[ ];
C.    var obj=//;
D.    var obj=1;
答案:AC
330_在JSP中,下面__()__块中可以定义一个新类:
A.    <%  %>
B.    <% ! %>
C.    <%@ %>
D.    <%=%>
答案:B
分析:B <% ! %> 可用作声明
A不正确
C为引用xxx,比如<% @page xxxxx%>
D为表达式
331_HTML含义和版本变化
HTML含义:
        Hyper Text Markup Language 超文本标记语言,是一种用来制作“网页”的简单标记语言;用HTML编写的超文本文档称为HTML文档,HTML文档的扩展名是html或者htm
版本变化:
        HTML1.0——在1993年6月作为IETF工作草案发布(并非标准)
        HTML 2.0——1995年11月作为RFC 1866发布
        HTML 3.2——1997年1月14日,W3C推荐标准
        HTML 4.0——1997年12月18日,W3C推荐标准
        HTML 4.01(微小改进)——1999年12月24日,W3C推荐标准
        HTML 5—2014年10月28日,W3C推荐标准HTML文档结构;
        HTML 5.1 - 2016年
        HTML 5.2 – 2018年最新版本
        HTML 5.3 is coming…
332_什么是锚链接
        锚链接是带有文本的超链接。可以跳转到页面的某个位置,适用于页面内容较多,超过一屏的场合 。分为页面内的锚链接和页面间的锚链接 。
例如:
        <a name=”1F”>1F</a><a name=”2F”>2F</a>
        <a href=”#2F”>跳转到2F标记位置</a>
 说明:
        1.在标记位置利用a标签的name属性设置标记。
        2.在导航位置通过a标签的href属性用#开头加name属性值即可跳转锚点位置。
333_HTML字符实体的作用及其常用字符实体
        有些字符,比如说“<”字符,在HTML中有特殊的含义,因此不能在文本中使用。想要在HTML中显示一个小于号“<”,需要用到字符实体:<或者<
        字符实体拥有三个部分:一个and符号(&),一个实体名或者一个实体号,最后是一个分号(;)
        常用字符实体:
 
334_HTML表单的作用和常用表单项类型
        表单的作用:
                利用表单可以收集客户端提交的有关信息。
        常用表单项类型:     
 
335_表格、框架、div三种HTML布局方式的特点 
 
336_form中input设置为readonly和disabled的区别
 
337_CSS的定义和作用
CSS的定义:CSS是Cascading Style Sheets(层叠样式表)的简称。
        CSS是一系列格式规则,它们控制网页内容的外观。CSS简单来说就是用来美化网页用的。
CSS的具体作用包括:
        使网页丰富多彩,易于控制。
        页面的精确控制,实现精美、复杂页面 。
        样式表能实现内容与样式的分离,方便团队开发。
        样式复用、方便网站的后期维护。
338_CSS2常用选择器类型及其含义
 
339_引入样式的三种方式及其优先级别
三种引用方式:
1. 外部样式表(存放.css文件中)
        不需要style标签
        <link rel=”stylesheet”  href=”引用文件地址” />
2. 嵌入式样式表
        <style type=“text/css”>
        p{color:red;}
        </style>
3.内联样式
        标签属性名为style
        <p style=“color:red;”></p>
优先级级别:内联定义最高、内部CSS次之、外部CSS优先级最低。
340_盒子模型
   盒子模型类似于生活中的盒子,具有4个属性,外边距,内边距,边框,内容。
   外边距:margin,用于设置元素和其他元素之间的距离。
   内边距:padding,用于设置元素内容和边框之间的距离。
   边框:border,用于设置元素边框粗细,颜色,线型。
   内容:width,height,用于设置元素内容显示的大小。
 
   例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20    <style>
    body{
      margin: 0;  /*取消body默认的外边距*/
    }      
#img1{
width:200px;   /*设置图片的宽度*/
border: 2px solid black; /*设置图片边框*/
margin: 5px;
/*设置图片外边距(表示该图片与其他图片的距离为5px)*/
padding:10px; /*设置图片与边框之间的距离*/
}  
#img2{
height: 200px; /* 设置图片的高度*/
border: 2px solid black; /*设置图片的边框*/
margin: 5px; /*设置图片外边距*/
padding: 20px; /*设置图片与边框之间的距离*/
}
</style>
<img id="img1" src="img/2.jpg" />
<img id="img2" src="img/lss.jpg" />
341_JavaScript语言及其特点
    Javascript一种基于对象(object-based)和事件驱动(Event Driven)的简单的并具有安全性能的脚本语言。
特点:
解释性:JavaScript不同于一些编译性的程序语言,例如C、C++等,它是一种解释性的程序语言,它的源代码不需要经过编译,而直接在浏览器中运行时被解释。
基于对象:  JavaScript是一种基于对象的语言。这意味着它能运用自己已经创建的对象。因此,许多功能可以来自于脚本环境中对象的方法与脚本的相互作用。
事件驱动:JavaScript可以直接对用户或客户输入做出响应,无须经过Web服务程序。它对用户的响应,是以事件驱动的方式进行的。所谓事件驱动,就是指在主页中执行了某种操作所产生的动作,此动作称为“事件”。比如按下鼠标、移动窗口、选择菜单等都可以视为事件。当事件发生后,可能会引起相应的事件响应。
跨平台:JavaScript依赖于浏览器本身,与操作环境无关,只要能运行浏览器的计算机,并支持JavaScript的浏览器就可正确执行。
342_JavaScript常用数据类型有哪些
数值型(Number):整数和浮点数统称为数值。例如85或3.1415926等。
字符串型(String):由0个,1个或多个字符组成的序列。在JavaScript中,用双引号或单引号括起来表示,如“您好”、‘学习JavaScript’等。 不区分单引号、双引号。
逻辑(布尔)型(Boolean):用true或false来表示。
空(null)值(Null):表示没有值,用于定义空的或不存在的引用。要注意:空值不等同于空字符串""或0。
未定义(Undefined)值:它也是一个保留字。表示变量虽然已经声明,但却没有赋值。
除了以上五种基本的数据类型之外,JavaScript还支持复合数据类型,包括对象和数组两种。
343_html语法中哪条命令用于使一行文本折行,而不是插入一个新的段落? 
A.    <TD>
B.    <BR>
C.    <P>
D.    <H1>
(B)
分析:
A <td>定义标准表格
C <p>表示文本一个段落
D <h1>表示对文本标题进行强调的一种标签
344_Ajax的优点和缺点
优点:减轻服务器的负担,按需取数据,最大程度的减少冗余请求,局部刷新页面,减少用户心理和实际的等待时间,带来更好的用户体验,基于xml标准化,并被广泛支持,不需安装插件等,进一步促进页面和数据的分离。
缺点:AJAX大量的使用了javascript和ajax引擎,这些取决于浏览器的支持.在编写的时候考虑对浏览器的兼容性.
345_怎样防止表单刷新重复提交问题?(说出思路即可)
JS脚本方式:
        第一种:定义全局变量,在form提交前判断是否已有提交过
1
2
3
4
5
6
7
8
9
10
11
12    <script>   
   var checkSubmitFlg = false;  
   function checkSubmit(){   
     if(checkSubmitFlg == true){   
return false;   
     }    
     checkSubmitFlg = true;   
     return true;  
  }
 </script>   
<form action="" οnsubmit="return checkSubmit();">
</form>
       第三种:单击提交按钮后,弹出屏蔽层,防止用户第二次点击
        第二种:单击提交按钮后,立刻禁用改按钮
345_怎样防止表单刷新重复提交问题?(说出思路即可)
JS脚本方式:
        第一种:定义全局变量,在form提交前判断是否已有提交过
1
2
3
4
5
6
7
8
9
10
11
12    <script>   
   var checkSubmitFlg = false;  
   function checkSubmit(){   
     if(checkSubmitFlg == true){   
return false;   
     }    
     checkSubmitFlg = true;   
     return true;  
  }
 </script>   
<form action="" οnsubmit="return checkSubmit();">
</form>
       第三种:单击提交按钮后,弹出屏蔽层,防止用户第二次点击
        第二种:单击提交按钮后,立刻禁用改按钮
346_JQuery.get()和JQuery.ajax()方法之间的区别是什么?
        JQuery.ajax()是对原生的javaScript的ajax的封装,简化了ajax的步骤,用户可用JQuery.ajax()发送get或者post方式请求,Jquery.get()是对ajax的get方式的封装,只能发送get方式的请求。
347_Jquery里的缓存问题如何解决?例如($.ajax()以及$.get())
        $.ajax()请求时候加上cache:false的参数,如:
1
2
3
4
5
6
7
8    $.ajax({  
    type : "get",  
    url : "XX",  
    dataType : "json",  
    cache:false,  
    success : function(json) {  
    }  
});
        $.get()请求时候加上时间,如:
1
2    $.get("url","data"+new Date(),function(data){
);
348_Javascript是面向对象的,怎么体现Javascript的继承关系?
        Javascript里面没有像java那样的继承,javascript中的继承机制仅仅是靠模拟的,可以使用prototype原型来实现
349_Javascript的有几种种变量。变量范围有什么不同?
可以分为三种
    1:原生类型(string,number,boolean)
    2:对象(Date,Array)
    3:特殊类型(var vara;(只什么没有定义),var varb = null;(定义一个变量并赋值为null))
350_Js如何获取页面的dom对象
1:直接获取
        //1.1 -- id方式获取  
        var varid = document.getElementById("unameid");    
        //1.2 -- name获取(获取的是数组对象)
        var varname = document.getElementsByName("sex");    
        //1.3 -- 元素获取(获取的是数组对象)
        var varinput = document.getElementsByTagName("input");  
2:间接方式获取  
        //2.1 父子关系 --childNodes
        var varchilds = document.getElementById("div01").childNodes;
        //2.2 子父关系--parentNode
        var varfather2 = document.getElementById("unameid").parentNode;
        //2.3 兄弟之间相互获取  nextSibling:下一个节点    previousSibling:上一个节点
351_Servlet API中forward() 与redirect()的区别?
答:
        为实现程序的模块化,就需要保证在不同的Servlet之间可以相互跳转,而Servlet中主要有两种实现跳转的方式:FORWARD方式与redirect方式。 
        Forward() : 是服务器内部的重定向,服务器直接访问目标地址的URL,把那个URL的响应内容读取出来,而客户端并不知道,因此在客户端浏览器的地址栏里不会显示跳转后的地址,还是原来的地址。由于在整个定向的过程中用的是同一个Request,因此FORWARD会将Request的信息带到被定向的JSP或Servlet中使用。
        Redirect():则是客户端的重定向,是完全的跳转,即客户端浏览器会获取跳转后的地址,然后重新发送请求,因此浏览器中会显示跳转后的地址。同时,由于这种方式比FORWARD方式多了一次网络请求,因此其效率低于FORWARD方式,需要注意到的是,客户端的重定向可以通过设置特定的HTTP 头或写JavaScript脚本来实现。
        鉴于以上的区别,一般当FORWARD方式可以满足需求时,尽可能的使用FORWARD方式。但在有些情况下,例如,需要跳转到一个其他服务器上的资源时,则必须使用redirect 方式。
352_Session域和request域什么区别?
作用域:存放数据,获取数据(传递数据)
有效的作用域:生命周期,作用范围
httpServeltRequest:
            生命周期 :一次请求之间
            作用范围:所有被请求转发过的servlet都能获取到
httpSession:
            生命周期:一次会话
            作用范围:所有的servlet都可以获取到
servletContex:
            生命周期:从项目开始运行到服务器关闭
            作用范围:所有的servlet都可以获取到
作用域如何选用?
      httpServeltRequest:和当前请求有关的信息
      httpSession:和当前用户有关的信息
      servletContex:访问量比较大,不易更改
353_页面中有一个命名为bankNo的下拉列表,写js脚本获取当前选项的索引值,如果用jquery如何获取
1
2    var a = document.getElementsByName("bankNo")[0].value;
var b = $("select[name=bankNo]").val();
354_写出要求11位数字的正则表达式
        ^[1-9]\d{10}$
355_分别获取指定name、Id的javascript对象,如果用jquey如何获取
js:
  id--document.getElementById("id");
  name--document.getElementsByName("name");
jquery
  id--$("#id");
  name--$("元素名称[name="name值"]");
356_一个页面有两个form,如何获取第一个form
用id方式获取;document.getElementById("id");
357_如何设置一个层的可见/隐藏
        可见:document.getElementById("divid").style.display = "block";
        隐藏:document.getElementById("divid").style.display = "none"; 
358_描述JSP中动态INCLUDE与静态INCLUDE的区别?
        动态导入
                1:会将多个jsp页面分别再编写成java文件,编译成class文件
                2:jsp文件中允许有相同的变量名,每个页面互不影响
                3: 当java代码比较多优先选用动态导入
                4:效率相对较低,耦合性低
        静态导入
                1:会将多个jsp页面合成一个jsp页面,再编写成java文件,编译成class文件
                2:jsp文件中不允许有相同的变量名
                3: 当java代码比较少或者没有java代码是优先选用静态导入
                4:效率相对较高,耦合性高
359_列举JSP的内置对象及方法
________________________________________
request表示HttpServletRequest对象。它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, header, 和session数据的有用的方法。 
________________________________________
response表示HttpServletResponse对象,并提供了几个用于设置送回 浏览器的响应的方法(如cookies,头信息等) 
________________________________________
out对象是javax.jsp.JspWriter的一个实例,提供了几个方法使你能用于向浏览器回送输出结果
________________________________________
pageContext表示一个javax.servlejt.sp.PageContext对象。它是用于方便存取各种范围的名字空间、servlet相关的对象的API,并且包装了通用的servlet相关功能的方法。 
________________________________________
session表示一个请求的javax.servlet.http.HttpSession对象。Session可以存贮用户的状态信息
________________________________________
applicaton 表示一个javax.servle.ServletContext对象。这有助于查找有关servlet引擎和servlet环境的信息 
________________________________________
config表示一个javax.servlet.ServletConfig对象。该对象用于存取servlet实例的初始化参数。 
________________________________________
page表示从该页面产生的一个servlet实例
________________________________________
Exception:异常
360_列举jsp的四大作用域
        page、request、session、application
361_html和xhtml的区别是什么?
________________________________________
        HTML与XHTML之间的差别,粗略可以分为两大类比较:一个是功能上的差别,另外是书写习惯的差别。关于功能上的差别,主要是XHTML可兼容各大浏览器、手机以及PDA,并且浏览器也能快速正确地编译网页。
        因为XHTML的语法较为严谨,所以如果你是习惯松散结构的HTML编写者,那需要特别注意XHTML的规则。但也不必太过担心,因为XHTML的规则并不太难。下面列出了几条容易犯的错误,供大家引用。
________________________________________
1:所有标签都必须小写
        在XHTML中,所有的标签都必须小写,不能大小写穿插其中,也不能全部都是大写。看一个例子。
        错误:<Head></Head><Body></Body>
        正确:<head></head><body></body>
________________________________________
2:标签必须成双成对
            像是<p>...</p>、<a>...</a>、<div>...</div>标签等,当出现一个标签时,必须要有对应的结束标签,缺一不可,就像在任何程序语言中的括号一样。
        错误:大家好<p>我是muki
        正确:<p>大家好</p><p>我是muki</p>
________________________________________
3:标签顺序必须正确
        标签由外到内,一层层包覆着,所以假设你先写div后写h1,结尾就要先写h1后写div。只要记住一个原则“先进后出”,先弹出的标签要后结尾。
        错误:<div><h1>大家好</div></h1>
        正确:<div><h1>大家好</h1></div>
________________________________________
4:所有属性都必须使用双引号
        在XHTML 1.0中规定连单引号也不能使用,所以全程都得用双引号。
        错误:<div style=font-size:11px>hello</div>
        正确:<div style="font-size:11px">hello</div
________________________________________
5:不允许使用target="_blank"
        从XHTML 1.1开始全面禁止target属性,如果想要有开新窗口的功能,就必须改写为rel="external",并搭配JavaScript实现此效果。
        错误:<a href="http://blog.mukispace.com" target="_blank">MUKI space</a>
        正确:<a href="http://blog.mukispace.com" rel="external">MUKI space</a> 
362_你做的页面用哪些浏览器测试过?这些测试的内核分别是什么?
________________________________________
1、Trident内核代表产品Internet Explorer,又称其为IE内核。 
        Trident(又称为MSHTML),是微软开发的一种排版引擎。使用Trident渲染引擎的浏览器包括:IE、傲游、世界之窗浏览器、Avant、腾讯TT、Netscape 8、NetCaptor、Sleipnir、GOSURF、GreenBrowser和KKman等。 
________________________________________
2、Gecko内核代表作品Mozilla 
        FirefoxGecko是一套开放源代码的、以C++编写的网页排版引擎。Gecko是最流行的排版引擎之一,仅次于Trident。使用它的最著名浏览器有Firefox、Netscape6至9。 
________________________________________
3、WebKit内核代表作品Safari、Chromewebkit 
        是一个开源项目,包含了来自KDE项目和苹果公司的一些组件,主要用于Mac OS系统,它的特点在于源码结构清晰、渲染速度极快。缺点是对网页代码的兼容性不高,导致一些编写不标准的网页无法正常显示。主要代表作品有Safari和Google的浏览器Chrome。 
________________________________________
4、Presto内核代表作品OperaPresto 
        是由Opera Software开发的浏览器排版引擎,供Opera 7.0及以上使用。它取代了旧版Opera 4至6版本使用的Elektra排版引擎,包括加入动态功能,例如网页或其部分可随着DOM及Script语法的事件而重新排版。
363_你遇到了哪些浏览器的兼容性问题?怎么解决的?
        答:因为不同的浏览器对同一段代码有不同的解析,造成页面显示效果不统一的情况;这是我们常见的兼容性问题。
解决方法:
        1:针对不同的浏览器写不同的代码
        2:使用jquery屏蔽浏览器差异
遇到不同的兼容问题,需要针对前端进行兼容适配;
364_你知道的常用的js库有哪些?
 1.moment.js  
举个例子:
用js转换时间戳为日期
let date = new Date(1437925575663);
        let year = date.getFullYear() + '-';
        let month = ( date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) :
date.getMonth() + 1 ) + '-';
        let day = date.getDate();
...
        return year + month + day;
用moment.js
return moment(1437925575663).format('YYYY-MM-DD HH:mm:ss')
2.chart.js
绘制简单的柱状图,曲线图,蛛网图,环形图,饼图等完全够用,用法比较简单。
3.D3.js
功能太强大了,看首页就知道了,感觉没有什么图d3绘不出来的。
4.Rx.js
很好的解决了异步和事件组合的问题。
5.lodash.js
365_Js中的三种弹出式消息提醒(警告窗口、确认窗口、信息输入窗口)的命令是什么?
________________________________________
alter(),confirm(),prompt()
 (4)执行 A, 并把 A 的返回结果赋值给变量 C
(5)执行 C
________________________________________
把这5步操作总结成一句话就是:
函数A的内部函数B被函数A外的一个变量 c 引用。
________________________________________
把这句话再加工一下就变成了闭包的定义:
当一个内部函数被其外部函数之外的变量引用时,就形成了一个闭包。
________________________________________
因此,当你执行上述5步操作时,就已经定义了一个闭包!
这就是闭包。 
367_写一段js,遍历所有的li,将每个li的内容逐个alert出来
________________________________________
1
2
3
4
5
6
7
8    <body>
      <ul>
        <li>张三:123</li>
        <li>李四:456</li>
        <li>王五:789</li>
        <li>赵六:147</li>
<ul>
   <body>

1
2
3
4
5
6    function test(){
  var varli = document.getElementsByTagName("li");
  for (var i=0;i<varli.length;i++) {
    alert(varli[i].innerText);
  }
}
368_页面上如何用JavaScript对多个checkbox全选
1
2
3
4
5
6
7
8
9
10    //全选
function checkAll(){
//获取复选框对象--数组对象
var varcheck = document.getElementsByName("name");
//alert(varcheck.length);
//遍历for
for(var i=0;i<varcheck.length;i++){
varcheck[i].checked = true;
}
}
369_写一个简单的JQuery的ajax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35    <script type="text/javascript" src="js/jquery-1.9.1.js" charset="utf-8"></script>
<script type="text/javascript">
function testJqAjax(){
//url  :请求地址
//type :请求的方式 get/post
//data :请求的参数(json/String)
//cache:true(走缓存 )  false(不走缓存)
//result:当ajax发送成功后会调用success后面的函数,result:相当于形参,返回的数据
//async:是否为异步请求 默认true异步 , false同步
$.ajax({
url:"TestJqAjax",
type:"get",
/* data:"uname=zhangsan&realname=张三丰", */
data:{uname:"zhangsan",realname:"张三丰"},
cache:false,
async:false,
success:function(result){
alert(result);
}
});
}
//ajax的get方式的请求
function jqAjaxGet(){
//url,[data],[callback](当ajax发送成功后调用的函数)
$.get("TestJqAjax",{uname:"zhangsan",realname:"张三丰"},function(result){
alert(result);
});
}
function  jqAjaxPost() {
//url,[data],[callback](当ajax发送成功后调用的函数)
$.post("TestJqAjax",{uname:"zhangsan",realname:"张三丰"},function(result){
alert(result);
});
}
</script>
370_J s截取字符串abcdefg的efg
1
2
3
4
5    Function test2(){
var str = "abcdefg";
var substr = str.substring(4);
alert(substr);
}
371_http的请求头信息包含了什么?
请求行(请求方式,资源路径,协议和协议版本号)
若干请求头
请求实体内容
372_http的响应码200,404,302,500表示的含义分别是?
        200 - 确定。客户端请求已成功
        302 - 临时移动转移,请求的内容已临时移动新的位置
        404 - 未找到文件或目录
        500 - 服务器内部错误
373_Servlet中request对象的方法有?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48    //获取网络信息
private void getNet(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("TestHttpRequest.getNet(获取客户端的ip):"+req.getRemoteAddr());
System.out.println("TestHttpRequest.getNet(获取客户端的端口):"+req.getRemotePort());
System.out.println("TestHttpRequest.getNet(获取服务器的ip):"+req.getLocalAddr());
System.out.println("TestHttpRequest.getNet(获取服务器的端口):"+req.getLocalPort());
}
  
//获取实体内容
private void getContent(HttpServletRequest req, HttpServletResponse resp) {
//获取单条信息
String uname = req.getParameter("uname");
//获取多条信息,数组格式
String[] favs = req.getParameterValues("fav");
//遍历数组
//判断
if(favs!=null&&favs.length>0){
for (int i = 0; i < favs.length; i++) {
System.out.println("TestHttpRequest.getContent(fav):"+favs[i]);
}
}
String un = req.getParameter("un");
System.out.println("TestHttpRequest.getContent():"+uname+"--"+favs+"--"+un);
}
  
//获取请求头信息
private void getHeads(HttpServletRequest req, HttpServletResponse resp) {
//获取单条头信息
//System.out.println("TestHttpRequest.getHeads(获取请求头信息-浏览器头信息):"+req.getHeader("User-Agent"));
//获取所有头信息--返回枚举类型
Enumeration strHeads = req.getHeaderNames();
//遍历枚举类型
while (strHeads.hasMoreElements()) {
String strhead = (String) strHeads.nextElement();
System.out.println("TestHttpRequest.getHeads(获取头信息):"+req.getHeader(strhead));
}
}
  
//获取请求行的信息
private void getLines(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("TestHttpRequest.getLines(请求方式***):"+req.getMethod());
System.out.println("TestHttpRequest.getLines(资源路径):"+req.getRequestURI());
System.out.println("TestHttpRequest.getLines(地址):"+req.getRequestURL());
System.out.println("TestHttpRequest.getLines(协议):"+req.getScheme());
System.out.println("TestHttpRequest.getLines(协议的版本号):"+req.getProtocol());
System.out.println("TestHttpRequest.getLines(获取参数信息):"+req.getQueryString());
System.out.println("TestHttpRequest.getLines(项目名称***):"+req.getContextPath());
}
374_JavaScript中获取某个元素的三种方式JavaScript中的三种弹出式消息提醒命令是什么?
________________________________________
window.alert()显示一个提示信息
window.confirm() 显示一个带有提示信息、确定和取消按钮的对话框
window.prompt()显示可提示用户输入的对话框
________________________________________
setTimeout与setInterval 的区别:
        setTimeout和setInterval的语法相同。它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将执行那段代码。
        不过这两个函数还是有区别的,setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。
________________________________________
window.setTimeout("function",time);//设置一个超时对象,只执行一次,无周期 
window.setInterval("function",time);//设置一个超时对象,周期='交互时间'
377_JavaScript操作CSS的两种方式
        第一种方式:操作元素的属性(对象.style.样式名=样式值;)
         //改变直接样式
1
2
3
4    var child2 = document.createElement("div");
    child2.innerHTML = "child2";
    child2.style.fontWeight = "bold";
    parent.appendChild(child2);
________________________________________
        第二种方式:操作元素的类(对象.className=类;)
    例如:
1    <p style="line-height: 1.5em;">var parent = document.getElementById("parent");     <br>   //改变className<br>   var child0 = document.createElement("div");<br>   child0.innerHTML = "child0";<br>   child0.className = "newDiv";<br>parent.appendChild(child0);<br></p>
378_静态网页和动态网页的联系和区别 
________________________________________
    联系:
    1)静态网页是网站建设的基础,静态网页和动态网页都要使用到HTMl语言。
    2)静态网页是相对于动态网页而言,指没有后台数据库、不含程序和不可交互的网页、是标准的HTML文件,它的文件扩展名是.htm或.html。你编的是什么它显示的就是什么、不会有任何改变。
    3)静态网页和动态网页之间并不矛盾,为了网站适应搜索引擎检索的需要,动态网站可以采用静动结合的原则,适合采用动态网页的地方用动态网页,如果必要使用静态网页,则可以考虑用静态网页的方法来实现,在同一个网站上,动态网页内容和静态网页内容同时存在也是很常见的事情。
________________________________________
    区别:
    1)程序是否在服务器端运行,是重要标志。在服务器端运行的程序、网页、组件,属于动态网页,它们会随不同客户、不同时间,返回不同的网页,例如ASP、PHP、JSP、ASP.net、CGI等。运行于客户端的程序、网页、插件、组件,属于静态网页,例如html页、Flash、javascript、VBscript等等,它们是永远不变的。
    2)编程技术不同。静态网页和动态网页主要根据网页制作的语言来区分。静态网页使用语言:HTML。 动态网页使用语言:HTML+ASP 或 HTML+PHP 或 HTML+JSP 等其它网站动态语言。
    3)被搜索引擎收录情况不同。由于编程技术不容,静态网页是纯粹HTML格式的网页,页面内容稳定,不论是网页是否被访问,页面都被保存在网站服务器上,很容易被搜索引擎收录。而动态网页的内容是当用户点击请求时才从数据库中调出返回给用户一个网页的内容,并不是存放在服务器上的独立文件,相比较于静态网页而言,动态网页很难被搜索引擎收录。
    4)用户访问速度不同。用户访问动态网页时,网页在获得搜索指令后经过数据库的调查匹配,再将与指令相符的内容传递给服务器,通过服务器的编译将网页编译成标准的HTML代码,从而传递给用户浏览器,多个读取过程大大降低了用户的访问速度。而静态网页不同,由于网页内容直接存取在服务器上,省去了服务器的编译过程,用户访问网页速度很快。
    5)制作和后期维护工作量不同。动态网页的设计以数据库技术为基础,可以实现多种功能,降低了网站维护的工作量。而静态网页由于没有数据库的支持,网页内容更改时需要直接修改代码,在网站内容制作和维护中,所需的工作量更大。
________________________________________
        动态网页与静态网页各有特点,网站设计师在网页设计时,主要根据网站的功能需求和网站内容多少选择不同网页。如,网站包含信息量太大时,就需要选择动态网页,反之,则选择静态网页。
379_JSP/ASP/PHP的比较 
        ASP(Active Server Pages),JSP(JavaServer Pages),PHP(Hypertext Preprocessor)是目前主流的三种动态网页语言。
        ASP是微软(Microsoft)所开发的一种后台脚本语言,它的语法和Visual BASIC类似,可以像SSI(Server Side Include)那样把后台脚本代码内嵌到HTML页面中。虽然ASP简单易用,但是它自身存在着许多缺陷,最重要的就是安全性问题。
________________________________________
        PHP是一种跨平台的服务器端的嵌入式脚本语言。它大量地借用C,Java和Perl语言的语法, 并耦合PHP自己的特性,使WEB开发者能够快速地写出动态产生页面。它支持目前绝大多数数据库。
        JSP是一个简化的Servlet,它是由Sun公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML中插入Java程序段和JSP标记(tag),从而形成JSP文件,后缀名为(*.jsp)。 用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。
________________________________________
       ASP优点:无需编译、易于生成、独立于浏览器、面向对象、与任何ActiveX scripting 语言兼容、源程序码不会外漏。
        缺点:
        1) Windows本身的所有问题都会一成不变的也累加到了它的身上。安全性、稳定性、跨平台性都会因为与NT的捆绑而显现出来。
        2) ASP由于使用了COM组件所以它会变的十分强大,但是这样的强大由于Windows NT系统最初的设计问题而会引发大量的安全问题。只要在这样的组件或是操作中一不注意,那么外部攻击就可以取得相当高的权限而导致网站瘫痪或者数据丢失。
        3) 还无法完全实现一些企业级的功能:完全的集群、负载均横。
________________________________________
        PHP优点:
        1)一种能快速学习、跨平台、有良好数据库交互能力的开发语言。
        2)简单轻便,易学易用。
        3) 与Apache及其它扩展库结合紧密。
        缺点:
        1) 数据库支持的极大变化。
        2) 不适合应用于大型电子商务站点。
________________________________________
     JSP优点:
       1)  一处编写随处运行。
       2)  系统的多台平支持。
       3)  强大的的可伸缩性。
       4)  多样化和功能强大的开发工具支持。
     缺点:
       1)  与ASP一样,Java的一些优势正是它致命的问题所在。
       2)  开发速度慢
380_CGI/Servlet/JSP的比较
________________________________________
        CGI(Common Gateway Interface),通用网关接口,是一种根据请求信息动态产生回应内容的技术。
________________________________________
       通过CGI,Web 服务器可以将根据请求不同启动不同的外部程序,并将请求内容转发给该程序,在程序执行结束后,将执行结果作为回应返回给客户端。也就是说,对于每个请求,都要产生一个新的进程进行处理。
________________________________________
        Servlet 是在服务器上运行的小程序。在实际运行的时候Java Servlet与Web服务器会融为一体。与CGI不同的是,Servlet对每个请求都是单独启动一个线程,而不是进程。这种处理方式大幅度地降低了系统里的进程数量,提高了系统的并发处理能力。
________________________________________
        比较:
        1) JSP从本质上说就是Servlet。JSP技术产生于Servlet之后,两者分工协作,Servlet侧重于解决运算和业务逻辑问题,JSP则侧重于解决展示问题。
        2) 与CGI相比,Servlet效率更高。Servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁。而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于Servlet 。
       3)与CGI相比,Servlet更容易使用,功能更强大,具有更好的可移植性,更节省投资。在未来的技术发展过程中,Servlet有可能彻底取代CGI。
381_HTTP协议工作原理及其特点
        超文本传输协议(HTTP:Hypertext Transport Protocol)是万维网应用层的协议,它通过两个程序实现:一个是客户端程序(各种浏览器),另一个是服务器 (常称Web服务器)。这两个通常运行在不同的主机上,通过交换报文来完成网页请求和响应,报文可简单分为请求报文和响应报文。
工作原理(流程):
        客户机与服务器建立连接后,浏览器可以向web服务器发送请求并显示收到的网页,当用户在浏览器地址栏中输入一个URL或点击一个超连接时,浏览器就向服务器发出了HTTP请求,请求方式的格式为:统一资源标识符、协议版本号,后边是MIME(Multipurpose Internet Mail Extensions)信息包括请求修饰符、客户机信息和可能的内容。该请求被送往由URL指定的WEB服务器,WEB服务器接收到请求后,进行相应反映,其格式为:一个状态行包括信息的协议版本号、一个成功或错误的代码,后边服务器信息、实体信息和可能的内容。即以HTTP规定的格式送回所要求的文件或其他相关信息,再由用户计算机上的浏览器负责解释和显示。 
特点:
         1)支持客户/服务器模式。
         2)简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
         3)灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
         4)无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
         5)无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
382_get和post的区别
        1. Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的。
        2. Get传送的数据量较小,这主要是因为受URL长度限制;Post传送的数据量较大,一般被默认为不受限制。
        3. Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集。
        4. Get执行效率却比Post方法好。Get是form提交的默认方法。
383_如何解决表单提交的中文乱码问题
         1)设置页面编码,若是jsp页面,需编写代码
1    <%@page language="java" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" %>
        若是html页面,在网页头部(<head></head>)中添加下面这段代码
1    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        2)将form表单提交方式变为post方式,即添加method="post";)在Servlet类中编写代码request.setCharacterEncoding("UTF-8"),而且必须写在第一行。
        3)如果是get请求,在Servlet类中编写代码
1
2    byte [] bytes = str.getBytes("iso-8859-1");
String  cstr =  new String(bytes,"utf-8");
        或者直接修改Tomcat服务器配置文件server.xml增加内容:
         URIEncoding="utf-8"
384_绝对路径、根路径、相对路径的含义及其区别
        绝对路径指对站点的根目录而言某文件的位置,相对路径指以当前文件所处目录而言某文件的位置,相对路径-以引用文件之网页所在位置为参考基础,而建立出的目录路径。绝对路径-以Web站点根目录为参考基础的目录路径。
________________________________________
        先给出一个网站结构图做实例加深理解,A网站(域名为http://www.a.com):/include/a-test.html,/img/a-next.jpg;B网站(域名为http://www.b.com):/include/b-test.html,/img/b-next.jpg。
________________________________________
        相对路径是从引用的网页文件本身开始构建的,如果在A网站中的a-test.html中要插入图片a-next.jpg,可以这样做:<img src="../img/a-next.jpg" />,重点是img前面的../,表示从html处于的include开始起步,输入一个../表示回到上面一级父文件夹下,然后再接着img/表示又从父级文件夹下的img文件开始了,最后定位img下面的next.jpg。
________________________________________
        根路径是从网站的最底层开始起,一般的网站的根目录就是域名下对应的文件夹,就如D盘是一个网站,双击D盘进入到D盘看到的就是网站的根目录,这种路径的链接样式是这样的:如果在A网站中的a-test.html中要插入图片a-next.jpg,可以这样做:<img src="/img/a-next.jpg" >,以/开头表示从网站根目录算起,找到根目录下面的img文件夹下的next.jpg。
________________________________________
        绝对路径就很好理解了,这种路径一般带有网站的域名,如果在A网站中的a-test.html中要插入图片a-next.jpg,需要这样这样写:<img src="http://www.a.com/img/a-next.jpg" >,将图片路径上带有了域名信息,再打个比方:如果在A网站中的a-test.html中要插入B网站的图片b-next.jpg,就需要这样写:<img src="http://www.b.com/img/b-next.jpg" >,这种方法适用与在不同网站之间插入外部网站的图片。
385_如实现servlet的单线程模式
        实现servlet的单线程的jsp命令是: <%@ page isThreadSafe=”false”%>。默认isThreadSafe值为true。
        属性isThreadSafe=false模式表示它是以Singleton模式运行,该模式implements了接口SingleThreadMode, 该模式同一时刻只有一个实例,不会出现信息同步与否的概念。若多个用户同时访问一个这种模式的页面,那么先访问者完全执行完该页面后,后访问者才开始执行。
        属性isThreadSafe=true模式表示它以多线程方式运行。该模式的信息同步,需访问同步方法(用synchronized标记的)来实现。 一般格式如下:
 public synchronized void syncmethod(...){
      while(...) {
        this.wait();
      }
      this.notifyAll();
 } 
386_Servlet的生命周期
        加载:在下列时刻加载 Servlet:(1)如果已配置自动加载选项,则在启动服务器时自动加载(web.xml中设置<load-on-start>);(2)在服务器启动后,客户机首次向 Servlet 发出请求时;(3)重新加载 Servlet 时(只执行一次)
________________________________________
        实例化:加载 Servlet 后,服务器创建一个 Servlet 实例。(只执行一次)
________________________________________
        初始化:调用 Servlet 的 init() 方法。在初始化阶段,Servlet 初始化参数被传递给 Servlet 配置对象ServletConfig。 (只执行一次)
________________________________________
        请求处理:对于到达服务器的客户机请求,服务器创建针对此次请求的一个“请求”对象和一个“响应”对象。服务器调用 Servlet 的 service() 方法,该方法用于传递“请求”和“响应”对象。service() 方法从“请求”对象获得请求信息、处理该请求并用“响应”对象的方法以将响应传回客户机。service() 方法可以调用其它方法来处理请求,例如 doGet()、doPost() 或其它的方法。(每次请求都执行该步骤)
________________________________________
        销毁:当服务器不再需要 Servlet, 或重新装入 Servlet 的新实例时,服务器会调用 Servlet 的 destroy() 方法。(只执行一次)
387_转发和重定向的区别
        转发是在服务端直接做的事情,是对客户端的同一个request进行传递,浏览器并不知道。重定向是由浏览器来做的事情。重定向时,服务端返回一个response,里面包含了跳转的地址,由浏览器获得后,自动发送一个新request。转发像呼叫转移或者110报警中心,重定向似114查号台。
  
        区别1:跳转效率的不同
                转发效率相对高;重定向效率相对低
        区别2:实现语句不同
                转发 request.getRequestDispatcher("xxxx").forward(request,response) ;
                重定向 response.sendRedirect("xxxx")
        区别3:是否共有同一个request的数据
                转发源组件与目标组件共有同一个request数据
                重定向源组件与目标组件不共有同一个request数据(可使用session共有数据)
        区别4:浏览器URL地址的不同
                转发后浏览器URL地址保持不变(源组件地址)
                重定向后浏览器URL地址改变为重定向后的地址(目标组件地址)
        区别5:"/"路径的含义不同
                转发时"/"代表当前项目的根路径 ;重定向时"/"代表当前服务器的根路径
        区别6:跳转范围的不同
                只能转发到同一应用中的URL(默认) ;可以重定向任何服务器、任何应用的URL
        区别7:刷新是否导致重复提交
                转发会导致重复提交(可以通过同步令牌解决);重定向不会导致重复提交
        区别8:是否经过过滤器
                转发不经过过滤器(默认情况);重定向经过过滤器
388_JSP的执行过程 
        在JSP运行过程中,首先由客户端发出请求,Web服务器接收到请求后,如果是第一次访问某个jsp页面,Web服务器对它进行以下3个操作。
        1)翻译:由.jsp变为.java,由JSP引擎实现。
        2)编译:由.java变为.class,由 Java编译器实现。
        3)执行:由.class变为.html,用Java虚拟机执行编译文件,然后将执行结果返回给Web服务器,并最终返回给客户端
        如果不是第一次访问某个JSP页面,则只执行第三步。所以第一次访问JSP较慢。
389_JSP动作有哪些,简述作用?
jsp:include:在页面被请求的时候引入一个文件。
jsp:useBean:寻找或者实例化一个JavaBean。 jsp:setProperty:设置JavaBean的属性。
jsp:getProperty:输出某个JavaBean的属性。
jsp:forward:把请求转到一个新的页面。
jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记。
390_page/request/session/application作用域区别
page:当前页面范围
request:当前页面范围+转发页面(forward)+包含页面(include)
session:当前会话:session在以下几种情况下失效
        1)销毁session:Session.invalidate();
        2)超过最大非活动间隔时间
        3)手动关闭浏览器(session并没有立刻失效,因为服务器端session仍旧存在,超过最大非活动间隔时间后真正失效)
application:当前应用;服务器重新启动前一直有效
391_JSP和Servlet的区别和联系
区别:
        1) JSP是在HTML代码里写JAVA代码,框架是HTML;而Servlet是在JAVA代码中写HTML代码,本身是个JAVA类。
        2) JSP使人们把显示和逻辑分隔成为可能,这意味着两者的开发可并行进行;而Servlet并没有把两者分开。
        3) Servlet独立地处理静态表示逻辑与动态业务逻辑.这样,任何文件的变动都需要对此服务程序重新编译;JSP允许用特殊标签直接嵌入到HTML页面, HTML内容与JAVA内容也可放在单独文件中,HTML内容的任何变动会自动编译装入到服务程序.
        4) Servlet需要在web.xml中配置,而JSP无需配置。
        5) 目前JSP主要用在视图层,负责显示,而Servlet主要用在控制层,负责调度
联系:
        1) 都是Sun公司推出的动态网页技术。
        2) 先有Servlet,针对Servlet缺点推出JSP。JSP是Servlet的一种特殊形式,每个JSP页面就是一个Servlet实例——JSP页面由系统翻译成Servlet,Servlet再负责响应用户请求。

392_谈谈过滤器原理及其作用?
________________________________________
原理:
        过滤器是运行在服务器端的一个拦截作用的web组件,一个请求来到时,web容器会判断是否有过滤器与该信息资源相关联,如果有则交给过滤器处理,然后再交给目标资源,响应的时候则以相反的顺序交给过滤器处理,最后再返回给用户浏览器
        一般用于日志记录、性能、安全、权限管理等公共模块。
________________________________________
过滤器开发:
        过滤器是一个实现了javax.servlet.Filter接口的java类
        主要业务代码放在doFilter方法中
        业务代码完成后要将请求向后传递,即调用FilterChain对象的doFilter方法
________________________________________
配置:
在web.xml中增加如下代码
1
2
3
4
5
6
7
8    <filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>Filter完整类名</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*(要过虑的url,此处*表示过虑所有的url)</url-pattern>
</filter-mapping>
________________________________________
谈谈监听器作用及其分类?
        监听器也叫Listener,是一个实现特定接口的java类,使用时需要在web.xml中配置,它是web服务器端的一个组件,它们用于监听的事件源分别为SerlvetConext,HttpSession和ServletRequest这三个域对象
________________________________________
主要有以下三种操作:
        – 监听三个域对象创建和销毁的事件监听器
        – 监听域对象中属性的增加和删除的事件监听器
        – 监听绑定到HttpSession域中的某个对象的状态的时间监听器
________________________________________
接口分类:
        – ServletContextListener
        – HttpSessionListener
        – ServletRequestListener
        – ServletContextAttributeListener
        – HttpSessionAttributeListener
        – ServletRequestAttributeListener
        – HttpSessionBindingListener(不需要配置)
        – HttpSessionActivationListener(不需要配置)
________________________________________
配置:
        <listener><listener-class>实现以上任意接口的java类全名</listener-class></listener>
393_jQuery相比JavaScript的优势在哪里
        jQuery的语法更加简单。
        jQuery消除了JavaScript跨平台兼容问题。
        相比其他JavaScript和JavaScript库,jQuery更容易使用。
        jQuery有一个庞大的库/函数。
        jQuery有良好的文档和帮助手册。
        jQuery支持AJAX 
394_DOM对象和jQuery对象的区别及其转换
        DOM对象,是我们用传统的方法(javascript)获得的对象,jQuery对象即是用jQuery类库的选择器获得的对象,它是对DOM对象的一种封装,jQuery对象不能使用DOM对象的方法,只能使用jQuery对象自己的方法。
________________________________________
        普通的dom对象一般可以通过$()转换成jquery对象
        如:var cr=document.getElementById("cr"); //dom对象
        var $cr = $(cr); //转换成jquery对象
________________________________________
        由于jquery对象本身是一个集合。所以如果jquery对象要转换为dom对象则必须取出其中的某一项,一般可通过索引取出
        如:$("#msg")[0],$("div").eq(1)[0],$("div").get()[1],$("td")[5]这几种语法在jQuery中都是合法的
395_jQuery中$的作用主要有哪些
________________________________________
1)$用作选择器
        例如:根据id获得页面元素$("#元素ID")
________________________________________
2)$相当于window.onload 和 $(document).ready(...)
        例如:$(function(){...});  function(){...}会在DOM树加载完毕之后执行。
________________________________________
3)$用作JQuery的工具函数的前缀
        例如: var str = '  Welcome to shanghai.com  ';
                   str = $.trim(str);去掉空格
________________________________________
4)$(element):把DOM节点转化成jQuery节点
        例如:var cr=document.getElementById("cr"); //dom对象
                  var $cr = $(cr); //转换成jquery对象
________________________________________
5)$(html):使用HTML字符串创建jQuery节点
        例如:var obj = $("<div>尚学堂,实战化教学第一品牌</div>")
396_Ajax含义及其主要技术
        Ajax (Asynchronous JavaScript and XML 阿贾克斯)不是一个新的技术,事实上,它是一些旧有的成熟的技术以一种全新的更加强大的方式整合在一起。
Ajax的关键技术:
        1)使用CSS构建用户界面样式,负责页面排版和美工
        2)使用DOM进行动态显示和交互,对页面进行局部修改
        3)使用XMLHttpRequest异步获取数据
        4)使用JavaScript将所有元素绑定在一起
397_Ajax的工作原理
        Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解。
        XMLHttpRequest是ajax的核心机制,它是在IE5中首先引入的,是一种支持异步请求的技术。简单的说,也就是javascript可以及时向服务器提出请求和处理响应,而不阻塞用户。达到无刷新的效果。
398_JSON及其作用
        JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式。同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包。
________________________________________
        在JSON中,有两种结构:对象和数组。
   Ø {} 对象
    Ø [] 数组
    Ø , 分隔属性
   Ø : 左边为属性名,右边为属性值 
   属性名可用可不用引号括起,属性值为字符串一定要用引号括起
________________________________________
举例:
varo={
    "xlid": "cxh",
    "xldigitid": 123456,
    "topscore": 2000,
    "topplaytime": "2009-08-20"
};
 
jsonranklist=[
    {
        "xlid": "cxh",
        "xldigitid": 123456,
        "topscore": 2000,
        "topplaytime": "2009-08-20"
    },
    {
        "xlid": "zd",
        "xldigitid": 123456,
        "topscore": 1500,
        "topplaytime": "2009-11-20"
    }
];
399_文件上传组件Common-fileUpload的常用类及其作用?
DiskFileItemFactory:磁盘文件工厂类,设置上传文件保存的磁盘目录,缓冲区大小。
ServletFileUpload:上传处理类,此类真正读取客户上传的文件,同时可以设置最大接收大小。
FileItem:上传的文件对象,可以是多个文件,每个上传的文件都是一个单独的FileItem对象。
400_说出Servlet的生命周期,并说出Servlet和CGI的区别?
        答:Web容器加载Servlet并将其实例化后,Servlet生命周期开始,容器运行其init()方法进行Servlet的初始化;请求到达时调用Servlet的service方法,service方法会调用与请求对应的doGet或doPost等方法;当服务器关闭会项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的destroy方法。Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI 对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于Servlet。
________________________________________
        【补充1】SUN公司在1996年发布Servlet技术就是为了和CGI进行竞争,Servlet是一个特殊的Java程序,一个基于Java的Web应用通常包含一个或多个Servlet类。   Servlet不能够自行创建并执行,它是在Servlet容器中运行的,容器将用户的请求传递给Servlet程序,此外将Servlet的响应回传给用户。通常一个Servlet会关联一个或多个JSP页面。以前CGI经常因为性能开销上的问题被诟病,然而Fast CGI早就已经解决了CGI效率上的问题,所以面试的时候大可不必诟病CGI,腾讯的网站就使用了CGI技术,相信你也没感觉它哪里不好。
________________________________________
        【补充2】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()
401_JSP 和Servlet 有有什么关系?
        答:其实这个问题在上面已经阐述过了,Servlet是一个特殊的Java程序,它运行于服务器的JVM中,能够依靠服务器的支持向浏览器提供显示内容。JSP本质上是Servlet的一种简易形式, JSP会被服务器处理成一个类似于Servlet的Java程序,可以简化页面内容的生成。Servlet和JSP最主要的不同点在于,Servlet 的应用逻辑是在Java 文件中,并且完全从表示层中的HTML分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp 的文件(有人说,Servlet就是在Java中写HTML,而JSP就是在HTML中写Java代码,当然,这个说法还是很片面的)。JSP侧重于视图,Servlet更侧重于控制逻辑,在MVC架构模式中,JSP适合充当视图(view)而Servlet适合充当控制器(controller)。 
402_JSP中的四种作用域?
答:page、request、session和application,具体如下:
        ①page 代表与一个页面相关的对象和属性。
        ②request 代表与Web客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个Web 组件;需要在页面显示的临时数据可以置于此作用域
        ③session代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的session中
        ④application代表与整个Web应用程序相关的对象和属性,它实质上是跨越整个Web应用程序,包括多个页面、请求和会话的一个全局作用域。
403_如何实现JSP或Servlet的单线程模式?
1    <%@page isThreadSafe=”false”%>
【补充】Servlet默认的工作模式是单实例多线程,如果Servlet实现了标识接口SingleThreadModel又或是JSP页面通过page指令设置isThreadSafe属性为false,那么它们生成的Java代码会以单线程多实例方式工作。显然,这样做会导致每个请求创建一个Servlet实例,这种实践将导致严重的性能问题。
404_实现会话跟踪的技术有哪些?
        答:由于HTTP协议本身是无状态的,服务器为了区分不同的用户,就需要对用户会话进行跟踪,简单的说就是为用户进行登记,为用户分配唯一的ID,下一次用户在请求中包含此ID,服务器据此判断到底是哪一个用户。
________________________________________
        ①URL 重写:在URL中添加用户会话的信息作为请求的参数,或者将唯一的会话ID添加到URL结尾以标识一个会话。
________________________________________
        ②设置表单隐藏域:将和会话跟踪相关的字段添加到隐式表单域中,这些信息不会在浏览器中显示但是提交表单时会提交给服务器。
这两种方式很难处理跨越多个页面的信息传递,因为如果每次都要修改URL或在页面中添加隐式表单域来存储用户会话相关信息,事情将变得非常麻烦。
________________________________________
        ③cookie:cookie有两种,一种是基于窗口的,浏览器窗口关闭后,cookie就没有了;另一种是将信息存储在一个临时文件中,并设置存在的时间。当用户通过浏览器和服务器建立一次会话后,会话ID就会随响应信息返回存储在基于窗口的cookie中,那就意味着只要浏览器没有关闭,会话没有超时,下一次请求时这个会话ID又会提交给服务器让服务器识别用户身份。会话中可以为用户保存信息。会话对象是在服务器内存中的,而基于窗口的cookie是在客户端内存中的。如果浏览器禁用了cookie,那么就需要通过下面两种方式进行会话跟踪。当然,在使用cookie时要注意几点:首先不要在cookie中存放敏感信息;其次cookie存储的数据量有限(4k),不能将过多的内容存储cookie中;再者浏览器通常只允许一个站点最多存放20个cookie。当然,和用户会话相关的其他信息(除了会话ID)也可以存在cookie方便进行会话跟踪。
________________________________________
        ④HttpSession:在所有会话跟踪技术中,HttpSession对象是最强大也是功能最多的。当一个用户第一次访问某个网站时会自动创建HttpSession,每个用户可以访问他自己的HttpSession。可以通过HttpServletRequest对象的getSession方法获得HttpSession,通过HttpSession的setAttribute方法可以将一个值放在HttpSession中,通过调用HttpSession对象的getAttribute方法,同时传入属性名就可以获取保存在HttpSession中的对象。与上面三种方式不同的是,HttpSession放在服务器的内存中,因此不要将过大的对象放在里面,即使目前的Servlet容器可以在内存将满时将HttpSession中的对象移到其他存储设备中,但是这样势必影响性能。添加到HttpSession中的值可以是任意Java对象,这个对象最好实现了Serializable接口,这样Servlet容器在必要的时候可以将其序列化到文件中,否则在序列化时就会出现异常。

405_过滤器有哪些作用和用法?
        答:Java Web开发中的过滤器(filter)是从Servlet 2.3规范开始增加的功能,并在Servlet 2.4规范中得到增强。对Web应用来说,过滤器是一个驻留在服务器端的Web组件,它可以截取客户端和服务器之间的请求与响应信息,并对这些信息进行过滤。当Web容器接受到一个对资源的请求时,它将判断是否有过滤器与这个资源相关联。如果有,那么容器将把请求交给过滤器进行处理。在过滤器中,你可以改变请求的内容,或者重新设置请求的报头信息,然后再将请求发送给目标资源。当目标资源对请求作出响应时候,容器同样会将响应先转发给过滤器,再过滤器中,你可以对响应的内容进行转换,然后再将响应发送到客户端。
        常见的过滤器用途主要包括:对用户请求进行统一认证、对用户的访问请求进行记录和审核、对用户发送的数据进行过滤或替换、转换图象格式、对响应内容进行压缩以减少传输量、对请求或响应进行加解密处理、触发资源访问事件、对XML的输出应用XSLT等。
        和过滤器相关的接口主要有:Filter、FilterConfig、FilterChain
406_监听器有哪些作用和用法?
        答:Java Web开发中的监听器(listener)就是application、session、request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件,如下所示:
        ①ServletContextListener:对Servlet上下文的创建和销毁进行监听。
        ②ServletContextAttributeListener:监听Servlet上下文属性的添加、删除和替换。
        ③HttpSessionListener:对Session的创建和销毁进行监听。
________________________________________
        补充:session的销毁有两种情况:
        1、session超时(可以在web.xml中通过<session-config>/<session-timeout>标签配置超时时间);
        2、通过调用session对象的invalidate()方法使session失效。
________________________________________
        ④HttpSessionAttributeListener:对Session对象中属性的添加、删除和替换进行监听。
        ⑤ServletRequestListener:对请求对象的初始化和销毁进行监听。
        ⑥ServletRequestAttributeListener:对请求对象属性的添加、删除和替换进行监听。
407_你的项目中使用过哪些JSTL标签?
        答:项目中主要使用了JSTL的核心标签库,包括<c:if>、<c:choose>、<c: when>、<c: otherwise>、<c:forEach>等,主要用于构造循环和分支结构以控制显示逻辑。
        【说明】虽然JSTL标签库提供了core、sql、fmt、xml等标签库,但是实际开发中建议只使用核心标签库(core),而且最好只使用分支和循环标签并辅以表达式语言(EL),这样才能真正做到数据显示和业务逻辑的分离,这才是最佳实践。
408_使用标签库有什么好处?如何自定义JSP标签?
________________________________________
答:使用标签库的好处包括以下几个方面:
        分离JSP页面的内容和逻辑,简化了Web开发;
        开发者可以创建自定义标签来封装业务逻辑和显示逻辑;
        标签具有很好的可移植性、可维护性和可重用性;
        避免了对Scriptlet(小脚本)的使用(很多公司的项目开发都不允许在JSP中书写小脚本)
________________________________________
自定义JSP标签包括以下几个步骤:
        编写一个Java类实现实现Tag/BodyTag/IterationTag接口(通常不直接实现这些接口而是继承TagSupport/BodyTagSupport/SimpleTagSupport类,这是对适配器模式中缺省适配模式的应用)
        重写doStartTag()、doEndTag()等方法,定义标签要完成的功能
        编写扩展名为tld的标签描述文件对自定义标签进行部署,tld文件通常放在WEB-INF文件夹或其子目录
        在JSP页面中使用taglib指令引用该标签库
________________________________________
下面是一个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44    package com.bjsxt;
package com.lovo.tags;  
   
import java.io.IOException;  
import java.text.SimpleDateFormat;  
import java.util.Date;  
   
import javax.servlet.jsp.JspException;  
import javax.servlet.jsp.JspWriter;  
import javax.servlet.jsp.tagext.TagSupport;  
   
public class TimeTag extends TagSupport {  
    private static final long serialVersionUID = 1L;  
       
    private String format = "yyyy-MM-dd hh:mm:ss";  
    private String foreColor = "black";  
    private String backColor = "white";  
   
    public int doStartTag() throws JspException {  
         SimpleDateFormat sdf = new SimpleDateFormat(format);  
         JspWriter writer = pageContext.getOut();  
         StringBuilder sb = new StringBuilder();  
         sb.append(String.format("<span style='color:%s;background-color:%s'>%s</span>",  
             foreColor, backColor, sdf.format(new Date())));  
         try {  
           writer.print(sb.toString());  
         } catch(IOException e) {  
           e.printStackTrace();  
         }  
         return SKIP_BODY;  
      }  
   
    public void setFormat(String format) {  
        this.format = format;  
    }  
   
    public void setForeColor(String foreColor) {  
        this.foreColor = foreColor;  
    }  
   
    public void setBackColor(String backColor) {  
        this.backColor = backColor;  
    }  
}
________________________________________
标签库描述文件(该文件通常放在WEB-INF目录或其子目录下)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26    <?xml version="1.0" encoding="UTF-8" ?>  
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   
    http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"  
    version="2.0">  
       
    <description>定义标签库</description>  
    <tlib-version>1.0</tlib-version>  
    <short-name>MyTag</short-name>  
    <tag>  
        <name>time</name>  
        <tag-class>com.lovo.tags.TimeTag</tag-class>  
        <body-content>empty</body-content>  
        <attribute>  
            <name>format</name>  
            <required>false</required>  
        </attribute>  
        <attribute>  
            <name>foreColor</name>  
        </attribute>  
        <attribute>  
            <name>backColor</name>  
        </attribute>  
    </tag>  
</taglib>
________________________________________
JSP页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21    <%@ page pageEncoding="UTF-8"%>  
<%@ taglib prefix="my" uri="/WEB-INF/tld/my.tld" %>  
<%  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
%>  
   
<!DOCTYPE html>  
<html>  
  <head>  
    <base href="<%=basePath%>">  
    <title>首页</title>  
    <style type="text/css">  
        * { font-family: "Arial"; font-size:72px; }  
    </style>  
  </head>  
     
  <body>  
    <my:time format="yyyy-MM-dd" backColor="blue" foreColor="yellow"/>  
  </body>  
</html>

  • 5
    点赞
  • 1
    评论
  • 43
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值