Java面试问题汇总

基础简答题

  1. 面试官介绍面试流程,以及注意事项
  2. 自我介绍
  3. Java面向对象的优势,为什么学Java
    优点:
    1、抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象 并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。
    2、继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的 一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类 (子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修 改或增加新的方法使之更适合特殊的需要。
    3、封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概 念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
    4、多态:多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语 言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
  4. Java的三大特性
    1、封装
    封装指的是属性私有化,根据需要提供setter和getter方法来访问属性。即隐藏具体属性和实现细节,仅 对外开放接口,控制程序中属性的访问级别。
    封装目的:增强安全性和简化编程,使用者不必在意具体实现细节,而只是通过外部接口即可访问类的成 员。
    2、继承
    继承是指将多个相同的属性和方法提取出来,新建一个父类。
    Java中一个类只能继承一个父类,且只能继承访问权限非private的属性和方法。 子类可以重写父类中的 方法,命名与父类中同名的属性。
    继承目的:代码复用。
    3、多态
    多态可以分为两种:设计时多态和运行时多态。
    设计时多态:即重载,是指Java允许方法名相同而参数不同(返回值可以相同也可以不相同)。
    运行时多态:即重写,是指Java运行根据调用该方法的类型决定调用哪个方法。
    多态目的:增加代码的灵活度。
    4、个人总结
    一.Java中应尽量减少继承关系,以降低耦合度。
    二.使用多态时,父类在在调用方法时,优先调用子类的方法。如果子类没有重写父类的方法,则再调用父类 的方法。
    三.Java三大特性是Java最基础的也是最重要的,应当牢记(面试中也是经常考的)。
  5. 重载和重写的区别
    重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可 以不同,发生在编译时。
    重写:发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父 类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法。
  6. JDK与JRE的区别

JDK:java development kit (java开发工具)
JRE:java runtime environment (java运行时环境)
JVM:java virtuak machine (java虚拟机)
一、JDK——开发环境(核心)
java development kit 的缩写,意思是JAVA开发工具,我们写文档做PPT需要office 办公软件,开发 当然需要开发工具了,说到开发工具大家肯定会想到Eclipse,但是如果直接安装Eclipse你会发现它是运 行不起来 是会报错的,只有安装了JDK,配置好了环境变量和path才可以运行成功。这点相信很多人都深有 体会。
JDK主要包含三部分:
第一部分就是Java运行时环境,JVM。
第二部分就是Java的基础类库,这个类库的数量还是非常可观的。
第三部分就是Java的开发工具,它们都是辅助你更好的使用Java的利器。
二、JRE——运行环境
java runtime environment (java运行时环境)的缩写
三、JVM——转换环境
java virtuak machine (java虚拟机)的缩写。
大家一提到JAVA的优点就会想到:一次编译,随处运行,说白了就是跨平台性好,这点JVM功不可没。
JAVA的程序也就是我们编译的代码都会编译为Class文件,Class文件就是在JVM上运行的文件,只有JVM还 不能成class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib,而jre包含lib类库。
JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节 码),就可以在多种平台上不加修改地运行。

  1. JDK1.8的新特性
    Lambda表达式
    函数式接口
    方法引用和构造器调用
    Stream API
    接口中的默认方法和静态方法
    新时间日期API
  2. 基本数据类型及其包装类、拆装箱
  • Java为每种基本数据类型分别设计了对应的类,称之为包装类。

基本数据类型

对应的包装类

byte

Byte

short

Short

int

Integer

long

Long

char

Character

float

Float

double

Double

boolean

Boolean

  • 自动拆箱:对象转换成基本数值
  • 自动装箱:基本数值转换成对象
  1. String、StringBuffer、StringBuilder使用及区别,StringBuffer如何保证线程安全的
    String 字符串常量
    StringBuffer 字符串变量(线程安全)
    StringBuilder 字符串变量(非线程安全)
    这3个类之间的主要区别:运行速度 和 线程安全。
    1.运行速度(一般情况): String < StringBuffer < StringBuilder 。
    ① String最慢原因:它为字符串常量,即String对象一旦创建后是不可更改的,而后两者是变量(可更改)。
    每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,即不断创建新的对象并且将旧的对象回收的一个过程(JVM的垃圾回收机制(GC)给回收掉),所以执行速度很慢。
    ②特别情况:在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,
    像以下的字符串对象生成中(String 效率比 StringBuffer 快的):
    String S1 = “a” + “b” + “c”;
    StringBuffer S2 = new StringBuilder(“a”).append(“b”).append(“c”);
    其实这是 JVM 的一个把戏,在 JVM 眼里,这个
    String S1 = “a” + “b” + “c”; 其实就是:
    String S1 = “abc”; 所以当然不需要太多的时间了。
    但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:
    String S2 = “a”;
    String S3 = “b”;
    String S4 = “c”;
    String S1 = S2 +S3 + S4;
    这时候 JVM 会规规矩矩的按照原来的方式去做(创建新对象,回收旧对象)。
    补充:
    StringBuffer 主要操作是 append()和 insert() 方法,可重载以接受任意类型的数据。
    每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。
    append 方法始终将这些字符添加到缓冲区的末端;
    insert 方法则在指定的点添加字符。
    例子:如果Obj引用一个当前内容是“123”的字符串缓冲区对象,则此方法调用Obj.append(“4”) 会使字符串缓冲区包含“1234”,而Obj.insert(2, “4”) 将更改字符串缓冲区,使之包含“1243”。
    2.线程安全:
    在字符串缓冲区被多个线程使用时,
    StringBuffer对象安全,因为很多方法中可以带synchronized关键字可以保证安全;
    StringBuilder的方法没有改关键字。
    但是,在单线程的情况下:建议使用速度比较快的StringBuilder。
    多线程在字符缓冲区操作StringBuffer,
    单线程在字符缓冲区操作StringBuilder。
  2. 与equals的区别,同一个对象使用与equals比较的结果是什么
  3. =: 判断两个字符串在内存中首地址是否相同,即判断两者是否是同一个字符串对象
  4. equles() : 如果没有重写equals()方法比较的是对象的地址,因为对Object来说对象没有什么属性可以比较,只  能比较最底层的地址.  
  5. 而如果重写equals()方法时,该方法的对象因为是Object的子类,所以调用时会调用子类对象里面的方法.所以只 有重写equals()方法后,两者比较的才是内容.或者说重写可以使自己定义比较的规则,不想按照地址去比较.
  1. 使用过的设计模式
  2. 代理模式—>动态代理、静态代理的区别,动态代理的过程
  3. Spring的IOC和AOP
  • Spring简介
    Spring是分层的Java SE/EE应用full-stack轻量级开源框架,以IoC(Inverse Of Control:
    反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层Spring
    MVC和持久层Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多
    著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。
  • Spring优点
    降低了组件之间的耦合性 ,实现了软件各层之间的解耦
    可以使用容易提供的众多服务,如事务管理,消息服务等
    容器提供单例模式支持
    容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能
    容器提供了众多的辅助类,能加快应用的开发
    spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等
    spring属于低侵入式设计,代码的污染极低
    独立于各种应用服务器
    spring的DI机制降低了业务对象替换的复杂性
    Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring的部分或全部
  • 什么是DI机制?
    依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者 因此也称为依赖注入。
    spring以动态灵活的方式来管理对象 , 注入的两种方式,设置注入和构造注入。
    设置注入的优点:直观,自然
    构造注入的优点:可以在构造器中决定依赖关系的顺序。
  • 什么是AOP?
    面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面
    1.面向切面编程提供声明式事务管理
    2.spring支持用户自定义的切面
    aop框架具有的两个特征:
    1.各个步骤之间的良好隔离性
    2.源代码无关性
  • Spring的事务管理机制实现的原理,就是通过这样一个动态代理对所有需要事务管理的Bean进行加载,并根据配置在invoke方法中对当前调用的方法名进行判定,并在method.invoke方法前后为其加上合适的事务管理代码,这样就实现了Spring式的事务管理。Spring中的AOP实现更为复杂和灵活,不过基本原理是一致的。
  1. SpringMVC中的MVC解释,并且画内部结构图

从图中可知,DispatcherServlet是核心,这里的DispatcherServlet就是一个Servlet,相当于一个看门员,所有的请求都得经过他转发。

SpringMVC工作流程

1、请求达到DispatcherServlet
2、DispatcherServlet解析Url中的mapping(mapping就是Controller上RequestMapping注解上的值),就交给处理器映射
3、处理器映射帮我们找到合适的Controller(Controller本质是一个注解,Spring容器会有一个类来分析这个注解,然后根据这个注解类构造出真正的Servlet,所以说Controller也可以说是Servlet),这个Controller就来处理我们的url信息了,一般处理相关的业务逻辑Controller肯定是委托给Service了
4、当Service处理完后会产生信息,这些信息就放在model上,然后Controller返回一个视图名(在视图上可以通过model访问这些产生的信息)
5、DispatcherServlet收到model和视图名不会自己去处理(简便自己的工作),而是委托给ViewResolver(视图解析器),他会帮我们把视图名匹配成一个视图
6、最终就形成了视图文件
7、把这个视图响应给客户端

  1. http的工程流程
  2. 为什么是四次挥手
  3. 数据库的四个特性
  1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
  2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
  3. 隔离性:多个事务之间。相互独立。
  4. 一致性:事务操作前后,数据总量不变
  1. 隔离级别,可能出现的情况,MySQL默认的隔离级别
    事务的隔离级别(了解)
    * 概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
    * 存在问题:
    1. 脏读:一个事务,读取到另一个事务中没有提交的数据
    2. 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
    3. 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不 到自己的修改。
    * 隔离级别:
    1. read uncommitted:读未提交
    * 产生的问题:脏读、不可重复读、幻读
    2. read committed:读已提交 (Oracle)
    * 产生的问题:不可重复读、幻读
    3. repeatable read:可重复读 (MySQL默认)
    * 产生的问题:幻读
    4. serializable:串行化
    * 可以解决所有的问题
    注意:隔离级别从小到大安全性越来越高,但是效率越来越低
  2. 如何处理幻读
  3. 项目中遇到的问题
  4. 反问面试官