JavaSE阶段测试

  1. 下列说法正确的是__B_。
    A.Java程序经编译后会产生machine code(机器码)
    B.Java程序经编译后会产生byte code (字节码)
    C.Java程序经编译后会产生DLL(动态链接库)
    D.以上都不正确

  2. 设 int x = 1 , int y = 2 , int z = 3,则表达式 y+=z–/++x 的值是___A__。
    A.3
    B.3.5
    C.4
    D.5
    解:y = 2 + 3 / 2 = 3

  3. 0.6332的数据类型是__B___。
    A.float
    B.double
    C.Float
    D.Double
    解:如果是float需要加f,即是0.6322f,默认的话就是double
    Float和Double都是包装类

  4. 下列说法正确的有__C___。
    A.class中的constructor不可省略
    B.constructor必须与class同名,但方法不能与class同名
    C.constructor在一个对象被new时执行
    D.一个class只能定义一个constructor

  5. 以下关于继承的叙述正确的是__A___。
    A.在Java中类只允许单一继承
    B.在Java中一个类只能实现一个接口
    C.在Java中一个类不能同时继承一个类和实现一个接口
    D.在Java中接口只允许单一继承

解:D,类只允许单一继承,但接口支持多继承

  1. 构造方法名必须与__A___相同,它没有返回值,用户不能直接调用它,只能通过new调用。
    A.类名
    B.对象名
    C.包名
    D.变量名
  2. 下列说法中,__B___是正确的。
    A.子类拥有的成员数目大于父类拥有的成员数目
    B.父类代表的对象范围比子类广
    C.子类要调用父类的方法,必须使用super关键字
    D.一个Java类可以有多个父类

解:A.子类拥有的成员数目可以等于父类拥有的成员数目
B.比如Animal类比dog类广
C.子类如果没有重写父类中的成员方法,就可以直接调用父类的方法
D.普通类单一继承

  1. 下列哪种异常是检查型异常,需要在编写程序时声明__C___。
    A.NullPointerException
    B.ClassCastException
    C.FileNotFoundException
    D.IndexOutOfBoundsException

解:其他都是编译时异常

  1. 下面哪个流类属于面向字符的输入流__D___。
    A.BufferedWriter
    B.FileInputStream
    C.ObjectInputStream
    D.InputStreamReader

解:字符流:Reader和Writer
字节流:InputStream和OutputStream

  1. 阅读如下代码:which method, placed at line 6, will cause a compiler error(编译错误)? __ B___
class Super{
public float getNum(){return 3.0f;}
}

public class Sub extends Super{

 }

A.public float getNum(){return 4.0f;}
B.public void getNum(){}
C.public void getNum(double d){}
D.public double getNum(float d){return 4.0d;}

解:A.方法重写
B.既不是方法重写,也不是方法重载。仅仅返回类型不同不足以称为方法的重载。
C、D.方法重载

在Java中,同一个类中的多个方法可以有相同的方法名称,但是有不同的参数列表,这就称为方法重载(method overloading)。

参数列表又叫参数签名,包括参数的类型、参数的个数、参数的顺序,只要有一个不同就叫做参数列表不同。

说明:
参数列表不同包括:个数不同、顺序不同、类型不同。
仅仅参数变量名称不同是不可以的。
跟成员方法一样,构造方法也可以重载。
声明为final的方法不能被重载。
声明为static的方法不能被重载,但是能够被在此声明。

方法的重载的规则:
方法名称必须相同。
参数列表必须不同。
方法的返回类型可以相同也可以不相同。
仅仅返回类型不同不足以称为方法的重载。

  1. 阅读如下代码__B___
public class Demo11 {
    
    public static void add3(Integer i) {
        
        int val = i.intValue();
        val += 3;
        i = new Integer(val);
    }

    public static void main(String args[]) {
    
        Integer i = new Integer(0);
        add3(i);
        System.out.println(i.intValue());
    }
}

what is the result?
A.compile fail
B.print out “0”
C.print out “3”
D.compile succeded but exception at line 3
JavaSE阶段测试_第1张图片

  1. 下列场景中,__D___不会触发类加载过程。
    A.创建类的实例
    B.初始化子类
    C.访问类的字面值常量(即类名.class)
    D.访问对象的成员

  2. 下面代码的运行结果为:C_

public class Demo13{

    public static void main (String[] args){
        
        String s;
        System.out.println("s=" + s);
    }
}

A.代码得到编译,并输出“s=”
B.代码得到编译,并输出“s=null”
C.由于String s没有初始化,代码不能编译通过
D.代码得到编译,但捕获到NullPointException异常

解:局部变量使用的时候得初始化,不初始化你这引用变量指向谁呀你就打印输出呢。
成员变量你不赋值,系统会初始化。
所以代码如果这样写,打印的值为0.

public class Demo13{

    public int i;

    public static void main (String[] args){

        //String s;
        //System.out.println("s=" + s);

        Demo13 demo13 = new Demo13();
        System.out.println(demo13.i);
    }
}
  1. 以下对接口描述错误的有___D__。
    A.接口没有提供构造方法
    B.接口中的方法默认使用public、abstract修饰
    C.接口中的属性默认使用public、static、final修饰
    D.接口不允许多继承

解:A.构造方法实例化用的,接口能实例化么?不能,那要构造方法干啥
抽象类有构造方法,因为抽象类有一些成员变量,子类可能会调用父类的构造方法实例化父类的成员变量。
B、C对
D.接口允许多继承

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

解:C.方法区是线程共享的

  1. 关于守护线程的说法,正确的是___A__。
    A.所有非守护线程终止,即使存在守护线程,进程运行终止
    B.所有守护线程终止,即使存在非守护线程,进程运行终止
    C.只要有守护线程或者非守护进程其中之一存在,进程就不会终止
    D.只要所有的守护线程和非守护线程终止运行之后,进程才会终止

  2. 下列方法被调用后,一定使调用线程改变当前状态的是__C___。
    A.notify()
    B.run()
    C.sleep()
    D.isAlive()

解:A.notify不放弃执行权也不放弃锁对象。
B.run()和线程调度没关系,run()是需要重写的
C.sleep使当前线程进入阻塞状态
D.isAlive判断是否活着

  1. 有如下程序__C__
public class Demo18 {
    public void m() {
        Object o = new Float(3.14F);
        Object[] oa = new Object[1];
        oa[0] = o;
        o = null;
        oa[0] = null;
        System.out.println(oa[0]);
    }
}

对象o最早可以被垃圾回收器回收的位置是:
A.After line 4
B.After line 6
C.After line 7
D.After line 9(that is,as the method returns)

解:首先看一下动态数组的存储方式(week01_day05)。
JavaSE阶段测试_第2张图片
可以看出,两个引用都不指向Float(3.14F)这个包装类对象的时候才会被回收。
JavaSE阶段测试_第3张图片

  1. JAVA语言对象状态的持久化是通过__C___实现的。
    A.文件
    B.管道
    C.序列化
    D.过滤器

  2. 在TCP/IP中,解决计算机到计算机之间通信问题的层次是__B___。
    A.网络接口层
    B.网际层
    C.传输层
    D.应用层

解:TCP/IP协议族分4个层次:
网络接口层(network interface layer):最底层,是负责网络层与硬件设备之间的联系。
网际层(Internet layer):解决的是计算机到计算机的通信问题。
传输层(transmission layer):解决的是计算机程序到计算机程序之间的通信问题。
应用层(application layer):提供一组常用的应用程序给用户

  1. 如下程序打印的结果是什么呢?(注:答案包括编译失败或运行异常。请说明结果的同时注明原因,下面同上)
public class Demo21 {
    public static final int END = Integer.MAX_VALUE;
    public static final int START = END - 100;

    public static void main(String[] args) {

        int count = 0;
        for (int i = START; i <= END; i++)
            count++;
        System.out.println(count);
    }
}

答:这是个死循环,当i==Integer.MAX_VALUE这一次循环结束时,i自加1,这个时候栈溢出,i为-2147483648.(不理解的话看补码的加法那一节)
所以会先打印出从Integer.MAX_VALUE-100到Integer.MAX_VALUE
的这100个数,然后,从Integer.MIN_VALUE开始接着打印,直到Integer.MAX_VALUE,并重复

  1. 如下程序打印的结果是什么呢?如果在同包的某个main方法中运行Father father = new Son(1000),程序的输出结果是什么?
class Father {
    int i = 10;

    public Father() {
        System.out.println(getI());
    }

    public int getI() {
        return i;
    }
}

class Son extends Father {
    int i = 100;

    public Son(int i) {
        this.i = i;
    }

    @Override
    public int getI() {
        return i;
    }
}

答:0
父类方法被子类覆盖,即使在父类中调用,调用到的也是子类方法,而此时父类对象还在初始化过程中,子类对象更是还未开始初始化,其成员变量的值还是默认值。
这段代码最好debug一下,一目了然

  1. 如下程序打印的结果是什么呢?
public class Demo23 {

    public static void main(String[] args) {

        final String pig = "length: 10";
        final String dog = "length: " + pig.length();
        System.out.println("Animals are equal: " + pig == dog);
    }
}

答:false
因为先拼接"Animals are equal: " + pig得到新的字符串,然后在比较==

    System.out.println("Animals are equal: " + (pig == dog));//当代码改成这样后

因为pig引用变量指向字符串常量池中的一个常量,值为"length: 10",
dog引用变量也指向堆中的一块内存,内存中保存的值也为"length: 10",
但是这两个内存地址不同,而 == 判断的是pig和dog指向的内存地址是否相同,不同,所以依然返回false

  1. 如下程序打印的结果是什么呢?
public class Demo24 {

    public static void main(String[] args) {

        String str1 = "hello";
        String str2 = "he" + new String("llo");
        System.err.println(str1 == str2);
    }
}

答:false
str1引用变量指向字符串常量池中的一个常量,值为"hello",
str2引用变量指向内存中的一块内存空间
但是这两个内存地址不同,而 == 判断的是str1和str2指向的内存地址是否相同,不同,所以返回false

  1. 如下程序打印的结果是什么呢?
public class Demo25 {

    public static void main(String args[]) {

        Dog woofer = new Dog();
        Dog nipper = new Basenji();
        woofer.bark();
        nipper.bark();
    }
}


class Dog {

    public static void bark() {
        System.out.print("woof ");
    }
}

class Basenji extends Dog {

    public static void bark() {
    }
}

答:woof woof
静态方法不能被覆盖,也不能构成多态。子类中的bark()并没有对父类中的bark()方法进行重写
第一个woof 是woofer.bark(); 执行父类的bark方法所打印出来的
第二个woof 是nipper.bark(); 既然静态方法不能被覆盖,也不能构成多态。所以父类引用执行父类的bark方法。

  1. 如下程序打印的结果是什么呢?
public class Demo26 {

    public static void main(String[] args) {

        System.out.println(decision());
    }

    static boolean decision() {
        try {
            return true;
        } finally {
            return false;
        }
    }
}

答:false
finally代码块中的内容实在try代码块的return语句中间执行的,而当finally中的代码块执行完后,已经不需要执行try代码块中return语句的后半部分了。

  1. 如下程序打印的结果是什么呢?
public class Demo27 {

    public static void main(String[] args) {

        int[] x = {0, 1, 2, 3};
        for (int i = 0; i < 3; i += 2) {
            try {
                System.out.println(x[i + 2] / x[i] + x[i + 1]);
            } catch (ArithmeticException e) {
                System.out.println("errorl");
            } catch (Exception e) {
                System.out.println("error2");
            }
        }
    }
}

答:
errorl
error2
循环总共执行两次
第一次:i = 0,输出:x[2]/x[0]+x[1],x[0]为0,除零异常
错误处理器中的代码,一旦执行完毕,紧接着程序继续正常执行,执行的是整个try代码块之后的代码
第二次:i = 2 , x[4]不存在,数组越界异常

  1. 如下程序打印的结果是什么呢?
public class Demo28 {

    static {
        System.out.println("C");
    }

    {
        System.out.println("B");
    }

    public Demo28(){
        System.out.println("A");
    }

    public static void main(String[] args) {
        Demo28 testMain = new Demo28();
    }
}

答:
C
B
A
静态代码块中的内容随着类加载而执行,最先执行
构造代码块中的内容随着对象的创建而执行,但其次序先于构造方法
构造代码块相当于把所有构造方法里面的公共部分提取出来了,执行构造方法时,先执行构造代码块里面的代码,再执行构造方法。

  1. 如下程序打印的结果是什么呢?
public class Demo29 extends Thread {

    public static void main(String[] args) {

        Demo29 bground = new Demo29();
        bground.run();
    }

    public void start() {
        for (int i = 0; i < 10; i++) {
            System.out.println("B ground.start()" + i);
        }
    }
}

答:无打印结果
main方法中只有主线程一个线程在执行,
直接调用一个线程的run方法是不会启动一个子线程的,直接调用run方法相当于一个普通的方法调用
而且子类不对Thread类的run方法进行重写的话,啥也不执行,因为run()方法是一个抽象方法,也就是一个空方法。

  1. 如下程序打印的结果是什么呢?
public class Demo30 {

    private Demo30 internalInstance = new Demo30();

    public Demo30() throws Exception {
        throw new Exception("I'm not coming out");
    }

    public static void main(String[] args) {

        try {
            Demo30 b = new Demo30();
            System.out.println("Surprise!");
        } catch (Exception ex)
        {
            System.out.println("I told you so");
        }
    }
}

答:Stackoverflow error 在创建对象,给成员变量赋值时,无限递归,( private Demo30 internalInstance = new Demo30();
)且没有递归出口

  1. 引用类型和原始类型有何区别?

原始类型(基本数据类型),有8种,基本数据类型的变量一般创建在栈帧中
引用类型本质上是一个类,引用类型的对象一般创建在堆上

标准答案:
1.基本数据类型包括:byte,short,char, int,long,float,double,boolean
引用数据类型主要包括:类,接口等
基本数据类型的变量存储的是该类型变量的值,而引用数据类型的变量存储的是地址(比如堆中对象的地址)

  1. Java语言多线程设计中,为什么wait, notify 和 notifyAll这些线程通信的方法不在thread类里面?

wait, notify 和 notifyAll都在Object类中
wait方法会唤醒在其他线程中,在同一个锁对象上,调用了notify或notifyAll方法。而这些对象,不一定继承了Thread类,但一定继承了Object类,因为所有类都是Object的子类

标准答案:线程通信,其实是依靠锁对象,来完成的(对于wait方法而言,调用wait方法的对象,首先必须被当前线程,作为锁对象持有),而java语言中的锁对象,可以是任意对象,因此这些方法被定义在Object中

  1. 方法重载和方法重写的区别。

标准答案:方法重载是指在同一个类中定义同名方法,而这些方法名称相同,但方法签名不同。
方法重写,是指在子类中,修改父类中定义的方法的实现。因此,他们发生的范围是不同的,方法重载发生在一个任意类中,而方法重写,发生在子类中,而且发生方法重写和方法覆盖的条件也不相同(这里不再赘述),同时,方法重载是编译时多态,而方法重写是运行时多态的前提条件之一

在Java中,同一个类中的多个方法可以有相同的方法名称,但是有不同的参数列表,这就称为方法重载(method overloading)。

参数列表又叫参数签名,包括参数的类型、参数的个数、参数的顺序,只要有一个不同就叫做参数列表不同。

说明:
参数列表不同包括:个数不同、顺序不同、类型不同。
仅仅参数变量名称不同是不可以的。
跟成员方法一样,构造方法也可以重载。
声明为final的方法不能被重载。
声明为static的方法不能被重载,但是能够被在此声明。

方法的重载的规则:
方法名称必须相同。
参数列表必须不同。
方法的返回类型可以相同也可以不相同。
仅仅返回类型不同不足以称为方法的重载。(因为只有返回值不同,参数列表都相同,调用的时候你知道调用的是哪个方法啊)

  1. 字符流和字节流最主要的区别是什么?如何理解字符流=字节流+编码表?

字节流中数据的逻辑单位是单个字节
字符流中数据的逻辑单位是单个字符对应的字节数据

所有的字符流都是包装流,都包装了一个字节流。其底层的数据传输都要基于字节流来完成。字符流本身只做了一件事情:编码和解码。

a)字符数据在内存中还是以二进制(字符的在编码表中对应的编码值)的形式保存和传输
b)而对于二进制的字节数据的写和读,字节流就已经能够很好的完成了
c) 但为了保证字符流中的数据是一个一个的完整字符,所以字符流在字节流的基础上,添加了编解码器,即在使用底层字节流写数据前,先利用编码器,对字符数据进行编码得到字符数据对应的二进制编码序列,然后利用底层字节流传输它们,同时,在读取数据的时候,先用解码器,将由底层字节流传输的字节数据,解码成一个一个的字符。

所以字符流的功能实现是字节流 + 编码表(基于编码表的编解码操作)

  1. 同步和异步有何异同,在什么情况下分别使用他们?

异步简单来说就是,线程之间,各自独立运行,互不影响,就好像线程之间“同时”,在各自做自己的事情,简单来说,就是我走你也走
同步和异步相对,同步是指线程之间不能在各自为政,自己运行自己的,而是在某些情况下等待其他线程。简单来说,就是我走你不走

线程天生就是异步执行的,而当多线程异步访问同一个共享数据的时候,为了保证共享数据访问的正确性,必须保证同时只有一个线程,能访问并修改共享变量的值,这意味着,如果一个线程正在,访问某共享变量,则其他所有要访问该共享变量的线程都需要等待,直到,该线程访问完毕。

  1. "=="和equals方法有何异同?

== 对于基本数据类型的数据而言,比较的是内容,对于引用数据类型的数据而言,比较的引用变量,所指向的内存地址。
equals方法是Object类的方法,其默认实现是比较两个对象的内存地址是否相同,若想:要比较量对象的内容是否相同,则需要在子类中覆盖Object的equals方法

  1. 写深度克隆的clone()方法时,该方法题通常都有一行代码,是什么?

super.clone(),因为该方法其实是在调用Object的clone方法,首先实现对该对象自身的浅克隆,然后在针对,该对象的引用变量做进一步的处理

  1. java中实现运行时多态的前提条件有哪些?
    a. 继承
    b. 要有方法覆盖
    c. 父类引用指向子类对象

  2. Java多线程中调用wait() 和 sleep()方法有什么不同?

Thread.sleep VS Object.wait()

相同点是两者都可以使一个线程处于阻塞状态

A. 所属不同:
a. sleep定义在Thread类,静态方法
b. wait定义在 Object类中,非静态方法

B. 唤醒条件不同
a. sleep: 休眠时间到
b. wait: 在其他线程中,在同一个锁对象上,调用了notify或notifyAll方法

C. 使用条件不同:
a. sleep 没有任何前提条件
b. wait(), 必须当前线程,持有锁对象,锁对象上调用wait()

D. 休眠时,对锁对象的持有,不同:(最最核心的区别)
a. 线程因为Sleep方法而处于阻塞状态的时候,在阻塞的时候不会放弃对锁的持有
b. 但是wait()方法,会在阻塞的时候,放弃锁对象持有

  1. 使用缓冲流是否可以在一定程度改善应用程序的IO的效率?为什么??

缓冲流可以从一定程度上改善Java程序的IO效率。因为,IO的底层实现,是要依靠操作系统内核的功能来实现的,而我们的java程序每次请求操作系统内核的功能完成IO的时候,都需要付出额外的代价。既然,每次完成IO操作,都需要付出一次通信代价,那么意味着,一次IO操作如果读写的数据越多,那么平均到每个字节(字符)的数据,所付出的额外代价就会越小。
而缓冲流,本身维护了一个较大的缓冲区,能够在和操作系统内核交互的过程中,一次读写较多的字节(字符)数据,从而在整个数据传输过程中,减少java程序和操作系统内核通信的次数。从而减少了,应用程序为了完成功能,所需要付出的额外代价

  1. 编程题:设计一个字符串哈希算法(不允许使用hashCode()方法)。
    第一题,只要给一个字符串,根据该字符串的内容,自己给个映射规则,实现将该字符串转化成一个对应整数即可
    比如简单的:把字符串对应的字节数值累加,得到一个整数(这就是一种简单的字符串到整数的hash映射),当然这种映射可以有很多很多,这里不再一一赘述
public class Demo41 {

    public static void main(String[] args) {

        String str = "what's up man?";
        byte[] bytes = str.getBytes();
        int i;
        int hashcode = 0;
        for (byte b : bytes) {
            i = (int) b;
            hashcode = (hashcode + i) % 27;
        }
        System.out.println("str的哈希码为:" + hashcode);
    }
}
  1. 编程题:输入一个整型数组,数组里面有正数也有负数,数组中连续的一个或多个整数组成子数组,每个子数组都有一个和。求所有子数组的和的最大值。例如,输入的数字为:1,-2,3,10,-4,7,2,-5,则和最大的子数组为3,10,-4,7,2和为18。
    JavaSE阶段测试_第4张图片
    JavaSE阶段测试_第5张图片

注:java不支持if(1)、while(0)这种写法,只能用if(true)或while(false)

你可能感兴趣的:(JavaSE)