Java小题精炼训练营(篇十一)

1、下面关于依赖注入(DI)的说法不正确的是()

只有通过Spring才能实现依赖注入(DI)
依赖注入的主要目的是解耦合
常见的依赖注入方式有Setter和构造方法

Spring依赖注入(DI)的三种方式,分别为:

1. 接口注入

2. Setter 方法注入

3. 构造方法注入

依赖注入的主要目的是解耦合。 常见的依赖注入方式有Setter和构造方法。  

A

2、假设 A 类有如下定义,设 a 是 A 类的一个实例,下列语句调用哪个是错误的?()

public class A
{
    public int i;
    static String s;
    void method1(){}
    static void method2(){}
}
System.out.println(a.i);
a.method1();
A.method1();
A.method2();

静态成员和静态方法,可以直接通过类名进行调用;其他的成员和方法则需要进行实例化成对象之后,通过对象来调用。

C

3、以上代码返回值是什么?

public boolean returnTest()
{
    try
    {
        return true;
    }
    catch (Exception e)
    {

    }
    finally
    {
        return false;
    }
}
true
false

finally其实是仅在return 语句执行前执行,如果return 一个函数,那么会先执行函数,但如果函数内有(return)语句,那么finally就会在这个return 语句前执行。finally在catch中的return之前执行但是如果catch中有返回值而finally中也有返回值的话finally中的返回值会替换catch中的返回值,因为catch中的返回值是存放在一个临时区中。

如果catch块有异常向外抛出,执行顺序呢:我执行我的,你抛你得异常,我finally我的语句,我俩互不干涉,你别管我啥时执行,但我一定会执行。

关于finally,您只需记着一点:除非调用system.exit()让程序退出(也就是将调用这个程序的进程断开了、退出了这个程序)就不会执行或断电等因素致使程序停止进程终止,否则,无论任何因素,finally块都一定会执行。

B

4、执行下列程序的输出结果为(      )

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");
         }
     }
 }

1.== 和 equals():

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

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

5、下面这三条语句

System.out.println(“is ”+ 100 + 5);
System.out.println(100 + 5 +“ is”);
System.out.println(“is ”+ (100 + 5));
is 1005, 1005 is, is 1005
is 105, 105 is, is 105
is 1005, 1005 is, is 105
is 1005, 105 is, is 105

1."is"说明后面的内容都会被强制转换为string,所以是最后结果是拼接起来的

2.100+5先得到105,然后与is拼接

3.先算括号内的

D

6、J2EE中,当把来自客户机的HTTP请求委托给servlet时,会调用HttpServlet的( )方法

service
doget
dopost
init

Servlet生命周期分为三个阶段:

1.初始化阶段  调用init()方法

2.响应客户请求阶段  调用service()方法

3.终止阶段  调用destroy()方法

A.首先Servlet通过HttpRequest对象封装http请求信息,然后Servlet容器调用HttpServlet的service方法,它会根据用户请求的方式调用具体的方法。如果请求方式是Get则调用doGet方法,如果请求方式是POST则调用doPost方法,执行完后,通过HttpRespones对象生成相应数据相应客户的请求,一般要重写doGet方法和doPost方法

A

7、transient 变量和下面哪一项有关?   

Cloneable
Serializable
Runnable
Comparable

通常一个类实现序列化方式是实现序列化接口 Serializable
序列化的作用:把数据长久的保存在磁盘中,磁盘和内存是不同的,内存一般在程序运行时占用,数据保存周期短,随程序结束而结束,磁盘可以长久保存数据
transient关键字的作用,在已实现序列化的类中,有的变量不需要保存在磁盘中,就要transient关键字修饰,如银行卡密码等,就这个作用------在已序列化的类中使变量不序列化

A

8、以下程序段的输出结果为:

public class EqualsMethod
{
    public static void main(String[] args)
    {
        Integer n1 = new Integer(47);
        Integer n2 = new Integer(47);
        System.out.print(n1 == n2);
        System.out.print(",");
        System.out.println(n1 != n2);
    }
}
false,false
false,true
true,false
true,true

==可用于基本类型和引用类型:当用于基本类型时候,是比较值是否相同;当用于引用类型的时候,是比较对象是否相同。
"=="和"!="比较的是地址 指第一个new()c出来的地址
所以因为两次new() 分出的内存也不同

B

9、以下描述错误的一项是( )?

程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行  到了第几行,是线程隔离的
原则上讲,所有的对象都是在堆区上分配内存,是线程之间共享的
方法区用于存储JVM加载的类信息、常量、静态变量,即使编译器编译后的代码等数据,是线程隔离的
Java方法执行内存模型,用于存储局部变量,操作数栈,动态链接,方法出口等信息,是线程隔离的

JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)

  • 栈区:
  1. 每个线程包含一个栈区,栈中只保存方法中(不包括对象的成员变量)的基础数据类型和自定义对象的引用(不是对象),对象都存放在堆区中
  2. 每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
  3. 栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
  • 堆区:
  1. 存储的全部是对象实例,每个对象都包含一个与之对应的class的信息(class信息存放在方法区)。
  2. jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身,几乎所有的对象实例和数组都在堆中分配。
  • 方法区:
  1. 又叫静态区,跟堆一样,被所有的线程共享。它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

Java运行时内存

1. 程序计数器,线程私有。可以看作是当前线程所执行的字节码的行号指示器,字节码解释器工作时就是通过改变整个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能。

由于JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,所以线程私有。

程序计数器是唯一一个在Java虚拟机规范中没有规定任何OOM的区域。

2. Java虚拟机栈,线程私有。生命周期和线程相同。虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧。每个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。

3. 本地方法栈,线程私有。和虚拟机栈的区别就在于一个是为了执行Java方法服务,一个是为了虚拟机使用到的Native方法服务。

4. 堆,线程共享。存放对象实例和数组。

5. 方法区,线程共享。存放已经被JVM加载的类信息,常量,静态变量,即时编译器编译后的代码。

简单来说 ,栈不可以被共享,而方法区、堆、线程可以被共享

C

10、如下代码的输出结果是什么?

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);
    } 
}
0
1
2
编译失败

静态变量只能在类主体中定义,不能在方法中定义

D

11、要导入java/awt/event下面的所有类,叙述正确的是?()

import java.awt.*和import java.awt.event.*都可以
只能是import java.awt.*
只能是import java.awt.event.*
import java.awt.*和import java.awt.event.*都不可以

导包只可以导到当前层,不可以再导入包里面的包中的类

C

12、Test.main()函数执行后的输出是( )

class Test {
    public static void main(String[] args) {
        System.out.println(new B().getValue());
    }
    static class A {
        protected int value;
        public A (int v) {
            setValue(v);
        }
        public void setValue(int value) {
            this.value= value;
        }
        public int getValue() {
            try {
                value ++;
                return value;
            } finally {
                this.setValue(value);
                System.out.println(value);
            }
        }
    }
    static class B extends A {
        public B () {
            super(5);
            setValue(getValue()- 3);
        }
        public void setValue(int value) {
            super.setValue(2 * value);
        }
    }
}

 本题中,始终需要遵循一个原则,即: 调用的方法都是实例化的子类中的重写方法,只有明确调用了super.xxx关键词或者是子类中没有该方法时,才会去调用父类相同的同名方法。

         首先,在main函数中,【new B()】new了一个B类的实例化对象,在实例化对象时,调用了B类中的构造函数,执行【super(5)】,也就是public A(int v)------>setValue(v),由于调用的方法必须是实例化子类中重写的方法的原则。因此,这里调用的是B类中的setValue(v)方法,此时B实例的value值设置为2 x 5 = 10,后执行super.setValue(10),将value=10的值存储起来。
        执行完super(5)后,执行构造函数中的【setValue(getValue()- 3)】中【getValue()】,由于B类中没有getValue()方法,则调用父类(A类)中的getValue()方法,value++所得到的值为11,并存储在value中(先执行finally中的部分,后执行try中的return),在finally中,调用了【this.setValue(value)】,由于调用的方法必须是实例化子类中重写的方法的原则,调用的是B类中的setValue(v)方法,此时B实例的value值设置为2 x 11= 22,之后执行System.out.println(value),即在控制台上打印22;
        执行完finally中的部分,后执行try中的return,将value++执行后,存储在value中的11,return回去;执行【setValue(getValue()- 3)】,即:setValue(8)。
        执行setValue(8)时,由于调用的方法必须是实例化子类中重写的方法的原则,则调用B类中的setValue(v)方法,此时B实例的value值设置为2 x 8= 16;此时B类中的构造函数执行结束。
        在实例化对象以后,执行【new B().getValue()】,由于B类中没有getValue()方法,则调用父类(A类)中的getValue()方法,value++所得到的值为17,并存储在value中,在finally中,调用了【this.setValue(value)】,由于调用的方法必须是实例化子类中重写的方法的原则,调用的是B类中的setValue(v)方法,此时B实例的value值设置为2 x 17= 34,之后执行System.out.println(value),即在控制台上打印34;
        执行完finally中的部分,后执行try中的return,将value++执行后,存储在value中的17,return回去;执行【System.out.println(new B().getValue())】,即在控制台上打印17。

        value值的变化过程,仅解释实例化对象时,构造函数中:super(5)与setValue(getValue()+3)两部分。图中两条线,起点分别为【new B()】与【setValue(getValue()+3)】

Java小题精炼训练营(篇十一)_第1张图片

B

13、 java关于异常处理机制的叙述哪些正确

catch部分捕捉到异常情况时,才会执行finally部分
当try区段的程序发生异常时,才会执行catch区段的程序
在try区段不论程序是否发生异常及捕获到异常,都会执行finally部分
以上都是

1.try和catch语句

●将要处理的代码放入try块中,然后创建相应的catch块的列表。如果生成都异常与catch中提到的相匹配,那么catch条件中的块语句就被执行。try块后可能有许多catch块,每个都处理不同的异常。每个catch中的参数都是Exception的子类。
2.finally语句

●finally语句定义一个总是执行的代码,而不考虑异常是否被捕获。
3.throw引起一个异常

‍●‍‍调用申明抛出异常

●‍throw语句强制抛出异常

BC

14、Java语言中,下面哪个语句是创建数组的正确语句?(     )

float f[][] = new float[6][6];
float []f[] = new float[6][6];
float f[][] = new float[][6];
float [][]f = new float[6][6];
float [][]f = new float[6][];

二维数组定义,一维长度必须定义,二维可以后续定义

ABDE

15、以下说法错误的是()

其他选项均不正确
java线程类优先级相同
Thread和Runnable接口没有区别
如果一个类继承了某个类,只能使用Runnable实现线程

B选项,在java中线程是有分优先等级的所以优先级不能相同,错误

C选项,Thread实现了Runnable接口是一个类不是接口,错误

D选项,实现多线程的三种方式,一种是继承Thread类使用此方式就不能继承其他的类了。还有两种是实现Runnable接口或者实现Callable接口

,所以D错误。

BCD

你可能感兴趣的:(Java小题训练营,java,开发语言,后端)