Java 面试核心知识点总结:Spring、MySQL、并发编程等
Java 后端开发面试的高频考点,涵盖微服务架构(Spring Cloud、Dubbo)、数据库优化(MySQL 索引、MVCC、分库分表)、并发编程(线程池、锁机制、JUC)、Spring 框架(IOC、AOP、事务)、以及 JVM 和 Linux 基础。内容包含设计模式、代码规范、分布式锁原理及常见面试题解答,旨在帮助开发者系统复习技术栈并提升面试通过率。

Java 后端开发面试的高频考点,涵盖微服务架构(Spring Cloud、Dubbo)、数据库优化(MySQL 索引、MVCC、分库分表)、并发编程(线程池、锁机制、JUC)、Spring 框架(IOC、AOP、事务)、以及 JVM 和 Linux 基础。内容包含设计模式、代码规范、分布式锁原理及常见面试题解答,旨在帮助开发者系统复习技术栈并提升面试通过率。

简单一点,把自己的情况说清楚,一两分钟即可。
答:微服务是把一个类似单体项目根据某种维度进行拆分,比如根据功能模块进行拆分。拆分之后,具备了更好的抗压性/扩展性,还可以更好的解耦,但是维护相比之前会更麻烦了。 常用的组件有 Spring Cloud。其中里面有:
答:本项目中是用作削峰和解耦。
答:索引。
答: (1)来源不一样:@Autowired 是 Spring 定义的注解,而 @Resource 是 Java 定义的注解。 (2)依赖查找的顺序不同:依赖注入的功能,是通过先在 Spring IoC 容器中查找对象,再将对象注入引入到当前类中。 @Autowired 是先根据类型(byType)查找,如果存在多个 Bean 再根据名称(byName)进行查找。 @Resource 是先根据名称查找,如果(根据名称)查找不到,再根据类型进行查找。 (3)支持的参数不同:@Autowired 和 @Resource 在使用时都可以设置参数,其中 @Autowired 只支持设置一个 required 的参数,而 @Resource 支持 7 个参数。 (4)依赖注入的用法不同:@Autowired 支持属性注入、构造方法注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入。 (5)编译器 IDEA 的提示不同:@Autowired 编译器会提示报错信息。
答:单例模式、适配器模式、工厂模式、代理模式。
答: 单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。 应用场景:对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。
答: (1)简单工厂模式:建立一个工厂类,对实现了同一接口的一些类进行实例的创建。优点是比较好理解,简单易操作。缺点是类的创建依赖工厂类,如果想要拓展程序,必须对工厂类进行修改。 (2)工厂方法模式:对简单工厂模式的改进,使用一个工厂接口,创建多个工厂类,每个工厂创建对应的对象。创建一个工厂接口和创建多个工厂实现类,一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。有利于代码的维护和扩展。 (3)抽象工厂模式:MyBatis 中使用的比较多,事务模块和数据源模块都使用了工厂方法模式。
答: (1)代码规范:命名、格式、内容、位置(包结构)。 (2)耦合、性能、内存。
答:ALTER TABLE ry-cloud.sys_user_role CHANGE role_id role_id1 bigint(20) NOT NULL COMMENT '角色 ID';
(1)change 可以更改列名 和 列类型 (每次都要把新列名和旧列名写上,即使两个列名没有更改,只是改了类型)。
(2)modify 只能更改列属性 只需要写一次列名,比 change 省事点。
答:是数据库的多版本并发控制,在读取数据不用加锁也可以提高读取效率和并发性的手段。 实现原理:一种读取操作,使用数据在某个时间点的快照显示查询结果,而不考虑同时运行的其他事务所执行的更改。 如果查询的数据已被另一个事务更改,则会根据 undo log 的内容重建原始数据。该技术避免了一些锁定问题,这些问题可以通过强制事务等待其他事务完成来减少并发性。 隐含字段:一个事务最新 id,回滚的指针。
答: (1)代码层面查两次。 (2)或者用 UNION 来代替。
答: (1)数据库视图:数据库一个或多个表导出的虚拟表,方便用户对数据进行操作。视图的数据依赖原数据,二者会互相影响。 (2)数据库序列化:是将数据结构或者对象转换成字节流、json 等方便去存储或者是传输。 (3)暂无详细回答。
答:关系型数据库容易成为系统瓶颈,链接数量,存储容量都是有限的,超过 1 千万之后因其查询维度的较多,性能会下降严重。 (1)垂直切分:分库:根据业务不同拆成不同库;分表:把不常用的字段或者长度比较大的字段拆到另一张表(主键跟着走)。缺点:只能在代码里面去聚合,增加了其复杂度。 (2)水平切分:库内分表、分库分表。将按照不同的条件分散到多个数据库或者多个表中,使单表数据量变小。缺点:维护难度加大、跨分片的事务不好保证。
答: (1)方法不是 public; (2)异常被方法吞掉了; (3)抛出异常类型大于@Transactional 默认回滚的是 RuntimeException 和 Error; (4)非同一个线程。
答:Lambda 表达式、Stream API、map 数据结构优化。
答:函数式接口 (Functional Interface) 就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。为 lambda 表达式和方法引用 (用冒号::来进行方法的调用) 提供目标类型。
答:面向切面的编程,通过预编译和运行期间动态代理实现程序功能统一的技术。实现 InvocationHandler 类则是 JDK 动态代理,否则是 CGLib 动态代理。
答: (1)主要是简化新 spring 应用的初始搭建和开发过程(使用 IntelliJ IDEA,可以利用创建 Spring Initializr 的方式创建 Spring Boot 项目、使用官方文档创建项目,在 Spring 官方文档上面提供了一种在线生成 Spring Boot 项目的方式、使用 Spring Tool Suite,可以直接新建 Spring Starter Project 项目)。 (2)嵌入式 Web 容器、自动化配置、可执行 Jar 部署。
答:Nacos 或者阿波罗都可以。
答:是一种软件设计规范,将业务逻辑、数据、显示分离的方法来组织代码,降低了视图和业务逻辑之间的耦合。 浏览器把请求放到试图层=控制器收到请求模型处理数据=返回视图=响应给浏览器。
答:HashMap、TreeMap。
答:串行:Stream,并行:parallelStream(其底层使用 Fork/Join 框架实现,通过 Fork 把任务拆开,Join 把结果进行合并)。
答:spring.profiles.active====》VM options 两处改动。
答: (1)值传递 (pass by value):在调用函数时,将实际参数复制一份传递到函数中,这样在函数中对参数进行修改,就不会影响到原来的实际参数; (2)引用传递 (pass by reference):在调用函数时,将实际参数的地址直接传递到函数中。这样在函数中对参数进行的修改,就会影响到实际参数; 个人认为:在一个类中调用其他方法,这个方法中如果是直接复制对象则是值传递,如果是在参数基础上改则是引用传递。
答: (1)可以动态的加载类,并创建其实例。String className = "com.example.MyClass"; Class<?> clazz = Class.forName(className); Object obj = clazz.newInstance(); (2)通过反射,我们可以在运行时动态地获取类的信息。这样就可以获取类的构造方法、字段、方法等信息,并进行相应的操作。
答: (1)不管 try 中是否出现异常,finally 块中的代码都会执行; (2)当 try 和 catch 中有 return 时,finally 依然会执行; (3)finally 中如果包含 return,那么程序将在这里返回,而不是 try 或 catch 中的 return 返回,返回值就不是 try 或 catch 中保存的返回值了。
答:会出现 Dubbo 报错 Data length too large;首先看这种大数据是不是符合双方约定的,如果是的话就去修改生产者 xml payload 参数,否则可以加一些限制。
答:throw 代表动作,表示抛出一个异常的动作;throws 代表一种状态,代表方法可能有异常抛出。 throw 用在方法实现中,而 throws 用在方法声明中; throw 只能用于抛出一种异常,而 throws 可以抛出多个异常。
答:在多进程环境里面,通过外部的工具来达到加锁功能。
答:是 Redisson 提供的自动延期机制,使得分布式锁可以自动延期,默认 30 秒。
答: (1)可能忘记了释放锁; (2)释放了别人的锁; (3)锁超时等问题。
答:Redisson、ZK、数据库。
答: (1)IO 密集型任务:2*核心数 +1 (2)CPU 密集型任务:核心数 +1 即使当计算(CPU)密集型的线程偶尔由于页缺失故障或者其他原因而暂停时,这个'额外'的线程也能确保 CPU 的时钟周期不会被浪费。
答: (1)401 Unauthorized:请求要求身份验证。客户端需要进行身份验证才能获取请求的内容。如果请求未包含有效的身份验证凭据,服务器可能返回此状态码。 (2)400 Bad Request:客户端发送的请求有错误。服务器不理解或无法处理客户端发送的请求。这可能是由于参数错误、缺少必要的信息或语法错误等引起的。 (3)403 Forbidden:服务器拒绝了客户端的请求。客户端没有访问请求的权限,无法获取请求的资源。 (4)404 Not Found:请求的资源不存在。服务器未能找到请求的资源。这可能是由于资源被删除或请求的 URL 错误等引起的。 (5)502 Bad Gateway:服务器作为网关或代理,从上游服务器接收到无效的响应。通常表示上游服务器发生了故障或响应超时。
答: (1)在默认安装位置下查看,大多数一般会安装在默认位置下(/usr/local/openresty/nginx 或/usr/local/nginx)。 (2)查看 nginx 进程(ps -aux|grep nginx)。 (3)nginx 运行进程,执行 ls -l /proc/进程号/exe ,然后会打印出安装/运行位置。
答:Docker 是一个开源的应用容器引擎,开发者可以把程序及其依赖项打包到一个可移值的镜像中,可以在任意的 Linux/Windows 系统上运行这些镜像。
答:两个或多个事务竞争资源导致互相等待称为死锁。
答:查看错误日志、使用命令:SHOW ENGINE INNODB STATUS。
答:手动解决:回滚其中一个事务;设置锁等待超时时间让其自动解除。
答: (1)避免大事务。 (2)合理设计索引减少表扫描。 (3)减少锁粒度。
答: (1)创建阶段:beforeCreate(进行数据侦听和事件/侦听器的配置之前同步调用),created(可以访问数据了)。 (2)挂载阶段:beforeMount(dom 马上被渲染),mounted(dom 被渲染出来了)。 (3)更新阶段:beforeUpdate(数据发送了变化,dom 还没更新),updated(数据更改导致 dom 被更改)。 (4)销毁阶段:beforeDestroy(实例销毁前的调用),destroyed(实例被销毁,vue 指令被解除)。
答:多次输入,只提交最后一次,主要思想就是定时器。
答:多次点击,只执行一次函数。
答:SpringBoot 主要解决了 Spring 传统重量级 xml 配置 bean。 启动类里面有@SpringBootApplication 注解,包含了@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan。 其中@SpringBootConfiguration 注解标记启动类为配置类。 @ComponentScan 注解会去扫描启动类所在包及子包下面所标记的 bean 类由 IOC 去注册为 bean。 @EnableAutoConfiguration 通过 @Import 注解导入 AutoConfigurationImportSelector 类,然后通过 AutoConfigurationImportSelector 类的 selectImports 方法去读取需要被自动装配的组件依赖下的 spring.factories 文件配置的组件的类全名,并按照一定的规则过滤掉不符合要求的组件的类全名,将剩余读取到的各个组件的类全名集合返回给 IOC 容器并将这些组件注册为 bean。
答:用来做动态服务发现、配置管理、服务管理平台。 优点:可以动态的添加、删除服务实例,无须重启服务或者改代码;可以提供不同环境、角色的配置;支持流量管理,可以进行控制、限流和熔断;易于操作的管理界面;社区活跃。
LinkedBlockingDeque:链表同步阻塞队列。 ArrayBlockingQueue:数组同步阻塞队列。 SynchronousQueue:同步阻塞队列。
答:静态方法获取 bean 实例,采用 Resource 和 Autowired 会导致空指针。 首先说说场景:我有一个工具类,这个工具类要去调数据库 mapper 做一些处理,静态方法里面要使用 mapper,这个 mapper 必须有 static。 分析原因:静态方法属于类本身,不依赖类的实例状态,无法直接访问。 解决办法:在某个类持有 ApplicationContext 引用,通过他的上下文获取。
答:采用拉链法:类似 hashmap 在数组内添加一个链表。
答:省略。
答:switch/case 使用跳转表来提高效率,如果 case 数量较多,性能优于 if/else。 if/else 是去遍历每个条件。 如果分支少且条件复杂,选择 if/else 更合适。
答:Kafka 为了提高并发性,生产者会把数据分发到多个分区,多个消费者可以组成一个消费组,一个分区数据只会被消费组的一个消费。 建议消费组中的消费者数量和分区 partition 保持一致。
答:分析是消费数量不够还是消费处理时间较长。
答:调用实际上是在当前类的实例内部发生的。因此,它不会触发 Spring AOP 代理的拦截,也就意味着不会触发事务管理器的拦截器。
答:冒泡排序就是对待排序的的序列从前往后两两比较,如果发现逆序则交换,最终得到从小到大的顺序。
答: (1)修改文件权限:chmod 644 test.php #只有拥有者可以修改,其他人只能看文件内容,chmod o+w test.php。 文件所有者可以用字母 u(user)表示。用户所在的组可以用字母 g(group)来表示。其他人可以用字母 o(other)来表示。所有人可以用字母 a(all)来表示。 (2)查看系统端口:netstat -ntlp//查看当前所有 tcp 端口·,查看一台服务器上面哪些服务及端口:netstat -lanp。
答:断言功能可以决定 http 请求应该由那个 Route 来做路由。就是我们 nacos 的 predicates 匹配规则。 过滤器类型: (1)网关过滤器(GatewayFilter):一般放在配置文件里面,比如 nacos(spring.cloud.routes.filters),作用在所有路由上面。 (2)全局过滤器(GlobalFilter):不用在配置文件中,比如全局日志过滤器,打印日志。
答:用于构建锁和同步器的基础框架,用于并发编程,基于 FIFO(First In, First Out)等待队列的阻塞锁和同步器。
答:mvn -v、mvn package(依据项目生成 jar 文件)、mvn install(在本地 Repository 中安装 jar)、mvn clean(清除目标目录中的生成结果)。
答: (1)Broker 是 Kafka 的实例。 (2)Topic 是消息的主题,可以理解为消息的分类,数据就保存在里面,每个 Broker 可以建立多个 Topic。 (3)Partition 是 Topic 的分区,分区的作用就是负载,提高 Kafka 的吞吐量。
答:八种基本数据类型:byte、short、int、long;float、double;char;boolean。 四种引用类型:数组、接口、类、(枚举、注解、字符串、)。
答:
答:
答:select * from user where name like concat('%',#{name},'%')。
答:实现 Interceptor。
答:lpush key value(将元素添加到列表左边),Rpush key value(将元素添加到列表右边)。
答:ConcurrentHashMap 在 jdk1.8 采用 CAS+synchronized 实现更加细粒度的锁。 锁的粒度指的是锁定共享资源的范围大小。 在 jdk1.7 锁粒度是每个段(Segment),1.8 是每个链表或红黑树的根节点。
答:指的就是 JVM 内存模型。
答:JUC 是 java.util.concurrent 包的简称。
答:MyBatis-Plus 实现批量插入:开启 insertBatchSomeColumn(); 自定义 sql 注入器,继承 DefaultSqlInjector。 将自定义 sql 注入器注册为 bean。 新建 mapper 继承 BaseMapper,配置 insertBatchSomeColumn() 方法。
答: (1)升级困难,每次升级变更较大。 (2)依赖大量第三方库,管理复杂且容易冲突。 (3)资源占用较多。
(1)使用@Value 注解。 (2)使用 Environment 接口。 (3)使用@ConfigurationProperties 注解。 (4)使用 PropertySource 注解。
答:采用 OpenCsv 来读取,设置一个每次读取的行数,如果集合 size 大于了这个行数,就去处理数据并清空集合。
答:使用 mock 机制:@Reference(mock = "return 666")。 配置熔断参数:配置超时时间和重试次数来,停止调用服务。
答:应用场景方面:mq 用于实时方面,可靠性要求比较高。 Kafka 用于活跃的流式数据,适合处理大数据量。 消费模型:
答:主要用于定义和使用用户变量。
答: (1)基本路由:只包含一个路由对象参数。 (2)命名路由:包含了多个路由参数。
答:key 的作用可以通过 diff 算法提高页面的渲染效率。
答:让小表作为驱动表效率更高,他的扫描 rows 会更少。
答:select name,count() from student s where grades >=60 group by name having count()>=3 ; 这里我限定三门了。
答:他是一种面向对象的设计方法,强调业务逻辑和领域模型置于软件设计中心。
首先就是把自己的项目讲清楚,特别是自己项目涉及的技术尽量把底层也弄懂,现在的面试占比可能项目占 70%,八股文也就 30%。如果有涉及笔试的话,建议多看看表结构设计,sql 要能手写出来比较好。还有就是自己的简历可以多优化一下,不要太简单了,多找厉害的朋友参考参考。 其次横向的学习挺重要,比如前端开发、Python 这种可以多学学。 对于社招感觉面比较窄,比如零售的行业你必须要有零售开发项目,制造业你可能得会 ERP 之类的。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online