Java基础面试知识点01
1. 什么是面向对象谈谈你对面向对象的理解对比面向过程面向过程更注重每个步骤面向对象更注重事情的参与者。举例洗衣服面向过程将任务拆解成一系列步骤函数打开洗衣机-放衣服-放洗衣粉-清洗-烘干面向对象拆出人和洗衣机两个对象人打开洗衣机放衣服放洗衣粉洗衣机清洗、烘干面向过程直接高效而面向对象更易于复用、扩展和维护。三大特性封装明确标识出允许外部使用的所有成员函数和数据项。内部细节对外部调用透明外部调用无需在意内部实现。继承继承基类的方法并做出自己的改变和扩展。子类共性的方法或者属性直接使用父类的而不需要自己再定义只需扩展自己个性化的内容。多态基于对象所属类的不同外部对同一个方法的调用实际执行的逻辑不同。实现前提继承、方法重写、父类引用指向子类对象。2. JDK、JRE、JVM三者区别和联系JDKJava Development KitJava开发工具包JREJava Runtime EnvironmentJava运行时环境JVMJava Virtual MachineJava虚拟机3. 和 equals 比较对比的是栈中的值基本数据类型比较变量值引用数据类型比较堆中对象的内存地址。equalsObject类中默认实现也是使用比较地址但常用类一般会重写该方法。String类重写后的equals()方法用于比较两个字符串存储的内容是否一致。4. 简述final作用为什么局部内部类和匿名内部类只能访问局部final变量final修饰作用修饰类表示该类不可被继承修饰方法表示方法不能被重写Override但可以被子类继承调用修饰变量变量仅能赋值一次基本类型值不可修改引用类型引用地址不可修改内部类访问局部变量限制原因核心原因生命周期不同。局部变量随方法出栈销毁内部类对象存于堆中生命周期可能远长于方法。编译器会给内部类拷贝一份该变量的副本。若不限制final外部可修改原局部变量副本与原值数据不一致会产生bugfinal限定变量不可修改保证两处读取数据统一避免脏数据问题。局部变量存储在栈中方法执行结束变量立即销毁内部类对象存储在堆中可被外部引用赋值生命周期远超当前方法编译器备份机制Java编译器会把局部变量拷贝一份作为内部类隐藏成员变量。如果变量不加final外部修改原始变量内部类使用副本两份数据不一致引发异常。因此Java强制要求被访问的局部变量必须用final修饰保证数据一致性。5. String、StringBuffer、StringBuilder区别及使用场景String被final修饰字符串不可变每次修改拼接都会生成新String对象。StringBuffer和StringBuilder在原有对象缓冲区上直接操作不会频繁创建新对象。StringBuffer方法添加synchronized修饰线程安全StringBuilder无同步锁线程不安全。性能排序StringBuilder StringBuffer String使用场景频繁修改字符串内容优先选用后两者单线程场景优先StringBuilder多线程共享操作字符串时使用StringBuffer。6. 重载和重写的区别重载Overload发生在同一个类中方法名必须相同参数类型、个数、顺序不同返回值与访问修饰符无强制限制编译期确定。作用同一方法名适配多种入参方便调用publicvoidshow(){}publicvoidshow(inta){}// 重载publicvoidshow(Strings){}// 重载重写Override发生在父子类之间方法名、参数列表必须完全一致子类返回值范围≤父类抛出异常范围≤父类访问权限≥父类父类private修饰的方法无法被子类重写。作用子类覆盖父类原有方法自定义业务逻辑classFather{publicvoidrun(){}}classSonextendsFather{Overridepublicvoidrun(){}// 重写父类run}7. 接口和抽象类的区别继承机制抽象类类与类单继承一个类只能继承一个抽象类接口支持多实现一个类可以同时实现多个接口成员属性抽象类变量修饰符无限制可定义实例变量、静态变量支持修改接口成员变量默认public static final属于常量必须初始化且不能修改方法定义抽象类可包含普通实例方法、static静态方法、抽象方法抽象方法权限可为public、protected接口抽象方法默认public abstractJava8新增default默认方法、static静态方法设计思想抽象类抽取多个子类共有属性与行为体现is-a继承关系接口定义行为规范只约束具备哪些功能不关注类本身属性使用场景关注事物本质共性使用抽象类只需要定义一组操作行为使用接口。8. List和Set的区别元素重复性List允许存储重复元素Set不允许元素重复依靠equals()hashCode()联合判断去重有序性与下标访问List存取有序自带索引下标可通过get(int index)按位置取值SetHashSet无序无索引不能按下标获取元素LinkedHashSet按照插入顺序排序TreeSet按照元素自然顺序排序遍历方式List支持普通for下标遍历、迭代器、增强for循环Set无下标仅可使用迭代器、增强for循环遍历9. ArrayList和LinkedList区别ArrayList底层基于动态数组连续内存存储随机下标查询效率高。数组容量不足时执行扩容新建数组拷贝原数据非尾部插入删除需要批量移动元素。初始化指定容量并尾部插入性能甚至优于LinkedListLinkedList需要频繁创建Node节点。LinkedList底层双向链表内存分散存储插入删除仅修改指针无需移动元素无索引结构遍历查询需要逐个节点遍历。禁止使用普通for循环搭配get(i)遍历每次get都会从头遍历链表性能损耗极大也不建议依靠indexOf获取索引遍历查找不到时会遍历整个链表推荐使用迭代器遍历。10. HashMap和HashTable有什么区别HashMap底层实现是什么二者区别HashMap方法无synchronized修饰非线程安全HashTable方法加同步锁线程安全。HashMap允许key、value为nullHashTable不允许key和value存入null。JDK1.8 HashMap底层实现主体结构数组 链表 红黑树节点以内部类Node存储。计算key哈希值经过二次扰动后对数组长度取模确定数组下标下标位置无元素直接存入Node节点发生哈希冲突调用equals比对keykey相同则覆盖valuekey不同则挂载链表链表长度达到8且数组容量大于等于64时链表转为红黑树红黑树节点数低于6时退化为链表key为null时统一存放在数组下标0位置。