java笔试

java笔试

1、下列描述中,错误的是( )

答案:C. java要求编程者管理内存
解析:java与C***很大的一点区别就是java是不需要使用者关注内存分配以及管理的,Java的内存管理由Java虚拟机来完成对内存的管理。

2、执行下面的程序段,语句3的执行次数为()
for (i = 0; i <= n-1; i++)   // (1)
    for (j = n; j > i; j--// (2)
        state;               // (3)

答案:C. n(n+1)/2
解析:假设代入法:
n=3,外层循环i的取值为0,1,2
当i=0时,内部循环j的取值为3,2,1,所以state执行3次;当i=1时,内部循环j的取值3,2,所以state执行2次;当i=2时,内部循环j的取值为3,所以 state执行1次。
综上所述:3+2+1=6次。将n=3带入选项中的出C符合结果。

3、在java中,下列对继承的说法,正确的是( )

答案:子类能继承父类的所有成员
解析:在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象。所以所谓的继承使子类拥有父类所有的属性和方法其实可以这样理解,子类对象确实拥有父类对象中所有的属性和方法,但是父类对象中的私有属性和方法,子类是无法访问到的,只是拥有,但不能使用。就像有些东西你可能拥有,但是你并不能使用。所以子类对象是绝对大于父类对象的,所谓的子类对象只能继承父类非私有的属性及方法的说法是错误的。可以继承,只是无法访问到而已。
使用反射可以看出子类是继承了父类的私有方法的(不管是否是final),只是直接调用父类的私有方法是不可以的,但是利用反射的方式可以调用。

4、在Java中,关于HashMap类的描述,以下正确的是 ()

A、HashMap使用键/值得形式保存数据
B、HashMap 能够保证其中元素的顺序
C、HashMap允许将null用作键
D、HashMap允许将null用作值

答案:A C D
解析:HashMap 不按插入顺序排序,按照哈希值排序。所以无序。但是不增删改键的情况下,输出是按照一定顺序不变的image-20220311154132297

5、以下关于对象序列化描述正确的是

A、使用FileOutputStream可以将对象进行传输
B、使用PrintWriter可以将对象进行传输
C、使用transient修饰的变量不会被序列化
D、对象序列化的所属类需要实现Serializable接口

答案:C D
解析:使用ObjectOutputStream和ObjectInputStream可以将对象进行传输.
声明为static和transient类型的成员数据不能被串行化。因为static代表类的状态, transient代表对象的临时数据。

6、下面有关java类加载器,说法正确的是?

A、引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的
B、扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。
C、系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类
D、tomcat为每个App创建一个Loader,里面保存着此WebApp的ClassLoader。需要加载WebApp下的类时,就取出ClassLoader来使用

答案:A B C D
解析:a、Bootstrap ClassLoader/启动类加载器。
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作.
B、Extension ClassLoader/扩展类加载器
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作
C、System ClassLoader/系统类加载器
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作.
B、 User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性.

7、对于java类型变量char c,short s,float f,double d,表达式c*s+f+d的结果类型为()

A、float
B、char
C、short
D、double

答案:D
解析:1.若参与运算的数据类型不同,则先转换成同一类型,然后进行运算。
2.转换按数据长度增加的方向进行,以保证精度不降低。例如int型和long型运算时,先把int量转成long型后再进行运算。
3.所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。
4.char型和short型参与运算时,必须先转换成int型。
5.在赋值运算中,赋值号两边的数据类型不同时,需要把右边表达式的类型将转换为左边变量的类型。
如果右边表达式的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度。
img
**&&.**long与double在java中本身都是用64位存储的,但是他们的存储方式不同,导致double可储存的范围比long大很多

8、有变量int i = 0; int a = i++; int b = ++a; int c = a+b; int d = (a == 1)?b:c; 请问a和d的值分别是多少?( )。答案:D

A、2,4
B、1, 4
C、1, 2
D、1,1
解析:int i = 0; //i=0
int a = i++; //a=i,a=0,i++,i=1
int b = ++a; //a++,a=1,b=a,b=1
int c = a+b;//c=2
int d = (a == 1)?b:c;//a1,d=b,d=1
综上a
1, d==1
三目运算符 基本格式为: boolean表达式1 ? 有返回值的表达式2 : 有返回值的表达式3
计算表达式1的值,若值为true则执行表达式2并得到其值,否则则执行表达式3并得到其值。

9、面向对象方法的多态性是指()答案:C

A、一个类可以派生出多个特殊类
B、一个对象在不同的运行环境中可以有不同的变体
C、针对一消息,不同的对象可以以适合自身的方式加以响应
D、一个对象可以是由多个其他对象组合而成的
解析:《疯狂java讲义》的标准解释是: 相同类型的变量、调用同一个方法时呈现出多种不同的行为特征,这就是多态。

10、有以下程序段, 则下面正确的选项是()答案:B C D
public class MyThead extends Thread{
    public static void main(String[] args) {
        MyThead t=new MyThead();
        MyThead s=new MyThead();
        t.start();
        System.out.println("one.");
        s.start();
        System.out.println("two.");
    }
    public void run() {
        System.out.println("Thread");
    }
}

A、编译失败
B、

程序运行可能结果为:
one.
Thread
two.
Thread       

C、

程序运行可能结果是:
one.
two.
Thread
Thread

D、程序运行结果不稳定
解析:单选题选D,多选题选BCD,都是套路!

11、下列选项中是正确的方法声明的是?()答案: A B C D

A、protected abstract void f1();
B、public final void f1() {}
C、static final void fq(){}
D、private void f1() {}
解析:A:抽象方法只可以被public 和 protected修饰;
B:final可以修饰类、方法、变量,分别表示:该类不可继承、该方法不能重写、该变量是常量
C:static final 可以表达在一起来修饰方法,表示是该方法是静态的不可重写的方法
D:private 修饰方法(这太常见的)表示私有方法,本类可以访问,外界不能访问

12、类方法中可以直接调用对象变量?答案:B

A、正确
B、错误
解析:是不能静态方法中引用非静态的域。原因也很简单关于类初始化的过程中,静态域是随着类加载就完成了初始化,而非静态域此时都没有完成初始化,你引用它肯定就出错了。

13、BufferedReader的父类是以下哪个?答案:D

A、FilterReader
B、InputStreamReader
C、PipedReader
D、Reader
解析:img

14、已知如下类说明: 如下哪些使用是正确的()答案:D
public class Test{
    private float f=1.0f;
    int m=12;
    static int n=1;
    public static void main(String args[]){
        Test t=new Test();
    }
}

A、t.f = 1.0
B、this.n
C、Test.m
D、Test.n
解析:A:编译不成功,因为float浮点类型默认是double类型 所以float f=1.0f;(必须加上f 强调定义的是float)此处是精度由高(double)向低(float)转型所以会报错 但是若是float f=1;这里是默认类型是Int 类型 精度由低(int)向高转型(float)不丢失精度不会报错。
B:this的使用时针对在方法内部使局部变量等值于实例变量而使用的一个关键字,此处的n是静态变量而非实例变量 所以this的调用会出错(试想一下,static本来是全类中可以使用的,是全局的,你非得this去调用,这不是区分局部变量和实例变量的分水线吗?但是此处是全局的,不需要区分)
C:m是实例变量,什么是实例变量:就是需要new 一个对象出来才能使用的,这里直接用类名就调用了,jvm怎么知道m是谁?
D:类变量可以通过类直接调用

15、下面哪些Java中的流对象是字节流? 答案:A B C D

A、FileInputStream
B、BufferedInputStream
C、PushbackInputStream
D、ByteArrayInputStream
解析:stream结尾都是字节流,reader和writer结尾都是字符流 两者的区别就是读写的时候一个是按字节读写,一个是按字符。 实际使用通常差不多。 在读写文件需要对内容按行处理,比如比较特定字符,处理某一行数据的时候一般会选择字符流。 只是读写文件,和文件内容无关的,一般选择字节流。
imgimg

字节流:

InputStream
|-- FileInputStream (基本文件流)
|-- BufferedInputStream
|-- DataInputStream

|-- ObjectInputStream

字符流

Reader
|-- InputStreamReader (byte->char 桥梁)
|-- BufferedReader (常用)
Writer
|-- OutputStreamWriter (char->byte 桥梁)
|-- BufferedWriter
|-- PrintWriter (常用)

16、jdk1.8版本之前的前提下,接口和抽象类描述正确的有( ) 答案:B C

A、抽象类没有构造函数
B、接口没有构造函数
C、抽象类不允许多继承
D、接口中的方法可以有方法体
解析:A,抽象类是一个类,所以有构造器
B,接口不是一个类,所以没有构造函数
C,抽象类是一个类,类不允许继承多个类,但是可以实现多个接口。而接口可以继承多个接口,接口不能实现接口。
D,jdk1.8之前,接口中的方法都是抽象方法,用public abstract修饰,jdk1.8新特性:可以有默认方法(用default修饰,不能缺省)和静态方法(static修饰),jdk1.9:接口中的默认方法还可以用private修饰

17、下列符号中可以在 java 程序里表示单行注释的是( ) 答案:C

A、–
B、/* ……/
C、//
D、/** ……
/
解析:1、单行(single-line)–短注释://……
注释格式:/* 注释内容 /
2、块(block)–块注释:/
……/
/

* 注释内容
/
3、文档注释:/**……
/
注释若干行,并写入javadoc文档。每个文档注释都会被置于注释定界符
/**…*/之中

18、下面代码运行结果是? 答案:A
public class Test
{
    static boolean foo(char c)
    {
        System.out.print(c);
        return true;
    }
    public static void main( String[] argv )
    {
        int i = 0;
        for ( foo('A'); foo('B') && (i < 2); foo('C'))
        {
            i++ ;
            foo('D');
        }
    }
}

A、ABDCBDCB
B、ABCDABCD
C、Compilation fails.
D、An exception is thrown at runtime.
解析:for(条件1;条件2;条件3) {

	  //语句

​ }

​ 执行顺序是条件1->条件2->语句->条件3->条件2->语句->条件3->条件2…

​ 如果条件2为true,则一直执行。如果条件2位false,则for循环结束

19、下列代码执行结果为() 答案:A
public static void main(String args[])throws InterruptedException{
	    	Thread t=new Thread(new Runnable() {
				public void run() {
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						throw new RuntimeException(e);
					}
					System.out.print("2");
				}
			});
	    	t.start();
	    	
	    	t.join();
	    	System.out.print("1");
	    }

A、21
B、12
C、可能为12,也可能为21
D、以上答案都不对
解析:thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的 Join()方法,直到线程A执行完毕后,才会继续执行线程B。

t.join(); //使调用线程 t 在此之前执行完毕。
t.join(1000); //等待 t 线程,等待时间是1000毫秒

20、尝试编译以下程序会产生怎么样的结果?() 答案:C
public class MyClass {
    long var;
    public void MyClass(long param) { var = param; }//(1)
    public static void main(String[] args) {
        MyClass a, b;
        a =new MyClass();//(2)
        b =new MyClass(5);//(3)
    }
}

A、编译错误将发生在(1),因为构造函数不能指定返回值
B、编译错误将发生在(2),因为该类没有默认构造函数
C、编译错误将在(3)处发生,因为该类没有构造函数,该构造函数接受一个int类型的参数
D、该程序将正确编译和执行
解析:这道题一定要看仔细了,MyClass方法并不是构造参数,而是返回类型为void的普通方法,普通方法自然需要实例化对象然后去调用它,所以124不对,第三个是正确的,因为没有带参数的构造器,所以自然不能传一个int进去。

构造方法就是:public 类名, 没有方法修饰符
 
所以 (1)  处就是一个普通方法
 
所以该类没有带参数构造方法 ,编译报错

(1)虽然方法名和类名相同,不过由于void的修饰,所以它并不是一个构造方法,只是一个普通方法。因此题类仍然只有默认的无参构造器,(3)向构造方法中传入一个参数故而有误。

21、下面代码在main()方法中第八行后可以正常使用的是( ) 答案:A D
public class Test
{
    private int a=10;
    int b=20;
    static int c=1;
    public static void main(String arg[])
    {
        Test t = new Test();
    }
 }

A、t.a
B、this.c
C、Test.b
D、t.c
解析:A : 在private 修饰不能在外部类中调用,main 方法属于Test类的方法, 所以 对象 t 可以在他自己的类方法中调用它的

​ private

​ B : static 方法中没有this 这么一说

​ C: b不是static变量

​ D: 合理

22、以下关于继承的叙述正确的是 答案:A

A、在Java中类只允许单一继承
B、在Java中一个类不能同时继承一个类和实现一个接口
C、在Java中接口只允许单一继承
D、在Java中一个类只能实现一个接口
解析:1)接口可以继承接口,而且可以继承多个接口,但是不能实现接口,因为接口中的方法全部是抽象的,无法实现;

另外,如果是Java 7以及以前的版本,那么接口中可以包含的内容有:1. 常量;2. 抽象方法
如果是Java 8,还可以额外包含有:3. 默认方法;4. 静态方法
如果是Java 9,还可以额外包含有:5. 私有方法

2)普通类可以实现接口,并且可以实现多个接口,但是只能继承一个类,这个类可以是抽象类也可以是普通类,如果继承抽象类,必须实现抽象类中的所有抽象方法,否则这个普通类必须设置为抽象类;

3)抽象类可以实现接口,可以继承具体类,可以继承抽象类,也可以继承有构造器的实体类。

抽象类中可以有静态main方法;抽象类里可以没有抽象方法,没有抽象方法的抽象类就是不想让别人实例化它;

另外,抽象类可以有构造方法,只是不能直接创建抽象类的实例对象而已。在继承了抽象类的子类中通过super(参数列表)调用抽象类中的构造方法,可以用于实例化抽象类的字段。

下面总结常见的抽象类与接口的区别:

1)抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象;

2)接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现(java8中 接口可以有实现方法 使用default修饰);

3)接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量;

4)抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个类实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类;

5)抽象方法要被实现,所以不能是静态static的,也不能是私有private的,也不能被final修饰(试想一下,静态方法可以被类名直接调用,而类名直接调用一个没有实现的抽象方法没有意义)。

总结得比较杂乱,见谅!

23、以下程序的执行结果是: 答案:
static boolean foo(char c){
     System.out.print(c);
     return true;
 }
 public static void main(String[] args) {
     int i =0;
     for(foo('A');foo('B')&&(i<2);foo('C')){
         i++;
         foo('D');
     }
 }

A、ABDCBDCB
B、ABCDABCD
C、编译时出错
D、运行时抛出异常
解析:1.其实foo(‘A’);就是初始化条件,只会执行一次,所以第一个打印的肯定是A
2.因为i=0;循环条件是i<2 (由此可知循环i等于2的时候就会停止循环,)所有0<2满足条件,接着会输出B,然后执行i++;i就变成1了,再输出D,再最后输出C,一次循环后的结果是:ABDC
3.第二次循环的开始是foo(‘A’);是初始条件所以不会执行,直接从foo(‘B’)开始,输出B,然后i为1,且小于2,此时循环体内再次执行i++;i的值为2了,再次输出D,最后输出C
第二次循环输出:BDC
4.*然后循环再次执行for(foo(‘A’);foo(‘B’)&&(i<2);foo(‘C’))
直接输出B,***i的值在第二轮循环后的值变成了2,2<2不成立,终止循环,输出B

考察的是for循环三条语句的执行顺序 for(第一条语句;第二条语句;第三条语句;) 首次循环时先执行前两句。以后的每次循环结束,都是执行最后一条语句,然后执行判断语句(也就是第二条语句)条件成立进入下一次循环。 第一条语句只会被执行一次

24、有时为了避免某些未识别的异常抛给更高的上层应用,在某些接口实现中我们通常需要捕获编译运行期所有的异常, catch 下述哪个类的实例才能达到目的:()答案:B

A、Error
B、Exception
C、RuntimeException
D、Throwable
解析:

img

1、正确答案是B,因为error是系统出错,catch是无法处理的,难以修复的,RuntimeException不需要程序员进行捕获处理,error和exception都是throwable的子类,我们只需要对exception的实例进行捕获即可

2、既然是要捕获在 编译期运行期

首先编译期在有些方法是必须要进行 try catch

而运行期可以手动添加 try catch

运行期间出现的异常都可以使用RuntimeException这个是运行期间所有异常的 “组长”

但是编译期就多了,他们没有这个所谓的 “组长”,但是它们上面还有个 “班长”(Exception)也就时 “组长” 的 “头儿”

*所以可以使用这个 “班长”**(Exception)*解决这两个组的异常

25、以下 json 格式数据,错误的是 答案:A C

A、{company:4399}
B、{“company”:{“name”:[4399,4399,4399]}}
C、{[4399,4399,4399]}
D、{“company”:[4399,4399,4399]}
E、{“company”:{“name”:4399}}

解析:
A:错误 {company:4399} 首先,其为json对象。但json对象要求属性必须加双引号。

B:正确

C:错误 {[4399,4399,4399]} 。使用 {} 则为json对象。json对象必须由一组有序的键值对组成。

D:正确。

答案:AC.

另参考(摘自<<Javascript 高级程序设计(第三版)>>):

JSON语法可以表示以下三种类型的值:

1.简单值:使用与JavaScript 相同的语法,可以在JSON中表示字符串,数值,布尔值和null。

2.对象:对象作为一种复杂数据类型,表示的是一组有序的键值对。而每组键值对中的值可以是简单值,也可以是复杂数据类型的值。

3.数组:数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中的值。数组的值也可以是任意类型–简单值,对象或数组。

26、以下哪种JAVA得变量声明方式可以避免程序在多线程竞争情况下读到不正确的值( ) 答案: A B

A、volatile
B、static volatile
C、synchronized
D、static
解析:1、synchronized不是修饰变量的 它修饰方法或代码块或对象
2、线程安全性比较关键的两个点:内存可见性和操作原子性 如果你不修改值,可以使用private static final int , final可以保证内存可见性语义。对于原生变量,final修饰后不可更改,从而也不存在操作原子性的问题。 如果你只是想单纯地进行赋值,而不进行复合操作,那么可以使用volatile int. volatile可以确保内存可见性,但是无法确保原子性,所以不支持复合操作的线程安全性。 如果你想进行复合操作,可以使用AtomicInteger这个原子类,支持CAS操作,可确保内存可见性和操作原子性。

27、下列程序段的输出结果是:( ) 答案:
public void complicatedexpression_r(){
    int x=20, y=30;
    boolean b;
    b = x > 50 && y > 60 || x > 50 && y < -60 || x < -50 && y > 60 || x < -50 && y < -60;
    System.out.println(b);
}

A、true
B、false
C、1
D、0
解析:

1、答:此题考查运算符优先级。

题中符号的优先级排序是:’>’,’<’,’&&’,’||’。

即 b=(x>50&&y>60)||(x>50&&y<-60)||(x<-50&&y>60)||(x<-50&&y<-60);

x>50结果为0,x<-50结果为0,所以括号中的表达式结果都为0,四个0或的结果0。

b为boolean类型,所以输出为false。

2、x>50为false,由于&&与操作,||或操作都是短路操作符,即与操作时一旦遇到false就停止执行后当前关系式中的后续代码,同理或操作时一旦遇到true也停止执行。

x>50&&y>60中x>50结果为false,所以就不需要判断y>60。继续判断第一个||或操作符后面的代码,结果为false || false || false || false。因此最终答案选择false。

28、默认RMI采用的是什么通信协议? 答案:C

A、HTTP
B、UDP/IP
C、TCP/IP
D、Multicast
解析:RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制。使用这种机制,某一台计算机上的对象可以调用另外一台计算机上的对象来获取远程数据。RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开发方式没有使用面向对象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote Procedure Call)应运而生,它使程序员更容易地调用远程程序,但在面对复杂的信息传讯时,RPC依然未能很好的支持,而且RPC未能做到面向对象调用的开发模式。针对RPC服务遗留的问题,RMI出现在世人面前,它被设计成一种面向对象的通讯方式,允许程序员使用远程对象来实现通信,并且支持多线程的服务,这是一次远程通讯的***,为远程通信开辟新的里程碑。

RMI的开发步骤

先创建远程接口及声明远程方法,注意这是实现双方通讯的接口,需要继承Remote

开发一个类来实现远程接口及远程方法,值得注意的是实现类需要继承UnicastRemoteObject

通过javac命令编译文件,通过java -server 命令注册服务,启动远程对象

最后客户端查找远程对象,并调用远程方法

所以选C

2、RMI采用的是TCP/IP协议

29、运行代码,结果正确的是: 答案: B
Boolean flag = false;
if(flag = true){
System.out.println("true");
}else{
System.out.println("false");
}

A、编译错误
B、true
C、false
D、什么也没有输出
解析:if(flag = true)的时候flag已经是true了,所以输出true;

​ 要是为if(flag == true)输出才为false

30、下面代码输出结果是? 答案:C
int i = 5;
int j = 10;
System.out.println(i + ~j);

A、Compilation error because”~”doesn’t operate on integers
B、-5
C、-6
D、15
解析:1、公式-n=n+1可推出n=-n-1,所以~10=-11再加5结果为-6

2、我认为应该是:

计算机本身储存的就是补码:

那么10的补码就是10的原码:0000 0000 0000 1010——这是补码,因为现在是计算机在计算

~10的补码就是:1111 1111 1111 0101

~10的反码就是:1111 1111 1111 0100——补码减1

~10的原码就是:1000 0000 0000 1011——反码取反:这个才是正常二进制数,换算为整数为-11

原码才可以对应为正常的整数,补码只有转换为原码才能被正常人类识别。

31、单例模式中,两个基本要点是答案: A D

A、构造函数私有
B、静态工厂方法
C、以上都不对
D、唯一实例
解析:

设计模式-单例模式
知识点
什么是单例模式?
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

单例模式有分为饿汉式和懒汉式

特点:

1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
应用实例:

1、一个班级只有一个班主任。
2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。
3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
优点:

1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例)。
2、避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

使用场景:

1、要求生产唯一序列号。
2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。

实例
单例模式-饿汉式
代码
//单例模式-饿汉式
public class SingletonDemo {
    public static void main(String[] args) {
        //编译错误:无法实例化
        // Singleton singleton = new Singleton();
 
        //正确获取对象的方法
        Singleton singleton = Singleton.getINSTANCE();
        singleton.hello();
    }
}
 
class Singleton{
    //创建一个本身对象
    private static final Singleton INSTANCE = new Singleton();
 
    //让构造方法为private,这样该类就不会被实例化
    private Singleton(){}
 
    //创建一个获取对象的方法
    public static Singleton getINSTANCE() {
        return INSTANCE;
    }
 
    public void hello(){
        System.out.println("Hello World! ——单例模式-饿汉式");
    }
}
结果

1
Hello World! ——单例模式-饿汉式
单例模式-懒汉式(线程不安全版)
这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。

代码
//单例模式-懒汉式
public class SingletonDemo2 {
    public static void main(String[] args) {
        Singleton2 singleton = Singleton2.getInstance();
        singleton.hello();
 
    }
 
}
 
class Singleton2{
    private static Singleton2 instance;
    private Singleton2(){}
 
    public static Singleton2 getInstance() {
        if (instance == null){
            instance = new Singleton2();
        }
        return instance;
    }
 
    public void hello(){
        System.out.println("Hello World! ——单例模式-懒汉式");
    }
}
结果

1
Hello World! ——单例模式-懒汉式
单例模式-懒汉式(线程安全版)
描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。

代码
//单例模式-懒汉式
public class SingletonDemo3 {
    public static void main(String[] args) {
        Singleton3 singleton = Singleton3.getInstance();
        singleton.hello();
 
    }
 
}
 
class Singleton3{
    private static Singleton3 instance;
    private Singleton3(){}
 
    public synchronized static Singleton3 getInstance() {
        if (instance == null){
            instance = new Singleton3();
        }
        return instance;
    }
 
    public void hello(){
        System.out.println("Hello World! ——单例模式-懒汉式");
    }
}
结果

复制代码
1
Hello World! ——单例模式-懒汉式
32、有以下代码: 请问输出的结果是: 答案: A
class A{
    public A(String str){
         
    }
}
public class Test{
    public static void main(String[] args) {
        A classa=new A("he");
        A classb=new A("he");
        System.out.println(classa==classb);
    }
}

A、false
B、true
C、报错
D、以上选项都不正确
解析:1、答案为 false 因为== 表示的是否指向的是同一个内存。

System.out.println(classa.equals(classb)); 如果这这样输出 答案也是错误的 因为子类没有覆盖Object

的equals()方法,而默认调用==的这个方法 判断两个对象是否相等需要覆盖equals()方法和hashcaode()方法

2、这题不管是还是equals输出结果都为false因为equals没有被重写时默认调用进行比较。

3、object类――众类鼻祖 1.取得对象信息:toString():对象输出时,会默认调用Object类的toString()方法,将对象信息变为字符串返回。 2.对象相等判断方法:equals():两个对象进行比较时,实际上是比较两个对象的地址值(从程序看出两个对象内容完全相等,但是结果是不相等的,这是因为classa与classb的内容分别在不同的内存空间指向了不同的内存地址)。所以要对equals()进行覆写,判断equals()方法里面的Object类对象是否与调用equals()的类是同一个类的实例(用instanceof判断),如果是,则进行向下转型,然后再调用String类中的equals方法对属性进行比较。 3.对象签名:hashCode():Object类有两种方法来推断对象的标识:equals()和hashCode()。如果根据equals()方法判断两个对象是相等的,那么对这两个对象中的每一个调用hashCode()方法都必然生成相同的整数结果。但是反过来,如果两个hashCode()返回的结果相等,两个对象的equals()方法却不一定相等。在默认情况下equals()方法用来比较两个对象的地址值,而原始的hashCode()方法用来返回其所在对象的物理地址(ps:对于非字符串变量而言,equals和比较的是地址,对于字符串变量而言equals()比较的是内容比较地址)

33、以下代码将打印出 答案:B
public static void main(String args[]) {
      List  Listlist1 = new ArrayList();
      Listlist1.add(0);
      List Listlist2 = Listlist1;
      System.out.println(Listlist1.get(0) instanceof Integer);
      System.out.println(Listlist2.get(0) instanceof Integer);
}

A、编译错误
B、true true
C、true false
D、false false
解析:collection类型的集合(ArrayList,LinkedList)只能装入对象类型的数据,该题中装入了0,是一个基本类型,但是JDK5以后提供了自动装箱与自动拆箱,所以int类型自动装箱变为了Integer类型。编译能够正常通过。

将list1的引用赋值给了list2,那么list1和list2都将指向同一个堆内存空间。instanceof是Java中关键字,用于判断一个对象是否属于某个特定类的实例,并且返回boolean类型的返回值。显然,list1.get(0)和list2.get(0)都属于Integer的实例

2、答案B 不指定ArrayList类型,存入数据,再次取出时,默认是Object类型;但这个题的关键是instanceof关键字,instanceof执行时类似利用java反射机制,识别对象信息。

3、List集合中的元素必须是对象。

Listlist1.add(0);JDK1.5之后支持自动装箱(int类型自动装箱成Integer),编译通过。

instanceof:前一个参数通常是一个引用类型变量,后一个操作数通常是一个类(也可以是一个接口, 它用于判断前面的对象是否是后面的类,或者其子类、实现类的实例

List没有使用泛型,说明使用get(0)取出的元素的编译类型是Object型的, 但运行时类型是Integer。所以打印true。这边体现了多态。

而Listlist1把引用赋给了List list2,说明两个指向同一个对象。第二个打印的也是true。

34、下面代码运行结果是? 答案:
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
解析:1、这题选A,考察的是值传递与引用传递,Java中原始数据类型都是值传递,传递的是值得副本,形参的改变不会影响实际参数的值, 引用传递传递的是引用类型数据,包括String,数组,列表, map,类对象等类型,形参与实参指向的是同一内存地址,因此形参改变会影响实参的值。

2、img

3、可能有人会选择B,包括我刚开始也是。总以为v不是已经指向了val了吗??为什么还是20呢?不应该是15吗?

其实,原因很简单。现在我们把second()换一下

publicvoidsecond(Value tmp,inti){

i = 0;

tmp.i = 20;

Value val = newValue( );

tmp = val;

System.out.println(tmp.i+" "+i);

}

这个tmp其实相当于是一个指向原来first中的V这个对象的指针,也就是对v对象的引用而已。但是引用是会改变所指的地址的值的。

所以在second中当tmp.i= 20的时候,就把原来first中的v的i值改为20了。接下来,又把tmp指向了新建的一个对象,所以在second中的tmp

现在指的是新的对象val,i值为15.

当执行完毕second后,在first中在此输出v.i的时候,应为前面second中已经把该位置的i的值改为了20,所以输出的是20.

至于疑惑v指向了val,其实只是名字的问题,在second中的v实践也是另外的一个变量,名字相同了而已,这个估计也是纠结的重点。

简单的总结,不对希望可以提出来,谢谢!

35、有关线程的哪些叙述是对的() 答案:B C D

A、一旦一个线程被创建,它就立即开始运行。
B、使用start()方法可以使一个线程成为可运行的,但是它不一定立即开始运行。
C、当一个线程因为抢先机制而停止运行,它可能被放在可运行队列的前面。
D、一个线程可能因为不同的原因停止并进入就绪状态。
解析:1、我自己最开始的时候只选了BD没选C。看评论里面也对C存疑,通过书籍查证C是可以选的。

在抢先式系统下,由高优先级的线程参与调度。分为2种情况:

1.若多个线程都处于就绪状态,则具有高优先级的线程会在低优先级之前得到执行;

2.在当前线程的运行过程中,如果有较高级别的线程准备就绪,则正在运行的较低级别的线程将被挂起,转到较高级别的线程运行,直到结束后又会转到原来被挂起的线程。

第二种情况就描述了C所代表的情况,可以看到当较高级别的线程抢去运行权并运行完成之后,是先将权利转给原来的线程的,所以C是正确的。

2、一个新创建的线程并不是自动的开始运行的,必须调用它的start()方法使之将线程放入可运行态(runnable state),这只是意味着该线程可被JVM的线程调度程序调度而不是意味着它可以立即运行。
线程的调度是抢先式的,而不是分时间片式的。
具有比当前运行线程高优先级的线程可以使当前线程停止运行而进入就绪状态。
不同优先级的线程间是抢先式的,而同级线程间是轮换式的。
一个线程停止运行可以是因为不同原因,可能是因为更高优先级线程的抢占,也可能是因为调用sleep()方法。
而即使是因为抢先而停止也不一定就进入可运行队列的前面,因为同级线程是轮换式的,它的运行可能就是因为轮换,而它因抢占而停止后只能在轮换队列中排队而不能排在前面。

36、下面哪些类可以被继承? Java.lang.Thread、java.lang.Number、java.lang.Double、java.lang.Math、 java.lang.ClassLoad 答案:A B E

A、Thread
B、Number
C、Double
D、Math
E、ClassLoader
解析:答案:ABE

A,Thread可以被继承,用于创建新的线程

B,Number类可以被继承,Integer,Float,Double等都继承自Number类

C,Double类的声明为

public final class Doubleextends Numberimplements Comparable<Double>

final生明的类不能被继承

D,Math类的声明为

public final class Mathextends Object

不能被继承

E,ClassLoader可以被继承,用户可以自定义类加载器

2、java.lang包中不能被继承的类:

public final class Byte

public final class Character

public static final class Character.UnicodeBlock

public final class Class

public final class Compile

public final class Double

public final class Float

public final class Integer

public final class Long

public final class Math

public final class ProcessBuilder

public final class RuntimePermission

public final class Short

public final class StackTraceElement

public final class StrictMath

public final class String

public final class StringBuffer

public final class StringBuilder

public final class System

public final class Void

37、下列类定义中哪些是合法的抽象类的定义?() 答案:C

A、abstract Animal{abstract void growl();}
B、class abstract Animal{abstract void growl();}
C、abstract class Animal{abstract void growl();}
D、abstract class Animal{abstract void growl(){System.out.println( “growl”);};}
解析:选C

1. 首先,类的修饰符,都应该在class关键字之前,AB错;

2. 抽象方法不能有方法体,D错。

2、自己总结的,有遗漏请私我指正,不知道为什么网上都说接口没有Main方法,然而我用IDEA和eclipse是可以的,不知道是不是我理解错了。

*jdk1.8之前*

*接口*

1.多实现

2.变量类型默认且只能为为public static final

3.函数类型默认且只能为public,只能有public类型的静态成员函数

4.非静态成员函数没有方法体,静态成员函数有方法体

5.子类必须实现所有接口函数

6.可以有main方法;可以new一个接口,需要在方法体中实现所有接口函数

7.没有构造器

*抽象类*

1.单继承

2.变量类型不限(静态变量+非静态变量)

3.函数类型不限(静态函数+非静态函数)

4.非静态函数包含没有方法体的抽象函数. 有方法体的普通函数

5.子类可以不覆写父类的抽象方法,但子类也要申明为抽象类;子类可以选择覆写父类的非抽象方法

6.可以有main方法;不可以new一个抽象类

7.可以有构造器

*Jdk1.8*

*接口中可以有default类型的方法,实现类可以选择实现该方法*

****意义:****默认方法的主要优势是提供一种拓展接口的方法,而不破坏现有代码。另一个优势为该方法是可选的,子类可以根据不同的需求Override或默认实现。

38、Java的Daemon线程,setDaemon( )设置必须要? 答案:A

A、在start之前
B、在start之后
C、前后都可以
解析:1、答案是A

setDaemon()方法必须在线程启动之前调用,当线程正在运行时调用会产生异常。

2、java线程基础知识----java daemon线程

java线程是一个运用很广泛的重点知识,我们很有必要了解java的daemon线程.

1.首先我们必须清楚的认识到java的线程分为两类: 用户线程和daemon线程

A.  用户线程: 用户线程可以简单的理解为用户定义的线程,当然包括main线程(以前我错误的认为main线程也是一个daemon线程,但是慢慢的发现原来main线程不是,因为如果我再main线程中创建一个用户线程,并且打出日志,我们会发现这样一个问题,main线程运行结束了,但是我们的线程任然在运行).

B.  daemon线程: daemon线程是为我们创建的用户线程提供服务的线程,比如说jvm的GC等等,这样的线程有一个非常明显的特征: 当用户线程运行结束的时候,daemon线程将会自动退出.(由此我们可以推出下面关于daemon线程的几条基本特点)

2. daemon 线程的特点:

A.  守护线程创建的过程中需要先调用setDaemon方法进行设置,然后再启动线程.否则会报出IllegalThreadStateException异常.(个人在想一个问题,为什么不能动态更改线程为daemon线程?有时间一个补上这个内容,现在给出一个猜测: 是因为jvm判断线程状态的时候,如果当前只存在一个线程Thread1,如果我们把这个线程动态更改为daemon线程,jvm会认为当前已经不存在用户线程而退出,稍后将会给出正确结论,抱歉!如果有哪位大牛看到,希望给出指点,谢谢!)

B.  由于daemon线程的终止条件是当前是否存在用户线程,所以我们不能指派daemon线程来进行一些业务操作,而只能服务用户线程.

C.  daemon线程创建的子线程任然是daemon线程.

3、A

java中线程分为两种类型:

1:用户线程。通过Thread.setDaemon(false)设置为用户线程;

2:守护线程。通过Thread.setDaemon(true)设置为守护线程,如果不设置,默认用户线程;

守护线程是服务用户线程的线程,在它启动之前必须先set。

39、当你编译和运行下面的代码时,会出现下面选项中的哪种情况? 答案:B
public class Pvf{
    static boolean Paddy;
    public static void main(String args[]){
        System.out.println(Paddy);
    }
}

A、编译时错误
B、编译通过并输出结果false
C、编译通过并输出结果true
D、编译通过并输出结果null
解析:类中声明的变量有默认初始值;方法中声明的变量没有默认初始值,必须在定义时初始化,否则在访问该变量时会出错。

boolean类型默认值是false

img

40、能单独和finally语句一起使用的块是( ) 答案:

A、try
B、catch
C、throw
D、throws
解析:解析:处理异常常用的两种方式:
1、try…catch(捕获处理机制);
2、throws(冒泡处理机制).
注意细节:使用try…catch块捕获时可以没有catch块,但当没用catch块的时候必须得有finally块.故选A)

40、以下代码段执行后的输出结果为 答案:D
public class Test {
    public static void main(String[] args) {
        System.out.println(test());
 
    }
    private static int test() {
        int temp = 1;
        try {
            System.out.println(temp);
            return ++temp;
        } catch (Exception e) {
            System.out.println(temp);
            return ++temp;
        } finally {
            ++temp;
            System.out.println(temp);
        }
    }
}

A、1,2,2
B、1,2,3
C、1,3,3
D、1,3,2
解析:执行顺序为:

输出try里面的初始temp:1;

temp=2;

保存return里面temp的值:2;

执行finally的语句temp:3,输出temp:3;

返回try中的return语句,返回存在里面的temp的值:2;

输出temp:2。

2、finally代码块在return中间执行。return的值会被放入临时空间,然后执行finally代码块,如果finally中有return,会刷新临时空间的值,方法结束返回临时空间值。

41、以下哪项不是java基础类型() 答案: C

A、int
B、boolean
C、String
D、float
解析:C是正确答案

Java中基本数据类型大体分为两类 数字类型(byte,short,int,long,float,double,char),布尔类型(boolean); 备注:由于char可以和数字间转换,也可认为大的范围是数字类型的。

2、数据类型包括基本数据类型和引用数据类型

基本数据类型:byte,short,int,long,char,float,double,boolean

引用数据类型:数组,接口,枚举,类,空类

3、java的基本数据类型有八种: 1)四种整数类型(byte、short、int、long): byte:8 位,用于表示最小数据单位,如文件中数据,-128~127 short:16 位,很少用,-32768 ~ 32767 int:32 位、最常用,-231-1~231 (21 亿) long:64 位、次常用 注意事项: int i=5; // 5 叫直接量(或字面量),即 直接写出的常数。 整数字面量默认都为 int 类型,所以在定义的 long 型数据后面加 L或 l。 小于 32 位数的变量,都按 int 结果计算。 强转符比数算符优先级高。见常量与变量中的例子。 2)两种浮点数类型(float、double): float:32 位,后缀 F 或 f,1 位符号位,8 位指数,23 位有效尾数。 double:64 位,最常用,后缀 D 或 d,1 位符号位,11 位指数,52 位有效尾 注意事项: 二 进 制 浮 点 数 : 1010100010=101010001.02=10101000.10210(2次方)=1010100.010*211(3次方)= . 10101000102^1010(10次方) 尾数: . 1010100010 指数: 1010 基数:2 浮点数字面量默认都为 double 类型,所以在定义的 float 型数据后面加F 或 f;double 类型可不写后缀,但在小数计算中一定要写 D 或 X.X float 的精度没有 long 高,有效位数(尾数)短。 float 的范围大于 long 指数可以很大。 浮点数是不精确的,不能对浮点数进行精确比较。 3)一种字符类型(char): char:16 位,是整数类型,用单引号括起来的 1 个字符(可以是一个中文字符),使用 Unicode 码代表字符,0~2^16-1(65535) 。 注意事项: 不能为 0个字符。 转义字符:\n 换行 \r 回车 \t Tab 字符 " 双引号 \ 表示一个\ 两字符 char 中间用“+”连接,内部先把字符转成 int 类型,再进行加法运算,char 本质就是个数!二进制的,显示的时候,经过“处理”显示为字符。 4)一种布尔类型(boolean):true 真 和 false 假。 5)类型转换: char–> 自动转换:byte–>short–>int–>long–>float–>double 强制转换:①会损失精度,产生误差,小数点以后的数字全部舍弃。②容易超过取值范围。 6)记忆:8位:Byte(字节型) 16位:short(短整型)、char(字符型) 32位:int(整型)、float(单精度型/浮点型) 64位:long(长整型)、double(双精度型) 最后一个:boolean(布尔类型

42、执行语句“int a= ’ 2 ’ ”后,a的值是( ) 答案:B

A、2
B、50
C、49
D、0
解析:1、常用ASCII码值:空格为32;数字0为48;“A”为65;“a”值为97。

2、一个简便的记忆法:0:48 A:65 a:97,数字连起来是486597 -> 486 597 -> 486 (486 + 111)

3、常见字符的ASCII码值如下:空格的ASCII码值为32;数字0到9的ASCII码值分别为48到57;大写字母“A”到“Z”的ASCII码值分别为65到90;小写字母“a”到“z”的ASCII码值分别为97到到122。

43、Which lines of the following will produce an error? 答案:A
byte a1 = 2, a2 = 4, a3;
short s = 16;
a2 = s;
a3 = a1 * a2;

A、Line 3 and Line 4
B、Line 1 only
C、Line 3 only
D、Line 4 only
解析:答案:A

short类型转为byte类型出错

a1*a2结果为int类型,转为byte类型出错

2、数值型变量在默认情况下为Int型,byte和short型在计算时会自动转换为int型计算,结果也是int 型。所以a1*a2的结果是int 型的。

44、 以下代码结果是什么? 答案: C
public class foo {
    public static void main(String sgf[]) {
 
        StringBuffer a=new StringBuffer("A");
 
        StringBuffer b=new StringBuffer("B");
 
        operate(a,b);
 
        System.out.println(a+"."+b);
    }
    static void operate(StringBuffer x,StringBuffer y) {
        x.append(y);
        y=x;
    }
}

A、代码可以编译运行,输出“AB.AB”。
B、代码可以编译运行,输出“A.A”。
C、代码可以编译运行,输出“AB.B”。
D、代码可以编译运行,输出“A.B”。
解析:这里简单地说,a,b,x,y就是四个指针。y本来指向的是b所指向的对象,但是一个“=”,y就指向了x所指向的目标即是a指向的对象,因此原来b所指向的目标并没有发生任何改变。与y不同的是,x进行的是对象操作,此时此对象在内存中是真正的本质上的改变。有点绕,但是手机打字,没发画图,不然其实很容易理解。

2、引用a指向对象A

引用b指向对象B

引用x指向对象A

引用y指向对象B

在operate方法中,引用x指向的对象A被连接了B,对象A也就被改变为AB

然后又把引用y指向了x所指向的对象地址,也就是此时引用a,x,y指向同一个对象AB

而引用b没有发生任何变化,依旧指向对象B。

45、在J2EE中,使用Servlet过滤器,需要在web.xml中配置()元素 答案:A B

A、
B、
C、
D、
解析:答案:AB
Servlet过滤器的配置包括两部分:
第一部分是过滤器在Web应用中的定义,由元素表示,包括和两个必需的子元素
第二部分是过滤器映射的定义,由元素表示,可以将一个过滤器映射到一个或者多个Servlet或JSP文件,也可以采用url-pattern将过滤器映射到任意特征的URL。

46、如下的Java程序 答案:B
public class Test { 
     public static void main(String[] args) { 
     System.out.println(args[0]); 
     } 
} 
 若采用命令行“java Test one two three”调用,则程序输出的结果为:

A、Test
B、one
C、two
D、java
解析:采用命令行“ java Test one two three ”调用

其中Test为调用的方法,而one two three则为Test方法里面main函数的参数;

System.out.println(args[0]);表示输出第一个元素,故为one;

47、事务隔离级别是由谁实现的? 答案:C

A、Java应用程序
B、Hibernate
C、数据库系统
D、JDBC驱动程序
解析:答案:C

A,我们写java程序的时候只是设定事物的隔离级别,而不是去实现它

B,Hibernate是一个java的数据持久化框架,方便数据库的访问

C,事物隔离级别由数据库系统实现,是数据库系统本身的一个功能

D,JDBC是java database connector,也就是java访问数据库的驱动

2、C

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。

√: 可能出现 ×: 不会出现

脏读不可重复读幻读
Read uncommitted
Read committed×
Repeatable read××
Serializable×××
48、上述代码返回结果为: 答案:B
Integer a = 1;
Integer b = 1;
Integer c = 500;
Integer d = 500;
System.out.print(a == b);
System.out.print(c == d);

A、true、true
B、true、false
C、false、true
D、false、false
解析:1、

Integer类型在-128–>127范围之间是被缓存了的,也就是每个对象的内存地址是相同的,赋值就直接从缓存中取,不会有新的对象产生,而大于这个范围,将会重新创建一个Integer对象,也就是new一个对象出来,当然地址就不同了,也就!=;

2、Interger的范围时[-128,127],在这个范围内比较大小,相等为true,超过范围为false

49、执行语句“int a= ’ 2 ’ ”后,a的值是( ) 答案:B

A、2
B、50
C、49
D、0
解析:1、常用ASCII码值:空格为32;数字0为48;“A”为65;“a”值为97。

2、一个简便的记忆法:0:48 A:65 a:97,数字连起来是486597 -> 486 597 -> 486 (486 + 111)

3、常见字符的ASCII码值如下:空格的ASCII码值为32;数字0到9的ASCII码值分别为48到57;大写字母“A”到“Z”的ASCII码值分别为65到90;小写字母“a”到“z”的ASCII码值分别为97到到122。

50、从以下哪一个选项中可以获得Servlet的初始化参数? 答案:C

A、Servlet
B、ServletContext
C、ServletConfig
D、GenericServlet
解析:C

通过ServletConfig接口的getInitParameter(java.lang.String name)方法

2、ServletContext对象:servlet容器在启动时会加载web应用,并为每个web应用创建唯一的servlet context对象,可以把ServletContext看成是一个Web应用的服务器端组件的共享内存,在ServletContext中可以存放共享数据。ServletContext对象是真正的一个全局对象,凡是web容器中的Servlet都可以访问。

整个web应用只有唯一的一个ServletContext对象

servletConfig对象:用于封装servlet的配置信息。从一个servlet被实例化后,对任何客户端在任何时候访问有效,但仅对servlet自身有效,一个servlet的ServletConfig对象不能被另一个servlet访问

51、下列类在多重catch中同时出现时,哪一个异常类应最后一个列出() 答案:C

A、ArithmeticException
B、NumberFormatException
C、Exception
D、ArrayIndexOutOfBoundException
解析:这是多重catch块的顺序问题,由于异常处理系统就近寻找匹配异常处理程序,应先子类后父类。

2、ArithmeticException 是算数异常

NumberFormatException 是数据格式异常

Exception 异常

ArrayIndexOutOfBoundException 数组索引超过界限异常

先处理具体的异常,如果没有则放到一个大的范围之中Exception

52、下面有关java实例变量,局部变量,类变量和final变量的说法,错误的是? 答案:B

A、实例变量指的是类中定义的变量,即成员变量,如果没有初始化,会有默认值。
B、局部变量指的是在方法中定义的变量,如果没有初始化,会有默认值
C、类变量指的是用static修饰的属性
D、final变量指的是用final 修饰的变量
解析:B,局部变量必须有初始值。

2、定义在类中的变量是类的成员变量,可以不进行初始化,Java会自动进行初始化,如果是引用类型默认初始化为null,如果是基本类型例如int则会默认初始化为0

局部变量是定义在方法中的变量,必须要进行初始化,否则不同通过编译

被static关键字修饰的变量是静态的,静态变量随着类的加载而加载,所以也被称为类变量

被final修饰发变量是常量

53、 答案:C
static String str0="0123456789";
static String str1="0123456789";
String str2=str1.substring(5);
String str3=new String(str2);
String str4=new String(str3.toCharArray());
str0=null;
假定str0,...,str4后序代码都是只读引用。
Java 7中,以上述代码为基础,在发生过一次FullGC后,上述代码在Heap空间(不包括PermGen)保留的字符数为()

A、5
B、10
C、15
D、20
解析:substring实际是new,5字符

str3和4也都是new,每个5字符

分别都会创建新的对象

常量池是PermGen的

因此应该是一共15字符

2、解析:这是一个关于java的垃圾回收机制的题目。垃圾回收主要针对的是堆区的回收,因为栈区的内存是随着线程而释放的。堆区分为三个区:年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation,也就是方法区)。

年轻代:对象被创建时(new)的对象通常被放在Young(除了一些占据内存比较大的对象),经过一定的Minor GC(针对年轻代的内存回收)还活着的对象会被移动到年老代(一些具体的移动细节省略)。

年老代:就是上述年轻代移动过来的和一些比较大的对象。Minor GC(FullGC)是针对年老代的回收

永久代:存储的是final常量,static变量,常量池。

str3,str4都是直接new的对象,而substring的源代码其实也是new一个string对象返回,如下图:

经过fullgc之后,年老区的内存回收,则年轻区的占了15个,不算PermGen。所以答案选C

54、下面哪些情况会引发异常: 答案:A B C

A、数组越界
B、指定URL不存在
C、使用throw语句抛出
D、使用throws语句
解析:1、throws出现在方法头,throw出现在方法体 2、throws表示出现异常的一种可能性,并不一定会发生异常;throw则是抛出了异常,执行throw则一定抛出了某种异常。 3、两者都是消极的异常处理方式,只是抛出或者可能抛出异常,是不会由函数处理,真正的处理异常由它的上层调用处理。

55、下面哪些描述是正确的:( ) 答案:B C
public class Test {
    public static class A {
        private B ref;
        public void setB(B b) {
            ref = b;
        }
    }
    public static Class B {
        private A ref;
        public void setA(A a) {
            ref = a;
        }
    }
    public static void main(String args[]) {start();.
    }
    public static void start() { A a = new A();
        B b = new B();
        a.setB(b);
        b = null; //
        a = null;}
}

A、b = null执行后b可以被垃圾回收
B、a = null执行后b可以被垃圾回收
C、a = null执行后a可以被垃圾回收
D、a,b必须在整个程序结束后才能被垃圾回收
解析:

img

2、内存如下:

a -> “a(b)”
b -> “b”

a引用指向一块空间,这块空间里面包含着b对象

b引用指向一块空间,这块空间是b对象

A选项,b = null执行后b可以被垃圾回收。这里"b可以被垃圾回收"中的b指的是引用b指向的内存。这块内存即使不被引用b指向,还是被引用a指向着,不会被回收。
B选项,a = null执行后b可以被垃圾回收。从代码中可以看到,a = null是在b = null后执行的,该行执行后,引用a和b都没有指向对象,对象会被回收。

C选项,同理。

56、只有实现了()接口的类,其对象才能序列化。 答案:A

A、Serializable
B、Cloneable
C、Comparable
D、Writeable
解析:Serializable要实现序列化对象必须要实现的接口

2、答案是A:Serializable接口是专门提供给类实现序列化用的。要实现序列化对象必须要实现 Serializable 接口

3、B、可进行复制

C、比较器

D、hadoop中的接口

57、的输出是? 答案:D
class Foo {
    final int i;
    int j;
    public void doSomething() {
        System.out.println(++j + i);
    }
}

A、0
B、1
C、2
D、不能执行,因为编译有错
解析:D。final类型的变量一定要初始化,因为final的变量不可更改。

final作为对象成员存在时,必须初始化;但是,如果不初始化,也可以在类的构造函数中初始

因为java允许将数据成员声明为final,却不赋初值。但是,blank finals必须在使用之前初始化,且必须在构造函数中初始化

58、下列代码编译和运行的结果是:() 答案:C
public class Threads4{
     public static void main(String[] args){
         new Threads4().go();
     }
     public void go(){
         Runnable r=new Runnable(){
             public void run(){
                 System.out.print("foo");
             }
         };
     Thread t=new Thread(r);
     t.start();
     }
 }

A、编译错误
B、抛出运行时异常
C、输出:foo
D、代码正常运行,但是无输出
解析:在java多线程中实现多线程的方式有两种①extends Thread ②implements Runnable。这两种情况是我们最常见的,还有一种是由第二种变形而来的直接new Runnable(){},我们都知道java的接口是不可以实例化的,但代码中的new Runnable(){xxx}确是实例化了,为什么? 接口和抽象类不可以实例化是对的,这个是java语法规范来的,而new Runnable(){}其实不是实例化Runnable接口来的,实际上一种内部类的一种简写 在这里:

①首先构造了一个”implements Runnable “的无名local内部类(方法内的内部类)

②然后构造了这个无名local内部类的一个实例

③然后用Runnable来表示这个无名local内部类的type(OO多态)。 例如上面这段代码编译后你会看到其实是编译了两个类来的,如下:

其中Text2$1就是无名local内部内类,这个也就很好地解释了为什么在main()方法中new Runnable(){xxx}里面的调用main()方法中的变量的时候要用final关键字来修饰

59、关于Java中参数传递的说法,哪个是错误的? 答案:D

A、在方法中,修改一个基础类型的参数不会影响原始参数值
B、在方法中,改变一个对象参数的引用不会影响到原始引用
C、在方法中,修改一个对象的属性会影响原始对象参数
D、在方法中,修改集合和Maps的元素不会影响原始集合参数
解析:

解析: 注意!Java中方法的参数传递都是值传递
A. 在方法中,修改一个基础类型的参数不会影响原始参数值
public static void main(String []args){
    int i = 5;   
    func(i);
    System.out.println(i);
}
static void func(int j){
    j = 10;
}
 
//输出结果
5
在主方法调用func(int j) 时 , 参数i是实际参数 , 值为5 , 参数j是形式参数 , 值是i给的 , 也是5 , i和j没有任何关系 , 是两个独立的参数 , 所以修改j的值时与i没有关系 , 仍然输出5。

B. 在方法中,改变一个对象参数的引用不会影响到原始引用
public static void main(String []args){
    User rabbiter = new User();
    rabbiter.setName("rabbiter");
    func(rabbiter);
    System.out.println(rabbiter.getName());
}
static void func(User user){
    user = new User();
    user.setName("zhangsan");
}
 
//输出结果
rabbiter
在主方法调用func(User user) 时 , 对象rabbiter保存的是一个地址值 , 本质上就是把rabbiter的地址值给了形参user , 所以此时实参rabbiter和形参user指向在堆中的同一个对象 , 他们的地址值相同 , 只是指向的对象一致 , 所以并不违反值传递的理论。
此时 , 如果修改形参user , new一个新的对象并让user指向它 , 修改的只是形参保存的地址 , 与实参rabbiter无关 , rabbiter指向的对象仍然是之前的那个对象。

C. 在方法中,修改一个对象的属性会影响原始对象参数
public static void main(String []args){
    User rabbiter = new User();
    rabbiter.setName("rabbiter");
    func(rabbiter);
    System.out.println(rabbiter.getName());
}
static void func(User user){
    user.setName("zhangsan");
}
 
//输出结果
zhangsan
在主方法调用func(User user) 时 , 对象rabbiter保存的是一个地址值 , 本质上就是把rabbiter的地址值给了形参user , 所以此时实参rabbiter和形参user指向在堆中的同一个对象 , 他们的地址值相同 , 指向的对象一致 , 所以并不违反值传递的理论。
那么user对其指向的对象的属性name进行修改 , rabbiter指向的对象的name属性也就被修改了。

D. 在方法中,修改集合和Maps的元素不会影响原始集合参数
集合和Maps都是对象 , 所以此项跟C选项的解析一致。
60、下面哪项技术可以用在WEB开发中实现会话跟踪实现? 答案:A B C D

A、session
B、Cookie
C、地址重写
D、隐藏域
解析:会话跟踪是一种灵活、轻便的机制,它使Web上的状态编程变为可能。
HTTP是一种无状态协议,每当用户发出请求时,服务器就会做出响应,客户端与服务器之间的联系是离散的、非连续的。当用户在同一网站的多个页面之间转换时,根本无法确定是否是同一个客户,会话跟踪技术就可以解决这个问题。当一个客户在多个页面间切换时,服务器会保存该用户的信息。
有四种方法可以实现会话跟踪技术:URL重写、隐藏表单域、Cookie、Session。
1).隐藏表单域:,非常适合步需要大量数据存储的会话应用。
2).URL 重写:URL 可以在后面附加参数,和服务器的请求一起发送,这些参数为名字/值对。
3).Cookie:一个 Cookie 是一个小的,已命名数据元素。服务器使用 SET-Cookie 头标将它作为 HTTP
响应的一部分传送到客户端,客户端被请求保存 Cookie 值,在对同一服务器的后续请求使用一个
Cookie 头标将之返回到服务器。与其它技术比较,Cookie 的一个优点是在浏览器会话结束后,甚至
在客户端计算机重启后它仍可以保留其值
4).Session:使用 setAttribute(String str,Object obj)方法将对象捆绑到一个会话

61、try括号里有return语句, finally执行顺序 答案:B

A、不执行finally代码
B、return前执行
C、return后执行
D、
解析:

下面的关键内容来自:

https://www.ibm.com/developerworks/cn/java/j-lo-finally/

是关于 try return finally 的详细解释文档,很有说服力。

清单 5.
 public class Test { 
 public static void main(String[] args) { 
        System.out.println("return value of getValue(): " + getValue()); 
	 } 

 public static int getValue() { 
        try { 
                 return 0; 
        } finally { 
                 return 1; 
	        } 
	 } 
 }

清单 5 的执行结果:

 return value of getValue(): 1
清单 6.
 public class Test { 
 public static void main(String[] args) { 
        System.out.println("return value of getValue(): " + getValue()); 
	 } 

 public static int getValue() { 
        int i = 1; 
        try { 
                 return i; 
        } finally { 
                 i++; 
        } 
	 } 
 }

清单 6 的执行结果:

 return value of getValue(): 1

利用我们上面分析得出的结论:finally 语句块是在 try 或者 catch 中的 return 语句之前执行的。 由此,可以轻松的理解清单 5 的执行结果是 1。因为 finally 中的 return 1;语句要在 try 中的 return 0;语句之前执行,那么 finally 中的 return 1;语句执行后,把程序的控制权转交给了它的调用者 main()函数,并且返回值为 1。那为什么清单 6 的返回值不是 2,而是 1 呢?按照清单 5 的分析逻辑,finally 中的 i++;语句应该在 try 中的 return i;之前执行啊? i 的初始值为 1,那么执行 i++;之后为 2,再执行 return i;那不就应该是 2 吗?怎么变成 1 了呢?

关于 Java 虚拟机是如何编译 finally 语句块的问题,有兴趣的读者可以参考《 The JavaTM Virtual Machine Specification, Second Edition 》中 7.13 节 Compiling finally。那里详细介绍了 Java 虚拟机是如何编译 finally 语句块。实际上,Java 虚拟机会把 finally 语句块作为 subroutine(对于这个 subroutine 不知该如何翻译为好,干脆就不翻译了,免得产生歧义和误解。)直接插入到 try 语句块或者 catch 语句块的控制转移语句之前。但是,还有另外一个不可忽视的因素,那就是在执行 subroutine(也就是 finally 语句块)之前,try 或者 catch 语句块会保留其返回值到本地变量表(Local Variable Table)中。待 subroutine 执行完毕之后,再恢复保留的返回值到操作数栈中,然后通过 return 或者 throw 语句将其返回给该方法的调用者(invoker)。请注意,前文中我们曾经提到过 return、throw 和 break、continue 的区别,对于这条规则(保留返回值),只适用于 return 和 throw 语句,不适用于 break 和 continue 语句,因为它们根本就没有返回值。

是不是不太好理解,那我们就用具体的例子来做形象的说明吧!

为了能够解释清单 6 的执行结果,我们来分析一下清单 6 的字节码(byte-code):

 Compiled from "Test.java"
 public class Test extends java.lang.Object{ 
 public Test(); 
  Code: 
   0: 	 aload_0 
   1:invokespecial#1; //Method java/lang/Object."<init>":()V 
   4: 	 return 

  LineNumberTable: 
   line 1: 0 

 public static void main(java.lang.String[]); 
  Code: 
   0: 	 getstatic 	 #2; //Field java/lang/System.out:Ljava/io/PrintStream; 
   3: 	 new 	 #3; //class java/lang/StringBuilder 
   6: 	 dup 
   7: 	 invokespecial 	 #4; //Method java/lang/StringBuilder."<init>":()V 
   10: 	 ldc 	 #5; //String return value of getValue(): 
   12: 	 invokevirtual 	 
   #6; //Method java/lang/StringBuilder.append:(
       Ljava/lang/String;)Ljava/lang/StringBuilder; 
   15: 	 invokestatic 	 #7; //Method getValue:()I 
   18: 	 invokevirtual 	 
   #8; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 
   21: 	 invokevirtual 	 
   #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
   24: 	 invokevirtual 	 #10; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
   27: 	 return 

 public static int getValue(); 
  Code: 
   0: 	 iconst_1 
   1: 	 istore_0 
   2: 	 iload_0 
   3: 	 istore_1 
   4: 	 iinc 	 0, 1 
   7: 	 iload_1 
   8: 	 ireturn 
   9: 	 astore_2 
   10: 	 iinc 	 0, 1 
   13: 	 aload_2 
   14: 	 athrow 
  Exception table: 
   from   to  target type 
     2     4     9   any 
     9    10     9   any 
 }

对于 Test()构造方法与 main()方法,在这里,我们不做过多解释。让我们来分析一下 getValue()方法的执行。在这之前,先让我把 getValue()中用到的虚拟机指令解释一下,以便读者能够正确的理解该函数的执行。

1.	iconst_ 
Description: Push the int constant  (-1, 0, 1, 2, 3, 4 or 5) onto the operand stack.
Forms: iconst_m1 = 2 (0x2)  iconst_0 = 3 (0x3)  iconst_1 = 4 (0x4)  
iconst_2 = 5 (0x5) iconst_3 = 6 (0x6)  iconst_4 = 7 (0x7)  iconst_5 = 8 (0x8)

2.	istore_ 
Description: Store int into local variable. The  must be an index into the 
local variable array of the current frame. 
Forms: istore_0 = 59 (0x3b)  istore_1 = 60 (0x3c)  istore_2 = 61 (0x3d)  
istore_3 = 62 (0x3e)

3.	iload_ 
Description: Load int from local variable. The  must be an index into the 
local variable array of the current frame. 
Forms: iload_0 = 26 (0x1a)  iload_1 = 27 (0x1b)  iload_2 = 28 (0x1c)  iload_3 = 29 (0x1d)

4.	iinc index, const 
Description: Increment local variable by constant. The index is an unsigned byte that 
must be an index into the local variable array of the current frame. The const is an 
immediate signed byte. The local variable at index must contain an int. The value 
const is first sign-extended to an int, and then the local variable at index is 
incremented by that amount.
Forms:  iinc = 132 (0x84)

Format:
iinc 	
index 	
const 	

5.	ireturn 
Description: Return int from method.
Forms:  ireturn = 172 (0xac)

6.	astore_ 
Description: Store reference into local variable. The  must be an index into the 
local variable array of the current frame.
Forms: astore_0 = 75 (0x4b) astore_1 = 76 (0x4c) astore_2 =77 (0x4d) astore_3 =78 (0x4e)

7.	aload_ 
Description: Load reference from local variable. The  must be an index into the 
local variable array of the current frame.
Forms: aload_0 = 42 (0x2a) aload_1 = 43 (0x2b) aload_2 = 44 (0x2c) aload_3 = 45 (0x2d)

8.	athrow 
Description: Throw exception or error.
Forms: athrow = 191 (0xbf)

有了以上的 Java 虚拟机指令,我们来分析一下其执行顺序:分为正常执行(没有 exception)和异常执行(有 exception)两种情况。我们先来看一下正常执行的情况,如图 1 所示:

图 1. getValue()函数正常执行的情况

img

由上图,我们可以清晰的看出,在 finally 语句块(iinc 0, 1)执行之前,getValue()方法保存了其返回值(1)到本地表量表中 1 的位置,完成这个任务的指令是 istore_1;然后执行 finally 语句块(iinc 0, 1),finally 语句块把位于 0 这个位置的本地变量表中的值加 1,变成 2;待 finally 语句块执行完毕之后,把本地表量表中 1 的位置上值恢复到操作数栈(iload_1),最后执行 ireturn 指令把当前操作数栈中的值(1)返回给其调用者(main)。这就是为什么清单 6 的执行结果是 1,而不是 2 的原因。

再让我们来看看异常执行的情况。是不是有人会问,你的清单 6 中都没有 catch 语句,哪来的异常处理呢?我觉得这是一个好问题,其实,即使没有 catch 语句,Java 编译器编译出的字节码中还是有默认的异常处理的,别忘了,除了需要捕获的异常,还可能有不需捕获的异常(如:RunTimeException 和 Error)。

从 getValue()方法的字节码中,我们可以看到它的异常处理表(exception table), 如下:

Exception table:

from to target type

2 4 9 any

它的意思是说:如果从 2 到 4 这段指令出现异常,则由从 9 开始的指令来处理。

图 2. getValue()函数异常执行的情况

img

先说明一点,上图中的 exception 其实应该是 exception 对象的引用,为了方便说明,我直接把它写成 exception 了。

由上图(图 2)可知,当从 2 到 4 这段指令出现异常时,将会产生一个 exception 对象,并且把它压入当前操作数栈的栈顶。接下来是 astore_2 这条指令,它负责把 exception 对象保存到本地变量表中 2 的位置,然后执行 finally 语句块,待 finally 语句块执行完毕后,再由 aload_2 这条指令把预先存储的 exception 对象恢复到操作数栈中,最后由 athrow 指令将其返回给该方法的调用者(main)。

通过以上的分析,大家应该已经清楚 try-catch-finally 语句块的执行流程了吧!

62、关于继承和实现说法正确的 是 ? ( ) 答案:A

A、类可以实现多个接口,接口可以继承(或扩展)多个接口
B、类可以实现多个接口,接口不能继承(或扩展)多个接口
C、类和接口都可以实现多个接口
D、类和接口都不可以实现多个接口
解析:1.类与类之间的关系为继承,只能单继承,但可以多层继承。 2.类与接口之间的关系为实现,既可以单实现,也可以多实现。 3.接口与接口之间的关系为继承,既可以单继承,也可以多继承。 故为A

2、java类是单继承的。 java接口可以多继承。 不允许类多重继承的主要原因是,如果A同时继承B和C,而B和C同时又有一个D方法,A如何决定该继承那一个呢? 但接口不存在这样的问题,接口全都是抽象方法继承谁都无所谓,所以接口可以继承多个接口

63、java中下面哪些是Object类的方法() 答案:A B D

A、notify()
B、notifyAll()
C、sleep()
D、wait()
解析:Object类中方法:

protected Object clone()创建并返回此对象的一个副本。

boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
protected void finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
class getClass()返回此 Object 的运行时类。
int hashCode()返回该对象的哈希码值。
void notify()唤醒在此对象监视器上等待的单个线程。
void notifyAll()唤醒在此对象监视器上等待的所有线程。
String toString()返回该对象的字符串表示。
void wait()在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
void wait(long timeout)在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。
void wait(long timeout, int nanos)在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。

64、关于下面这段Java程序,哪些描述是正确的:( ) 答案:C
public class ThreadTest extends Thread {
    public void run() {
        System.out.println("In run");
        yield();
        System.out.println("Leaving run");
    }
    public static void main(String []argv) {
        (new ThreadTest()).start();
    }
}

A、程序运行输出只有In run
B、程序运行输出只有Leaving run
C、程序运行输出先有In run后有Leaving run
D、程序运行输出先有Leaving run后有In run
解析:Thread.yield()方法作用是:暂停当前正在执行的线程对象,并执行其他线程。

yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

65、关于运行时常量池,下列哪个说法是正确的 答案:B C D

A、运行时常量池大小受栈区大小的影响
B、运行时常量池大小受方法区大小的影响
C、存放了编译时期生成的各种字面量
D、存放编译时期生成的符号引用
解析:之前写的确实写的有问题,我都没想到会被这么多人赞,为了不误人子弟,我重新写一写这个题,用到的知识点:

为了避免歧义,以下提及的JVM,是Hotspot

方法区是什么?
方法区是广义上的概念,是一个定义、标准,可以理解为Java中的接口,在Jdk6、7方法区的实现叫永久代;Jdk8之后方法区的实现叫元空间,并从JVM内存中移除,放到了直接内存中;
方法区是被所有方法线程共享的一块内存区域.

运行时常量池是什么?
运行时常量池是每一个类或接口的常量池的运行时表示形式.

具体体现就是在Java编译后生成的.class文件中,会有class常量池,也就是静态的运行时常量池;

运行时常量池存放的位置?

运行时常量池一直是方法区的一部分,在不同版本的JDK中,由于方法区位置的变化,运行时常量池所处的位置也不一样.JDK1.7及之前方法区位于永久代.由于一些原因在JDK1.8之后彻底祛除了永久代,用元空间代替。

运行时常量池存放什么?
存放编译期生成的各种字面量和符号引用;(字面量和符号引用不懂的同学请自行查阅)
运行时常量池中包含多种不同的常量,包括编译期就已经明确的数值字面量,也包括到运行期解析后才能够获得的方法或者字段引用。 此时不再是常量池中的符号地址了,这里换为真实地址。

运行时常量池与字符串常量池?(可能有同学把他俩搞混)
字符串常量池:在JVM中,为了减少相同的字符串的重复创建,为了达到节省内存的目的。会单独开辟一块内存,用于保存字符串常量,这个内存区域被叫做字符串常量池.

字符串常量池位置?

JDK1.6时字符串常量池,被存放在方法区中(永久代),而到了JDK1.7,因为永久代垃圾回收频率低;而字符串使用频率比较高,不能及时回收字符串,会导致导致永久代内存不足,就被移动到了堆内存中。

66、以下不属于构造方法特征的是() 答案:D

A、构造方法名与类名相同
B、构造方法不返回任何值,也没有返回类型
C、构造方法在创建对象时调用,其他地方不能显式地直接调用
D、每一个类只能有一个构造方法
解析:这道题目感觉有很多模糊又不明确的地方,题目质量不好。

A:一个类里面多个内部类,构造方法名是与和.java文件同名的public类名。内部类也是类,构造方法名和内部类名不同。

B:构造方法不返回任何值,也没有返回类型。无异议。

C:子类在构造方法里面调用父类的构造方法时,会在第一行使用“super(参数列表)”显示调用父类的构造方法。这里是显示地直接调用,而且没有创建新对象。

D:每一个和.java文件同名的public类可以有多个构造方法,构造方法允许重载。内部类也可以有多个构造方法,而匿名内部类一个构造方法都没有。

67、有以下代码片段:请问输出的结果是: 答案:D
String str1="hello";
 
String str2="he"+ new String("llo");
 
System.out.println(str1==str2);

A、true
B、都不对
C、null
D、false
解析:

 1)String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。在Java中,被final修饰的类是不允许被继承的,并且该类中的成员方法都默认为final方法。
 
    2)String类底层是char数组来保存字符串的。
 
    对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象
 
 
 
<h3 style="color: rgb(47,47,47);">
    字符串常量池
 
 
    在class文件中有一部分来存储编译期间生成的字面常量以及符号引用,这部分叫做class文件常量池,在运行期间对应着方法区的运行时常量池。
 
    JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池
 
    工作原理
 
    当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。
 
    实现前提
 
    字符串常量池实现的前提条件就是Java中String对象是不可变的,这样可以安全保证多个变量共享同一个对象。如果Java中的String对象可变的话,一个引用操作改变了对象的值,那么其他的变量也会受到影响,显然这样是不合理的。
 
 
 
    String str1 = "hello";
 
    这里的str1指的是方法区中的字符串常量池中的“hello”,编译时期就知道的;
 
    String str2 = "he" + new String("llo");
 
    这里的str2必须在运行时才知道str2是什么,所以它是指向的是堆里定义的字符串“hello”,所以这两个引用是不一样的。
 
    如果用str1.equal(str2),那么返回的是true;因为String类重写了equals()方法。
 
    编译器没那么智能,它不知道"he" + new String("llo")的内容是什么,所以才不敢贸然把"hello"这个对象的引用赋给str2.
 
    如果语句改为:"he"+"llo"这样就是true了。
 
    new String("zz")实际上创建了2个String对象,就是使用“zz”通过双引号创建的(在字符串常量池),另一个是通过new创建的(在堆里)。只不过他们的创建的时期不同,一个是编译期,一个是运行期。
 
    String s = "a"+"b"+"c";
 
    语句中,“a”,"b", "c"都是常量,编译时就直接存储他们的字面值,而不是他们的引用,在编译时就直接将它们连接的结果提取出来变成"abc"了。
68、在java7中,下列哪个说法是正确的: 答案:D

A、ConcurrentHashMap使用synchronized关键字保证线程安全
B、HashMap实现了Collection接口
C、Arrays.asList方法返回java.util.ArrayList对象
D、SimpleDateFormat对象是线程不安全的
解析:hashMap在单线程中使用大大提高效率,在多线程的情况下使用hashTable来确保安全。hashTable中使用synchronized关键字来实现安全机制,但是synchronized是对整张hash表进行锁定即让线程独享整张hash表,在安全同时造成了浪费。concurrentHashMap采用分段加锁的机制来确保安全

2、Arrays.asList()

将一个数组转化为一个List对象,这个方***返回一个ArrayList类型的对象, 这个ArrayList类并非java.util.ArrayList类,**而是Arrays类的静态内部类!**用这个对象对列表进行添加删除更新操作,就会报UnsupportedOperationException异常。

69、如下代码,执行test()函数后,屏幕打印结果为() 答案:D
public class Test2
{
    public void add(Byte b)
    {
        b = b++;
    }
    public void test()
    {
        Byte a = 127;
        Byte b = 127;
        add(++a);
        System.out.print(a + " ");
        add(b);
        System.out.print(b + "");
    }
}

A、127 127
B、128 127
C、129 128
D、以上都不对
解析:public void add(Byte b){ b=b++; } 这里涉及java的自动装包/自动拆包(AutoBoxing/UnBoxing) Byte的首字母为大写,是类,看似是引用传递,但是在add函数内实现++操作,会自动拆包成byte值传递类型,所以add函数还是不能实现自增功能。也就是说add函数只是个摆设,没有任何作用。 Byte类型值大小为-128~127之间。 add(++a);这里++a会越界,a的值变为-128 add(b); 前面说了,add不起任何作用,b还是127

70、下面哪个不对? 答案:C

A、RuntimeException is the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine.
B、A method is not required to declare in its throws clause any subclasses of RuntimeExeption that might be thrown during the execution of the method but not caught
C、An RuntimeException is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.
D、NullPointerException is one kind of RuntimeException
解析:

img

运行时异常: 都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常 (编译异常): 是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

2、四个选项都来自于Java API原文.

A选项是RuntimeException的定义;

B选项是把Error的第二段定义拿来改掉换成RuntimeException,但这样说对于RuntimeException也没错;

C选项也是把Error的定义换成了RuntimeException,但这里的"indicates serious problems"不应该用在RuntimeException上,Error才表示严重的错误,RuntimeException并不是.

D选项显然.

71、 答案:B

类 ABC 定义如下:

1 . public class ABC{

2 . public int max( int a, int b) { }

3 .

4 . }

将以下哪个方法插入行 3 是不合法的。( )。

A、public float max(float a, float b, float c){ }
B、public int max (int c, int d){ }
C、public float max(float a, float b){ }
D、private int max(int a, int b, int c){ }
解析:选B,

细说一下重写和重载:

这两个都是多态的一种表现形式。

重载:

1、 重载是在编译器通过方法中形参的静态类型确定调用方法版本的过程。

2、 重载是多态在编译期的表现形式

3、 重载的判定只有两个条件(其他的条件都不能作为判定):

1、 方法名一致

2、形参列表不同

重写:

1、重写在方法运行时,通过调用者的实际类型来确定调用的方法版本。(具体细说,就是子父类中的重写方法在对应的class文件常量池的位置相同,一旦子类没有重写,那么子类的实例就会沿着这个位置往上找,直到找到父类的同名方法**)**

2、重写只发生在可见的实例方法中:

1、静态方法不存在重写,形式上的重写只能说是隐藏。

2、私有方法也不存在重写,父类中private的方法,子类中就算定义了,就是相当于一个新的方法。

3、静态方法和实例方法不存在相互重写。

3、重写满足一个规则:两同两小一大

1、两同:方法名和形参列表一致

2、两小:重写方法的返回值(引用类型)和抛出异常,要和被重写方法的返回值(引用类型)和抛出异常****相同或者是其子类。注意,一旦返回值是基本数据类型,那么重写方法和被重写方法必须相同,且不存在自动拆装箱的问题。

3、一大:重写方法的访问修饰符大于等于被重写方法的访问修饰符。

72、下列哪些语句关于内存回收的说明是正确的? ( ) 答案:B

A、程序员必须创建一个线程来释放内存
B、内存回收程序负责释放无用内存
C、内存回收程序允许程序员直接释放内存
D、内存回收程序可以在指定的时间释放内存对象
解析:A、JVM一旦启动,就会创建一个守护线程来监测是否需要有对象内存被释放。

C、无法直接释放。

D、不可以指定时间,System.gc(),只是提醒JVM可以进行一次Full GC,但是什么时候真正执行,还是不知道的。

img

73、instanceof运算符能够用来判断一个对象是否为: 答案:C

A、一个类的实例
B、一个类的实例
C、全部正确
D、一个子类的实例
解析:instance是java的二元运算符,用来判断他左边的对象是否为右面类(接口,抽象类,父类)的实例

74、以下程序的输出结果是 答案:A
public class Print{
    static boolean out(char c){
        System.out.print(c);
        return true;
    }
    public static void main(String[] argv){
        int i = 0;
        for(out('A');out('B') && (i<2);out('C')){
            i++;
            out('D');
        }
    }
}

A、ABDCBDCB
B、BCDABCD
C、编译错误
D、运行错误
解析:答案选A 解释:这道题考for循环执行顺序 参看 http://jingyan.baidu.com/article/7f766dafaa6ee04101e1d0e6.html

for循环的执行顺序用如下表达式:

for(expression1;expression2;expression3){

expression4;

}

执行的顺序应该是:

1)第一次循环,即初始化循环。

首先执行表达式expression1(一般为初始化语句);再执行expression2(一般为条件判断语句),判断expression1是否符合expression2的条件;如果符合,则执行expression4,否则,停止执行;最后执行expression3。

2)第N(N>=2)次循环

首先执行expression2,判断在expression3是否符合在expression2要求;如果符合,则继续执行在expression4,否则,停止执行。最后执行在expression3。如此往复,直至expression3不满足在expression2条件是为止。

总结:

总的来说,执行的顺序是一致的。先条件判断(expression2),再函数体执行(expression4),最后for执行(expression3)。往复…区别在于,条件判断的对象。第一次判断时,对象为初始化语句(expression1),后续的判断对象为执行后的结果(expression3)。

75、下列哪个说法是正确的() 答案:D

A、ConcurrentHashMap使用synchronized关键字保证线程安全
B、HashMap实现了Collction接口
C、Array.asList方法返回java.util.ArrayList对象
D、SimpleDateFormat是线程不安全的
解析:

A选项中,ConcurrentHashMap 使用segment来分段和管理锁,segment继承自ReentrantLock,因此ConcurrentHashMap使用ReentrantLock来保证线程安全。

B中,HashMap定义规则如下:

public class HashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable

C中,应该是Arrays.asList(),其将一个数组转化为一个List对象,这个方***返回一个ArrayList类型的对象, 这个ArrayList类并非java.util.ArrayList类,而是Arrays类的内部类:

图片说明

2、A. JDK1.8 的 ConcurrentHashMap 采用CAS+Synchronized保证线程安全。 JDK1.7 及以前采用segment的分段锁机制实现线程安全,其中segment继承自ReentrantLock,因此采用Lock锁来保证线程安全。

B. img

C. Arrays.asList() 返回 java.util.Arrays.ArrayList 对象,这里的 ArrayList 是 Arrays 私有的内部类

D. img

76、Java Application 源程序的主类是指包含有( )方法的类。 答案:

A、public static void main方法
B、toString方法
C、init方法
D、actionPerfromed方法
解析:java程序种类:

1.内嵌于web文件中,有浏览器观看的applet

2.可独立运行的application

3.服务器端的servlets

77、在 applet 的方法中 , 可关闭小应用程序并释放其占用资源的是( ) 答案:D

A、stop()
B、paint()
C、init()
D、destroy()
解析:Applet 类是浏览器类库中最为重要的类,同时也是所有 JAVA 小应用程序的基本类。 一个 Applet 应用程序从开始运行到结束时所经历的过程被称为 Applet 的生命周期。 Applet 的生命周期涉及 init() 、 start() 、 stop() 和 destroy() 四种方法,这 4 种方法都是 Applet 类的成员,可以继承这些方法,也可以重写这些方法,覆盖原来定义的这些方法。除此之外,为了在 Applet 程序中实现输出功能,每个 Applet 程序中还需要重载 paint() 方法:

1、 public void init()

init()方法是 Applet 运行的起点。当启动 Applet 程序时,系统首先调用此方法,以执行初始化任务。

2、 public void start()

start()方法是表明 Applet 程序开始执行的方法。当含有此 Applet 程序的 Web 页被再次访问时调用此方法。因此,如果每次访问 Web 页都需要执行一些操作的话,就需要在 Applet 程序中重载该方法。在 Applet 程序中,系统总是先调用 init() 方法,后调用 start() 方法。

3、 public void stop()

stop()方法使 Applet 停止执行,当含有该 Applet 的 Web 页被其他页代替时也要调用该方法。

4、 public void destroy()

destroy()方法收回 Applet 程序的所有资源,即释放已分配给它的所有资源。在 Applet 程序中,系统总是先调用 stop() 方法,后调用 destroy() 方法。

5、 paint(Graphics g)

paint(Graphics g)方法可以使 Applet 程序在屏幕上显示某些信息,如文字、色彩、背景或图像等。参数 g 是 Graphics 类的一个对象实例,实际上可以把 g 理解为一个画笔。对象 g 中包含了许多绘制方法,如 drawstring() 方法就是输出字符串。

78、下列说法正确的是( ) 答案:C

A、volatile,synchronized 都可以修改变量,方法以及代码块
B、volatile,synchronized 在多线程中都会存在阻塞问题
C、volatile能保证数据的可见性,但不能完全保证数据的原子性,synchronized即保证了数据的可见性也保证了原子性
D、volatile解决的是变量在多个线程之间的可见性、原子性,而sychroized解决的是多个线程之间访问资源的同步性
解析:synchronized关键字和volatile关键字比较:

  • volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。

  • 多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞

  • volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。

  • volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。

    2、synchronized: 具有原子性,有序性和可见性;(三个都有)
    volatile:具有有序性和可见性(缺一个原子性)

79、下面程序的输出是什么? 答案:B
public class TestDemo
{
    public static String output = "";
    public static void foo(inti)
    {
        try
        {
            if (i == 1)
            {
                throw new Exception();
            }
        }
        catch (Exception e)
        {
            output += "2";
            return ;
        } finally
        {
            output += "3";
        }
        output += "4";
    }
    public static void main(String[] args)
    {
        foo(0);
        foo(1);
        System.out.println(output);
    }
}

A、342
B、3423
C、34234
D、323
解析:首先是foo(0),在try代码块中未抛出异常,finally是无论是否抛出异常必定执行的语句,

所以 output += “3”;然后是 output += “4”;

执行foo(1)的时候,try代码块抛出异常,进入catch代码块,output += “2”;

前面说过finally是必执行的,即使return也会执行output += “3”

由于catch代码块中有return语句,最后一个output += “4”不会执行。

所以结果是3423

2、try-catch-finally块中,finally块在以下几种情况将不会执行。

(1)finally块中发生了异常。

(2)程序所在线程死亡。

(3)在前面的代码中用了System.exit();

(4)关闭了CPU

80、如何获取ServletContext设置的参数值? 答案:B

A、context.getParameter()
B、context.getInitParameter()
C、context.getAttribute()
D、context.getRequestDispatcher()
解析:getParameter()是获取POST/GET传递的参数值;
getInitParameter获取Tomcat的server.xml中设置Context的初始化参数

getAttribute()是获取对象容器中的数据值;
getRequestDispatcher是请求转发。

81、现有一变量声明为 boolean aa; 下面赋值语句中正确的是 ( ) 答案:A

A、aa=false;
B、aa=False;
C、aa=“true”;
D、aa=0;
解析:

img

82、执行下列程序的输出结果为( ) 答案:D
public class Test {
    public static void main(String[] args) {
         String s1 = "HelloWorld";
         String s2 = new String("HelloWorld");
         if (s1 == s2) {
             System.out.println("s1 == s2");
         } else {
             System.out.println("s1 != s2");
         }
         if (s1.equals(s2)) {
             System.out.println("s1 equals s2");
         } else {
             System.out.println("s1 not equals s2");
         }
     }
 }

A、

s1 == s2
s1 not equals s2

B、

s1 == s2
s1 equals s2

C、

s1 != s2
s1 not equals s2

D、

s1 != s2
s1 equals s2

解析:1.== 和 equals():

(1)“==” 用于比较基本数据类型时比较的是值,用于比较引用类型时比较的是引用指向的地址。

(2)Object 中的equals() 与 “==” 的作用相同,但String类重写了equals()方法,比较的是对象中的内容。

public boolean equals(Object anObject) {  if (this == anObject) {
          return true;    } else {  if (anObject instanceof String) {
            String aString = (String)anObject;
       if (this.coder() == aString.coder()) {  return this.isLatin1() ? StringLatin1.equals(this.value, aString.value) : StringUTF16.equals(this.value, aString.value); 
       }
      } return false;    }
}
83、在一个基于分布式的游戏服务器系统中,不同的服务器之间,哪种通信方式是不可行的()? 答案:A

A、管道
B、消息队列
C、高速缓存数据库
D、套接字
解析:对于管道,有下面这几种类型:

①普通管道(PIPE):通常有两种限制,一是单工,即只能单向传输;二是血缘,即常用于父子进程间(或有血缘关系的进程间)。

②流管道(s_pipe):去除了上述的第一种限制,实现了双向传输。

③命名管道(name_pipe):去除了上述的第二种限制,实现了无血缘关系的不同进程间通信。

*显然,要求是对于不同的服务器之间的通信,是要要求全双工形式的,而管道只能是半双工**,虽然可以双向,*但是同一时间只能有一个方向传输,全双工和半双工的区别可以如下图示理解:

img

84、关于中间件特点的描述.不正确的是() 答案:A

A、中间件运行于客户机/服务器的操作系统内核中,提高内核运行效率
B、中间件应支持标准的协议和接口
C、中间件可运行于多种硬件和操作系统平台上
D、跨越网络,硬件,操作系统平台的应用或服务可通过中间件透明交互
解析:

中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件。相连接的系统,即使它们具有不同的接口,但通过中间件相互之间仍能交换信息。执行中间件的一个关键途径是信息传递。通过中间件,应用程序可以工作于多平台或OS环境。

85、下面有关java classloader说法正确的是()? 答案:A C D

A、ClassLoader就是用来动态加载class文件到内存当中用的
B、JVM在判定两个class是否相同时,只用判断类名相同即可,和类加载器无关
C、ClassLoader使用的是双亲委托模型来搜索类的
D、Java默认提供的三个ClassLoader是Boostrap ClassLoader,Extension ClassLoader,App ClassLoader
解析:JDK中提供了三个ClassLoader,根据层级从高到低为:

  1. Bootstrap ClassLoader,主要加载JVM自身工作需要的类。
  2. Extension ClassLoader,主要加载%JAVA_HOME%\lib\ext目录下的库类。
  3. Application ClassLoader,主要加载Classpath指定的库类,一般情况下这是程序中的默认类加载器,也是ClassLoader.getSystemClassLoader() 的返回值。(这里的Classpath默认指的是环境变量中配置的Classpath,但是可以在执行Java命令的时候使用-cp 参数来修改当前程序使用的Classpath)

JVM加载类的实现方式,我们称为 双亲委托模型

如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委托给自己的父加载器,每一层的类加载器都是如此,因此所有的类加载请求最终都应该传送到顶层的Bootstrap ClassLoader中,只有当父加载器反馈自己无法完成加载请求时,子加载器才会尝试自己加载。

双亲委托模型的重要用途是为了解决类载入过程中的安全性问题。

假设有一个开发者自己编写了一个名为***Java.lang.Object*的类,想借此欺骗JVM。现在他要使用自定义ClassLoader来加载自己编写的java.lang.Object*类。然而幸运的是,双亲委托模型不会让他成功。因为JVM会优先在Bootstrap ClassLoader的路径下找到**java.lang.Object***类,并载入它

86、给出以下代码 答案:B
public class TestObj{
    public static void main(String[] args){
        Object o=new Object(){
            public boolean equals(Object obj){
                return true;
            }
        };
        System.out.println(o.equals("Fred"));
    }
}

A、运行时抛出异常
B、true
C、Fred
D、第三行编译错误
解析:本题涉及匿名内部类、多态和覆盖三个知识点。 语句

Object o=new Object(){
            public boolean equals(Object obj){
                return true;
            }
        };

创建了一个匿名内部类,并将所创建的匿名对象赋给 Object (多态:子类对象赋给超类引用)。同时,该匿名内部类重写了 Object 类的 equals 方法。

在执行语句

o.equals(“Fred”)

时,根据多态及覆盖原则,会调用匿名内部类重写后的 equals 方法。

关于 “Java 内部类 ” 和 “Java 继承、多态与类的复用” 的更详细的阐述,请查看我的两篇博文 “http://blog.csdn.net/justloveyou_/article/details/53245561” 和 “http://blog.csdn.net/justloveyou_/article/details/52798666”。

87、下面有关java基本类型的默认值和取值范围,说法错误的是? 答案:C

A、字节型的类型默认值是0,取值范围是-27—27-1
B、boolean类型默认值是false,取值范围是true\false
C、字符型类型默认是0,取值范围是-2^15 —2^15-1
D、long类型默认是0,取值范围是-263—263-1
解析:

  1. 默认值 取值范围 示例

字节型 : 0 -27—-27-1 byte b=10;

字符型 : ‘ \u0000′ 0—-2^16-1 char c=’c’ ;

short : 0 -215—-215-1 short s=10;

int : 0 -231—-231-1 int i=10;

long : 0 -263—-263-1 long o=10L;

float : 0.0f -231—-231-1 float f=10.0F

double : 0.0d -263—-263-1 double d=10.0;

boolean: false true\false boolean flag=true;

默认值存储需求(字节)取值范围示例
byte01-27—27-1byte b=10;
char‘ \u0000′20—2^16-1char c=’c’ ;
short02-215—215-1short s=10;
int04-231—231-1int i=10;
long08-263—263-1long o=10L;
float0.0f4-231—231-1float f=10.0F
double0.0d8-263—263-1double d=10.0;
booleanfalse1true\falseboolean flag=true;
88、访问权限控制从最大权限到最小权限依次为:public、 包访问权限、protected和private 。( ) 答案:B

A、正确
B、错误
解析:应该是:public>protected>默认(包访问权限)>private,因为protected除了可以被同一包访问,还可以被包外的子类所访问

img

89、关于访问权限说法正确 的是 ? ( ) 答案:B

A、外部类前面可以修饰public,protected和private
B、成员内部类前面可以修饰public,protected和private
C、局部内部类前面可以修饰public,protected和private
D、以上说法都不正确
解析:

privatedefaultprotectedpublic
同一个类中
同一个包中
子类中
全局范围内

( 1 )对于外部类而言,它也可以使用访问控制符修饰,但外部类只能有两种访问控制级别: public 和默认。因为外部类没有处于任何类的内部,也就没有其所在类的内部、所在类的子类两个范围,因此 private 和 protected 访问控制符对外部类没有意义。

( 2 )内部类的上一级程序单元是外部类,它具有 4 个作用域:同一个类( private )、同一个包( protected )和任何位置( public )。

( 3 ) 因为局部成员的作用域是所在方法,其他程序单元永远不可能访问另一个方法中的局部变量,所以所有的局部成员都不能使用访问控制修饰符修饰。

90、下列说法正确的有( ) 答案:A C D

A、构造方法的方法名必须与类名相同
B、构造方法也没有返回值,但可以定义为void
C、在子类构造方法中调用父类的构造方法,super() 必须写在子类构造方法的第一行,否则编译不通过
D、一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个默认的构造方法,这个构造方法不执行任何代码
解析:关于B选项:Java:语法要求的构造函数只能那么写。如果写成public void 类名(){} 这种格式的话。此时就相当与你重新定义了一个函数,不能起到构造函数的作用,调用这个类的时候不能自动执行构造函数里的代码。

91、若有下列定义,下列哪个表达式返回false? 答案:
String s = "hello";
String t = "hello";
char c[] = {'h', 'e', 'l', 'l', 'o'} ;

A、s.equals(t);
B、t.equals©;
C、s==t;
D、t.equals(new String(“hello”));
解析:Java又不是C++,什么时候字符数组等于字符串了(对这句话我不负责任)?

而常量池中的字符串,只有变量名不同是可以用双等号判断是否相等的,内存都是常量池中的字符串。

但是new出来的字符串,只能用equals,用双等号是不相等的,因为是两个内存对象。

public class HelloWorld {
    public static void main(String []args) {
        String s = "hello";
        String t = "hello";
        char c[] = {'h','e','l','l','o'} ;
        System.out.println(s.equals(t));
        //c++中定义的东西,不要在java中混为一谈。(对这句话我不负责任)
        System.out.println(t.equals(c));
        System.out.println(s==t);
        System.out.println(t.equals(new String("hello")));
        //这个不相等,因为语句中new的字符串不在常量池,是在堆
        System.out.println(t==new String("hello"));
        //这样可以判断字符数组与字符串是否包含同样的字符序列
        System.out.println(t.equals(new String(c)));
    }
}
92、关于protected 修饰的成员变量,以下说法正确的是 答案:A

A、可以被该类自身、与它在同一个包中的其它类、在其它包中的该类的子类所访问
B、只能被该类本身和该类的所有的子类访问
C、只能被该类自身所访问
D、只能被同一个包中的类访问
解析:java中有四大修饰符,分别为private,default,protected,public,下面主要是四者之间的区别:
- private(私有的)
private可以修饰成员变量,成员方法,构造方法,不能修饰类(此刻指的是外部类,内部类不加以考虑)。被private修饰的成员只能在其修饰的本类中访问,在其他类中不能调用,但是被private修饰的成员可以通过set和get方法向外界提供访问方式
- default(默认的)
defalut即不写任何关键字,它可以修饰类,成员变量,成员方法,构造方法。被默认权限修饰后,其只能被本类以及同包下的其他类访问。
- protected(受保护的)
protected可以修饰成员变量,成员方法,构造方法,但不能修饰类(此处指的是外部类,内部类不加以考虑)。被protected修饰后,只能被同包下的其他类访问。如果不同包下的类要访问被protected修饰的成员,这个类必须是其子类。
- public(公共的)
public是权限最大的修饰符,他可以修饰类,成员变量,成员方法,构造方法。被public修饰后,可以再任何一个类中,不管同不同包,任意使用。
public protected default private
同一个类 √ √ √ √
同一个包 √ √ √
子类 √ √
不同包 √
img

93、下列说法正确的是() 答案:C

A、WebLogic中开发消息Bean的non-persistent 方式可以保证消息的可靠
B、EJB容器发生错误,non-persistent方式下JMS容器仍然会将消息发送
C、EJB容器发生错误,persistent方式下JMS容器仍然会将消息发送
D、EJB容器发生错误,两种方式下JMS容器仍会在MDB可用的时候将消息发送
解析:weblogic中开发消息Bean时的persistent与non-persisten的差别:

  • persistent方式的MDB可以保证消息传递的可靠性,也就是如果EJB容器出现问题而JMS服务器依然会将消息在此MDB可用的时候发送过来。
  • non-persistent方式的消息将被丢弃
94、以下代码运行输出的是 答案:C
public class Person{
    private String name = "Person";
    int age=0;
}
public class Child extends Person{
    public String grade;
    public static void main(String[] args){
        Person p = new Child();
        System.out.println(p.name);
    }
}

A、输出:Person
B、没有输出
C、编译出错
D、运行出错
解析:Java中对字段属性是静态绑定,方法成员是动态绑定,这里错在:在子类中试图访问父类的private字段,所以编译不通过,将private去掉就可访问,不是动态绑定的问题,它本来就属于静态绑定。

2、
1.一个java文件里,public 的类只能出现一个,只能出现一个,只能出现一个,否则,不管你用哪一个类名命名文件名编译器都会报错

2.关于多态。子类继承了父类的所有成员,包括private权限的成员变量,但是继承的子类具有私有变量的拥有权但是没有使用权。

3.private的成员变量,根据权限修饰符的访问控制范围,只有在类内部才能被访问,就算是他的子类,也不能访问。

95、以下哪些语言是面向对象的是() 答案:B C

A、C
B、C++
C、JAVA
D、汇编
解析:c是面向过程,c++面向对象,JAVA面向对象,汇编是面向机器

96、类 ABC 定义如下 答案:B

1 . public class ABC{

2 . public double max( double a, double b) { }

3 .

4 . }

将以下哪个方法插入行 3 是不合法的。()

A、public float max(float a, float b, float c){ return a }
B、public double max (double c, double d){ return c }
C、public float max(float a, float b){ return a }
D、private int max(int a, int b, int c){return a }
解析:重载要求方法的参数列表需要不一样(个数,或者参数类型),修改参数名或者修改返回值以及访问权限并没有用
img

97、通过HttpServletRequest. getParameter获取的参数. 答案:C

A、总是采用UTF-8编码
B、总是采用lS08859-1编码
C、由客户端浏览器和Web容器配置共同决定编码
D、由服务器所在的操作系统决定编码
解析:编码格式由浏览器决定,浏览器根据html中指定的编码格式进行编码,tomcat根据指定的格式进行解码,另外get请求和post请求对编码格式的处理也是不同的
2、选C

1、浏览器根据jsp页面开头声明的编码方式对request中参数编码;

2、tomcat默认解码是ISO-8859-1, 但是我们可以显示指定解码格式通过调用 request.setCharacterEncoding(“UTF-8”),或者修改tomcat的配置文件server.xml中的编码,添加uriEncoding属性。

98、Math.floor(-8.5)=( ) 答案:D

A、(float)-8.0
B、(long)-9
C、(long)-8
D、(double)-9.0
解析:D Math.floor(x) 返回小于等于x的最接近整数,类型为double

99、ava中Hashtable, Vector, TreeSet, LinkedList哪些线程是安全的? 答案: A B

A、Hashtable
B、Vector
C、TreeSet
D、LinkedList
解析:线程安全概念:

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

线程安全问题都是由全局变量静态变量引起的。

若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

img

LinkedList 和 ArrayList 都是不同步的,线程不安全;
Vector 和 Stack 都是同步的,线程安全;
Set是线程不安全的;

Hashtable的方法是同步的,线程安全;
HashMap的方法不是同步的,线程不安全;

简单记忆线程安全的集合类: 喂! SHE 喂是指 vector S 是指 stack H 是指 hashtable E 是指: Eenumeration

100、下述有关c++的虚类和java接口的描述,说法错误的是? 答案:C D

A、c++虚类相当与java里面的抽象类
B、c++中没有接口的概念,与之对应的是纯虚类,对应的是java的接口
C、纯虚函数和虚函数的区别在于前者只包含定义,而后者还可以包含函数体。
D、一个抽象类和接口中的方法必须是抽象方法
解析:

1、一个子类只能继承一个抽象类(虚类),但能实现多个接口;
2、一个抽象类可以有构造方法,接口没有构造方法;
3、一个抽象类中的方法不一定是抽象方法,即其中的方法可以有实现(有方法体),接口中的方法都是抽象方法,不能有方法体,只有声明;
4、一个抽象类可以是public、private、protected、default,
   接口只有public;
5、一个抽象类中的方法可以是public、private、protected、default,
   接口中的方法只能是public和default
101、设int x=1,float y=2,则表达式x/y的值是:() 答案:D

A、0
B、1
C、2
D、以上都不是
解析:本题的意义在于两点,明白这两点之后题会不会本身就不重要了:①float x = 1;与float x = 1.0f,这两种对于float类型的变量来说定义的方式都是正确的,也是比较常见的笔试题里面考察类型转换的例子,当第一种情况时,是将低精度int向上转型到float,是由于java的特性导致而不需要进行强制转换,而第二种情况则是比较正式的对于float变量的定义,由于这种类型本身在工作项目中并不常见,常用的带小数的数字我们一般都直接使用double类型,而double类型直接定义是没有问题的:double x = 1.0。而由于float的精度没有double类型高,因此必须对其进行显示的格式书写,如果没有这个f,就默认是double类型了。当然double x = 1.0d也是正确的命名,不信你可以尝试,虽然这是一个令人窒息的操作。②当多个精度的数字同时进行运算时,最终结果以最高精度为准。在多数情况下,整数和小数的各级混合运算中,一般结果都是double类型的。但就本题而言,结果是float类型的,因为x,y两个数字精度最高的就是float,所以最终结果是0.5,并且这个0.5是float类型的。为什么说不是double类型呢,当然如果你这样处理:double m = x/y,当然m是double类型的,也不会报错,而如果你写成int m = x/y,编译器报错提示的时候就会让你转换成float或者进行强制转换成int,他是不会提示你转换成double的,尽管这么写并没有报错,原因就是①

中所说的向上强转。float转换成double不需要任何提示。

102、定义有StringBuffer s1=new StringBuffer(10);s1.append(“1234”),则s1.length()和s1.capacity()分别是多少? 答案:A

A、4 10
B、4 4
C、10 10
D、10 4
解析:length 返回当前长度

如果字符串长度没有初始化长度大,capacity返回初始化的长度

如果append后的字符串长度超过初始化长度,capacity返回增长后的长度

103、若需要定义一个类,下列哪些修饰符是允许被使用的?( ) 答案:A C D

A、static
B、package
C、private
D、public
解析:这题只说定义一个类,但是没有说这个类是普通外部类或者内部类。

因为**普通类也就是外部类,**通过 eclipse 的警告“Illegal modifier for the class Test; only public, abstract & final are permitted” 可知只能用 public, abstract 和 final 修饰。

内部类则可以用 **修饰成员变量的修饰符修饰内部类,**比如 private, static, protected 修饰。

2、

104、下面哪些类实现或继承了 Collection 接口? 答案:B C

A、HashMap
B、ArrayList
C、Vector
D、Iterator
解析:

img

105、character流和byte流的的说法错误的是 答案:A B D

A、每次读入的字节数不同
B、前者带有缓冲,后者没有。
C、前者是字符读入,后者是字节读入。
D、二者没有区别,可以互换。
解析:字符流和字节流每次读入的字节数是不确定的,可能相同也可能不相同;字符流和字节流都有缓冲流
2、Java的流操作分为字节流和字符流两种。

字节流与字符流主要的区别是他们的处理方式

字节流是最基本的,所有的InputStream和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的。但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化

这两个之间通过 InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联。

在实际开发中出现的汉字问题实际上都是在字符流和字节流之间转化不统一而造成的。
字节流---->字符流
字节流转化为字符流,实际上就是byte[]转化为String时,
public String(byte bytes[], String charsetName)
有一个关键的参数字符集编码,通常我们都省略了,那系统就用操作系统的lang
字符流---->字节流

字符流转化为字节流,实际上是String转化为byte[]时,byte[] String.getBytes(String charsetName)也是一样的道理至于java.io中还出现了许多其他的流,按主要是为了提高性能和使用方便,如BufferedInputStream,PipedInputStream等

常识:

对于GBK编码标准,英文占用1个字节,中文占用2个字节
对于UTF-8编码标准,英文占用1个字节,中文占用3个字节
对于Unicode编码标准,英文中文都是2个字节。这也是为什么叫做unicode

106、cnt的值是 答案: A
public class Test1 {
 
    static int cnt = 6;
 
    static {
        cnt += 9;
    }
 
    public static void main(String[] args) {
        System.out.println("cnt =" + cnt);
    }
 
    static {
        cnt /= 3;
    }
}

A、cnt=5
B、cnt=2
C、cnt=3
D、cnt=6
解析:看了前面的解答,我想更正一下其中几位同学的解答。

如楼上有的同学说的,静态初始化块,静态变量这两个是属于同一级别的,是按代码写得顺序执行的!

而不是先执行静态变量后执行静态初始化块!这是错的。我举个例子:

public class Test{  static{  cnt = 6;
    }  static int cnt = 100;  public static void main(String[] args){
        System.out.println("cnt = " + cnt);
        //最后输出是50,如果按照错误说法就应该是3
        //按顺序执行就是cnt=6--->cnt=100---->cnt = 100/2 = 50.
    }  static{ cnt /= 2;
    }
}

2、(1)父类静态成员和静态初始化块,按在代码中出现的顺序依次执行。

(2)子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。

(3)父类实例成员和实例初始化块,按在代码中出现的顺序依次执行。

(4)执行父类构造方法。

(5)子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。

(6)执行子类构造方法。

107、在Java中,以下关于方法重载和方法重写描述正确的是? 答案:D

A、方法重载和方法的重写实现的功能相同
B、方法重载出现在父子关系中,方法重写是在同一类中
C、方法重载的返回值类型必须一致,参数项必须不同
D、方法重写的返回值类型必须相同或相容。(或是其子类)
解析:方法重载的返回值的类型可以不同,因为判断方法重载的方法主要是根据方法的参数不同来判定;方法重写的返回值类型需要相同,重写就是子类继承了父类的方法,并在此方法上重写属于自己的特征,既然是继承过来的,那么它的返回值类型就必须要相同
2、

public class TTTTT extends SuperC{
    public String get(){
        return null;
    }
}
class SuperC{
    Object get(){
        return null;
    }
}
方法重载(overload):
1.必须是同一个类
2方法名(也可以叫函数)一样
3参数类型不一样或参数数量不一样

方法的重写(override)两同两小一大原则:
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。
108、Math.round(11.5) 等于多少 (). Math.round(-11.5) 等于多少 ( ). 答案:C

A、11 ,-11
B、11 ,-12
C、12 ,-11
D、12 ,-12
解析:floor : 意为地板,指向下取整,返回不大于它的最大整数 ceil : 意为天花板,指向上取整,返回不小于它的最小整数 round : 意为大约,表示“四舍五入”,而四舍五入是往大数方向入。Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11而不是-12。

109、实现或继承了Collection接口的是() 答案:B C E

A、Map
B、List
C、Vector
D、Iterator
E、Set
解析:

A,Map接口未实现Collection接口
B,List接口的定义为
public interface List<E>extends Collection<E>
C,Vector定义为
public class Vector<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, Serializable
Vector实现了List接口自然实现了Collection接口

D,Iterator接口未实现Collection接口
E,
public interface Set<E>extends Collection<E>
Set接口继承自Collection接口
110、Hashtable 和 HashMap 的区别是: 答案:B C D E

A、Hashtable 是一个哈希表,该类继承了 AbstractMap,实现了 Map 接口
B、HashMap 是内部基于哈希表实现,该类继承AbstractMap,实现Map接口
C、Hashtable 线程安全的,而 HashMap 是线程不安全的
D、Properties 类 继承了 Hashtable 类,而 Hashtable 类则继承Dictionary 类
E、HashMap允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
解析:选B、C、D、E。

Hashtable

(1)Hashtable 是一个散列表,它存储的内容是键值对(key-value)映射。

(2)Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。

(3)HashTable直接使用对象的hashCode。

HashMap:

(1)由数组+链表组成的,基于哈希表的Map实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。

(2)不是线程安全的,HashMap可以接受为null的键(key)和值(value)。

(3)HashMap重新计算hash

Hashtable,HashMap,Properties继承关系如下:

public class Hashtable<K,V> extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable
 
public class HashMap<K,V>extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
java.lang.Objecct
  java.util.Dictionary<K,V>
    java.util.Hashtable<Object,Object>
      java.util.Properties 
111、在上下文和头文件正常的情况下,代码将打印? 答案:B
System.out.println(10%3*2);

A、1
B、2
C、4
D、6
解析:%和*是同一个优先级,从左到右运算

img

112、在 JAVA 编程中, Java 编译器会将 Java 程序转换为( ) 答案:A

A、字节码
B、可执行代码
C、机器代码
D、以上都不对
解析:
编译器将Java源代码编译成字节码class文件
类加载到JVM里面后,执行引擎把字节码转为可执行代码
执行的过程,再把可执行代码转为机器码,由底层的操作系统完成执行。

113、下列关于计算机系统和Java编程语言的说法,正确的是() 答案:C

A、计算机是由硬件、操作系统和软件组成,操作系统是缺一不可的组成部分。
B、Java语言编写的程序源代码可以不需要编译直接在硬件上运行。
C、在程序中书写注释不会影响程序的执行,可以在必要的地方多写一些注释。
D、Java的集成开发环境(IDE),如Eclipse,是开发Java语言必需的软件工具。
解析:裸机也可以跑,以前搞嵌入式的时候,并不一定要安装操作系统,直接操作寄存器就可以了,操作系统不是必须的
/2多写详细的注释,我认为是错的。大量详细的注释会导致系统后期难以维护。应该是良好的编码风格+清晰的变量定义+必要的注释。

114、以下 b 的值是: byte b = (byte)129; 答案:B

A、-126
B、-127
C、-128
D、-129
解析:答案是B。
因为byte是有符号单字节整形,所以存储数字范围是[-128·127]
而127[01111111]+1==128[10000000]。
为什么呢?
因为科学家定义数字的时候是一个环,最大的数字后面就是最小,这样才可以把[0·255]分配给[-128·127]。
底层就是补码的概念。
好,我们再从java程序上运行一次。

public class HelloWorld {
    public static void main(String []args) {
       byte b = (byte)129;
       byte c = (byte)128;
       System.out.println(b);
       System.out.println(c);
    }
}

都写的啥****,我来正解,上面没看到完全正确的,所以实在忍不了写出正确的解答

这题考察的就两个知识点:一、强制转换(主要涉及各个类型占几个字节,这里我只简单说一下byte型占一个字节,也就是8位,int型4个字节,32位);二、在计算机系统中,数值一律用补码来表示(存储)

正数:补码=反码=原码(当然以二进制形式表达)

129 int类型(4个字节)二进制: 00000000 00000000 00000000 10000001

强制转换byte型后,只有一个字节即 10000001(注意这里从二进制角度看,第一位是符号位,即求负数的补码接下来)

只要求出上面原码对应的补码就行了,然后再转换对应的int型数值(因为题干所给的答案都是比较int型)

10000001(原码) 对应的反码为1111 1110

又补码等于反码+1

即1111 1111 该二进制转换int型刚好是-127(1+2+4+8+16+32+64)

普及一下:正数原码,反码,补码相同

负数反码除了符号位不变,其他位取反,补码=反码+1;

之前那些解答都啥玩意,不会别误导大家,我的是正解,嘻嘻

115、JDK1.8版本之前,抽象类和接口的区别,以下说法错误的是 答案:D

A、接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的。
B、abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个interface,实现多重继承。接口还有标识(里面没有任何方法,如Remote接口)和数据共享(里面的变量全是常量)的作用。
C、在abstract class 中可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface中,只能够有静态的不能被修改的数据成员(也就是必须是 static final的,不过在 interface中一般不定义数据成员),所有的成员方法默认都是 public abstract 类型的。
D、abstract class和interface所反映出的设计理念不同。其实abstract class表示的是"has-a"关系,interface表示的是"is-a"关系。
解析:1)接口可以继承接口,而且可以继承多个接口,但是不能实现接口,因为接口中的方法全部是抽象的,无法实现;

另外,如果是Java 7以及以前的版本,那么接口中可以包含的内容有:1. 常量;2. 抽象方法
如果是Java 8,还可以额外包含有:3. 默认方法;4. 静态方法
如果是Java 9,还可以额外包含有:5. 私有方法

2)普通类可以实现接口,并且可以实现多个接口,但是只能继承一个类,这个类可以是抽象类也可以是普通类,如果继承抽象类,必须实现抽象类中的所有抽象方法,否则这个普通类必须设置为抽象类;

3)抽象类可以实现接口,可以继承具体类,可以继承抽象类,也可以继承有构造器的实体类。

抽象类中可以有静态main方法;抽象类里可以没有抽象方法,没有抽象方法的抽象类就是不想让别人实例化它;

另外,抽象类可以有构造方法,只是不能直接创建抽象类的实例对象而已。在继承了抽象类的子类中通过super(参数列表)调用抽象类中的构造方法,可以用于实例化抽象类的字段。

下面总结常见的抽象类与接口的区别:

1)抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象;

2)接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现(java8中 接口可以有实现方法 使用default修饰);

3)接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量;

4)抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个类实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类;

5)抽象方法要被实现,所以不能是静态static的,也不能是私有private的,也不能被final修饰(试想一下,静态方法可以被类名直接调用,而类名直接调用一个没有实现的抽象方法没有意义)。
2、is-a:继承关系 has-a:从属关系 like-a:组合关系

116、下面哪个选项是main方法的返回类型? 答案: B

A、int
B、void
C、Boolean
D、static
解析:Java中类的主方法定义如下

class Demo{
    public static void main(String args[]){
    //代码段
    }
}
117、代码片段: 关于上面代码片段叙述正确的是() 答案:C
byte b1=1,b2=2,b3,b6; 
final byte b4=4,b5=6; 
b6=b4+b5; 
b3=(b1+b2); 
System.out.println(b3+b6);

A、输出结果:13
B、语句:b6=b4+b5编译出错
C、语句:b3=b1+b2编译出错
D、运行期抛出异常
解析:被final修饰的变量是常量,这里的b6=b4+b5可以看成是b6=10;在编译时就已经变为b6=10了

而b1和b2是byte类型,java中进行计算时候将他们提升为int类型,再进行计算,b1+b2计算后已经是int类型,赋值给b3,b3是byte类型,类型不匹配,编译不会通过,需要进行强制转换。

Java中的byte,short,char进行计算时都会提升为int类型。
2、表达式的数据类型自动提升, 关于类型的自动提升,注意下面的规则。

①所有的byte,short,char型的值将被提升为int型;

②如果有一个操作数是long型,计算结果是long型;

③如果有一个操作数是float型,计算结果是float型;

④如果有一个操作数是double型,计算结果是double型;

而声明为final的变量会被JVM优化,第6行相当于 b6 = 10

118、下列关于if-else if选择结构的说法正确的是 答案:B D

A、多个else if块之间的顺序可以改变,改变之后对程序的执行结果没有影响
B、多个else if块之间的顺序可以改变,改变之后可能对程序的执行结果有影响
C、多个else if块之间的顺序不可以改变,改变后程序编译不通过
D、多个else if块之间的顺序可以改变,改变后程序编译可以通过
解析:

int age = 11;
int a = 0;
if(age < 10){
    a += 1;
}else if(age < 15){
    a += 2;
}else if(age < 25){
    a += 3;
}上面的代码  两个ifelse如果互换位置   a的值就不一样了:
119、java运行时内存分为“线程共享”和“线程私有”两部分,以下哪些属于“线程共享”部分 答案: B D

A、程序计算器
B、方法区
C、java虚拟机栈
D、java堆
解析:共享的资源有:

a. 堆 由于堆是在进程空间中开辟出来的,所以它是理所当然地被共享的;因此new出来的都是共享的(16位平台上分全局堆和局部堆,局部堆是独享的)

b. 全局变量 它是与具体某一函数无关的,所以也与特定线程无关;因此也是共享的

c. 静态变量 虽然对于局部变量来说,它在代码中是“放”在某一函数中的,但是其存放位置和全局变量一样,存于堆中开辟的.bss和.data段,是共享的

d. 文件等公用资源 这个是共享的,使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。

独享的资源有

a. 栈 栈是独享的

b. 寄存器 这个可能会误解,因为电脑的寄存器是物理的,每个线程去取值难道不一样吗?其实线程里存放的是副本,包括程序计数器PC

私有:java虚拟机栈,程序计数器,本地方法栈 共享:java堆,方法区
120、Given the following code: 正确答案: A D
package cn.com.test;
 
public class EnclosingOne {
    public class InsideOne {}
 
}
package cn.com.cow;
 
import cn.com.test.EnclosingOne;
import cn.com.test.EnclosingOne.InsideOne;
public class InerTest
{
    public static void main(String[]args)
    {
        EnclosingOne eo = new EnclosingOne();
        //insert code here 
    }
 
}

Which statement at line 10 constructs an instance of the inner class?
A、InsideOne ei=eo.new InsideOne();
B、eo.InsideOne ei=eo.new InsideOne();
C、InsideOne ei=EnclosingOne.new InsideOne();
D、EnclosingOne.InsideOne ei=eo.new InsideOne();
解析:

public class Enclosingone {
    //非静态内部类
    public class InsideOne {}
    //静态内部类
    public static class InsideTwo{}
}
 
class Mytest02{
    public static void main(String args []){
        Enclosingone.InsideOne obj1 = new Enclosingone().new InsideOne();//非静态内部类对象
        Enclosingone.InsideTwo obj2 = new Enclosingone.InsideTwo();//静态内部类对象
    }
}

2、对于A答案 主要在开头添加 import EnclosingOne.Insider这一句,不然的话A肯定是错误,其他类不能够直接引用内部类的

img

121、编译 Java 源程序文件产生的字节码文件的扩展名为() 答案:B

A、java
B、class
C、html
D、exe
解析:java源文件的后缀名是.java。源文件通过jvm虚拟机编译后会生成二进制字节码文件,后缀是.class

122、根据以下代码段,执行new Child(“John”, 10); 要使数据域data得到10,则子类空白处应该填写( )。 答案:D
class Parent {
    private int data;
    public Parent(int d){ data = d; }
}
class Child extends Parent{
    String name;
    public Child(String s, int d){
        ___________________
        name = s;
    }
}

A、data = d;
B、super.data = d;
C、Parent(d);
D、super(d);
解析:1.子父类存在同名成员时,子类中默认访问子类的成员,可通过super指定访问父类的成员,格式:super.xx (注:xx是成员名);

2.创建子类对象时,默认会调用父类的无参构造方法,可通过super指定调用父类其他构造方法,格式:s uper(yy) (注:yy是父类构造方法需要传递的参数)
2:1.super可以访问父类中public、default、protected修饰的成员变量,不能访问private修饰的成员变量。格式为super.成员名称。

2.super可以访问父类中public、default、protected修饰的实例方法,不能访问private修饰的实例方法。格式为super.实例方法。

3.super可以访问父类中public、default、protected修饰的构造方法,不能访问private修饰的构造方法,格式为super(参数).

123、以下多线程对int型变量x的操作,哪个不需要进行同步() 答案:D

A、++x
B、x=y
C、x++
D、x=1
解析:同步是害怕在操作过程的时候被其他线程也进行读取操作,一旦是原子性的操作就不会发生这种情况。
因为一步到位的操作,其他线程不可能在中间干涉。另外三项都有读取、操作两个步骤,而X=1则是原子性操作。
2、前三个都至少需要先读取,再操作,非原子操作。而D的话,直接赋值。

124、下面有关java object默认的基本方法,说法错误的是? 答案:B

A、equals(Object obj) 指示某个其他对象是否与此对象“相等”
B、copy() 创建并返回此对象的一个副本
C、wait() 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法
D、toString() 返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成
解析:
Object里的方法如下所示,其中不包含copy方法img

125、以下各类中哪几个是线程安全的?( ) 答案:B C D

A、ArrayList
B、Vector
C、Hashtable
D、Stack
解析:在集合框架中,有些类是线程安全的,这些都是jdk1.1中的出现的。在jdk1.2之后,就出现许许多多非线程安全的类。 下面是这些线程安全的同步的类:

vector:就比arraylist多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率(页面响应速度)是优先考虑的。

statck:堆栈类,先进后出

hashtable:就比hashmap多了个线程安全

enumeration:枚举,相当于迭代器

除了这些之外,其他的都是非线程安全的类和接口。
2、线程同步:喂,SHE

喂(Vector)

S(Stack)

H(hashtable)

E(enumeration)
img

126、下面语句正确的是() 答案:D

A、x+1=5
B、i++=1
C、a++b=1
D、x+=1
解析:总结一下: 1-首先赋值运算符“=”右值可以是任何常数、变量或者表达式(只要能生成一个值就行)。但左值必须是一个明确的、已命名的变量。 2-常用的双元运算符:+=,-=,*=,/= 解析: A:x+1=5,赋值运算符左边是表达式,不对; B:i++=1,从左到右运算是i=i+1=1,赋值运算符左边是表达式,错误; C:a++b=1,赋值运算符左边为表达式,错误。 D:x+=1,既x=x+1,正确。 注意背一下各个运算符的先后顺序。

127、Which of the following statements are valid array declaration? 答案:

(A) int number();
(B) float average[];
© double[] marks;
(D) counter int[];

A、(B) & ©
B、(A)
C、(A) & ©
D、(D)
解析:java里面有两种数组声明方式
2/invalid 无效的 valid 有效的
可能大家错误都犯在这里

128、以下代码输出的是: 答案:A
public class SendValue{
    public String str="6";
    public static void main(String[] args) {
        SendValue sv=new SendValue();
        sv.change(sv.str);
        System.out.println(sv.str);
    }
    public void change(String str) {
        str="10";
    }
}

A、6
B、10
C、都不对
D、16
解析:补充Java内存管理知识:

1. 内存分配策略

按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的。

静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间。这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求。

栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的。和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存。和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。

静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例。堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放。

2. JVM中的堆和栈

JVM是基于堆栈的虚拟机。JVM为每个新创建的线程都分配一个堆栈,也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

java把内存分两种:一种是栈内存,另一种是堆内存

栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。

栈(stack):是一个先进后出的数据结构,通常用于保存方法(函数)中的参数,局部变量。

堆(heap):是一个可动态申请的内存空间(其记录空闲内存空间的链表由操作系统维护),是一个运行时数据区,C中的malloc语句所产生的内存空间就在堆中。

3. 堆和栈优缺点比较

栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。

堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

4. Java中的数据类型有两种

一种是基本类型

共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。

这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。

另外,**栈有一个很重要的特殊性,就是存在栈中的数据可以共享。**假设我们同时定义:

int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。

特别注意的是,这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完a与b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

另一种是包装类数据

如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。

String是一个特殊的包装类数据。即可以用String str = new String(“abc”);的形式来创建,也可以用String str = “abc”;的形式来创建(作为对比,在JDK 5.0之前,你从未见过Integer i = 3;的表达式,因为类与字面值是不能通用的,除了String。而在JDK 5.0中,这种表达式是可以的!因为编译器在后台进行Integer i = new Integer(3)的转换)。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。Java中的有些类,如DateFormat类,可以通过该类的getInstance()方法来返回一个新创建的类,似乎违反了此原则。其实不然。该类运用了单例模式来返回类的实例,只不过这个实例是在该类内部通过new()来创建的,而getInstance()向外部隐藏了此细节。那为什么在String str = “abc”;中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有。

5.String在内存中的存放

String是一个特殊的包装类数据,可以用用以下两种方式创建:

String str = new String(“abc”);第一种创建方式是用new()来新建对象的,它会存放于堆中。每调用一次就会创建一个新的对象。

String str = “abc”; 第二种创建方式先在栈中创建一个对String类的对象引用变量str,然后在栈中查找有没有存放值为”abc”的地址,如果没有,则开辟一个存放字面值为”abc”的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为”abc”的地址,则查找对象o,并返回o的地址,最后将str指向对象o的地址。

值得注意的是,一般String类中字符串值都是直接存值的。但像String str = “abc”;这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!

6.数组在内存中的存放

int x[] 或者int []x 时,在内存栈空间中创建一个数组引用,通过该数组名来引用数组。

x = new int[5] 将在堆内存中分配5个保存int型数据的空间,堆内存的首地址放到栈内存中,每个数组元素被初始化为0。

7.static变量在内存中的存放

用 static的修饰的变量和方法,实际上是指定了这些变量和方法在内存中的“固定位置”-static storage。既然要有“固定位置”那么他们的 “大小”似乎就是固定的了,有了固定位置和固定大小的特征了,在栈中或堆中开辟空间那就是非常的方便了。如果静态的变量或方法在不出其作用域的情况下,其引用句柄是不会发生改变的。

8. java中变量在内存中的分配

1、类变量(static修饰的变量)

在程序加载时系统就为它在堆中开辟了内存,堆中的内存地址存放于栈以便于高速访问。静态变量的生命周期一直持续到整个”系统”关闭

2、实例变量

当你使用java关键字new的时候,系统在堆中开辟并不一定是连续的空间分配给变量(比如说类实例),然后根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的”物理位置”。 实例变量的生命周期–当实例变量的引用丢失后,将被GC(垃圾回收器)列入可回收“名单”中,但并不是马上就释放堆中内存

3、局部变量

局部变量,由声明在某方法,或某代码段里(比如for循环),执行到它的时候在栈中开辟内存,当局部变量一但脱离作用域,内存立即释放

129、执行以下程序,最终输出可能是: *代表空格 答案:C

img

A、010 2123012 3434
B、01201 340124 2334
C、0012314 01223344**
D、12345 12345 12345
解析:每个线程输出0,1,2,3,4,’空格, 输出空格前必有线程输出了0-4,所以选C、

130、 答案:A C D G

class A {}
class B extends A {}
class C extends A {}

class D extends B {}

下面的哪4个语句是正确的?

A、The type Listis assignable to List.
B、The type Listis assignable to List.
C、The type Listis assignable to List<?>.
D、The type Listis assignable to List<?extends B>.
E、The type List<?extends A>is assignable to List.
F、The type Listis assignable to any List reference.
G、The type List<?extends B>is assignable to List<?extends A>.
解析:耐心看完,保证能懂这道题!

**1. 只看尖括号里边的!!明确点和范围两个概念**2. 如果尖括号里的是一个类,那么尖括号里的就是一个点,比如List,List,List**3. 如果尖括号里面带有问号,那么代表一个范围,<? extends A> 代表小于等于A的范围,<? super A>代表大于等于A的范围,<?>代表全部范围4. 尖括号里的所有点之间互相赋值都是错,除非是俩相同的点5. 尖括号小范围赋值给大范围,对,大范围赋值给小范围,错。如果某点包含在某个范围里,那么可以赋值,否则,不能赋值6. List<?>和List 是相等的,都代表最大范围----------------------------------------------------------------------------------7.补充:List既是点也是范围,当表示范围时,表示最大范围

public static void main(String[] args) {
        List<A> a;
        List list;
        list = a;   //A对,因为List就是List<?>,代表最大的范围,A只是其中的一个点,肯定被包含在内
        List<B> b;
        a = b;      //B错,点之间不能相互赋值
        List<?> qm;
        List<Object> o;
        qm = o;     //C对,List<?>代表最大的范围,List<Object>只是一个点,肯定被包含在内
        List<D> d;
        List<? extends B> downB;
        downB = d;  //D对,List<? extends B>代表小于等于B的范围,List<D>是一个点,在其中
        List<?extends A> downA;
        a = downA;  //E错,范围不能赋值给点
        a = o;      //F错,List<Object>只是一个点
        downA = downB;  //G对,小于等于A的范围包含小于等于B的范围,因为B本来就比A小,B时A的子类嘛
    }
131、下列代码的执行结果是() 答案:B
public class Test {
    public static int a = 1;
    public static void main(String[] args) {
        int a = 10;
        a++; Test.a++;
        Test t=new Test();
        System.out.println("a=" + a + " t.a=" + t.a);
    }
}

A、a=10 t.a=3
B、a=11 t.a=2
C、a=12 t.a=1
D、a=11 t.a=1
解析:静态成员变量未被final时,它的值可以被更改;所以t.a = 2;
2、值为1的a属于类变量也叫作成员变量,值为10的a是局部变量 首先a++时就近原则,用局部变量10来加,Text.a直接用类名调用成员变量的情况,只能是static 修饰的成员变量1来加,然后又实例化了对象,在输出中第一个a= 用就近原则输出11,第二个t.a 对象只能调用类变量输出2

132、关于Float,下列说法错误的是() 答案:C

A、Float是一个类
B、Float在java.lang包中
C、Float a=1.0是正确的赋值方法
D、Float a= new Float(1.0)是正确的赋值方法
解析:
Float是类,float不是类.
查看JDK源码就可以发现Byte,Character,Short,Integer,Long,Float,Double,Boolean都在java.lang包中.
Float正确复制方式是Float f=1.0f,若不加f会被识别成double型,double无法向float隐式转换.
Float a= new Float(1.0)是正确的赋值方法,但是在1.5及以上版本引入自动装箱拆箱后,会提示这是不必要的装箱的警告,通常直接使用Float f=1.0f.
2、Float a = new Float(1.0); 这个的东西能存在,是因为Float类中有形参是float和double的两个构造器。

Double d = new Double(1.0F);这个能成立的原因是float向上转型了。

Float a = 1.0;这个东西不成立是因为浮点型的默认类型是double,而double不会自动转成float,然后再装箱。

Double d = 1.0f;不成立的原因是因为Double类中的装箱方法,只有valueOf(String s)和valueOf(double d);装箱本身可不会自动向上转型啊。

133、语句:char foo=‘中’,是否正确?(假设源文件以GB2312编码存储,并且以javac – encoding GB2312命令编译) 答案:A

A、正确
B、错误
解析:Java语言中,中文字符所占的字节数取决于字符的编码方式,一般情况下,采用ISO8859-1编码方式时,一个中文字符与一个英文字符一样只占1个字节;采用GB2312或GBK编码方式时,一个中文字符占2个字节;而采用UTF-8编码方式时,一个中文字符会占3个字节。

在C++中

在C++中,char是基础数据类型,8位,1个字节。byte不是基础数据类型,一般是typedef unsigned char byte;这样子的,也就是说,byte其实是unsigned char类型,那么也是8位,1个字节。不同的是,char可以表示的范围是-128-127,而byte可以表示的范围是0-255。

在Java中

在java中,char和byte都是基础数据类型,其中的byte和C++中的char类型是一样的,8位,1个字节,-128-127。但是,char类型,是16位,2个字节, ‘\u0000’-’\uFFFF’。

为什么java里的char是2个字节?

因为java内部都是用unicode的,所以java其实是支持中文变量名的,比如string 世界 = “我的世界”;这样的语句是可以通过的。

综上,java中采用GB2312或GBK编码方式时,一个中文字符占2个字节,而char是2个字节,所以是对的

134、下面对静态数据成员的描述中,正确的是 答案:A

A、静态数据成员可以在类体内进行初始化
B、静态数据成员不可以被类的对象调用
C、静态数据成员不受private控制符的作用
D、静态数据成员可以直接用类名调用
解析:D选项需要考虑在A类通过类名访问B类的静态成员变量时,B类的静态成员变量必须public修饰
2、答案应该是A,D很明显是错误的,最典型的就是单例模式。

事实上Java的设计原则是属性私有,接口公开,方法看情况,静态数据成员也不例外,枚举类型才公开,但枚举的也不能叫成员,是实例。

针对小哥的疑问,我就直接上图了。因为篇幅的原因,所以代码阅读性一般,见谅。

img

135、下面是java语言的基本特性是?() 答案:A B C

A、封装
B、多态
C、继承
D、高效
解析:封装 继承 多态 还有个抽象

136、下列程序执行后结果为( ) 答案: A
class A {
    public int func1(int a, int b) {
        return a - b;
    }
}
class B extends A {
    public int func1(int a, int b) {
        return a + b;
    }
}
public class ChildClass {
    public static void main(String[] args) {
    A a = new B();
    B b = new B();
    System.out.println("Result=" + a.func1(100, 50));
    System.out.println("Result=" + b.func1(100, 50));
    }
}

A、

Result=150
Result=150

B、

Result=100
Result=100

C、

Result=100
Result=150

D、

Result=150
Result=100

解析:

其实很简单,涉及转型的题目,分为向上或者向下转型。

关键的来了,不论向上或者向下转型,都是一句话,“编译看左边,运行看右边”。也就是编译时候,会看左边引用类型是否能正确编译通过,运行的时候是调用右边的对象的方法。

就本题来说,编译时候会发现左边满足条件所以编译通过,运行时候又会调用右边也就是 class B 的方法,所以答案都是150。
2、此题考查的是多态。

对于多态,可以总结它为:

一、使用父类类型的引用指向子类的对象;

二、该引用只能调用父类中定义的方法和变量;

三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)

四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。

多态的3个必要条件:

​ 1.继承 2.重写 3.父类引用指向子类对象。

向上转型: Person p = new Man() ; //向上转型不需要强制类型转化

向下转型: Man man = (Man)new Person() ; //必须强制类型转化

137、用户不能调用构造方法,只能通过new关键字自动调用。() 答案: B

A、正确
B、错误
解析:在类内部可以用户可以使用关键字this.构造方法名()调用(参数决定调用的是本类对应的构造方法)
在子类中用户可以通过关键字super.父类构造方法名()调用(参数决定调用的是父类对应的构造方法。)
反射机制对于任意一个类,都能够知道这个类的所有属性和方法,包括类的构造方法。
2、1. 在类的其他构造方法中可以用this()的方式调用其他构造方法;

  1. 在类的子类中则可以通过super调用父类中指定的构造方法;
  2. 在反射中可以使用newInstance()的方式调用。
138、对于Java中异常的描述正确的是( ) 答案: D

A、用throws定义了方法可能抛出的异常,那么调用此方法时一定会抛出此异常。
B、如果try块中没有抛出异常,finally块中的语句将不会被执行。
C、抛出异常意味着程序发生运行时错误,需要调试修改
D、Java中的非检测(unchecked)异常可能来自RuntimeException类或其子类。
解析:A错 在调用此方法的时候 也可以再次申明以将异常交由更高一级处理。
B错 finally块中的语句一定会被执行。除非catch块中有System.exit(0)
C错 抛出异常不一定是运行时异常,也有可能是编译时异常。
D对 运行时异常的特点是Java编译器不会检查它。
2、Exception(异常)
是程序本身可以处理的异常。主要包含RuntimeException等运行时异常和IOException,SQLException等非运行时异常。
运行时异常 包括:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常(编译异常) 包括:RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常

139、()运算符把其操作数中所有值为0和所有值为1的位分别在结果的相应中设置1和0 答案:D

A、&
B、|
C、!
D、~
解析:&与操作;

|或操作;

!非操作;

~取反操作;
2、~是位运算符,意义是 按位非(NOT)
按位非也叫做补,一元运算符NOT“~”是对其运算数的每一位取反。

  • 仅用于整数值
  • 反转位,即0位变为1位,1变成0
  • 在所有情况下〜x等于(-x)- 1

例如

  ~ 0111 (7) = 1000 (8)
140、下面有关Java的说法正确的是( ) 答案:A C D F

A、一个类可以实现多个接口
B、抽象类必须有抽象方法
C、protected成员在子类可见性可以修改
D、通过super可以调用父类构造函数
E、final的成员方法实现中只能读取类的成员变量
F、String是不可修改的,且java运行环境中对string对象有一个对象池保存

解析:解释一下c选项,意思是父类中的protected方法子类在重写的时候访问权限可以修改,其实就是重写的要素之一,换了个说法而已
2、解释一下后两个,final 的成员方法除了能读取类的成员变量,还能读取类变量。(之前混淆了,给大家带来混乱,抱歉)

img

String 不可以修改,StringBuffer 和 StringBuilder 可以修改,String 只能改变指引,如果字符串常量池中没有正需要的串,就创建一 个新的字符串,然后让 String 对象指向它。

141、在委托事件模型中,源生成事件并把它发送给一个或多个监听器,每个监听器必须向事件源注册。 答案:A

A、T
B、F
解析:建议牛客取消关于图形化界面的题

142、一个类可以有多个不同名的构造函数 (不考虑内部类的情况)。( ) 答案:B

A、正确
B、错误
解析:只有与类名相同的方法可以叫构造函数
2、有歧义:此题本意是想说构造方法的名字与类名相同,而方法的签名是由方法的名字加参数的构成的
所以如果说是方法的签名不同也是可以说的通

143、abstract和final可以同时作为一个类的修饰符。( ) 答案:B

A、正确
B、错误
解析:abstract修饰一个类,这个类肯定可以被继承,但是final类是不能继承的,所以有矛盾,肯定不能同时用
2、Abstract表示抽象类,抽象类本身不可实例化,必须有子类去继承,且子类中实现抽象父类中所有的抽象方法,子类才可实例化。

final修饰的类,不可继承。

这个修饰符功能相克的。

144、下面代码将输出什么内容:() 答案:
public class SystemUtil{
    public static boolean isAdmin(String userId){
        return userId.toLowerCase()=="admin";
    }
    public static void main(String[] args){
        System.out.println(isAdmin("Admin"));
    }
}

A、true
B、false
C、1
D、编译错误
解析:equals和==的区别 == [查看全部](javascript:void(0))

145、对于JVM内存配置参数: 答案:D

-Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio=3

,其最小内存值和Survivor区总大小分别是()

A、5120m,1024m
B、5120m,2048m
C、10240m,1024m
D、10240m,2048m
解析:-Xmx:最大堆大小

-Xms:初始堆大小

-Xmn:年轻代大小

-XXSurvivorRatio:年轻代中Eden区与Survivor区的大小比值

年轻代5120m, Eden:Survivor=3,Survivor区大小=1024m(Survivor区有两个,即将年轻代分为5份,每个Survivor区占一份),总大小为2048m。

-Xms初始堆大小即最小内存值为10240m

-Xmx10240m:代表最大堆
 -Xms10240m:代表最小堆
 -Xmn5120m:代表新生代
 -XXSurvivorRatio=3:代表Eden:Survivor = 3    根据Generation-Collection算法(目前大部分JVM采用的算法),一般根据对象的生存周期将堆内存分为若干不同的区域,一般情况将新生代分为Eden ,两块Survivor;    计算Survivor大小, Eden:Survivor = 3,总大小为5120,3x+x+x=5120  x=1024
新生代大部分要回收,采用Copying算法,快!
老年代 大部分不需要回收,采用Mark-Compact算法
146、以下关于Integer与int的区别错误的是 答案:D

A、int是java提供的8种原始数据类型之一
B、Integer是java为int提供的封装类
C、int的默认值为0
D、Integer的默认值为1
解析:int 是八大基本数据类型之一(byte,char,short,int,long,float,double,boolean)
Integer 是 int 包装类;
int是基本数据类型,默认值为0,
Integer 是类,默认值为null;
Integer 表示的是对象,用一个引用指向这个对象,
int是基本数据类型,直接存储数值。

147、问这个程序的输出结果。 答案:D
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();
    }
}

A、Base SonB
B、Son SonB
C、Base Son SonB
D、编译不通过
解析:

Base base = new Son();

这句new 了一个派生类,赋值给基类,所以下面的操作编译器认为base对象就是Base类型的

Base类中不存在methodB()方法,所以编译不通过

148、关于OutOfMemoryError,下面说法正确的是()? 答案: A B C

A、java.lang.OutOfMemoryError: PermGen space 增加-XX:MaxPermSize这个参数的值的话,这个问题通常会得到解决。
B、java.lang.OutOfMemoryError: Requested array size exceeds VM limit当你正准备创建一个超过虚拟机允许的大小的数组时,这条错误将会出现
C、java.lang.OutOfMemoryError: Java heap space 一般情况下解决这个问题最快的方法就是通过-Xmx参数来增加堆的大小
D、java.lang.OutOfMemoryError: nativeGetNewTLA这个异常只有在jRockit虚拟机时才会碰到
解析:关于此题,《深入理解java虚拟机》有关于OOM(OutOfMemory)问题的解释

A:属于运行时常量池导致的溢出,设置-XX:MaxPermSize可以解决这个问题,

B:属于堆空间不足导致的错误,问题比较少见,解决方式和C相同,

C:属于java堆内存问题,一般的手段是通过内存映像分析工具,对Dump出来的堆转储存快照进行分析,重点是确认内存中的对象是否是有必要的,也就是要判断是出现了内存泄漏,还是出现了内存溢出,如果是内存列楼,通过工具检查泄露对象打GC Roots的引用链信息,可以准确的确定出泄露代码的位置,不存在泄露,就应该检查虚拟机的堆参数,如果可以继续调大,可以设置-Xmx解决问题

D:java.lang.OutOfMemoryError: nativeGetNewTLA指当虚拟机不能分配新的线程本地空间(Thread Local Area)的时候错误信息,此错误是线程申请一个新的TLA时产生的,这个异常一般只会发生在jRockit虚拟机,只有过于绝对。

149、以下关于JAVA语言异常处理描述正确的有? 答案:C D

A、throw关键字可以在方法上声明该方法要抛出的异常。
B、throws用于抛出异常对象。
C、try是用于检测被包住的语句块是否出现异常,如果有异常,则捕获异常,并执行catch语句。
D、finally语句块是不管有没有出现异常都要执行的内容。

E、在try块中不可以抛出异常

解析:Java语言中的异常处理包括声明异常、抛出异常、捕获异常和处理异常四个环节。

throw用于抛出异常。

throws关键字可以在方法上声明该方法要抛出的异常,然后在方法内部通过throw抛出异常对象。

try是用于检测被包住的语句块是否出现异常,如果有异常,则抛出异常,并执行catch语句。

cacth用于捕获从try中抛出的异常并作出处理。

finally语句块是不管有没有出现异常都要执行的内容。

150、Gadget has-a Sprocket and Gadget has-a Spring and Gadget is-a Widget and Widget has-a

Sprocket 以下哪两段代码可以表示这个关系? (选择两项) ( ) 答案:A C

A、

class Widget { Sprocket s; }
class Gadget extends Widget { Spring s; }

B、

class Widget { }
class Gadget extends Widget { Spring s1; Sprocket s2; }

C、

class Widget { Sprocket s1; Spring s2; }
class Gadget extends Widget { }

D、

class Gadget { Spring s; }
class Widget extends Gadget{ Sprocket s; }

解析:
is-a 表示继承:Gadget is-a Widget就表示Gadget 继承 Widget;

has-a表示从属:Gadget has-a Sprocket就表示Gadget中有Sprocket的引用,Sprocket是Gadget的组成部分;

like-a表示组合:如果A like-a B,那么B就是A的接口
2、从题目中可以得出以下几个结论:

  1. Gadget中有对Sprocket的引用。
  2. Gadget中有对Spring的引用。
  3. Gadget继承了Widget。
  4. Widget中有对Sprocket的引用。
  • A

    class Widget { Sprocket s; }
    class Gadget extends Widget { Spring s; }
    

    完全符合要求,这里的结论1虽然没有明确表明,但是因为结论3(Gadget继承了Widget)的存在,即父类中的非私有成员(Sprocket)子类都默认拥有。故结论都成立。

  • B

    class Widget { }
    class Gadget extends Widget { Spring s1; Sprocket s2; }
    

    结论123成立,但是没有表明结论4。

  • C

    class Widget { Sprocket s1; Spring s2; }
    class Gadget extends Widget { }
    

    完全符合要求,这里的结论12虽然没有明确表明,但是因为结论3(Gadget继承了Widget)的存在,即父类中的非私有成员(Sprocket和Spring

    )子类都默认拥有。故结论都成立。

  • D

    class Gadget { Spring s; }
    class Widget extends Gadget{ Sprocket s; }
    

    结论24成立,但是结论13没有表明。这里只是表明了Widget继承了Gadget,并且Widget具有对Spring的引用。

151、关于下面代码 int[] x=new int[25]; 描述正确的是() 答案:C

A、x[25]存放了数据“\0”。
B、x[24] 存放了数据“\0”。
C、若访问x[25],程序将抛出异常。
D、x[1]访问此数组的第一个元素。
解析:A:不存在x[25] 索引从0开始到length-1
B:x[24] 存的是默认值0(java中没有’\0’这一说)
C:超出内存 正确
D:第二元素

152、JDK8之前版本,HashMap的数据结构是怎样的? 答案:C

A、数组
B、链表
C、数组+链表/红黑树
D、二叉树
解析:JDK8及其以后版本,HashMap的数据结构是数组+链表+红黑树

153、假如某个JAVA进程的JVM参数配置如下:

-Xms1G -Xmx2G -Xmn500M -XX:MaxPermSize=64M -XX:+UseConcMarkSweepGC -XX:SurvivorRatio=3,
请问eden区最终分配的大小是多少? 答案:C

A、64M
B、500M
C、300M
D、100M
解析:Xms 起始内存

Xmx 最大内存

Xmn 新生代内存

Xss 栈大小。 就是创建线程后,分配给每一个线程的内存大小

-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4

-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5

-XX:MaxPermSize=n:设置持久代大小

收集器设置
-XX:+UseSerialGC:设置串行收集器
-XX:+UseParallelGC:设置并行收集器
-XX:+UseParalledlOldGC:设置并行年老代收集器
-XX:+UseConcMarkSweepGC:设置并发收集器
垃圾回收统计信息
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
并行收集器设置
-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
并发收集器设置
-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。
-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

154、下列关于容器集合类的说法正确的是? 答案: C

A、LinkedList继承自List
B、AbstractSet继承自Set
C、HashSet继承自AbstractSet
D、WeakMap继承自HashMap
解析:
a选项linkedlist类是实现了List接口,而不是继承

b选项AbstractSet类实现Set接口

c选项HashSet继承 AbstractSet类,同时也实现set

d选项WeakMap是js里面的玩意儿吧,,不太懂

155、下列关于JAVA多线程的叙述正确的是() 答案:B C

A、调用start()方法和run()都可以启动一个线程
B、CyclicBarrier和CountDownLatch都可以让一组线程等待其他线程
C、Callable类的call()方法可以返回值和抛出异常
D、新建的线程调用start()方法就能立即进行运行状态
解析:A,start是开启线程,run是线程的执行体,run是线程执行的入口。

**B,**CyclicBarrier和CountDownLatch都可以让一组线程等待其他线程。前者是让一组线程相互等待到某一个状态再执行。后者是一个线程等待其他线程结束再执行。

C,Callable中的call比Runnable中的run厉害就厉害在有返回值和可以抛出异常。同时这个返回值和线程池一起用的时候可以返回一个异步对象Future。

D,start是把线程从new变成了runnable

156、下列程序段执行后t3的结果是()。 答案: A
int t1 = 2, t2 = 3, t3;
t3 = t1 < t2 ? t1 : (t2 + t1);

A、2
B、4
C、5
D、6
解析:if(t1<t2)
t3=t1;;
else
t3=t2+t1;

157、以下对选择语句描述错误的是() 答案:A

A、根据某一条件重复执行一部分代码直到满足终止条件为止
B、可以根据条件控制程序流程,改变程序执行的顺序
C、选择语句可以嵌套使用
D、当条件满足时就会执行相应的语句
解析:流程控制语句分类:
顺序结构
选择结构:if语句、switch语句
循环结构:while语句、for语句
2、A答案说的是循环语句

java的4类流程控制语句

  1. 循环语句:while,for,do while
  2. 选择语句(分支语句):if,switch
  3. 跳转语句:break,continue,break,label
  4. 异常处理语句:try catch finally,throw
158、Which lines of the following will produce an error? 答案:A
byte a1 = 2, a2 = 4, a3;
short s = 16;
a2 = s;
a3 = a1 * a2;

A、Line 3 and Line 4
B、Line 1 only
C、Line 3 only
D、Line 4 only
解析:short类型转为byte类型出错

a1*a2结果为int类型,转为byte类型出错

159、下面描述属于java虚拟机功能的是? 答案:A B C D

A、通过 ClassLoader 寻找和装载 class 文件
B、解释字节码成为指令并执行,提供 class 文件的运行环境
C、进行运行期间垃圾回收
D、提供与硬件交互的平台
解析:A,C不用解释,B中JVM将字节码转换成不同平台(OS)下可执行的机器码指令。D中说的与硬件交互是JVM机器指令与硬件的交互。

160、下列哪些操作会使线程释放锁资源? 答案:B C

A、sleep()
B、wait()
C、join()
D、yield()
解析:join()底层就是调用wait()方法的,wait()释放锁资源,故join也释放锁资源

img

2、1.sleep会使当前线程睡眠指定时间,不释放锁

2.yield会使当前线程重回到可执行状态,等待cpu的调度,不释放锁

3.wait会使当前线程回到线程池中等待,释放锁,当被其他线程使用notify,notifyAll唤醒时进入可执行状态

4.当前线程调用 某线程.join()时会使当前线程等待某线程执行完毕再结束,底层调用了wait,释放锁
2、1.sleep()方法

在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。

sleep()使当前线程进入阻塞状态,在指定时间内不会执行。

2.wait()方法

在其他线程调用对象的notify或notifyAll方法前,导致当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。

当前线程必须拥有当前对象锁。如果当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常。

唤醒当前对象锁的等待线程使用notify或notifyAll方法,也必须拥有相同的对象锁,否则也会抛出IllegalMonitorStateException异常。

waite()和notify()必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronized block中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。

3.yield方法

暂停当前正在执行的线程对象。

yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

yield()只能使同优先级或更高优先级的线程有执行的机会。

4.join方法

等待该线程终止。

等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。

161、下列叙述错误的是( ) 答案: D

A、在接口中定义的方法除了default和static关键字修饰的方法拥有方法体,其他方法都应是没有方法体的抽象方法(JDK1.8以后)
B、一个java类只能有一个父类,但可以实现多个接口
C、在类声明中,用implements关键字声明该类实现的接口
D、定义接口时使用implements关键字。
解析
A、JDK8开始,接口中可以定义有方法体的方法,方法必须被default和static修饰。除此之外,其他方法都是抽象方法。

B、Java的语法是单继承,但是继承可以传递。其实B更准确一点是只能有一个直接父类。

C、继承用extends,实现用implements。先继承后实现。

D、类是class,接口是interface。

162、如果定义一种表达式结构:(+ 6 3)的值为9,(- 6 3)的值为3,(* 6 3)的值为18,(/ 6 3)的值为2;那么对于表达式(* (- 16 (* 3 2 2 )) (+ 5 (/ 6 (- 5 3))))输出的结果为____。 答案:D

A、44
B、40
C、40
D、32
解析:(* (- 16 (* 3 2 2 )) (+ 5 (/ 6 (- 5 3))))

(* (- 16 (* 3 2 2 )) (+ 5 (/ 6 2)))

(* (- 16 (* 3 2 2 )) (+ 5 3))

(* (- 16 (* 3 2 2 )) 8)

(* (- 16 12) 8)

(* 4 8)

32

163、关键字super的作用是? 答案:D

A、用来访问父类被隐藏的非私有成员变量
B、用来调用父类中被重写的方法
C、用来调用父类的构造函数
D、以上都是
解析:super代表父类对应的对象,所以用super访问在子类中无法直接使用的父类成员和方法
2、 1:特殊变量super,提供了对父类的访问。
2:可以使用super访问父类被子类隐藏的变量或覆盖的方法。
3:每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
4:构造是不能被继承的。

164、How should servlet developers handle the HttpServlet’s service() methond when extending HttpServlet? 答案: D

A、They should override the service()method in most cases;
B、They should call the service()method from doGet()or doPost();
C、They should call the service()method from the init()method;
D、They should override at least one doXXX()method(such as doPost())
解析:题目的意思是开发者在开发servlet继承HttpServlet时如何处理父类的service方法,一般我们都是不对service方法进行重载(没有特殊需求的话),而只是重载doGet()之类的doXxx()方法,减少了开发工作量。但如果重载了service方法,doXXX()方法也是要重载的。即不论是否重载service方法,doXXX()方法都是需要重载的。D说至少需要重载doXXX()方法是对的。

165、下面有关maven和ant的描述,描述错误的是? 答案:C

A、Ant 没有正式的约定如一个一般项目的目录结构,你必须明确的告诉 Ant 哪里去找源代码
B、Maven 拥有约定,因为你遵循了约定,它已经知道你的源代码在哪里
C、maven和ant都有“生命周期”的概念,当你输入一个命令后,maven或者ant会执行一系列的有序的步骤,直到到达你指定的生命周期
D、Ant构建文件默认命名为build.xml,Maven默认构建文件为pom.xml
解析:Ant和Maven都是基于Java的构建(build)工具。理论上来说,有些类似于(Unix)C中的make ,但没有make的缺陷。Ant是软件构建工具,Maven的定位是软件项目管理和理解工具。
Ant特点 ›
没有一个约定的目录结构 ›必须明确让ant做什么,什么时候做,然后编译,打包 ›没有生命周期,必须定义目标及其实现的任务序列 ›没有集成依赖管理
Maven特点
›拥有约定,知道你的代码在哪里,放到哪里去 ›拥有一个生命周期,例如执行 mvn install 就可以自动执行编译,测试,打包等构建过程 ›只需要定义一个pom.xml,然后把源码放到默认的目录,Maven帮你处理其他事情 ›拥有依赖管理,仓库管理

166、Continue语句跳出整个循环 答案:B

A、正确
B、错误
解析:1)continue是跳出本次循环,

比如

(for i = 0; i < 5; i++){
    if(i == 2){
        continue;
    }
    System.out.println("i = " + i);
}
//则结果应该是:
//i = 0
//i = 1
//i = 3
//i = 4

即当遇到continue时,本次循环结束,直接开始下一次循环;

2)break是跳出本循环体

比如

(for i = 0; i < 4; i++){
(for j = 0; j < 4; j++){
    if(j == 2){
        break;
    }
    System.out.println("i = " + i + ", j = " + j);
}
//则结果应该是:
//i = 0, j = 0
//i = 0, j = 1
//i = 1, j = 0
//i = 1, j = 1
//i = 2, j = 0
//i = 2, j = 1
//i = 3, j = 0
//i = 3, j = 1

即当遇到break时,本循环体结束。

这些就是区别。

167、以下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,因为已经存在一个key为name的项,所以会用新的value替换旧的vaue,因此,两条put之后,HashMap中只有一个key/value键值对。那就是(name,jack)。所以,size为1.

168、在类Tester中定义方法如下,

public double max(int x, int y) { // 省略 }

则在该类中定义如下哪个方法头是对上述方法的重载(Overload)? 答案:B

A、public int max(int a, int b) {}
B、public int max(double a, double b) {}
C、public double max(int x, int y) {}
D、private double max(int a, int b) {}
解析:重载就是一句话:同名不同参,返回值无关。

覆盖/重写:同名同参
2、Java 重载的规则:

1、必须具有不同的参数列表;

2、可以有不同的返回类型,只要参数列表不同就可以;

3、可以有不同的访问修饰符;

4、可以抛出不同的异常;

5、方法能够在一个类中或者在一个子类中被重载。

方法的重写:

1、在子类中可以根据需要对从基类中继承来的方法进行重写。

2、重写的方法和被重写的方法必须具有相同方法名称、参数列表和返回类型。

3、重写方法不能使用比被重写的方法更严格的访问权限。

169、根据下面的程序代码,哪些选项的值返回true? 答案:C
public class Square {  
    long width;  
    public Square(long l) {   
        width = l;  
    }  
    public static void main(String arg[]) {   
        Square a, b, c;  
        a = new Square(42L);   
        b = new Square(42L);   
        c = b;   
        long s = 42L;  
    } 
}

A、a == b
B、s == a
C、b == c
D、a.equals(s)
解析:C

a = new Square(42L);   
 b = new Square(42L);   

这里new了两个对象,所以a,b不是同一个引用a!=b

s的类型跟a,b不同类型,所以s!=a,s!=b

 c = b;

这里b,c是同一个对象的引用,所以b==c是true

170、下面有关servlet service描述错误的是? 答案:B

A、不管是post还是get方法提交过来的连接,都会在service中处理
B、doGet/doPost 则是在 javax.servlet.GenericServlet 中实现的
C、service()是在javax.servlet.Servlet接口中定义的
D、service判断请求类型,决定是调用doGet还是doPost方法
解析:doGet/doPost 则是在 javax.servlet.http.HttpServlet 中实现的

171、局部变量能否和成员变量重名? 答案:A

A、可以,局部变量可以与成员变量重名,这时可用“this”来指向成员变量
B、可以,这时可用“local”关键字来指向局部变量
C、不能,局部变量不能与成员变量重名
D、不能,在一个类中不能有重名变量,不管是成员变量还是函数中的局部变量
解析: 局部变量可以和成员变量重名,不加“this”修饰时,优先使用最近的变量。

img

172、下面的程序将来打印什么?() 答案:A
public class TestIncr {
    public static void main(String args[]) {
        int i = 0;
        i = i++ + i;
        System.out.println("I =" +i);
    }
}

A、I = 1
B、I = 2
C、I = 3
D、编译出错
解析:我相信很多人会不懂为什么是A

首先,在 i = i++ + i 中,先执行的是 i++ ,此时式子可为 i = 0 + i

然后再进行后一步 +i ,因为前面执行了 i++ ,所以这个 i 的值已经 +1 了

那么最后这个式子就是 i = 0 + 1 ,话不多说,直接上代码看吧

img

173、Java创建对象的说法正确的有() 答案:A B C D

A、用new语句创建对象,是最常见的创建对象的方法。
B、运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
C、调用对象的clone()方法。
D、运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
解析:Java有5种方式来创建对象: 1、使用 new 关键字(最常用): ObjectName obj = new ObjectName(); 2、使用反射的Class类的newInstance()方法: ObjectName obj = ObjectName.class.newInstance(); 3、使用反射的Constructor类的newInstance()方法: ObjectName obj = ObjectName.class.getConstructor.newInstance(); 4、使用对象克隆clone()方法: ObjectName obj = obj.clone(); 5、使用反序列化(ObjectInputStream)的readObject()方法: try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME))) { ObjectName obj = ois.readObject(); }
2、Java创建对象的5种方式:

  • 1.new
  • 2.对象克隆clone()方法
  • 3.反射Constructor类的newInstance()方法
  • 4.反射的Class类的newInstance()方法
  • 5.反序列化的readObject()方法
174、以下 json 格式数据,错误的是 答案:A C

A、{company:4399}
B、{“company”:{“name”:[4399,4399,4399]}}
C、{[4399,4399,4399]}
D、{“company”:[4399,4399,4399]}

解析:A:错误 {company:4399} 首先,其为json对象。但json对象要求属性必须加双引号。

B:正确

C:错误 {[4399,4399,4399]} 。使用 {} 则为json对象。json对象必须由一组有序的键值对组成。

D:正确。

答案:AC.

另参考(摘自<<Javascript 高级程序设计(第三版)>>):

JSON语法可以表示以下三种类型的值:

1.简单值:使用与JavaScript 相同的语法,可以在JSON中表示字符串,数值,布尔值和null。

2.对象:对象作为一种复杂数据类型,表示的是一组有序的键值对。而每组键值对中的值可以是简单值,也可以是复杂数据类型的值。

3.数组:数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中的值。数组的值也可以是任意类型–简单值,对象或数组。

175、Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持,下面关于Java反射的描述,错误的:( ) 答案:A D F

A、Java反射主要涉及的类如Class, Method, Filed,等,他们都在java.lang.reflet包下
B、通过反射可以动态的实现一个接口,形成一个新的类,并可以用这个类创建对象,调用对象方法
C、通过反射,可以突破Java语言提供的对象成员、类成员的保护机制,访问一般方式不能访问的成员
D、Java反射机制提供了字节码修改的技术,可以动态的修剪一个类
E、Java的反射机制会给内存带来额外的开销。例如对永生堆的要求比不通过反射要求的更多
F、Java反射机制一般会带来效率问题,效率问题主要发生在查找类的方法和字段对象,因此通过缓存需要反射类的字段和方法就能达到与之间调用类的方法和访问类的字段一样的效率

解析:A选项Class类位于lang包下面,D选项反射的本质就是从字节码中查找,动态获取类的整容结构,包括属性,构造器,动态调用对象的方法,而不是修剪类,F选项我觉得应该是,使用了反射的效率都会降低,就算加了缓存
2、A Class类在java.lang包

B 动态代理技术可以动态创建一个代理对象,反射不行

C 反射访问私有成员时,Field调用setAccessible可解除访问符限制

D CGLIB实现了字节码修改,反射不行

E 反射会动态创建额外的对象,比如每个成员方法只有一个Method对象作为root,他不胡直接暴露给用户。调用时会返回一个Method的包装类

F 反射带来的效率问题主要是动态解析类,JVM没法对反射代码优化。

176、有这样一段程序: 请问运行主要的程序会打印出的是什么() 答案:C
public class Test{
    public static void main(String [] args){
        List list=new ArrayList();
        list.add("a");
        list.add("b");
        list.add("a");
        Set set=new HashSet();
        set.add("a");
        set.add("b");
        set.add("a");
        System.out.println(list.size()+","+set.size());
    }
}

A、2,2
B、2,3
C、3,2
D、3,3
解析:1、List和Set的区别,set中不能放重复的
2、Set中重复的定义,未定义自己的equels方法的话,调用默认的,也就是直接==

由于此题采用的添加的是字符串,而字符串已经实现了equels方法,所以不会产生2中提到的问题,但是自己定义的类就要注意了。

综上所述,题目应该更改为只是为了检测1中的概念

publicclassTest{

public staticvoidmain(String [] args){

​ List list=newArrayList();

​ List.add(“a”);

​ List.add(“b”);
​ List.add(“a”);

​ Set set=newHashSet();

​ set.add(“a”);

​ set.add(“b”);

​ set.add(“a”);

​ System.out.println(list.size()+","+set.size());

}

};

177、执行以下程序后的输出结果是() 答案:D
public class Test {
    public static void main(String[] args) {
        StringBuffer a = new StringBuffer("A"); 
        StringBuffer b = new StringBuffer("B"); 
        operator(a, b); 
        System.out.println(a + "," + b); 
    } 
    public static void operator(StringBuffer x, StringBuffer y) { 
        x.append(y); y = x; 
    }
}

A、A,A
B、A,B
C、B,B
D、AB,B
解析:StringBuffer a = newStringBuffer(“A”);

StringBuffer b = newStringBuffer(“B”);

此时内存中的状态如下图所示:

img

publicstaticvoidoperator(StringBuffer x, StringBuffer y) {

x.append(y); y = x;

}

进入如下方法后,内存中的状态为:

img

x.append(y);

这条语句执行后,内存的状态为:

img

y = x;

这条语句执行后,内存的状态为:

img

当operator方法执行完毕后内存中的状态为:因为方法执行完毕,局部变量消除。

img

有内存中的状态,可以知道最后的结果。

178、以下哪项陈述是正确的? 答案:E

A、垃圾回收线程的优先级很高,以保证不再使用的内存将被及时回收
B、垃圾收集允许程序开发者明确指定释放哪一个对象
C、垃圾回收机制保证了JAVA程序不会出现内存溢出
D、进入”Dead”状态的线程将被垃圾回收器回收
E、以上都不对
解析:E

A: 垃圾回收在jvm中优先级相当相当低。
B:垃圾收集器(GC)程序开发者只能推荐JVM进行回收,但何时回收,回收哪些,程序员不能控制。
C:垃圾回收机制只是回收不再使用的JVM内存,如果程序有严重BUG,照样内存溢出。
D:进入DEAD的线程,它还可以恢复,GC不会回收

179、下列描述错误的是? 答案:B D

A、类只能继承一个父类,但是可以实现多个接口
B、抽象类自身可以定义成员而接口不可以
C、抽象类和接口都不能被实例化(忽略匿名内部类)
D、一个类可以有多个父类和多个基接口
解析:**A、java为单继承,多实现。可以实现多个接口。
B、接口允许定义成员,但必须是常量。
C、*抽象类和接口类的无法实例化,任何编译器中直接使用new会报错。
D、A
,单继承,多实现。

180、下面有关java的引用类型,说法正确的有? 答案:A B C D

A、被GCroot强引用=Gcroot对象来说,只要有强引用的存在,它就会一直存在于内存中
B、如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
C、如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存
D、一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的空间
解析:发现这道题完全没头绪,就去查了一下,感觉说的比较清楚了。

四种引用类型

JDK1.2 之前,一个对象只有“已被引用”和"未被引用"两种状态,这将无法描述某些特殊情况下的对象,比如,当内存充足时需要保留,而内存紧张时才需要被抛弃的一类对象。

所以在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱。

一,强引用

Object obj = new Object(); //只要obj还指向Object对象,Object对象就不会被回收 obj = null; //手动置null

只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError,不会去回收。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了

二,软引用

软引用是用来描述一些非必需但仍有用的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。这种特性常常被用来实现缓存技术,比如网页缓存,图片缓存等。

在 JDK1.2 之后,用java.lang.ref.SoftReference类来表示软引用。

三,弱引用

弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。在 JDK1.2 之后,用 java.lang.ref.WeakReference 来表示弱引用。

四,虚引用

虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用。
2、1、强引用:一个对象赋给一个引用就是强引用,比如new一个对象,一个对象被赋值一个对象。

2、软引用:用SoftReference类实现,一般不会轻易回收,只有内存不够才会回收。

3、弱引用:用WeekReference类实现,一旦垃圾回收已启动,就会回收。

4、虚引用:不能单独存在,必须和引用队列联合使用。主要作用是跟踪对象被回收的状态。

181、下列类定义代码,当用来声明对象car,并用Car car=new Car();实例化后,可以通过car对象直接赋值的字段是() 答案:B

img

A、type,No
B、type,price
C、heavy,owner
D、type,owner,price
解析:这题目就不严谨,题目说:可以通过car对象给变量赋值,还考虑个锤子的控制符作用域。我认为public,protect,default都可以。除了prive因为不是在本类中。垃圾题目。
img

182、指出下列程序运行的结果() 答案:B
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、good and abc
B、good and gbc
C、test ok and abc
D、test ok and gbc
解析:**简单总结一下:直接赋值而不是使用new关键字给字符串初始化,在编译时就将String对象放进字符串常量池中;使用new关键字初始化字符串时,是在堆栈区存放变量名和内容;字符串的拼接操作在程序运行时,才在堆中创建对象。一般,可以认为使用"=="比较的是引用,equals比较的是内容。**对于上面的题,看完下面的几个例子,你就会有所感悟:String str = new String(“good”);是在编译时在堆栈中创建对象和分配内容,而在传参的时候,传递的是地址,把外面的str引用地址复制了一份给方法内的str而不是里面的内容。

看例子:;

例子A:
String str1 = “java”;
String str2 = “java”;
System.out.print(str1str2);
大部分人也许认为会输出false,因为**比较的是引用,equals比较的是内容**。可以在自己的机子上运行一 下,结果是true!原因很简单,String对象被放进常量池里了,再次出现“java”字符串的时候,JVM很兴奋地把str2的引用也指向了 “java”对象,它认为自己节省了内存开销。不难理解吧 呵呵
例子B:
String str1 = new String(“java”);
String str2 = new String(“java”);
System.out.print(str1
str2);
看过上例的都学聪明了,这次肯定会输出true!很不幸,JVM并没有这么做,结果是false。原因很简单,例子A中**那种直接赋值(而没有通过new关键字实例化的字符串变量)声明的方式确实是在 String常量池创建“java”对象,但是一旦看到new关键字,JVM会在堆中为String分配空间。**两者声明方式貌合神离,这也是我把“如何创 建字符串对象”放到后面来讲的原因。大家要沉住气,还有一个例子。
例子C:
String str1 = “java”; //直接赋值而不是使用new关键字给字符串初始化,在编译时就将String对象放进字符串常量池中
String str2 = “blog”; //直接赋值而不是使用new关键字给字符串初始化,在编译时就将String对象放进字符串常量池中
String s = str1+str2; //字符串的拼接操作在程序运行时,才在堆中创建对象,
System.out.print(s
"javablog");
再看这个例子,很多同志不敢妄言是true还是false了吧。爱玩脑筋急转弯的人会说是false吧……恭喜你,你会抢答了!把那个“吧”字去掉你就完 全正确。原因很简单,JVM确实会对型如String str1 = “java”; 的String对象放在字符串常量池里,但是它是在编译时刻那么做的,而String s = str1+str2; 是在运行时刻才能知道(我们当然一眼就看穿了,可是Java必须在运行时才知道的,人脑和电脑的结构不同),也就是说str1+str2是在堆里创建的, s引用当然不可能指向字符串常量池里的对象。没崩溃的人继续看例子D。
例子D:
String s1 = “java”;
String s2 = new String(“java”);
System.out.print(s1.intern()==s2.intern());
intern()是什么东东?反正结果是true。如果没用过这个方法,而且训练有素的程序员会去看JDK文档了。简单点说就是
用intern()方法就可以用“==”比较字符串的内容了。在我看到intern()方法到底有什么用之前,我认为它太多余了。其实我写的这一条也很多余,intern()方法 还存在诸多的问题,如效率、实现上的不统一……

例子E:
String str1 = “java”;
String str2 = new String(“java”);
System.out.print(str1.equals(str2));
无论在常量池还是堆中的对象,用equals()方法比较的就是内容,就这么简单!

183、执行下面的程序段,语句3的执行次数为() 答案:C
for (i = 0; i <= n-1; i++)   // (1)
    for (j = n; j > i; j--// (2)
        state;               // (3)

A、n(n+2)/2
B、(n-1)(n+2)/2
C、n(n+1)/2
D、(n-1)(n+2)
解析:假设代入法:

  • n=3,外层循环i的取值为0,1,2
  • 当i=0时,内部循环j的取值为3,2,1,所以state执行3次;当i=1时,内部循环j的取值3,2,所以state执行2次;当i=2时,内部循环j的取值为3,所以state执行1次。
  • 综上所述:3+2+1=6次。将n=3带入选项中的出C符合结果。
184、存根(Stub)与以下哪种技术有关 答案:B

A、交换
B、动态链接
C、动态加载
D、磁盘调度
解析:存根类是一个类,它实现了一个接口,它的作用是:如果一个接口有很多方法,如果要实现这个接口,就要实现所有的方法。但是一个类从业务来说,可能只需要其中一两个方法。如果直接去实现这个接口,除了实现所需的方法,还要实现其他所有的无关方法。而如果通过继承存根类就实现接口,就免去了这种麻烦。

RMI 采用stubs 和 skeletons 来进行远程对象(remote object)的通讯。stub 充当远程对象的客户端***,有着和远程对象相同的远程接口,远程对象的调用实际是通过调用该对象的客户端***对象stub来完成的。
每个远程对象都包含一个***对象stub,当运行在本地Java虚拟机上的程序调用运行在远程Java虚拟机上的对象方法时,它首先在本地创建该对象的***对象stub, 然后调用***对象上匹配的方法。每一个远程对象同时也包含一个skeleton对象,skeleton运行在远程对象所在的虚拟机上,接受来自stub对象的调用。这种方式符合等到程序要运行时将目标文件动态进行链接的思想

185、对Collection和Collections描述正确的是 答案: B D

A、Collection是java.util下的类,它包含有各种有关集合操作的静态方法
B、Collection是java.util下的接口,它是各种集合结构的父接口
C、Collections是java.util下的接口,它是各种集合结构的父接口
D、Collections是java.util下的类,它包含有各种有关集合操作的静态方法
解析:java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。

java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

186、关于Java语言的内存回收机制,下列选项中最正确的一项是 答案:C

A、Java程序要求用户必须手工创建一个线程来释放内存
B、Java程序允许用户使用指针来释放内存
C、内存回收线程负责释放无用内存
D、内存回收线程不能释放内存对象
解析:A,java的内存回收是自动的,Gc在后台运行,不需要用户手动操作

B,java中不允许使用指针

D,内存回收线程可以释放无用的对象内存

187、字符界面下接受用户从键盘输入,需要import的包是:( ) 答案:C

A、java.lang包
B、java.awt包
C、java.io包
D、java.applet包
解析:这个问题的前提是:字符界面下

前端用户输入、后台程序获取,都是字符流的传输,因此需要导入java.io包。

而java.util中的Scanner则是获取控制台的输入。

因此,答案选C

188、以下代码结果是什么? 答案:C
public class foo {
    public static void main(String sgf[]) {
 
        StringBuffer a=new StringBuffer("A");
 
        StringBuffer b=new StringBuffer("B");
 
        operate(a,b);
 
        System.out.println(a+"."+b);
    }
    static void operate(StringBuffer x,StringBuffer y) {
        x.append(y);
        y=x;
    }
}

A、代码可以编译运行,输出“AB.AB”。
B、代码可以编译运行,输出“A.A”。
C、代码可以编译运行,输出“AB.B”。
D、代码可以编译运行,输出“A.B”。
解析:这里简单地说,a,b,x,y就是四个指针。y本来指向的是b所指向的对象,但是一个“=”,y就指向了x所指向的目标即是a指向的对象,因此原来b所指向的目标并没有发生任何改变。与y不同的是,x进行的是对象操作,此时此对象在内存中是真正的本质上的改变。有点绕,但是手机打字,没发画图,不然其实很容易理解。
2、引用a指向对象A

引用b指向对象B

引用x指向对象A

引用y指向对象B

在operate方法中,引用x指向的对象A被连接了B,对象A也就被改变为AB

然后又把引用y指向了x所指向的对象地址,也就是此时引用a,x,y指向同一个对象AB

而引用b没有发生任何变化,依旧指向对象B。

189、下面哪几个语句正确的声明一个整型的二维数组() 答案:C D

A、int a[][]=new int[][]
B、int b[10][10]=new int[][]
C、int c[][]=new int[10][10]
D、int []d[]=new int[10][10]
解析:

img

\1. 定义一维数组时,必须显式指明数组的长度;

\2. 定义***数组时,其一维数组的长度必须首先指明,其他维数组长度可以稍后指定;

\3. 采用给定值初始化数组时,不必指明长度;

\4. “[]” 是数组运算符的意思,在声明一个数组时,数组运算符可以放在数据类型与变量之间,也可以放在变量之后。

190、关于volatile关键字,下列描述不正确的是? 答案:B D

A、用volatile修饰的变量,每次更新对其他线程都是立即可见的。
B、对volatile变量的操作是原子性的。
C、对volatile变量的操作不会造成阻塞。
D、不依赖其他锁机制,多线程环境下的计数器可用volatile实现。
解析:一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

2)禁止进行指令重排序。

volatile只提供了保证访问该变量时,每次都是从内存中读取最新值,并不会使用寄存器缓存该值——每次都会从内存中读取。

而对该变量的修改,volatile并不提供原子性的保证。

由于及时更新,很可能导致另一线程访问最新变量值,无法跳出循环的情况

多线程下计数器必须使用锁保护。

191、 答案:B

多重继承的概念在Java中实现是通过如下哪些?()

I. 扩展两个或多个类

II. 扩展一个类并实现一个或多个接口。

III. 实现两个或更多接口。

A、只有I &II
B、只有II & III
C、只有III
D、都是
解析:Java只支持单继承,实现多重继承三种方式:(1)直接实现多个接口 (2)扩展(extends)一个类然后实现一个或多个接口 (3)通过内部类去继承其他类

192、volatile关键字的说法错误的是 答案:A

A、能保证线程安全
B、volatile关键字用在多线程同步中,可保证读取的可见性
C、JVM保证从主内存加载到线程工作内存的值是最新的
D、volatile能禁止进行指令重排序
解析:出于运行速率的考虑,java编译器会把经常经常访问的变量放到缓存(严格讲应该是工作内存)中,读取变量则从缓存中读。但是在多线程编程中,内存中的值和缓存中的值可能会出现不一致。volatile用于限定变量只能从内存中读取,保证对所有线程而言,值都是一致的。但是volatile不能保证原子性,也就不能保证线程安全。
2、1.java的内存模型

java 内存模型规定了所有的变量都存储在主内存中,但是每个线程会有自己的工作内存,线程的工作内存保存了该线程中使用了的变量(从主内存中拷贝的),线程对变量的操作都必须在工作内存中进行,不同线程之间无法直接访问对方工作内存中的变量,线程间变量值从传递都要经过主内存完成

图片说明

2.什么是原子性

一个操作是不可中断的,要么全部执行成功要么全部执行失败,比如银行转账

3.什么是可见性

当多个线程访问同一变量时,一个线程修改了这个变量的值,其他线程就能够立即看到修改的值

4.什么是有序性

程序执行的顺序按照代码的先后顺序执行

int` `a = ``0``; ``//1``int` `b = ``2``; ``//2

像这2句代码1会比2先执行,但是jvm在正真执行时不一定是1在2之前,这里涉及一个概念叫做指令重排,处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。比如上面的代码语句1和语句2谁先执行对最终的程序结果并没有影响,那么就有可能在执行过程中,语句2先执行而语句1后执行。
在指令重排时会考虑指令之间的数据依赖性,比如2依赖了1的数值,那么处理器会保证1在2之前执行。
但是在多线程的情况下,指令重排就会有影响了。

5.volatile到底做了什么

  • 禁止了指令重排
  • 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量值,这个新值对其他线程是立即可见的
  • 不保证原子性(线程不安全)
193、在Java中,关于HashMap类的描述,以下正确的是 () 答案: A C D

A、HashMap使用键/值得形式保存数据
B、HashMap 能够保证其中元素的顺序
C、HashMap允许将null用作键
D、HashMap允许将null用作值
解析:

Map集合类keyvalue
HashMap允许为null允许为null
TreeMap不允许为null允许为null
ConcurrentMap不允许为null不允许为null
HashTable不允许为null不允许为null
194、String s=null;

下面哪个代码片段可能会抛出NullPointerException? 答案:A C

A、if((s!=null)&(s.length()>0))
B、if((s!=null)&&(s.length()>0))
C、if((s==null)|(s.length()0))
D、if((s
null)||(s.length()==0))
解析:s为null,因此只要调用了s.length()都会抛出空指针异常。因此这个题目就是考察if语句的后半部分会不会执行。
A,单个与操作的符号& 用在整数上是按位与,用在布尔型变量上跟&&功能类似,但是区别是无论前面是否为真,后面必定执行,因此抛出异常
B,与操作,前半部分判断为假,后面不再执行
C,这里跟 & 和&& 的区别类似,后面必定执行,因此抛出异常
D,或语句,前面为真,整个结果必定为真,后面不执行

195、下面有关servlet的层级结构和常用的类,说法正确的有? 答案:A B C D

A、GenericServlet类:抽象类,定义一个通用的、独立于底层协议的Servlet。
B、大多数Servlet通过从GenericServlet或HttpServlet类进行扩展来实现
C、ServletConfig接口定义了在Servlet初始化的过程中由Servlet容器传递给Servlet得配置信息对象
D、HttpServletRequest接口扩展ServletRequest接口,为HTTP Servlet提供HTTP请求信息
解析:img

196、下列外部类定义中,不正确的是:( ) 答案:C

A、class x { … }
B、class x extends y { … }
C、static class x implements y1,y2 { … }
D、public class x extends Applet { … }
解析:static修饰的为类成员,会随着类的加载而加载,比如静态代码块,静态成员,静态方法(这里只是加载,并没有调用)等等,可以想象一下,如果把一个Class文件中的外部类设为static,目的难道是让这个类随着应用的启动而加载吗?如果在这次使用过程中根本没有使用过这个类,那么是不是就会浪费内存。这样来说设计不合理,总而言之,设计不合理的地方,Java是不会让它存在的。
而为什么内部类可以使用static修饰呢,因为内部类算是类的成员了,如果没有使用静态来修饰,那么在创建内部类的时候就需要先有一个外部类的对象,如果我们一直在使用内部类,那么内存中就会一直存在外部类的引用,而我们有时候只需要使用内部类,不需要外部类,那么还是会浪费内存,甚至会造成内存溢出。使用static修饰内部类之后,内部类在创建对象时就不需要有外部类对象的引用了。
最终结论就是:static可以用来修饰内部类,但是不可以用来修饰外部类

197、下面论述正确的是()? 答案: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()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!
2、A:在hashmap中,key值是不可能重复的,由hashCode和equals方法共同判断key值是否相等。即使两个对象的hashCode相同相等,也不能说他们的key值相等。

B和D:如果x.equals(y)返回true,那么这两个对象的hashCode返回的整数结果必然相同。如果x.equals(y)返回false,则不一定;

反之,hashCode返回的值不相等,则equals方法返回值一定不相等。hashCode返回值相等,则不一定

C:hashCode的值是可以相同的

198、有以下程序片段,下列哪个选项不能插入到第一行 。( )。 答案:A
1.

2.public  class  A{

3.//do sth

4. }

A、public class MainClass{ }
B、package mine;
C、class ANotherClass{ }
D、import java.util.*;
解析:**Java一个源程序只能有一个public类存在,且类名与文件名相同。**Java程序是从main方法开始执行的,public为类加载器提供入口,然后找到public类中的main方法开始执行。如果存在多个public类,程序将不知道该从哪里执行。
注意,内部类可以是public的,因为内部类是作为外部类的成员存在的。

199、下面代码的输出结果是什么? 答案:D
public class ZeroTest {
    public static void main(String[] args) {
     try{
       int i = 100 / 0;
       System.out.print(i);
      }catch(Exception e){
       System.out.print(1);
       throw new RuntimeException();
      }finally{
       System.out.print(2);
      }
      System.out.print(3);
     }
 }

A、3
B、123
C、1
D、12
解析:1、inti = 100/ 0; 会出现异常,会抛出异常,System.out.print(i)不会执行,

2、catch捕捉异常,继续执行System.out.print(1);

3、当执行 thrownewRuntimeException(); 又会抛出异常,这时,除了会执行finally中的代码,其他地方的代码都不会执行

200、以下哪种方式实现的单例是线程安全的 答案: A B C D

A、枚举
B、静态内部类
C、双检锁模式
D、饿汉式
解析:高频面试题:单列模式的6种实现方式。

整理分享不易,点个赞鸭~

目录:
img

一、单例模式的定义

定义: 确保一个类只有一个实例,并提供该实例的全局访问点。

这样做的好处是:有些实例,全局只需要一个就够了,使用单例模式就可以避免一个全局使用的类,频繁的创建与销毁,耗费系统资源。

二、单例模式的设计要素
  • 一个私有构造函数 (确保只能单例类自己创建实例)
  • 一个私有静态变量 (确保只有一个实例)
  • 一个公有静态函数 (给使用者提供调用方法)

简单来说就是,单例类的构造方法不让其他人修改和使用;并且单例类自己只创建一个实例,这个实例,其他人也无法修改和直接使用;然后单例类提供一个调用方法,想用这个实例,只能调用。这样就确保了全局只创建了一次实例。

三、单例模式的6种实现及各实现的优缺点
(一)懒汉式(线程不安全)

实现:

public class Singleton {
     private static Singleton uniqueInstance;

     private Singleton() {

    }

    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

说明: 先不创建实例,当第一次被调用时,再创建实例,所以被称为懒汉式。

优点: 延迟了实例化,如果不需要使用该类,就不会被实例化,节约了系统资源。

缺点: 线程不安全,多线程环境下,如果多个线程同时进入了 if (uniqueInstance == null) ,若此时还未实例化,也就是uniqueInstance == null,那么就会有多个线程执行 uniqueInstance = new Singleton(); ,就会实例化多个实例;

(二)饿汉式(线程安全)

实现:

public class Singleton {

    private static Singleton uniqueInstance = new Singleton();

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        return uniqueInstance;
    }

}

说明: 先不管需不需要使用这个实例,直接先实例化好实例 (饿死鬼一样,所以称为饿汉式),然后当需要使用的时候,直接调方法就可以使用了。

优点: 提前实例化好了一个实例,避免了线程不安全问题的出现。

缺点: 直接实例化好了实例,不再延迟实例化;若系统没有使用这个实例,或者系统运行很久之后才需要使用这个实例,都会操作系统的资源浪费。

(三)懒汉式(线程安全)

实现:

public class Singleton {
    private static Singleton uniqueInstance;

    private static singleton() {
    }

    private static synchronized Singleton getUinqueInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }

}

说明: 实现和 线程不安全的懒汉式 几乎一样,唯一不同的点是,在get方法上 加了一把 锁。如此一来,多个线程访问,每次只有拿到锁的的线程能够进入该方法,避免了多线程不安全问题的出现。

优点: 延迟实例化,节约了资源,并且是线程安全的。

缺点: 虽然解决了线程安全问题,但是性能降低了。因为,即使实例已经实例化了,既后续不会再出现线程安全问题了,但是锁还在,每次还是只能拿到锁的线程进入该方***使线程阻塞,等待时间过长。

(四)双重检查锁实现(线程安全)

实现:

public class Singleton {

    private volatile static Singleton uniqueInstance;

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }  
}

说明: 双重检查数相当于是改进了 线程安全的懒汉式。线程安全的懒汉式 的缺点是性能降低了,造成的原因是因为即使实例已经实例化,依然每次都会有锁。而现在,我们将锁的位置变了,并且多加了一个检查。 也就是,先判断实例是否已经存在,若已经存在了,则不会执行判断方法内的有锁方法了。 而如果,还没有实例化的时候,多个线程进去了,也没有事,因为里面的方法有锁,只会让一个线程进入最内层方法并实例化实例。如此一来,最多最多,也就是第一次实例化的时候,会有线程阻塞的情况,后续便不会再有线程阻塞的问题。

为什么使用 volatile 关键字修饰了 uniqueInstance 实例变量 ?

uniqueInstance = new Singleton(); 这段代码执行时分为三步:

  1. 为 uniqueInstance 分配内存空间
  2. 初始化 uniqueInstance
  3. 将 uniqueInstance 指向分配的内存地址

正常的执行顺序当然是 1>2>3 ,但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1>3>2。
单线程环境时,指令重排并没有什么问题;多线程环境时,会导致有些线程可能会获取到还没初始化的实例。
例如:线程A 只执行了 1 和 3 ,此时线程B来调用 getUniqueInstance(),发现 uniqueInstance 不为空,便获取 uniqueInstance 实例,但是其实此时的 uniqueInstance 还没有初始化。

解决办法就是加一个 volatile 关键字修饰 uniqueInstance ,volatile 会禁止 JVM 的指令重排,就可以保证多线程环境下的安全运行。

优点: 延迟实例化,节约了资源;线程安全;并且相对于 线程安全的懒汉式,性能提高了。

缺点: volatile 关键字,对性能也有一些影响。

(五)静态内部类实现(线程安全)

实现:

public class Singleton {

    private Singleton() {
    }

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getUniqueInstance() {
        return SingletonHolder.INSTANCE;
    }

}

说明: 首先,当外部类 Singleton 被加载时,静态内部类 SingletonHolder 并没有被加载进内存。当调用 getUniqueInstance() 方法时,会运行 return SingletonHolder.INSTANCE; ,触发了 SingletonHolder.INSTANCE ,此时静态内部类 SingletonHolder 才会被加载进内存,并且初始化 INSTANCE 实例,而且 JVM 会确保 INSTANCE 只被实例化一次。

优点: 延迟实例化,节约了资源;且线程安全;性能也提高了。

(六)枚举类实现(线程安全)

实现:

public enum Singleton {

    INSTANCE;

    //添加自己需要的操作
    public void doSomeThing() {

    }

}

说明: 默认枚举实例的创建就是线程安全的,且在任何情况下都是单例。

优点: 写法简单,线程安全,天然防止反射和反序列化调用。

  • 防止反序列化
    **序列化:**把java对象转换为字节序列的过程;
    反序列化: 通过这些字节序列在内存中新建java对象的过程;
    说明: 反序列化 将一个单例实例对象写到磁盘再读回来,从而获得了一个新的实例。
    我们要防止反序列化,避免得到多个实例。
    枚举类天然防止反序列化。
    其他单例模式 可以通过 重写 readResolve() 方法,从而防止反序列化,使实例唯一重写 readResolve() :
private Object readResolve() throws ObjectStreamException{
        return singleton;
}
四、单例模式的应用场景

应用场景举例:

  • 网站计数器。
  • 应用程序的日志应用。
  • Web项目中的配置对象的读取。
  • 数据库连接池。
  • 多线程池。

使用场景总结:

  • 频繁实例化然后又销毁的对象,使用单例模式可以提高性能。

  • 经常使用的对象,但实例化时耗费时间或者资源多,如数据库连接池,使用单例模式,可以提高性能,降低资源损坏。

  • 使用线程池之类的控制资源时,使用单例模式,可以方便资源之间的通信。

    2、

    第一种:饿汉模式(线程安全)

    public class Single2 {
    
        private static Single2 instance = new Single2();
        
        private Single2(){
            System.out.println("Single2: " + System.nanoTime());
        }
        
        public static Single2 getInstance(){
            return instance;
        }
    }
    

    第二种:懒汉模式 (如果方法没有synchronized,则线程不安全)

    public class Single3 {
    
        private static Single3 instance = null;
        
        private Single3(){
            System.out.println("Single3: " + System.nanoTime());
        }
        
        public static synchronized Single3 getInstance(){
            if(instance == null){
                instance = new Single3();
            }
            return instance;
        }
    }
    

    第三种:懒汉模式改良版(线程安全,使用了double-check,即check-加锁-check,目的是为了减少同步的开销)

    public class Single4 {
    
        private volatile static Single4 instance = null;
        java
        private Single4(){
            System.out.println("Single4: " + System.nanoTime());
        }
        
        public static Single4 getInstance(){
            if(instance == null){
                synchronized (Single4.class) {
                    if(instance == null){
                        instance = new Single4();
                    }
                }
            }
            return instance;
        }
    }
    

    第四种:利用私有的内部工厂类(线程安全,内部类也可以换成内部接口,不过工厂类变量的作用于要改为public了。)

    public class Singleton {
        
        private Singleton(){
            System.out.println("Singleton: " + System.nanoTime());
        }
        
        public static Singleton getInstance(){
            return SingletonFactory.singletonInstance;
        }
        
        private static class SingletonFactory{
            private static Singleton singletonInstance = new Singleton();
        }
    }
    
201、以下说法错误的是() 答案: C

A、数组是一个对象
B、数组不是一种原生类
C、数组的大小可以任意改变
D、在Java中,数组存储在堆中连续内存空间里
解析: 在java中,数组是一个对象, 不是一种原生类,对象所以存放在堆中,又因为数组特性,是连续的,只有C不对

202、 在异常处理中,如释放资源,关闭数据库、关闭文件应由( )语句来完成。 答案:C

A、try子句
B、catch子句
C、finally子句
D、throw子句
解析:C。finally子句一般是用来清理这些资源的。try-finally语句是Microsoft对C和C++语言的扩展,它能使32位的目标程序在异常出现时,有效保证一些资源能够被及时清除,这些资源的清除任务可以包括例如内存的释放,文件的关闭,文件句柄的释放等等。

Q: 为何C++不提供“finally”结构?
A: 因为C++提供了另一种机制,完全可以取代finally,而且这种机制几乎总要比finally工作得更好:就是——“分配资源即初始化”。(见《The C++ Programming Language》14.4节)基本的想法是,用一个 局部对象来封装一个资源,这样一来局部对象的析构函数 就可以自动释放资源。这样,程序员就不会“忘记释放资源”了。 [译注:因为C++的对象“生命周期”机制替他记住了 😮) ]

3、try:可能发生异常的语句
catch:捕获,并处理异常(printStackTrace()用来跟踪异常事件发生时执行堆栈的内容)
throw:方法内部抛异常
throws:声明方法异常
finaly:代码中无论是否有异常都会执行,清除资源

203、关于以下程序代码的说明正确的 答案:D
class HasStatic{
    private static int x = 100;
    public static void main(String args[ ]){
        HasStatic hs1 = new HasStatic();
        hs1.x++;
        HasStatic hs2 = new HasStatic();
        hs2.x++;
        hs1=new HasStatic();
        hs1.x++;
        HasStatic.x--;
        System.out.println( "x=" +x);
    }
}

A、5行不能通过编译,因为引用了私有静态变量
B、10行不能通过编译,因为x是私有静态变量
C、程序通过编译,输出结果为:x=103
D、程序通过编译,输出结果为:x=102
解析:因为x的 修饰符为 static 所以x为类变量,即对于所有的实例来说,他们访问的x为同一个x,类变量存储在方法区,不属于每个实例的私有,

刚开始x=100

调用hs1.x++ x为101;

调用hs2.x++ x为102;

调用hs1.x++ x为103 (此时hs1指向了一个新的HasStatic实例,但是依然访问的是同一个X)

调用HasStatic.x-- x为102

所以结果为D

204、有以下类定义: 答案:B
abstract class Animal{
    abstract void say();
}
public class Cat extends Animal{
    public Cat(){
        System.out.printf("I am a cat");
    }
    public static void main(String[] args) {
        Cat cat=new Cat();
    }
}

A、I am a cat
B、Animal能编译,Cat不能编译
C、Animal不能编译,Cat能编译
D、编译能通过,但是没有输出结果
解析:B 当一个实体类集成一个抽象类,必须实现抽象类中的抽象方法,抽象类本身没有错误,但是cat类编译通不过
2、包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样可以拥有成员变量和普通的成员方法。注意,抽象类和普通类的主要有三点区别:

1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。

2)抽象类不能用来创建对象;

3)如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。

在其他方面,抽象类和普通的类并没有区别。

205、说明输出结果。 答案:C
import java.util.Date;  
public class SuperTest extends Date{  
    private static final long serialVersionUID = 1L;  
    private void test(){  
       System.out.println(super.getClass().getName());  
    }  
     
    public static void main(String[]args){  
       new SuperTest().test();  
    }  
}  

A、SuperTest
B、SuperTest.class
C、test.SuperTest
D、test.SuperTest.class
解析:C.

TestSuper和Date的getClass都没有重写,他们都是调用Object的getClass,而Object的getClass作用是返回的是运行时的类的名字。这个运行时的类就是当前类,所以super.getClass().getName()返回的是test.SuperTest,与Date类无关

要返回Date类的名字需要写super.getClass().getSuperclass()
2、解题要点:

1、super.getClass()调用的是父类即Date类的方法;

2、父类的getClass方法继承自Object类,且该方法是final的,不能被修改;

3、Object中的getClass()返回的是当前运行的类,即SuperTest;

4、Class中的getName()方法针对引用类型的返回的是包名+类名,即test.SuperTest;

5、如果想要返回父类,即Date的名称,可以使用super.getClass().getSuperClass().getName();

6、此处super还是this,亦或直接getClass().getName(),结果都是一样的;

206、关于下面程序,哪些描述是正确的: ( ) 答案:
 public class While {
    public void loop() {
        int x= 10;
        while ( x )  {
            System.out.print("x minus one is " + (x - 1));
            x -= 1;
        }
    }
}

A、行1有语法错误
B、行4有语法错误
C、行5有语法错误
D、行6有语法错误
解析:这个题主要考while()中表达式的判断,在C语言中大于0的int值都会被认为是true,而java中没有这个机制,必须是boolean类型的。

207、 答案: C
public class IfTest{
    public static void main(String[]args){
        int x=3;
        int y=1;
        if(x=y)
            System.out.println("Not equal");
        else
            System.out.println("Equal");
     }
}

A、The output is “Equal”
B、The output in “Not Equal”
C、An error at line 5 causes compilation to fall.
D、The program executes but does not print a message.
解析:这个题考查两个知识点。

1、Java中,赋值是有返回值的 ,赋什么值,就返回什么值。比如这题,x=y,返回y的值,所以括号里的值是1。

2、Java跟C的区别,C中赋值后会与0进行比较,如果大于0,就认为是true;而Java不会与0比较,而是直接把赋值后的结果放入括号

208、下面属于java包装类的是? 答案:B C D

A、String
B、Long
C、Character
D、Short
解析:Java 语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,即包装类。对应的基本类型和包装类如下表:

基本数据类型包装类
byteByte
booleanBoolean
shortShort
charCharacter
intInteger
longLong
floatFloat
doubleDouble
209、给出下面的代码段: 答案:C D

public class Base{
int w, x, y ,z;
public Base(int a,int b)
{
x=a; y=b;
}
public Base(int a, int b, int c, int d)
{
// assignment x=a, y=b
w=d;z=c;
}}
在代码说明// assignment x=a, y=b处写入如下哪几个代码是正确的?()

A、Base(a,b);
B、x=a, y=b;
C、x=a; y=b;
D、this(a,b);
解析:B选项,可以使用逗号的是变量初始化的语句,比如

int i=1,b=2;

如果是赋值语句,不能用逗号分隔。

210、下列代码片段中,存在编译错误的语句是() 答案:B C D
byte b1=1,b2=2,b3,b6,b8;
final byte b4=4,b5=6,b7;
b3=(b1+b2);  /*语句1*/
b6=b4+b5;    /*语句2*/
b8=(b1+b4);  /*语句3*/
b7=(b2+b5);  /*语句4*/
System.out.println(b3+b6);

A、语句2
B、语句1
C、语句3
D、语句4
解析:B C D------------知识点------------

Java表达式转型规则由低到高转换

1、所有的byte,short,char型的值将被提升为int型;

2、如果有一个操作数是long型,计算结果是long型;

3、如果有一个操作数是float型,计算结果是float型;

4、如果有一个操作数是double型,计算结果是double型;

5、被fianl修饰的变量不会自动改变类型,当2个final修饰相操作时,结果会根据左边变量的类型而转化。

--------------解析--------------

语句1错误:b3=(b1+b2);自动转为int,所以正确写法为b3=(byte)(b1+b2);或者将b3定义为int;

语句2正确:b6=b4+b5;b4、b5为final类型,不会自动提升,所以和的类型视左边变量类型而定,即b6可以是任意数值类型;

语句3错误:b8=(b1+b4);虽然b4不会自动提升,但b1仍会自动提升,所以结果需要强转,b8=(byte)(b1+b4);

语句4错误:b7=(b2+b5); 同上。同时注意b7是final修饰,即只可赋值一次,便不可再改变

211、Java 源程序文件的扩展名为() 答案: A

A、.java
B、.class
C、.exe
D、.jar
解析:.class 编译后的Java文件
.java是未编译的程序
.jsp是页面程序
.xml配置程序
.jar是.calss的集合
2、class:编译后的Java文件 ;
.java:是未编译的Java程序;

.jsp:是Java 服务器页面技术,支持Java代码的***页;

.xml:可拓展文本标记语言,一种文本格式,常用来做配置文件;

.jar:一种压缩包格式,常用来打包 Java 类库。

212、以下哪个不能用来处理线程安全 答案:D

A、synchronized关键字
B、volatile关键字
C、Lock类
D、transient关键字
解析:synchrozied关键字称作同步,主要用来给方法、代码块加锁,被加锁的代码段,同一时间内多线程同时访问同一对象的加锁方法/代码块时,只能有一个线程执行能执行方法/代码块中的代码,其余线程必须等待当前线程执行完以后才执行该方法/代码块。

volatile关键字1.保证了不同线程对该变量操作的内存可见性.(当一个线程修改了变量,其他使用次变量的线程可以立即知道这一修改)。2.禁止了指令重排序.

Lock接口提供了与synchronized关键字类似的同步功能,但需要在使用时手动获取锁和释放锁。

transient关键字 简单地说,就是让某些被修饰的成员属性变量不被序列化。

213、下面有关java final的基本规则,描述错误的是? 答案:B

A、final修饰的类不能被继承
B、final修饰的成员变量只允许赋值一次,且只能在类方法赋值
C、final修饰的局部变量即为常量,只能赋值一次。
D、final修饰的方法不允许被子类覆盖
解析:final修饰的成员变量为基本数据类型是,在赋值之后无法改变。当final修饰的成员变量为引用数据类型时,在赋值后其指向地址无法改变,但是对象内容还是可以改变的。

final修饰的成员变量在赋值时可以有三种方式。1、在声明时直接赋值。2、在构造器中赋值。3、在初始代码块中进行赋值。

214、在Java中,关于HashMap类的描述,以下错误的是()? 答案:A

A、HashMap能够保证其中元素的顺序
B、HashMap允许将null用作值
C、HashMap允许将null用作键
D、HashMap使用键/值得形式保存数据
解析:HashMap的底层是由数组加链表实现的,对于每一个key值,都需要计算哈希值,然后通过哈希值来确定顺序,并不是按照加入顺序来存放的,因此可以认为是无序的,但不管是有序还是无序,它都一个自己的顺序。故A错。

最开始有Hashtable,Hashtable是不允许key和value的值为空的,但后来开发者认为有时候也会有key值为空的情况,因为可以允许null为空,通过查看HashMap的源代码就知道:if(key = null) {putForNullKey(value);};

Map底层都是用key/value键值对的形式存放的

215、如下代码的输出结果是什么? 答案:
public class Test {
    public int aMethod(){
        static int i = 0;
        i++;
        return i;
    }
public static void main(String args[]){
    Test test = new Test();
    test.aMethod();
    int j = test.aMethod();
    System.out.println(j);
    }
}

A、0
B、1
C、2
D、编译失败
解析:静态变量只能在类主体中定义,不能在方法中定义

216、可以把任何一种数据类型的变量赋给Object类型的变量。 答案: A

A、对
B、错
解析:对象类型的不必多说可以赋值;而八大基础数据类型会自动装箱后赋值给Object,所以编译运行都不会报错
2、还是老话,Java中一切都是对象,Object是所有类的根类!

217、StringBuffer类对象创建之后可以再修改和变动. 答案: A

A、正确
B、错误
解析:1.String对象不可变、StringBuffer对象可变的含义: 举个例子:String str = “aa”; str = “aa”+“bb”; 此时str的值为"aabb",但是"aabb"不是在开始的字符串"aa"后面直接连接的"bb",而是又新生成了字符串"aabb",字符串"aa"一旦被初始化,那么它的值不可能再改变了。 StringBuffer strb = StringBuffer(“aa”); strb.append(“bb”); 此时的strb的值也为"aabb",但是"aabb"是直接在开始的字符串"aa"后面连接的“bb”,并没有生成新的字符串。

218、在 main() 方法中给出的整型数组,如果将其写到一个文件中,需要( )。 答案:B

A、System.out.print (buffer[i]);
B、DataOutputStream dout = new DataOutputStream(new FileOutputStream(this.filename));
C、DataInputStream din = new DataInputStream(new FileInputStream(this.filename));。
D、System.in.read(buffer)。
解析:input和output指的是对于程序而言。input是从文件读取进来,output是输出到文件。
2、数据写入文件即out ,把数据写入输出流 DataOutputStream 输入输出流都是对于程序来讲的

219、当我们需要所有线程都执行到某一处,才进行后面的的代码执行我们可以使用? 答案:B

A、CountDownLatch
B、CyclicBarrier
C、Semaphore
D、Future
解析:CountDownLatch 是等待一组线程执行完,才执行后面的代码。此时这组线程已经执行完。
CyclicBarrier 是等待一组线程至某个状态后再同时全部继续执行线程。此时这组线程还未执行完。
本人也是选B,如果选A的话,难道是因为题目要求执行的是后面的代码?而不是继续执行线程?
2、从jdk作者设计的目的来看,javadoc是这么描述它们的: CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. CyclicBarrier : A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. 从javadoc的描述可以得出: CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行; CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。 对于CountDownLatch来说,重点是“一个线程(多个线程)等待”,而其他的N个线程在完成“某件事情”之后,可以终止,也可以等待。 而对于CyclicBarrier,重点是多个线程,在任意一个线程没有完成,所有的线程都必须互相等待,然后继续一起执行。 CountDownLatch是计数器,线程完成一个记录一个,只不过计数不是递增而是递减,而CyclicBarrier更像是一个阀门,需要所有线程都到达,阀门才能打开,然后继续执行。 按照这个题目的描述等所有线程都到达了这一个阀门处,再一起执行,此题强调的是,一起继续执行,我认为 选B 比较合理!

220、关于Java以下描述正确的有( ) 答案:A

A、native关键字表名修饰的方法是由其它非Java语言编写的
B、能够出现在import语句前的只有注释语句
C、接口中定义的方法只能是public
D、构造方法只能被修饰为public或者default
解析:C是错的。

接口是更抽象的东西,属性默认是:public static final的,方法默认是public abstract的!

img

题目中如果说可以使用static或者default修饰方法,jdk1.8后是没问题的,但是绝对不可以说默认是static的:

img

默认意味着去掉也正确,假如我在这里去掉static:

img

很明显有错,所以C100%不对!
2、A:native是由调用本地方法库(如操作系统底层函数),可以由C,C++实现,A正确
B:import是用于导包语句,其前面可以出现package,用来声明包的,B错误
C:接口方法的修饰符可以是:public,abstract,default,static(后两者需要有{}),C正确
D:构造方法可以用private,protected,default,private,D错误

221、以下程序输出() 答案:D
public static void main(String[] args) {
   int num = 2;
   switch (num) {
   case 1:
        ++num;
   case 2:
        ++num;
   case 3:
        ++num;
   default:
        ++num;
   break;
   }
   System.out.println(num);
 }
}

A、2
B、3
C、4
D、5
解析:记住一点,遇到break才跳出
2、匹配到case 2 num->3 但是其后没有break,所以继续执行case 3 num->4、default num->5而后结束,所以答案为 5

注意细节!

222、JVM内存不包含如下哪个部分( ) 答案:D

A、Stacks
B、PC寄存器
C、Heap
D、Heap Frame
解析:img

2、java好像只有栈帧 没有堆帧 pc寄存器 就是 程序计数器

程序计数器是一个以线程私有的一块较小的内存空间,用于记录所属线程所执行的字节码的行号指示器;字节码解释器工作时,通过改变程序计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳准、异常处理、线程恢复等基础功能都需要依赖程序计数器来完成

QAQ 第一次回答 不知道对不对

img

223、 答案:A
下列代码执行结果为()
public static void main(String args[])throws InterruptedException{
            Thread t=new Thread(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.print("2");
                }
            });
            t.start();
             
            t.join();
            System.out.print("1");
        }

A、21
B、12
C、可能为12,也可能为21
D、以上答案都不对
解析:选A

thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

t.join(); //使调用线程 t 在此之前执行完毕。
t.join(1000); //等待 t 线程,等待时间是1000毫秒

224、下面哪些选项是正确的() 答案: A D

A、>>是算术右移操作符
B、>>是逻辑右移操作符
C、>>>是算术右移操作符
D、>>>是逻辑右移操作符
解析:就是这么规定的吧。

>> 右移 高位补符号位

>>> 右移 高位补0
2、运算符“>>”执行算术右移,它使用最高位填充移位后左侧的空位。

右移的结果为:每移一位,第一个操作数被2除一次,移动的次数由第二个操作数确定。

逻辑右移或叫无符号右移运算符“>>>“只对位进行操作,没有算术含义,它用0填充左侧的空位。

算术右移不改变原数的符号,而逻辑右移不能保证这点。

移位运算符约简其右侧的操作数,当左侧操作数是int类型时,右侧以32取模;当左侧是long类型时,右侧以64取模。

225、如下哪些是 java 中有效的关键字() 答案: A D

A、native
B、NULL
C、false
D、this
解析:这个关键字常见的坑:

true、false、null都不是关键字

goto、const、是保留的关键字

abstract                continue           for            new        
switch                  default            if             package     
synchronized            do                 goto           private     
this                    break              double         implements   
protected               throw              byte           else       
import                  public             throws         case       
enum                    instanceof         return         transient  
catch                   extends            int            short       
try                     char               final          interface    
static                  void               class          finally   
long                    strictfp           volatile       const      
float                   native             super          while
boolean                 assert 
226、下列InputStream类中哪个方法可以用于关闭流? 答案:B

A、skip()
B、close()
C、mark()
D、reset()
解析:inputstream的close方法用来关闭流
skip()用来跳过一些字节
mark()用来标记流
reset()复位流

227、以下哪个方法用于定义线程的执行体? 答案:C

A、start()
B、init()
C、run()
D、synchronized()
解析:run()相当于线程的任务处理逻辑的入口方法,它由Java虚拟机在运行相应线程时直接调用,而不是由应用代码进行调用。

而start()的作用是启动相应的线程。启动一个线程实际是请求Java虚拟机运行相应的线程,而这个线程何时能够运行是由线程调度器决定的。start()调用结束并不表示相应线程已经开始运行,这个线程可能稍后运行,也可能永远也不会运行。

228、ArrayList list = new ArrayList(20);中的list扩充几次 答案:A

A、0
B、1
C、2
D、3
解析:Arraylist默认数组大小是10,扩容后的大小是扩容前的1.5倍,最大值小于Integer 的最大值减8,如果新创建的集合有带初始值,默认就是传入的大小,也就不会扩容

private static final int DEFAULT_CAPACITY = 10; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 
private void grow(int minCapacity) { // overflow-conscious code  int oldCapacity = elementData.length;  int newCapacity = oldCapacity + (oldCapacity >> 1);  if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;  if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);  // minCapacity is usually close to size, so this is a win:  elementData = Arrays.copyOf(elementData, newCapacity); }
229、下面有关servlet和cgi的描述,说法错误的是? 答案:D

A、servlet处于服务器进程中,它通过多线程方式运行其service方法
B、CGI对每个请求都产生新的进程,服务完成后就销毁
C、servlet在易用性上强于cgi,它提供了大量的实用工具例程,例如自动地解析和解码HTML表单数据、读取和设置HTTP头、处理Cookie、跟踪会话状态等
D、cgi在移植性上高于servlet,几乎所有的主流服务器都直接或通过插件支持cgi
解析:

选择D,servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。

2、ervlet 与 CGI 的比较

和CGI程序一样,Servlet可以响应用户的指令(提交一个FORM等等),也可以象CGI程序一样,收集用户表单的信息并给予动态反馈(简单的注册信息录入和检查错误)。
然而,Servlet的机制并不仅仅是这样简单的与用户表单进行交互。传统技术中,动态的网页建立和显示都是通过CGI来实现的,但是,有了Servlet,您可以大胆的放弃所有CGI(perl?php?甚至asp!),利用Servlet代替CGI,进行程序编写。
对比一:当用户浏览器发出一个Http/CGI的请求,或者说 调用一个CGI程序的时候,服务器端就要新启用一个进程 (而且是每次都要调用),调用CGI程序越多(特别是访问量高的时候),就要消耗系统越多的处理时间,只剩下越来越少的系统资源,对于用户来说,只能是漫长的等待服务器端的返回页面了,这对于电子商务激烈发展的今天来说,不能不说是一种技术上的遗憾。
而Servlet充分发挥了服务器端的资源并高效的利用。每次调用Servlet时并不是新启用一个进程 ,而是在一个Web服务器的进程敏感词享和分离线程,而线程最大的好处在于可以共享一个数据源,使系统资源被有效利用。
对比二:传统的CGI程序,不具备平台无关性特征,系统环境发生变化,CGI程序就要瘫痪,而Servlet具备Java的平台无关性,在系统开发过程中保持了系统的可扩展性、高效性。
对比三:传统技术中,一般大都为二层的系统架构,即Web服务器+数据库服务器,导致网站访问量大的时候,无法克服CGI程序与数据库建立连接时速度慢的瓶颈,从而死机、数据库死锁现象频繁发生。而我们的Servlet有连接池的概念,它可以利用多线程的优点,在系统缓存中事先建立好若干与数据库的连接,到时候若想和数据库打交道可以随时跟系统"要"一个连接即可,反应速度可想而知。

230、下面有关java类加载器,说法正确的是? 答案:A B C D

A、引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的
B、扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。
C、系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类
D、tomcat为每个App创建一个Loader,里面保存着此WebApp的ClassLoader。需要加载WebApp下的类时,就取出ClassLoader来使用
解析:jvm classLoader architecture :

a、Bootstrap ClassLoader/启动类加载器
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作.

B、Extension ClassLoader/扩展类加载器
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作

C、System ClassLoader/系统类加载器
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作.

B、 User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性.

231、设有下面两个类的定义: 类Person和类Student的关系是()。答案:
class  Person {}
class  Student  extends  Person {
public int id;     //学号
public int score;  //总分
public String  name;   // 姓名
public int getScore(){return  score;}
}

A、包含关系
B、继承关系
C、关联关系
D、无关系,上述类定义有语法错误
解析:Java中类之间的六种关系:
第一种:继承关系,例如:子类继承父类,子接口继承父接口。
第二种:实现关系,例如:类实现接口。
第三种:依赖关系,例如:一个类作为另一个类中方法的参数存在,这种关系具有偶然性和临时性。
第四种:关联关系,例如:一个类作为另一个类中的成员变量存在,它是一种强依赖关系。
第五种:聚合关系,例如:整体和部分之间,他们是可以分离的拥有各自的生命周期,并且部分是相同的。像鸟群和鸟。
第六种:组合关系,它是一种强聚合,并且整体和部分之间不可分离,具有相同的生命周期,整体包含该部分,也包含其他部分,其他部分和该部分是不相同的,像cpu和计算机,计算机除了包括cpu还有键盘和显示器等。

232、关于下面的程序,说法正确的是: 答案:D
1. class StaticStuff
2 {
3.     static int x = 10;
4.
5.     static { x += 5; }
6.
7. public static void main(String args[])
8. {
9.     System.out.println(“x = ” + StaticStuff .x);
10. }
11.    static
12.     {x /= 3; }
13.}

A、第5行和12行不能编译,因为该方法没有方法名和返回值。
B、第12 行不能编译,因为只能有一个static初始化块。
C、代码编译并执行,输出结果x = 10.
D、代码编译并执行,输出结果 x = 5.
E、代码编译并执行,输出结果 x = 15.
解析:选D。考察的是代码执行的顺序。
第5、12行属于static修饰的静态代码块。所以A、B说法错误。
静态代码块以及静态变量自上而下的顺序依次随着类加载而执行,所以依据题目的变量初始化:
x初始为10
x+5赋值x,结果为15
x/3赋值给x,结果为5

233、下面代码运行结果是? 答案: A
public class Test
{
    static boolean foo(char c)
    {
        System.out.print(c);
        return true;
    }
    public static void main( String[] argv )
    {
        int i = 0;
        for ( foo('A'); foo('B') && (i < 2); foo('C'))
        {
            i++ ;
            foo('D');
        }
    }
}

A、ABDCBDCB
B、ABCDABCD
C、Compilation fails.
D、An exception is thrown at runtime.
解析:for(条件1;条件2;条件3) {
//语句
}
执行顺序是条件1->条件2->语句->条件3->条件2->语句->条件3->条件2…
如果条件2为true,则一直执行。如果条件2位false,则for循环结束

234、以下哪项不属于java类加载过程? 答案:B

A、生成java.lang.Class对象
B、int类型对象成员变量赋予默认值
C、执行static块代码
D、类方法解析
解析:不应该选D,而应该选B
类的加载包括:加载,验证,准备,解析,初始化。
选项A:生成java.lang.Class对象是在加载时进行的。生成Class对象作为方法区这个类的各种数据的访问入口。
选项B:既然是对象成员,那么肯定在实例化对象后才有。在类加载的时候会赋予初值的是类变量,而非对象成员。
选项C:这个会调用。可以用反射试验。
选项D:类方法解析发生在解析过程。

235、以下说法哪个是正确的() 答案:A B C D

A、IOException在编译时会被发现
B、NullPointerEception在编译时不被发现
C、SQLException在编译时会被发现
D、FileNotFoundException在编译时会被发现
解析:
img

编译时能被发现的是必须加上try catch的异常,这些异常在编译时可以被发现,如果异常编译时不一定发生,如除以0异常,指针为空异常。

236、类声明中,声明抽象类的关键字是 ( ) 答案:B

A、public
B、abstract
C、final
D、class
解析:

public 共有类,可以在包外使用,此时,源文件名必须和类名相同。

abstract 抽象类,抽象类位于继承树的抽象层,抽象类不能被实例化。

final  不能被继承,没有子类,final类中的方法默认是final的。

class 只能在包内使用的类

自己总结的,有遗漏请私我指正,不知道为什么网上都说接口没有Main方法,然而我用IDEA和eclipse是可以的,不知道是不是我理解错了。
jdk1.8之前

接口

1.多实现

2.变量类型默认且只能为为public static final

3.函数类型默认且只能为public,只能有public类型的静态成员函数

4.非静态成员函数没有方法体,静态成员函数有方法体

5.子类必须实现所有接口函数

6.可以有main方法;可以new一个接口,需要在方法体中实现所有接口函数

7.没有构造器

抽象类

1.单继承

2.变量类型不限(静态变量+非静态变量)

3.函数类型不限(静态函数+非静态函数)

4.非静态函数包含没有方法体的抽象函数. 有方法体的普通函数

5.子类可以不覆写父类的抽象方法,但子类也要申明为抽象类;子类可以选择覆写父类的非抽象方法

6.可以有main方法;不可以new一个抽象类

7.可以有构造器

Jdk1.8

接口中可以有default类型的方法,实现类可以选择实现该方法

意义:默认方法的主要优势是提供一种拓展接口的方法,而不破坏现有代码。另一个优势为该方法是可选的,子类可以根据不同的需求Override或默认实现。

237、子类要调用继承自父类的方法,必须使用super关键字。 答案:B

A、正确
B、错误
解析:1、子类构造函数调用父类构造函数用super

2、子类重写父类方法后,若想调用父类中被重写的方法,用super

3、未被重写的方法可以直接调用。

238、以下代码的运行结果是什么( ) 答案:A
class Supper{     
 public int get()    
  {          
System.out.println("Supper");         
 return 5;     
 }    
 }     
public class Sub{     
 public int get()    
 {         
 System.out.println("Sub");        
 return new Integer("5");          }      
 public static void main(String args[]) {          
 new Supper().get();        
   new Sub().get();          }   
  }

A、Supper Sub
B、Supper 5 Sub
C、Supper 5 5 Sub
D、Supper Sub 5 5
解析:我做了600多道题,才遇到这么一个多选题可以选一个选项的(所以虽然觉得A之外其他都不对但还是选了一个
2、newSupper().get()和newSub().get()只调用了get()方法,又没有打印输出get()返回的数值,所以肯定没有5

239、下列说法正确的是() 答案:B

A、在类方法中可用this来调用本类的类方法
B、在类方法中调用本类的类方法时可直接调用
C、在类方法中只能调用本类中的类方法
D、在类方法中绝对不能调用实例方法
解析:在类方法中不能有this关键字,img,直接调用类方法即可,A错误,B正确,在类方法中可以通过创建实例对象调用类的实例方法,C\D错误
2、先要理解什么是类的方法,所谓类的方法就是指类中用static 修饰的方法(非static 为实例方法),比如main 方法,那么可以以main 方法为例,可直接调用其他类方法,必须通过实例调用实例方法,this 关键字不是这么用的

240、off-heap是指那种内存() 答案:B

A、JVM GC能管理的内存
B、JVM进程管理的内存
C、在JVM老年代内存区
D、在JVM新生代内存
解析:off-heap叫做堆外内存,将你的对象从堆中脱离出来序列化,然后存储在一大块内存中,这就像它存储到磁盘上一样,但它仍然在RAM中。对象在这种状态下不能直接使用,它们必须首先反序列化,也不受垃圾收集。序列化和反序列化将会影响部分性能(所以可以考虑使用FST-serialization)使用堆外内存能够降低GC导致的暂停。堆外内存不受垃圾收集器管理,也不属于老年代,新生代。

241、映射 (Map) 的key和value都不可重复。( ) 答案:B

A、正确
B、错误
解析:Map接口有两个金典的子类分别是 Hashtable 和 Hashmap。
Hashtable 线程安全,不支持key和value为空,key不能重复,但value可以重复,不支持key和value为null。
Hashmap 非线程安全,支持key和value为空,key不能重复,但value可以重复,支持key和value为null。
由于题目否定Map集合中的value都不可重复,这是错误的。

242、一个类的构造器不能调用这个类中的其他构造器。( ) 答案:B

A、正确
B、错误
解析:this()和super()都是构造器,this()调用本类构造器,super()调用父类构造器

243、类Person里面有个方法sleep(),如果直接用Person.sleep(),则方法sleep前面必须用的关键词是? ( ) 答案:B

A、class
B、static
C、public
D、final
解析:能被类直接调用,说明是静态的,随着类的加载而加载
2、tatic关键字:针对多个对象共有的成员变量值时所提出的。
特点:1、随着类的加载而加载; 2、优先于对象存在; 3、被类的所有对象共享; 4、可以通过类名直接调用。
注意事项:1.在静态方法中是没有this关键字的; 2.静态方法只能访问静态的成员变量和静态的成员方法。

244、ResultSet中记录行的第一列索引为? 答案:C

A、-1
B、0
C、1
D、以上都不是
解析:ResultSet跟普通的数组不同,索引从1开始而不是从0开始

245、如果希望监听TCP端口9000,服务器端应该怎样创建socket? 答案:B

A、new Socket(“localhost”,9000);
B、new ServerSocket(9000);
C、new Socket(9000);
D、new ServerSocket(“localhost”,9000);
解析:答案选B。

ServerSocket(int port) 是服务端绑定port端口,调accept()监听等待客户端连接,它返回一个连接队列中的一个socket。

Socket(InetAddress address , int port)是创建客户端连接主机的socket流,其中InetAddress是用来记录主机的类,port指定端口。

socket和servletSocket的交互如下图所示

img

详细了解,大家可以看此博客:http://www.cnblogs.com/rond/p/3565113.html

246、不考虑反射机制,一个子类显式调用父类的构造器必须用super关键字。( ) 答案: A

A、正确
B、错误
解析:应该是正确的,题目中说的是子类***显示调用***父类中的构造方法必须使用super关键字;如果子类没有显示调用父类中的构造方法,则系统默认会调用父类中的无参构造方法;若此时父类中没有定义无参构造方法则会报错。

2、java中的super关键词
super用于代表子类的直接父类的特征
super可以访问:
父类的成员变量,成员方法,构造方法
使用super关键词的情况:
在子类中,存在与父类相同的属性和方法,由于访问子类中属性和方法的优先级高于父类,可以通过super关键词来访问父类中的属性和方法
在子类中,可以通过super关键词来显示的调用父类的构造方法
子类的构造方法默认调用父类的无参构造方法,当父类中不存在无参构造方法时,可以同过super来调用父类的有参构造芳法来避免编译时错误。

super是引用吗?请大家讲一下,我不是很懂。。

247、以下代码段执行后的输出结果为 答案:D
public class Test {
    public static void main(String args[]) {
        int x = -5;
        int y = -12;
        System.out.println(y % x);
    }
}

A、-1
B、2
C、1
D、-2
解析:取模运算,结果的符号和被除数符号一致,切记切记
2、当x和y的正负相同时,取余和取模结果相同;

当x和y的正负不同时,取余结果的符号和x相同,取模结果的符号和y相同。(口诀:取余取头,取模取尾)

248、下面这段java代码,当 T 分别是引用类型和值类型的时候,分别产生了多少个 T对象和T类型的值() 答案:D
T t = new T();(值类型时:T t;)
Func(t);
Func 定义如下:
public void Func(T t) {  }

A、1 1
B、2 1
C、2 2
D、1 2
解析:D。引用类型作为函数的参数时,复制的是引用的地址,不会产生一个新的T;而如果T是值类型,其作为函数实参时会复制其值,也就是产生了一个新的T。所以D选项正确
2、值类型的对象我觉得并没有创建对象 而且值类型能叫对象吗?

答案在A和D之间 这个毫无悬念

主要就在值类型能否创建对象 能创建对象则又能创建几个对象

值类型即八大基础类型,基础类型在使用时是从常量池中获取,更严谨的而言其实是在-128~127之间 使用时是从常量池中获取,那么在使用的时候将常量池中的地址重复利用

但是在限制范围之外,得到的地址就会发生变化 代码为证

public static void main(String[] args) {
    int x1 = 127;
    int x2 = 129;
 
    int identityHashCode = System.identityHashCode(x1);
    System.out.println("传递之前:x1 identityHashCode = "+identityHashCode);
 
    identityHashCode = System.identityHashCode(x2);
    System.out.println("传递之前:x2 identityHashCode = "+identityHashCode);
 
    System.out.println("-----------------------------------------");
    method(x1);
    method(x2);
}
 
public static void method(int x) {
    int identityHashCode = System.identityHashCode(x1);
    System.out.println("传递之后:x identityHashCode = "+identityHashCode);
}

img

x1前后得到的hashCode相同

x2前后得到的hashCode不相同

总之,我还是认为值类型的不能称之为对象,虽然超过缓存范围限制时重新开辟了空间,但是不能与引用类型混为一谈

我坚持值类型传递创建了0个对象,开辟了2个内存地址

249、 对于文件的描述正确的是( ) 答案:D

A、文本文件是以“.txt”为后缀名的文件,其他后缀名的文件是二进制文件。
B、File类是Java中对文件进行读写操作的基本类。
C、无论文本文件还是二进制文件,读到文件末尾都会抛出EOFException异常。
D、Java中对于文本文件和二进制文件,都可以当作二进制文件进行操作。
解析:A.文件分为文本文件和二进制文件,计算机只认识二进制,所以实际上都是二进制的不同解释方式。文本文件是以不同编码格式显示的字符,例如Ascii、Unicode等,window中文本文件的后缀名有".txt",".log",各种编程语言的源码文件等;二进制文件就是用文本文档打开是看不懂乱码,只要能用文本打开的文件都可以算是文本文件,只是显示的结果不是你想要的,二进制文件只有用特殊的应用才能读懂的文件,例如".png",".bmp"等,计算机中大部分的文件还是二进制文件。

B.File类是对文件整体或者文件属性操作的类,例如创建文件、删除文件、查看文件是否存在等功能,不能操作文件内容;文件内容是用IO流操作的。

C.当输入过程中意外到达文件或流的末尾时,抛出EOFException异常,正常情况下读取到文件末尾时,返回一个特殊值表示文件读取完成,例如read()返回-1表示文件读取完成。

D.上面A选项已经说了,不论是文本文件还是二进制文件,在计算机中都是以二进制形式存储的,所以都当做二进制文件读取。

250、Java的集合框架中重要的接口java.util.Collection定义了许多方法。选项中哪个方法是Collection接口所定义的( ) 答案: A B D

A、int size()
B、boolean containsAll(Collection c)
C、compareTo(Object obj)
D、boolean remove(Object obj)
解析:Collection 接口常用的方法
size():返回集合中元素的个数
add(Object obj):向集合中添加一个元素
addAll(Colletion coll):将形参coll包含的所有元素添加到当前集合中
isEmpty():判断这个集合是否为空
clear():清空集合元素
contains(Object obj):判断集合中是否包含指定的obj元素
① 判断的依据:根据元素所在类的equals()方法进行判断
②明确:如果存入集合中的元素是自定义的类对象,要去:自定义类要重写equals()方法
constainsAll(Collection coll):判断当前集合中是否包含coll的所有元素
rentainAll(Collection coll):求当前集合与coll的共有集合,返回给当前集合
remove(Object obj):删除集合中obj元素,若删除成功,返回ture否则
removeAll(Collection coll):从当前集合中删除包含coll的元素
equals(Object obj):判断集合中的所有元素 是否相同
hashCode():返回集合的哈希值
toArray(T[] a):将集合转化为数组
①如有参数,返回数组的运行时类型与指定数组的运行时类型相同。
iterator():返回一个Iterator接口实现类的对象,进而实现集合的遍历。
数组转换为集合:Arrays.asList(数组)

251、Java Application 中的主类需包含main方法,以下哪项是main方法的正确形参?( ) 答案:B

A、String args
B、String[] args
C、Char arg
D、StringBuffer[] args
解析:String[] args / String args[] / String… args都是正确的。

252、javac的作用是( )。 答案:A

A、将源程序编译成字节码
B、将字节码编译成源程序
C、解释执行Java字节码
D、调试Java代码
解析:javac将源程序编译成.class文件,字节码;java将字节码转为机器码,.exe程序
2、选 A
javac 可以将java源文件编译为class字节码文件。
如 javac HelloWorld.java,运行javac命令后,如果成功编译没有错误的话,会出现一个HelloWorld.class的文件。
java 可以运行class字节码文件。
如 java HelloWorld。注意java命令后面不要加.class

253、下列关于Java并发的说法中正确的是() 答案:B

A、CopyOnWriteArrayList适用于写多读少的并发场景
B、ReadWriteLock适用于读多写少的并发场景
C、ConcurrentHashMap的写操作不需要加锁,读操作需要加锁
D、只要在定义int类型的成员变量i的时候加上volatile关键字,那么多线程并发执行i++这样的操作的时候就是线程安全的了
解析:A,CopyOnWriteArrayList适用于写少读多的并发场景
B,ReadWriteLock即为读写锁,他要求写与写之间互斥,读与写之间互斥,
读与读之间可以并发执行。在读多写少的情况下可以提高效率
C,ConcurrentHashMap是同步的HashMap,读写都加锁
D,volatile只保证多线程操作的可见性,不保证原子性
2、对于D选项,volatite只保证线程在“加载数据阶段”加载的数据是最新的,并不能保证线程安全。

一个线程执行的过程有三个阶段:
加载(复制)主存数据到操作栈 --> 对操作栈数据进行修改 --> 将操作栈数据写回主存
volatite关键字,让编译器不去优化代码使用缓存等,以保证线程在“加载数据阶段”加载的数据都是最新的

比如:
某一时刻i=6是最新的值,volatile保证线程A,B都同时加载了这个最新的值,
然后A执行i(A)+1=7,然后将7写回主存,
B也执行i(B)+1=7,然后也将7写回内存,
这样,执行两次加法,i却只增加了1

254、阅读如下代码。 请问,对语句行 test.hello(). 描述正确的有() 答案:A
package NowCoder;
class Test {
    public static void hello() {
        System.out.println("hello");
    }
}
public class MyApplication {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Test test=null;
        test.hello();
    }
}

A、能编译通过,并正确运行
B、因为使用了未初始化的变量,所以不能编译通过
C、以错误的方式访问了静态方法
D、能编译通过,但因变量为null,不能正常运行
解析:这题我认为答案错了
因为Test类的hello方法是静态的,所以是属于类的,当实例化该类的时候,静态会被优先加载而且只加载一次,所以不受实例化new Test();影响,只要是使用到了Test类,都会加载静态hello方法!
另外,在其他类的静态方法中也是可以调用公开的静态方法,此题hello方法是使用public修饰的所以在MyApplication中调用hello也是可以的。
总结:即使Test test=null;这里也会加载静态方法,所以test数据中包含Test类的初始化数据。(静态的,构造的,成员属性)
因此test.hello是会调用到hello方法的。
附上运行图:img

255、如果Child extends Parent,那么正确的有()? 答案:B C D

A、如果Child是class,且只有一个有参数的构造函数,那么必然会调用Parent中相同参数的构造函数
B、如果Child是interface,那么Parent必然是interface
C、如果Child是interface,那么Child可以同时extends Parent1,Parent2等多个interface
D、如果Child是class,并且没有显示声明任何构造函数,那么此时仍然会调用Parent的构造函数
解析:选BCD
A、子类的构造器第一行默认都是super(),默认调用直接父类的无参构造,一旦直接父类没有无参构造,那么子类必须显式的声明要调用父类或者自己的哪一个构造器。
BC、接口只能继承接口,但是可以多继承。类都是单继承,但是继承有传递性。
D、一个类一旦没有显式的定义任何构造,那么JVM会默认给你一个无参构造。无参构造的第一行依然默认是super()。
2A 可以调用父类无参的构造函数,子类的有参构造函数和是否调用父类的有参数的构造函数无必然联系。
B 接口继承的时候只能继承接口不能继承类,因为如果类可以存在非抽象的成员,如果接口继承了该类,那么接口必定从类中也继承了这些非抽象成员,这就和接口的定义相互矛盾,所以接口继承时只能继承接口。
C 接口可以多继承可以被多实现,因为接口中的方法都是抽象的,这些方法都被实现的类所实现,即使多个父接口中有同名的方法,在调用这些方法时调用的时子类的中被实现的方法,不存在歧义;同时,接口的中只有静态的常量,但是由于静态变量是在编译期决定调用关系的,即使存在一定的冲突也会在编译时提示出错;而引用静态变量一般直接使用类名或接口名,从而避免产生歧义,因此也不存在多继承的第一个缺点。 对于一个接口继承多个父接口的情况也一样不存在这些缺点。所以接口可以多继承。
D 子类即使没有显示构造函数,也会有个无参数的默认构造函数,仍然会调用父类的构造函数。、

256、下列整型常量 i 的定义中,正确的是( ) 答案:C

A、final i;
B、static int i;
C、static final int i=234;
D、final float i=3.14f;
解析:java中final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。int关键字修饰整型类型。static修饰静态变量,即当利用这个关键字来修饰一个变量的时候,在创建对象之前就会为这个变量在内存中创建一个存储空间。以后创建对对象如果需要用到这个静态变量,那么就会共享这一个变量的存储空间。
A:缺少必要的整型类型声明
B:缺少常量关键字final
D:定义一个浮点常量

257、 以下代码执行后输出结果为( ) 答案:A
public class Test {
    public static void main(String[] args) {
        System.out.println("return value of getValue(): " +
        getValue());
    }
     public static int getValue() {
         try {
             return 0;
         } finally {
             return 1;
         }
     }
 }

A、return value of getValue(): 1
B、return value of getValue(): 0
C、return value of getValue(): 0return value of getValue(): 1
D、return value of getValue(): 1return value of getValue(): 0
解析:根据官方的JVM规范:
如果try语句里有return,返回的是try语句块中变量值。
详细执行过程如下:

如果有返回值,就把返回值保存到局部变量中;
执行jsr指令跳到finally语句里执行;
执行完finally语句后,返回之前保存在局部变量表里的值。
如果try,finally语句里均有return,忽略try的return,而使用finally的return.

258、下列说法正确的有() 答案:A

A、能被java.exe成功运行的java class文件必须有main()方法
B、J2SDK就是Java API
C、Appletviewer.exe可利用jar选项运行.jar文件
D、能被Appletviewer成功运行的java class文件必须有main()方法
解析:java程序的种类
1.Application:Java应用程序,是可以由Java解释器直接运行的程序。
2.Applet:即Java小应用程序,是可随网页下载到客户端由浏览器解释执行的Java程序。
3.Servlet:Java服务器端小程序,由Web服务器(容器)中配置运行的Java程序。

2、B、C、D都错
A:正确main方法是入口
B:J2SDK当然不仅仅包含java API
C:jar选项是java.exe 的选项
D:Appletviewer是运行applet的, applet 不用main方法,继承applet类即可。

259、以下哪个类包含方法flush()?() 答案:B

A、InputStream
B、OutputStream
C、A 和B 选项都包含
D、A 和B 选项都不包含
解析:flush()函数强制将缓冲区中的字符流、字节流等输出,目的是如果输出流输出到缓冲区完成后,缓冲区并没有填满,那么缓冲区将会一直等待被填满。所以在关闭输出流之前要调用flush()。

260、Java中的集合类包括ArrayList、LinkedList、HashMap等类,下列关于集合类描述正确的是() 答案:A B D

A、ArrayList和LinkedList均实现了List接口
B、ArrayList的访问速度比LinkedList快
C、添加和删除元素时,ArrayList的表现更佳
D、HashMap实现Map接口,它允许任何类型的键和值对象,并允许将null用作键或值
解析:ArrayList插入和现有项的删除开销很大,除非在末端
LinkedList插入和删除开销很小
ArrayList和LinkedList都是实现了List接口
HashMap可以用null值和空字符串作为K,不过只能有一个

261、执行如下代码后输出结果为( ) 答案:C
public class Test {
 public static void main(String[] args) {
     System.out.println("return value of getValue(): " + getValue());
 }
 public static int getValue() {
     int i = 1;
     try {
         i = 4;
     } finally{
         i++;
         return i;
     }
     }
 }

A、return value of getValue(): 1
B、return value of getValue(): 4
C、return value of getValue(): 5
D、其他几项都不对
解析:

    public static int getValue() {
        int i = 1;
        try {
            i = 4;
        } finally {
            i=i++;(把戏的重点:这样才是4)
            return i;
        }
    }
262、 枚举(enum)属于原始数据类型(primitive type)。 答案:B

A、正确
B、错误

解析:在Java中,变量有两种类型,一种是原始类型,一种是引用类型。

原始类型一共有8种,它们分别是char,boolean,byte,short,int,long,float,double。在Java API中,有它们对应的包装类,分别是(首字母大写)Character,Boolean,Byte,Short,Integer,Long,Float,Double(char,int的变化稍微大点)。

JAVA JVM对于不同的原始类型会分配不同的存储空间,具体分配如下:

byte : 1个字节 8位
最大值: 127 (有符号)

short : 2个字节 16位 32767

int : 4个字节 32位 2147483647

long: 8个字节 64位 9223372036854775807

float: 4个字节 32位 3.4028235E38

double:8个字节 64位 1.7976931348623157E308

枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示,是特殊的类,可以拥有成员变量和方法。
263、AccessViolationException异常触发后,下列程序的输出结果为( ) 答案:A
static void Main(string[] args)  
{  
    try  
    {  
        throw new AccessViolationException();  
        Console.WriteLine("error1");  
    }  
    catch (Exception e)  
    {  
        Console.WriteLine("error2");  
    }  
    Console.WriteLine("error3");  
} 

A、

error2
error3

B、

error3

C、

error2

D、

error1

解析:1.若catch(){}块中,如果有throw 语句,则,try{}catch(){} finally{}块之外的代码不执行;否则,执行。 2.try{}中有异常,则异常下面代码不执行。 3.finally{}中代码必执行。
2、首先,不知道是不是jdk1.7版本太低,找不到AccessViolationException这个异常。如果换作别的异常,编译是这样的:

img

其次,如果人工设置成非检查异常,题目答案是正确的:

img

最后,之所以有一部分朋友跟我一样选择C,是因为咱们以前遇到的题目是这样的:

img

个人理解是这样的,try…catch中,catch捕获到异常后,只要没有抛出异常语句(throw…),并不影响后续程序(try代码块中错误语句及其以后的代码不执行,catch及其以后正常执行)。个人观点,欢迎指正。

264、下面哪段程序能够正确的实现了GBK编码字节流到UTF-8编码字节流的转换: 答案:B
byte[] src,dst;

A、dst=String.fromBytes(src,“GBK”).getBytes(“UTF-8”)
B、dst=new String(src,“GBK”).getBytes(“UTF-8”)
C、dst=new String(“GBK”,src).getBytes()
D、dst=String.encode(String.decode(src,“GBK”)),“UTF-8” )
解析:选B,先通过GBK编码还原字符串,在该字符串正确的基础上得到“UTF-8”所对应的字节串。
2、String就没有decode和encode方法,坑爹货!

265、下面属于JSP内置对象的是? 答案: A B C D

A、out对象
B、response对象
C、application对象
D、page对象
解析:这些都是JSP内置对象

JSP内置对象有:
1.request对象
客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例。
2.response对象
response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。
3.session对象
session对象指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例.
4.out对象
out对象是JspWriter类的实例,是向客户端输出内容常用的对象
5.page对象
page对象就是指向当前JSP页面本身,有点象类中的this指针,它是java.lang.Object类的实例
6.application对象
application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。
7.exception对象
exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,否则无法编译。他实际上是java.lang.Throwable的对象
8.pageContext对象
pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本 类名也叫pageContext。
9.config对象
config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)

266、下列哪个类的声明是正确的? 答案:D

A、abstract final class HI{}
B、abstract private move(){}
C、protected private number;
D、public abstract class Car{}
解析:A只能有final和abstract的一个,因为final是最终类,不能继承,必须可以创建实例,而abstract是抽象类,只能继承,不有实例。冲突了,所以不对。
B是抽象方法,不能有方法体。所以末尾不是{}而是;才对
C中 访问修饰符只能有一个,而且对象没有类型。
D正确,这是抽象类。
2、A选项,final是最终类,不能被继承;abstrct类是抽象类,只能被继承,两者冲突。 B选项,private修饰符定义的属性及方法不能被子类实现,而抽象类的子类必须实现所有的抽象方法。两者冲突。 C选项,修饰符重复,而且没有定义数据类型。 D选项,正确

267、在 Java 中,属于整数类型变量的是() 答案: C

A、single
B、double
C、byte
D、char
解析:Java中的四类八种基本数据类型
第一类:整数类型 byte short int long
第二类:浮点型 float double
第三类:逻辑型 boolean(它只有两个值可取true false)

第四类:字符型 char

268、 下列说法正确的是()? 答案:B D

A、我们直接调用Thread对象的run方法会报异常,所以我们应该使用start方法来开启一个线程
B、一个进程是一个独立的运行环境,可以被看做一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序的单一进程。线程可以被称为轻量级进程。线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源
C、synchronized可以解决可见性问题,volatile可以解决原子性问题
D、ThreadLocal用于创建线程的本地变量,该变量是线程之间不共享的
解析:volatile与synchronized的区别:
volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.
volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.
volatile仅能实现变量的修改可见性,但不具备原子特性,而synchronized则可以保证变量的修改可见性和原子性.
volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.
volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化.

269、往OuterClass类的代码段中插入内部类声明, 哪一个是错误的: 答案:
public class OuterClass{
    private float f=1.0f;
    //插入代码到这里
}

A、

class InnerClass{
public static float func(){return f;}
}

B、

abstract class InnerClass{
public abstract float func(){}
}

C、

static class InnerClass{
protected static float func(){return f;}
}

D、

public class InnerClass{
 static float func(){return f;}
}

解析:主要考核了这几个知识点:
1.静态内部类才可以声明静态方法
2.静态方法不可以使用非静态变量
3.抽象方法不可以有函数体
2、1.为什么使用内部类?
使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,
对于内部类都没有影响
1.1.使用内部类最大的优点就在于它能够非常好的解决多重继承的问题,使用内部类还能够为我们带来如下特性:
(1)、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独。
(2)、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
(3)、创建内部类对象的时刻并不依赖于外围类对象的创建。
(4)、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
(5)、内部类提供了更好的封装,除了该外围类,其他类都不能访问。
2.内部类分类:
(一).成员内部类:

public class Outer{
		private int age = 99;
		String name = "Coco";
		public class Inner{
			String name = "Jayden";
			public void show(){
				System.out.println(Outer.this.name);
				System.out.println(name);
				System.out.println(age);
			}
		}
		public Inner getInnerClass(){
			return new Inner();
		}
		public static void main(String[] args){
			Outer o = new Outer();
			Inner in = o.new Inner();
			in.show();
		}
	}

1.Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,
如 public 、 protected 、 private 等
2.Inner 类中定义的 show() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,
如直接访问 Outer 类中的私有属性age
3.定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,
即:内部类 对象名 = 外部类对象.new 内部类( );
4.编译上面的程序后,会发现产生了两个 .class 文件: Outer.class,Outer$Inner.class{}
5.成员内部类中不能存在任何 static 的变量和方法,可以定义常量:
(1).因为非静态内部类是要依赖于外部类的实例,而静态变量和方法是不依赖于对象的,仅与类相关,
简而言之:在加载静态域时,根本没有外部类,所在在非静态内部类中不能定义静态域或方法,编译不通过;
非静态内部类的作用域是实例级别
(2).常量是在编译器就确定的,放到所谓的常量池了
★★友情提示:
1.外部类是不能直接使用内部类的成员和方法的,可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法;
2.如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,
可以使用 this 关键字,如:Outer.this.name
(二).静态内部类: 是 static 修饰的内部类,
1.静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
2.如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;
如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
3.创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名 = new 内部类();

public class Outer{
			private int age = 99;
			static String name = "Coco";
			public static class Inner{
				String name = "Jayden";
				public void show(){
					System.out.println(Outer.name);
					System.out.println(name);					
				}
			}
			public static void main(String[] args){
				Inner i = new Inner();
				i.show();
			}
		}

(三).方法内部类:其作用域仅限于方法内,方法外部无法访问该内部类
(1).局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的
(2).只能访问方法中定义的 final 类型的局部变量,因为:
当方法被调用运行完毕之后,局部变量就已消亡了。但内部类对象可能还存在,
直到没有被引用时才会消亡。此时就会出现一种情况,就是内部类要访问一个不存在的局部变量;
==>使用final修饰符不仅会保持对象的引用不会改变,而且编译器还会持续维护这个对象在回调方法中的生命周期.
局部内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,
自己内部的方法调用的实际是自己的属性而不是外部类方法的参数;
防止被篡改数据,而导致内部类得到的值不一致

   /*
		使用的形参为何要为 final???
		 在内部类中的属性和外部方法的参数两者从外表上看是同一个东西,但实际上却不是,所以他们两者是可以任意变化的,
		 也就是说在内部类中我对属性的改变并不会影响到外部的形参,而然这从程序员的角度来看这是不可行的,
		 毕竟站在程序的角度来看这两个根本就是同一个,如果内部类该变了,而外部方法的形参却没有改变这是难以理解
		 和不可接受的,所以为了保持参数的一致性,就规定使用 final 来避免形参的不改变
		 */
		public class Outer{
			public void Show(){
				final int a = 25;
				int b = 13;
				class Inner{
					int c = 2;
					public void print(){
						System.out.println("访问外部类:" + a);
						System.out.println("访问内部类:" + c);
					}
				}
				Inner i = new Inner();
				i.print();
			}
			public static void main(String[] args){
				Outer o = new Outer();
				o.show();
			}
		}    

(3).注意:在JDK8版本之中,方法内部类中调用方法中的局部变量,可以不需要修饰为 final,匿名内部类也是一样的,主要是JDK8之后增加了 Effectively final 功能

http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html

反编译jdk8编译之后的class文件,发现内部类引用外部的局部变量都是 final 修饰的

(四).匿名内部类:

(1).匿名内部类是直接使用 new 来生成一个对象的引用;

(2).对于匿名内部类的使用它是存在一个缺陷的,就是它仅能被使用一次,创建匿名内部类时它会立即创建一个该类的实例,
该类的定义会立即消失,所以匿名内部类是不能够被重复使用;
(3).使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口;
(4).匿名内部类中是不能定义构造函数的,匿名内部类中不能存在任何的静态成员变量和静态方法;
(5).匿名内部类中不能存在任何的静态成员变量和静态方法,匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法
(6).匿名内部类初始化:使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果

  public class OuterClass {
            public InnerClass getInnerClass(final int   num,String str2){
                return new InnerClass(){
                    int number = num + 3;
                    public int getNumber(){
                        return number;
                    }
                };        /* 注意:分号不能省 */
            }
            public static void main(String[] args) {
                OuterClass out = new OuterClass();
                InnerClass inner = out.getInnerClass(2, "chenssy");
                System.out.println(inner.getNumber());
            }
        }
        interface InnerClass {
            int getNumber();
        }          
270、在使用super和this关键字时,以下描述错误的是() 答案:B C D

A、在子类构造方法中使用super()显示调用父类的构造方法,super()必须写在子类构造方法的第一行,否则编译不通过
B、super()和this()不一定要放在构造方法内第一行
C、this()和super()可以同时出现在一个构造函数中
D、this()和super()可以在static环境中使用,包括static方法和static语句块
解析:super和this都只能位于构造器的第一行,而且不能同时使用,这是因为会造成初始化两次,this用于调用重载的构造器,super用于调用父类被子类重写的方法

2、1、super()表示调用父类构造函数、this()调用自己的构造函数,而自己的构造函数第一行要使用super()调用父类的构造函数,所以这俩不能在一个构造函数中会出现重复引用的情况
2、super()和this()必须在构造函数第一行,所以这一点也表明他俩不能在一个构造函数中
3、this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块(里面不能使用非static类型的)。

271、下列关于修饰符混用的说法,错误的是( ) 答案:D

A、abstract不能与final并列修饰同一个类
B、abstract 类中不建议有private的成员
C、abstract 方法必须在abstract类或接口中
D、static方法中能直接处理非static的属性
解析:A、abstract修饰的类,不可实例化,所以需要子类去继承,然后重写其中的抽象方法。但是final修饰类是不可继承的。两者属性相冲。
B、看清楚,人家说的是不建议有,不是不能有。
C、抽象类中可以没有抽象方法,但是抽象方法必须在抽象类中或者接口中
D、static不可以修饰非static的属性,因为类加载的时候,static属性比非static先初始化,那么一个存在的总不能访问一个没有存在的吧。

272、观察以下代码: 列哪些针对代码运行结果的描述是正确的? 答案:A
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、Car
B、Vehicle
C、Compiler error at line 3
D、Compiler error at line 5
解析:答案:A
首先final声明的方法是不能被覆盖的,但是这里并不错误,因为方法是private的,也就是子类没有继承父类的run方法,因此子类的run方法跟父类的run方法无关,并不是覆盖。new Car().run()也是调用子类的run方法。
2、此题的父类方法有private修饰,所以对子类不可见,子类不能覆盖。所以子类方法和父类是两个方法。
扩展:如果父类方法将private改为public 会怎样?
会报错,因为父类方法有final修饰,不能被覆盖。

273、下面这条语句一共创建了多少个对象:String s=“welcome”+“to”+360; 答案:A

A、1
B、2
C、3
D、4
解析:

String test="javaandpython"; 
String str1="java"; 
String str2="and"; 
String str3="python"; 
System. out. println(test=="java"+"and"+"python"): 
System. out. println(test ==str1 + str2 + str3);

对于上面这段代码,结果是true false
这是因为字符串字面量拼接操作是在Java编译器编译期间就执行了,也就是说编译器编译时,直接把"java"、“and"和"python"这三个字面量进行”+“操作得到一个"javaandpython” 常量,并且直接将这个常量放入字符串池中,这样做实际上是一种优化,将3个字面量合成一个,避免了创建多余的字符串对象(只有一个对象"javaandpython",在字符串常量池中)。而字符串引用的"+“运算是在Java运行期间执行的,即str1 + str2 + str3在程序执行期间才会进行计算,它会在堆内存中重新创建一个拼接后的字符串对象。且在字符串常量池中也会有str1,str2与str3,这里创建多少个新的对象与原来字符串常量池中有没有str1\str2\str3有关,如果之前存在就不会创建新的对象。
总结来说就是:字面量”+“拼接是在编译期间进行的,拼接后的字符串存放在字符串池中;而字符串引用的”+"拼接运算实在运行时进行的,新创建的字符串存放在堆中。
那么再来看这题,很明显只在编译期间在字符串常量池中创建了"welcometo360"一个字符串

274、Given the following code: 答案:B
public class Test {
    private static int j = 0;

    private static Boolean methodB(int k) {
        j += k;
        return true;
    }

    public static void methodA(int i) {
        boolean b;
        b = i < 10 | methodB(4);
        b = i < 10 || methodB(8);

    }

    public static void main(String args[]) {
        methodA(0);
        System.out.println(j);
    }
}

What is the result?
A、The program prints”0”
B、The program prints”4”
C、The program prints”8”
D、The program prints”12”
解析:在main函数中先调用methodA(0)

在methodA中,第二行

b = i < 10 | methodB(4); //中间为与计算符,执行完methodB(4)后,j = 4 

methodA中,第三行

b = i < 10 || methodB(8);//中间为或计算符,因为i < 10 已成立,不需要后续计算

所以最后结果输出为4

275、 以下代码可以使用的修饰符是:() 答案:A B D
public interface Status {
 /*INSERT CODE HERE*/  int MY_VALUE=10;
 }

A、final
B、static
C、abstract
D、public
解析:接口中字段的修饰符:public static final(默认不写)
接口中方法的修饰符:public abstract(默认不写)
2、ABD中的三个关键字在接口中的存在原因:
public:接口可以被其他接口继承,也可以被类实现,类与接口、接口与接口可能会形成多层级关系,采用public可以满足变量的访问范围;
static:如果变量不是static的,那么接口必须实例化才可以访问自己的变量,接口不能被实例化,故非static的变量是无效的;
final:如果变量不是final的,而方法是abstract的,因此接口中的方法又不可以修改变量值,虽然可以直接修改静态成员变量,但所有实现类对应的值都被修改了,此做法等同于抽象类,故需要final修饰成员变量;

276、java语言中,按照一定格式生成程序的文档的工具是? 答案:C

A、javac
B、javah
C、javadoc
D、jar
解析:

jar         将许多文件组合成一个jar文件
javac    编译
javadoc 它从程序源代码中抽取类、方法、成员等注释形成一个和源代码配套的API帮助文档。
javah 把java代码声明的JNI方法转化成C\C++头文件。 JNI可参考java核心技术卷二第12章
如
public class HelloNative {
    public static native void greeting();
}
使用javah后生成
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class javaTest_semaphore_HelloNative */


#ifndef _Included_javaTest_semaphore_HelloNative
#define _Included_javaTest_semaphore_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     javaTest_semaphore_HelloNative
 * Method:    greeting
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_javaTest_semaphore_HelloNative_greeting(JNIEnv *, jclass);


#ifdef __cplusplus
}
#endif
#endif
277、//中可以嵌套//注释,也能嵌套//注释。 答案:B

A、正确
B、错误
解析:在Java中规定,多行注释可以嵌套单行注释,但是不能嵌套多行注释。 不太能理解原因的朋友不妨这样想,如果多行注释/A//B/完全可以将内部的A//B作为普通字符串来理解,没有所谓单行不单行之说,所以可以嵌套单行注释。 但是如果是嵌套多行注释呢可以看看/A/B/C/,到编译器遇到多行注释的时候会以’/A/B/’来作为匹配的字符串,从而C/会被理解为程序语句,而C*/显然不符合程序语法,因此这样想就能理解为什么不能多行注释嵌套多行注释了

278、指出下列程序运行的结果: 答案:B
指出下列程序运行的结果:
public class Example{
    String str=new String("tarena");
    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、tarena and abc
B、tarena and gbc
C、test ok and abc
D、test ok and gbc
解析:string和char数组都是引用类型,引用类型是传地址的,会影响原变量的值,但是string是特殊引用类型,为什么呢?因为string类型的值是不可变的,为了考虑一些内存,安全等综合原因,把它设置成不可变的; 不可变是怎么实现的?Java在内存中专门为string开辟了一个字符串常量池,用来锁定数据不被篡改,所以题目中函数中的str变量和原来的str已经不是一个东西了,它是一个局部引用,指向一个testok的字符串,随着函数结束,它也就什么都没了,但是char数组是会改变原值的

279、下列程序的运行结果 答案:B
public static void main(String args[]) {
    Thread t = new Thread() {
        public void run() {
            pong();
        }
    };
    t.run();
    System.out.print("ping");
}
static void pong() {
    System.out.print("pong");
}

A、pingpong
B、pongping
C、pingpong和pongping都有可能
D、都不输出
解析:这里需要注意Thread的start和run方法
用start方法才能真正启动线程,此时线程会处于就绪状态,一旦得到时间片,则会调用线程的run方法进入运行状态。
而run方法只是普通方法,如果直接调用run方法,程序只会按照顺序执行主线程这一个线程。
2、在第7行的时候,调用的是t.run();方法,之间调用run方法就是普通的方法调用而已,所以肯定是先执行pong()再执行System.out.print(“ping”);
如果第7行换成t.start()方法,答案就应该选择c,因为t.start()后,线程变为就绪状态,什么时候开始执行时不确定的,可能是主程序先继续执行,也可能是新线程先执行。

280、在JAVA中,下列哪些是Object类的方法() 答案:B C D

A、synchronized()
B、wait()
C、notify()
D、notifyAll()
解析:A synchronized Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
B C D 都是Object类中的方法
notify(): 是唤醒一个正在等待该对象的线程。
notifyAll(): 唤醒所有正在等待该对象的线程。
E sleep 是Thread类中的方法

wait 和 sleep的区别:
wait指线程处于进入等待状态,形象地说明为“等待使用CPU”,此时线程不占用任何资源,不增加时间限制。
sleep指线程被调用时,占着CPU不工作,形象地说明为“占着CPU睡觉”,此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制。

281、为Test类的一个无形式参数无返回值的方法method书写方法头,使得使用类名Test作为前缀就可以调用它,该方法头的形式为( ) 答案:A

A、static void method()
B、public void method
C、protected void method()
D、abstract void method()
解析:A是静态方法,可以直接用如下形式调用 Test.method();
B是普通public方法,必须实例化类,Test test = new Test(); test.method();
C是protected方法,用法同B,只是对于其他的外部class,protected就变成private;
D是抽象方法,必须被子类继承并重写,然后调用的方式同B。

282、若有定义语句: int a=10 ; double b=3.14 ; 则表达式 ‘A’+a+b 值的类型是() 答案: C

A、char
B、int
C、double
D、float
解析:选C,double类型,因为按照类型大的与类型小的运算,强制转换类型小的进行运算的规则,double>int>char,因此结果是double类型。

283、Java 中,以下不是修饰符 final 作用的是( )。 答案:C

A、修饰常量
B、修饰不可被继承的类
C、修饰不可变类
D、修饰不可覆盖的方法
解析:final的作用:
1. 修饰变量,变量的引用地址不可变,但是地址中的内容可以变。
2. 修饰方法,方法不可被重写,但是还是可以重载
3. 修饰类,类不可继承。

不可变类,说的是一个类一旦被实例化,就不可改变自身的状态。常见的比如String和基本数据类型的包装类,对于这种不可变类,一旦在进行引用传递的时候,形参一开始就和实际参数指向的不是一个地址,所以在方法中对形参的改变,并不会影响实际参数。

284、以下程序会输出什么 答案:C
        int a =100,b=50,c=a---b,d=a---b;
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);

A、100 48 48 49
B、100 49 48 52
C、98 50 50 49
D、98 50 50 48
解析:我只想说。。加个括号能死啊。进公司写这种代码的人都肯定被同事打死Java运算符优先级

img

可知自增自减运算符优先级大于加减运算符的优先级

int a =100,b=50,c=a—b,d=a—b;

先考虑a–,a执行后自减操作,即先用a后再自减1,与–a先反

(1)c=a—b,先执行a-b操作,得到c=50,再执行a减1操作,得到a=99

(2)d=a—b,先执行a-b操作,得到d=49,再执行a减1操作,得到a=98

答案选C!

285、 假定Base b = new Derived(); 调用执行b.methodOne()后,输出结果是什么? 答案:A
public class Base
{
   public void methodOne()
   {
      System.out.print("A");
      methodTwo();
   }

   public void methodTwo()
   {
      System.out.print("B");
   }
}

public class Derived extends Base
{
   public void methodOne()
   {
      super.methodOne();
      System.out.print("C");
   }

   public void methodTwo()
   {
      super.methodTwo();
      System.out.print("D");
   }
}

A、ABDC
B、AB
C、ABCD
D、ABC
解析:只要是被子类重写的方法,不被super调用都是调用子类方法
2、这是一道类多态的向上转型题。

Base b = new Derived();

向上转型:父类只能调用父类方法或者子类覆写后的方法,而子类中的单独方法则是无法调用的。

因此:

调用的顺序是:(1)、(2)、(3)、(4)、(5)、(6)、(7) ; 得到的结果是:ABDC

class Base
{ public void methodOne()  // (3)
    {
        System.out.print("A");
        methodTwo();  //执行到这里的时候调用子类的覆盖方法 (4)
    } public void methodTwo() // (7)
    {
        System.out.print("B");
    }
} 
 class Derived extends Base { public void methodOne() // (1)
    { super.methodOne();   // (2)
        System.out.print("C");
    } public void methodTwo()  //该方法为重写了父类的方法 (5)
    { super.methodTwo(); //(6)
        System.out.print("D");
    }
}
286、下列关于继承的哪项叙述是正确的? 答案:D

A、在java中类允许多继承
B、在java中一个类只能实现一个接口
C、在java中一个类不能同时继承一个类和实现一个接口
D、java的单一继承使代码更可靠
解析:java为单继承,但可以实现多个接口
解析:Java是单继承,但是可以实现多个接口。
原因:为什么不能实现类的多继承?为了防止多个类中有相同的方法名,这个时候,子类不知道要重写哪一个方法,
但是接口可以有多个,因为接口没有方法体,无论重写哪一个,没有区别。

287、下面关于静态方法说明正确的是 答案:B

A、在静态方法中可用this来调用本类的类方法
B、在静态方法中调用本类的静态方法时可直接调用
C、在静态方法中只能调用本类中的静态方法
D、在静态方法中绝对不能调用实例方法
解析:A.静态成员随类的加载而加载,这个时候对象都还没有,this代表当前对象,所以this不能用于static方法中.C还可以调用静态变量D.可以通过对象.进行调用
A:不能使用this调用本类的类方法(即静态方法);具体原理不清楚(望指点),个人理解为this指向的是实例对象,此时未实例化,故不能使用
B: 正确
C:在静态方法中,不只可以调用本类的静态方法,也可以使用【类名.静态方法名】调用其他类的静态方法
D:可以调用实例方法,使用【new 类名().实例方法名】调用

288、下面关于volatile的功能说法正确的是哪个 答案:B C

A、原子性
B、有序性
C、可见性
D、持久性
解析:synchronized保证三大性,原子性,有序性,可见性,volatile保证有序性,可见性,不能保证原子性volatile到底做了什么:
禁止了指令重排
保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量值,这个新值对其他线程是立即可见的
不保证原子性(线程不安全)
synchronized关键字和volatile关键字比较:
volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。
多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞
volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。
volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。

289、 下面HttpServletResponse方法调用,那些给客户端回应了一个定制的HTTP回应头:( )答案: A B

A、response.setHeader(“X-MyHeader”, “34”);
B、response.addHeader(“X-MyHeader”, “34”);
C、response.setHeader(new HttpHeader(“X-MyHeader”, “34”));
D、response.addHeader(new HttpHeader(“X-MyHeader”, “34”));
解析:1、同名Header可以有多个 ,Header[] getHeaders(String name)。
2、运行时使用的是第一个, Header getFirstHeader(String name)。
3、addHeader,如果同名header已存在,则追加至原同名header后面。
4、setHeader,如果同名header已存在,则覆盖一个同名header。
2、

img

HttpServletResponse(接口)就只是提供了这么几个方法声明来设置响应头的数据。
290、关于Java中的数组,下面的一些描述,哪些描述是准确的:( ) 答案: A C F

A、数组是一个对象,不同类型的数组具有不同的类
B、数组长度是可以动态调整的
C、数组是一个连续的存储结构
D、一个固定长度的数组可类似这样定义: int array[100]
E、两个数组用equals方法比较时,会逐个便利其中的元素,对每个元素进行比较
F、可以二维数组,且可以有多维数组,都是在Java中合法的

解析:我是错在E选项了 所以分析一下 给后人填坑

img

数组是一种引用数据类型 那么他肯定是继承Object类的 所以里面有equals() 方法 但是肯定没有重写过 因为他并不是比较数组内的内容

使用Arrays.equals() 是比较两个数组中的内容。

291、哪个关键字可以对对象加互斥锁?() 答案:A

A、synchronized
B、volatile
C、serialize
D、static
解析:synchronized关键字是同步代码块关键字,对对象加互斥锁
A:
synchronized 关键字 : 用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。
volatile:用来确保将变量的跟新操作通知到其他线程,当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。然而,在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比 synchronized关键字更轻量级的同步机制。
serialize:Java 对象序列化为二进制文件。
static关键字: static关键字可以修饰变量,方法,静态代码块。
静态变量:
由static修饰的变量称为静态变量
静态变量属于类,而不属于某个对象
静态变量它的副本只有一个(静态变量在类中只加载一)
静态方法:
在静态方法中只能调用静态变量和静态方法
在非静态方法中,可以调用静态方法或者变量。
在静态方法中不能使用this和super关键字。
静态代码块
作用:用来给静态成员变量初始化

292、 java语言的下面几种数组复制方法中,哪个效率最高? 答案:B

A、for 循环逐一复制
B、System.arraycopy
C、Array.copyOf
D、使用clone方法
解析:看了几个评论,你们会就好好回答,不会就别复制别人错误答案耽误别人好吧? 复制的效率System.arraycopy>clone>Arrays.copyOf>for循环,这个有兴趣自己测试一下就知道了。这里面在System类源码中给出了arraycopy的方法,是native方法,也就是本地方法,肯定是最快的。而Arrays.copyOf(注意是Arrays类,不是Array)的实现,在源码中是调用System.copyOf的,多了一个步骤,肯定就不是最快的。前面几个说System.copyOf的不要看,System类底层根本没有这个方法,自己看看源码就全知道了。

293、对下面Spring声明式事务的配置含义的说明错误的是() 答案:C
<bean id="txProxyTemplate" abstract="true"
class=
"org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="myTransactionManager" />
<property name="transactionAttributes">      
 <props>
        <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
         <prop key="*">PROPAGATION_REQUIRED</prop>
     </props>
</property> 
</bean>

A、定义了声明式事务的配置模板
B、对get方法采用只读事务
C、缺少sessionFactory属性的注入
D、配置需要事务管理的bean的代理时,通过parent引用这个配置模板,代码如下:

<bean id="petBiz" parent="txProxyTemplate">
         <property name="target" ref="petTarget"/>
</bean>

解析:皇上作为对象,太监作为IOC容器,当皇上要挑选妃子晚上睡觉的时候,不用管,只要到床上即可。太监则根据皇上喜好(找到对应依赖或其他对象),找到对应的妃子送到皇上榻上。 看过一篇文章这样写到
2、1.Spring本身并不直接管理事务,而是提供了事务管理器接口,对于不同的框架或者数据源则用不同的事务管理器;而对于事务,它把相关的属性都封装到一个实体里边去,有以下的属性:

    int propagationBehavior;    /*事务的传播行为*/
    int isolationLevel;                /*事务隔离级别*/
    int timeout;                            /*事务完成的最短时间*/
    boolean readOnly;                /*是否只读*/

Spring提供了对编程式事务和声明式事务的支持,编程式事务是嵌在业务代码中的,而声明式事务是基于xml文件配置。

  1. readOnly – 事务隔离级别,表示只读数据,不更新数据

    3.PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 
    PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。 
    PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 
    PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 
    PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 
    PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
    
294、 下面哪些具体实现类可以用于存储键,值对,并且方法调用提供了基本的多线程安全支持:() 答案:A E

A、java.util.ConcurrentHashMap
B、java.util.Map
C、java.util.TreeMap
D、java.util.SortMap

E、java.util.Hashtable

解析:线程安全的map:HashTable,*SynchronizedMap,**ConcurrentHashMap***
Hashtable的方法都是synchrnized修饰的线程安全,ConcurrentHashMap并发容器,JDK7采用分段锁,JDK8采用CAS算法,线程安全,建议使用,Connections工具类提供了一个方法synchrnizedMap可以把Map同步,本质就是给每一个方法加上synchrnized关键字进行同步

295、A,B,C,D 中哪些是 setvar的重载? 答案:A C D
public class methodover
{
    public void setVar(int a, int b, float c) {}
}

A、private void setVar(int a, float c, int b){}
B、protected void setVar(int a, int b, float c){}
C、public int setVar(int a, float c, int b){return a;}
D、public int setVar(int a, float c){return a;}
解析:ACD

重载是在同一个类中,有多个方法名相同,参数列表不同(参数个数不同,参数类型不同),与方法的返回值无关,与权限修饰符无关,B中的参数列表和题目的方法完全一样了。
2、方法的重载是指:
1、在同一个类中
2、方法名相同
3、方法的形参列表不同
具体的不同表现为:
类型、个数、顺序的不同才可以构成重载
4、#比较容易忽略的一点#
与方法的返回值类型与访问权限无关

296、定义:String s1 = “uml”; String s2 = “uml”; String s3= new String(“uml”); String s4= new String(“uml”);那么,s1==s2;s3 == s4;s1.equals(s3); 判断正确与否 答案: A

A、T,F,T
B、F,T,F
解析:该题考察的是String类创建的对象在JVM中的内存分配和**“equals”与“==”的区别**。

  • “==”比较的是地址和值
  • “equals”比较的是
  • img
  • s1==s2,比较的是比较的是地址和值,由上图得知两个引用指向的是同一个地址,所以返回true.
  • s3 == s4,比较的是两个new出来开辟的空间对象地址,所以值相同,但地址不同,返回false.
  • s1.equals(s3),比较的是内容,返回true
297、 答案:A
//point X
public class Foo {
    public static void main(String[] args) throws Exception {

        PrintWriter out = new PrintWriter(
                new java.io.OutputStreamWriter(System.out), true);
        out.println("Hello");
    }

}
下面哪个选项放在point X这里可以正确执行?

A、import java.io.PrintWriter;
B、include java.io.PrintWriter;
C、import java.io.OutputStreamWriter;
D、include java.io.OutputStreamWriter;
解析:java中没有include关键字,导包用import
由于代码中使用了printWriter 类,所以要导入此类Import java.io.PrintWriter;
2、思路:
首先排除include和最后一个
其次:
1.PrintWriter
2.OutputStreamWriter
注意:
在创建OutputStreamWriter的时候,使用的是类的全名称。所以不需要使用import
故:选择A

298、在java中,下列对继承的说法,正确的是( ) 答案:A

A、子类能继承父类的所有成员
B、子类继承父类的非私有方法和状态
C、子类只能继承父类的public方法和状态
D、子类只能继承父类的方法
解析:使用反射可以看出子类是继承了父类的私有方法的(不管是否是final),只是直接调用父类的私有方法是不可以的,但是利用反射的方式可以调用。字段同理。

package work.litao;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
class Parent{
    Parent() {
        System.out.println("调用父类构造方法!");
    }
    private static void staticParent() {
        System.out.println("调用父类静态方法");
    }
    private final  void finalParent() {
        System.out.println("调用父类final方法");
    }
    private void printParent(){
        System.out.println("调用父类私有方法");
    }
}
class Child extends Parent {
    public void printChild(){
        System.out.println("调用子类公有方法");
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        //获取子类
        Class clazz = Class.forName("work.litao.Child");
        //得到父类
        Class superClass = clazz.getSuperclass();
        //得到父类非继承的所以方法
        Method[] methods = superClass.getDeclaredMethods();
        //设置私有方法可以被访问
        AccessibleObject.setAccessible(methods,true);
        for (Method m:methods) {
            System.out.println();
            System.out.println("子类调用方法"+m.getName()+"()的调用结果:" );
            m.invoke(new Child());
        }

    }
}

运行结果:

img

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass. [子类从其父类继承所有成员(字段,方法和嵌套类)。 构造函数不是成员,所以它们不被子类继承,但是可以从子类调用超类的构造函数。]

来自Oracle官方文档https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

299、以下哪些继承自 Collection 接口() 答案: A B

A、List
B、Set
C、Map
D、Array
解析:集合常考点:

img

300、 对于线程局部存储TLS(thread local storage),以下表述正确的是 答案:A B D

A、解决多线程中的对同一变量的访问冲突的一种技术
B、TLS会为每一个线程维护一个和该线程绑定的变量的副本
C、每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了
D、Java平台的java.lang.ThreadLocal是TLS技术的一种实现
解析:ABD

C:同一全局变量或者静态变量每个线程访问的是同一变量,多个线程同时访存同一全局变量或者静态变量时会导致冲突,尤其是多个线程同时需要修改这一变量时,通过TLS机制,为每一个使用该全局变量的线程都提供一个变量值的副本,每一个线程均可以独立地改变自己的副本,而不会和其它线程的副本冲突。
2、 ThreadLocal可以给一个初始值,而每个线程都会获得这个初始化值的一个副本,这样才能保证不同的线程都有一份拷贝。ThreadLocal 不是用于解决共享变量的问题的,不是为了协调线程同步而存在,而是为了方便每个线程处理自己的状态而引入的一个机制.

301、关于下面程序 ThisTest .java 运行结果 说法正确的是 : ( ) 答案: B
public class ThisTest {
    		public static void main(String args[]) {
        		String x="7";       
    	int y = 2;
        		int z=2;              
        System.out.println(x+y+z); 
    		}  
}

A、11
B、722
C、22
D、程序有编译错误
解析:img

302、下面哪种情况会导致持久区jvm堆内存溢出? 答案: C

A、循环上万次的字符串处理
B、在一段代码内申请上百M甚至上G的内存
C、使用CGLib技术直接操作字节码运行,生成大量的动态类
D、不断创建对象
解析:建议看看这篇博客 入门 通俗易懂 http://blog.csdn.net/sivyer123/article/details/17139443
简单的来说 java的堆内存分为两块:permantspace(持久带) 和 heap space。
持久带中主要存放用于存放静态类型数据,如 Java Class, Method 等, 与垃圾收集器要收集的Java对象关系不大。
而heapspace分为年轻带和年老带
年轻代的垃圾回收叫 Young GC, 年老代的垃圾回收叫 Full GC。
在年轻代中经历了N次(可配置)垃圾回收后仍然存活的对象,就会被复制到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象
年老代溢出原因有 循环上万次的字符串处理、创建上千万个对象、在一段代码内申请上百M甚至上G的内存,既A B D选项
持久代溢出原因 动态加载了大量Java类而导致溢出

303、What is the result of compiling and executing the following fragment of code: 答案:C
Boolean flag = false;
if (flag = true)
{
    System.out.println("true");
}
else
{
    System.out.println("false");
}

A、The code fails to compile at the “if” statement.
B、An exception is thrown at run-time at the “if” statement.
C、The text“true” is displayed.
D、The text“false”is displayed.
解析:Boolean修饰的变量为包装类型,初始化值为false,进行赋值时会调用Boolean.valueOf(boolean b)方法自动拆箱为基本数据类型,因此赋值后flag值为true,输出文本true。 如果使用==比较,则输出文本false。if的语句比较,除boolean外的其他类型都不能使用赋值语句,否则会提示无法转成布尔值。
2、

304、String与StringBuffer的区别是? 答案:A B

A、String是不可变的对象,StringBuffer是可以再编辑的
B、字符串是常量,StringBuffer是变量
C、String是可变的对象,StringBuffer是不可以再编辑的
D、以上说法都不正确
解析:String, StringBuffer,StringBuilder的区别

java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题。现在总结一下,看看他们的不同与相同。

1.可变与不可变

String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。

private final char value[];

String 为不可变对象,一旦被创建,就不能修改它的值. . 对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.

StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。

char[] value;

StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象 , 它只能通过构造函数来建立, 如: StringBuffer sb = new StringBuffer();

不能通过赋值符号对他进行付值. sb = “welcome to here!”;//error**
**对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer中赋值的时候可以通过它的append方法. sb.append(“hello”);

2.是否多线程安全

String中的对象是不可变的,也就可以理解为常量, 显然线程安全

AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。

StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是 线程安全的 。看如下源码:

1   public   synchronized  StringBuffer reverse() {

2       super .reverse();

3       return   this ;

4  }

5  

6   public   int  indexOf(String str) {

7       return  indexOf(str, 0);         //存在 public synchronized int indexOf(String str, int fromIndex) 方法

8  }

StringBuilder并没有对方法进行加同步锁,所以是 非线程安全的

3.StringBuilder与StringBuffer共同点

StringBuilder与StringBuffer有公共父类AbstractStringBuilder( 抽象类 )。

抽象类与接口的其中一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。

StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(…)。只是StringBuffer会在方法上加synchronized关键字,进行同步。

最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。

效率比较String < StringBuffer < StringBuilder,但是在String S1 =“This is only a”+“simple”+“test”时,String效率最高。
2、String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
String 类代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都是String类的对象。字符串是常量;它们的值在创建之后不能改变。所以可以共享它们。StringBuffer是字符串缓存区,它的内容可以被修改,长度也可以改变,StringBuffer类是线程安全的,也就是说多个线程可以安全的访问StringBuffer对象。StringBuilder与StringBuffer类似,都是字符串缓冲区,但StringBuilder不是线程安全的,如果你只是在单线程中使用字符串缓冲区,那么StringBuilder的效率会更高些。值得注意的是StringBuilder是在JDK1.5版本中增加的。以前版本的JDK不能使用该类。

305、关于Java的一些概念,下面哪些描述是正确的:( ) 答案:B F

A、所有的Java异常和错误的基类都是java.lang.Exception, 包括java.lang.RuntimeException
B、通过try … catch … finally语句,finally中的语句部分无论发生什么异常都会得到执行
C、java中所有的数据都是对象
D、Java通过垃圾回收回收不再引用的变量,垃圾回收时对象的finallize方法一定会得到执行

E、ava是跨平台的语言,无论通过哪个版本的Java编写的程序都能在所有的Java运行平台中运行
F、Java通过synchronized进行访问的同步,synchronized作用非静态成员方法和静态成员方法上同步的目标是不同的
解析:A、java异常和错误的基类Throwable,包括Exception和Error
B、try…catch…finally finally不管什么异常都会执行
C、java是面向对象的,但是不是所有的都是对象,基本数据类型就不是对象,所以才会有封装类的;
D、如果是等待清理队列中如果又被调用,则不会执行finallize方法
E、JAVA跨平台性 实现在任意平台的java程序都可以在其他平台运行
F、synchronized实现方式:三种
2、A.错误(Error)的基类是Throwable
C.基本类型不是对象
D.垃圾回收器并不总是工作,只有当内存资源告急时,垃圾回收器才会工作;即使垃圾回收器工作,finalize方法也不一定得到执行,这是由于程序中的其他线程的优先级远远高于执行finalize()函数线程的优先级。(这是楼下的答案)
E.低版本JRE无法运行高版本JRE

306、java 中哪个关键字可以对对象加互斥锁? 答案: B

A、transient
B、synchronized
C、serialize
D、static
解析:选 B: synchronized
synchronized 关键字 : 用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。
volatile:用来确保将变量的跟新操作通知到其他线程,当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。然而,在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比 synchronized关键字更轻量级的同步机制。
serialize:Java 对象序列化为二进制文件。
static关键字: static关键字可以修饰变量,方法,静态代码块。
静态变量:
由static修饰的变量称为静态变量
静态变量属于类,而不属于某个对象
静态变量它的副本只有一个(静态变量在类中只加载一)
静态方法:
在静态方法中只能调用静态变量和静态方法
在非静态方法中,可以调用静态方法或者变量。
在静态方法中不能使用this和super关键字。
静态代码块
作用:用来给静态成员变量初始化

307、以下是java concurrent包下的4个类,选出差别最大的一个 答案:C

A、Semaphore
B、ReentrantLock
C、Future
D、CountDownLatch
解析:A、Semaphore:类,控制某个资源可被同时访问的个数;
B、ReentrantLock:类,具有与使用synchronized方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大;
C、 Future:接口,表示异步计算的结果;
D、 CountDownLatch: 类,可以用来在一个线程中等待多个线程完成任务的类。

308、以下哪一项正则能正确的匹配网址: http://www.bilibili.com/video/av21061574 () 答案:B

A、/^(https?😕/)?([a-zA-Z\d]+).bilibili.com/?video/av(\D{1,8})/?KaTeX parse error: Undefined control sequence: \/ at position 13: / B、/^(http:\̲/̲\/)?(\w+)\.bili…/
C、/^(https?😕/)?(\w+).bilibili.com/?\w*KaTeX parse error: Undefined control sequence: \/ at position 13: / D、/^(http:\̲/̲\/)?([a-zA-Z\d]…/
解析:楼上的回答有点问题,我来简单的梳理一下这道题用到的正则表达式的知识点:
首先,^表示匹配输入的开始,$表示匹配输入的结束
每个选项从前向后看,http都能够严格匹配
?表示匹配某元素0次或1次,这里四个选项都没有问题,能够匹配0次或1次字符s
接下来:严格匹配,//严格匹配两个//
接着往下看,[]表示字符集合,它用在正则表达式中表示匹配集合中的任一字符
A D 选项中的 [a-zA-Z\d] 表示匹配一个小写字母 或者 大写字母 或者 数字
B C 选项中的 \w 表示匹配字母数字或下划线(注意这里比A D中能多匹配下划线类型)
+表示匹配某元素1次或多次,到这里四个选项都能够完美匹配字符www
.可以匹配除了换行符\n \r外的任何字符
接下来我们看选项A,bilibili com video av都严格匹配,而 \D 表示匹配一个非数字字符而非数字字符,av后的数字是无法匹配成功的,A错误
B选项,\d匹配数字,{m,n}表示最少匹配m次,最多匹配n次,/?能匹配末尾的0个或1个/字符,B正确
C选项,*表示匹配某元素0次或多次,但 \w 并不能匹配字符 /,C错误
D选项,前面都对,错在最后的/+至少要匹配一个/,而原字符串最后并没有/img

309、下面哪个不属于HttpServletResponse接口完成的功能? 答案:C

A、设置HTTP头标
B、设置cookie
C、读取路径信息
D、输出返回数据
解析:A:设置HTTP头标

response.setHeader("Refresh","3"); //三秒刷新页面一次

B:设置cookie

Cookie c1 = new Cookie("username","only");
response.addCookie(c1);

C(错误):读取路径信息,request读取路径信息

从request获取各种路径总结 
request.getRealPath("url"); // 虚拟目录映射为实际目录
request.getRealPath("./");    // 网页所在的目录
request.getRealPath("../"); // 网页所在目录的上一层目录
request.getContextPath();    // 应用的web目录的名称

D:输出返回数据

复制代码

HttpServleteResponse.getOutputStream().write();
310、以下说法错误的是() 答案: B C D

A、其他选项均不正确
B、java线程类优先级相同
C、Thread和Runnable接口没有区别
D、如果一个类继承了某个类,只能使用Runnable实现线程
解析:B选项,在java中线程是有分优先等级的所以优先级不能相同,错误
C选项,Thread实现了Runnable接口是一个类不是接口,错误
D选项,实现多线程的三种方式,一种是继承Thread类使用此方式就不能继承其他的类了。还有两种是实现Runnable接口或者实现Callable接口
,所以D错误。
A选项,综上A说其余三项都是错误的,所以A选项所述为真,不是错误的。

311、在程序代码中写的注释太多,会使编译后的程序尺寸变大。 答案:B

A、正确
B、错误
解析:javadoc 用来识别注释
javac 用来识别代码
二者互不影响

312、定义如下程序 答案:D
public static void main(String[] args){
    Double x=1.2;  
    long l = 1.2;  
    float f =  x/l;
    System.out.println(f);
}

程序执行结果是? ()
A、1
B、1f
C、运行报错
D、编译报错
解析:这是java的题,高精度类型得到低精度结果需要进行强转
2、从double 到float会丢失数据,在发生强转的时候

313、下列哪个对访问修饰符作用范围由大到小排列是正确的? 答案:D

A、private>default>protected>public
B、public>default>protected>private
C、private>protected>default>public
D、public>protected>default>private
解析:D public可以被当前类,子类,包,其他包,访问,
protected 可以被当前类,子类,包访问
default可以被可以被当前类,包内访问;
private只能被当前类访问img

314、对于如下代码段 答案:C
class A{
    public A foo() {
        return this;
    }
}
class B extends A {
    public A foo(){
        return this;
    }
}
class C extends B {
    _______

}

可以放入到横线位置,使程序正确编译运行,而且不产生错误的选项是( )
A、public void foo(){}
B、public int foo(){return 1;}
C、public A foo(B b){return b;}
D、public A foo(){return A;}
解析:重写 要求两同两小一大原则, 方法名相同,参数类型相同,子类返回类型小于等于父类方法返回类型, 子类抛出异常小于等于父类方法抛出异常, 子类访问权限大于等于父类方法访问权限。[注意:这里的返回类型必须要在有继承关系的前提下比较]

重载 方法名必须相同,参数类型必须不同,包括但不限于一项,参数数目,参数类型,参数顺序
再来说说这道题 A B 都是方法名和参数相同,是重写,但是返回类型没与父类返回类型有继承关系,错误 D 返回一个类错误 c的参数类型与父类不同,所以不是重写,可以理解为广义上的重载访问权限小于父类,都会显示错误
虽然题目没点明一定要重载或者重写,但是当你的方法名与参数类型与父类相同时,已经是重写了,这时候如果返回类型或者异常类型比父类大,或者访问权限比父类小都会编译错误

315、以下哪些jvm的垃圾回收方式采用的是复制算法回收 答案:A D

A、新生代串行收集器
B、老年代串行收集器
C、并行收集器
D、新生代并行回收收集器
E、老年代并行回收收集器
F、cms收集器
解析:两个最基本的java回收算法:复制算法和标记清理算法
复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。此为新生代最常用的算法
标记清理:一块区域,标记可达对象(可达性分析),然后回收不可达对象,会出现碎片,那么引出
标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象
两个概念:新生代和年老代
新生代:初始对象,生命周期短的
永久代:长时间存在的对象
整个java的垃圾回收是新生代和年老代的协作,这种叫做分代回收。
P.S:Serial New收集器是针对新生代的收集器,采用的是复制算法
Parallel New(并行)收集器,新生代采用复制算法,老年代采用标记整理
Parallel Scavenge(并行)收集器,针对新生代,采用复制收集算法
Serial Old(串行)收集器,新生代采用复制,老年代采用标记整理
Parallel Old(并行)收集器,针对老年代,标记整理
CMS收集器,基于标记清理
G1收集器:整体上是基于标记 整理 ,局部采用复制

综上:新生代基本采用复制算法,老年代采用标记整理算法。cms采用标记清理。

316、下列哪个修饰符可以使在一个类中定义的成员变量只能被同一包中的类访问? 答案:B

A、private
B、无修饰符
C、public
D、protected
解析:B

名称说明备注
public可以被任何类访问
protected可以被同一包中的所有类访问可以被所有子类访问子类没有在同一包中也可以访问
private只能够被 当前类的方法访问
缺省无访问修饰符可以被同一包中的所有类访问如果子类没有在同一个包中,也不能访问
317、下面的程序 编译运行后,在屏幕上显示的结果是() 答案:A
public class Test {

    public static void main(String args[]) {
        int x, y;
        x = 5 >> 2;
        y = x >>> 2;
        System.out.println(y);
    }
}

A、0
B、2
C、5
D、80
解析:5 >> 2 相当于 5除于2的平方,等于1 ,>>> 表示无符号 右移,高位用0 填充,0001 右移两位 0000,所以答案选 A
2、5的二进制是0101。
x=5>>2 (>>带符号右移)

将0101右移2位,为:0001。
y=x>>>2 (>>>无符号右移,左边空缺补充为0)

将0001右移2位,补0。结果为:0000。

所以得出答案0

这道题首先要知道二进制的计算方式
举例:0011
二进制换算十进制,从右到左,以当前位数字 乘以 2 的索引字幂,然后相加,索引从0开始计算。
如:
右一数字为1,索引为0。所以为:1*2^0(1乘以2的0次方)

右二数字为1,索引为1。所以为:1*2^1(1乘以2的1次方)

右三数字为0,索引为2。所以为:0*2^2(0乘以2的2次方)

右四数字为0,索引为3。所以为:0*2^3(0乘以2的3次方)

最后把结果相加。所以计算方式为:

023+0*22+121+1*20

=0+0+2+1

=3

318、给定以下JAVA代码,这段代码运行后输出的结果是() 答案:B
public class Test
{  
    public static int aMethod(int i)throws Exception
    {
        try{
            return i/10;
        }
        catch (Exception ex)
        {
            throw new Exception("exception in a aMethod");
        }finally{
      System.out.printf("finally");
        }
} 
    public static void main(String[] args){
        try
        {
            aMethod(0);
        }
        catch (Exception ex)
        {
            System.out.printf("exception in main");
        }
        System.out.printf("finished");
    }
}

A、exception in main finished
B、finallyfinished
C、exception in main finally
D、finally exception in main finally
解析:进入main方法->try->aMethod(0)->return 0/10;这里注意并没有出现异常所以执行finally打印finally,返回的时候也并没有异常,所以不会打印exception in main然后按照顺序执行然后打印finished,希望被采纳。
2、i在上面,不在下面。。。审题要仔细

319、ArrayLists和LinkedList的区别,下述说法正确的有? 答案: A B C D

A、ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
B、对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要迭代器。
C、对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。
D、ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间。
解析:A. ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 //正确,这里的所谓动态数组并不是那个“ 有多少元素就申请多少空间 ”的意思,通过查看源码,可以发现,这个动态数组是这样实现的,如果没指定数组大小,则申请默认大小为10的数组,当元素个数增加,数组无法存储时,系统会另个申请一个长度为当前长度1.5倍的数组,然后,把之前的数据拷贝到新建的数组。

B. 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。//正确,ArrayList是数组,所以,直接定位到相应位置取元素,LinkedLIst是链表,所以需要从前往后遍历

C. 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。//正确,ArrayList的新增和删除就是数组的新增和删除,LinkedList与链表一致。

D. ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间。//正确,因为ArrayList空间的增长率为1.5倍,所以,最后很可能留下一部分空间是没有用到的,因此,会造成浪费的情况。对于LInkedList的话,由于每个节点都需要额外的指针,所以,你懂的。

320、关于Java中的ClassLoader下面的哪些描述是错误的:( ) 答案:B D F

A、默认情况下,Java应用启动过程涉及三个ClassLoader: Boostrap, Extension, System
B、一般的情况不同ClassLoader装载的类是不相同的,但接口类例外,对于同一接口所有类装载器装载所获得的类是相同的
C、类装载器需要保证类装载过程的线程安全
D、ClassLoader的loadClass在装载一个类时,如果该类不存在它将返回null
E、ClassLoader的父子结构中,默认装载采用了父优先
F、所有ClassLoader装载的类都来自CLASSPATH环境指定的路径
解析:A.Java系统提供3种类加载器:启动类加载器(Bootstrap ClassLoader) 扩展类加载器(Extension ClassLoader) 应用程序类加载器(Application ClassLoader). A正确
B.《深入理解Java虚拟机》P228:对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间。这句话可以表达得更通俗一些:比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个Class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那么这两个类必定不相等。接口类是一种特殊类,因此对于同一接口不同的类装载器装载所获得的类是不相同的。B错误
C.类只需加载一次就行,因此要保证类加载过程线程安全,防止类加载多次。C正确
D. Java程序的类加载器采用双亲委派模型,实现双亲委派的代码集中在java.lang.ClassLoader的loadClass()方法中,此方法实现的大致逻辑是:先检查是否已经被加载,若没有加载则调用父类加载器的loadClass()方法,若父类加载器为空则默认使用启动类加载器作为父类加载器。如果父类加载失败,抛出ClassNotFoundException异常。D错误
E.双亲委派模型的工作过程:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。E正确
F.应用程序类加载器(Application ClassLoader)负责加载用户类路径(ClassPath)上所指定的类库,不是所有的ClassLoader都加载此路径。F错误

321、在Java中,什么是Garbage Collection?() 答案:

A、自动删除在程序中导入但未使用的任何包
B、JVM检查任何Java程序的输出并删除任何没有意义的东西
C、当对象的所有引用都消失后,对象使用的内存将自动回收
D、操作系统定期删除系统上可用的所有java文件
解析:完蛋,只知道GC不知道GC的全程是什么😂
2、这道题C的描述也有问题吧,就是“当对象的所有引用都消失”有问题,gc回收的是不能和gc roots引用链连接的对象。这道题的歧义在于:如果两个对象之间有循环依赖,但是又不在引用链上,还是会回收的。

322、如果一个list初始化为{5,3,1},执行以下代码后,其结果为()? 答案:B
nums.add(6);
nums.add(0,4);
nums.remove(1);

A、[5, 3, 1, 6]
B、[4, 3, 1, 6]
C、[4, 3, 6]
D、[5, 3, 6]
解析:list{5,3,1}
nums.add(6); //往后边加一个6,{5,3,1,6}
nums.add(0,4);//往下标为0的数加一个4,{4,5,3,1,6}
nums.remove(1); // 移除下标为1 的元素,{4,3,1,6}

323、java如何返回request范围内存在的对象? 答案:B

A、request.getRequestURL()
B、request.getAttribute()
C、request.getParameter()
D、request.getWriter()
解析:request.getAttribute()方法返回request范围内存在的对象,而request.getParameter()方法是获取http提交过来的数据。getAttribute是返回对象,getParameter返回字符串。
equest.getParameter()方法传递的数据,会从Web客户端传到Web服务器端,代表HTTP请求数据;request.setAttribute()和getAttribute()方法传递的数据只会存在于Web容器内部,在具有转发关系的Web组件之间共享。
request域代表一次请求处理的过程,就是从客户端到服务端的一次请求的过程。 request.getParameter()获取HTTP提交过来的数据。
而request.getAttribute()方法返回reques,sessiont范围内存在的对象

324、一般情况下,以下哪个选项不是关系数据模型与对象模型之间匹配关系? 答案: D

A、表对应类
B、记录对应对象
C、表的字段对应类的属性
D、表之间的参考关系对应类之间的依赖关系
解析:一般关系数据模型和对象数据模型之间有以下对应关系:表对应类,记录对应对象,表的字段对应类的属性
2、目前ORMapping只是规定了数据结构和数据集的映射关系,还没到规定赖关系的阶段

325、下面的Java赋值语句哪些是有错误的 () 答案:B F

A、int i =1000;
B、float f = 45.0;
C、char s = ‘\u0639’;
D、Object o = ‘f’;
E、String s = “hello,world\0”;
F、Double d = 100;

解析:ifg头像ifg
b:小数如果不加 f 后缀,默认是double类型。double转成float向下转换,意味着精度丢失,所以要进行强制类型转换。
c:是使用unicode表示的字符。
d:‘f’ 字符会自动装箱成包装类,就可以向上转型成Object了。
f:整数默认是int类型,int类型不能转型为Double,最多通过自动装箱变为Integer但是Integer与Double没有继承关系,也没法进行转型。

326、对于以下代码段,4个输出语句中输出true的个数是( )。 答案:C
class A{}

class B extends A{}

class C extends A{}

class D extends B{}

A obj = new D();

System.out.println(obj instanceof B);

System.out.println(obj instanceof C);

System.out.println(obj instanceof D);

System.out.println(obj instanceof A);

A、1
B、2
C、3
D、4
解析: A
| |
B C
|
D
D属于B,D属于A,D属于D,D不属于C
2、instanceof是判断前者是否可以类型可以转化为后者,可以转化即为true,分为向上转型和向下转型B D都是A的子类向下转型,C直接继承自A,obj的实际类型为D,和C没有关系。所以obj instanceof C 输出false。

img

327、子类A继承父类B, A a = new A(); 则父类B构造函数、父类B静态代码块、父类B非静态代码块、子类A构造函数、子类A静态代码块、子类A非静态代码块 执行的先后顺序是? 答案:C

A、父类B静态代码块->父类B构造函数->子类A静态代码块->父类B非静态代码块->子类A构造函数->子类A非静态代码块
B、父类B静态代码块->父类B构造函数->父类B非静态代码块->子类A静态代码块->子类A构造函数->子类A非静态代码块
C、父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A构造函数
D、父类B构造函数->父类B静态代码块->父类B非静态代码块->子类A静态代码块->子类A构造函数->子类A非静态代码块
解析:正确的执行顺序是:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A构造函数

也就是说非静态初始化块的执行顺序要在构造函数之前。

class SuperClass{
	private static String STR = "Super Class Static Variable";
	static{
		System.out.println("Super Class Static Block:"+STR);
	}

	public SuperClass() {
		System.out.println("Super Class Constructor Method");
	}
	{
		System.out.println("Super Class Block");
	}

}
public class ObjectInit extends SuperClass{
	private static String STR = "Class Static Variable";
	static{
		System.out.println("Class Static Block:"+STR);
	}

	public ObjectInit() {
		System.out.println("Constructor Method");
	}
	{
		System.out.println("Class Block");
	}
	public static void main(String[] args) {
		@SuppressWarnings("unused")
		ObjectInit a =new ObjectInit();
	}
}

执行完之后可以看到顺序如下:

Super Class Static Block:Super Class Static Variable
Class Static Block:Class Static Variable
Super Class Block
Super Class Constructor Method
Class Block
Constructor Method

328、选项中哪一行代码可以替换 //add code here 而不产生编译错误 答案:A
public abstract class MyClass {
     public int constInt = 5;
     //add code here
     public void method() {
     } 

A、public abstract void method(int a);
B、consInt=constInt+5;
C、public int method();
D、public abstract void anotherMethod(){}
解析:A是抽象方法,抽象类可以包含抽象方法,也可以不包含,实现重载。(√)

B 在类中不能constInt = constInt + 5(×)
C 返回值不能作为重载的依据(×)
D 有方法体的不能作为抽象函数(×)
2、A:抽象类可以包含抽象方法
B:类中定义成员和方法,不能直接进行运算,可以写在代码块{}或者静态代码块中static{}中
C: 与第四行想要构成重载,二者区别是返回类型,但是返回类型不能作为重载的依据
D: 该方法使用abstract修饰,是抽象方法,但是他有方法体(带有{}的就是方法体,即使里面是空的),就不能作为抽象方法

329、看以下代码:

文件名称:forward.jsp 答案:A

<html>  
     <head><title> 跳转  </title> </head> 
     <body>  
         <jsp:forward page="index.htm"/>     
     </body>
 </html> 

如果运行以上jsp文件,地址栏的内容为

A、http://127.0.0.1:8080/myjsp/forward.jsp
B、http://127.0.0.1:8080/myjsp/index.jsp
C、http://127.0.0.1:8080/myjsp/index.htm
D、http://127.0.0.1:8080/myjsp/forward.htm
解析:orward和redirect是最常问的两个问题
forward,服务器获取跳转页面内容传给用户,用户地址栏不变
redirect,是服务器向用户发送转向的地址,redirect后地址栏变成新的地址
因此这个题是A
2、redirect:请求重定向:客户端行为,本质上为2次请求,地址栏改变,前一次请求对象消失。举例:你去银行办事(forward.jsp),结果告诉你少带了东西,你得先去***局办(index.html)临时身份证,这时你就会走出银行,自己前往***局,地址栏变为index.html.
forward:请求转发:服务器行为,地址栏不变。举例:你把钱包落在出租车上,你去警察局(forward.jsp)报案,警察局说钱包落在某某公司的出租车上(index.html),这时你不用亲自去找某某公司的出租车,警察局让出租车自己给你送来,你只要在警察局等就行。所以地址栏不变,依然为forward.jsp

330、以下哪些方法是Object类中的方法 答案:A B C D

A、clone()
B、toString()
C、wait()
D、finalize()
解析:全选,Object 类中方法及说明如下:
registerNatives() //私有方法
getClass() //返回此 Object 的运行类。
hashCode() //用于获取对象的哈希值。
equals(Object obj) //用于确认两个对象是否“相同”。
clone() //创建并返回此对象的一个副本。
toString() //返回该对象的字符串表示。
notify() //唤醒在此对象监视器上等待的单个线程。
notifyAll() //唤醒在此对象监视器上等待的所有线程。
wait(long timeout) //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或 者超过指定的时间量前,导致当前线程等待。
wait(long timeout, int nanos) //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
wait() //用于让当前线程失去操作权限,当前线程进入等待序列
finalize() //当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

331、后端获取数据,向前端输出过程中,以下描述正确的是 答案:D

A、对于前端过滤过的参数,属于可信数据,可以直接输出到前端页面
B、对于从数据库获得的数据,属于可信数据,可以直接输出到前端页面
C、对于从用户上传的Excel等文件解析出的数据,属于可信数据,可以直接输出到前端页面
D、其它选项都不属于可信数据,输出前应该采用信息安全部发布的XSSFilter做进行相应编码
解析:后端获取数据,向前端输出的过程中,输出前应该采用信息安全部发布的XSSFilter进行相应编码。
2、做题的时候感觉D很有可能是出题人想要的,但是我自己没想出来数据库的数据为什么也不安全,因为如果数据库没有被不安全数据侵入那么就是安全的吧,为什么也要检验,不懂

332、已知有下列Test类的说明,在该类的main方法的横线处,则下列哪个语句是正确的?() 答案:A
public class Test
{
private float f = 1.0f;
int m = 12;
static int n = 1;
public static void main (String args[])
{
Test t = new Test();
————————
}
}

A、t.f = 1;
B、this.n = 1;
C、Test.m = 1;
D、Test.f = 1;
解析:加入这个空格是放在“Test t = new Test();”的下一行,那么:
1、f 虽然是 Test 类的私有成员属性,但因为 main 方法就在 Test 类内,因此可以通过 “对象名.属性名” 的方式调用,所以 A 对。
2、static 静态成员属性不能使用 this 关键字调用,B 错
3、m 和 f 都是普通成员属性,而 “类名.” 方式只能调用 静态成员属性,因此 C 和 D 都错。

333、下面有关jdbc statement的说法错误的是? 答案:C

A、JDBC提供了Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程
B、对于PreparedStatement来说,数据库可以使用已经编译过及定义好的执行计划,由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement 对象”
C、PreparedStatement中,“?” 叫做占位符,一个占位符可以有一个或者多个值
D、PreparedStatement可以阻止常见的SQL注入式攻击
解析:1.Statement、PreparedStatement和CallableStatement都是接口(interface)。
2.Statement继承自Wrapper、PreparedStatement继承自Statement、CallableStatement继承自PreparedStatement。

  1. Statement接口提供了执行语句和获取结果的基本方法;
    PreparedStatement接口添加了处理 IN 参数的方法;
    CallableStatement接口添加了处理 OUT 参数的方法。
  2. a.Statement:
    普通的不带参的查询SQL;支持批量更新,批量删除;
    b.PreparedStatement:
    可变参数的SQL,编译一次,执行多次,效率高;
    安全性好,有效防止Sql注入等问题;
    支持批量更新,批量删除;
    c.CallableStatement:
    继承自PreparedStatement,支持带参数的SQL操作;
    支持调用存储过程,提供了对输出和输入/输出参数(INOUT)的支持;

Statement每次执行sql语句,数据库都要执行sql语句的编译 ,
最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement。

PreparedStatement是预编译的,使用PreparedStatement有几个好处

  1. 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。
  2. 安全性好,有效防止Sql注入等问题。
  3. 对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;
  4. 代码的可读性和可维护性。
    2、JDBC statement中的PReparedStatement的占位符对应着即将与之对应当值,并且一个占位符只能对应一个值,如果能对应多个就会引起混淆。sql语句是确定的,那么一个占位符必定只能对应一个值
334、下列关于包(package)的描述,正确的是() 答案:D

A、包(package)是Java中描述操作系统对多个源代码文件组织的一种方式。
B、import语句将所对应的Java源文件拷贝到此处执行。
C、包(package)是Eclipse组织Java项目特有的一种方式。
D、定义在同一个包(package)内的类可以不经过import而直接相互使用。
解析:1、为了更好地组织类,Java提供了包机制。包是类的容器,用于分隔类名空间。如果没有指定包名,所有的示例都属于一个默认的无名包。Java中的包一般均包含相关的类,java是跨平台的,所以java中的包和操作系统没有任何关系,java的包是用来组织文件的一种虚拟文件系统。A错
2、import语句并没有将对应的java源文件拷贝到此处仅仅是引入,告诉编译器有使用外部文件,编译的时候要去读取这个外部文件。B错
3、Java提供的包机制与IDE没有关系。C错
4、定义在同一个包(package)内的类可以不经过import而直接相互使用。

2、外部类只能被public、abstract、final、(default)修饰
private修饰类的话只能修饰内部类
内部类可以被public、abstract、final、(default)、private修饰
内部类是外部类的一个成员,所以可以访问外部类的私有属性
5.同包无需导入即可使用,因为外部类不会是private的

335、Java7特性中,abstract class和interface有什么区别。 答案:A B D

A、抽象类可以有构造方法,接口中不能有构造方法
B、抽象类中可以有普通成员变量,接口中没有普通成员变量
C、抽象类中不可以包含静态方法,接口中可以包含静态方法
D、一个类可以实现多个接口,但只能继承一个抽象类。
解析:含有abstract修饰符的class即为抽象类,abstract类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。

  1. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
    eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

  2. 抽象类中可以包含静态方法,接口中不能包含静态方法

  3. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。

  4. 一个类可以实现多个接口,但只能继承一个抽象类。
    下面接着再说说两者在应用上的区别:
    接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,
    例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码,伪代码如下:

package com.lei;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class BaseServlet extends HttpServlet {

 /**
 * serialVersionUID属性概述
 * 
 */
 private static final long serialVersionUID = 1L;

 public final void service(HttpServletRequest request,
 HttpServletResponse response) throws IOException, ServletException {
 // 记录访问日志
 // 进行权限判断
 if (true)// if条件里写的是“具有权限”
 {
 try {
 doService(request, response);
 } catch (IOException e) {
 // 记录异常信息
 }
 }
 }
 protected abstract void doService(HttpServletRequest request,
 HttpServletResponse response) throws IOException, ServletException;
}

实现类如下:

package com.lei;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends BaseServlet{

 /**
 * serialVersionUID属性概述
 * 
 */
 private static final long serialVersionUID = 1L;

 @Override
 protected void doService(HttpServletRequest request,
 HttpServletResponse response) throws IOException, ServletException {
 // TODO Auto-generated method stub
 
 }

}

父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。
备注:这道题的思路是先从总体解释抽象类和接口的基本概念,然后再比较两者的语法细节,最后再说两者的应用区别。
比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性等6个方面逐一去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底。

336、编译java程序的命令文件是( ) 答案:B

A、java.exe
B、javac.exe
C、applet.exe
解析:javac.exe是编译功能javaCompiler
java.exe是执行程序,用于执行编译好的.class文件
javadoc.exe用来制作java文档
jdb.exe是java的调试器
javaprof.exe是剖析工具
2、javac.exe是编译功能javaCompiler
java.exe是执行class,如果没有编译的话是不能执行的,同理,javac.exe编译完以后如果没有java.exe执行的话也是没有运行的

337、数学表达式|x|<10 对应的java表达式为 。 答案:B

A、|x|<10
B、x<10&&x>-10
C、x<10||x>-10
D、10>x>-10
解析:10>x>-10不是Java表达式
2、B,|x|>10的范围为-10>x>10,在Java中表示为x<10&&x>-10,所以选B

338、 设有下面两个赋值语句:

a = Integer.parseInt(“1024”);

b = Integer.valueOf(“1024”).intValue();

下述说法正确的是() 答案:D

A、a是整数类型变量,b是整数类对象。
B、a是整数类对象,b是整数类型变量。
C、a和b都是整数类对象并且它们的值相等。
D、a和b都是整数类型变量并且它们的值相等。
解析:intValue()是把Integer对象类型变成int的基础数据类型;
parseInt()是把String 变成int的基础数据类型;
Valueof()是把String 转化成Integer对象类型;(现在JDK版本支持自动装箱拆箱了。)
本题:parseInt得到的是基础数据类型int,valueof得到的是装箱数据类型Integer,然后再通过valueInt转换成int,所以选择D
2、Integer对象的方法
Integer.parseInt("");是将字符串类型转换为int的基础数据类型
Integer.valueOf("")是将字符串类型数据转换为Integer对象
Integer.intValue();是将Integer对象中的数据取出,返回一个基础数据类型int

339、 答案:B
String str = "";
System.out.print(str.split(",").length);
输出结果为:

A、0
B、1
C、出现异常
解析:

    /**  * String split 这个方法默认返回一个数组,  * 如果没有找到分隔符,  * 会把整个字符串当成一个长度为1的字符串数组  * 返回到结果, 所以此处结果就是1  */  private static void testSpringSpilte(){
        String str = "12,3";
        String str2 = "123";
        System.out.print(str.split(",").length);
        System.out.print(str2.split(",").length);
    }
}
结果  2  1
340、下列关于异常的说法,正确的是() 答案:A

A、RuntimeException及其子类的异常可以不做处理
B、Catch段中的语句,不允许再次出现异常
C、在方法定义中以throws标识出的异常,在调用该方法中的方法必须处理
D、程序中所有的可能出现的异常必须在catch中捕获,否则将引起编译错误
解析:异常分为两种,一种为运行异常RuntimeException,另一种为检查异常CheckedException。
对于运行异常,编译器没有强制对其进行捕获。会把异常一直往上层抛出,直到遇到处理代码为止。常见的运行异常有:nullpointexception(空指针异常),indexoutofboundexception(越界异常)。。。。。
检查异常,所有继承自Exception并且不是运行异常的都是检查异常,在程序中需要用try catch进行捕获。常见的有IO异常和SQL异常。

341、如果类的方法没有返回值,该方法的返回值类型应当是abstract。() 答案:B

A、正确
B、错误
解析:如果类的方法没有返回值,该方法的返回值类型应当是void。
被abstract修饰的类是抽象类,抽象类不能被实例化,但是可以被继承,也可以继承。

342、下列叙述错误的是( ) 答案:C

A、java程序的输入输出功能是通过流来实现的
B、java中的流按照处理单位可分成两种:字节流和字符流
C、InputStream是一个基本的输出流类。
D、通过调用相应的close()方法关闭输入输出流
解析:大家相对纠结的应该是C选项吧,
C.InputStream是一个基本的输出流类
这里"基本的",其实就是将流分为节点流和处理流,而“基本的”是表示节点流
所以C选项可以看成:InputStream是属于节点输出流;
所以我们就要判断InputStream是节点流还是处理流,是输出流还是输入流
这就涉及到哪些是节点流,哪些是处理流了,而且很明显,他是一个输入流
节点流:
FileInputStream,FileOutputStrean,FileReader,FileWriter
StringReader,StringWriter

ByteArrayInputStream ,ByteArrayOutputStream ,CharArrayReader

PipedInputStream PipedOutputStream PipedReaderPipedWriter

处理流:
BufferedInputStrean,BufferedOutputStream,BufferedReader,BufferedWriter
InputStreamReader,OutputStreamReader

DataInputStream,DataOutputStream

PrintWriter

不知道大家发现没有,节点流的前缀都是名词,如File,String,Char等;处理流的前缀都是动词,如input,print,bufferd等等
所以大家别烦分不清一个流到底是节点流还是处理流,看他前缀是名词还是动词就行了
手敲不易,所以有帮助请左上角走一波
2、Io流的分类

按照流的流向分,可以分为输入流和输出流。

  • 输入流: 只能从中读取数据,而不能向其写入数据。
  • 输出流:只能向其写入数据,而不能向其读取数据。

此处的输入,输出涉及一个方向的问题,对于如图15.1所示的数据流向,数据从内存到硬盘,通常称为输出流——也就是说,这里的输入,输出都是从程序运行所在的内存的角度来划分的。

注:如果从硬盘的角度来考虑,图15.1所示的数据流应该是输入流才对;但划分输入/输出流时是从程序运行所在的内存的角度来考虑的,因此如图15.1所在的流时输出流。而不是输入流。

对于如图15.2所示的数据流向,数据从服务器通过网络流向客户端,在这种情况下,Server端的内存负责将数据输出到网络里,因此Server端的程序使用输出流;Client端的内存负责从网络中读取数据,因此Client端的程序应该使用输入流。

这是图片描述

注:java的输入流主要是InputStream和Reader作为基类,而输出流则是主要由outputStream和Writer作为基类。它们都是一些抽象基类,无法直接创建实例。

343、java用()机制实现了线程之间的同步执行 答案:****

A、监视器
B、虚拟机
C、多个CPU
D、异步调用
解析:我的答案是A 首先jvm中没有进程的概念 ,但是jvm中的线程映射为操作系统中的进程,对应关系为1:1。那这道题的问的就是jvm中线程如何异步执行 。 在jvm中 是使用监视器锁来实现不同线程的异步执行, 在语法的表现就是synchronized 。
2、A:
The code segments within a program that access the same object from separate, concurrent threads are called “critical sections”。
翻译:在一个程序当中代码段访问了同一个对象从单独的并发的线程当中,那么这个代码段叫”临界区”
怎么解决呢:使用同步的机制对临界区进行保护

同步的两种方式:同步块和同步方法
对于同步来说都是使用synchronized方法
每一个对象都有一个监视器,或者叫做锁。
同步块实例

package ticket; class Tickets { public static void main(String[] args)
    {
        sellTickets st = new sellTickets(); //四个线程同时卖这100张票,注意是同一个对象创建四个线程,他们共享同一个变量ticket new Thread(st).start(); new Thread(st).start(); new Thread(st).start(); new Thread(st).start();
    }
} class sellTickets implements Runnable { int ticket = 100;
    Object o = new Object();
    @Override public void run() { while(true)
        { //每一个对象都有一个监视器,或者叫做锁。同步块示例 synchronized (o) { if(ticket > 0)
                { //存在的隐藏的问题当ticket=1,它的时间片到期了进入到if语句中,第二个线程进入到if语句然后时间片到期 try { //线程睡眠,该方法需要写异常 Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();                    
                    } //第几个线程卖出了第多少张票 System.out.println(Thread.currentThread().getName() + "sell tickets" + ticket);
                    ticket--;
                }
            }
        }
    }
}

344、以下代码的输出结果是? 答案: C
public class B
{
    public static B t1 = new B();
    public static B t2 = new B();
    {
        System.out.println("构造块");
    }
    static
    {
        System.out.println("静态块");
    }
    public static void main(String[] args)
    {
        B t = new B();
    }
}

A、静态块 构造块 构造块 构造块
B、构造块 静态块 构造块 构造块
C、构造块 构造块 静态块 构造块
D、构造块 构造块 构造块 静态块
解析:开始时JVM加载B.class,对所有的静态成员进行声明,t1 t2被初始化为默认值,为null,又因为t1 t2需要被显式初始化,所以对t1进行显式初始化,初始化代码块→构造函数(没有就是调用默认的构造函数),咦!静态代码块咋不初始化?因为在开始时已经对static部分进行了初始化,虽然只对static变量进行了初始化,但在初始化t1时也不会再执行static块了,因为JVM认为这是第二次加载类B了,所以static会在t1初始化时被忽略掉,所以直接初始化非static部分,也就是构造块部分(输出’‘构造块’’)接着构造函数(无输出)。接着对t2进行初始化过程同t1相同(输出’构造块’),此时就对所有的static变量都完成了初始化,接着就执行static块部分(输出’静态块’),接着执行,main方法,同样也,new了对象,调用构造函数输出(‘构造块’)
2、之前我一直有一个误区!就是认为静态块一定是最先初始化的!但是,阿里爸爸今天又用一记重拳猛击我的脸,额,好疼…当时的情况是这样的:
我在牛客网找虐中,碰到了这样的一道题,心中充满了鄙夷,心想"这tm还用看吗,肯定先是静态块,再接着三个构造块,弱鸡题",但是 = = ,答案却是"构造块 构造块 静态块 构造块".
…[黑线|||||||||]
于是总结了一下,以警后世 - -
正确的理解是这样的:
并不是静态块最先初始化,而是静态域.(BM:啊!多么痛的领悟!)
而静态域中包含静态变量、静态块和静态方法,其中需要初始化的是静态变量和静态块.而他们两个的初始化顺序是靠他们俩的位置决定的!
So!
初始化顺序是 t1 t2 静态块

345、在Java中,对于不再使用的内存资源,如调用完成的方法,“垃圾回收器”会自动将其释放。( ) 答案: B

A、正确
B、错误
解析:方法调用时,会创建栈帧在栈中,调用完是程序自动出栈释放,而不是gc释放
2、JVM 内存可简单分为三个区:

1、堆区(heap):用于存放所有对象,是线程共享的(注:数组也属于对象)

2、栈区(stack):用于存放基本数据类型的数据和对象的引用,是线程私有的(分为:虚拟机栈和本地方法栈)

3、方法区(method):用于存放类信息、常量、静态变量、编译后的字节码等,是线程共享的(也被称为非堆,即 None-Heap)

Java 的垃圾回收器(GC)主要针对堆区

346、java程序内存泄露的最直接表现是( ) 答案:C

A、频繁FullGc
B、jvm崩溃
C、程序抛内存溢出的Exception
D、java进程异常消失
解析:C
java是自动管理内存的,通常情况下程序运行到稳定状态,内存大小也达到一个 基本稳定的值
但是内存泄露导致Gc不能回收泄露的垃圾,内存不断变大.
最终超出内存界限,抛出OutOfMemoryExpection
2、C,依次解释一下相关选项
首先理解一下内存泄漏的概念,内存泄漏就是对象引用消失了,对象内存却没有被回收。
A答案:FullGC 是老年代内存空间不足的时候,才会触发的,老年代一般是生命周期较长的对象或者大对象,频繁的 FullGC 不会可能会影响程序性能(因为内存回收需要消耗CPU等资源),但是并不会直接导致内存泄漏。
B 答案:JVM奔溃的可能是内存溢出引起的,也可能是其他导致 JVM崩溃的操作,例如设置了错误的JVM参数等。
C 答案:内存异常,最常见的 就是 StackOverFlow 了把,内存溢出,其实内存泄漏的最终结果就是内存溢出。所以,基本上C是对的答案。
D 答案:Java 进程异常消失,这个明显不对的。

347、有以下一个对象: 答案:D
public class DataObject implements Serializable{
    private static int i=0;
    private String word=" ";
    public void setWord(String word){
        this.word=word;
    }
    public void setI(int i){
        Data0bject.i=i;
     }
}

创建一个如下方式的DataObject:

DataObject object=new Data0bject ( );
object.setWord("123");
object.setI(2); 

将此对象序列化为文件,并在另外一个JVM中读取文件,进行反序列化,请问此时读出的Data0bject对象中的word和i的值分别为:
A、"", 0
B、"", 2
C、“123”, 2
D、“123”, 0
解析:这道题的答案应该是: D,序列化保存的是对象的状态,静态变量属于类的状态,因此,序列化并不保存静态变量。所以i是没有改变的
2、序列化的是对象,不是类,类变量不会被序列化

348、Java语言中,方法的重写(Overriding)和重载(Overloading)是多态性的不同表现。下边哪些说法是对的? 答案:A C

A、重写是父类与子类之间多态性的一种表现
B、重写是一个类中多态性的一种表现
C、重载是一个类中多态性的一种表现
D、重载是父类与子类之间多态性的一种表现
解析:A and C
重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。
Overloaded的方法是可以改变返回值的类型。
2、A C 重写(Overriding)是父类与子类之间多态性的一种表现,类的不同实现可以重写父类方法,实现同方法名,同参数,同返回类型,不同的实现。重载(Overloading)最典型的就是一个类的不同构造函数,方法名相同,参数个数不同,返回类型也可以不同,重载是一个类中多态性的一种表现。

349、以下哪些内存区域属于JVM规范?(  ) 答案:A D E

A、方法区
B、实例变量
C、静态变量
D、程序计数器

E、程序计数器
解析:jvm规范如图所示

img

img

350、ervlet的生命周期可以分为初始化阶段,运行阶段和销毁阶段三个阶段,以下过程属于初始化阶段是()。 答案: A C D

A、加载Servlet类及.class对应的数据
B、创建servletRequest和servletResponse对象
C、创建ServletConfig对象
D、创建Servlet对象
解析:Servlet的生命周期一般可以用三个方法来表示:
init():仅执行一次,负责在装载Servlet时初始化Servlet对象
service() :核心方法,一般HttpServlet中会有get,post两种处理方式。在调用doGet和doPost方法时会构造servletRequest和servletResponse请求和响应对象作为参数。
destory():在停止并且卸载Servlet时执行,负责释放资源
初始化阶段:Servlet启动,会读取配置文件中的信息,构造指定的Servlet对象,创建ServletConfig对象,将ServletConfig作为参数来调用init()方法。所以选ACD。B是在调用service方法时才构造的
2、img

351、ArrayList和LinkList的描述,下面说法错误的是? 答案:D

A、LinkedeList和ArrayList都实现了List接口
B、ArrayList是可改变大小的数组,而LinkedList是双向链接串列
C、LinkedList不支持高效的随机元素访问
D、在LinkedList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在ArrayList的中间插入或删除一个元素的开销是固定的
解析:D
这个说法说反了
Arraylist的内存结构是数组,当超出数组大小时创建一个新的数组,吧原数组中元素拷贝过去。其本质是顺序存储的线性表,插入和删除操作会引发后续元素移动,效率低,但是随机访问效率高
LinkedList的内存结构是用双向链表存储的,链式存储结构插入和删除效率高,不需要移动。但是随机访问效率低,需要从头开始向后依次访问

2、

352、执行如下代码段后,变量s1引用的字符串值是( )。

String s1 = “ABCD”;String s2 = “1234”;System.out.println(s1 + s2); 答案:A

A、ABCD
B、1234
C、ABCD1234
D、1234ABCD
解析:因为 String 是不可变类型,是存储在常量字符区的, 所以答案是ABCD。 另外可千万不要选成输出显示的结果,对就跟我(o(╯□╰)o)一样选了ABCD1234,。

353、下列程序test 类中的变量c 的最后结果为 答案:D
public class Test {
    public static void main(String args[]) {
        int a = 10;
        int b;
        int c;
        if (a > 50) {
             b = 9;
        }
        c = b + a;
    }
}

A、10
B、0
C、19
D、编译出错
解析:方法内定义的变量没有初始值,必须要进行初始化。 类中定义的变量可以不需要赋予初始值,默认初始值为0。

354、如果要导入一个java.scut.computer的包,叙述正确的是? ( ) 答案: A

A、只需在代码中加入“import java.scut.computer;”一个语句,并且必须放在代码非注释的第一行
B、只需在代码中加入“import java.scut;”一个语句
C、必须在代码中加入“import java.scut;”和“package java.scut.computer;”两个语句
D、在代码中,不一定是第一句,只要是类定义前,加入package语句即可
解析:实际上在Java语言规范中,不允许package name以“java”开头,不然会报一个java.lang.SecurityException 的错误。因为假如我们允许包名以java开头,那么我们完全可以编写和jdk标准包下一模一样的类,如Java.lang.Integer。因此在虚拟机进行类或接口解析时可能会发生冲突。一句话总结就是:假如允许包名以java开头,可能会导致命名空间污染的问题。实际上Java对此也做了限制,具体的源码解析可以参考这篇博客–http://www.jianshu.com/p/f9a56a3edadd
2、A选项还不够准确,应该加上一句: 必须放在代码的第一行

355、mysql数据库,game_order表表结构如下,下面哪些sql能使用到索引()? 答案: B C D E

img

A、select * from game_order where plat_game_id=5 and plat_id=134
B、

select * from game_order where plat_id=134 and
plat_game_id=5 and plat_order_id=’100’

C、select * from game_order where plat_order_id=’100’
D、

select * from game_order where plat_game_id=5 and
plat_order_id=’100’ and plat_id=134

E、select * from game_order where plat_game_id=5 and plat_order_id=’100’
解析:这道题目想考察的知识点是MySQL组合索引(复合索引)的最左优先原则。最左优先就是说组合索引的第一个字段必须出现在查询组句中,这个索引才会被用到。只要组合索引最左边第一个字段出现在Where中,那么不管后面的字段出现与否或者出现顺序如何,MySQL引擎都会自动调用索引来优化查询效率。
根据最左匹配原则可以知道B-Tree建立索引的过程,比如假设有一个3列索引(col1,col2,col3),那么MySQL只会会建立三个索引(col1),(col1,col2),(col1,col2,col3)。
所以题目会创建三个索引(plat_order_id)、(plat_order_id与plat_game_id的组合索引)、(plat_order_id、plat_game_id与plat_id的组合索引)。根据最左匹配原则,where语句必须要有plat_order_id才能调用索引(如果没有plat_order_id字段那么一个索引也调用不到),如果同时出现plat_order_id与plat_game_id则会调用两者的组合索引,如果同时出现三者则调用三者的组合索引。
题目问有哪些sql能使用到索引,个人认为只要Where后出现了plat_order_id字段的SQL语句都会调用到索引,只不过是所调用的索引不同而已,所以选BCDE。如果题目说清楚是调用到三个字段的复合索引,那答案才是BD。

356、下面程序段执行后b的值是()。 答案:B

Integer integ =new Integer(9);
boolean b = integ instanceof Object;

A、9
B、true
C、1
D、false
解析:instanceof 用来在运行时指出对象是否是特定类的一个实例,instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例
2、选B,Object是 integ 的父类。而且我还去运行了一下,第一句后面的分号,你写的是中文的,哈哈。

357、一个以". java"为后缀的源文件,哪些说法是正确的? 答案:C

A、只能包含一个类,类名必须与文件名相同
B、只能包含与文件名相同的类,以及其中的内部类
C、只能有一个与文件名相同的类,可以包含其他类
D、可以包含任意类
解析:C。一个与文件名相同的public的类敏感词类可随意多个。
2、一个java文件可以包含多个java类,但是只能包含一个public类,并且public类的类名必须与java文件名相同。

358、要导入java/awt/event下面的所有类,叙述正确的是?() 答案:C

A、import java.awt.和import java.awt.event.都可以
B、只能是import java.awt.

C、只能是import java.awt.event.

D、import java.awt.*和import java.awt.event.*都不可以
解析:导包只可以导到当前层,不可以再导入包里面的包中的类
2、java.awt.*是导入java\awt包下所有的类,并不包括其子包下的类。
java.awt.event.*才能导入java\awt\event包下的类。

359、下面代码的运行结果是( ) 答案:
public class Arraytest{
    int a[] = new int[6];
    public static void main ( String arg[] ) {
        System.out.println ( a[0] );
    }
}

A、null
B、0
C、编译出错
D、运行出错
解析:在static方法中是不能访问非静态变量 a 的,需要将 a 声明为static,答案才会是 0 ,否则是编译出错
2、Java静态 方法不能访问 非静态变量

360、以下关于final关键字说法错误的是() 答案:A C

A、final是java中的修饰符,可以修饰类、接口、抽象类、方法和属性
B、final修饰的类不能被继承
C、final修饰的方法不能被重载
D、final修饰的变量不允许被再次赋值
解析:1.final修饰变量,则等同于常量
2.final修饰方法中的参数,称为最终参数。
3.final修饰类,则类不能被继承
4.final修饰方法,则方法不能被重写。

final 不能修饰抽象类
2、A.final不能修饰接口和抽象类 C.final修饰的方法不能被重写

361、以下关于 abstract 关键字的说法,正确的是() 答案:D

A、abstract 可以与final 并列修饰同一个类。
B、abstract 类中不可以有private的成员。
C、abstract 类中必须全部是abstract方法。
D、abstract 方法必须在abstract类或接口中。
解析:1abstract类不能与final,static使用。final修饰方法,子类可以调用,但不能覆盖。
2最好不要有private因为私有和抽象放在一起,子类如果想重写父类的私有方法根本继承不过来,也就无法重写
3抽象类中可以有非抽象方法
4抽象类中可以都是非抽象的,但是抽象方法一定要在类和接口中
2、含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。

362、关于final说法正确的是? ( ) 答案:B

A、final类的方法肯定不能被同一个包的类访问
B、final类的方法能否被同一个包的类访问不是由final决定
C、final方法等同于private方法
D、final对象本身的引用和值都不能改变
解析:final变量,如果是基本数据类型,则其数值一旦初始化后就不能被改变。如果是引用类型的变量,则对其初始化后,便不能再指向另一个对象,但是其里面的值是可以改变的。引用变量所指向的对象中的内容是可以改变的。
2、final 修饰符
final 变量:

final 变量能被显式地初始化并且只能初始化一次。被声明为 final 的对象的引用不能指向不同的对象。但是 final 对象里的数据可以被改变。也就是说 final 对象的引用不能改变,但是里面的值可以改变。

final 修饰符通常和 static 修饰符一起使用来创建类常量。
final 方法
类中的 final 方法可以被子类继承,但是不能被子类修改。

声明 final 方法的主要目的是防止该方法的内容被修改。

如下所示,使用 final 修饰符声明方法。

final 类
final 类不能被继承,没有类能够继承 final 类的任何特性。

363、下面属于java合法变量名定义的是? 答案:C

A、final
B、1var1
C、_var2
D、var3&
解析:A.final 是关键字
B.不能以数字做首写
C.首写字母可以为下划线
D.不能与&相组合来命名
2、标识符:
1. 数字,字母,符号(只有_和$两种),数字不能开头。
2. 不能是关键字(有两个保留关键字,goto,const,关键字都是小写的)或者显式常量(null,true,false)。

364、Which method you define as the starting point of new thread in a class from which n thread can be execution?

下列哪一个方法你认为是新线程开始执行的点,也就是从该点开始线程n被执行。 答案:B

A、public void start()
B、public void run()
C、public void int()
D、public static void main(String args[])
解析:要写一个线程类,可以继承Thread方法,然后override他的run()方法
另一种方法是实现Runable接口,即为实现run()方法。
A,start()是启动一个线程的方法
2、题目的意思是,下列哪一个方法你认为是新线程开始执行的点,也就是从该点开始线程n被执行。
了解过线程的知识我们知道:
start()方法是启动一个线程,此时的线程处于就绪状态,但并不一定就会执行,还需要等待CPU的调度。
run()方法才是线程获得CPU时间,开始执行的点。

365、关于java集合下列说法不正确的有哪些() 答案: A B D

A、HashSet 它是线程安全的,不允许存储相同的对象
B、ConcurrentHashMap 它是线程安全的,其中存储的键对象可以重复,值对象不能重复
C、Collection接口是List接口和Set接口的父接口,通常情况下不被直接使用
D、ArrayList线程安全的,允许存放重复对象
解析:基本上我们平常用到的都是非线程安全的集合类,因为要使线程安全,是要加锁来实现的,势必造成性能降低。如hashset、hashmap、arraylist、linkedlist、treemap、treeset、stringbulider等。
像stringbuhffer、vector、hashtable这些都是专用于多线程的,再者以concurrent(意为:同时发生的)为前缀的集合类大多是线程安全的。
2、A: HashSet 它不是线程安全的,属于Set接口下的实现类,Set下的实现类特征就是无序,不允许存储相同的对象

B: ConcurrentHashMap 它是线程安全的HashMap实现,特征也相似,其中存储的值对象可以重复,键对象不能重复

C: Collection接口是List接口和Set接口的父接口,通常情况下不被直接使用

D: ArrayList线程不安全的,底层是数组实现,允许存放重复对象

366、java7后关键字 switch 支不支持字符串作为条件:() 答案:A

A、支持
B、不支持
解析:在Java7之前,switch只能支持 byte、short、char、int或者其对应的封装类以及Enum类型。在Java7中,呼吁很久的String支持也终于被加上了。

在switch语句中,表达式的值不能是null,否则会在运行时抛出NullPointerException。在case子句中也不能使用null,否则会出现编译错误。

同时,case字句的值是不能重复的。对于字符串类型的也一样,但是字符串中可以包含Unicode转义字符。重复值的检查是在Java编译器对Java源代码进行相关的词法转换之后才进行的。也就是说,有些case字句的值虽然在源代码中看起来是不同的,但是经词法转换之后是一样的,就会在成编译错误。比如:“男”和“\u7537”就是一个意思。

然后看一个源代码及反编译后的代码:

public class StringForSwitch {
    public void test_string_switch() {
        String result="";  
        switch ("doctor") {
        case "doctor":
            result = "doctor";
            break;
        default:
            break;
        }
    }
}

反编译后的,还原成大致的Java的代码如下:

public class StringForSwitch {
    public StringForSwitch() {
    }
    public void test_string_switch() {
        String result = "";
        String var2 = "doctor";
        switch("doctor".hashCode()) {
        case -1326477025:
            if(var2.equals("doctor")) {
                result = "doctor";
            }
        default:
           break;
        }
    }
}

可以看出,字符串类型在switch语句中利用hashcode的值与字符串内容的比较来实现的;但是在case字句中对应的语句块中仍然需要使用String的equals方法来进一步比较字符串的内容,这是因为哈希函数在映射的时候可能存在冲突。
2、看了一下,这个题大家都说的不是很全面。
switch(exp),在JDK7之前,只能是byte、short、char、int或者对应的包装类,或者枚举常量(内部也是由整型或字符类型实现)。
为什么必须是这些呢,因为其实exp只是对int型支持的,其他都是因为可以自动拆卸或者自动向上转型到int,所以才可以。
到了JDK7的时候,String被引入了,为什么String能被引入呢?
其实本质上还是对int类型值得匹配。
原理如下,通过对case后面得String对象调用hashCode方法,得到一个int类型得hash值,然后用这个hash值来唯一标识这个case。那么当匹配时,首先调用exp的hashCode,得到exp的hash值,用这个hash值来匹配所有case,如果没有匹配成功,就说明不存在;如果匹配成功了,接着会调用字符串的equals方法进行匹配。(hash值一致,equals可不一定返回的就是true)。
所以,exp不能为null,cas子句使用的字符串也不能为null,不然会出现空指针异常。

367、 以下哪个接口的定义是正确的?( ) 答案: D

A、

interface  B
{  void print()  {  } ;}

B、

interface  B
{ static void print() ;}

C、

abstract  interface  B  extends  A1, A2  //A1、A2为已定义的接口
{ abstract  void  print(){  };}

D、

interface  B
 {  void  print();}

解析:A,接口中方法的默认修饰符时public abstract,抽象方法可是没有方法体的,没有大括号{}
B,JDK8中,接口中的方法可以被default和static修饰,但是!!!被修饰的方法必须有方法体。
C,注意一下,接口是可以多继承的。整个没毛病,和A选项一样,抽象方法不能有方法体
2、jdk1.8新特性,接口中的方法可以用static,default修饰,且二者修饰的方法要求有方法体

368、以下代码将打印出 答案:C
 public static void main (String[] args) { 
    String classFile = "com.jd.". replaceAll(".", "/") + "MyClass.class";
    System.out.println(classFile);
}

A、com. jd
B、com/jd/MyClass.class
C、///MyClass.class
D、com.jd.MyClass
解析:C。由于replaceAll方法的第一个参数是一个正则表达式,而".“在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成”/"。如果想替换的只是".",那么久要写成"\.".
选C 由于replaceAll方法的第一个参数是一个正则表达式,而".“在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成”/"。如果想替换的只是".",那么久要写成"\."., 一开始没看懂

369、以下哪些方法是Object类中的方法 答案:: A B C D

A、clone()
B、toString()
C、wait()
D、finalize()
解析:
img

img

370、Java类Demo中存在方法func1、func2、func3和func4,请问该方法中,哪些是不合法的定义?( ) 答案:B D
public class Demo{

  float func1()
  {
    int i=1;
    return;
  }
  float func2()
  {
    short i=2;
    return i;
  }
  float func3()
  {
    long i=3;
    return i;
  }
  float func4()
  {
    double i=4;
    return i;
  }
}

A、func1
B、func2
C、func3
D、func4
解析:这道题考的是数据类型转换问题。由大到小需要强制转换,由小到大不需要。
A:return; 没有返回值,错误
B:short → float 无须强制转换,正确

C:long → float 无须强制转换(这个最选项容易出错),正确。

float占4个字节为什么比long占8个字节大呢,因为底层的实现方式不同。
浮点数的32位并不是简单直接表示大小,而是按照一定标准分配的。
第1位,符号位,即S
接下来8位,指数域,即E。
剩下23位,小数域,即M,取值范围为[1 ,2 ) 或[0 , 1)
然后按照公式: V=(-1)^s * M * 2^E
也就是说浮点数在内存中的32位不是简单地转换为十进制,而是通过公式来计算而来,通过这个公式虽然,只有4个字节,但浮点数最大值要比长整型的范围要大。

D:double → float 没有强制转换,错误。
2、数据类型的转换,分为自动转换和强制转换。自动转换是程序在执行过程中 “ 悄然 ” 进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换;强制类型转换则必须在代码中声明,转换顺序不受限制。

自动数据类型转换

自动转换按从低到高的顺序转换。不同类型数据间的优先关系如下:
低 ---------------------------------------------> 高
byte,short,char-> int -> long -> float -> double

运算中,不同类型的数据先转化为同一类型,然后进行运算,转换规则如下:

操作数 1 类型操作数 2 类型转换后的类型
byte 、 short 、 charintint
byte 、 short 、 char 、 intlonglong
byte 、 short 、 char 、 int 、 longfloatfloat
byte 、 short 、 char 、 int 、 long 、 floatdoubledouble

强制数据类型转换

强制转换的格式是在需要转型的数据前加上 “( )” ,然后在括号内加入需要转化的数据类型。有的数据经过转型运算后,精度会丢失,而有的会更加精确

371、java中下面哪个能创建并启动线程() 答案:C
public class MyRunnable implements Runnable { 
     public void run() { 
         //some code here 
     } 
 }

A、new Runnable(MyRunnable).start()
B、new Thread(MyRunnable).run()
C、new Thread(new MyRunnable()).start()
D、new MyRunnable().start()
解析:首先:创建并启动线程的过程为:定义线程—》实例化线程—》启动线程。
一 、定义线程: 1、扩展java.lang.Thread类。 2、实现java.lang.Runnable接口。
二、实例化线程: 1、如果是扩展java.lang.Thread类的线程,则直接new即可。
2、如果是实现了java.lang.Runnable接口的类,则用Thread的构造方法:
Thread(Runnable target)
Thread(Runnable target, String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
所以A、D的实例化线程错误。
三、启动线程: 在线程的Thread对象上调用start()方法,而不是run()或者别的方法。
所以B的启动线程方法错误。
2、img

372、关于以下application,说法正确是什么? 答案:B
public class Test {
	static int x=10;
	static {x+=5;}
	public static void main(String[] args) //4
        {
		System.out.println("x="+x);
	}
	static{x/=3;};
}//9

A、4行与9行不能通过编译,因为缺少方法名和返回类型
B、编译通过,执行结果是:x=5
C、编译通过,执行结果是:x=3
D、9行不能通过编译,因为只能有一个静态初始化器
解析:首先明确一下执行顺序,静态代码块先于主方法执行,静态代码块之间遵从代码顺序执行。
所以:先初始化静态变量x=10;//x=10
执行第一个静态代码块,x=x+5; //x=15
执行第二静态代码块 x=x/3; //x=5
执行主方法: 输出x=5
拓展一下,在类中定义的{}之间被称为构造块,构造块相对于构造方法先执行,构造块之间按照代码编译顺序执行
此外还有普通代码块,存在于方法之中。
贴出参考文章:http://www.cnblogs.com/sophine/p/3531282.html
2、B
这道题主要考察类记载时候的初始化问题,执行这个类的 main方法,会导致类进行加载,而类加载的属性如下
1、虚拟机在首次加载Java类时,会对静态初始化块、静态成员变量、静态方法进行一次初始化。我们不要去纠结这里的顺序,一般来说我们只需要知道,静态方法一般在最后。
2、只有在调用new方法时才会创建类的实例
3、类实例创建过程:按照父子继承关系进行初始化,首先执行父类的初始化块部分,然后是父类的构造方法;再执行本类继承的子类的初始化块,最后是子类的构造方法
4、类实例销毁时候,首先销毁子类部分,再销毁父类部分

373、以下会产生精度丢失的类型转换是( ) 答案:B

A、float a=10
B、int a=(int)8846.0
C、byte a=10; int b=-a
D、double d=100
解析:会产生信息丢失不如说丢失精度,这样可能更容易明白,而精度丢失只会发生在从大范围到小范围的转换
上面四个选项,只有 B 是从 double 到 int ,也就是从大范围到小范围。
2、对于c选项
只要int类型的数没有超出(byte,short,char)的表述范围也就是127,可以直接byte a=23

374、对于上面这段代码,以下说法正确的是: 答案:C
public class Test
{
    public int x;
    public static void main(String []args)
    {
        System. out. println("Value is" + x);
    }
}

A、程序会打出 “Value is 0”
B、程序会抛出 NullPointerException
C、非静态变量不能够被静态方法引用
D、编译器会抛出 "possible reference before assignment"的错误
解析:C
非静态成员只能被类的实例化对象引用,因此这里在静态方法中访问x会造成编译出错
2、当类加载时,static静态方法随着类加载而初始化,此时实例对象还未被创建,但是非静态成员变量需要等到实例对象创建才会被初始化,故无法被引用。

375、 多态的作用() 答案:B C

A、隐藏细节
B、提高可重用性
C、扩展代码模块
D、提高编译可靠性
解析:

376、关于抽象类和接口叙述正确的是? ( ) 答案:D

A、抽象类和接口都能实例化的
B、抽象类不能实现接口
C、抽象类方法的访问权限默认都是public
D、接口方法的访问权限默认都是public
解析:抽象类
特点:
1.抽象类中可以构造方法
2.抽象类中可以存在普通属性,方法,静态属性和方法。
3.抽象类中可以存在抽象方法。
4.如果一个类中有一个抽象方法,那么当前类一定是抽象类;抽象类中不一定有抽象方法。
5.抽象类中的抽象方法,需要有子类实现,如果子类不实现,则子类也需要定义为抽象的。
6,抽象类不能被实例化,抽象类和抽象方法必须被abstract修饰

关键字使用注意:
抽象类中的抽象方法(其前有abstract修饰)不能用private、static、synchronized、native访问修饰符修饰。

接口
1.在接口中只有方法的声明,没有方法体。
2.在接口中只有常量,因为定义的变量,在编译的时候都会默认加上public static final
3.在接口中的方法,永远都被public来修饰。
4.接口中没有构造方法,也不能实例化接口的对象。(所以接口不能继承类)
5.接口可以实现多继承
6.接口中定义的方法都需要有实现类来实现,如果实现类不能实现接口中的所有方法则实现类定义为抽象类。
7,接口可以继承接口,用extends
2、1、抽象类和方法都不能被实例化
2、抽象类可以实现接口
3、抽象类方法默认访问权限都是default
4、接口就是访问的,默认访问权限都是public

377、 为AB类的一个无形式参数无返回值的方法method书写方法头,可以用AB.method()方式调用,该方法头的形式为( )。 答案:A

A、static void method( )
B、public void method( )
C、final void method( )
D、abstract void method( )
解析:首先声明什么是静态方法:
用static修饰的方法
静态方法是使用公共内存空间的,就是说所有对象都可以直接引用,不需要创建对象再使用该方法。
其次说明静态方法的使用:
在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。
而实例方法只有后面这种方式。
也就是说,只有调用静态方法时可以无需创建对象。
根据题目.
1:AB为一个类,可以不创建对象,直接使用AB.method ("类名.方法名"的方式)
---------------所以method是static修饰的静态方法
2:其次method无返回值
----------------所以method是void类型的方法.
所以选B static void method();
2、A、static修饰方法,方法属于类本身,可以类名调用。
B、正常的实例方法,公有方法,必须实例化对象才可以调用。
C、final修饰方法,方法不可被重写,但是可以被重载。
D、abstract修饰方法,方法不能有方法体。abstract修饰方法,方法必须在抽象类或者接口中。

378、下列语句哪一个是不正确的() 答案:D

A、Log4j支持按分钟为间隔生成新的日志文件
B、Log4j是一个打印日志用的组件
C、Log4j支持按年为间隔生成新的日志文件
D、Log4j的日志打印级别可以在运行时重新设置
解析:日志的级别之间的大小关系如右所示:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF Log4j建议只使用四个级别,优先级从高到低分别是 ERROR > WARN > INFO > DEBUG。 log4j在运行期间是不可以重新设置的

379、以下代码执行后输出结果为( ) 答案: A
public class ClassTest{
     String str = new String("hello");
     char[] ch = {'a','b','c'};
     public void fun(String str, char ch[]){
     str="world";
     ch[0]='d';
 }
 public static void main(String[] args) {
     ClassTest test1 = new ClassTest();
     test1.fun(test1.str,test1.ch);
     System.out.print(test1.str + " and ");
     System.out.print(test1.ch);
     }
 }

A、hello and dbc
B、world and abc
C、hello and abc
D、world and dbc
解析:java中都是按栈中的值传递,基本数据类型栈中的值就是实际存储的值,引用类型栈中的值就是指向堆中的地址

1)String和char[ ]都是引用类型,所以在方法中传递的都是指向真实数据的地址

2)假设String str指向的hello的地址为d1,str传递到fun函数中的也是地址d1,成员变量str和fun的形参str不是同一个变量,把fun型中的str赋值为world只是修改了该str指向的地址,该地址由d1更改成了world的地址,并没有改变成员变量str指向的地址及堆中的数据,所以str还是hello。

3)假设char[ ] ch指向的abc的地址是d2,传递到fun函数中的地址也是d2,同上成员变量ch和fun的形参ch不是同一个变量,(1)如果把fun中的ch[0]='d’更改为ch = new ch[3];ch[0]=‘d’,那么成员变量ch的值是没有变化的,还是abc,原理同上String,只是改变了引用ch指向的堆数据的地址,并没有改变成员变量ch指向的地址以及堆中的数据。(2)改变了堆中的数据,所以最终结果编程dbc,此ch只是形参而不是成成员变量ch,如果对ch变化对成员变量ch没有影响,但是ch[i]指向了堆数据的地址,直接修改堆数据,所以成员变量变了。
2、

img

380、以下代码执行的结果是多少()? 答案:C
		public class Demo {
	public static void main(String[] args) {
		Collection<?>[] collections = 
{new HashSet<String>(), new ArrayList<String>(), new HashMap<String, String>().values()};
				Super subToSuper = new Sub();
				for(Collection<?> collection: collections) {
	System.out.println(subToSuper.getType(collection));
}
}
abstract static class Super {
	public static String getType(Collection<?> collection) {
		returnSuper:collection”;
}
public static String getType(List<?> list) {
		returnSuper:list”;
}
public String getType(ArrayList<?> list) {
		returnSuper:arrayList”;
}
public static String getType(Set<?> set) {
		returnSuper:set”;
}
public String getType(HashSet<?> set) {
		returnSuper:hashSet”;
}
}
static class Sub extends Super {
	public static String getType(Collection<?> collection) {
            return "Sub"; }
}
}

A、

Sub:collection
Sub:collection
Sub:collection

B、

Sub:collection
Sub:collection
Sub:collection

C、

Super:collection
Super:collection
Super:collection

D、

Super:hashSet
Super:arrayList
Super:collection

解析:这是静态分派的过程,在编译时已经决定了使用super的方法,因为subToSuper 是指super对象,可是为什么会选择collection呢,for循环出来他们实际上指的是collection对象表示的,即类似于Collection col = new HashSet<>();这样传入方法getType()中的参数就是col,左边是静态类型,右边是实际类型。由于重载实际上是使用静态分派的,重载时是通过参数的静态类型而不是实际类型作为判定依据的。详细参考深入理解java虚拟机248页解释。
2、考察点1:重载静态多分派——根据传入重载方法的参数类型,选择更加合适的一个重载方法
考察点2:static方法不能被子类覆写,在子类中定义了和父类完全相同的static方法,则父类的static方法被隐藏,Son.staticmethod()或new Son().staticmethod()都是调用的子类的static方法,如果是Father.staticmethod()或者Father f = new Son(); f.staticmethod()调用的都是父类的static方法。
考察点3:此题如果都不是static方法,则最终的结果是A. 调用子类的getType,输出collection

381、下面哪个选项没有实现 java.util.Map 接口? 答案:C

A、Hashtable
B、HashMap
C、Vector
D、IdentityHashMap
解析:A,B,D都实现了Map接口,其中A与B的区别是一个是线程安全的,一个是线程不安全的
C中Vector是实现了List接口,是一个线程安全的List
img

382、以下选项中循环结构合法的是: 答案:C

A、while(int i<7){i++;System.out.println("i is "+i);}
B、int j=3;while(j){ System.out.println("j is "+j);}
C、int j=0;for(int k=0;j+k!=10;j++,k++){System.out.println("j is "+j+“k is” +k);}
D、int j=0; do{System.out.println("j is "+j++);if(j3){continue loop;}}while(j<10);
解析:只有C对。
A、while(int i<7){i++;System.out.println("i is "+i);},int i要放在外面声明;
B、int j=3;while(j){ System.out.println("j is "+j);},java判断处为boolean类型,应该如j
3,j>1之类才行 ;不像C中,0可以表示假,非0可以表示真。java的真假就是true和false以及判别式。
C、int j=0;for(int k=0;j+k!=10;j++,k++){System.out.println("j is "+j+“k is” +k);},当j=5,k=5时循环结束;
D、int j=0; do{System.out.println("j is "+j++);if(j==3){continue loop;}}while(j<10);,continue loop前面没有标注出循环名loop,相当于未定义。

383、下面有关servlet中init,service,destroy方法描述错误的是? 答案:D

A、init()方法是servlet生命的起点。一旦加载了某个servlet,服务器将立即调用它的init()方法
B、service()方法处理客户机发出的所有请求
C、destroy()方法标志servlet生命周期的结束
D、servlet在多线程下使用了同步机制,因此,在并发编程下servlet是线程安全的
解析:servlet在多线程下其本身并不是线程安全的。
如果在类中定义成员变量,而在service中根据不同的线程对该成员变量进行更改,那么在并发的时候就会引起错误。最好是在方法中,定义局部变量,而不是类变量或者对象的成员变量。由于方法中的局部变量是在栈中,彼此各自都拥有独立的运行空间而不会互相干扰,因此才做到线程安全

2、当当头像当当
init方法: 是在servlet实例创建时调用的方法,用于创建或打开任何与servlet相的资源和初始 化servlet的状态,Servlet规范保证调用init方法前不会处理任何请求
service方法:是servlet真正处理客户端传过来的请求的方法,由web容器调用, 根据HTTP请求方法(GET、POST等),将请求分发到doGet、doPost等方法
destory方法:是在servlet实例被销毁时由web容器调用。Servlet规范确保在destroy方法调用之 前所有请求的处理均完成,需要覆盖destroy方法的情况:释放任何在init方法中 打开的与servlet相关的资源存储servlet的状态

384、URL u =new URL(“http://www.123.com”);。如果www.123.com不存在,则返回______。 答案: A

A、http://www.123.com
B、””
C、null
D、抛出异常
解析:我们在执行URL u =new URL(“http://www.123.com”);这句话的时候确实要抛出异常,但是这个异常属于IOException,不管网址是否存在,最后都会返回该网址的一个连接,打印出来就是该网址。

img

看源码可知,MalformedURLException是继承IOException的

img
2、new URL()时必须捕获检查异常,但这个异常是由于字符串格式和URL不符导致的,与网址是否存在无关。URL的toString方法返回字符串,无论网址是否存在。

img

385、servlet周期包含哪些: 答案:A B C

A、初始化
B、销毁
C、请求处理
D、开始
解析:init() --> 初始化
service() --> 处理请求
destory () --> 销毁(停止)
2、Servlet生命周期分成3个阶段:

1)初始化阶段:调用init方法

2)响应客户请求:调用service

3)终止:调用destory方法

初始化阶段:在下列时刻servlet容器装载servlet

1 servlet容器启动时,自动装载某些servlet

2 在servlet容器启动后,客户首次向servlet发送请求

3 servlet类文件被更新之后,重新装载servlet

Servlet被装载之后,servlet容器创建一个servlet’对象并调用servlet的init方法,在servlet生命周期内,init方法只能被调用一次。servlet工作原理:客户端发起一个请求,servlet调用service方法时请求进行响应,service对请求的方式进行了匹配,选择调用dopost或者doget等这些方法,然后进入对应方法中调用逻辑层的方法,实现对客户的响应。

响应客户请求:对于用户到达servlet的请求,servlet容器会创建特定于该请求的servletrequest和servletresponse对象,然后调用servlet的service方法,service方法从servletrequest对象中获取客户请求的信息,处理该请求,并且通过servletresponse对象向客户端返回响应信息。

终止:当web应用终止或者servlet容器终止或servlet容器重新装载servlet新实例时,servlet容器会调用servlet对象的destory方法,在destory方法中可以释放servlet占用的资源
2、img

386、在 main() 方法中给出数组buffer和下标i,如果将此下标中的元素显示到控制台上,需要使用( )。 答案: A

A、System.out.print (buffer[i]);
B、FileOutputStream fout = new FileOutputStream(this.filename);
C、FileInputStream fin = new FileInputStream(this.filename);
D、System.in.read(buffer)。
解析:在main中已经给出字节数组,直接System.out.print();输出即可。BC都是文件输出输入流,D是标准输入流,所以不符合题意。
答案:A, BC明显错误,这里又不是读取和写入文件,不存在filename 的,D的话,因为是数组,所以也错误。

387、关于访问权限,说法正确的是? ( ) 答案:A

A、类A和类B在同一包中,类B有个protected的方法testB,类A不是类B的子类(或子类的子类),类A可以访问类B的方法testB
B、类A和类B在同一包中,类B有个protected的方法testB,类A不是类B的子类(或子类的子类),类A不可以访问类B的方法testB
C、访问权限大小范围:public > 包权限 > protected > private
D、访问权限大小范围:public > 包权限 > private > protected
解析:img

388、能单独和finally语句一起使用的块是( ) 答案:A

A、try
B、catch
C、throw
D、throws
解析:解析:处理异常常用的两种方式:
1、try…catch(捕获处理机制);
2、throws(冒泡处理机制).
注意细节:使用try…catch块捕获时可以没有catch块,但当没用catch块的时候必须得有finally块.故选A)

389、在Java中,HashMap中是用哪些方法来解决哈希冲突的? 答案:: C

A、开放地址法
B、二次哈希法
C、链地址法
D、建立一个公共溢出区
解析:以上方法都是解决哈希填冲突的策略,但是在java.util.HashMap中,总体来说是使用的链地址法来解决冲突的。
当然了,使用链地址***导致get的效率从o(1)降至o(n),所以在Java8中,使用的是平衡树来解决提高效率的。
参考:http://blog

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值