Java面试题整理

1.什么是面向对象?

面向过程 注重事情的每一个步骤及顺序,面向对象 更注重事情有哪些参与者(对象)及各自需要做什么。

  • 面向对象的三大特性:

(1) 封装 :明确标识出允许外部使用的所有成员函数和数据项,内部细节对外部调用透明,外部调用无需修改或者关心内部实现。如:javabean的属性私有,提供get、set对外访问,属性的赋值或者获取逻辑只能由javabean本身决定,而不能由外部胡乱修改;orm框架,操作数据库时我们不需要关心链接是如何建立的,sql是如何执行的,只需要引入mybatis调用方法即可。
(2) 继承 :extend 继承基类的方法,并做出自己的改变或扩展。子类共性的方法或者属性直接使用父类的,而不需要自己再定义,只需扩展自己个性化的。
(3) 多态 :基于对象所属类的不同,外部对同一个方法的调用,实际执行的逻辑不同。
继承、方法重写、父类引用指向子类对象(无法调用子类特有的功能)

父类类型 变量名 = new 子类对象;
变量名.方法名();

2、JDK、JRE、JVM三者的区别和联系

JDK: Java Develpment Kit java开发工具 – 提供给开发人员用
JRE: Java Runtime Environment java运行环境 – 提供给运行java程序的用户用
JVM: Java Virtual Machine java虚拟机 – 编译解释class文件成机器码映射到系统中
在这里插入图片描述

3. ==和equals

双等于对比的是栈中的值:基本数据类型对比的是变量值,引用类型对比的是堆中内存对象的地址。
不做特殊处理时,双等于 和equals是一样的,string重写equals之后和==不一样。

4. 简述final的作用

final 最终的

  • 修饰类:表示类不可被继承 – 不可以有子类
  • 修饰方法:表示方法不可被子类覆盖(不可以重写),但是可以重载(改变形参列表和返回值)
  • 修饰变量:表示变量一旦被赋值就不可以更改它的值

(1) 修饰成员变量

  • final修饰普通成员变量(final int b = 0;)时,在声明的时候就要赋值或者构造器(变量初始化方法)或者代码块 { b = 0; }中赋值,否则报错;
  • 如果是静态类变量(final static int a = 0;),在声明的时候就需要赋值或者静态代码块(static{ a = 0; })赋值;

(2)修饰局部变量
局部变量只声明(final int a;),没有初始化不会报错,与final无关,但在使用之前一定要赋值,且只能赋值一次。
(3)修饰基本类型数据和引用类型数据

  • final修饰基本数据类型的变量,则其数值一旦初始化就不能更改;
  • final修饰引用数据类型的变量,则其初始化之后地址不能更改,但引用的值可以更改,如数组不能为空,但数组中的值可以改。

5. 为什么局部内部类和匿名内部类只能访问局部final变量?

主方法执行结束之后线程退出,变量回收,此时内部类引用变量时该变量已经不存在,于是规定编译之后生成两个class文件,作为变量的拷贝,但为了保证变量值始终一致不被篡改,则需要加final修饰。

6. String、StringBuffer、StringBuilder区别及使用场景

  • String是final修饰的,不可变,每次操作都会产生新的String对象(浪费内存),而StringBuffer和StringBuilder都是在原对象上进行操作,经常需要改变字符串内容时使用后两个。
  • StringBuffer是线程安全的(是否安全取决于是否需要额外加锁,StringBuffer里面每一个方法都有synchronized修饰,保证多线程环境下共享变量结果不被更改,不会出现并发问题),StringBuilder线程不安全。
  • 性能:StringBuilder>StringBuffer>String
  • 优先使用StringBuilder,多线程使用共享变量时使用StringBuffer。

7. 重载和重写的区别

  • 重载:发生在同一个类中,方法名必须相同,参数类型不同或者个数不同或者顺序不同都是重载,但方法返回值和访问修饰符不同不是重载(允许不同)。
  • 重写:发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private则子类就不能重写该方法。

8. 接口和抽象类的区别

  • 抽象类可以存在普通成员函数(实现方法),而接口中只能存在public abstract (抽象)方法;
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
  • 抽象类只能继承一个,接口可以实现多个;

接口的设计目的是对类的行为进行约束,可以强制要求不同类具有相同的行为,只约束行为的有无,不对如何实现进行限制;(like A)
抽象类的设计目的是代码复用,当不同的类具有相同的行为及行为实现方式时,可以将这些类派生出一个抽象类,而不同的地方则留给子类自己实现,所以抽象类不允许实例化(否则当调用A-B时无法执行)。(is A)
使用场景:关注事物本质时 —抽象类;关注操作时 —接口

9.List和Set的区别

  • List:有序(按对象进入的顺序保存对象),可重复,允许多个Null元素对象,可以使用iterator取出所有元素,再逐一遍历,也可以使用get(int index)获取指定下标的元素;
  • Set:无序,不可重复,最多允许有一个Null元素对象,取元素时只能用iterator接口取得所有元素,再逐一遍历。

10.hashCode和equals

  1. 如果两个对象相等,则hashcode一定也是相同的;
  2. 两个对象相等,对两个对象分别调用equals方法都返回true;
  3. 两个对象有相同的hashcode值,它们也不一定是相等的;
  4. equals方法被覆盖过,则hashcode方法也必须被覆盖;
  5. hashcode()的默认行为是对堆上的对象产生独特值。如果没有重写hashcode(),则该class的两个对象无论如何都不会相等(即使两个对象指向相同的数据)

11. ArrayList和LinkedList区别

  • ArrayList:基于动态数组,连续内存存储,适合下标访问(随机访问),扩容机制,因为数组长度固定,超出长度存数据时需要新建数组,然后将老数组的数据拷贝到新数组,如果不是尾插数据还涉及元素的移动(往后复制一份,插入新元素),使用尾插法并指定初始容量可以极大提升性能,甚至超过linkedList(需要创建大量的node对象)。
  • LinkedList:基于链表,可以存储在分散的内存中,适合做数据插入及删除操作,不适合查询,需要逐一遍历。遍历LinkedList必须使用iterator不能使用for循环,因为每次for循环体内通过get(i)取得某一元素时都需要对list重新进行遍历,性能消耗极大。
    另外,不要试图使用indexOf等返回元素索引,并利用其进行遍历,使用indexOf对list进行了遍历,当结果为空时会遍历整个列表。

12. HashMap和HashTable的区别?底层实现是什么?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值