带你了解10道java入门面试题

来自:互联网
时间:2021-08-09
阅读:

1. 谈谈你对面向对象的了解? (谈谈你对面向对象和面向过程的了解?)

面向对象与面向过程相比较,面向过程注重事件的步骤与顺序,比较直接高效,面向对象注重事件参与的对象与对象各己需要做的事,更易于复用,维护与扩展。(以举例来说明更加形象)

(例:拿常见手机支付来看)

面向过程:1,手机扫码——>2,输入密码——>3,确认是否支付成功——>4,离开

面向对象:拆出人与手机二个对象,(人:输入密码,离开,手机:手机扫码,确认是否支付成功)

下面就要谈谈面向对象的三大特征:封装。继承与多态

封装的意义:明确标识出允许外部使用的属性与方法,内部细节对外部隐藏,外部调用无需修改和关心内部如何实现。

继承:继承父类(基类)的方法,不包括私有化的部分,引用父类的方法或者按自己需求进行修改与扩展。

多态:(条件:1,在继承的基础上,2,存在方法重写,3,父类的引用指向子类的对象),基于对象所属类的不同,子类对父类同一个方法的调用,实际执行的逻辑不同。(无法调用调用子类特有的方法)。

2.==与equals的比较(笔试中常见)

==:比较的是栈中的值,基本上就是比较的变量当中的值,引用类型是堆中的内存对象地址、

equals:Object默认采用“==”比较,通常继承后会进行重写比较的为对象的内容(例如String)。

例题:

public class Taxi {
    public static void main(String[] args) {
        String str1="hello";
        String str2=new String("hello");
        String str3=str2;
        System.out.println(str1==str2);//false
        System.out.println(str1==str3);//false
        System.out.println(str2==str3);//true
        System.out.println(str1.equals(str2));//true
        System.out.println(str1.equals(str3));//true
        System.out.println(str2.equals(str3));//true
    }
}

解析:在Java中字符串是对象,字符串在生成时其实是在内存常量池当中生成。所以str1指向的“hello”的对象内存地址,str2因为new关键字在堆中开辟内存,但内存指向常量池中的“hello”,str2指向开辟内存的对象地址。str3==str2,所以str3指向str2指向开辟内存的对象地址。因为str1与str2和str1与str3“==”比较内存地址不同返回flase,str2与str3的内存地址相同返回ture,字符串方法中equals重写过,比较的是内容,str1与str2与str3的内容相同为“hello”,所以返回的是ture.

3.fianl关键字

final的作用:

该类不能被继承
方法 该方法不能被重写,但可以重载
变量 变量一旦被赋值就不能修改
成员变量(普通) 在声明的时候就需要赋值,或者静态块中与构造函数中赋值
成员变量(静态) 在声明的时候就需要赋值,或者静态块中赋值
局部变量 系统不会给变量初始化,必须程序员写入,在初始化时不会报错,但在使用前一定要初始化,不然报错
基本数据类型 基本数据类型的数值初始化后不能改变
引用数据类型 初始化后不能指向另一个对象,但引用的值是可以改变的

4.为什么局部内部类与匿名内部类只能访问局部的final变量?

首先必须知道,内部类与外部类,内部类不会因为定义在方法中,跟方法执行完一起回收,就会产生一个问题,外部方法结束时,就会回收局部变量,但内部类对象(当没有引用时回收)还存在,就存在了一个问题,内部类访问了一个不存在的变量,所以在jdk当中为了解决这个办法,局部就复制了一份内部类成员变量,当局部变量回收后仍可以访问局部变量,但实际访问的是“copy”过的值。(为了复制的局部变量必须与原局部变量一样,所以使用final修饰)

public class Management {
    private int id=10;
    //final修饰局部变量
    public void outPrint(final String x){
        class InClass{
            public void Inprint(){
                System.out.println(x);
                System.out.println(id);
            }
        }
        new InClass().Inprint();
    }
    public static void main(String[] args) {
       Management m=new Management();
        m.outPrint("小罗");
    }
}

5.String,StringBuffer,StringBuilder 三者的区别与使用场景?

String:final修饰的,不可变的,每次操作会产生新的对象。

StringBuffer,StringBuilder:对原对象进行操作,不产生新对象。

性能上:StringBuilder (线程不安全)> StringBuffer(线程安全) > String

使用场景:当需要对字符串内容进行多次改变时,使用StringBuffer,StringBuilder。但因为性能原因优先使用StringBuilder ,需要多线程,共享变量时使用StringBuffer。

6.重载和重写(覆盖)的区别?

重载:发生在类当中,方法名称必须相同,参数的类型,个数顺序不同。方法返回值与修饰符可以不同。(下图:不是重载,方法名称必须相同,参数的类型,个数顺序相同,重载与返回值没有关系)

 public void outPrint(String x,int i){
       
    }
public int outPrint(String x,int i){
       //这个不是重载,编译时会报错 
    }

重写(覆盖):发生在继承的父类与子类当中,方法名与参数列表必须相同,返回值的范围小于等于父类,如果存在异常,抛出异常范围小于等于父类,修饰符的权限必须大于等于父类。如果父类方法以private修饰则子类不能重写该方法。

7.接口与抽象类的区别?

1,抽象类可以存在普通成员函数,而接口只能存在public abstract 方法,

2,抽象类只能继承一个,而接口可以s实现多个。

3,抽象类中成员变量可以是任何类型,而接口中成员变量只能是public static final 类型的。

(高级:接口设计的目的:是对类行为进行约束,抽象类的目的:提高代码的复用性,抽象类不允许实例化)

使用场景:当你关注的是事务本身时,就用抽象类,当你关注操作时就使用接口。

8.list与set的区别?

list:有序,可重复的,按对象进入顺序进行存储,允许多个null对象,可以使用迭代器取出所以元素,还可以所以get方法获取指定下标的元素。

set:无序,不可重复。只允许有一个null对象,只能使用迭代器遍历元素。

9.hashCode与equals

equals:Object默认采用“==”比较,通常继承后会进行重写比较的为对象的内容(例如String)。

hashCode:定义在Object中hashCode()会获取哈希码(又称为散列码),确定哈希表表上的索引,并返回int整数。特点“根据键快速找到与之对应的值”

联系与规则:

1,如果二个对象相等,hashCode一定也是相等的

2,如果二个对象相等,二个对象调用equals返回ture。

3,二个对象的hashCode一样,他们不一定相等。

4,equals方法被覆盖,hashCode方法也必须覆盖。

5,hashCode默认行为是堆上的对象独特值,如果没有重写hashCode(),则该类二个对象无论如何都不会相等。

10.ArryList与LinkList的区别?

ArryList:基于动态数组,连续存储,适合下标访问,扩容机制:因为数组长度是固定的,超过固定长度会新建立一个数组,长度扩大原来1.5倍,回收老数组。

LinkList:基于列表,可以存储在分散的内存当中。适合插入,删除,不适合查询。LinkList一般使用迭代器进行遍历。不建议使用for循环遍历,因为每一次遍历都会get方法,消耗性能大,不使用indexOf来返回元素索引,和遍历元素。用indexOf遍历list进行遍历时,当结果为空时还遍历这个列表。

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注的更多内容!

返回顶部
顶部