1. Character 字符封装类
String 常量池中字符串
StringBuffer 存放字符数组
Vector 数组
2. JVM是Java Virtual Machine(Java 虚拟机 )的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
简单来看,虚拟机本质就是一个进程。模拟平台操作的一个进程, 是一种计算机软件技术
3. 一般关系数据模型和对象数据模型之间有以下对应关系:表对应类,记录对应对象,表的字段对应类的属性
4.
void waitForSignal()
{
Object obj = new Object();
synchronized(Thread.currentThread())
{
obj.wait();
obj.notify();
}
}
Which statement is true?(A)
A. This code may throw an InterruptedException
B. This code may throw an IllegalStateException
C. This code may throw a TimeOutException after ten minutes
D. This code will not compile unless”obj.wait()”is replaced with”(Thread)obj).wait()”
E. Reversing the order of obj.wait()and obj.notify()may cause this method to complete normally
解析:
这题有两个错误的地方,第一个错误是 wait() 方法要以 try/catch 包覆,或是掷出 InterruptedException 才行
因此答案就是因为缺少例外捕捉的 InterruptedException
第二个错误的地方是, synchronized 的目标与 wait() 方法的物件不相同,会有 IllegalMonitorStateException ,不过 InterruptedException 会先出现,所以这不是答案
最后正确的程式码应该是这样:
void waitForSignal() {
Object obj = new Object();
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
obj.notify();
}
}
5. 多态分为 编译时多态 和 运行时多态 。其中 编辑时多态是静态的 , 主要是指方法的重载 ,它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不同的函数,在运行时谈不上多态。而 运行时多态是动态的 ,它是 通过动态绑定来实现的 ,也就是我们所说的多态性(要有继承关系 2.子类要重写父类的方法 3.父类引用指向子类)
6. 引用数据类型是引用传递(call by reference),基本数据类型是值传递(call by value)
值传递不可以改变原变量的内容和地址—》原因是java方法的形参传递都是传递原变量的副本,在方法中改变的是副本的值,而不适合原变量的
引用传递不可以改变原变量的地址,但可以改变原变量的内容– 原因是当副本的引用改变时,原变量 的引用并没有发生变化,当副本改变内容时,由于副本引用指向的是原变量的地址空间,所以,原变量的内容发生变化。
结论:1.值传递不可以改变原变量的内容和地址;
2.引用传递不可以改变原变量的地址,但可以改变原变量的内容;
7. 有这么一段程序:
public class Test{
public String name="abc";
public static void main(String[] args){
Test test=new Test();
Test testB=new Test();
System.out.println(test.equals(testB)+","+test.name.equals(testB.name));
}
}
请问以上程序执行的结果是(C)
A. true,true
B. true,false
C. false,true
D. false,false
解析:
没有重写equals()方法,比较的是对象的地址是否一样,因为new出来的两个对象肯定是不同的对象,不同的对象它们的地址是不同的,所以第一个返回false;String类重写了equals()方法,比较的是两个对象的内容(值)是否相等,因为两个对象的name都是"abc",所以是true。
8. java的GC回收是完全自动的,没有提供相关api手动回收,所有的内存分配和回收权限都在jvm,在开发人员手里没有绝对的强制垃圾回收的方法,不过可以这样去做:
1. 对于不再引用的对象,及时把它的引用赋为null。 obj = null;
2. 如果内存确实很紧张,调用System.gc() 方法来建议垃圾回收器开始回收垃圾,通知GC运行,但是Java语言规范并不保证GC一定会执行。
9. 在为传统面向对象语言的程序做单元测试的时候,经常用到mock对象。Mock对象通过反射数。请问反射最大程度破坏了面向对象的以下哪个特性?(封装)
反射破坏代码的封装性,破坏原有的访问修饰符访问限制
MARK:
mock对象:也称为伪对象,在测试中的利用mock对象来代替真实对象,方便测试的进行。
java的封装性:指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,通过该类提供的方法实现对内部信息的操作访问。
反射机制:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性
10. Java 程序中使用赋值运算符进行对象赋值时,可以得到两个完全相同的对象。(错误)
解析:
对象赋值时,比如A=B,只是把A对象的地址指向了B对象的地址,所以其实对象只有一个
11. Exception(异常)
是程序本身可以处理的异常。主要包含RuntimeException等运行时异常和IOException,SQLException等非运行时异常。
运行时异常 包括:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常(编译异常) 包括:RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常
12.
class Car extends Vehicle
{
public static void main (String[] args)
{
new Car(). run();
}
private final void run()
{
System. out. println ("Car");
}
}
class Vehicle
{
private final void run()
{
System. out. println("Vehicle");
}
}
下列哪些针对代码运行结果的描述是正确的?(A)
A. Car
B. Vehicle
C. Compiler error at line 3
D. Compiler error at line 5
E. Exception thrown at runtime
解析:
此题的父类方法有private修饰,所以对子类不可见,子类不能覆盖。所以子类方法和父类是两个方法。
扩展:如果父类方法将private改为public 会怎样?
会报错,因为父类方法有final修饰,不能被覆盖。
13. 下列语句哪一个正确( B)
A. Java程序经编译后会产生machine code
B. Java程序经编译后会产生byte code
C. Java程序经编译后会产生DLL
D. 以上都不正确
解析:
C/C++源程序编译后会直接编译成机器码,机器码是由CPU来执行的;
java编译后值产生的中间代码,也就是JAVA字节码,然后在运行的时候再把字节码变成机器码
14. Java的跨平台特性是指它的源代码可以在多个平台运行。(错)
解析:
语言跨平台是编译后的文件跨平台,而不是源程序跨平台。Java源代码首先经过编译器生成字节码,即class文件,该class文件与平台无关,而class文件经过解释执行之后翻译成最终的机器码,这是平台相关的。
15. 下列关于异常处理的描述中,错误的是(D)。
A.程序运行时异常由Java虚拟机自动进行处理
B. 使用try-catch-finally语句捕获异常
C. 可使用throw语句抛出异常
D. 捕获到的异常只能在当前方法中处理,不能在其他方法中处理
解析:
编译时异常必须显示处理,运行时异常交给虚拟机。
运行时异常可以不处理。当出现这样的异常时,总是由虚拟机接管。比如我们从来没有人去处理过Null Pointer Exception异常,它就是运行时异常,并且这种异常还是最常见的异常之一。出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。只不过往往不对它处理罢了。也就是说,如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
16. 以下代码对其执行后,NumberList里的元素依次为:(D)
List NumberList = new ArrayList();
NumberList.add(2);
NumberList.add(4);
NumberList.add(1);
NumberList.add(3);
NumberList.add(5);
for(int i =0;i
A. 2,4,1,3,5
B. 2,1,3,5
C. 4,1,3,5
D. 会出现越界情况
解析:
这题主要考察两点:
1.ArrayList删除元素后,剩余元素会依次向前移动,因此下标一直在变,size()也会减小;
2.remove()方法调用的是remove(int index),而不是remove(Object o),因此删除的是index索引处的元素;
该题具体流程:1.i=0,v=2,remove(2)删除掉了元素1,因此NumberList剩余元素为【2,4,3,5】;
2.i=1,v=4,remove(4),此时线性表中只有四个元素,不可能删除索引为4的元素,因此会报数组下标越界异常。
17.MARK:
Vector & ArrayList 的主要区别
1)
同步性:Vector是线程安全的,也就是说是同步的 ,而ArrayList 是线程序不安全的,不是同步的 数2。
2)
数据增长:当需要增长时,Vector默认增长为原来一倍 ,而ArrayList却是原来的50% ,这样,ArrayList就有利于节约内存空间。
如果涉及到堆栈,队列等操作,应该考虑用Vector,如果需要快速随机访问元素,应该使用ArrayList 。
扩展知识:
1. Hashtable & HashMap
Hashtable和HashMap它们的性能方面的比较类似 Vector和ArrayList,比如Hashtable的方法是同步的,而HashMap的不是。
2. ArrayList & LinkedList
ArrayList的内部实现是基于内部数组Object[],所以从概念上讲,它更象数组,但LinkedList的内部实现是基于一组连接的记录,所以,它更象一个链表结构,所以,它们在性能上有很大的差别:
从上面的分析可知,在ArrayList的前面或中间插入数据时,你必须将其后的所有数据相应的后移,这样必然要花费较多时间,所以,当你的操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能; 而访问链表中的某个元素时,就必须从链表的一端开始沿着连接方向一个一个元素地去查找,直到找到所需的元素为止,所以,当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
18. 以下java程序代码,执行后的结果是(C)
java.util.HashMap map=new java.util.HashMap();
map.put("name",null);
map.put("name","Jack");
System.out.println(map.size());
A.0
B. null
C.1
D.2
解析:
HashMap可以插入null的key或value,插入的时候,检查是否已经存在相同的key,如果不存在,则直接插入,如果存在,则用新的value替换旧的value,
第一条put语句,会将key/value对插入HashMap,
第二条put语句,要替换为(name,jack)。所以,size为1.
19. Which of the following can be applied to constructors(E)
A.final
B. static
C. synchronized
D. native
E. None of these.
解析:
构造方法不能被子类继承,所以用final修饰没有意义。构造方法用于创建一个新的对象,不能作为类的静态方法,所以用static修饰没有意义。此外,Java语言不支持native或synchronized的构造方法
MARK:
识别合法的构造方法;
1:
构造方法可以被重载,一个构造方法可以通过this关键字调用另一个构造方法,this语句必须位于构造方法的第一行;
重载:方法的重载(overload):重载构成的条件:方法的名称相同,但参数类型或参数个数不同,才能构成方法的重载。
2 当一个类中没有定义任何构造方法,Java将自动提供一个缺省构造方法;
3 子类通过super关键字调用父类的一个构造方法;
4 当子类的某个构造方法没有通过super关键字调用父类的构造方法,通过这个构造方法创建子类对象时,会自动先调用父类的缺省构造方法
5 构造方法不能被static、final、synchronized、abstract、native修饰,但可以被public、private、protected修饰;
6 构造方法不是类的成员方法;
7 构造方法不能被继承。
20. 经过强制类型转换以后,变量a,b的值分别为多少?(B)
short a =128;
byte b =(byte) a;
A. 128 127
B. 128 - 128
C. 128 128
D. 编译错误
解析:
1.short类型,a的二进制是:0000 0000 1000 0000;
2.强制转换的截后8位,正数用源码表示,负数用补码表示,第一位是符号。
3.因此,a截取后8位的二进制是:1000 0000,第一位是1,表示是一个负数,二进制的值是128,所以结果是 -128。
MARK:
int占4个字节,32位
byte占1个字节,8位
所以强转时会截断。前24位
在内存中表示形式( 注意java中是以补码表示一个数,所以表示形式是补码,不是原码! ):
int a = 3 ,00000000 00000000 00000000 00000011 (强转byte时前面24个0被截断)
byte b = 3 , 00000011
int a = -3 ,11111111 11111111 11111111 11111101 (强转byte时前面24个1被截断)
byte b = -3 , 11111101
1、Java中用补码形式表示
2、第一位正负位,1表示负,0表示正。
3、原码:一个数的二进制表示。
3的原码00000011 -3的 原码 10000011
4、反码:负数原码按位取反(符号位不变)。正数原码本身。
3的反码00000011 -3的反码11111100
5、补码:正数是原码本身。负数反码加1。
3的补码是00000011 -3的补码是11111101
21. given the following code,what will be the output?(A)
class Value{
public int i=15;
}
public class Test{
public static void main(String argv[]){
Test t=new Test( );
t.first( );
}
public void first( ){
int i=5;
Value v=new Value( );
v.i=25;
second(v,i);
System.out.println(v.i);
}
public void second(Value v,int i){
i = 0;
v.i = 20;
Value val = new Value( );
v = val;
System.out.println(v.i+" "+i);
}
}
A. 15 0 20
B. 15 0 15
C. 20 0 20
D. 0 15 20
解析:
22. 下列不属于Java语言性特点的是(D)
A. Java致力于检查程序在编译和运行时的错误
B. Java能运行虚拟机实现跨平台
C. Java自己操纵内存减少了内存出错的可能性
D. Java还实现了真数组,避免了覆盖数据类型的可能
解析:
Java致力于检查程序在编译和运行时的错误。
Java虚拟机实现了跨平台接口
类型检查帮助检查出许多开发早期出现的错误。
Java自己操纵内存减少了内存出错的可能性。
Java还实现了真数组,避免了覆盖数据的可能。(内存连续就是真数组,内存不连续就是假数组,例如python的list)
注意,是避免数据覆盖的可能,而不是数据覆盖类型
23. 哪个类可用于处理 Unicode?(A)
A. InputStreamReader
B. BufferedReader
C. Writer
D. PipedInputStream
解析:InputStreamReader可以指定字符编码格式
24. java用(A)机制实现了进程之间的同步执行
A. 监视器
B. 虚拟机
C. 多个CPU
D. 异步调用
解析:
首先jvm中没有进程的概念 ,但是jvm中的线程映射为操作系统中的进程,对应关系为1:1。那这道题的问的就是jvm中线程如何异步执行 。 在jvm中 是使用监视器锁来实现不同线程的异步执行, 在语法的表现就是synchronized
25.
package Wangyi;
class Base
{
public void method()
{
System.out.println("Base");
}
}
class Son extends Base
{
public void method()
{
System.out.println("Son");
}
public void methodB()
{
System.out.println("SonB");
}
}
public class Test01
{
public static void main(String[] args)
{
Base base = new Son();
base.method();
base.methodB();
}
}
问这个程序的输出结果(D)
A. Base SonB
B. Son SonB
C. Base Son SonB
D. 编译不通过
解析:
Base base=new Son(); 是多态的表示形式。父类对象调用了子类创建了Son对象。
base调用的method()方法就是调用了子类重写的method()方法。
而此时base还是属于Base对象,base调用methodB()时Base对象里没有这个方法,所以编译不通过。
要想调用的话需要先通过SON son=(SON)base;强制转换,然后用son.methodB()调用就可以了。
编译看左边,运行看右边。意思编译时候,看左边有没有该方法,运行的时候结果看 new 的对象是谁,就调用的谁
26. 下列说法正确的有(ACD )
A. 环境变量可在编译source code时指定
B. 在编译程序时,所能指定的环境变量不包括class path
C. javac一次可同时编译数个Java源文件
D. javac.exe能指定编译结果要置于哪个目录(directory)
解析:
javac -help
用法: javac
-d <目录> 指定放置生成的类文件的位置
-s <目录> 指定放置生成的源文件的位置
-h <目录> 指定放置生成的本机标头文件的位置
27. 以下哪几种方式可用来实现线程间通知和唤醒:(AC )
A. Object.wait/notify/notifyAll
B. ReentrantLock.wait/notify/notifyAll
C. Condition.await/signal/signalAll
D. Thread.wait/notify/notifyAll
解析:
wait()、notify()和notifyAll()是 Object类 中的方法
Condition是在java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition1的await()、signal()这种方式实现线程间协作更加安全和高效。因此通常来说比较推荐使用Condition,阻塞队列实际上是使用了Condition来模拟线程间协作。
28. 以下关于Object类的说法正确的是(A)
A. Java中所有的类都直接或间接继承自Object,无论是否明确的指明,无论其是否是抽象类。
B. Java中的接口(interface)也继承了Object类
C. 利用== 比较两个对象时,Java调用继承自Object的equals方法,判断是否相等。
D. 如果类的定义中没有重新定义toString()方法,则该类创建的对象无法使用toStrig()方法。
解析:
Object 是基类 Java中的所有的类都直接或间接的继承;所以A对
从一个class派生的必然是另一个class。Object是一个class,如果interface继承自Object,那么interface必然是一个class,所以B错
利用equals()方法进行比较时 会调用 == 可以看equals()方法的源码,可以这样说, == 比equal更加强大,所以C错
toString()方法是Object类中 即使不重写也能使用 所以D错
29. String类不可变,指的是String对象内容不可变,因为’String对象存在常量池中,而String的引用是可以可变,可以为String引用赋予新的对象字符串。
30. A 派生出子类 B , B 派生出子类 C ,并且在 java 源代码有如下声明:
1. A a0=new A();
2. A a1=new B();
3. A a2=new C();
问以下哪个说法是正确的?(D)
A. 只有第一行能通过编译
B. 第1、2行能通过编译,但第3行编译出错
C. 第1、2、3行能通过编译,但第2、3行运行时出错
D. 第1行,第2行和第3行的声明都是正确的
解析:
这道题的考点是Java的继承关系。B继承于A,C继承于B,所以A为B和C共同的父类。
父类(基类)的引用可以指向子类的实例化对象
31. 下面论述正确的是(D)?
A. 如果两个对象的hashcode相同,那么它们作为同一个HashMap的key时,必然返回同样的值
B. 如果a,b的hashcode相同,那么a.equals(b)必须返回true
C. 对于一个类,其所有对象的hashcode必须不同
D. 如果a.equals(b)返回true,那么a,b两个对象的hashcode必须相同
解析:
hashCode()方法和equals()方法的作用其实是一样的,在Java里都是用来对比两个对象是否相等一致。
那么equals()既然已经能实现对比的功能了,为什么还要hashCode()呢?因为重写的equals()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高。
那么hashCode()既然效率这么高为什么还要equals()呢? 因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,
所以我们可以得出:
1.equals()相等的两个对象他们的hashCode()肯定相等,也就是用equals()对比是绝对可靠的。
2.hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
所有对于需要大量并且快速的对比的话如果都用equals()去做显然效率太低,所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equal()去再对比了),如果hashCode()相同,此时再对比他们的equals(),如果equals()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!
32. socket编程中,以下哪个socket的操作是不属于服务端操作的(C)?
A. accept
B. listen
C. connect
D. close
解析
33. Web程序中,当前用户上下文信息应该保存在下面哪个对象中(C)
A. page
B. request
C. session
D. Application
解析
当前用户上下文信息:session
appication:当前应用
pageContext:当前页面
request:当前请求
重点在 当前用户 , application能被同一个应用程序的所有用户访问,所以当前用户的信息就不宜保存在application中
session会话对象,一个会话只可能是一个用户的,生命周期默认30分钟,也可以自行定义,当前会话结束(如关闭浏览器),当前session被销毁。所以当前用户的信息应该保存在session中
34.MARK:
( 1 )
对于外部类而言,它也可以使用访问控制符修饰,但外部类只能有两种访问控制级别: public 和默认。因为外部类没有处于任何类的内部,也就没有其所在类的内部、所在类的子类两个范围,因此 private 和 protected 访问控制符对外部类没有意义。
( 2 )
内部类的上一级程序单元是外部类,它具有 4 个作用域:同一个类( private )、同一个包( protected )和任何位置( public)。
( 3 )
因为局部成员的作用域是所在方法,其他程序单元永远不可能访问另一个方法中的局部变量,所以所有的局部成员都不能使用访问控制修饰符修饰。
35. 以下Java程序运行的结果是(A)
public class Tester{
public static void main(String[] args){
Integer var1=new Integer(1);
Integer var2=var1;
doSomething(var2);
System.out.print(var1.intValue());
System.out.print(var1==var2);
}
public static void doSomething(Integer integer){
integer=new Integer(2);
}
}
A. 1true
B. 2true
C. 1false
D. 2false
解析:
doSomething(),因为这里传递的是引用,而不是地址值,即新建了一个Integer integer,其指向var2所指向的那个栈中的1.至此,integer和var毫无关系,除了同时指向同一个栈中的值。然后integer = new Integer(2);便是在栈中新建了一个为2的值,然后integer重新指向了这个栈中的值。所以var1和var2都没有改变,都是指向栈中为1的那个值。
36. 关于sleep和wait,以下描述错误的是(D)
A. sleep是线程类的方法,wait是object的方法
B. sleep不释放对象锁,wait放弃对象锁
C. sleep暂停线程,但监控状态依然保持,结束后会自动恢复
D. wait进入等待锁定池,只有针对此对象发出notify方法获得对象锁进入运行状态
解析
首先,sleep()是Thread类中的方法,而wait()则是Object类中的方法。
sleep()方法导致了程序暂停,但是他的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。
wait()方法会导致线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
注意是准备获取对象锁进入运行状态,而不是立即获得,
D选项最终是进入就绪状态,而不是运行状态。
37. 抽象类方法的访问权限默认都是public。(错误)
解析
关于抽象类
JDK 1.8以前,抽象类的方法默认访问权限为protected
JDK 1.8时,抽象类的方法默认访问权限变为default
关于接口
JDK 1.8以前,接口中的方法必须是public的
JDK 1.8时,接口中的方法可以是public的,也可以是default的
JDK 1.9时,接口中的方法可以是private的
38.Java中用正则表达式截取字符串中第一个出现的英文左括号之前的字符串。比如:北京市(海淀区)(朝阳区)(西城区),截取结果为:北京市。正则表达式为(A)
A. “.?(?=\()"
B. ".?(?=()”
C. “.(?=\()"
D. ".(?=()”
MARK:
1.什么是正则表达式的贪婪与非贪婪匹配
如:String str=“abcaxc”;
Patter p="abc";
贪婪匹配:
正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(abc)。
非贪婪匹配:
就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。
2.编程中如何区分两种模式
默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式。
量词:
{m,n}:m到n个
*:任意多个
+:一个到多个
?:0或一个
此题:
.表示除\n之外的任意字符
表示匹配0-无穷
+表示匹配1-无穷
(?=Expression) 顺序环视,(?=\()就是匹配正括号
懒惰模式正则:
src=".? (?=\()) "
结果:北京市
因为匹配到第一个"就结束了一次匹配。不会继续向后匹配。因为他懒惰嘛。
39. Java的体系结构包含(Java编程语言,Java类文件格式,JavaAPI,JVM)。
40. Servlet的生命周期可以分为初始化阶段,运行阶段和销毁阶段三个阶段,以下过程属于初始化阶段是(ACD)。
A. 加载Servlet类及.class对应的数据
B. 创建servletRequest和servletResponse对象
C. 创建ServletConfig对象
D. 创建Servlet对象
解析
Servlet的生命周期一般可以用三个方法来表示:
1.init(): 仅执行一次,负责在装载Servlet时初始化Servlet对象
2.service() : 核心方法,一般HttpServlet中会有get,post两种处理方式。在调用doGet和doPost方法时会构造servletRequest和servletResponse请求和响应对象作为参数。
3.destory(): 在停止并且卸载Servlet时执行,负责释放资源
初始化阶段:Servlet启动,会读取配置文件中的信息,构造指定的Servlet对象,创建ServletConfig对象,将ServletConfig作为参数来调用init()方法。所以选ACD。B是在调用service方法时才构造的