2024年5月面试知识点梳理
- 资料来源
- Java基础
- 泛型
- 基本概念
- 常见问题
- 字符串
- 注解
- 异常
- 反射
- SPI机制
- Java集合
- Collection
- Map
- 并发基础
- 基础理论
- 线程
- Java 中的锁
- 乐观锁与悲观锁
- 自旋锁与非自旋锁
- 公平锁与非公平锁
- 并发关键字 - synchronized
- 并发集合
- Lock核心类
- 并发集合核心类
- 原子类核心类
- 线程池核心类
- ScheduledThreadPoolExecutor
- ForkJoinPool
- FokJoinTask
- JUC原子类: CAS, Unsafe和原子类详解
- JUC 工具类
- Java IO
- 字节流
- 字符流
- Java 7 特性
- Java 8 特性
- 开发框架
- Spring
- Spring Boot
- Mybatis
- Tomcat
- 虚拟机
- MySQL
- MySQL基础
- MySQL主从复制
- 集群
- Redis
- [小林Coding的Redis](<https://xiaolincoding.com/redis/ >)
- 主从复制是怎么实现的
- 哨兵模式
- Redis集群
- Zookeeper
- 常用排序算法
- 大数据处理算法
- 何谓海量数据处理? 解决的思路?
- 大数据处理之分治思想?
- 加密算法
- 架构相关
- 缓存
- 限流
- 降级和熔断
- 负载均衡
- 灾备和故障转移
- 开发工具
- Git
- Maven
- 分布式
- 一致性算法
- 全局唯一ID
- 分布式锁
- 分布式事务
- 分布式缓存
- 分布式任务
- 分布式会话
- 常见系统设计
- [网络](<https://xiaolincoding.com/network/ >)
- 其他
- 设计模式
- 软件理论
本文是本次N+1后,开始找工作的面试准备,进行的一些常见的知识点的梳理,尽量全面,尽量争取拿到大厂Offer,持续更新…
资料来源
- Java 全栈知识体系
- Hello算法
- 小林Coding
Java基础
-
面向对象
- 封装
- 存在继承的情况下,初始化顺序为:
- 父类(静态变量、静态语句块)
- 子类(静态变量、静态语句块)
- 父类(实例变量、普通语句块)
- 父类(构造函数)
- 子类(实例变量、普通语句块)
- 子类(构造函数)
- 存在继承的情况下,初始化顺序为:
- 继承
- 多态
- 类图:泛化关系、实现关系、聚合关系、组合关系、关联关系、依赖关系
-
快速记忆1:凡(泛化)是(实现)狙(聚合)击组(组合),都可以(依赖)来参观(关联)
-
快速记忆2:可以分三组记忆(依赖关联 - 箭头、聚合组合 - 菱形、继承实现 - 三角形)
关系 耦合度 记忆 依赖 最小 箭头 + 虚线 关联 较小 箭头 + 实线 聚合 适中 菱形(空心)+实线 组合 较大 菱形(实心)+实线 实现 大 空三角形 + 虚线 继承(泛化) 最大 空三角形 + 实线
-
- 封装
-
注解、泛型、集合、多线程、熟悉线程同步、阻塞队列、并发工具类、线程池
泛型
Java 基础 - 泛型机制详解
基本概念
- 泛型类
- 泛型接口
- 泛型方法
- 泛型的上下限
- 泛型数组
常见问题
- 如何理解Java中的泛型是伪泛型?
- 泛型中类型擦除如何证明类型的擦除呢?
- 如何理解类型擦除后保留的原始类型?
- 如何理解泛型的编译期检查?
- 如何理解泛型的多态?
- 泛型的桥接方法如何理解基本类型不能作为泛型类型?
- 如何理解泛型类型不能实例化?
- 泛型数组:能不能采用具体的泛型类型进行初始化?
- 泛型数组:如何正确的初始化泛型数组实例?
- 如何理解泛型类中的静态方法和静态变量?
- 如何理解异常中使用泛型?
- 如何获取泛型的参数类型?
字符串
- java 基础 - String
- 字符串常量池
注解
Java 基础 - 注解机制详解
- 注解基础
- Java内置注解
- 内置注解 - @Override
- 内置注解 - @Deprecated
- 内置注解 - @SuppressWarnings
- 元注解
- 元注解 - @Target
- 元注解 - @Retention & @RetentionTarget
- 元注解 - @Documented
- 元注解 - @Inherited
- 元注解 - @Repeatable (Java8)
- 元注解 - @Native (Java8)
- 注解与反射接口
- 自定义注解
- Java内置注解
- 深入理解注解
- Java8提供了哪些新的注解?
- 注解支持继承吗?
- 注解实现的原理?
- 注解的应用场景
- 配置化到注解化 - 框架的演进
- 继承实现到注解实现 - Junit3到Junit4
- 自定义注解和AOP - 通过切面实现解耦
异常
分类、使用心得、Java 7 的 try-with-resource(AutoCloseable)、异常的底层(Exception Table)
- 异常的层次结构
- Throwable
- Error(错误)
- Exception(异常)
- 可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)
- 异常基础
- 异常关键字
- 异常的申明(throws)
- 异常的抛出(throw)
- 异常的自定义
- 异常的捕获
- try-catch
- try-catch-finally
- try-finally
- try-with-resource
- 异常基础总结
- 常用的异常
- 异常实践
- 只针对不正常的情况才使用异常
- 在 finally 块中清理资源或者使用 try-with-resource 语句
- 尽量使用标准的异常
- 对异常进行文档说明
- 优先捕获最具体的异常
- 不要捕获 Throwable 类
- 不要忽略异常
- 不要记录并抛出异常
- 包装异常时不要抛弃原始的异常
- 不要使用异常控制程序的流程
- 不要在finally块中使用return。
- 深入理解异常
- JVM处理异常的机制?
- 异常是否耗时?为什么会耗时?
Java 基础 - 异常机制详解
反射
Java 基础 - 反射机制详解
每个类都有一个 Class 对象,包含了与类有关的信息。
当编译一个新类时,会产生一个同名的 .class 文件,该文件内容保存着 Class 对象。
类加载相当于 Class 对象的加载。
类在第一次使用时才动态加载到 JVM 中,可以使用 Class.forName(“com.mysql.jdbc.Driver”) 这种方式来控制类的加载,该方法会返回一个 Class 对象。
反射可以提供运行时的类信息,并且这个类可以在运行时才加载进来,甚至在编译时期该类的 .class 不存在也可以加载进来。
Class 和 java.lang.reflect 一起对反射提供了支持,java.lang.reflect 类库主要包含了以下三个类:
- Field : 可以使用 get() 和 set() 方法读取和修改 Field 对象关联的字段;
- Method : 可以使用 invoke() 方法调用与 Method 对象关联的方法;
- Constructor : 可以用 Constructor 创建新的对象。
SPI机制
Java常用机制 - SPI机制详解
- 什么是SPI机制
- SPI机制的简单示例
- SPI机制的广泛应用
- SPI机制 - JDBC DriverManager
- JDBC接口定义
- mysql实现
- postgresql实现
- 使用方法
- 源码实现
- SPI机制 - Common-Logging
- SPI机制 - 插件体系
- SPI机制 - Spring中SPI机制
- SPI机制 - JDBC DriverManager
- SPI机制深入理解
- SPI机制通常怎么使用
- 定义标准
- 具体厂商或者框架开发者实现
- 程序猿使用
- 使用规范
- SPI和API的区别是什么
- SPI机制实现原理
- SPI机制的缺陷
- SPI机制通常怎么使用
Java集合
Collection 和 Map 两种
Collection
Set(HashSet/TreeSet/LinkedHashSet)、List(ArrayList/Vector/LinkedList)、Queue(LinkedList/PriorityQueue)、Stack & Queue - ArrayDeque
Map
TreeMap/HashMap/HashTable/LinkedHashMap
并发基础
基础理论
Java 并发 - 理论基础
- 带着BAT大厂的面试问题去理解
- 为什么需要多线程
- 线程不安全示例
- 并发出现问题的根源: 并发三要素
- 可见性: CPU缓存引起
- 原子性: 分时复用引起
- 有序性: 重排序引起
- JAVA是怎么解决并发问题的: JMM(Java内存模型)
- 关键字: volatile、synchronized 和 final
- Happens-Before 规则
-
- 单一线程原则
-
- 管程锁定规则
-
- volatile 变量规则
-
- 线程启动规则
-
- 线程加入规则
-
- 线程中断规则
-
- 对象终结规则
-
- 传递性
-
- 线程安全: 不是一个非真即假的命题
-
- 不可变
-
- 绝对线程安全
-
- 相对线程安全
-
- 线程兼容
-
- 线程对立
-
- 线程安全的实现方法
-
- 互斥同步
-
- 非阻塞同步
-
- 无同步方案
-
线程
Java 并发 - 线程基础
解决了什么问题、创建、状态流转、中断方式、协作方式
- 线程状态转换
- 新建(New)
- 可运行(Runnable)
- 阻塞(Blocking)
- 无限期等待(Waiting)
- 限期等待(Timed Waiting)
- 死亡(Terminated)
- 线程使用方式
- 实现 Runnable 接口
- 实现 Callable 接口
- 继承 Thread 类
- 实现接口 VS 继承 Thread
- 基础线程机制
- Executor
- Daemon
- sleep()
- yield()
- 线程中断
- InterruptedException
- interrupted()
- Executor 的中断操作
- 线程互斥同步
- synchronized
- ReentrantLock
- 比较
- 使用选择
- 线程之间的协作
- join()
- wait() notify() notifyAll()
- await() signal() signalAll()
Java 中的锁
Java并发 - Java中所有的锁
乐观锁与悲观锁
自旋锁与非自旋锁
公平锁与非公平锁
- 公平锁
- 非公平锁
并发关键字 - synchronized
关键字: synchronized详解
- 带着BAT大厂的面试问题去理解Synchronized
- Synchronized可以作用在哪里? 分别通过对象锁和类锁进行举例。
- Synchronized本质上是通过什么保证线程安全的? 分三个方面回答:加锁和释放锁的原理,可重入原理,保证可见性原理。
- Synchronized由什么样的缺陷? Java Lock是怎么弥补这些缺陷的。
- Synchronized和Lock的对比,和选择?
- Synchronized在使用时有何注意事项?
- Synchronized修饰的方法在抛出异常时,会释放锁吗?
- 多个线程等待同一个Synchronized锁的时候,JVM如何选择下一个获取锁的线程?
- Synchronized使得同时只有一个线程可以执行,性能比较差,有什么提升的方法?
- 我想更加灵活的控制锁的释放和获取(现在释放锁和获取锁的时机都被规定死了),怎么办?
- 什么是锁的升级和降级? 什么是JVM里的偏斜锁、轻量级锁、重量级锁?
- 不同的JDK中对Synchronized有何优化?
- Synchronized的使用
- 对象锁
- 代码块形式:手动指定锁定对象,也可是是this,也可以是自定义的锁
- 方法锁形式:synchronized修饰普通方法,锁对象默认为this
- 类锁s
- ynchronize修饰静态方法
- synchronized指定锁对象为Class对象
- 对象锁
- Synchronized原理分析
- 加锁和释放锁的原理
- 可重入原理:加锁次数计数器
- 保证可见性的原理:内存模型和happens-before规则
- JVM中锁的优化
- 锁的类型
- 自旋锁与自适应自旋锁
- 自旋锁
- 自适应自旋锁
- 锁消除
- 锁粗化
- 轻量级锁
- 轻量级锁加锁
- 偏向锁
- 偏向锁的撤销
- 锁的优缺点对比
- Synchronized与Lock
- synchronized的缺陷
- Lock解决相应问题
- 再深入理解
synchronized(对象,对象监视器,同步队列以及执行线程状态之间的关系、缺点)/final/volatile(如何实现可见性)
并发集合
Lock核心类
并发集合核心类
原子类核心类
-
原子更新基本类型
-
AtomicBoolean: 原子更新布尔类型。
-
AtomicInteger: 原子更新整型。
-
AtomicLong: 原子更新长整型。
-
-
原子更新数组
-
AtomicIntegerArray: 原子更新整型数组里的元素。
-
AtomicLongArray: 原子更新长整型数组里的元素。
-
AtomicReferenceArray: 原子更新引用类型数组里的元素。
-
-
原子更新引用类型
-
AtomicIntegerFieldUpdater: 原子更新整型的字段的更新器。
-
AtomicLongFieldUpdater: 原子更新长整型字段的更新器。
-
AtomicStampedFieldUpdater: 原子更新带有版本号的引用类型。
-
AtomicReferenceFieldUpdater: 上面已经说过此处不在赘述
-
-
原子更新字段类
-
AtomicReference: 原子更新引用类型。
-
AtomicStampedReference: 原子更新引用类型, 内部使用Pair来存储元素值及其版本号。
-
AtomicMarkableReferce: 原子更新带有标记位的引用类型。
-
线程池核心类
ScheduledThreadPoolExecutor
ForkJoinPool
FokJoinTask
工作窃取
JUC原子类: CAS, Unsafe和原子类详解
JUC 工具类
CountDownLatch、CyclicBarrier、Semaphore、Phaser、Exchanger
Java IO
字节流
字符流
Java 7 特性
Strings in Switch StatementType
Inference for Generic Instance Creation
Multiple Exception Handling
Support for Dynamic Languages
Try with Resources
Java nio Package
Binary Literals, Underscore in literals
Diamond Syntax
Java 8 特性
Optional
Lambda Expressions
Pipelines and Streams
Date and Time API
Default MethodsType Annotations
Nashhorn JavaScript Engine
Concurrent Accumulators
Parallel operations
PermGen Error Removed
开发框架
Spring
- AOP 有哪些应用场景?
- 有哪些AOP Advice通知的类型?
- AOP 有哪些实现方式?
- 谈谈你对CGLib的理解?
- Spring AOP和AspectJ AOP有什么区别?
- Spring中的bean生命周期?
- 说说自己对于Spring MVC的了解?
- Spring MVC的工作原理了解嘛?
- Spring框架中用到了哪些设计模式?
- @Component和@Bean的区别是什么?
- 将一个类声明为Spring的bean的注解有哪些?
- Spring事务管理的方式有几种?
- Spring事务中的隔离级别有哪几种?
- Spring事务中有哪几种事务传播行为?
- Bean Factory和ApplicationContext有什么区别?
- 如何定义bean的范围?
- 可以通过多少种方式完成依赖注入?
Spring Boot
- 什么是SpringBoot?
- 为什么使用SpringBoot?
- SpringBoot自动配置的原理?
- Spring Boot的核心注解是哪些?他主由哪几个注解组成的?
- SpringBoot的核心配置文件有哪几个?他们的区别是什么?
- 什么是Spring Boot Starter?有哪些常用的?
- spring-boot-starter-parent有什么作用?
- 如何自定义Spring Boot Starter?
- 为什么需要spring-boot-maven-plugin?
- SpringBoot 打成jar和普通的jar有什么区别?
- 如何使用Spring Boot实现异常处理?
- SpringBoot 实现热部署有哪几种方式?
- Spring Boot中的监视器是什么?
- Spring Boot 可以兼容老 Spring 项目吗?
Mybatis
- 什么是日志系统和日志门面?分别有哪些框架?
- 日志库中使用桥接模式解决什么问题?
- 在日志配置时会考虑哪些点?
- 对Java日志组件选型的建议?
- 对日志架构使用比较好的实践?
- 对现有系统日志架构的改造建议?
Tomcat
- Tomcat 整体架构的设计?
- Tomcat 一个请求的处理流程?
- Tomcat 中类加载机制?
- Tomcat Container设计?
- Tomcat LifeCycle机制?
- Tomcat 中Executor?
- Tomcat 中的设计模式?
虚拟机
熟悉JVM内存模型,内存结构、垃圾回收机制;了解CMS/G1垃圾回收器基本原理等
MySQL
MySQL基础
答案链接
- 基础篇👇
- 执行一条 SQL 查询语句,期间发生了什么?
- MySQL 一行记录是怎么存储的?
- 索引篇 👇
- 索引常见面试题
- 从数据页的角度看 B+ 树
- 为什么 MySQL 采用 B+ 树作为索引?
- MySQL 单表不要超过 2000W 行,靠谱吗?
- 索引失效有哪些?
- MySQL 使用 like “%x“,索引一定会失效吗?
- count(*) 和 count(1) 有什么区别?哪个性能最好?
- 事务篇 👇
- 事务隔离级别是怎么实现的?
- MySQL 可重复读隔离级别,完全解决幻读了吗?
- 锁篇 👇
- MySQL 有哪些锁?
- MySQL 是怎么加锁的?
- update 没加索引会锁全表?
- MySQL 记录锁+间隙锁可以防止删除操作而导致的幻读吗?
- MySQL 死锁了,怎么办?
- 字节面试:加了什么锁,导致死锁的?
- 日志篇 👇
- undo log、redo log、binlog 有什么用?
- 内存篇 👇
- 揭开 Buffer_Pool 的面纱
MySQL主从复制
答案链接
- 原理和SQL
- 什么是事务?
- 事务基本特性ACID?
- 数据库中并发一致性问题?
- 事务的隔离等级?
- ACID靠什么保证的呢?
- SQL 优化的实践经验?
- Buffer Pool、Redo Log Buffer 和undo log、redo log、bin log 概念以及关系?
- 从准备更新一条数据到事务的提交的流程描述?
- MySQL
- 能说下myisam 和 innodb的区别吗?
- 说下MySQL的索引有哪些吧?
- 什么是B+树?
- 为什么B+树成为主要的SQL数据库的索引实现?
- 那你知道什么是覆盖索引和回表吗?
- 什么是MVCC?
- 说说MySQL实现MVCC的原理?
- MySQL 锁的类型有哪些呢?
- 你们数据量级多大?分库分表怎么做的?
- 那分表后的ID怎么保证唯一性的呢?
- 分表后非sharding_key的查询怎么处理呢?
- MySQL主从复制?
- MySQL主从的延迟怎么解决呢?
- MySQL读写分离方案?
集群
Redis
小林Coding的Redis
主从复制是怎么实现的
第一次同步 -> 命令传播
分摊主服务器的压力
增量复制
常见面试题
- Redis主从节点时长连接还是短连接
- 怎么判断 Redis 某个节点是否正常工作?
- 主从复制架构中,过期key如何处理?
- Redis 是同步复制还是异步复制?
- 主从复制中两个 Buffer(replication buffer 、repl backlog buffer)有什么区别?
- 如何应对主从数据不一致?
- 主从切换如何减少数据丢失?
- 主从如何做到故障自动切换?
哨兵模式
Redis集群
Redis数据结构(快表、跳表)、Redis哨兵模式、Raft选举、主从复制原理、利用watch实现分布式锁、Redis watch功能?
Redis Stream
Zookeeper
数据结构、数据同步流程、以及选举机制,熟悉数据发布-订阅、分布式锁等使用场景;
常用排序算法
大数据处理算法
何谓海量数据处理? 解决的思路?
所谓海量数据处理,无非就是基于海量数据上的存储、处理、操作。何谓海量,就是数据量太大,所以导致要么是无法在较短时间内迅速解决,要么是数据太大,导致无法一次性装入内存。那解决办法呢?
- 针对时间: 我们可以采用巧妙的算法搭配合适的数据结构,如Bloom filter/Hash/bit-map/堆/数据库或倒排索引/trie树;
- 针对空间: 无非就一个办法: 大而化小,分而治之(hash映射);
- 集群|分布式: 通俗点来讲,单机就是处理装载数据的机器有限(只要考虑cpu,内存,硬盘的数据交互); 而集群适合分布式处理,并行计算(更多考虑节点和节点间的数据交互)。
大数据处理之分治思想?
分而治之/hash映射 + hash统计 + 堆/快速/归并排序,说白了,就是先映射,而后统计,最后排序:
- 分而治之/hash映射: 针对数据太大,内存受限,只能是: 把大文件化成(取模映射)小文件,即16字方针: 大而化小,各个击破,缩小规模,逐个解决。
- hash_map统计: 当大文件转化了小文件,那么我们便可以采用常规的hash_map(ip,value)来进行频率统计。
- 堆/快速排序: 统计完了之后,便进行排序(可采取堆排序),得到次数最多的IP。
加密算法
架构相关
缓存
- 使用缓存的经验?
不合理使用缓存非但不能提高系统的性能,还会成为系统的累赘,甚至风险。 12-2-缓存
限流
- 什么是限流?三种限流的算法?
- 限流令牌桶和漏桶对比?
- 在单机情况下如何实现限流?
- 在分布式环境下如何实现限流?
降级和熔断
- 为什么会有容错?一般有哪些方式解决容错相关问题?
- 谈谈你对服务降级的理解?
- 什么是服务熔断?和服务降级有什么区别?
- 如何设计服务的熔断?
- 服务熔断有哪些实现方案?
负载均衡
- 什么是负载均衡?原理是什么?
- 负载均衡有哪些分类?
- 常见的负载均衡的算法?
灾备和故障转移
- 什么是容灾?一般基于什么实现?
- 一般怎么实现灾备?
开发工具
Git
Maven
- Maven中包的依赖原则?如何解决冲突?
分布式
一致性算法
- 什么是分布式系统的副本一致性?有哪些?
- 在分布式系统中有哪些常见的一致性算法?
- 谈谈你对一致性hash算法的理解?
- 什么是Paxos算法? 如何实现的?
- 什么是Raft算法?
全局唯一ID
- 全局唯一ID有哪些实现方案?
- 数据库方式实现方案?有什么缺陷?
- 雪花算法如何实现的?
- 雪花算法有什么问题?有哪些解决思路?
分布式锁
- 有哪些方案实现分布式锁?
- 基于数据库如何实现分布式锁?有什么缺陷?
- 基于redis如何实现分布式锁?有什么缺陷?
- 基于zookeeper如何实现分布式锁?
分布式事务
- 什么是ACID?
- 分布式事务有哪些解决方案?
- 什么是分布式的XA协议?
- 什么是2PC?
- 什么是3PC?
- 什么是TCC?
- 什么是SAGA方案?
- ZAB
分布式缓存
- 分布式系统中常用的缓存方案有哪些?
- 分布式系统缓存的更新模式?
- 分布式系统缓存淘汰策略
分布式任务
- Java中定时任务是有些?如何演化的?
- 常见的JOB实现方案?
分布式会话
- Cookie和Session有什么区别?
- 谈谈会话技术的发展?
- 分布式会话有哪些解决方案?
- 什么是Session Stick?
- 什么是Session Replication?
- 什么是Session 数据集中存储?
- 什么是Cookie Based Session?
- 什么是JWT?使用JWT的流程?对比传统的会话有啥区别?
常见系统设计
- 如何设计一个秒杀系统?
- 接口设计要考虑哪些方面?
- 什么是接口幂等?如何保证接口的幂等性?
网络
- SYN洪泛攻击(SYN Flood,半开放攻击),怎么解决?
- DNS 解析流程?
- 为什么DNS通常基于UDP?
- 什么是DNS劫持?
- 什么是DNS污染?
- 为什么要DNS流量监控?
- 输入URL 到页面加载过程?
- 如何使用TCPDump抓包?
- 如何使用Wireshark抓包分析?
其他
设计模式
软件理论
- 什么是CAP理论?
- 什么是BASE理论?
- 什么是SOLID原则?
- 什么是合成/聚合复用原则?
- 什么是迪米特法则?
- 什么是康威定律?
、算法、项目、MQ、分库分表、Flink、MongoDB、ClickHouse、DDD、Faiss