Java开发岗高频面试题全解.docx

上传人:b****1 文档编号:675322 上传时间:2023-04-29 格式:DOCX 页数:35 大小:107.74KB
下载 相关 举报
Java开发岗高频面试题全解.docx_第1页
第1页 / 共35页
Java开发岗高频面试题全解.docx_第2页
第2页 / 共35页
Java开发岗高频面试题全解.docx_第3页
第3页 / 共35页
Java开发岗高频面试题全解.docx_第4页
第4页 / 共35页
Java开发岗高频面试题全解.docx_第5页
第5页 / 共35页
Java开发岗高频面试题全解.docx_第6页
第6页 / 共35页
Java开发岗高频面试题全解.docx_第7页
第7页 / 共35页
Java开发岗高频面试题全解.docx_第8页
第8页 / 共35页
Java开发岗高频面试题全解.docx_第9页
第9页 / 共35页
Java开发岗高频面试题全解.docx_第10页
第10页 / 共35页
Java开发岗高频面试题全解.docx_第11页
第11页 / 共35页
Java开发岗高频面试题全解.docx_第12页
第12页 / 共35页
Java开发岗高频面试题全解.docx_第13页
第13页 / 共35页
Java开发岗高频面试题全解.docx_第14页
第14页 / 共35页
Java开发岗高频面试题全解.docx_第15页
第15页 / 共35页
Java开发岗高频面试题全解.docx_第16页
第16页 / 共35页
Java开发岗高频面试题全解.docx_第17页
第17页 / 共35页
Java开发岗高频面试题全解.docx_第18页
第18页 / 共35页
Java开发岗高频面试题全解.docx_第19页
第19页 / 共35页
Java开发岗高频面试题全解.docx_第20页
第20页 / 共35页
亲,该文档总共35页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

Java开发岗高频面试题全解.docx

《Java开发岗高频面试题全解.docx》由会员分享,可在线阅读,更多相关《Java开发岗高频面试题全解.docx(35页珍藏版)》请在冰点文库上搜索。

Java开发岗高频面试题全解.docx

Java开发岗高频面试题全解

Java开发岗高频面试题全解

●JAVA零基础入门

●一、基本语法

●1.Java常识

●Java语言的特点是什么?

●面向对象

●跨平台

●支持多线程

●简单安全

没有指针

●鲁棒性

自动垃圾回收机制

●JDK、JRE、JVM直接的关系是什么?

●JDK

JavaDevelopmentKit,Java开发工具包

●Java的最小开发环境,由JRE和Java工具组成。

●JRE

JavaRuntimeEnvironment,Java运行时环境

●Java的最小运行环境,由JVM和核心类库组成。

●JVM

JavaVirtualMachine,Java虚拟机

●是Java字节码运行的容器,需要加上核心类库才能运行Java

●独立于硬件和操作系统,具有平台无关性,提供了垃圾回收等机制。

●请你比较一下Java和JavaScript

●面向对象和基于对象:

Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象。

JavaScript是一种基于对象和事件驱动的编程语言,本身提供了丰富的内部对象供设计人员使用。

●解释和编译:

Java是先编译后解释的语言。

而JavaScript是一种解释性编程语言,其源代码不需经过编译,就可以由浏览器来解释执行。

●强弱类型变量:

Java采用强类型变量检查,即所有变量在编译之前必须作声明。

而JavaScript中变量是弱类型的,在使用变量前可以不作声明。

●简单介绍一下Java8的新特性

●Lambda表达式:

允许把函数作为方法的参数进行传递

●方法引用:

使得Lambda在调用那些已经拥有方法名的方法时更简洁、更容易理解

●StreamAPI:

引入了函数式编程风格

●DateTimeAPI:

加强对日期与时间的处理

●Optional类:

用来解决空指针异常(使用了一个没有实际值的对象)

●新增接口的默认方法,default关键字

●NashornJavaScript引擎:

允许在JVM上运行特定的JavaScript应用

●类依赖分析器:

可以展示包层级和类层级的Java类依赖关系

Javadependencies(jdeps)

●请你说说Lamda表达式的优缺点

●优点是简洁和容易实现并行计算。

●缺点是不容易调试和非并行计算时速度慢,而并行计算也需要预热才能体现效率。

●对JIT编译器有了解吗?

●定义:

JIT编译器全名叫JustInTimeCompile也就是即时编译器,把经常运行的代码作为"热点代码"编译成与本地平台相关的二进制机器码,并对变量进行逃逸分析,若确定不会被外部的线程和方法访问,则对其进行优化。

●优化:

同步消除(去掉synchronized)、标量替换(将对象拆成标量)、栈上分配(减轻GC负担)

●2.数据类型

●八大基本数据类型是哪些?

各自的字节数是多少?

●整型byte/short/int/long字节数1/2/4/8

●浮点型float/double字节数4/8

●字符型char字节数2

●布尔型boolean字节数1

●补充1:

获取长度String.valueOf(object).length()

●补充2:

自动类型转换,浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入

●如何创建数组?

●int[]arrayName=newint[size];默认值为0

●int[]arrayName=newint[]{值1,值2,值3,...,值n};newint[]可以省略

●什么是标量与聚合量?

●标量(Scalar)就是八大基本数据类型,无法再分解成更小的数据

●Java中的对象就是聚合量(Aggregate),可以分解成其他聚合量和标量

●int和Integer有什么区别?

●为了能够将包括int在内的八大基本数据类型当成对象操作,JAVA为每一个基本数据类型都引入了对应的包装类,并设计了自动装箱/拆箱机制,使得二者可以相互转换。

●例子:

●classAutoUnboxingTest{

●publicstaticvoidmain(String[]args){

●Integera=newInteger(3);

●//将3自动装箱成Integer类型

●Integerb=3;

●intc=3;

●//false两个引用没有引用同一对象

●System.out.println(a==b);

●//truea自动拆箱成int类型再和c比较

●System.out.println(a==c);

●}

●}

●请解释一下String为什么不可变?

为什么要这样设计?

●不可变是String类是final类,内部的value字节数组也是final类型

●如此设计的用途包括:

实现字符串池(节约堆空间)、实现多线程、确保hash码的唯一性(适合作为Map的键)

●请你说明String、StringBuffer以及StringBuilder的区别

●String存储的字符串不可变,而StringBuffer以及StringBuilder是为可变字符串设计的

●StringBuffer带有Synchronized是线程安全的,StringBuilder则在单线程时性能更好

●String对象作为参数传递给方法后,返回的结果却没有改变对象的属性,为什么?

●String、Interger等final类型的引用,在方法调用后外边的结果不变,是因为fianl类型的引用是不可变的,有点类似于C++中的常指针,在调用方法内实际上是新建了一个同名的局部引用对象,调用结束后就回收了。

●3.关键字与符号

●请你讲讲Java里面的final关键字是怎么用的?

●类的角度:

当用final修饰一个类时,表明这个类不能被继承。

●方法角度:

final方法可以被继承但不允许被子类重写

不可用于修饰构造方法,因为子类本就不能重写父类构造方法

●变量角度:

类似于C++中的const,修饰基本数据类型后不可更改,修饰引用类型后无法再指向另一个对象

●请你说明符号“==”比较的是什么?

●对象是引用类型:

两个引用指向同一个对象时返回true,否则返回false

●对象是基本数据类型:

比较数值是否相等

●静态(static)与非静态的区别?

●空间分配的角度:

静态成员变量在类被加载时存放在常量池中,而非静态成员变量是存放在堆中,局部变量存放在栈中

●使用权限的角度:

公有静态成员可以通过类名访问,静态成员函数不能调用非静态成员(还未被加载)

●关键字throws,throw,try,catch,finally分别代表什么意义?

●try来指定一块需要预防异常的代码

●紧跟在try后,catch子句用来指定捕捉异常的类型,并做处理

●throw语句用来创建并抛出一个异常

●throws用来向上抛出异常

●缺省处理器finally不管发生异常与否都执行其内容

●Java中的元注解有哪些?

●Java中提供了4个元注解,元注解的作用是负责注解其它注解。

●@Target:

说明注解所修饰的对象范围

●例子:

●@Target({ElementType.TYPE,ElementType.METHOD})

●public@interfaceMyAnn{

●}

●扩展:

源码

●public@interfaceTarget{

●ElementType[]value();

●}

●publicenumElementType{

●TYPE,FIELD,METHOD,PARAMETED,CONSTRUCTOR,LOCAL_VARIABLE,ANNOCATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE

●}

●@Retention:

定义了该注解被保留的时间长短

●扩展:

源码

●public@interfaceRetention{

●RetentionPolicyvalue();

●}

●publicenumRetentionPolicy{

●SOURCE,CLASS,RUNTIME

●}

●其中,SOURCE:

表示在源文件中有效(即源文件保留);CLASS:

表示在class文件中有效(即class保留);RUNTIME:

表示在运行时有效(即运行时保留)

●例子:

●@Retention(RetentionPolicy.RUNTIME)标注表示该注解在运行时有效

●@Inherited:

修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类

●@Documented:

用于描述其它类型的annotation,可以被javadoc文档化

●注解有什么作用?

如何定义注解?

●注解可以代替繁杂的配置文件,简化开发。

●定义注解必须用@interface

●例子:

●public@interfaceMyAnn{

●Stringvalue();

●intvalue1();//定义注解时候的value就是属性,看着是一个方法,但我们称它为属性。

当为注解指定属性后,那么在使用注解时就必须要给属性赋值了。

●}

●//使用注解MyAnn,设置属性

●@MyAnn(value1=100,value="hello")

●publicclassMyClass{

●}

●4.其他基础

●请说明JAVA语言如何进行异常处理

●Java通过面向对象的方法进行异常处理,每个异常都是一个对象,它是Throwable类或其子类的实例

●当程序出现异常后便抛出一个异常对象,其中包含有异常信息,需要对其捕获并处理

●哪类异常必须处理否则无法编译?

举几个例子。

●checkedexception受检异常也叫编译时异常

●常见的有SQLException、InterruptedException、IOException

●Java中的Exception和Error有什么区别?

●Exception是程序正常运行中预料到可能会出现的错误,应该被捕获并进行相应的处理,是一种异常现象,如IOException

●Error是正常情况下不可能发生的错误,Error会导致JVM处于一种不可恢复的状态,不需要捕获处理,如OutOfMemoryError

●捕获异常应该遵循哪些原则?

●尽可能捕获具体的异常,而不是使用Exception一起捕获

●捕获异常后应有日志记录,方便之后的排查

●不要使用一个很大的try–catch包住整段代码,不利于问题的排查

●说说Java中反射机制

●在程序运行中动态获取信息(类的所有属性和方法)和动态调用对象方法(动态代理)的功能称为反射机制

●流行的框架如Spring的底层依赖JAVA的反射机制,也可以用反射实现Java程序和JDBC驱动的松耦合

●请你简单描述一下正则表达式及其用途

●正则表达式是记录字符串文本规则的代码,在处理字符串数据时中可以通过编写正则表达式进行匹配分割等操作。

●请你谈谈Java中是如何支持正则表达式操作的?

●Java中的String类提供了支持正则表达式操作的方法,如matches()、split()等

●Java中可以用Pattern类表示正则表达式对象,它提供了丰富的API进行各种正则表达式操作

●什么是可变参数列表?

●publicvoidsum(intp,int...n);实参可以为数组,影响重载

●什么是增强型for循环?

●又叫foreach循环,用于快速遍历

●intarr={1,2,3,4,5,6,7};

●for(intn:

arr)

●System.out.println(n);

●介绍Java序列化与反序列化的过程

●将对象转换为字节序列存储到硬盘上的过程叫做对象的序列化

●反序列化则是把硬盘上的字节序列读取恢复成一个对象的过程

●为什么会出现4.0-3.6=0.40000001这种现象?

●计算机在计算10进制小数的过程中要先转换为2进制进行计算,这个过程中出现了误差

●请判断当一个对象被当作参数传递给一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

为什么?

请举例说明。

●这是值传递。

Java只有值传递,没有引用传递

●假设新建一个引用a,指向对象b,其中栈中a的值就是堆中b的地址。

方法c来调用这个对象b并返回变化后的结果

●此时括号中实参应该写a而不是b,而传递的内容是a的值而不是a在栈中的地址,所以说这是值传递不是引用传递

●二、面向对象

●1.基本概念

●说说什么是面向对象?

●现实世界中任何实体都可以看作是对象,对象之间通过消息相互作用。

●请你谈一下面向对象的"六原则一法则"

●单一职责原则:

一个类只做它该做的事情

●开闭原则:

软件实体应当对扩展开放,对修改关闭

●依赖倒转原则:

声明时尽可能使用抽象类,面向接口编程

●里氏替换原则:

任何时候都可以用子类型替换掉父类型

●接口隔离原则:

接口要小而专,绝不能大而全

●合成聚合复用原则:

优先使用合成或聚合关系复用代码,而不是继承

●迪米特法则:

又叫最少知识原则,一个对象应当对其他对象尽可能了解得少

●Object类有什么作用?

●Object类是所有类的父类,Java中的每个类都可以使用Object中定义的方法

一个类没有使用extends关键字明确标识继承关系,则默认继承Object类(包括数组)

●Object类的常用方法有哪些?

●toString():

以字符串对象的形式返回当前对象本身的有关信息

●equals():

比较两个对象是否是同一个对象,是则返回true

●hashCode():

返回该对象的哈希代码值

●getClass():

获取当前对象所属的类信息,返回Class对象

●notify()/notifyAll():

唤醒在此对象监视器上等待的单个/全部线程

●clone():

创建并返回此对象的一个副本。

●finalize():

由对象的垃圾回收器调用

●wait():

当前的线程等待

●2.三大特性

●简单描述面向对象的三大特性。

●封装是指类隐藏数据和过程等信息,留出访问的接口,可以减少耦合,增强安全性。

●继承是一种联结类的层次模型,从父类中派生出一个子类,子类继承父类的方法和属性,并且可以通过重写来增强父类的能力。

●多态的本质就是一个程序中存在多个同名的不同方法,分为编译时多态(类内方法重载)和运行时多态(子类重写父类方法或父类引用子类对象)

●举例说明耦合的概念,如何解决耦合问题?

●举例说明:

类T负责两个不同的职责P1P2,当职责P1需求发生改变而需要修改类T时有可能会导致原本运行正常的职责P2功能发生故障,则说明P1P2被耦合在了一起

●解决办法:

遵守单一职责原则,将不同的职责封装到不同的类或模块中。

分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。

此时修改类T1时,不会使职责P2发生故障风险

●请说明Java的接口和C++的虚类的相同和不同处。

●C++虚类相当于java中的抽象类

●相同之处:

都不能实例化、除非子类是抽象类,否则需要实现所有抽象方法

●不同之处:

●1)子类可以实现很多个接口,但是只能继承一个抽象类

●2)抽象类可以有构造方法,接口没有构造方法

●3)抽象类中的方法不一定是抽象方法,可以有具体实现;而接口中的方法都是抽象方法,JDK8新增的默认方法除外

●4)抽象类可以使用全部四种访问修饰符,接口只能是public

●请说明什么是向上转型和向下转型?

●向上转型:

子类对象被父类引用,如Fatherf=newSon();

●向下转型:

父类对象转化为子类,如Sons=(Son)f;

该父类必须实际指向了一个子类对象才可强制类型向下转型

●请说明重载(Overload)和重写(Override)的区别。

重载的方法能否根据返回类型进行区分?

●方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性

●重载发生在一个类中,同名的方法如果有不同的参数列表(类型、个数)则视为重载

●重写发生在子类与父类之间,重写要求子类重写方法与父类参数类型、个数、返回类型都相同,且不能比父类被重写方法声明更多的异常(里氏代换原则)。

●三、集合

●1.Collection

●请说明Collection和Collections的区别

●Collection是集合类的上级接口,继承于他的接口有Set和List

●Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作

●请你讲讲什么是泛型?

●泛型,即“参数化类型”,类似于方法圆括号里的变量形参

●声明集合对象时在尖括号中写泛型,使用时需传入指定类型的集合元素,读取时无须进行强制类型转换

●List、Map、Set三个接口存取元素时,各有什么特点?

●List以特定索引顺序来存取元素,可以有重复元素

●Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)

●Map可以保存键值对(key-valuepair)映射

●List、Map、Set三者的底层实现分别是什么?

●ArrayList:

底层由数组实现,长度动态增长,适合快速查询

●LinkedList:

由双向链表实现,适合快速地插入和删除元素

●Set和Map容器都有基于哈希存储和排序树的两种实现版本,基于哈希存储的版本理论存取时间复杂度为O

(1),而基于排序树版本的实现在插入或删除元素时会按照键(key)构成排序树从而达到排序和去重的效果

●Set和List接口有哪些具体实现类?

●Set接口的实现类主要有:

HashSet、TreeSet、LinkedHashSet

●List接口的实现类主要有:

ArrayList、LinkedList、Stack以及Vector

●阐述ArrayList、Vector、LinkedList的存储性能和特性

●ArrayList和Vector都是使用数组方式存储数据,索引速度快而插入数据慢

●两者的区别是Vector有synchronized,线程安全而性能稍差

●LinkedList使用双向链表实现,插入速度快,内存利用率高

●ArrayList(intinitialCapacity)会不会初始化数组大小?

●会的,但只是让ArrayList有了容纳initialCapacity个元素的潜力(容器的容量和当前容器中的对象数量不是一回事)

●此时的size还是0,只能用add添加元素,若直接set(intindex,Eelement)设置某一位置的值会抛出IndexOutOfBoundsException

●ArrayList用来做队列合适么?

做栈呢?

●ArrayList不适合作为队列,因为队列是先进后出的,如果⽤ArrayList做队列,就需要在数组尾部追加数据,数组头部删除数组,要么浪费大量空间要么进行数据搬迁,总之不划算。

而定长的数组可以用于实现环形队列

●ArrayList适合作为栈,因为栈是先进先出,虽然需要频繁增删元素,但操作的都是数组末端的元素不涉及整个数组的

●ArrayList的遍历和LinkedList遍历性能比较如何?

●ArrayList要⽐LinkedList快得多,优势在于内存的连续性,CPU会缓存连续的内存片段,大幅降低读取内存的开销

●请简单说明一下什么是迭代器?

●集合对象可以通过实现Iterable接口中创建Iterator对象,对集合元素进行迭代

●迭代时只能用Iterator接口中的remove()方法删除元素,否则会触发快速失败,抛出ConcurrentModificationException

●请说明什么是集合中的快速失败(fast-fail)机制?

能讲讲其底层实现吗?

●快速失败是Java集合的一种错误检测机制,当某线程使用迭代器遍历集合A时,其他线程对集合A进行结构上的改变的操作(如增加或删除了一个元素),会抛出ConcurrentModificationException,产生快速失败,终止遍历

●当一个集合在被迭代器遍历期间发生了结构型变化,就会改变其变量modCount的值。

当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedModCount值,是的话就返回遍历,否则抛出异常,终止遍历

●拓展:

源码

●请你讲讲数组(Array)和列表(ArrayList)的区别

●Array可以包含基本类型和对象类型,ArrayList只能包含对象类型

●Array大小是固定的,ArrayList的大小是动态变化的(默认大小10,满了就扩充0.5倍变成15,建立新的、复制、销毁旧的)

●ArrayList提供了更多的方法和特性,比如:

addAll(),removeAll(),iterator()等

●Iterator和ListIterator的区别是什么?

●ListIterator是Iterator的一个实现,只能用来遍历list集合

●ListIterator可以前向和后向遍历集合,Iterator只能前向遍历

●2.Map

●Map接口有哪些实现类?

●Map接口的实现类主要有:

HashMap、Hashtable、ConcurrentHashMap、TreeMap、LinkedHashMap

●请你说明HashMap和Hashtable的区别

●HashMap允许键和值是null,而Hashtable不允许

●HashMap不考虑同步,线性不安全,多线程环境下进行扩容可能会出现HashMap死循环。

而Hashtable在put和remove等方法上使用synchronized进行同步,所以对单个方法的使用是线程安全的。

但在多个方法复合操作时,线程安全性也无法保证,比如一个线程执行先get然后put的复合操作,在这两个操作之间别的线程可能会对这个key做改动。

●HashMap

●HashMap底层实现结构有了解吗?

●JDK8之后由数组+链表+红黑树实现,新增加的红黑树解决了之前链表太长导致的查询速度变慢的问题

●HashMap的初始容量,加载因子,扩容增量是多少?

●HashMap的初始容量16,加载因子为0.75,扩容增量是原容量的1倍。

●例子:

初始容量为16,那么一次扩容后容量为32。

HashMap扩容是指元素个数(包括数组和链表+红黑树中)超过了16*0.75=12之后开始扩容。

●解决Hash冲突的方法有哪些?

●拉链法(HashMap使用的方法)

●线性探测再散列法

●二次探测再散列法

●伪随机探测再散列法

●哪些类适合作为HashMap的键?

●String和Interger这样的包装类很适合做为HashMap的键,因为他们是final类型的类,而且重写了equals和hashCode方法,避免了键值对改写,有效提高HashMap性能。

●请你解释为什么重写equals还要重写hashcode?

●HashMap中,如果要比较key是否相等,要同时使用

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2