java面试题相关持续更新

变量和常量

  • A:案例演示
    • 面试题:看下面的程序是否有问题,如果有问题,请指出并说明理由。
    • byte b1 = 3;
    • byte b2 = 4;
    • byte b3 = b1 + b2;(报错,可能损失精度)
      • 从两方面去回答这个题
      • b1和b2是两个变量,变量里面存储的值都是变化的,所以在程序运行中JVM是无法判断里面具体的值
      • byte类型的变量在进行运算的时候,会自动类型提升为int类型
    • byte b4 = 3 + 4;(可以正常运行无错误)
      • 3和4都是常量,java有常量优化机制,就是在编译的的时候直接把3和4的结果赋值给b4了

        运算符

  • A:案例演示

    • 请分别计算出a,b,c的值?
    • int a = 10;
      int b = 10;
      int c = 10;
      
      a = b++;        a=10,b=11        
      c = --a;        a=9,c=9    
      b = ++a;        a=10,b=10
      a = c--;        a=9,c=8    
      所以最后结果a=9,b=10,c=8
      
  • B:案例演示

    • 请分别计算出x,y的值?

      int x = 4;
      int y = (x++)+(++x)+(x*10);
               4 + 6 + 60
      结果x=6,y=70
      
  • C:面试题
    • byte b = 10; 正常
    • b++; 正常(与下对比正常因为,运算符会有自动强转)
    • b = b + 1; 报错,可能损失精度
    • 问哪句会报错,为什么
  • D位运算符
    * 请自己实现两个整数变量的交换(不定义第三方变量)
    
    • 例子

      逻辑运算符&&和&的区别

  • A:案例演示
    • &&和&的区别?
      • a:最终结果一样。
      • b:&&具有短路效果。左边是false,右边不执行。
      • &是无论左边是false还是true,右边都会执行
      • 例子

        赋值符

  • A:案例演示
    • 面试题:看下面的程序是否有问题,如果有问题,请指出并说明理由。
    • short s=1;s = s+1; //报错可能损失精度,因为也要提升为int计算,结果也是int
    • short s=1;s+=1; //正常不报错,s+ 和++一样也会自动加强转符号

选择结构switch语句

  • A:switch语句的格式
  • if放的是条件表达式
  • switch可以接受
  • 1.基本数据类型可以接受:byte,short,char,int(也就是可以转为int计算的比int精度高的不可以)
  • 2.引用数据表达式可以接受枚举(JDK1.5) 、String(1.7)
  • B:面试题
    • byte可以作为switch的表达式吗? 可以
    • long可以作为switch的表达式吗?不可以
    • String可以作为switch的表达式吗?JDK1.7以后版本可以
  • C:注意事项
    • a:case后面只能是常量,不能是变量,而且,多个case后面的值不能出现相同的
    • b:default可以省略吗?
      • 可以省略,但是不建议,因为它的作用是对不正确的情况给出提示。
      • 特殊情况:
        • case就可以把值固定。
        • 如只有A,B,C,D4个选项
    • c:break可以省略吗?
      • 最后一个可以省略,其他最好不要省略
      • 否则会出现一个现象:case穿透。
      • 最终建议不要省略
    • d:default一定要在最后吗?
      • 不是,可以在任意位置。但是建议在最后。
    • e:switch语句的结束条件
      • a:遇到break就结束了
      • b:执行到switch的右大括号就结束了
  • D:两个例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    * A:看程序写结果:
    *
    int x = 2;
    int y = 3;
    switch(x){
    default:
    y++;
    break;
    case 3:
    y++;
    case 4:
    y++;
    }
    System.out.println("y="+y); 4
    * B:看程序写结果:
    *
    int x = 2;
    int y = 3;
    switch(x){
    default:
    y++;
    case 3:
    y++;
    case 4:
    y++;
    }
    System.out.println("y="+y); 6
  • E:switch和if各自使用场景

    • A:总结switch语句和if语句的各自使用场景
  • switch建议判断固定值的时候用
  • if建议判断区间或范围的时候用

循环相关

 j=1;
while(j<999);{

 }
  • 注意while条件后面加分号,大括号内的语句就无法执行了。
  • A:案例演示
    • 三种循环语句的区别:
    • do…while循环至少执行一次循环体。
    • 而for,while循环必须先判断条件是否成立,然后决定是否执行循环体语句。
  • B:案例演示
    • for循环和while循环的区别:
      • A:如果你想在循环结束后,继续使用控制条件的那个变量,用while循环,否则用for循环。不知道用谁就用for循环。因为变量及早的从内存中消失,可以提高内存的使用效率。
  • C:死循环
  • (循环结构注意事项之死循环)
  • A:一定要注意控制条件语句控制的那个变量的问题,不要弄丢了,否则就容易死循环。
  • B:两种最简单的死循环格式
    • while(true){…}
    • for(;;){…}
  • D:break、continue
    • break跳出循环
    • continue终止本次循环继续下次循环
  • E:break,continue综合练习题
  • for(int x=1; x<=10; x++) {
        if(x%3==0) {
            //在此处填写代码
        }
        System.out.println(“Java基础班”);
    }
    
    我想在控制台输出2次:“Java基础班“
    我想在控制台输出7次:“Java基础班“
    我想在控制台输出13次:“Java基础班“    
    
    1
    2
    3
    4
    5
    6
    7
    8
    for(int x=1; x<=10; x++) {
    if(x%3==0) {
    //break; //我想在控制台输出2次:“Java基础班“
    //continue; //我想在控制台输出7次:“Java基础班“
    System.out.println("Java基础");//我想在控制台输出13次:“Java基础班“
    }
    System.out.println("Java基础");
    }

(控制跳转语句return语句)

  • A:return的作用
    • 返回
    • 其实它的作用不是结束循环的,而是结束方法的。
  • B:案例演示
    • return和break以及continue的区别?
    • return是结束方法
    • break是跳出循环
    • continue是终止本次循环继续下次循环

      标号

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      //mark 标记
      outer: for (int i = 1;i <= 10 ;i++ ) { //outer就是标号,只要是合法的标识符即可
      System.out.println("i = " + i);
      inner: for (int j = 1;j <= 10 ;j++ ) {
      System.out.println("j = " + j);
      break outer;//跳出整个大循环,如果不加跳出一个
      }
      }
      System.out.println("大家好");
      http://www.heima.com
      //注意上一行也无错误为标号后面为单行注释
      System.out.println("才是真的好");

数组

  • 输出结果为
  • [代表几维数组,I代表int类型@固定后面为16进制地址
  • A:二维数组格式1

    int[][] arr = new int[3][2];
    
  • A:二维数组格式2
    • int[][] arr = new int[3][];
    • arr[0] = new int[3];
    • arr[1] = new int[5];
  • B:注意事项

    • a:以下格式也可以表示二维数组
      • 1:数据类型 数组名[][] = new 数据类型[m][n];
      • 2:数据类型[] 数组名[] = new 数据类型[m][n];
    • b:注意下面定义的区别
    • int x;
      int y;
      int x,y;
      
      int[] x;
      int[] y[];
      
      int[] x,y[];    x是一维数组,y是二维数组
      

      Java中的内存分配以及栈和堆的区别

  • A:栈(掌握)
    • 存储局部变量(引用) 例 int[] arr =new int[3]; arr(引用)在栈,int数组在堆
    • 还有方法
  • B:堆(掌握)
    • 存储new出来的数组或对象
  • C:方法区
    • 面向对象部分讲解,简单来说代码区
  • D:本地方法区
    • 和系统相关
  • E:寄存器
    • 给CPU使用

      Java中的参数传递

  • /*
    基本数据类型的值传递,不改变原值,因为调用后就会弹栈,局部变量随之消失
    引用数据类型的值传递,改变原值,因为即使方法弹栈,但是堆内存数组对象还在,可以通过地址继续访问

Java中到底是传值还是传址
1,既是传值,也是传地址,基本数据类型传递的值,引用数据类型传递的地址
2,java中只有传值,因为地址值也是值(出去面试都说这种,支持者是高司令(java之父))

面向对象中的一些概念

1.面向对象创建一个对象的步骤

  • A:
    • Student s = new Student();
    • 1,Student.class加载进内存
    • 2,栈中声明一个Student类型引用s
    • 3,在堆内存创建对象,
    • 4,给对象中属性默认初始化值
    • 5,属性进行显示初始化
    • 6,构造方法进栈,对对象中的属性赋值,构造方法弹栈
    • 7,将对象的地址值赋值给s
      07.10_面向对象(static关键字的特点)(掌握)
  • A:static关键字的特点
    • a:随着类的加载而加载
    • b:优先于对象存在
    • c:被类的所有对象共享
      • 举例:咱们班级的学生应该共用同一个班级编号。
      • 其实这个特点也是在告诉我们什么时候使用静态?
        • 如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
      • 举例:
        • 饮水机(用静态修饰)
        • 水杯(不能用静态修饰)
        • 共性用静态,特性用非静态
    • d:可以通过类名调用
      • 其实它本身也可以通过对象名调用。
      • 推荐使用类名调用。
      • 静态修饰的内容一般我们称其为:与类相关的,类成员
  • B:一个类中都是静态方法
    • 如果一个类中方法都是静态的,那要多做一步,创建静态构造函数,目的不让其他类创建本类对象

2.static的注意事项

  • A:static的注意事项
    • a:在静态方法中是没有this关键字的
      • 如何理解呢?
        • 静态是随着类的加载而加载,this是随着对象的创建而存在。
        • 静态比对象先存在。
    • b:静态方法只能访问静态的成员变量和静态的成员方法
      • 静态方法:
        • 成员变量:只能访问静态变量
        • 成员方法:只能访问静态成员方法
      • 非静态方法:
        • 成员变量:可以是静态的,也可以是非静态的
        • 成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
      • 简单记:
        • 静态只能访问静态。

3.静态变量和成员变量的区别

  • 静态变量也叫类变量 成员变量也叫对象变量
  • A:所属不同
    • 静态变量属于类,所以也称为为类变量
    • 成员变量属于对象,所以也称为实例变量(对象变量)
  • B:内存中位置不同
    • 静态变量存储于方法区的静态区
    • 成员变量存储于堆内存
  • C:内存出现时间不同
    • 静态变量随着类的加载而加载,随着类的消失而消失
    • 成员变量随着对象的创建而存在,随着对象的消失而消失
  • D:调用不同
    • 静态变量可以通过类名调用,也可以通过对象调用
    • 成员变量只能通过对 象名调用

      4.代码块相关

    • A:代码块概述
    • 在Java中,使用{}括起来的代码被称为代码块。
  • B:代码块分类
    • 根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。
  • C:常见代码块的应用
    • a:局部代码块
      • 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
    • b:构造代码块 (初始化块)
      • 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
    • c:静态代码块
      • 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,优先于main方法,并且只执行一次。
      • 一般用于加载驱动
  • A:看程序写结果
  • class Student {
        static {
            System.out.println("Student 静态代码块");
        }
    
        {
            System.out.println("Student 构造代码块");
        }
    
        public Student() {
            System.out.println("Student 构造方法");
        }
    }
    
    class Demo2_Student {
        static {
            System.out.println("Demo2_Student静态代码块");
        }
    
        public static void main(String[] args) {
            System.out.println("我是main方法");
    
            Student s1 = new Student();
            Student s2 = new Student();
        }
    }
    

    继承相关

    1.继承的好处和弊端

  • A:继承的好处
    • a:提高了代码的复用性
    • b:提高了代码的维护性
    • c:让类与类之间产生了关系,是多态的前提
  • B:继承的弊端

    • 类的耦合性增强了。

    • 开发的原则:高内聚,低耦合。

    • 耦合:类与类的关系
    • 内聚:就是自己完成某件事情的能力

2.Java中类的继承特点

  • A:Java中类的继承特点
    • a:Java只支持单继承,不支持多继承。(一个儿子只能有一个爹)
      • 有些语言是支持多继承,格式:extends 类1,类2,…
    • b:Java支持多层继承(继承体系)
  • B:案例演示
    • Java中类的继承特点
      • 如果想用这个体系的所有功能用最底层的类创建对象
      • 如果想看这个体系的共性功能,看最顶层的类

3.继承的注意事项和什么时候使用继承

  • A:继承的注意事项
    • a:子类只能继承父类所有非私有的成员(成员方法和成员变量)
    • b:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法。
    • c:不要为了部分功能而去继承
    • 项目经理 姓名 工号 工资 奖金
    • 程序员 姓名 工号 工资
  • B:什么时候使用继承

    • 继承其实体现的是一种关系:”is a”。
      Person

      Student
      Teacher
      

      水果

      苹果
      香蕉
      橘子
      

      采用假设法。
      如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。

4.this和super的区别和应用

  • A:this和super都代表什么
    • this:代表当前对象的引用,谁来调用我,我就代表谁
    • super:代表当前对象父类的引用
  • B:this和super的使用区别
    • a:调用成员变量
      • this.成员变量 调用本类的成员变量,也可以调用父类的成员变量
      • super.成员变量 调用父类的成员变量
    • b:调用构造方法
      • this(…) 调用本类的构造方法
      • super(…) 调用父类的构造方法
    • c:调用成员方法
      • this.成员方法 调用本类的成员方法,也可以调用父类的方法
      • super.成员方法 调用父类的成员方法

5.继承中构造方法的关系

  • A:案例演示
    • 子类中所有的构造方法默认都会访问父类中空参数的构造方法
  • B:为什么呢?

    • 因为子类会继承父类中的数据,可能还会使用父类的数据。
    • 所以,子类初始化之前,一定要先完成父类数据的初始化。

    • 其实:

      • 每一个构造方法的第一条语句默认都是:super() Object类最顶层的父类。

6.继承中构造方法的注意事项

  • A:案例演示
    • 父类没有无参构造方法,子类怎么办?
    • super解决
    • this解决
  • B:注意事项
    • super(…)或者this(….)必须出现在构造方法的第一条语句上

7.继承中的面试题

  • A:案例演示
  • 看程序写结果1
    class Fu{
    public int num = 10;
    public Fu(){

    System.out.println("fu");
    

    }
    }
    class Zi extends Fu{
    public int num = 20;
    public Zi(){

    System.out.println("zi");
    

    }
    public void show(){

    int num = 30;
    System.out.println(num);
    System.out.println(this.num);
    System.out.println(super.num);
    

    }
    }
    class Test1_Extends {
    public static void main(String[] args) {

    Zi z = new Zi();
    z.show();
    

    }
    }

    看程序写结果2
    class Fu {
    static {

    System.out.println("静态代码块Fu");
    

    }

    {

    System.out.println("构造代码块Fu");
    

    }

    public Fu() {

    System.out.println("构造方法Fu");
    

    }
    }

    class Zi extends Fu {
    static {

    System.out.println("静态代码块Zi");
    

    }

    {

    System.out.println("构造代码块Zi");
    

    }

    public Zi() {

    System.out.println("构造方法Zi");
    

    }
    }

    Zi z = new Zi(); 请执行结果。

8.方法重写概述及其应用

  • A:什么是方法重写
    • 重写:子父类出现了一模一样的方法(注意:返回值类型可以是子父类,这个我们学完面向对象讲)
  • B:方法重写的应用:
    • 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。这样,即沿袭了父类的功能,又定义了子类特有的内容。
  • C:案例演示
    • a:定义一个手机类。

9.方法重写的注意事项

  • A:方法重写注意事项

    • a:父类中私有方法不能被重写
      • 因为父类私有方法子类根本就无法继承
    • b:子类重写父类方法时,访问权限不能更低
      • 最好就一致
    • c:父类静态方法,子类也必须通过静态方法进行重写

      • 其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解(静态只能覆盖静态)
    • 子类重写父类方法的时候,最好声明一模一样。

  • B:案例演示
    • 方法重写注意事项

10. 方法重写的面试题

  • A:方法重写的面试题

    • Override和Overload的区别?Overload能改变返回值类型吗?
    • overload可以改变返回值类型,只看参数列表
    • 方法重写:子类中出现了和父类中方法声明一模一样的方法。与返回值类型有关,返回值是一致(或者是子父类)的

    • 方法重载:本类中出现的方法名一样,参数列表不同的方法。与返回值类型无关。

    • 子类对象调用方法的时候:

      • 先找子类本身,再
      • 找父类。

        final关键字

  • A:final概述
  • B:final修饰特点

    • 修饰类,类不能被继承
    • 修饰变量,变量就变成了常量,只能被赋值一次 一半与public公用如 public static int a;
    • 修饰方法,方法不能被重写

      多态

      class Fu {
          public void show() {
              System.out.println("fu show");
          }
      }
      
      class Zi extends Fu {
          public void show() {
              System.out.println("zi show");
          }
      
          public void method() {
              System.out.println("zi method");
          }
      }
      
      class Test1Demo {
          public static void main(String[] args) {
              Fu f = new Zi();
              f.method();//这句有问题不能调用子类特有的方法
              f.show();
          }
      }
      
  • B:看下面程序是否有问题,如果没有,说出结果

  • class A {
        public void show() {
            show2();
        }
        public void show2() {
            System.out.println("我");
        }
    }
    class B extends A {
        public void show() {
            show2();
        }
        public void show2() {
            System.out.println("爱");
        }
    }
    class C extends B {
        public void show() {
            super.show();
        }
        public void show2() {
            System.out.println("你");
        }
    }
    public class Test2DuoTai {
        public static void main(String[] args) {
            A a = new B();
            a.show();
    
            B b = new C();
            b.show();
        }
    }
    

    *输出爱你,因为show方法可以继承下来,第二个因为调用父类show,而show方法调用show2调用的还是子类的show2,所以输出的是你。

抽象相关

  • A:面试题1
    • 一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
      • 可以
      • 这么做目的只有一个,就是不让其他类创建本类对象,交给子类完成
  • B:面试题2
    • abstract不能和哪些关键字共存
      • abstract和static不能共存
        • 因为被abstract修饰的方法没有方法体
        • 被static修饰的可以用类名.调用,但是类名.调用抽象方法是没有意义的
      • abstract和final不能共存
        *被abstract修饰的强制子类重写而被final修饰的不让重写
      • abstract和private
        *被abstract修饰的是为了让子类看见而private不让子类看见

        面向对象

        权限

        本类     同一个包下(子类和无关类)    不同包下(子类)    不同包下(无关类)
        
        private Y
        默认 Y Y
        protected Y Y Y
        public Y Y Y Y

        面向对象(成员内部类的面试题

  • A:面试题
  • 要求:使用已知的变量,在控制台输出30,20,10。
    
    class Outer {
        public int num = 10;
        class Inner {
            public int num = 20;
            public void show() {
                int num = 30;
                System.out.println(?); num
                System.out.println(??); this.num
                System.out.println(???); Outer.this.num
            }
        }
    }
    class InnerClassTest {
        public static void main(String[] args) {
            Outer.Inner oi = new Outer().new Inner();
            oi.show();
        }    
    }
    
  • B ==号和equals方法的区别
  • ==是一个比较运算符号,既可以比较基本数据类型,也可以比较引用数据类型,基本数据类型比较的是值,引用数据类型比较的是地址值
  • equals方法是一个方法,只能比较引用数据类型,所有的对象都会继承Object类中的方法,如果没有重写Object类中的equals方法,equals方法和==号比较引用数据类型无区别,重写后的equals方法比较的是对象中的属性

String类

  • 1.判断定义为String类型的s1和s2是否相等

    String s1 = "abc";
    String s2 = "abc";
    System.out.println(s1 == s2);   //true 虽然比较的是引用对象,但是String放在常量池里,所以是一样的
    System.out.println(s1.equals(s2)); //true
    
  • 2.下面这句话在内存中创建了几个对象?

    String s1 = new String(“abc”);
    //创建了2个,一个是在常量池创建‘“abc”这个对象,另一个是在堆里创建

  • 3.判断定义为String类型的s1和s2是否相等

    String s1 = new String(“abc”);
    String s2 = “abc”;
    System.out.println(s1 == s2); ? //false 第一个s1是在堆内存中,s2是在常量池中
    System.out.println(s1.equals(s2)); ? //true

  • 4.判断定义为String类型的s1和s2是否相等

    String s1 = “a” + “b” + “c”;
    String s2 = “abc”;
    System.out.println(s1 == s2); ? //true,java中有常量优化机制所以等同于上述1题,指向同一个常量值“abc”
    System.out.println(s1.equals(s2)); ? //true

  • 5.判断定义为String类型的s1和s2是否相等

    String s1 = “ab”;
    String s2 = “abc”;
    String s3 = s1 + “c”;
    System.out.println(s3 == s2); //false 注意s3=s1+”c”;其中s1是变量,并不是常量,由其和“+”符号相连得到的字符串不在常量池,而是在堆内转换的
    System.out.println(s3.equals(s2)); ? //true

  • 6.String,StringBuffer,StringBuilder的区别

    • StringBuffer和StringBuilder的区别
    • StringBuffer是jdk1.0版本的,是线程安全的,效率低
    • StringBuilder是jdk1.5版本的,是线程不安全的,效率高

    • String和StringBuffer,StringBuilder的区别

    • String是一个不可变的字符序列
    • StringBuffer,StringBuilder是可变的字符序列

Integer

  • 看程序写结果
    
    Integer i1 = new Integer(97);
    Integer i2 = new Integer(97);
    System.out.println(i1 == i2);       //false
    System.out.println(i1.equals(i2));  //true        
    System.out.println("-----------");
    
    Integer i3 = new Integer(197);
    Integer i4 = new Integer(197);
    System.out.println(i3 == i4);      //false
    System.out.println(i3.equals(i4)); //true
    System.out.println("-----------");
    
    Integer i5 = 127; //-128-127都可以
    Integer i6 = 127;
    System.out.println(i5 == i6);      //true
    System.out.println(i5.equals(i6)); //true
    System.out.println("-----------");
    
    Integer i7 = 128;   大于等于128
    Integer i8 = 128;
    System.out.println(i7 == i8);      //false
    System.out.println(i7.equals(i8)); //true
    
    * 上述两个“==”判断结果不同,因为JDK5新特性,有自动装箱机制,
    * -128-127是byte的取值范围,如果在这个范围就不会创建新的对象
    * 但是超过这个范围内就会创建对象了
    
坚持原创技术分享,您的支持将鼓励我继续创作!