一、Java语言特性
面向对象编程(OOP)
封装、继承、多态
面向对象的三大特性,封装指的外部不能直接操作类中的数据,而是使用类提供的私有方法进行操作,保证了数据的安全性
继承是不同对象经常有一些相同的特点,继承就是将共同的属性提取出来作为基础类,子类可以继承父类的所有属性和方法,但不能调用父类的私有方法,可以实现
多态是一个一个对象可以由多种状态,具体表现为为父类的引用指向子类的实现
接口和抽象类的共同点
实例化:接口和抽象类都不能直接实例化,只能被实现(接口)或继承(抽象类)后才能创建具体的对象。 抽象方法:接口和抽象类都可以包含抽象方法。抽象方法没有方法体,必须在子类或实现类中实现。
接口和抽象类的区别
设计目的:接口主要用于对类的行为进行约束,你实现了某个接口就具有了对应的行为。抽象类主要用于代码复用,强调的是所属关系。
继承和实现:一个类只能继承一个类(包括抽象类),因为 Java 不支持多继承。但一个类可以实现多个接口,一个接口也可以继承多个其他接口。
成员变量:接口中的成员变量只能是 public static final
类型的,不能被修改且必须有初始值。抽象类的成员变量可以有任何修饰符(private
, protected
, public
),可以在子类中被重新定义或赋值。
方法:Java 8 之前,接口中的方法默认是 public abstract
,也就是只能有方法声明。自 Java 8 起,可以在接口中定义 default
(默认) 方法和 static
(静态)方法。 自 Java 9 起,接口可以包含 private
方法。抽象类可以包含抽象方法和非抽象方法。抽象方法没有方法体,必须在子类中实现。非抽象方法有具体实现,可以直接在抽象类中使用或在子类中重写。
静态(static)方法与实例方法的区别
静态方法可以通过类名.方法名
和对象.方法名
进行调用,实例方法只可以通过对象.方法名
进行调用
静态方法在访问本类的成员时,只允许访问静态成员变量和静态方法,不允许访问实例成员变量和实例方法,而实例方法不存在这个限制。
二、关键字
(1)访问控制类关键字
private: 私用模式,访问控制修饰符,可以应用于类、方法或在类中声明的变量;表示只能访问本类中的方法或成员
protected:保护模式,可以应用于类、方法或在类中声明的变量的访问控制修饰符;表示只能访问本类中的方法或成员+同一个包下的其他类中的方法或成员
public:共用模式,可以应用于类、方法或字段在类中声明的变量的访问控制修饰符。表示能访问任意包任意类的方法或成员
(2)修饰符类关键字
abstract:表明类或者成员方法具有抽象属性,用于修改类或方法;
class: 声明一个类,用来声明新的Java类;
extends:表明一个类型是另一个类型的子类型,表示继承关系;对于类,可以是另一个类或者抽象类;对于接口,可以是另一个接口;
final:用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量;
implements:表明一个类实现了给定的接口;
interface:接口;
native:用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的;
new:用来创建新实例对象;
static:表明具有静态属性;
strictfp:用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范;
synchronized:表明一段代码需要同步执行;
transient:声明不用序列化的成员域;
volatile: Java提供的一种轻量级的同步机制
(3)程序控制类关键字
break:提前跳出一个块;
continue:回到一个块的开始处;
return:从成员方法中返回数据;
do:用在do-while循环结构中;
while:用在循环结构中;
if:条件语句的引导词;
else:用在条件语句中,表明当条件不成立时的分支;
for:一种循环结构的引导词;
instanceof:用来测试一个对象是否是指定类型的实例对象;
switch:分支语句结构的引导词;
case:用在switch语句之中,表示其中的一个分支;
default:默认,例如:用在switch语句中,表明一个默认的分支Java8 中也作用于声明接口函数的默认实现。
(4)错误处理类关键字
try:尝试一个可能抛出异常的程序块;
catch:用在异常处理中,用来捕捉异常;
throw:抛出一个异常;
throws:声明在当前定义的成员方法中所有需要抛出的异常。
(5)包相关的关键字
import:表明要访问指定的类或包;
package:包。
(6)基本数据类型关键字
boolean:基本数据类型之一,声明布尔类型的关键字;
byte:基本数据类型之一,字节类型;
char:基本数据类型之一,字符类型;
double:基本数据类型之一,双精度浮点数类型;
float:基本数据类型之一,单精度浮点数类型;
int:基本数据类型之一,整数类型;
long:基本数据类型之一,长整数类型;
short:基本数据类型之一,短整数类型;
null:空,表示无值,不能将null赋给原始类型(byte、short、int、long、char、float、double、boolean)变量;
true:真,boolean变量的两个合法值中的一个;
false:假,boolean变量的两个合法值之一。
(7)变量引用类关键字
super:表明当前对象的父类型的引用或者父类型的构造方法;
this:指向当前实例对象的引用,用于引用当前实例;
void:声明当前成员方法没有返回值,void可以用作方法的返回类型,以指示该方法不返回值。
(8)保留字
保留字是什么?:保留字是在编程语言中由语法规定为特定用途而被预留的单词或标识符。简单来说目前还没有具体用法,但随着语言的发展之后可能会有特点用途。保留字同样不可以作为变量名,类名
goto:保留关键字
Const:保留关键字
三、核心类库
- String类
String
、StringBuilder
、StringBuffer
区别- 字符串常量池(String Pool)
- Object类
toString()
、equals()
、clone()
方法- 深拷贝与浅拷贝
- 集合框架(Collection Framework)
- List(ArrayList vs LinkedList)
- Set(HashSet vs TreeSet)
- Map(HashMap、LinkedHashMap、ConcurrentHashMap)
Comparable
与Comparator
接口
- IO/NIO
- 字节流(InputStream/OutputStream)
- 字符流(Reader/Writer)
- NIO的Buffer、Channel、Selector
四、多线程与并发
- 线程基础
- 创建线程的方式(继承Thread、实现Runnable、Callable)
- 线程生命周期(新建、就绪、运行、阻塞、死亡)
- 线程同步
synchronized
关键字ReentrantLock
与ReadWriteLock
- 死锁的产生与避免
- 并发工具类
volatile
关键字(可见性、禁止指令重排)ThreadLocal
的作用与内存泄漏问题- 线程池(ThreadPoolExecutor)
- 原子类(AtomicInteger、CAS原理)
- JUC包(java.util.concurrent)
CountDownLatch
、CyclicBarrier
、Semaphore
ConcurrentHashMap
实现原理
五、JVM与内存管理
- 内存区域
- 堆(Heap)与栈(Stack)
- 方法区(元空间)、程序计数器、本地方法栈
- 垃圾回收(GC)
- 分代回收(Young/Old Generation)
- GC算法(标记-清除、复制、标记-整理)
- 常见GC器(Serial、Parallel、CMS、G1、ZGC)
- 类加载机制
- 类加载过程(加载、验证、准备、解析、初始化)
- 双亲委派模型
- 打破双亲委派(Tomcat类加载机制)
六、设计模式
一、什么是设计模式
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因
二、设计模式的六大原则
1、开闭原则(Open Close Principle)
开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2、里氏代换原则(Liskov Substitution Principle)
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科
3、依赖倒转原则(Dependence Inversion Principle)
这个是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。
5、迪米特法则(最少知道原则)(Demeter Principle)
为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
6、合成复用原则(Composite Reuse Principle)
原则是尽量使用合成/聚合的方式,而不是使用继承。
三、设计模式的三大类
总体来说设计模式分为三大类:
创建型模式(5种):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式(7种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
七、新特性(Java 8+)
- Lambda表达式
- 函数式接口(
@FunctionalInterface
)
- 函数式接口(
- Stream API
- 集合的流式操作(filter、map、reduce)
- Optional类
- 避免空指针异常
- 模块化系统(Java 9)
module-info.java
文件
- 记录类(Record,Java 14+)
- 简化不可变类的定义
高频面试题示例
HashMap
的工作原理及扩容机制?synchronized
和ReentrantLock
的区别?- JVM内存模型中堆和栈的区别?
- 如何实现线程安全的单例模式?
- Java中的强引用、软引用、弱引用、虚引用?
通过以上模块和知识点,可以系统性地覆盖Java基础面试的核心内容。如果需要更具体的题目或深入某个知识点,可以进一步细化!