记录Javaの一次考试

今天 考试了
试卷以及答案

不定选择题(30分)
1.下面程序哪个语句是正确的( )
A. byte a=0,b=3; byte c =a+b; 默认int
B. short s =23; s=s+12; 默认int
✅C. short s=23; s+=12; 默认(short)(s = s+12)
D. float f = 23+23.23;缺少f后缀

  1. 下面程序的运行后,结果正确的是:()
    int a=1,b=2;
    int c=(a+b>3?a++:++b); a+b=3 执行++b语句 b = b+1 ->b = 3 a保持不变 c = 3
    A. a=2,b=3 ✅B. a=1,b=3 C. a=1,b=2 D. c=2
    3.下面程序执行的结果
    for(int i=1;i<=10;i++){
    if (i%3==0) {
    continue; }
    System.out.println(“java基础”);
    }
    在屏幕上打印几次“java基础”?( )
    3 6 9不打印 1,2,4,5,7,8,10 共七次打印
    A. 5 B. 6 ✅C. 7 D. 8
  2. 阅读下面代码段:
    classDemo{
      public static void main (String[] args){
    int[] arr = new int[10];
       System.out.println(arr[1]);
      }}
    执行结果正确的说法是( ) 数组未初始化 默认为0
    A. 编译时将产生错误 B. 编译时正确,运行时将产生错误
    C.✅ 输出零 D. 输出空
  3. 和下面代码能完成相同的选项是()
    int i=1;
    intsum=0;
    while(i<=100){
    if(i%2==0){
    sum=sum+i;
    }
    i++;
    } 此代码为1到100所有的偶数求和
    A. for (int x=1; x<=100;x++){ sum=sum+x;} B✅. for (int x =0; x<=100;x+=2){ sum=sum+x;}
    C. for (int x =1; x<=100;x+=2){ sum=sum+x;} D.上述全对
  4. 以下对继承的描述错误的是()
    A)✅ Java中的继承允许一个子类继承多个父类 java不允许多继承
    B) 父类更具有通用性,子类更具体 正确
    C) Java中的继承存在着传递性 正确
    D) 当实例化子类时会递归调用父类中的构造方法 正确
    //对象创建的过程
    // 0.按照1~5顺序构造父类,但依次先类加载所有类型
    // 1.类加载:静态代码块
    // 2.默认初始化成员变量
    // 3.显式初始化成员变量
    // 4.实例代码块
    // 5.构造方法
  5. 下面哪些是合法的标志符()
    A. 2variable(数字不能做开头) B✅. variable2 C✅. what$ D✅. 3
  6. 下列方法中能和方法int max(int a, int b, double c)构成重载关系的是( )
    函数的重载就是在同一个类中允许同时存在一个以上的同名函数,只要它们的参数个数或类型不同即可。
    在同一个类中可以定义多个同名方法—方法名重载(overload)。
    A. double max(int a, int b, double c) B✅. void max(int a, double c, int b)
    C✅. int max(double a, int b) D. int max(int x, int y, double z)
  7. 下面关于循环描述正确的是()
    A✅. while循环先判断循环条件,后执行循环操作 B. while 至少会执行一次
    C. do-while先进行循环条件判断,后执行循环操作 D.✅ do-while循环至少执行一次,后进行循环判断
  8. 以下关于final关键字说法错误的是()
    A✅) final是java中的修饰符,可以修饰类、接口、抽象类、方法和属性
    final关键字不能用来抽象类和接口。
    B) final修饰的类肯定不能被继承
    C✅) final修饰的方法不能被重载
    方法可以被重载 不能被重写
    D) final修饰的变量不允许被再次赋值
  9. 根据下面的代码,
    String s = null;会抛出NullPointerException异常的有()
    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) )
    考察短路
  10. 以下关于对象序列化描述正确的是( )
    A) 使用FileOutputStream可以将对象进行传输
    不行!

B✅) 使用PrintWriter可以将对象进行传输
C✅) 使用ObjectOutputStream类完成对象存储,使用ObjectInputStream类完成对象读取
D✅) 对象序列化的所属类需要实现Serializable接口

  1. 下面是有关子类继承父类构造函数的描述,其中正确的是:( )
    A. 创建子类的对象时,先调用子类自己的构造函数,然后调用父类的构造函数。 错误
    //对象创建的过程
    // 0.按照1~5顺序构造父类,但依次先类加载所有类型
    // 1.类加载:静态代码块
    // 2.默认初始化成员变量
    // 3.显式初始化成员变量
    // 4.实例代码块
    // 5.构造方法

B. 子类可以不调用父类的构造函数 错误
C✅. 子类必须通过super()关键字调用父类的构造函数
D. 子类可以继承父类的构造函数。 错误

  1. 构造函数何时被调用( )
    A、类定义时 B✅.创建对象时
    C.调用对象方法时 D.使用对象的变量时
  2. 函数重载是指 ( )
    A✅、两个或两个以上的函数取相同的函数名,但形参的个数或类型不同
    B、两个以上的函数取相同的名字和具有相同的参数个数,但形参的类型可以不同
    C、两个以上的函数名字不同,但形参的个数或类型相同
    D、两个以上的函数取相同的函数名,并且函数的返回类型相同

判断题(T/F)(10分)

  1. HashMap集合不允许存储重复键. ✅
  2. 在Java中声明变量时可以不指定一个类型。 ❎ java是强语言
  3. 数组有length()这个方法。 ❎ 数组只有length属性
  4. Object是Java中所有类的共同父类。 ✅
  5. 一个数组可以存放不同类型的数值。 ❎ 只能存放同一个类型的数值
  6. 对象是类的实例. ✅
  7. 被final修饰后的类,只能指向一个对象,地址不能再更改,对象内部的成员也不能修改。 ❎ 对象内部的成员可以修改
  8. 静态变量是被同一个类的所有实例所共享的。 ✅
  9. Java中所有的I/O都是通过流来实现的。 ✅
  10. static关键字可以修饰成员变量,也可以修饰局部变量。 ❎ static不能修饰局部变量
    填空题(10分)
  11. 一个long型数据在内存占( 8 )个字节。
  12. 表达式19/3*3+19%3的值是( 19 )。 18+1=19
  13. 若a和b都是整数,则生成[a, b]范围内随机整数的表达式是( Math.Random()*(b-a+1)+a )
  14. 若char型变量c存储的是一个大写字母,则输出其对应小写字母的语句是( System.out.println(c+32) )
  15. 面向对象特点是( 封装 )、( 继承 )、( 多态 )。
  16. JVM运行java分为( 编译 )、( 运行 )两个阶段。
  17. 使用继承关键字是( extends )。
  18. Exception分为( 运行时异常 )、( 编译时异常 )两大类。
  19. 所有字节输出流的超类是( InputStream ),所有字节输入流的超类是( OutputStream )。
  20. 所有集合的父接口是( Collections )。
    解答题(20分)
    1.”==”和”equals”的区别。
    == 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。
    equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。
    2.简单说明函数重载和函数重写。
    Override是覆盖的意思,也就是重写,它与返回值类型无关,只看参数列表;
    Overload是重载的意思,表示在同一个类中,允许存在一个以上的同名函数,只要他们的参数个数或者参数类型不同即可;
    两者不同主要体现在:目的不同、范围不同、参数要求不同、返回类型不同。
  • 同:overload用于增加程序的可读性(做法不同,但是做的同一事情)。 override用于提供其超级类已经提供的方法的特定实现。
  • 同:overload 在相同的类范围内内执行。 override发生在两类具有继承(继承)的关系。
  • 参数要求不同:overload参数必须不同。 override参数必须相同。
  • 返回类型不同:overload中可以相同或不同。 override必须是相同的或协变的。
    3.请说出作用域public,private,protected,以及不写时的区别
    1、public: 所修饰的类、变量、方法,在内外包均具有访问权限;
    2、protected: 这种权限是为继承而设计的,protected所修饰的成员,对所有子类是可访问的,但只对同包的类是可访问的,对外包的非子类是不可以访问;
    3、包访问权限(default): 只对同包的类具有访问的权限,外包的所有类都不能访问; 不写的时候
    4、private: 私有的权限,只对本类的方法可以使用;
  1. String s = “Hello”;s = s + “ world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?String s1=new String(“java”)创建了几个对象?
    1)原始的内容没有改变 JVM在堆内存中创建了一个新的“Helloworld”对象,原来的“Hello”对象成为废弃对象
    2)如果之前的代码没有新建内容为“java”的对象在堆内存中,则创建了两个对象,否则创建了一个对象。
    5.java的基本数据类型有哪些?
    byte,short,int,long,float,double,boolean,char
  2. final, finally, finalize的区别。
    final:Java中关键字,修饰符。
    如果一个类被声明为final,则意味着该类不能被继承,无法派生出新的子类。所以,一个类不能同时被abstract和final修饰。
    如果将变量或者方法声明为final,可以保证变量和方法在以后的使用中,不会被修改。被final修饰的变量必须在声明时赋初值,在以后的引用中只能读取,不能修改。被final修饰的方法只能使用,不能被重写。
    finally:表示一种异常处理机制。
    finally是对Java异常处理模型的最佳补充。finally结构使代码总会执行,而不管无异常发生。使用finally可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。

finalize: Java中的Object类的一个方法名。
Java中,垃圾收集器在将对象从内存中清除出去前,需要使用finalize()方法做一些必要的清理工作。这个方法是由垃圾收集器在确定该对象没有被引用时,对该对象调用**finalize()**方法。因为该方法是在Object类中定义的,因此所有的类都继承了该方法。子类可以覆盖该方法来整理系统资源或者执行其他的清理工作。

  1. 实现一个线程的两种方式;调用start()方法和run()方法有什么区别?
    1)1.通过继承Thread类实现线程
    2.通过实现Runnable接口实现线程
    2)start()方法是开启了一个线程,会自动调用run()方法,此时程序会自动往下执行,此时不等start()方法执行完。
    如果线程直接调用run()方法,则程序会等run()方法执行完再往下执行。

  2. 说出ArrayList,Vector, LinkedList的存储性能和特性
    1)ArrayList和Vector都是数组作为底层,查找比较方便,不擅长大量的添加和删除。Vector与ArrayList相比线程安全
    2)LinkedList是以链表作为底层,添加删除比较方便,查找效率较低。

  3. 什么是java序列化,如何实现java序列化?
    1)序列化:把对象转换为字节序列的过程称为对象的序列化。
    2)实现Serializable接口,再使用ObjectOutputStream类 即可序列化java类

  4. 说说&和&&的区别。
    1.&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
    2.&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x==33 & ++y>0) y会增长,If(x==33 && ++y>0)不会增长
    3.&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。
    编程题(30分)
    1.Account.java文件中定义了一个银行帐户类Account,其中包括了帐户名属性accountName、存款余额属性amount、存款方法deposit(double money)。阅读并理解这个类,并为其增加一个“取款”方法withdraw():当存款余额大于取款金额时,执行取款修改余额;当存款余额小于取款金额时,不执行取款;以返回值0表示取款成功,返回值1表示取款不成功。
    public class Account {
    private String accountName;
    private double amount;
    public void deposit(double money){
    if(money>0){
    this.amount+=money;
    }
    }

    public int withdraw(double money){
    if(money<amount){
    amount=amount-money;
    return 0;
    }
    else{
    return 1;
    }
    }

    public Account(String accountName, double amount) {
    this.accountName = accountName;
    this.amount = amount;
    }

    public Account() {
    }
    }
    2.复制一个文件到另一个目录。
    public class Copy {
    public static void main(String[] args) throws IOException {
    // 1.创建流对象
    // 1.1 指定数据源
    FileInputStream fis = new FileInputStream(“D:\test.jpg”);
    // 1.2 指定目的地
    FileOutputStream fos = new FileOutputStream(“test_copy.jpg”);
    // 2.读写数据
    // 2.1 定义数组
    byte[] b = new byte[1024];
    // 2.2 定义长度
    int len;
    // 2.3 循环读取
    while ((len = fis.read(b))!=‐1) {
    // 2.4 写出数据
    fos.write(b, 0 , len);
    }
    // 3.关闭资源
    fos.close();
    fis.close();
    }
    }
    3.键入一个字符串,求其中每个字符出现的次数,并按顺序打印,打印格式如下:
    a:5
    b:1
    f:3

    public class Test1 {
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    String s;
    System.out.print(“请输入字符串”);
    s = sc.nextLine();
    Map<Character,Integer> map=new TreeMap<>();
    char[] chars = s.toCharArray();
    for(int i=0;i<chars.length;i++){
    if(map.get(chars[i])==null){
    map.put(chars[i],1);
    }else{
    map.put(chars[i],map.get(chars[i])+1);
    }
    }
    Set<Map.Entry<Character, Integer>> entries = map.entrySet();
    Iterator<Map.Entry<Character, Integer>> iterator = entries.iterator();
    while (iterator.hasNext()){
    Map.Entry<Character,Integer> entry=iterator.next();
    System.out.println(entry.getKey()+”:”+entry.getValue());
    }
    }
    }

1. 作业评讲:

* 数组的第一项是a[0]
* if(b=true) 太繁琐 直接写成 if(b)
* 求平均分要记得将sum设置成double 求的时候
double avg = sum / (a.length/1.0);

2. 讲解了课堂练习:

1)输入一串字符串,输出里面有多少个a,多少个b,多少个c…
先用了测试类 junit4是不支持Scanner的 所以不能用test,要用main方法
可以通过’c’-‘a’的差值 得到索引值,通过int数组进行获取

public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);//System.in默认的关联就是键盘
       System.out.print("请输入一串小写字母:");
       String str = sc.nextLine();//以回车符号作为结束的标志
       //可以为了测试方便 先把str的值写死,省去输入字符串的时间
       System.out.println(str);
       int[] arr = new int[26];
       for (int i = 0; i < str.length(); i++) {
           char a = str.charAt(i);
           int index = a - 'a';
           arr[index]+=1;
       }
       for (int i = 0; i < arr.length; i++) {
           char s = (char)('a'+ i);
           if(arr[i]!=0)
               System.out.println(s + "的个数:" + arr[i]);
       }
   }

2)输入1200的整数,5个奇数,5个偶数 不能重复 奇数偶数不能超过5个的上限 最后打印结果 AZ a~z
提示信息:
继续输入
结果例子:
您输入结果:
奇数: 1 5 7 65(A) 17* 素数
自己写的版本:

public class Test2 {
    public static boolean isSu(int a){
        boolean isSuSu = false;
        if(a==1){
            return false;
        }else if(a==2){
            return true;
        }
        else{
            for (int i = 2; i < a; i++) {
                if(a%i==0){
                    isSuSu = false;
                }else
                {isSuSu = true;}
            }
        }
        return isSuSu;
    }
    public static char isChar(int a){
        char ss = (char)a;
        if((ss>'a'&&ss<'z')||(ss>'A'&&ss<'Z')){
            return ss;
        }else{
            ss = ' ';
        }
        return ss;
    }
    public static boolean isJi(int a){
        boolean isJiJi = true;
        if(a%2==0){
            isJiJi = false;
        }else
        {
            isJiJi = true;
        }
        return isJiJi;
    }
    public static boolean isContain(int a,int[] arr){
        boolean isContains = false;
        for (int aa:
             arr) {
            if(aa==a){
                isContains = true;
            }
        }
        return isContains;
    }
    public static void printNum(int[] arr){
        for (int a :
                arr) {
            String str = a+"";
            if (isSu(a)){
                str += "*";
            }
            if(isChar(a)!=' '){
                str += "(" + (char)isChar(a) + ")";
            }
            System.out.print(str + '\t');
        }
        System.out.println();
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int jiShu[] = new int[5];
        int ouShu[] = new int[5];
        int indexJi = 0;
        int indexOu = 0;
        while (true){
            System.out.print("请输入1~200的数字:");
            int input = sc.nextInt();
            if(input>=1&&input<=200){
                if(input%2==0){
                   if(indexOu>=5||isContain(input,ouShu)){
                       System.out.println("偶数数量已满5个或者有重复数字!");
                       continue;
                   }
                    ouShu[indexOu] = input;
                    indexOu++;
                }
                else {
                    if(indexJi>=5||isContain(input,jiShu)){
                        System.out.println("奇数数量已满5个或者有重复数字!");
                        continue;
                    }
                    jiShu[indexJi] = input;
                    indexJi++;
                }
            }
            else{
                System.out.println("你不认识字吗?");
                continue;
            }
            if(indexJi>=5&&indexOu>=5){
                break;
            }
        }//输入部分
        System.out.println("您输入结果:");
        System.out.print("奇数:");
        printNum(jiShu);
        System.out.print("偶数:");
        printNum(ouShu);
    }
}

写代码之前一定要分析好需求和设计好写法 多用模块化

面试题:

  1. 一个类与它的对象之间是什么关系?
    答:类是对象的抽象,是一个拥有静态属性(如姓名,年龄)和动态属性(如睡觉跑步)的一个模板
  2. 如何定义一个类,由哪些部分组成,各个部分的作用是什么?
    答:语法格式:
    [< 修饰符>] class < 类名>
    {
    [<属性声明>]
    [<构造器声明>]
    [<方法声明>]
    }
    修饰符是用来做访问控制,类名就是类的名字,属性声明是类的静态属性,方法声明是类的动态属性。
    说明:修饰符public:类可以被任意访问,类的正文要用{ }括起来
  3. 如何创建一个对象,如何使用该对象?
    答:< 类名> [对象名] = new <类名> [<构造方法>]
    通过【对象名】.[属性名] 或者 [对象名].[方法名]进行使用
  4. 局部变量和成员变量的区别?
    答:A:在类中的位置不同
    成员变量:在类中方法外
    局部变量:在方法定义中或者方法声明上
    B:在内存中的位置不同
    成员变量:在堆内存
    局部变量:在栈内存
    C:生命周期不同
    成员变量:随着对象的创建而存在,随着对象的消失而消失
    局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
    D:初始化值不同
    成员变量:有默认初始化值
    局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
    注意事项:
    局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
  5. 构造方法和成员方法的区别?
    答:构造方法是初始化一个类的对象时候调用的,它没有返回值,而且名字必须与类的名字一样,而成员函数是由类对象主动调用的,使用点操作符,它有返回值
    构造函数是赋予对象”生命特征”的,成员方法则是对象所具有的”行为,能力”
    构造函数只有在建立对象时由系统调用的,其他任何时候你都别指望用他.