史上最全面Java面试汇总(面试题+答案)

1.面向对象和面向过程的区别

面向过程 优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。 缺点:没有面向对象易维护、易复用、易扩展面向对象 优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护 缺点:性能比面向过程低

2.Java的四个基本特性(抽象、封装、继承,多态)

抽象:就是把现实生活中的某一类东西提取出来,用程序代码表示,我们通常叫做类或者接口。抽象包括两个方面:一个是数据抽象,一个是过程抽象。数据抽象也就是对象的属性。过程抽象是对象的行为特征。 封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行封装隐藏。封装分为属性的封装和方法的封装。 继承:是对有着共同特性的多类事物,进行再抽象成一个类。这个类就是多类事物的父类。父类的意义在于抽取多类事物的共性。 多态:允许不同类的对象对同一消息做出响应。方法的重载、类的覆盖正体现了多态。

 篇幅限制下面就只能给大家展示小册部分内容了。这份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记的【点击此处即可】即可免费获取

3.重载和重写的区别

重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。 重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类;如果父类方法访问修饰符为private则子类中就不是重写。

4.构造器Constructor是否可被override

构造器不能被重写,不能用static修饰构造器,只能用public private protected这三个权限修饰符,且不能有返回语句。

5.访问控制符public,protected,private,以及默认的区别

private只有在本类中才能访问; public在任何地方都能访问; protected在同包内的类及包外的子类能访问; 默认不写在同包内能访问。

6是否可以继承String类

String类是final类故不可以继承,一切由final修饰过的都不能继承。

7.String和StringBuffer、StringBuilder的区别

可变性 String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的。StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value,这两种对象都是可变的。线程安全性 String中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。性能 每次对String 类型进行改变的时候,都会生成一个新的String 对象,然后将指针指向新的String 对象。StringBuffer每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StirngBuilder 相比使用 StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险。

8.hashCode和equals方法的关系

equals相等,hashcode必相等;hashcode相等,equals可能不相等。

9.抽象类和接口的区别

语法层次 抽象类和接口分别给出了不同的语法定义。设计层次 抽象层次不同,抽象类是对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。抽象类是自底向上抽象而来的,接口是自顶向下设计出来的。跨域不同 抽象类所体现的是一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is-a" 关系,即父类和派生类在概念本质上应该是相同的。对于接口则不然,并不要求接口的实现者和接口定义在概念本质上是一致的,仅仅是实现了接口定义的契约而已,"like-a"的关系。

10.自动装箱与拆箱

装箱:将基本类型用它们对应的引用类型包装起来; 拆箱:将包装类型转换为基本数据类型; Java使用自动装箱和拆箱机制,节省了常用数值的内存开销和创建对象的开销,提高了效率,由编译器来完成,编译器会在编译期根据语法决定是否进行装箱和拆箱动作。

11.什么是泛型、为什么要使用以及泛型擦除

泛型,即“参数化类型”。 创建集合时就指定集合元素的类型,该集合只能保存其指定类型的元素,避免使用强制类型转换。 Java编译器生成的字节码是不包涵泛型信息的,泛型类型信息将在编译处理是被擦除,这个过程即类型擦除。泛型擦除可以简单的理解为将泛型java代码转换为普通java代码,只不过编译器更直接点,将泛型java代码直接转换成普通java字节码。 类型擦除的主要过程如下: 1).将所有的泛型参数用其最左边界(最顶级的父类型)类型替换。 2).移除所有的类型参数。

12.Java中的集合类及关系图

List和Set继承自Collection接口。 Set无序不允许元素重复。HashSet和TreeSet是两个主要的实现类。 List有序且允许元素重复。ArrayList、LinkedList和Vector是三个主要的实现类。 Map也属于集合系统,但和Collection接口没关系。Map是key对value的映射集合,其中key列就是一个集合。key不能重复,但是value可以重复。HashMap、TreeMap和Hashtable是三个主要的实现类。 SortedSet和SortedMap接口对元素按指定规则排序,SortedMap是对key列进行排序。

15.HashMap和HashTable区别

1).HashTable的方法前面都有synchronized来同步,是线程安全的;HashMap未经同步,是非线程安全的。 2).HashTable不允许null值(key和value都不可以) ;HashMap允许null值(key和value都可以)。 3).HashTable有一个contains(Object value)功能和containsValue(Object value)功能一样。 4).HashTable使用Enumeration进行遍历;HashMap使用Iterator进行遍历。 5).HashTable中hash数组默认大小是11,增加的方式是old*2+1;HashMap中hash数组的默认大小是16,而且一定是2的指数。 6).哈希值的使用不同,HashTable直接使用对象的hashCode; HashMap重新计算hash值,而且用与代替求模。

16.ArrayList和vector区别

ArrayList和Vector都实现了List接口,都是通过数组实现的。 Vector是线程安全的,而ArrayList是非线程安全的。 List第一次创建的时候,会有一个初始大小,随着不断向List中增加元素,当List 认为容量不够的时候就会进行扩容。Vector缺省情况下自动增长原来一倍的数组长度,ArrayList增长原来的50%。

17.ArrayList和LinkedList区别及使用场景

区别 ArrayList底层是用数组实现的,可以认为ArrayList是一个可改变大小的数组。随着越来越多的元素被添加到ArrayList中,其规模是动态增加的。 LinkedList底层是通过双向链表实现的, LinkedList和ArrayList相比,增删的速度较快。但是查询和修改值的速度较慢。同时,LinkedList还实现了Queue接口,所以他还提供了offer(), peek(), poll()等方法。使用场景 LinkedList更适合从中间插入或者删除(链表的特性)。 ArrayList更适合检索和在末尾插入或删除(数组的特性)。

18.Collection和Collections的区别

java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。 java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

19.Concurrenthashmap实现原理

 篇幅限制下面就只能给大家展示小册部分内容了。这份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记的【点击此处即可】即可免费获取

20.Error、Exception区别

Error类和Exception类的父类都是throwable类,他们的区别是: Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。 Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

21.Unchecked

Exception和Checked Exception,各列举几个#Unchecked Exception: a. 指的是程序的瑕疵或逻辑错误,并且在运行时无法恢复。 b. 包括Error与RuntimeException及其子类,如:OutOfMemoryError, UndeclaredThrowableException, IllegalArgumentException, IllegalMonitorStateException, NullPointerException, IllegalStateException, IndexOutOfBoundsException等。 c. 语法上不需要声明抛出异常。

Checked Exception: a. 代表程序不能直接控制的无效外界情况(如用户输入,数据库问题,网络异常,文件丢失等) b. 除了Error和RuntimeException及其子类之外,如:ClassNotFoundException, NamingException, ServletException, SQLException, IOException等。 c. 需要try catch处理或throws声明抛出异常。

22.Java中如何实现代理机制(JDK、CGLIB)

JDK动态代理:代理类和目标类实现了共同的接口,用到InvocationHandler接口。 CGLIB动态代理:代理类是目标类的子类,用到MethodInterceptor接口。

23.多线程的实现方式

继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。

24.线程的状态转换

25.如何停止一个线程

 篇幅限制下面就只能给大家展示小册部分内容了。这份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记的【点击此处即可】即可免费获取

26.什么是线程安全

线程安全就是多线程访问同一代码,不会产生不确定的结果。

27.如何保证线程安全

对非安全的代码进行加锁控制; 使用线程安全的类; 多线程并发情况下,线程共享的变量改为方法级的局部变量。

28.synchronized如何使用

synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种: 1). 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象; 2). 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象; 3). 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象; 4). 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

29.synchronized和Lock的区别

主要相同点:Lock能完成synchronized所实现的所有功能 主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。Lock的锁定是通过代码实现的,而synchronized是在JVM层面上实现的,synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。Lock还有更强大的功能,例如,它的tryLock方法可以非阻塞方式去拿锁。Lock锁的范围有局限性,块范围,而synchronized可以锁住块、对象、类。

30.多线程如何进行信息交互

void notify() 唤醒在此对象监视器上等待的单个线程。 void notifyAll() 唤醒在此对象监视器上等待的所有线程。 void wait() 导致当前的线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法。 void wait(long timeout) 导致当前的线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,或者超过指定的时间量。 void wait(long timeout, int nanos) 导致当前的线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值