java常见面试题

1. 什么是Java?

Java是一种跨平台的高级编程语言,能够在不同的操作系统上运行相同的代码。它的特点包括面向对象、安全、可靠、易于学习和使用等。

2. 什么是Java虚拟机(JVM)?

Java虚拟机(JVM)是Java程序的运行环境,它是一个虚拟的计算机,可以在不同的操作系统上运行Java程序,提供了Java程序的跨平台性。JVM负责将Java字节码编译成机器码,并管理Java程序的内存。它还提供了一些重要的功能,如垃圾回收、安全性和异常处理等。JVM是Java语言成功的关键之一,因为它使得Java程序可以在不同的计算机上运行,而不必担心操作系统的差异性。

3. 什么是Java的内存模型?

Java的内存模型定义了Java程序如何使用内存,包括如何分配、使用和释放内存。Java内存模型规定了多线程程序中内存访问的可见性、原子性和有序性等方面的规则,以确保多线程程序的正确性。
Java内存模型中的主要概念包括堆、栈和方法区等。堆用于存储对象、实例变量和数组等,它是所有线程共享的。栈用于存储局部变量和方法调用等,每个线程都有自己的栈。方法区用于存储类的信息、常量池和静态变量等,它也是所有线程共享的。
Java内存模型还提供了一些同步机制,如synchronized块和volatile变量等,来避免线程冲突和数据竞争等问题。synchronized块可以保证同一时刻只有一个线程可以访问同步块中的代码,而volatile变量可以保证变量的可见性,即一个线程修改了volatile变量的值,其他线程可以立即看到修改后的值。

4. 什么是垃圾回收器?

垃圾回收器是Java虚拟机的一部分,负责自动管理Java程序中的内存。它会自动检测不再使用的对象,并释放内存以供其他对象使用。
在Java程序中,内存分为堆和栈两部分。堆用于存储对象、实例变量和数组等,而栈用于存储局部变量和方法调用等。当一个对象不再被引用时,它就变成了垃圾,但是它所占用的内存并不会立即被释放。垃圾回收器会定期地检测堆中的垃圾,并释放它们所占用的内存。
Java垃圾回收器的工作方式可以分为标记-清除、复制和标记-整理等方式。其中标记-清除算法会标记所有的垃圾对象,然后清除它们所占用的内存。复制算法会将堆分为两部分,每次只使用其中一部分,当这部分内存满了之后,它会将存活的对象复制到另一部分,并清除旧的部分。标记-整理算法则会将存活的对象移动到一端,然后清除边界以外的内存。
垃圾回收器的自动内存管理可以避免内存泄漏和内存溢出等问题,提高了Java程序的可靠性和稳定性。但是,垃圾回收器的工作也会占用一定的CPU和内存资源,可能会对Java程序的性能产生一定的影响。

5. 什么是面向对象编程?

面向对象编程是一种编程范式,具有可重用性、可扩展性、可维护性和可靠性等优点。它将数据和操作数据的方法打包在一起,形成对象。面向对象编程中的对象可以互相交互,从而实现复杂的功能。
在面向对象编程中,一切皆为对象。对象是一个具有属性和行为的实体,属性指对象的特征,行为指对象可以执行的操作。对象可以通过定义类来创建,类是一种抽象的数据类型,它定义了对象的属性和行为。类可以看作是对象的模板,通过创建对象来实现对类的实例化。

6. 什么是多态?

多态是面向对象编程中的一个重要概念。它指的是同一行为(方法)在不同情况下表现出不同的行为特征。具体来说,它包括两种形式:编译时多态和运行时多态。
编译时多态是通过重载和重写实现的,即在编译时根据不同的参数、内部状态等来决定执行哪个方法。编译时多态实现简单,但缺乏灵活性。
运行时多态是通过接口、抽象类和虚函数实现的,即程序在运行时根据对象的实际类型来调用相应的方法。这种多态形式实现起来较为复杂,但更加灵活,能够充分发挥面向对象的优势。

7. 什么是继承?

继承是一种面向对象编程中的重要概念,它允许一个类(称为子类)从另一个类(称为父类)中继承属性和方法。子类可以使用父类的属性和方法,也可以添加自己的新属性和方法。这样可以避免在编写代码时重复编写相同的代码,同时还可以提高代码的可维护性和可扩展性。在继承中,子类会自动获得父类的属性和方法,但可以通过覆盖父类中的方法来实现自己的特殊需求。

8. 什么是抽象类?

抽象类是一种特殊的类,它不能被实例化,只能用于继承。抽象类中的方法没有实现代码,只有声明,这些方法被称为“抽象方法”,因为它们只是定义了方法的签名(名称、参数和返回类型),但没有提供方法的具体实现。
抽象类的主要用途是作为其他类的基类,以提供一组抽象方法,这些方法必须在派生类中被实现。这样可以确保派生类中实现了基类中定义的所有抽象方法,从而保证了派生类的一致性和可靠性。
另外,抽象类也可以包含非抽象的方法,这些方法可以有实现代码。派生类可以选择性地覆盖这些方法,或者继承它们的默认实现。这为面向对象编程提供了一种灵活的方式,使得基类可以提供一些通用的功能实现,而派生类可以选择性地对其进行修改或扩展。
在Java中,抽象类是使用关键字abstract来声明的,而在C++中,它们被称为“纯虚函数”,使用关键字virtual和=0来声明。抽象类是面向对象编程中的重要概念,深入理解其原理和使用方法对于开发高质量的软件系统非常重要。

9. 什么是接口?

接口是一种约定,用于规定某个对象或者方法应该提供哪些操作或功能。在面向对象编程中,接口是一种抽象类型,它定义了一个或多个方法的规范,但却不具体实现这些方法。实现接口的类必须实现这些方法,以满足接口的规定。
接口的设计可以让我们的代码更加灵活、高效,也能够减少代码的依赖,提高代码的可读性和可维护性。通常情况下,接口会让程序员将实现细节和约束分开来,从而使得程序的设计更加清晰。
需要注意的是,在Java语言中,接口是在编译期间就被确定并写入.class文件中的,而在程序运行时,接口并不占用内存空间,因为它不是一个具体的类。

10. 什么是重载和重写?

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处,在于子类可以根据自身需要,定义特定于自己的行为。 也就是说子类能够根据需要重写父类的方法。
重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。
当需要在子类中调用父类的被重写方法时,可以使用 super 关键字。

重载是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的场景就是构造器的重载。

11. 对集合的理解?

HashMap与HashTable的区别?

HashMap没有考虑同步,是线程不安全的;Hashtable使用了synchronized关键字,是线程安全的;
HashMap允许K/V都为null;hashtable后者K/V都不允许为null;
HashMap继承自AbstractMap类;而Hashtable继承自Dictionary类;

如何决定选用HashMap还是TreeMap?

对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小,也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历。

ArrayList和Vector有何异同点?

ArrayList和Vector在很多时候都很类似。
(1)两者都是基于索引的,内部由一个数组支持。
(2)两者维护插入的顺序,我们可以根据插入顺序来获取元素。
(3)ArrayList和Vector的迭代器实现都是fail-fast的。
(4)ArrayList和Vector两者允许null值,也可以使用索引值对元素进行随机访问。
以下是ArrayList和Vector的不同点。
(1)Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
(2)ArrayList比Vector快,它因为有同步,不会过载。
(3)ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表

ArrayList和LinkedList有何区别?

ArrayList和LinkedList两者都实现了List接口,但是它们之间有些不同。
(1)ArrayList是由Array所支持的基于一个索引的数据结构,所以它提供对元素的随机访问,复杂度为O(1),但LinkedList存储一系列的节点数据,每个节点都与前一个和下一个节点相连接。所以,尽管有使用索引获取元素的方法,内部实现是从起始点开始遍历,遍历到索引的节点然后返回元素,时间复杂度为O(n),比ArrayList要慢。
(2)与ArrayList相比,在LinkedList中插入、添加和删除一个元素会更快,因为在一个元素被插入到中间的时候,不会涉及改变数组的大小,或更新索引。
(3)LinkedList比ArrayList消耗更多的内存,因为LinkedList中的每个节点存储了前后节点的引用。
• Linkedlist是底层:双向链表
在ArrayList中增加或者删除某个元素,通常会调用System.arraycopy方法,这是一种极为消耗资源的操作,因此,在频繁的插入或者是删除元素的情况下,LinkedList的性能会更加好一点。

12. 简述线程,程序、进程的基本概念。以及他们之间关系是什么?

线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。
进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。
线程 是 进程 划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段

13. 什么是同步和异步?

同步请求,就是按顺序处理,即当我们向服务器发出一个请求时,在服务器没返回结果给客户端之前,我们要一直处于等待状态直至服务器将结果返回到客户端,我们才能执行下一步操作。例如我们经常使用浏览器去访问一个网站的时候,其实就是同步请求,也就是浏览器发出一个请求,服务器就回复一个请求。
同样的,这里异步指的就是异步请求,也就是java上说的并行处理。即当我们向服务器发出一个请求时,在服务器没返回结果之前,我们还是可以执行其他操作。因为系统的迁移程序会启动,所以你可以关闭你的请求窗口,而实际上你的请求系统已经响应了。

例如

泡茶需要的步骤有烧水,洗杯子,装茶叶,倒水。同步的话,就是在烧水的时候就等着,直到水烧开后,再去洗杯子,洗完杯子后再去装茶叶,最后再倒水。而异步的话就是指在烧水的时候我们不用一直等着,我们可以先去做后面的几件事。

14. 什么是锁?

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。 基本锁类型:锁包括行级锁和表级锁

15. 什么是事务?

事务是一种机制、一个操作序列,包含了一组数据库操作命令,事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失败,事务是一个不可分割的工作逻辑单元

16. 什么是ORM框架?

ORM 全称是对象关系映射,是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。

17. 什么是Web框架?

Web框架是一种软件框架,它通常用于支持Web应用程序的开发。Web应用程序是指运行在Web浏览器中的应用程序,比如在线商店、社交媒体平台等。
Web框架一般包括以下组件:路由、模板引擎、数据库连接、表单验证等。路由用于将请求路由到相应的处理函数;模板引擎用于生成HTML页面;数据库连接允许在代码中与数据库进行交互,而表单验证则可以确保用户输入的数据的正确性和安全性。
常见的Web框架有Django、Flask、Ruby on Rails等。

18. 什么是RESTful API?

一 : 说说什么是REST规则

① 首先什么是REST ?

  基于HTTP、URI、XML、JSON等标准和协议,支持轻量级、跨平台、跨语言的架构设计。是Web服务的一种新的架构风格(一种思想)。

② 满足哪些REST原则的架构能够称为 RESTful ?

对网络上所有的资源都有一个资源标志符。
对资源的操作不会改变标识符。
同一资源有多种表现形式(xml、json)
所有操作都是无状态的(Stateless)

二,什么是无状态性 ?

使得客户端和服务器端不必保存对方的详细信息,服务器只需要处理当前的请求,不需了解请求的历史。可以更容易的释放资源,让服务器利用Pool(连接池)技术来提高稳定性和性能。

三,什么是 RESTful

RESTful是一种常见的REST应用,是遵循REST风格的web服务,REST式的web服务是一种ROA(面向资源的架构)。

19. 什么是消息队列?

关于这个问题我从三个方面解答,第一个是概念MQ,消息队列是一种应用之间异步通信的方式,主要由三部分组成,第一个是生产者,也就是说生产消息的这一端,主要负责消息所承载业务信息的一个实例化,他是整个消息的发起方,中间的broker,也就是代理,他是整个消息的一个服务端,主要处理消息单元,他负责消息的存储,投递,以及一些其他附加功能的实现,他是整个消息队列里面最核心的组成部分。
第三个是消费者,他主要负责消息的消费,根据消息所承载的信息去处理各种业务逻辑。
应用场景主要分为三种:
第一种是异步处理,主要应用在实时性要求不严格的一些场景,比如说用户注册,发送验证码下单通知,发送优惠券等,服务方只需要把协商好的信息发送到消息队列,剩下的是由消费者的消息服务去处理,不需要等待消费者的返回结果就可以直接返回给客户端,返回到业务层面。
第二种是应用解耦,应用解藕可以看做是把一些相关的,但是藕合度不高的一些系统关联起来,比如说订单系统与优惠券积分系统,有关联度,但是没有那么紧密,每个系统之间只需要去把一些约定的消息发送到 MQ,另外的系统直接去消费这个消息就行了,他可以解决各类系统之间,采用不同的一些框架语言来实现,从而大大增加了整个系统的灵活度。
第三个是流量削峰,流量削峰一般是应用在大流量入口的一些短时间内的业务,需求处理不完的一些服务,为了去权衡高可用把大量的一些并行任务发送到 MQ,根据 MQ 存储和分发的功能,平稳的处理后续的一些业务,起到大流量缓冲的一个作用。
目前市面上常见的消息队列中间件有ActiveMq,RabbitMq,kafka,rocketMq。根据业务需求选择合适的中间件,低吞吐量的用 ActiveMq,高吞吐量的用 kafka 和 rocketMq。

20. 什么是缓存?

【1】缓存就是数据交换的缓冲区(称作:Cache),当某一硬件要读取数据时,会首先从缓存汇总查询数据,有则直接执行,不存在时从内存中获取。由于缓存的数据比内存快的多,所以缓存的作用就是帮助硬件更快的运行。
【2】缓存往往使用的是RAM(断电既掉的非永久存储),所以在用完后还是会把文件送到硬盘等存储器中永久存储。电脑中最大缓存就是内存条,硬盘上也有16M或者32M的缓存。
【3】高速缓存是用来协调CPU与主存之间存取速度的差异而设置的。一般CPU工作速度高,但内存的工作速度相对较低,为了解决这个问题,通常使用高速缓存,高速缓存的存取速度介于CPU与主存之间。系统将一些CPU在最近几个时间段经常访问的内容存在高速缓存,这样就在一定程度上缓解了由于主存速度低造成的CPU“停工待料”的情况。
【4】缓存就是把一些外存上的数据保存在内存上而已,为什么保存在内存上,我们运行的所有程序里面的变量都是存放在内存中的,所以如果想将值放入内存上,可以通过变量的方式存储。在JAVA中一些缓存一般都是通过Map集合来实现的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

B64A-消闲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值