今天记录一下今年一家深圳上市公司java开发工程师的面试题,也是比较经典的一些问题,希望能帮助到大家
学习目标:
2024年JAVA开发工程师面试题
学习内容:
1.常见的集合有哪些?
常见的集合有list,set,map,其中:
list集合常见的有:ArrayList和LinkedList和Vector,区别就是ArrayList的底部是数组,查询速度快,删除效率低,LinkedList的底部是双向链表,增删操作快,查询较慢。Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素(其区别经常会问)
set集合常见的有HashSet
map集合常见的有haspmap与ConcurrHashmap,后者比前者具有线程安全性。
2.== 和 equals 的区别是什么?
== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;
而 equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。
3.HashMap 和 Hashtable 有什么区别?
hashTable同步的,而HashMap是非同步的,效率上比hashTable要高。
hashMap允许空键值,而hashTable不允许。
4.面对对象的特点
Java面向对象具有以下三个主要特征:
封装(Encapsulation)
封装是Java面向对象编程的基本特征之一。它将数据和相关的方法封装在一个对象中,并对外部提供公共接口来访问这些数据和方法。通过封装,对象的内部细节被隐藏起来,外部只能通过接口来与对象进行交互,而无需关心对象内部的实现细节。
封装的优势在于它提高了代码的可维护性和复用性。封装将数据和行为封装在一起,使得代码更加模块化和可组织。这种模块化的设计有助于代码的维护和调试,并且可以减少对其他代码的依赖性。此外,封装还可以保护数据的安全性,防止数据被意外修改或破坏。通过提供合适的访问控制,可以限制对数据的直接访问,从而确保数据的完整性和一致性。
继承(Inheritance)
继承是Java面向对象编程的另一个重要特征。继承允许创建一个新类,通过继承已有类的属性和方法,从而实现代码的重用和扩展。在继承关系中,被继承的类称为父类或基类,而继承父类的类称为子类或派生类。
继承的优势在于它提供了代码的重用性和层次化的设计。通过继承,子类可以直接使用父类中已经定义的方法和变量,无需重新编写相同的代码。这样可以减少代码的冗余,提高代码的复用性和可维护性。此外,继承还允许我们建立对象之间的层次结构,通过使用父类引用指向子类对象,可以实现多态性。
多态(Polymorphism)
多态是面向对象编程中的一个重要概念,也是Java的核心特征之一。多态是指在面向对象编程中,同一消息可以被不同类型的对象解释和执行的能力。具体来说,当多个对象都可以以某种方式响应相同的消息时,就存在多态。
多态的优势在于它提高了代码的灵活性和可扩展性。通过多态,我们可以编写更通用、更可复用的代码。多态使得代码可以适应不同类型的对象,而无需修改已有的代码逻辑。这样,我们可以通过定义通用的接口或抽象类来操作对象,而不需要关心具体的对象类型。这种灵活性使得我们可以在运行时动态地决定使用哪个对象的实现,从而实现更高层次的代码组织和扩展。
5.接口有什么特点
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
接口的特点:
①:接口不可实例化,可结合多态进行使用 接口 对象=new 对象();
②:接口里的成员属性全部是以 public(公开)、static(静态)、final(最终) 修饰符修饰,
接口里的成员方法均为抽象方法,全部是以 public(公开)、abstract(抽象) 修饰符修饰
全局常量的修饰符会自动设为:public static final
抽象方法的修饰符会自动设为:public abstract
③:接口里不能包含普通方法、静态方法以及实例域,可包含常量。
④:只能由实现了接口的子类并覆盖了接口中所有的抽象方法后,该子类才可以实例化。 否则,这个子类就是一个抽象类。接口是不能直接通过new来实例化的,没有具体实现的接口实例化也没有意义。
6.抽象类的特点:
①成员属性必须不能是 private(私有) 修饰符修饰
②成员方法可包含普通方法(虚方法)和abstract(抽象)修饰的抽象方法
③子类可选择性的重写虚方法,必须实现父类的所有抽象方法
7.String类型有什么特点
①字符串String类型本身是final声明的,意味着我们不能继承String。final类不能被继承。
②字符串的对象也是不可变对象,意味着一旦进行修改,就会产生新对象。
③String对象内部是用字符数组进行保存的。
8.对象与实例之间的区别
对象是同类事物的一种抽象表现形式,而实例是对象的具体化,一个对象可以实例化很多实例,对象就是一个模型
9.堆栈的不同
java堆是在程序运行时,而不是在程序编译时,申请某个大小的内存空间。即动态分配内存,对其访问和对一般内存的访问没有区别。栈是先进后出的,但是于堆而言却没有这个特性,两者都是存放临时数据的地方。
10.string与stringbuffer的区别
String类提供的数值不可改变,StringBuffer是可以对字符串进行修改的。
11.int和integer区别
int是基础数据类型,integer是一个类
12.Rabbitmq应用场景
MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。
RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、 安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。
应用场景:
1. 解耦(为面向服务的架构(SOA)提供基本的最终一致性实现)
2. 异步提升效率(串行和并行)
3. 流量削峰(流量削峰也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛)
13.序列化和反序列化
Java的序列化(Serialization)和反序列化(Deserialization)是指将对象转换为字节流以便存储或传输,并在需要时重新构建该对象。
Java序列化:
①使用java.io.ObjectOutputStream
类来进行序列化操作。
②首先创建一个FileOutputStream
对象,将其连接到目标文件上。
③然后通过调用writeObject()
方法将对象写入文件中
Java反序列化:
①使用java.io.ObjectInputStream
类来进行反序列化操作。
②首先创建一个FileInputStream
对象,将其连接到包含序列化数据的文件上。
③然后通过调用readObject()
方法从文件中读取对象。
14.HashMap的底层原理
HashMap是一个存储key-value键值对的集合,每一个键值对也叫做entry,这些entry分散存储在一个数组中,这个数组也是HashMap的主干,这个数组每个元素的初始值都是null。
数组(键值对entry组成的数组主干)+ 链表(元素太多时为解决哈希冲突数组的一个元素上多个entry组成的链表)+ 红黑树(当链表的元素个数达到8链表存储改为红黑树存储)
无序,线程不安全。
Java的HashMap是一种常用的数据结构,用于存储键值对。它的底层实现原理是基于哈希表。
哈希表是一种以键值对存储和访问数据的数据结构。它通过将键映射到哈希表中的一个位置来快速访问值。在Java的HashMap中,键和值都可以为任意类型的对象。
15.静态多态和动态多态关系
Java中多态分两种,一种是静态多态,一种为动态多态;后者才是我们常说的多态
一、静态多态(类中方法重载)
静态多态就是类中方法重载
二、动态多态(重写)
多态的使用一般都是子类给父类引用进行赋值
16.垃圾回收机制
垃圾回收是指在程序运行过程中,自动回收不再使用的内存空间,以便程序能够更有效地使用内存。Java的垃圾回收机制是一种自动化的内存管理技术,它可以自动回收不再使用的内存空间,从而避免了程序员手动管理内存的繁琐工作
17.JVM
•JVM是JavaVirtualMachine(Java虚拟机)的缩写
•JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
•JVM就是一个虚拟的用于执行bytecodes字节码的计算机
•Java虚拟机是Java最核心技术,也是跨平台的基础。
•Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
•Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因
18.线程与多线程的理解
一、线程的基本概念 线程是指程序中独立运行的一个执行线索,在一个进程中可以有多个线程并行执行。每个线程都有自己的执行路径,可以独立地执行任务。与传统的顺序执行相比,多线程可以提高程序的效率和响应性,特别适用于需要同时处理多个任务的情况。
线程主要有两种状态:运行状态和阻塞状态。当线程创建并启动后,就处于运行状态,开始执行任务。当线程需要等待某个条件满足或者等待其他线程的结束时,它会进入阻塞状态,暂时停止执行。当条件满足或者其他线程结束后,线程会被重新唤醒,回到运行状态继续执行。
二、创建线程的方式 在Java中,创建线程有两种方式:继承Thread类和实现Runnable接口。这两种方式都可以创建线程,但推荐使用实现Runnable接口的方式,因为Java不支持多重继承,而实现接口可以更灵活地组织代码。
19.MVC的原理
MVC核心思想:业务数据抽取同业务数据实现相分离
模型层(M) :业务数据的信息表示,关注支撑业务的信息构成,通常是多个业务实体的组合;
视图层(V): 为用户提供UI,重点关注数据的呈现;
控制器(C) : 接受用户请求,并调用相应的模型处理;
(相当于一个总调配中心,有什么需求,就去调用相应模型进行处理,最后通过视图给用户进行展示);
MVC(Model-View-Controller)设计思想
即把一个应用的输入、处理、输出流程按照Model、View、Controller的方式进行分离,这样一个应用被分成三个层——模型层、视图层、控制层。
视图(View)代表用户交互界面;
模型(Model):就是业务流程/状态的处理以及业务规则的制定。
业务模型还有一个很重要的模型那就是数据模型。数据模型主要指实体对象的数据 保存(持续化)。
控制(Controller)可以理解为从用户接收请求, 将模型与视图匹配在一起,共同完成用户的请求.
20.SpringMVC的常见注解
1、@Component 在类定义之前添加@Component注解,他会被spring容器识别,并转为bean。
2、@Repository 对Dao实现类进行注解 (特殊的@Component)
3、@Service 用于对业务逻辑层进行注解, (特殊的@Component)
4、@Controller 用于控制层注解 , (特殊的@Component)
21.service层出现重复的类怎么办
1. 删除重复类:如果重复类没有任何差异或者只是命名不同,可以直接删除其中一个类。
2. 合并重复类:如果重复类有一些差异,但是功能相似,可以考虑将它们合并成一个类,通过继承或者接口实现来处理差异。
3. 使用重命名:如果重复类之间存在一些区别,但是功能相似,可以通过重命名其中一个类来区分它们。
4. 使用包管理:如果重复类来自不同的包或者模块,可以通过包管理来区分它们,确保每个类都有唯一的全限定类名。