• 面试2——java基础1


    1.int和Integer的区别

    1、Integer是int的包装类,int则是java的一种基本数据类型 
    2、Integer变量必须实例化后才能使用,而int变量不需要 
    3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值 
    4、Integer的默认值是null,int的默认值是0

    5、Integer的值缓存范围为-128~127

    延伸: 
    关于Integer和int的比较 
    1、由于Integer变量实际上是对一个Integer对象的引用,所以两个通过new生成的Integer变量永远是不相等的(因为new生成的是两个对象,其内存地址不同)。

    Integer integer1 = new Integer(100);
    Integer integer2 = new Integer(100);
    System.out.println(integer1==integer2); false

    2、Integer变量和int变量比较时,只要两个变量的值是向等的,则结果为true(因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较)

    Integer integer = new Integer(100);
    int a = 100;
    System.out.println(integer==a); true

    3、非new生成的Integer变量和new Integer()生成的变量比较时,结果为false。(因为非new生成的Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象,两者在内存中的地址不同)

    Integer integer3 = new Integer(200);
    Integer j = 200;
    System.out.println(integer3==j); false

    4、对于两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true,如果两个变量的值不在此区间,则比较结果为false

    Integer a1 = 200;
    Integer b1 = 200;
    System.out.println(a1==b1); false
    Integer a1 = 100;
    Integer b1 = 100;
    System.out.println(a1==b1); true

    涉及的知识点:

    1.java数据类型

    基本数据类型:byte、int、short、long、float、double、char、boolean

    引用数据类型:数组、类、接口

    2.自动封箱和自动拆箱

    自动装箱是将一个java定义的基本数据类型赋值给相应封装类的变量。

    拆箱与装箱是相反的操作,自动拆箱则是将一个封装类的变量赋值给相应基本数据类型的变量。


     2.equals和==的区别

    比较对象是值变量:“==”常被用来比较基本数据类型(byte,int,short,long,float,double,char,boolean),变量直接存储的就是他们的值,所以“==”比较的就是他们的值,注意的是,基本数据类型不能用equals进行比较(equals是个函数,而基本类型不是对象)。

    比较对象是引用型变量:“==” 比较的是两个变量在堆中存储的地址是否相同。equals表示的是两个变量是否对同一个对象的引用,即堆中的内容是否相同。==比较的是两个对象的地址,equals比较的是两个对象的内容,equals为true时,“==”不一定为true。

    equals是object的一个方法,创建的对象均可调用object的equals方法,但是使用equals方法时,要对它进行重写,否则它和==比较的效果一样。

    总结:

    == : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不试同一个对象。

    equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况(前面第1部分已详细介绍过):
                     情况1,类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。
                     情况2,类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。

    //object中定义的equals方法
    public
    boolean equals(Object obj) { return (this == obj); }

     3.Java面向对象的基本特征

    • 继承  子类继承父类   ,子类可以获取到父类的属性和方法                                                                                                                                                                             

       注:关于子类能否继承父类的私有方法? 

             从语言角度上说:JDK官方文档明确说明子类不能继承父类的私有方法; 
            但从内存角度来说,jvm在实例化子类对象之前,会先在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类对象。所以子类确实拥          有父类所有的属性和方法,但是父类中的私有方法子类无法访问。  

    • 封装  

        封装可以使类具有独立性和隔离性;保证类的高内聚。只暴露给类外部或者子类必须的属性和操作。类封装的实现依赖类的修饰符(public、protected和private等)

    • 多态

                  多态是在继承的基础上实现的。多态的三个要素:继承、重写和父类引用指向子类对象。父类引用指向不同的子类对象时,调用相同的方法,呈现出不同的行为;就是类多               态特性。多态可以分成编译时多态和运行时多态。

    • 抽象

      提取现实世界中某事物的关键特性,为该事物构建模型的过程。对同一事物在不同的需求下,需要提取的特性可能不一样。得到的抽象模型中一般包含:属性(数据)和操作(行为)。这个抽象模型我们称之为类。对类进行实例化得到对象。


    4. &和&&的区别

    &:按位与 &&:逻辑与

    &&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进行运算。

    例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为:username != null &&!username.equals(“”),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。


    5.值传递和引用传递

    所谓的值传递对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。

    引用传递一般是相对于对象型来说的,传递的是该对象在内存中保存的地址信息的一个副本,并不是原对象本身,原对象本身存放在堆中。


     6.Java中的方法重写(Overriding)和方法重载(Overloading)

    方法覆盖:发生在子类和父类之间。子类重新定义了父类的方法,方法覆盖必须有相同的方法名,参数列表以及返回值类型。子类要比父类被重写的方法有更好的访问,不能声明比父类更多的异常

    方法重载:同一类中两个或多个方法名相同但是参数列表(参数个数,参数类型)不同的方法,对返回结果不做要求。

    重写和重载是多态的实现方式,重载实现的编译时的多态性,后者实现的是运行时的多态性。


     7.接口和抽象类的 区别

    抽象方法是一种特殊的方法:它只有声明,没有具体的实现。abstract void a();  抽象方法必须用abstract关键字进行修饰。

    如果一个类中具有抽象方法,那么这个类就是抽象类。一个类中只要包含抽象方法,那么这个类就是抽象类,抽象类也可以包含非抽象方法。一个类中没有抽象方法,它只要被abstract关键字修饰,那么它也是抽象方法。抽象类中含有无具体实现的方法,所以抽象类不能被实体化。

    包含抽象方法的为抽象类,并不意味着,抽象类中只能具有抽象方法,和普通类一样,抽象类同样可以拥有成员变量和普通的成员方法。

    普通类和抽象类的区别

    1. 抽象类必须要为public或者protected,因为要对它进行继承,不能使用private,若不写,默认为public。

    2.抽象类不能被实体化,普通类可以。

    3.如果一个类继承一个抽象类,则子类必须实现抽象类中的所有抽象方法。如果子类没有实现父类的所有抽象方法,需要把子类也定义为abstract类。

    接口:用interface修饰的, 接口中可以包含变量和方法,变量被隐式地指定为public static final变量(只能是public static fianl)。而方法被隐式指定为public abstract(用其他关键字,private,protected,static,final会报编译错误),所有接口中的方法只能是抽象方法。接口不能被实体化。

    接口和抽象类的区别

    参数 抽象类 接口
    默认的方法实现 它可以有默认的方法实现 接口完全是抽象的,根本不存在方法的实现
    实现

    子类使用extend关键字来继承抽象类。如果子类不是 抽象类的话

    它需要提供抽象类中所有声明的抽象方法的实现。

    子类使用关键字implement来实现接口。

    它需要提供接口中所有声明的方法的实现。

    构造器 抽象类可以有构造器(从语法的角度来说,抽象类必须有构造方法,而接口严禁有构造方法,这本身也说明了它们性质的不同。抽象类是一个类,别的类是用关键字 extends 来继承下来,并扩展的,有非常强的is-a的关系,这种关系一般来说符合里氏代换原则。而接口,是被其他类用关键字 implements 来实现接口定义的方法的) 接口不能 有构造器(接口是一种规范,被调用时,主要关注的是里边的方法,而方法是不需要初始化的)
    与正常java类的区别 除了不能实例化之外,与普通类没有区别 接口是完全不同的类型
    访问修饰符 抽象类可以被public、protected和default修饰符修饰 接口默认的修饰符为public,不可以使用其他修饰符
    main方法 抽象类中可以有main方法。 接口中没有main方法
    多继承 抽象类只能继承一个类和实现多个接口 接口只能继承一个或多个其他接口
    速度 抽象类比接口速度要快 接口是稍微有点慢的,它需要时间去寻找在类中实现的方法
    添加新方法 可以给他提供默认的实现 需要改变实现该接口的类

     8.final、finally和finalze的区别

    final:用final进行声明属性、方法和类,分别表示属性不可变,方法不可重写,类不可继承。

    finally:异常处理语句结构中的一部分,表示总是执行。

    try {
                
            } catch (Exception e) {
                // TODO: handle exception
            }finally {
                
            }

    finalze:是object类中的一个方法,当垃圾回收器将要回收对象所占内存之前被调用,即当一个对象被虚拟机宣告死亡时会先调用它finalize()方法,让此对象处理它生前的最后事情(这个对象可以趁这个时机挣脱死亡的命运)。

    flnalze的详细解释https://www.cnblogs.com/Smina/p/7189427.html


      9.Object类中的方法。

     object类是java中所有类的祖先,是所有类的基类,Object具有哪些属性和行为,是java语言设计背后的思维体现。

    object类为与java.lang包中,java.lang包包含着java最基础和核心的类,在编译时会自动导入。

    Object类中共有13种方法:getClass()、hashCode()、equals()、clone()、toString()、notify()、notifyall()、wait()、finalize()

    clone():clone函数返回的是一个引用,指向的是新的clone出来的对象,此对象与原对象分别占用不同的堆空间。

    getClass():getClass()也是一个native方法,返回的是此Object对象的类对象/运行时类对象Class<?>。效果与Object.class相同。

    notify()、notifyall()、wait() :这几个方法主要用于java多线程之间的协作。既然是作用于多线程中,为什么却是Object这个基类所具有的方法?原因在于理论上任何对象都可以视为线程同步中的监听器,且wait(...)/notify()|notifyAll()方法只能在同步代码块中才能使用。

    wait(...)方法调用后当前线程将立即阻塞,且适当其所持有的同步代码块中的锁,直到被唤醒或超时或打断后且重新获取到锁后才能继续执行;

    notify()/notifyAll()方法调用后,其所在线程不会立即释放所持有的锁,直到其所在同步代码块中的代码执行完毕,此时释放锁,因此,如果其同步代码块后还有代码,其执行则依赖于JVM的线程调度。


     10.hashcode()和equals()区别

    https://www.cnblogs.com/skywang12345/p/3324958.html

    1.若重写了equals(Object obj)方法,则有必要重写hashCode()方法。

    2.若两个对象equals(Object obj)返回true,则hashCode()有必要也返回相同的int数。

    3.若两个对象equals(Object obj)返回false,则hashCode()不一定返回不同的int数。

    4.若两个对象hashCode()返回相同int数,则equals(Object obj)不一定返回true。

    5.若两个对象hashCode()返回不同int数,则equals(Object obj)一定返回false。

    6.同一对象在执行期间若已经存储在集合中,则不能修改影响hashCode值的相关信息,否则会导致内存泄露问题。

  • 相关阅读:
    【项目】项目236
    【项目】项目237
    【项目】项目238
    【项目】项目233
    【项目】项目235
    【项目】项目231
    Windows10系统MySQL5.7升级到8.0
    对接口限流方案
    工作中项目涉及的小细节,你都遇到了吗
    62.Mysql的binlog清除方法
  • 原文地址:https://www.cnblogs.com/znn93/p/9057217.html
Copyright © 2020-2023  润新知