Advertisement

2022Java后端开发面试题总结(社招+春招+秋招)

阅读量:

前言

在2022年的互联网寒冬时节,
有人在为另谋一份职业而作准备,
有人也在为寻找新的职业机会而作准备,
如果你感到迷茫不知所措的话,
不妨点击下方查看~

文章目录

学习 Java 的核心知识;深入理解集合与泛型组件(如容器)的功能与应用场景;掌握线程管理技术的基本原理;学习主要的框架如注解、反射以及流行框架的知识;理解继承、多态与封装的基本原理;掌握设计模式的核心思想及其实际应用;了解虚拟机环境与类加载机制的理解;熟悉 I/O 操作管理技术的学习;系统学习网络编程技术及计算机网络的基础知识;全面掌握数据库原理及应用学习;深入理解操作系统内核与系统管理技术的学习;掌握数据结构的核心概念及其实现方法掌握

Java基础—基础知识

一、八种基本数据类型的大小,以及他们的封装类。

八位字节(Byte),十六位短整数(Short), thirty-two位整数(Integer), sixty-four位长整数(Long),四舍五入精度浮点数(Float), sixty-four位双精度浮点数(Double),one-bit布尔值(Boolean), sixteen位字符(Character)

二、Switch能否用string做参数?

在switch语句中可使用的数据类型包括byte、short、int和char等基本数据类型。自 JDK 1.7 起,默认支持String类型的使用,在switch语句中通过比较其hashCode值并将其视为整数来进行判断。

三、equals与==的区别。

==操作符用于判断两个变量在内存中的存储位置是否相同;即通过比较变量值来确定其一致性。由String类从其父类Object继承而来;该方法被用来检测两个对象内容的一致性。

四、String s=new String(‘xyz’);创建了几个object对象?

将创建一个名为s的String类型变量。若类在此处尚未定义"xyz"常量,则会导致此处生成对应的字符串常量对象。新关键字在合规JVM上执行时将生成相应的字符串对象。

五、 Object有哪些公用方法?

1、clone()创建并返回此对象的副本

2、equals()判断

3、getclass()返回object的运行类

4、hashcode()返回对象的哈希码值

5、notify()唤醒正在等待对象监听器的单个进程

6、notifyAll()唤醒正在等待对象监听器的所有进程

7、调用wait()会引起此线程的等待;直到其他线程调用该对象的notify()方法或notifyAll()方法时才会触发。

8、toString()返回此对象的字符串表示形式

9、finalize()当垃圾收集确定不需要该对象时,垃圾回收器调用该方法

六、Java的四种引用,强弱软虚,用到的场景。

强引用:垃圾回收器不会回收

软件引用机制:如果内存资源充裕,则垃圾回收器会选择性地释放资源;反之,在内存资源紧张的情况下,则会触发垃圾回收器以实现资源管理。

弱引用:一旦发现了只有弱引用的对象,垃圾回收器就会进行回收。

虚拟引用:当发现该对象还存在虚拟引用时,在回收该对象之前将其加入与其相关联的引用队列中。

七、静态变量和实例变量的区别。

静态变量前要加上关键字static,实例变量则不会。

作为一个属性体存在于某个对象中,在这种情况下必须确保已经构建好了相应的关联对象之后才可以确保该属性体能够获得内存空间分配并进而可以访问其属性值。另一方面而言,在访问普通的非静态字段时,则需要构建出一个具体的实现了该接口的实际类型对应的完整个体之后才可以确保该字段能够获得内存空间分配并进而可以访问其属性值。本质上来说,在访问静态字段时无需构造任何实际的对象实体就可以直接获取其值;相反,在访问普通属性时则必须先构建对应的实现类型的具体化个体才能够完成赋值操作

八、 Overload和Override的区别:

重载Overload指的是同一类中有多个具有相同名称但参数配置不同的成员方法;这些成员方法的主要区别在于其输入或输出数据类型的差异;允许在这些情况下实现不同数据类型的输出;然而,在特定情况下——当两个成员函数拥有完全相同的输入和输出数据类型配置时——不允许通过修改函数后端处理逻辑来实现成员函数之间的互操作性;在这种特定情况下不允许通过修改后端处理逻辑来实现在这种情况下

Override操作符表明子类的方法名称及参数与parent class完全一致。当使用sub class实例调用此method时,则会执行sub class中所定义的method。也就是该method继承了parent的相关功能。当sub subclass覆盖parent method时,则只会抛出比parent更少或更小范围的异常错误信息。实现此功能的方式必须与被覆盖的方法返回值保持一致

九、抽象类和接口的区别。

抽象类具备预定义的具体实现能力,并且支持自定义的构造函数以及通过main方法运行功能。
一个抽象类不具备预定义的具体实现能力,并且无法直接使用main函数启动程序。
当在一个接口中添加新的成员方法时,则必须确保其具体实现类提供了相应的功能。
该系统不允许直接在抽象类中添加新的default方法。
此外,在设计此类系统时也必须考虑到不能直接为接口提供default实施方式。

十、String、StringBuffer与StringBuilder的区别。

String表示不可变的字符串类型而StringBuffer是可变的字符串类型两者都实现了equals()方法但只有String成功地覆盖并实现了hashCode()方法这使得当使用基于哈希码的操作时如果操作对象是基于equals()方法进行比较而哈希码未被正确计算的情况下会导致无法正常运行的问题特别是在集合类中存储的时候更加明显

StringBulider也提供了内容可以修改的字符串;然而其线程存在安全隐患;运行效率较高。

十一、 Java面向对象的特征与含义。

封装、继承、抽象、多态

封装的主要目标是为了通过设计实现程序运行中的"高内聚"与"低耦合"原则,在避免各组件之间互相干扰的同时保障系统的稳定性和可维护性。这种做法能够确保所有的操作方法与其相关联的操作内容被系统地整合到同一个实体类中,并且通过这种方式实现了对同一对象的一体化管理与处理。具体而言,在一个类体内不仅会包含处理该对象所有属性的操作方法及其相关的属性数据存储位置安排也包括了这些方法如何与数据相互作用的具体机制设计

抽象就是识别出事物之间的共同特征,并将其归纳为一类;仅考虑这些事物的共同特征,并排除与当前主题无关的因素。

3、继承:子类型能够继承其基础功能并在此基础上进行扩展。根据具体需求进行适当的扩展或优化以满足特殊应用的需求。从而提升了程序的复用性和灵活性。

4、多态:多态是指程序中定义的一个标识符所指向的具体数据类型以及通过该标识符引发的方法调用,在编程阶段无法明确确定,在运行期间才确定;即一个标识符最终对应的具体实例对象及其所引发的方法调用属于哪个类的具体实现需由程序运行阶段来决定。

十二、java多态的实现

接口实现,继承父类进行方法重写,

同一个类中进行方法重载。

十三、error和exception区别

error表示一种可能恢复但较为困难的严重问题,并且程序无法进行有效的处理;exception则表示一种设计或实现上的问题。

十四、运行时异常和一般异常的区别

异常标志:程序运行过程中可能出现的一种非正常状态。
运行时异常表明:虚拟机在常规操作中可能会发生的异常情况。
该编译器规定:方法必须声明可能被抛出的不可回收(non-recoverable)非运行时错误(exceptions),但并未强制要求对无法被捕获(uncaught)这类错误进行声明。

十五、Java中的异常处理机制和简单原理和应用

当 JAVA 程序违背了 JAVA 语义规范时

第十六章Java语言中的异常处理机制包括哪些内容throws throw try catch finally等关键字的作用是什么以及在一个try块内是否可以投射异常

Java采用面向对象的方式进行异常处理,并将不同类型的异常进行了分类管理的同时提供了一系列方便使用的接口。在Java编程中定义了多个具体的例外类来表示不同情况下的错误状态,在程序运行过程中一旦发生错误就会生成相应的错误信息并触发相应的异常机制以便及时响应可能出现的问题状态以提高系统的健壮性和可维护性

当遇到错误时会生成一个错误对象;其中包含错误信息;可以通过调用该对象的方法捕获到这一错误并进行相应的处理; Java 的错误处理机制则由五个关键字实现: try 用于执行一段代码块; catch 用于捕捉特定类型的错误; throw 可以定义新类型的错误并将其抛出; throws 则用于声明方法或操作符能抛出的所有可能类型的错误; finally 则用于指定默认的后话处理程序;通常在 try 关键字下执行一段代码块;如果这段代码块在运行过程中发生错误就会触发 throw 关键词导致系统会抛出一个错误(即通过 throws 关键字声明的操作符或方法);此时可以根据具体需求选择使用 catch 关键字捕获该类型的具体错误或者让缺省的后话处理器来进行后续操作

通过try指令必须包括一个catch子句来指定各种异常。

throw语句用来明确地抛出一个”异常”。

throws用来标明一个成员函数可能抛出的各种”异常”。

Finally为确保一段代码不管发生什么”异常”都被执行一段代码。

在一个成员函数调用外部编写一个try块,在其内部编写另一个try块以保护其他代码。每当遇到一个try块时,“异常”的框架会被放置到栈上,并继续直到所有嵌套的try块都处理完毕。
如果下一层级的try块未对某种特定的异常进行处理,则栈就会展开并继续向上查找处理该异常的第一层try块。

十七、 try catch finally,try里有return,finally还执行么?

1、finally语句总会执行

如果try/catch块包含return语句而finally块没有return语句,则在finally块中更改(除了包装类型、静态变量以及全局变量之外)的数据不会对try/catch块返回的变量产生任何影响(其中包装类型和静态变量会受到影响而全局变量不受影响)。

应尽量避免在finally块中调用return语句。若需要这样做,则会导致跳过try-catch块内的正常返回语句并忽视这些异常的处理,并最终忽视错误的处理过程。

4)在 finally 块中避免再次抛出异常,在 finally 块内出现异常会导致该块内的异常信息被释放出来,并且 try-catch 块中的任何异常将不会被捕获或处理

十八、 Java中final、finally和finalize的区别

Final用于声明属性、方法及类,并分别表明其特性:属性固定不变方法无法被覆盖;而类无法继承

内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……

finally是异常处理语句结构的一部分,表示总是执行。

finalize属于Object类的一个成员函数,在垃圾收集器执行的过程中会被当前被回收的对象自动调用该函数,并通过这种方式来实现对其他资源的有效回收。例如,在处理文件关闭等操作时具有特殊功能。需要注意的是,并非所有情况下该函数都会被调用。

十九、 常见的运行时异常

系统异常是RuntimeException的子类,常见的系统异常有:

ArrayIndexOutOfBoundsException - 数组越界访问

ClassCastException - 类型转换异常

NullPointerException - 试图访问一空对象的变量、方法或空数组的元素

IllegalArgumentException - 方法的参数无效

NoClassDefFoundException - JAVA运行时系统找不到所引用的类

集合:

二十、Collection框架的结构

集合框架(Collection Framework)涵盖java.util包的一系列类和接口.包括Collection, List, ArrayList, LinkedList, Vector(动态数组), HashSet, HashMap等。

在集合框架中定义的类通常实现了对一系列常见数据结构的封装与操作

集合框架类似于编程中常用的工具包,在促进编码者的专注能力方面起到了关键作用——通过使他们无需从底层实现相关细节而得以专注于业务层——包括对数据结构进行封装以及典型算法的具体实施

二十一、Collection包结构

Collection作为集合体的父亲接口,并且属于单一列结构。其主要继承了Set与List这两种接口.

Set接口的子接口有:HashSet,TreeSet

List接口的子接口有:Arraylist,LinkedList,Vector

二十二、Collection与Collections的区别。

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

该帮助类专门针对集合类设计,并负责执行集合相关的各种操作。

二十三、 Colection框架中实现比较要实现什么接口?

comparable:只包含compareTo()方法

comparator:compare()和equals()

二十四、Map、Set、List、Queue、Stack的特点与用法。

Map是以键值对的形式存储的数据结构,在其中每个键都是唯一的且不重复出现,并且每个键对应一个或多个可变值;当存在相同键时(即相同的输入),后续插入的新值会覆盖之前的记录。常见的实现方式有几种包括Treemap和HashMap;例如Tremap按键值顺序排列而 HashMap 则不按照特定顺序排列

2、List 有序,可重复

|–ArrayList

底层数据结构是数组,查询快,增删慢,线程不安全,效率高

|–Vector

底层数据结构是数组,查询快,增删慢,线程不安全,效率高

|–LinkedList

底层数据结构是链表,查询慢,增删块,线程安全,效率低

3、Set 无序,唯一

|–HashSet

底层数据结构是哈希表

如何保证元素的唯一性:

依赖两个方法,hashCode()和equals()

|–LinkedHashSet

由线性链表和哈希表构成底层数据结构,在线性链表中实现数据的有序排列,在哈希表中实现数据的唯一存储

|–TreeSet底层数据结构是红黑树,

如何保证元素的排序:

自然排序:让元素所属的类实现Comparable接口

比较器排序:让集合接收一个Comparator的实现类对象

如何保证元素的唯一性:

根据比较的返回值是否是0来决定的

4、遵循先进先出原则的Query队列不允许插入null值,在此框架中提供了相应的入队与出队操作。建议采用 offer() 方法以实现增删功能,并配合 poll() 方法完成增删操作。

Stack遵循先进后进的原则,并基于Vector类设计。该类增加了5个操作:支持push和pop操作,并包含检测堆栈是否为空的方法。

6、使用方法:

如果涉及到堆栈,队列等操作,建议使用List

对于快速插入和删除元素建议使用LinkedList

需要快速随机访问元素建议使用ArrayList

二十五、 Set里面的元素不能重复,用什么方法区分重复与否?

在Set中存储的元素必须唯一且不可重复,在判断一个元素是否已经存在于集合中时可以通过调用equals()方法来实现

equals方法和==运算符用于判断两个引用是否指向同一个对象实例。该方法被重写于类中以实现特定功能:如果两个不同对象的内容和类型相匹配,则返回true的布尔值。

二十六、HashMap和Hashtable的区别。

1、Hashtable是基于Dictionary类的,HashMap是Map接口的一个实现类

Hashtable是thread-safe的,并且是synchronized的;HashMap不是thread-safe,并且不是synchronized。

3、HashMap可以将空值作为key或value

二十七、 HashMap、LinkedHashMap、TreeMap的区别。

基于键的hashcode值实现数据存储,在Java语言中使用HashMap时会显著地提升数据查找效率,并且能够快速直接地通过键获取对应的值。此外,在内存中的位置是随机分布的。

按照记录的存入次序组织存储,在初始化时可指定依据应用频率进行排序参数。当我们采用Iterator进行遍历的时候,则最先被获取到的数据必定是最早被存入的数据。

3、TreeMap实现了SortMap接口,并能依据键对存储的记录进行排序。默认采用升序排列;用户可指定自定义的比较器来排序;遍历时将返回已按顺序排列的数据。

在Java程序设计中,请详细阐述这些数据结构(HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList和LinkedList)所依据的基础架构及其具体实现机制。

HashMap由Java数据结构中的两个主要构造单元(数组和链表)组成。 HashMap每个底层数组中的每一个元素都构成一个链表。 程序会通过调用键(key)的hashCode()方法计算出的结果来确定其存储位置。

存储的位置,在未被占用的情况下会将元素放置于此处;当处理两个具有相同key的Entry时,则会通过equals方法进行比较。若比较结果为true,则会覆盖原有的value;若结果为false,则会导致Entry链的形成并位于头部位置。

2、ArrayList基于动态数组实现,在执行add操作时,首先判断当前数组是否已满,并若已满则进行扩容。随后将原有数据复制到新分配的数组中。

3、LinkedList基于一个链表结构,在支持增删改查等基本操作方面与数据结构中的操作一致,并且其插入操作按顺序进行

其内部结构采用双链表形式,并未设置额外的锁定机制以保障数据一致性

ConcurrentHashMap 由段数组结构和 HashEntry 数组结构构成,在 ConcurrentHashMap 中段作为锁的作用发挥着关键作用,并且每个 HashEntry 用于存储键值对数据。其中每个段内仅包含一个 HashEntry 元素,在该元素内部进行数据修改时必须先获取其对应的段锁。此外,默认情况下每个 ConcurrentHashMap 配置有 16 个段

二十九、迭代器Iterator

Iterator提供了一种统一的遍历集合元素的操作接口,并且实现了Iterator接口的所有功能。具体来说,在调用iterator()方法后即可获得一个迭代器实例,并通过该实例依次对元素进行遍历操作。需要注意的是,在使用迭代器时应当避免直接调用集合自身的移除操作方法,否则会导致异常发生。相反地,在需要修改数据时可以通过remove()方法来实现元素的删除操作。

三十、 快速失败(fail-fast)和安全失败(fail-safe)的区别。

Iterator的安全失败现象源于对底层集合进行复制操作,并因此不受源集合修改的影响。在util包下所有的集合类均呈现快速失效特征,在util.concurren包下的所有类均为安全失效类型。

Java基础—集合框架/泛型/容器

概念

一、容器(Container)
Spring 提供了容器功能。这种容器能够管理对象的生命周期以及它们之间的依赖关系。通过一个配置文件(通常为 XML 类型),您可以指定对象的名字以及它们产生的方式(包括原型法和单一实例法)。当容器启动后,在线即可获取这些对象,并无需编写代码即可生成这些对象或建立它们之间的依赖关系。
换一种更直观的说法:Spring 的容器功能是一个基于 Java 编写的工具,默认情况下它会自动为您处理复杂的对象管理和依赖关系建立工作。

常用容器:WebSphere,WebLogic,Resin,Tomcat。

容器类

容器类本质上是一种专门用于存储和组织数据的数据结构,在Java中它被划分为集合(Set)、列表(List)和映射(Map)。那么为什么要使用容器呢?在Java编程中,默认情况下数组的大小是固定的,并且只能存储同一种类型的元素。而使用集合、列表或映射等容器类则能解决这些问题。

Java 容器类包含 List、ArrayList、Vector 及 map、HashTable、HashMap。

ArrayList和HashMap是非阻塞的,而Vector和Hash-Table则是阻塞类型的.由此可知,Vector和Hash-Table通过实现线程安全性达到了较高的执行效率,而传统的ArrayList和HashMap由于缺乏这种机制,运行效率相对较低.

二、集合框架的说明

全部集合类型均属于 java.util 包模块。Java 的集合类型主要由两个核心组件构成基础架构:Collection 和 Map 这两个核心组件是 Java 集合框架的基础架构中的核心组件,并且它们还包含了许多子组件或实现形式

1.Set、List 和 Map 可以看做集合的三大类:

该列表数据结构具有顺序特征,并且允许存储相同值;通过索引的方式能够快速获取指定位置的数据项。

Set 被称为无序集合的一种数据结构。
该集合中的所有成员必须唯一。
获取其中的成员仅能依据其自身属性进行。
同时也是由于集合中不允许出现相同元素所致。

Map集合中存储Key-value对形式的元素,在访问时仅凭每项元素的key以获取其value

三、集合框架详细说明

1、作为接口设计的Collection是一个高度抽象的集合结构,并整合了集合的基本操作与属性功能。其分支类型主要包括列表(List)与集合(Set)两大类。

该列表是一个有序排列的数据集合;每个元素都附有一个索引值;序列的第一个元素具有起始索引值 0;实现该列表的数据结构包括LinkedList、ArrayList、Vector以及Deque。

(2)Set 是一个禁止包含重复成员的集合数据结构。 Set 的具体实施类有 HashSet 和 TreeSet。 HashSet 被实现了基于 HashMap 算法;TreeSet 则是被实现了基于 TreeMap 算法

2、Map 实现了键值对的映射功能。每个 Map 元素都由一个键及其对应的值组成。作为 Map 接口的核心抽象基类(AbstractMap),它提供了丰富的公共API方法(如 put、get 等)。如 HashMap、TreeMap 和 WeakHashMap 等常用实现类均继承自该抽象基类,并扩展补充了特定的操作功能(例如有序存储)。尽管 Hashtable 的基类定义为 Dictionary 但其本质上仍遵循 Map 接口的要求。

3、接下来,请了解Iterator。它是一个访问集合对象的工具。由于Collection类必须实现iterator()方法以获取其元素,并返回迭代器对象作为结果。而ListIterator则专为访问List对象设计。

了解JDK 1.0中的枚举类Enum及其特性;该类类似于Iterator用于集合遍历;然而由于其功能限制,在上述框图中仅适用于Hashtable、Vector及Stack等常用集合类型

5、最后,看 Arrays 和 Collections。它们是操作数组、集合的两个工具类。

四、集合与数组

五、层次关系

六、几种重要的接口和类简介

七、遍历

八、ArrayList 和 LinkedList

九、Map 集合

十、主要实现类区别小结

Java基础—多线程

一、多线程基本概念

二、线程相关的常用方法

三、继承Thread类

四、实现Runnable 接口

五、Java 分为两种线程:用户线程和守护线程

六、用户线程就是前台线程,守护线程就是后台线程

七、什么是可重入锁?

八、Lock 与 synchronized 的不同

九、synchronized的使用

十、atomic 包底层实现原理

十一、Lock底层原理

十二、多线程不安全的底层原因以及两种加锁方式的区别

十三、Java多线程中 的各种锁

十四、Java多线程中 的各种锁(补充)

十五、阻塞队列BlockingQueue

十六、Java线程池、Java线程池进阶、Java中的ThreadLocal

Java基础—框架基础:注解/反射/流行框架

一、优化 Hibernate 所鼓励的7大措施

二、序列化和反序列化

三、Java中池的概念

四、Java反射

五、Spring的IOC和AOP概念和实现原理

六、 仿照 Spring 实现简单的 IOC

七、仿照 Spring 实现简单的 AOP

八、Spring bean 的生命流程

九、仿写Spring 进阶之 AOP和IOC协作

Java基础—面向对象:继承/多态/封装

一、重写与重载

二、单继承和多继承

三、多态

四、super和this关键字

Java基础—设计模式

一、单例模式之懒汉式和饿汉式

二、设计模式之观察者模式

三、设计模式之工厂模式

四、设计模式之代理模式

Java基础—JVM/类加载

一、初始化执行代码顺序(包含static块和构造块)以及类方法和实例方法

二、JVM内存结构

三、JVM组成部分

四、类加载机制

五、类加载器

六、Java类加载器之间的关系

七、虚拟机中的对象

八、虚拟机 分配内存

九、Java中的引用类型

十、JVM如何判断是否回收对象

十一、垃圾回收算法

十二、JVM运行时数据区域

十三、JVM垃圾收集器

十四、JVM垃圾回收

十五、Java中的内存泄露和内存溢出

Java基础——I/O

一、I/O 基本概念

二、I/O 模型 ——阻塞、非阻塞、多路复用、异步

三、JAVA中 BIO 与 NIO、AIO

网络编程和计网

一、Java中的原码、反码和补码

二、forward 和 redirect

三、URL的组成

四、通信的基础——IP、DNS、MAC地址

五、关于ip地址的理解

六、GFW(中国防火长城)工作原理

七、OSI七层模型和 五层体系结构

八、TCP 三次握手和四次挥手协议

九、TCP协议 (可靠保证、TCP、UDP、拥塞、ARQ)

十、HTTP 和 HTTPS

十一、Http/1.0、Http/1.1、Http2

十二、Https 加密过程详解

十三、HTTP协议的补充(POST、GET请求方法、幂等性)

十四、网络攻击(XSS、CSRF)详解

十五、DDoS 攻击详解

十六、SQL注入攻击详解

数据库

一、结果集 (ResultSet)全面解析

二、基本概念

三、索引

四、事务

五、存储引擎

六、数据库优化

七、数据库锁

八、主从复制和读写分离

操作系统

一、线程进程部分

二、内存和中断

三、互斥和同步

四、Linux相关命令

五、Linux IO 模式及 select、poll、epoll 详解

数据结构

一、链表、数组、字符、树篇

二、堆、栈、队列篇

三、B树、B+树、B*树

四、Java实现排序算法,比较时间复杂度

五、红黑树

六、数据结构之栈

七、搜索与回溯算法-Java实现

八、高效判断一个数,是不是素数

最后

为节省篇幅起见, 我选取了一些常见的重要面试题进行了展示.

由于每套面试题都有其独特性, 上述试题仅作为参考借鉴.

主要目的是为了通过积累知识储备做好充分准备, 以防不测.

如需获取资料, 请访问我的主页.

全部评论 (0)

还没有任何评论哟~