震惊!这么简单的java基础题竟然都做错了!!

《Java面试十八式》------第三式【水晶之恋】

水晶之恋:java虐我千百遍,我待java为初恋,找回你被java初虐的感觉

害,一不小心用了震惊体,主要是前几篇文章观看者寥寥无几,连个提意见的都没有,看来是缺少干货,这篇文章,主要来测验下你是否肾虚,不对,测验你的java的基础是否牢靠。

在没有疫情之前,我们去面试肯定少不了笔试这一轮,现在虽然电话面试居多,但是基础可不能少

以下习题来自牛客网,首先声明我不是打广告,我是真的在牛客网刷题的,发现自己的底子确实很差

震惊!这么简单的java基础题竟然都做错了!!_第1张图片

我这里为大家总结几种题型,其中包括 String,类型转换,类的初始化,多态,数组,i++,标识符 等问题

大家肯定在想,这种题型你也考我,太简单了吧!

震惊!这么简单的java基础题竟然都做错了!!_第2张图片

莫慌,各位看官继续往下看。

String

一、String s = new String(“xyz”);创建了几个StringObject?
A. 两个或一个都有可能
B. 两个
C. 一个
D. 三个


二、已知String a="a",String b="b",String c=a+b,String d=new String("ab") 以下操作结果为true的是 (多选)

A. (a+b).equals( c )
B. a+b == c
C. c == d
D. c.equals(d)

答案&解析:

第一题:选A

解析:因为new字符串对象的时候,肯定会在堆中创建一个新的对象,然后他还会去看常量池是否有这个字符串,没有则创建,有就不创建,所以有可能是两个或者一个。

第二题:选A D
解析:
A选项:因为使用equals比较的是值是否相等,所以A正确
B选项:这里a和b使用的是变量,所以肯定是一个新的对象,所以和c的地址不相等
C选项:c和d都创建了新的对象 ,不相等
D选项,比较值,所以相等

知识点小总结:

==和equals的区别

==:既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址

equals: 他是java.lang.Object里的方法 如果没有被重写默认和==是一样的,如果复写过看具体复写的方法,但是String中的equals方法重写后比较的值是否相等


String对象的创建和比较

//①常量之间的比较
String a = "a"; 
String aa = "a";
System.out.println(aa == a ); //true
System.out.println(aa.equals(a) ); //true
//②常量相加
String a = "a"; 
String b = "b";
String c = "a" + "b";
System.out.println("a"+"b" == c ); //true
System.out.println(a+b == c ); //false

常量对象相加(“a”+“b”):会把"a" + “b” 优化成 “ab”
变量对象相加(a+b):只会在堆中产生新的对象

//③变量之间比较
String a = new String("a");
String aa = new String("a");
System.out.println(aa == a ); //false
System.out.println(aa.equals(a)); //true

对象创建
在创建对象时因为使用了new关键字,所以肯定会在堆中创建一个对象。然后会在常量池中看有没有要创建的字符串;如果没有 此时还会在常量池中创建一个;如果有 则不创建。所以一共会产生两个对象,每次创建新对象的地址都是不同的

//④变量+常量之间的比较
String a = "a"; 
String b = new String("b");
String c = a + "b";
System.out.println(a + b == c );//false

关于a + "b"的执行过程
底层会生成一个StringBuilder对象,随后调用SringBuilder中的append方法进行拼接,最后利用 StringBuilder.toString()的方法返回一个新的String对象,所以只要和变量相加就会产生新的对象
例:
new StringBuilder.append(a).append(“b”).toString();

基本类型转换

一、下面赋值语句中正确的是(多选)()
A. double d = 5.3e12;
B. float f = 11.1;
C. int i = 0.0;
D. Double oD = 3;
E. short s = 1; s = s + 1;
F. short s = 1; s += 1;

二、下面输出正确的是()

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.	以上都不对

三、关于下面代码片段叙述正确的是()

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.	运行期抛出异常

答案&解析:

第一题:选A F
解析:
A. 正确
B. 错误,11.1默认是double类型,double转型float需要强转,可用(float)11.1或11.1f
C. 错误,需要强转
D. 错误,Double是包装类,(自动装箱的目标必须严格对应它拆箱后的类型)
E. 错误,s + 1 最后的类型为int,转化成short需要强转
F. 正确,+= 会自动类型转换为前面的变量类型

第二题:选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

第三题:选C
解析:被final修饰的变量是常量,这里的b6=b4+b5可以看成是b6=10;在编译时就已经变为b6=10了
而b1和b2是byte类型,java中进行计算时候将他们提升为int类型,再进行计算,b1+b2计算后已经是int类型,赋值给b3,b3是byte类型,类型不匹配,编译不会通过,需要进行强制转换。

知识点小总结:

1.类型自动转换:低类型可以直接转换成高类型,Java中的byte,short,char进行计算时都会提升为int类型,注意计算结果为int类型,

2.强制类型转换:高类型若转为低类型,必须进行强制类型转换

3.强转发生的溢出或精度的下降:Byte类型值大小为-128~127之间,发生越界会从-128重新计算

4.final修饰的如何强转(常量):常量相加,加完之后看是否在数据类型范围内,如果不在则报错

5.包装类如何转化:包装类赋值的时候,严格对应精度,不会发生自动转换

6.+=的类型转换问题:+ 不会自动类型转换;+= 会自动类型转换为前面的变量类型

类初始化&多态

一.下面代码的输出是什么?

public class Base{
    private String baseName = "base"; 
    
    public Base(){
        callName();
    }
 
    public void callName(){
        System. out. println(baseName);
    }
 
	static class Sub extends Base{
        private String baseName = "sub";
    
        public void callName(){
            System. out. println (baseName) ;
        }
    }
    
    
    public static void main(String[] args){
        Base b = new Sub();
    }
    
}

A.	null
B.	sub
C.	base

二.下面代码的输出是什么?

public class P {
    
	public static int abc = 123;
    
    static{
  	  System.out.println("P is init");
    }
}

public class S extends P {
    static{
    	System.out.println("S is init");
    }
}

public class Test {
    public static void main(String[] args) {
   	 System.out.println(S.abc);
    }
}

A.	P is init,123
B.	S is init,P is init,123
C.	P is init,S is init,123
D.	S is init,123

三.下面代码的输出是什么?

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

A.	6 7 7
B.	22 34 17
C.	22 74 74
D.	11 17 34

答案&解析:

第一题:选 A
解析:首先创建子类对象,要先进行父类初始化,在父类初始化构造器的时候 调用的className()方法,因为我们创建的是子类实例,所以调用的是子类的className()方法,子类方法的baseName使用的是子类的属性,但是子类还未进行初始化,所以子类当前的baseName为null

第二题:选 A
解析:子类引用父类的静态字段,只会触发子类的加载、父类的初始化,不会导致子类初始化 而静态代码块在类初始化的时候执行,所以子类的静态代码块不会执行

第三题:选 B
解析:new B()创建子类实例,调用父类有参构造区super(5); 因为创建的是子类实例,所以这里的setValue(5)调用的是子类的,然后是super.setValue(2 * 5);到此value的值 = 10;
接下来看 setValue(getValue()- 3); 因为子类没有getValue,所以调用父类的getValue(),操作value++后,value变成了11,并将11等待返回,因为存在finally方法,所以还有继续执行finally,this.setValue(),这里的this指的是子类对象,所以调用子类的setValue()方法,11 * 2 = 22 输出打印
前面说了11在登台return返回 所以11- 3 = 8,然后继续setValue(8); 调用的子类的方法 所以 value变成了16,看最后的new B().getValue(),value++ = 17,17等待返回,进入finally方法,打印2*17 = 34,最后的return返回打印sout(17)。

知识点小总结:

类的加载顺序

1.父类静态代码块 ( java虚拟机加载类时,就会执行该块代码,故只执行一次)
2 .子类静态代码块 ( java虚拟机加载类时,就会执行该块代码,故只执行一次)
3.父类属性对象初始化
4.父类普通代码块(每次new,每次执行)
5.父类构造函数(每次new,每次执行)
6.子类属性对象初始化
7.子类普通代码块(每次new,每次执行 )
8.子类构造函数(每次new,每次执行)

this
构造器:在构造器中使用this,指的是构造器创建的新对象
方法:在方法中使用this,指的是调用该方法的对象
我们说了this表示的是某个对象,所以在静态方法和静态代码块是无法使用this的,因为当静态块初始化的时候还没有实例化对象

finally
①try或者catch有return,会先将要返回的值保存起来,然后继续执行finally,等finally执行结束,再将结果返回
②finally有return语句,无视try或者catch的return语句,执行finally的return

Switch

一.下面代码的输出是什么?

void main(void) {
    char *s = "1314520";
    int v1 = 0, v2 = 0, v3 = 0, v4 =0;
    for (int i = 0; s[i]; i++) {
        switch(s[i]) {
            default: v4++;
            case '1': v1++;
            case '2': v2++;
            cas3 '3': v3++;
        }
    }
    printf("%d, %d, %d, %d", v4,v1,v2,v3)
}

A.	3,5,6,7
B.	7,7,7,7
C.	7,2,1,1
D.	0,2,1,1

答案&解析:

第一题:选A
解析: 首先我们看v4进行几次,因为是default就是没有case匹配到,4,5,0,是无法被case匹配到的,所以default会执行3次,在default执行3次之后,因为没有break,所以还会往下继续执行,这样就导致了下面v1,v2,v3都执行了3次,然后数组中存在两个1,一个2,一个3,所以结果为3,5,6,7

知识点小总结:

知识点:
switch表达式可使用的类型:1.6支持byte、short、char、int,1.7之后支持了对String的判断。
执行顺序:没有遇到break或者return,会一直向下执行直到程序运行结束
default:当所有的case都没有匹配到的时候,才会执行

数组

一.定义一个存放50个String类型对象的数组,正确的是(多选)?

A.	char a[][];
B.	String a[];
C.	String[] a;
D.	Object a[50];
E.	String a[50];
F.	Object a[];

答案&解析:

第一题:选B C F
解析:A:char[][] 定义了二位字符数组。在Java中,使用字符串对char数组赋值,必须使用toCharArray()方法进行转换。所以A错误。

B、C:在Java中定义String数组,有两种定义方式:String a[]和String[] a。所以B、C正确。

D、E:数组是一个引用类型变量 ,因此使用它定义一个变量时,仅仅定义了一个变量 ,这个引用变量还未指向任何有效的内存 ,因此定义数组不能指定数组的长度。所以D、E错误。

F:Object类是所有类的父类。子类其实是一种特殊的父类,因此子类对象可以直接赋值给父类引用变量,无须强制转换,这也被称为向上转型。这体现了多态的思想。所以F正确。

知识点小总结:

数组在声明的时候不能给定长度
数组的三种创建方式:

	//1
	int[] arr1 = {1,2,3};
	//2
	int[] arr2;
	arr2 = new int[]{1,2,3}; 
	//3
	int[] arr3;
	arr3 = new int[3];

i++ 和++i

一.以下代码段执行后的输出结果为?

public class Test {
    public static void main(String args[]) {
        int i = -5;
        i =  ++(i++);
        System.out.println(i);
	}
}

A.	-7
B.	-3
C.	编译错误
D.	-5

二.最后输出什么??

  public void test() {
        int a = 10;
        System.out.println(a++ + a--);
    }

A.	19
B.	20
C.	21
D.	22
 

答案&解析:

第一题:选C
解析:++后应该跟变量。++(i++) 中的i++ 是一个字面量,也就是一个确定的值,所以编译不通过

第二题:选C
解析:a++ 先返回a = 10 再自增 a = 11,a-- 先返回a = 11 再自增 a = 12,所以10 + 11 = 21

知识点小总结:

①++后面跟的是变量
② ++i, 先自增,后使用,i++,先使用,后自增

标识符

一.以下标识符正确的是?(多选)

A.	Tree&Glasses
B.	FirstJavaApplet
C.	First_Applet
D.	273.5
E.	Sky
F.	$Computer
G.	for
H.	NULL
I.	9HelloWorld
J.	_Hello World
K.	Hello*World
L.	Hello$World

答案:

B C E F H L

知识点小总结:

Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。

关于Java标识符,有以下几点需要注意:

  • 所有的标识符都应该以字母(A-Z或者a-z),美元符($)、或者下划线(_)开始
  • 首字符之后可以是字母(A-Z或者a-z),美元符($)、下划线(_)或数字的任何字符组合
  • 关键字不能用作标识符
  • 标识符是大小写敏感的
  • 合法标识符举例:age、$salary、_value、__1_value
  • 非法标识符举例:123abc、-salary

不知道各位的肾还好吗,是觉得简单so easy还是觉得自己确实对某些知识点的概念有些模糊

另外我给大家提供了资料大礼包一份(共2G),大家可以关注我的公众号(在最下方!),回复:java面试题 来领取
震惊!这么简单的java基础题竟然都做错了!!_第3张图片

你可能感兴趣的:(java面试,java,面试)