粉丝1451获赞8479

刚面了一个三年经验的 java 后端,我问他,你项目用了分布式和微服务,那分布式到底是什么?和微服务有啥区别? cap 理论为啥不能三者同时满足? b a、 s、 e 理论核心是什么?他直接说,分布式就是多台服务器,微服务就是拆服务。 type 记不清,辈子不太了解。我再追问, java 里分布式和微服务的落地差异在哪儿? c p 里 p 为啥是 b 选项? b a s e? 怎么解决高病发数据一致性问题?他根本答不上来。好多 java 后端面试遇到这类架构题容易丢分怎么办?如果你也没把握,我整理了一套让大厂 hr 沉默的面试题库,包含 java 基础、 spring 全家桶、 myico radis、 微服务、分布式实战和 ai 代码落地面试题,只要是我粉丝,留三个六打包带走。这道题到底怎么答才能让面试官眼前一亮,直接认可你的专业度?今天我把完整思路拆解给你,这可是送分题。 java 后端架构题,答题核心要遵守,概念清晰、原理通透、贴合、实战落地可讲四大原则,目标是避开概念混淆、原理模糊、脱离业务的坑,展现你的架构认知深度。 一、什么是分布式?和微服务有什么区别?分布式是一种主流架构思想,将整套 java 业务系统拆分部署在多台独立服务器上,依靠 r、 p、 c、 h、 t p 等网络方式完成服务间通信协作,主要用来解决单机服务器病发压力不足、 融错率低、拓展性差等线上项目痛点,常见于大型电商业务复杂的后端项目。微服务则是分布式架构在 java 领域最主流的落地实现方式, 严格按照实际业务领域进行拆分,拆分为用户、订单、支付等独立服务,依靠 spring boot spring cloud 技术站开发,各个服务能够独立开发、独立部署、独立迭代,服务之间做到彻底结后。二者三大核心区别,架构层级不同 分布式属于宏观整体架构理念,微服务是分布式架构下精细化的实践方案。拆分方向不同,分布式偏向服务器部署层面拆分,微服务聚焦后端实际业务功能进行拆分。代码藕合,不同, 传统分布式架构存在仅藕合情况,而 java 微服务天生低藕合,方便团队协调开发与项目灰度发布。二、什么是 c a p? 为什么无法三者同时满足? c a p 是 分布式后端系统的核心基础,定力明确一致性、可用性、分区容错性三大特性在实际项目中最多只能满足两项, 无法三者同时兼备。 c 一 致性,集群内所有服务节点的数据保持实时同步,一旦数据发生修改,集群所有节点都能查询到最新数据。 a。 可用性,后端系统能够全天候正常接收并处理用户请求,稳定响应,不会出现宕机、请求超时等问题。 p 分 区容错性, 当集群出现网络中断、节点失联产生网络分区时,整套系统依旧可以维持正常运转。无法同时满足的核心原因,在真实线上 java 项目环境中,网络波动、网络故障无法彻底避免。 因此,分区容错性屁是所有分布式系统的必备条件。选择一致性加分区容错性,就要暂停业务请求,等待数据同步,直接牺牲系统可用性,选择可用性加分区容错性优先保障系统正常运行,只能暂时牺牲数据实时一致性。 如果强行选择一致性加可用性,舍弃分区容错性,一旦出现网络故障,整个分布式系统就会直接瘫痪失效。三、 b a s e 理论讲解 b a s e 理论是互联网高并发后端项目中针对 c、 a、 p 定律衍生出的最优折中设计思想,核心思路就是舍弃数据强一致性,优先保障系统高可用,最终实现数据一致性,也是电商、支付等高流量项目的核心设计思路。 b 基本可用,当系统出现故障,流量峰值过大时, 主动降级,关闭非核心业务功能,权力保障、订单、交易、支付等核心后端业务平稳运行。 s 软状态,允许分布式集群中的数据存在临时中间状态,短时间内无需强制做到数据完全同步统一 最终一致性。不要求数据实时一致,允许存在短暂延迟。我们在 java 项目中,可以通过消息队列、异步补偿、定时任务等方式,让所有节点数据在指定时间内完成同步,达成最终一致。最后划重点, java 后端面试官考这三题本质看你分布式架构认知、技术权衡能力、实战落地经验, 不是死记硬背,而是懂原理、会应用。最后问大家一句,你在 java 项目里用分布式和微服务时踩过最大的坑是什么?评论区一起交流避坑!

面试官,扎巴类什么时候会被加载,什么时候会被出示化?你说你有对象的时候,访问静态变量的时候,反射的时候?面试官,那通过子类访问父类的静态变量,子类会被出示化吗?你说会吧, 子类调用了负类的静态变量。面试官,错,通过子类访问负类静态变量指出式化,负类子类不出式化,这叫被动引用。今天用三秒戳穿你的知识盲区,厉害。今天面一个五年扎瓦老兵简历上写着深入理解 jvm 类加载机制。 我问他,一个类从加载到卸载经历哪几个阶段?他,加载验证,准备解析,初步化使用、卸载。我每个阶段分别干什么?准备阶段做了什么事情?他,准备阶段给静态变量分配内存, 并设置默认出使值。比如 int 是 零,引用是诺。我那静态变量如果写成 public static final, int, value, equals one, hundred, twenty three, 准备阶段它的值是多少? 他也是默认出使值零,等出使化阶段才负一百二十三。我错, final 修饰的静态常量在准备阶段就直接赋值一百二十三,这是特殊情况,他开始下意识摸鼻子, 那什么情况下会触发类的出使?话说五种,他拗对象访问静态变量,调用静态方法反射出使化子类时,负类先出使化。我那通过数组定义来引用类, 比如 student new students, equals new student 会触发 student 的 初始化吗?他 应该是会的吧?我不会,这是被动引用,不会触发初始化。他表情开始僵硬。我再问,你,访问一个类的 final 静态常亮,会触发初始化吗?他会,因为访问了静态变量?我不对。 如果是翻译期间就能确定的 final 常量,会被放入调用类的常量池中,不会触发原类的出省话。这就是典型的背了生命周期, 没吃透边界条件。如果这道题目你也不会回答的话,我整理了让大厂 hr 沉默的必考题库,包含 jvm 夺命连环问、 spring 灵魂八谷高病发必杀场景、 radis 深度陷阱点个赞,评论区甩六六六,打包带走 nice。 java 类加载是 jvm 的 核心机制,但能说清楚准备阶段和初步化阶段区别的人不多。今天我从四个层次一一带大家解析本质。一类的七个生命周期阶段,每个阶段在做什么? java 类从加载到卸载经历七个阶段,其中加载、验证、准备、出场、卸载这五个阶段的顺序是固定的。解析阶段的顺序不一定,它可以在出场之后再开始,以支持 java 的 动态绑定。第一阶段是加载 类,加载器根据类的权限定名,查找并读取类的二进制。第二阶段是验证,验证自解码文件格式是否正确,语义是否符合 java 规范,自解码指令是否合法。 验证阶段包括文件格式验证、原数据验证、自解码验证、符号引用验证,如果验证失败会抛出 verify error。 这个阶段是为了防止恶意自解码破坏 jvm。 第三阶段是准备,准备阶段为静态变量分配内存,并设置默认出使值。注意,这里是默认出使值,不是代码中写的值。 例如 public static int count equals one hundred。 在 准备阶段, count 的 值是零,不是一百,真正负一百发生在出使化阶段,但有一个特殊情况, public static final int equals one hundred twenty three file 的 长量在准备阶段就直接赋值为一百二十三,因为它在编一期就能确定。第四阶段是解析。 解析阶段,将长量池中的符号引用替换为直接引用。符号引用是用字母串形式描述的引用,比如 java lang string 直接引用是 jvm 内部能直接定位目标的指向或距饼。 第五阶段是出使化。出使化阶段,执行类的构造器方法为静态变量赋代码中写的值,并执行静态代码块。 java 程序真正的类出使化逻辑都在这里发生。本质二,类出使化的五种触发时机主动引用 java 虚拟机规范明确规定了五种情况必须立即对类进行抽象,这叫做主动引用。第一种是遇到 new get static put static invoke static 这四条自解码指令时,对应到 java 代码,就是你有一个对象,获取或设置一个静态变量,调用一个静态方法。 第二种是通过反射调用类时,如果类没有被驶使化,必须先驶使化。第三种是驶使化一个类时,如果副类没有被驶使化,必须先驶使化。副类接口的特殊之处在于驶使化子接口不会导致负接口的驶使化。 第四种是程序启动时, jvm 会先驶使化包含 main 方法的主类。第五种是 jdk 七引入的动态语言支持, 如果一个 java dot lambda, dot in focus, dot matter handle 实力的解析结果是 ref, get static 等类型的锯柄,且锯柄对应的类没有被出场,需要先出场。这五种情况是面试的常考点,但更重要的是记住哪些情况不会触发出场。 本质。三,被动引用的边界条件面试必考的四种场景被动引用是指通过子类引用父类的静态变量、通过数组定义引用类、通过 final 常量引用类等情况,这些时候子类或目标类不会被出场。 第一种被动引用是通过子类引用父类的静态变量,例如 system 点 out 点 current, 其中 value 是 父类的静态变量, 这段代码只会出使化副类,不会出使化子类,因为静态变量属于负类,子类只是继承了这个变量,不需要出使化子类。第二种被动引用是通过数组定义引用类,例如 student deal students equals new student。 这里只是创建了一个树组,并没有创建 student 对 象,所以不会触发 student 类的出使化,这个树组本身是一个由 jvm 自动生成的类。第三种被动引用是通过常量引用于,例如 system 点 out 点 current。 如果 hello 是 一个翻译期就能确定的 final 常量, const class 不 会被出示化,因为这个常量在翻译阶段就被放到了当前类的常量池中,运行时根本不需要用到 const class。 第四种被动引用是通过类名 class 获取 class 对 象,例如 class class equals student class 不会触发 student 类的抽象,这一步只是从方法区中获取已经存在的 class 结构,不需要执行抽象逻辑。 本质四,类加载器的双亲伪派模型 java 的 类加载器采用双亲伪派模型,当一个类加载器收到类加载请求时,不会自己先去加载,而是先把请求伪派给负类加载器去完成 这样一层层向上尾派,直到顶层的 bootstrap 类加载器。只有当副类加载器反馈自己无法加载这个类时,子加载器才会自己尝试加载。 双星尾派的核心优势有三个,第一是沙箱安全机制,用户自定义的 java 点 lange 点 string 类永远不会被加载,因为 bootstrap 加载器会优先加载 rt 点二中的 string, 这防止了核心类库被篡改。 第二是避免类重复加载,同一个类只会被加载一次,不会出现多个版本。第三是保证类型的唯一性, jvm 中判断两个类是否相同,除了类名,还要看加载器。双亲伪派保证了同一个类在所有加载器中版本一致。打破双亲伪派的经典场景是 tomcat 和 jdbc, tomcat 需要隔离不同 web 应用的类,所以每个应用有自己的 web app cluster 优先加载自己的 g 二包。 j d b c 的 driver manager 在 二 t 减 g 二中由 bootstrap 加载器加载, 但 j d b c 驱动在 classpath 中,于是 j d b c 使用了现成上下文类加载器,让副加载器反过来委托子加载器啊,这个就叫专业。 最后来播灵魂总结,下次面试官问你类加载机制,你要讲出七个生命周期,加载验证准备解析出纸化使用确仔 准备阶段区别,普通静态变量给默认值 final 静态常量直接赋值。五种主动引用触发出纸化,四种被动引用不触发 双擎委派三层优势,沙箱安全,避免重复加载,保证类型为一性。这道题答透了,京东的架构师定级就是你的了,你这招从哪里学回来的?牛逼牛逼。

今天一个同学问我说,在答辩的时候,老师会经常问一些什么问题呢?或者说这些问题该怎么回答呢?然后自己的表达能力啊,或者说技术方面能力啊,可能不是很好,然后自己语言组织能力没有那么的出色,然后 我觉得这些跟语言组织能力这些都搭不上边,主要还是一个自己想怎么说吧。就是我给大家提供一个框架性的回答,那首先老师肯定上来肯定会从一个背景上面去问你问题的。首先从 背景上说,那背景上说肯定上来就是问你,嗯,一,这个项目 介绍一下,介绍一下你的这个项目。好,这个其实是有框架性回答的,你就说我的项目是基于后端是什么框架呢? spring boot, 你 就说 spring boot 的 框架,然后前端是 voe 开,前端是 voe 框架开发的一个什么什么管理系统啊?你的系统名字,然后采用 bix 架构, 后端是 spring boot 为核心框架整合的一个 spring mvc 啊, my base plus 操作数据库的。然后前端是吗?前端你是 voe 二还是 voe 三呢? 加 element, element ui 那 些搭建的一个页面呢?是怎么交互的?通过 ios 实现前后端接收的一个数据的交互。然后就是说你的系统实现了什么功能?比如我的系统实现了用户登录注册呀,权限管理呀,数据的一些增删改查部分的功能啊。然后就介绍一下你优势嘛?我的页面非常的简洁,逻辑非常的完整,嗯,非常方便使用。 好,等你介绍完之后,老师可能会再想问你一下啊,为什么?你为什么你前面把你的框架说的那么好,那我先来问你啊,你为什么要选用全部的加 v 框架呢? 你就说 spring boot 框架呢,它就是一个自动自动配置啊,也不用自己也不用自己配置 xmail 文件呐,然后也不用说自己重新一个一个加依赖,就是一个起步依赖简化的开发,然后内置了一个 tomcat 的, 也无需额外的部署,就能够快速的搭起后端接口的一个服务。 然后为什么是 v o e 呢?你就说 v o e 是 一个轻量级件件式框架,它是一个组件化的开发,数据绑定非常的容易,然后页面也不需要刷新跳转,它这个开发效率非常的高啊,也比较方便。后面的维护, 它采用的是一个前后端分离的一个形式,然后部署完全结偶,各司其职,就比较维护后面的一个开发呀,或者扩展啊,维护啊什么的。现在我们来 仔细分发一下在各个场景中常见的问题。好,后端在后端层面上经常会问些什么呢?好,他会问你说你采用了 spring boot, spring boot 框架,那 spring boot 框架的优势是什么呢? spring boot 框架的优势核心的热点是什么 啊? steam 部的核心特点有什么呢?第一个就是自动装配,它可以根据依赖依赖自动配置一些组建呐,也不用我们手动的去配置。然后就是刚前面说的一个起步依赖呀的一个场景,它可以你想要什么依赖,在创建的时候自己可以直接勾选,也不用说自己后面再一个一个的去重新写。 再一个就是一个内置化的容器,比如内嵌汤姆卡子,直接用慢方法直接启动慢方法就可以启动项目。再一个就是它简化了一个配置,它的一个全局配置文件 r v k 型点,要么文件它可以统一管理一些参数。 再一个就是它不需要传统的那个插面配置,是零插面配置,然后通过注解驱动开发。我们这边不是有一个玩笑吗?面向注解编程。好,讲完了这个核心依赖,他再问你详细一点,比如说你的,嗯, 比如问你啊,四,就是一个 reset 的 接口规范是什么? reset 接口规范是什么? 你说 reset 接口规范是通过 http 请求定义的一个操作行为规范,统一接口的一个风格,就比如我们说的 get 查询数据吗? post 新增数据, put 修改数据,然后 delete 是 删除数据,所有的接口统一返回 jsen 格式的数据接口路径羽翼化,不需要无需多余的动词。 好,前端说完了,我们再来说说。哦,后端说完了,我们再来说说前端,前端常问的一些问题是什么呢?嗯, 他说 vue 在 前端开发中有哪些优势? vue 前端, 你说 v o e, 它是采用一个组卷化,组卷化开发的模式,数据双向绑定,使得操作更加的便捷。它更轻量化和较为平缓的学习路线,结合 v e router 实现路由管理, v e x 负责状态管理,从而能够高效的构建响应式的一个单一的应用。 好,刚刚提到了一个 v o e 是 采用一个组卷化开发的模式,那么我再借这个来进一步提问, 那么组建化开发有一个什么好处呢? 比如说组建化开发呢?是将页面拆分成一个公共的组件,什么导航栏呐,侧边栏呐,表单呐,表格呀这些,它就能够实现代码的复用,降低一个笼鱼的代码,减少开发,它的结构呢,也会更加的清晰,也可以更方便于后期的一个维护与修改。 好,前端,后端都已经讲完了。好,现在就是一个数据库层面的数据库层面, 那么我先首先问你,你这个项目用的是什么数据库呢?然后去是怎么去操作数据库的呢?你说啊,我的项目是用的 sql 啊, oracle 啊, my sql 数据库啊,通过一个 my business plus 来操作数据库的。好,用的什么数据库啊?操作数据库的 好数据库。问你了,他可能会进一步问你一个,进一步问你数据库的一些内容,有什么是事物呀,什么是锁影啊,什么是仕途呀?这些 还是比较简单嘛。啊,我就举一个例子吧,是事物,嗯,事物锁影啊,仕途呀, 你说事务呢?是在 service 业务方法上添加啊, transaction 注解,然后保证多个数据库操作全部成功,如果没有全部成功,那就全部回滚。这样做有一个什么好处呢?就是防止数据不一致啊,常见的就是一个修改啊,新增啊之类的关联的一个业务的操作。好 前端,后端数据库都讲了,接下来他可能会问些什么呢?交互啊,数据交互,前后端交互,那你说,嗯,那前后端是,前后端是怎么交互的? 前后端是怎么交互的呢?你就说前端是通过 anson 发送 h c, d, d p 请求,然后携带了一个参数去访问后端的一个 controller 的 接口, 后端接收到了一个前端的一个请求呢,然后他就会查询数据,然后以接收格式返回数据结果,然后前端去接收了后端返回的一个接收的数据,将数据渲染到页面展示 好。然后我还后面还会问你一下吗?后面这个是补充一下,这个项目的创新点在哪里? 这个项目的创新点在哪里?然后啊,你可以,你就可以说你的这个项目是有什么创新啊?比如说你的这个项目中有这个功能,是以往的项目也没有的,或者说你的这个项目的操作呀,哪些技术呀?是个人的一个创新,你可以说一下。还有一个就是 开发过程中遇到了什么问题,开发过程中遇到了什么问题?嗯,你就说一下,你开发的时候啊,是前后端交互不一致呀,还有还有什么数据不更新啊,或者哪一些功能实现不了呀?你就结合你 个人薄弱的点,说一下你自己在项目中遇到了一个什么问题吗?好,这些都说了,可能还会补充一句,你这个项目基于此以后还有什么改进的地方,也就是说功能上有有什么新加的功能。 那你就可以说一说你后面这个项目,嗯,还会有什么新功能的添加,或者说对现在功能的一个完善,是吧?后面还可能加一些什么功能啊?你都可以说一下。最后一个就是说好,你通过,你通过这个项目,你获得了,获得了什么能量, 你获得了什么成长,你就可以介绍一下关于你自己的个人一个心里路程呀,代码开发的一个逻辑呀,效率呀,包括你个人生活上面的成长呀,代码方面的成长啊,跟朋友沟通方面的成长呀,是哪个朋友教会了你什么技术呀,你都可以说说嘛,或者你看到了什么人啊,看到了网上的什么博主学到了什么技术, 这都是你个人的一个成长。这个答辩呢?答辩怎么说呢,你主要是靠你自己一个资源提说嘛, 你说有没有说啊,有些老师会不会问很深的技术点呐什么的?会问,但是可能性不是很大,因为有些老师嘛,他从毕业 就一直待在学校啊,新的技术他自己也接受不到,或者说哪怕自己知道新技术,他也不会说啊,去学习新技术。所以他在技术层面的问题可能会问的比较少啊。主要就是一些啊,常见的问题啊,偏向于项目方面的, 说白了就是一个文科性的东西,你只要能说,基本上都能过。咱换一个说法,你说老师非要卡着你,不卡着你,不让你过是为了什么是吧?你又自己,咱都是普通学校是吧,只要学生能过,他都会放学生过, 当然一些特别好的学校啊,那就另当别论了是吧。这十个问题可能是就是一些常见的问题,当然可能会问到的 绝对不只是这十个问题,还会问到很多很多,当然你有什么还有什么不懂的,也可以在评论区啊说出来,或者说你觉得,嗯,有什么改进的呀,也都可以说出来, 我也可以根据你的不同的地方为你做一个讲解嘛,当然我说的很多也不一定是全部对的哈,如果,如果有同学的啊,项目经理比较足够,也可以对我进行一个批评指正。

大家好,我是方格,今天我们讲解面试片之场景题,关于买漱口为什么一定要有一个主见这样一道面试题啊,这道面试题是小米的一道面试题, 首先呢,我们在回答这道题的时候,我们需要知道一个事情,就是买漱口呢,他并没有强制要求我们一张表必须显示的去定义出一个主见呢 啊,因为组建呢啊,它有一些优点,比如说第一个啊,嗯,我们可以聊一聊关于这个存储引擎底层那个实现 啊,底层那个实现,如果你最近也有这么面试,不知怎么准备的话,我这整理了能让大厂面试官沉默的必考题库,覆盖了 jvm 夺命连环、 one spring 灵魂八谷高并发必考场景, radis 深度陷阱、 mesco 必考题库,说句谢谢就行,谢谢啊,让我们知道啊,这是在 存储引擎啊,选型上面,如果门是 inodb 啊,这是 my circle 底层的其中一种啊引擎, 那么在 inodb 这种引擎的情况下呢?它的聚储所引机制什么意思呢?就说 inodb 呢,是 my circle 的 默认存储引擎啊,它呢使用组建呢?作为 g 级所引啊,什么叫 g 级所引呢?它其实上啊,就是咱们所说的物理所引啊,物理所引啊, 那么其上的一级锁钥,物理锁钥,它就是主键啊,就是主键,它只能有一个啊,如果你没有显示的去定义这个主键,那么 inno 比在选行的时候,它就会选择第一个非空的啊,非空的唯一锁钥来助 a 聚集锁钥 啊,就聚集锁钥只能有一个,其他锁钥可以有多个啊,所以如果你啊不定于主键的话,那这个时候它就会选第一个非空的唯一锁钥,主 a 聚集锁钥, 那如果也没有这个,也没有选型上,就是也没有选举上,那那他就会选择第二种方案,就是自动生成隐藏的柔 id 啊,为主键。 当然柔 id 啊,他会有一些弊端啊,因为,嗯,柔 id 的 话,如果你这个整个表没有主键的话,他会将这个引起一个问题啊,就是无主键表,他会共享咱们的全体的这个虚拟 id 啊,可能就会引引发一个征用啊,热点征用的一个问题 啊,然后他当然也没有办法去利用主键啊,查询的物理顺序的一个优势啊,他毕竟是一个相当于是伪的一个主键啊,假的一个主键啊,是这样的啊,所以这 id 并并不是我们首选啊啊,所以就说为什么要有主键,就是第一个, 是啊,引擎底层就是锯级锁印所限制的也就一级锁印,那么第二个是关于二级锁印,就是就抛开一级锁印不说,到二级锁印这个层面,我们知道啊,二级锁印呢,他 在叶子节点存储的是主键值,它不是物理地址,对吧?不是物理地址,那所以呢,你没有主键的时候呢,那么二极所引它存储的将就是这个尾的 r i d, 这样会导致一个 啊,什么问题呢?就是他的回表啊,导致咱们查询的效率会降低啊,导致回表的就是查询的效率会降低。嗯,这样一个事情,什么是回表呢?咱们简单聊一下。回表就是说大家想一想啊,我二级缩影其实没有一级缩影快,因为你没有主键的话,大家想一个事情, 你没有主键,主键是怎么找的?主键大家可以想成玩画个图啊,他是这样嘞,哎 sorry 啊,他这样来找数据的啊,就说我根据我的缩影,对吧?逐渐缩影,他就会直接啊,根据这个缩影值,我就定位到什么呢?我就定位到真实的数据行,就真实的定位到这个数据行啊,这是 啊,这是锁眼,对吧?这是锁眼页,这是数据,这是数据页,是吧?我写一下啊,这是锁眼啊,锁眼页,然后十二啊,锁眼页面的页啊,这是数据页,他就直接一步到位啊,就进到数啊,循至到这个数据页面啊, date 页面, 那 index 这个配件啊,我们写成 index 配件啊,而这个是 date 配件啊, date 配件啊,它就会直接一步到位。那如果你没有这个主键,你走了二级锁页,那二级锁页里边纯的是主键,它还得回到这个 啊,一级锁页所在的位置,找到这个主键值,然后呢再去锁定了这个数据页,它相当于中间的多了一道手续啊,所以它回表就导致咱们查询的效率就降低了, 这是站在咱们这个存储引擎这个级别来探讨这个问题。第二个就是才在这个还是最终的一个结果,就查询性能的维度来说, 那么有主键的话,咱们可以快速的去定位数据,那么想组建查找前还一步定位吗?所以他的时间复杂度啊,就是 o e 的 就直接能锁定到这条数据,嗯,然后他当然就是可以直接的去减少啊,咱们的这个显卡的 i o 啊,也可以避免咱们全盘扫描啊,还全表扫描啊,全表扫描,全表扫描其实就是什么呢?就是说你没有主键的时候啊,你的这个查询都是啊,一条一条记录去找的,直到找到目标数据就一个个找,这个时候呢,这个啊就太慢了啊,就太慢了,没有主键的话 啊,啊,组建就相当于是我们,比如说我的啊,好,还是在这边画个图啊,我的数据假如说在第一万行人有主见的话,我直接就可以通过主见啊作为查询条件直接锁定到第一万行,那如果没有主见,我只能从第一行一行一行向下走,所以这个性能是比较低的啊,是比较低的 好,这第二个站在查询性能这个层列。第三个就是关于数据维信保证的一个事情啊,数据维信保证呢,咱们知道啊,这个组建啊他肯定是非空的,并且是唯一的,那他就可以防止数据的重复啊,重复插入就不需要咱们在 业务承载需要额外的叫验,就是我这个数据会不会重复啊,这个事情就去省去了。还有一个就是他是外界关联的一个基础, 就这是站在这个数据关系的层面来说,数据唯一保证和其他数据表之间的一个关联的层面来说啊。好吧, 第四个就是关于这个运维和扩展的一个需求,就说在组成复制和分库分表的场景之下,那么其上呢?组建呢?他在整个的这个数据复制,还有咱们所说的这个关于数据啊,路由啊,它的这种机制选型上啊,就是有组建它更加的方便和简单 啊。这还有一个就是第三个呢,就是它关于这个 o m 框架的一个适配,就是大多数 o m 框架它都是基于什么呢?要求你这个表必须有主键,基于主键啊,生成的就是做的,咱们的这个相当于是啊全自动化或者半自动化的缩口啊,这样一个硬核关系啊。 最后一个就是基于这个什么呢?基于这个设计规范度啊,就是咱们所说的这个规范角度来说啊。那么你这个 啊,你这个每张表从我们从这个啊,无论就是项目的大小,咱们每张表都应该是有一个主见的啊。第二位是关于未来的一个扩展性啊, 未来的扩展性就是将来我们因为业务的变化啊,我们可能需要去啊这个进行一些这个夹子段,或者说我们要进行一些这个调整,对吧?调整一些数据,那这个时候呢,如果没有组建的话,那么咱们在调整数据的这个时候啊,就会非常非常的麻烦,非常非常的麻烦, 那么所以最佳实践就是 best practice, 咱们应该怎么去做呢?就是我们每一张表都要有主键,而且是显示定义,那主键呢?大家都知道我们是自增啊,最好能是自增啊,最好能是自增,当然也可以有一个 id 啊,这个没有问题。 然后我们避免呢用业务手段作为主见,除非我们啊,就是呃,在真正的实践当中知道这个它是符合自然主见的一个条件呢,比如说我们可以拿订单号作为主见,但在有一些业务场景下,你用业务手段作为主见是不太合适的 啊。然后就是复合组建呢,在多对多关联的场景,特殊场景是有,一般我们也不会用复合组建啊,但是在一些特殊场景下,复合组建确实能解决我们的一些就是比较棘手的一些问题啊。 好,那么这就是今天咱们所讲解的就是关于为什么啊,一张表就是必须要设计组建,咱们站在了多个维度,从 啊咱们所说的这个啊,数据库引擎底层,就是关于一级二级所引的维度去探讨,从这个最终造成的这个查询性能影响方面,以及从这个数据规划性,还要从咱们所说的这个运维与需求扩展的这个层面来说,以及最后咱们所说的这个 关于设计规范度的一个保证啊。好,那么基本上呢,今天关于咱们所讲的就是马斯克为什么必须有主见,咱们站在五个维度的回答就到这里就结束了,那么最后呢,当然 啊,还是啊感谢大家的收听啊,如果大家感觉今天的讲解的内容,分享的内容对大家有所帮助的话,大家可以一键三连,好,我们下次可称再见。

我发现卡不卡,消息不丢失这道题真的是面试照妖镜,每次问到这个问题,百分之九十的人上来就开始背,有副本机制,还有 i s r 机制,能保证消息不丢失。作为面试官,我真的一点都不想听你背这些名词。最想知道的是,出了这些问题,怎么都顶 卡不卡?消息不丢失绝对不是单纯靠某一个机制,而是生产端、 brook 端、消费端三端协同,任何一个环节出问题都会导致消息丢失。 想知道近期面试最常问的技术方向,我花了一个星期的时间,特意整理了一份二零二六年最新面试攻略,包含市面上百分之九十的技术场景题,还有完整的答题思路,只要你是我的粉丝,扣八八八,打包带走。第一步, 生产端,确保消息是真的发送到 broker 不 丢。在发送路上,新配置就两个,一是 a cks 参数一定要设置为二或者负一,意思是消息不仅要写入 delete 的 副本,还要等 i s r 列表里所有副本都确认收到才算发送成功。二呢,是 retrace 参数, 设置合理的重试次数,配合重试间隔,应对网络抖动等临时故障,避免一次失败就直接丢弃消息。第二步, block 端,确保消息持久化,高可用不丢。在存储环节,一方面,副本因子至少设为三, 这样即使一个 block 宕机,另外两个副本还能正常提供服务,避免单点故障导致的消息丢失。另一方面,配合生产端, a c k s 等于二,设置 main inside replace 等于二, 意思是至少要有两个副本同步成功,才算消息写入成功,双重保障。同时呢,禁止安肯令选己,也就是不要把非 i s r 副本选为里等,否则会导致未同步的消息丢失。第三步,消费端。这是最容易丢失消息的环节,百分之九十的丢失问题都是出在这的。 很多人以为消息拉取到消费端就万事大吉了,其实不然。核心原则只有一个,先处理业务逻辑,再提交偏移量。 具体做法很简单,一是关闭自动提交,改为手动提交,只有当消息完全处理成功,再手动提交 offside。 二是处理失败时不要轻易提交 offside, 可重试几次, 重试失败呢,就投递到死信队列,绝对不能因提交 offside 导致消息没处理,却被标记为已消费的丢失问题。另外,消费端一定要保证密等性,避免消息重试导致重复消费,进而引发业务问题,这也是保证数据一致性的兜底操作。 除了三端配置,业务层面还要有最后一道防线,也就是兜底方案。比如生产端发送消息时记录发送日期或临时落库。消费端处理消息时,记录消费日制定期通过离线任务比对发送和消费的消息,一旦发现丢失,及时复盘修复, 虽然不能时时避免丢失,但能最大限度降低损失。以上就是我的答题思路,如果是你,你会这样回答吗?

哈喽,大家好,我是方格,今天我们讲解面试篇之场景题,关于 gvm o m 问题如何排查和解决,这是京东的一道面试题。然后呢,首先第一步,我们要想排查 o m 问题,我们首先确定 o m 的 类型, 就是 o m 引发类型,是因为对内存不足而引发的 o m 还是原数据去移除引发的 o m 还是直接内存移除, 还是现成书过多,因为不同的内存移除它解决方案是不一样的。如果你最近也有张满面试不知怎么准备的话,我这整理了能让大场面试官沉默的备考提库, 覆盖了 jvm 夺命连环 one spring 灵魂花鼓高并发必考场景, radius 深度陷阱 meso 必考题库,说句谢谢就行,谢谢啊。那么首先我们先来看堆内存,如果内存不足,那这个时候我们引发 o m 的 时候,我们怎么样去排查 这个第一步呢?首先我们需要先去添加一个设置,也就说我们可以在 idea 当中我们去设置一下,就是添加 gvm 的 参数,就是当我引发 o m 这个问题的时候,我自动地会生成 pdf 文件, 生成 pdf 文件,当这个 pdf 文件被写到我的硬盘上的时候呢,我们可以通过第二步,也就是通过一个工具及 profiler, 我 们可以把这个硬盘上的 文件,又是我们的大部分文件啊,载入到,载入到我们的 profile 当中。然后呢,我们可以去查找啊,就是占用内存最大的对象啊,最大的对象, 这个最大的对象呢,我们检查到之后呢,我们可以去检查它的一个引用链,引用链进而去找到真真正正啊,导致咱们这个 o m 的 一个元音, 其实它的关键点就是定位什么呢?需要定位到我们在哪个代码去重复的创建了大的对象,这个代码一般都是在创建大的树组或者说缓存数据, 比如说老师那边呢,咱们也是创建了这样一个自定义的类型,叫微冷,对吧?然后给内幕和 age 这个属性,然后我们给个啊 类似集合,然后不断地向类似集合里边来塞入数据,那这个时候晴儿就是模拟了一个大对象的一个不断地去创建的这样一个过程啊,这样一个过程, 好,那这边呢有一个这个 gopro file 的 一个分析图啊,我们会发现的,晴儿,我们发现这个大对象,就是咱们所说的这个关于我们项目当中的这个微冷这样一个类型啊,这样一个类型, 好,那么第三个第三步呢,就是我们可以去监控 g c 的 行为,我们可以使用 g state 命令啊,监控 g c 的 行为呢,它会有一些参数,就有一些信息啊打回, 比如说它会告诉我们这个 u n g c 还有负 g c, 它回收的一个次数以及消耗的一个时间,我们可以通过就是 o g c 啊,它回收的一个频率啊,进而去判断出来啊,就是说我们有没有内存泄露啊,我们也可以结合第三方的工具 g c e z 啊,进行 g c s 制的分析,就是当数据列,当我们这个列表看起来不是那么清晰的时候,好吧, 第四步呢,就是我们可以去检查我们的 g v m 参数配置啊,是否啊配置的恰当啊,这个主要是检查两种配置,一个是确认对大小的配置是否合理,一个就是检查咱们 新生代和老年代的一个比例是否设置合理,因为如果设置的不合理,我们知道啊,就新生代如果空间过小的话,那么它的这个代数啊就晋升的比较快,就会直接从新生代,没有过几代它就直接会过渡到老年代,那这样的话就会引发频繁的这个,呃, g c 啊,频繁的 g c 这样一个过程啊, 这是咱们所说的这个堆空间啊,咱们站在了这么四个维度啊,去进行这个操作,当然是第一个就是我先生成一个 dump 文件,第二步就是我通过 g profiler, 我 去把这个 dump 文件经解析,找到它的大堆箱占用啊,以及它的引用列。 然后第三步其实就我们可以去监控啊 g c 的 行为。然后第四步呢,就是我们可以去调优或者去检查我们的 g v m 的 参数配置 好。第二个就是如果是非对内存 o m 啊,它的异常,我们怎么去排查?那首先第一步呢,就是我们如果是啊,原空间区的溢出啊,那我们原空间因为是方法区啊, 呃,所以呢,它一般呢是我们动态生成类啊过多,而原空间本身又配置比较小,比如说我们动态生成类通过反射机制,或者通过 c g d 反向带这个,呃, cctv 动态代理啊,这种机制啊,传递类过多了,但原空间啊配置过小啊,那怎么解决呢?那我们就需要就调整原空间的大小啊,调整原空间的大小。 第二种就是现成数过多,且让它从这个维度上也能啊,也能去引发我们的这个内存的 o m 啊,内存的 o m 且让那 g profile 呢?工具当中也是啊,有现成数的益处,对吧?现成数的一个益处啊,也可以去进行追踪啊, 当然我们去怎么去解决这个问题啊?就是我们需要去调整啊,这个现成的一个数量限制啊,现成数量限制好,这是怎么样去应对我们所说的这个非堆内存的 o m 排查? 那么还有一个就是我们可以站在最后啊,站在代码级别啊,就是站在代码优化级别来调整。第一个就是我们 呃,站在内存泄露修复的这个维度,比如说我有大量的这个静态集合,那这个时候我可以改成若引用,或者我把他们这个静态集合设置国旗策略啊,这样的话让我的内存及时得到释放啊,及时得到释放。 然后呢还有一种就是比较宝贵的一些资源,可能我没有去进行这个连接的关闭啊,连接的关闭 啊,或者说用文件流的关闭,比如说数据库连接非常宝贵的资源,我们一直用了之后呢,没有进行关闭,或者说文件我们读取完成之后,我们写入完成之后,我们都需要进行关闭。好,站在这个维度啊,我们可以对内存泄泄露啊,进行修复。 那么第二个就是减少内存的占用啊,就是因为这是 o m 嘛,是 auto memory, 我 们所出的内存溢出了,那所以我就要减少内存的占用,怎么去减少呢?就需要去避免大的对象频繁创建。 其实我们刚才的一样例,就是为什么导致 o m 我 们伪造的一种场景或者构造的一种场景,其实呢就是 大的对象不断地被创建啊,不断地被创建,那么到最后呢,其实 gvm 啊,它整个的就啊压力啊,就过载了,那所以就会导致内存溢出了啊,堆堆去的,当然我们我们的那个是堆去内存就溢出了,对吧?一般都是只用大速度打字,不串,对,我们需要去 通过这大部分文件的解析,对这个大部分文件的解析,我们去追踪啊,去追踪啊,当然如果我们必须要用这么大的速度和这么大的字幕串,那我们怎么办呢?我们可以去采用分块啊,分块处理啊,或者说我们可以去赋用对象啊,赋用对象好这样一种方式啊,进行操作啊就 嗯,其实上呢就是他是站在,就是我们回答这个问题的时候,这个问题其上,呃,面试官问的会比较多啊,在我们回答这个问题的时候,我们可以站在多个维度去回答啊,站在多个维度去回答。 好,那么关于这个 gvm o m 的 问题,我们今天就讲解到这里,如果大家感觉老师讲解的内容对大家有所帮助的话,咱们可以一键三连。好,最后我们感谢大家的收听,我们下次课程再见。

mybites 的 palmer 注解什么时候需要用?在我的印象中从来没有用过,我理解在绝大部分情况下都不需要使用。看完这个视频, 我才恍然大悟,原来要这么用。最常见的是翻翻你有多个参数的时候,为啥必须要加参数?多了 mybites 根本分不清谁是谁, 他会默认给参数排个号,比如第一个叫 pyro 一, 第二个叫 pyro 二。当你写搜索的时候,肯定想写 user name, address 这些有业务含义的名字,这时候要是没有加 add pyro, my buddies 就 不认识这些名字,直接报错,说找不到参数,所以必须用 add pyro 给每个参数起名字。按照它的说法, 有多个参数。在 sql 里面使用参数谜引用执行后没有报错, 执行成功。再来说个要特别注意的参瞄,你的哨口加了多了符号,参数就必须加 and parallel。 有 的场景咱们不得不使用多了符号。比如动态常用列名表明的时候,因为另一个常用的警符号会自动加单引号,你传过 id 过去,它会变成单引号, id 写在哨口里直接出错。警号会自动加单引号吗? 这个我是头一次听说啊,警号不是应该替换成问号吗?脑袋炸了 哦,多了符号,直接把参数拼接烧烤里必须明确告诉 mybit 要拼接的参数叫啥,所以得加 and parallel, 给参数起编名。如果你想按某个字段排序给参数加 and parallel, o 的 by, 烧烤里就写多了 o 的 by 才不混乱。按照它的说法,我在 o 的 by 里面使用了多了符,参数上面没有加注减, 执行成功,最后也是最容易被忽略的,就算只有一个参数,只要冻在烧黑里用它做了判断,也必须加 add power 助减。好多人在这踩过坑,觉得就一个参数直接用就行了,结果一运行就报错。为啥?比如 给你写了个判断,如果 id 不是 空,就加上微妙条件,这里的 id 是 在找参数的名字,要是没给参数加 adouble id, my balance 根本就不知道这个 id 指的是哪个参数。当你学的时候就因为这事查了半天的错。现在每次写东南烧烤的时候,第一件事就检查有没有加 adouble 注解,这里是一个一符一句 id, 没有使用注解执行成功。总结一下就是,不管参数多少,只要在稍后,你需要明确写出参数的名字,不管是多参数加 alt pair 区分,单参数加 alt pair, 取别 名用多了符加 alt pair 定位还是动态判断词加 alt pair 标识都必须加 alt pair。 这四种情况记牢了,下次面试官再问 你,不光能答全,还能特意提嘴。最后那个容易忽略的场景绝对显得你经验足。我也总结一下,这其中场景千万不要记错了,否则面试就危险了。

在 java 后端工作的第二十八天,我悟了,面试不是比谁技术最牛,是比谁最会投其所好。先说句实话,以下三类人,别指望一周通关,早放弃早解脱。第一类,连基础都不想背的人, java 基础语法集合框架多,县城基础都记不住,再厉害的技巧也救不了你。第二类,想抄答案不练手的人,面试必考的手写题,单立模式,生产者消费者 l i u 缓存,光看代码不动手,面试官让你现场写,直接露馅。第三类,不会包装项目的人, 做过的项目只会说,我用 spring boot 写了个 c r u d, 说不出技术难点,优化方案,业务价值等于没做。好了,我们正式进入正题,一周通关。核心方法,每天四小时不瞎熬,不用贪多,每天吃透一个模块,面试足够用。第二天死背基础,八股面试保底分,重点记高频题, 扎瓦基础封装继承多态 stream, 可变性异常体系, gvm 内存模型,垃圾回收算法类加载机制,多线程 synchronize 与 rentrent lock 区别,线程持参数 monitor, myico 锁影结构,必加数,事务隔离级别所机制,不用深挖原码,背准标准答案即可先拿到基础分。 第三、四天练熟三道高频手写题,面试加分,关键必练三题,手写单立模式,双重检查所加静态内部类,生产者消费者模型, lock in q 或 wait notify 实现手写 l r u 缓存 link to hip hop 或双向练表加 hip hop, 每天写两遍,直到能脱稿默写,面试手写不卡科。第五天,包装一个项目,面试核心亮点,不用复杂,哪怕是个电商秒杀 demo。 重点说清三点,技术战用的什么? spring boot, my bedits, reduced, rocket, mq 难点遇到什么问题? 高并发库存超慢接口响应慢?分布式事务解决怎么解决的? radis 预扣库存 m p u 学风填谷 t c c 套上高并发优化分布式关键词听起来就有深度。第六七天模拟面试加踩坑避雷少一份 java 后段高平面经我整理了让面试官沉默的大厂必考题库,包含 jvm 夺命连环问 spring 灵魂八股 高并发症必杀场景 radis 深度陷阱最新 java 加 ai 面筋试题点个赞,评论区来个五五全部打包带走对着镜子念答案脸流畅度记住面试官常挖的坑 time drops 循环锁影失效场景 spring 循环依赖录音回听发现卡卡点立刻补一周痛苦换上按机会别内耗,先冲进去。

刚灭了个六年 java 简历,谢 jvm 调优专家,线上 cms 优化效果显著。我问他,来讲讲 cms 的 垃圾回收过程,为啥要分成四步?他张口就来,出示标记,并发标记,重新标记,并发清除。分成四步是为了减少 stop the word, 让业务县城和 jc 县城并发工作。我点头,标准八股,那我问你点实际的,大促期间,你的 cms 正在并发标记,业务县城疯狂修改对象引用标记,结果已经不准了。等会儿重新标记阶段,你得从头再扫一遍。老年代 sw 从几十毫秒直接飙到两秒,订单接口超时率暴涨,你怎么提前预判?他愣了一下,调整 c m s s c i n g before remarks 参数我追问掉了,但你的老年带碎片化严重并发症阶段根本清不出连续空间,下次 y g c 后的晋升又失败。 c m s 被迫并发模式失败, 自动降级到 serial old 做 four g c。 整个服务停断了五秒 k 八秒的健康检查探针连续失败, part 被重启,凌晨三点你被叫起来怎么根治他?开始被参数, sex in the shooting occupancy fraction。 我 打断他,别背了,二零二六年还死磕 cms 的 人,已经看不懂新一代云原声 jvm 了。 cms 分 四部的原因根本不是八国里写的那样,真正的门槛在于你要理解这四部每一部的停顿代价,并发风险,以及碎片化带来的慢性病。 然后你要有能力做三件事,要么根治,要么降维打击,要么全链路可观测。如果这道题你也不会的话,我整理了让大厂 hr 沉默的必考题库,包含 jvm 夺命连环问 spring 灵魂八谷高病发必杀场景 radis 深度陷阱点个赞, 评论区甩六六六,打包带走。第一层为什么要四步?为了拆解 stw, 但拆完引入了病发标记的数据脏毒问题。 cms 的 设计初衷很明确,把最耗时的标记和清除阶段做成并发,避免全尘 stw, 所以 它拆成初始标记 stw 极短,是标记 gc roots 直接引用的对象并发标记并发长。从这些跟对象开始,便利整个老年代。重新标记 stw, 按比全量扫描短, 修正并发期间被业务线程改过的对象引用并发清除并发清理垃圾对象。但二零二六年的生产环境告诉你,并发标记阶段业务线程每秒产生几百 g b 的 对象引用变更,你的重新标记用增量更新算法根本追不上 cms 的 remox s g w 越来越长,本质是并发标记阶段的脏卡表膨胀。二零二六年的解决方案不是调参数,而是换掉 cms 的 根扫描算法, 用 satb snapshot at the beginning, 像之一那样,在并发标记开始时就拍对象图快照。并发期间只记录变更,重新标记,只处理这些变更,而不是全量重扫。但可惜 cms 不 支持 satb, 所以 你只能降级 第二层。并发模式失败与碎片化的终极解法,别修 c m s 了,直接上 z g c 或分带 z g c m s。 最怕的两个字,失败。并发模式失败,晋升失败。碎片化导致大对象分配失败。二零二六年的主流方案是放弃 c m s, 全面迁移到 z g c j d k 二十一加的分带 z g c g g c。 把停顿时间定死在一毫秒以内,而且根本不分四步。它用染色纸针加毒屏障加病发整理,清除垃圾的同时整理内存碎片。如果因为历史,系统必须保留 c m s, 那 就起用 c m s 的 增量模式 x x 加 c m s incremental mode, 把病发标记和病发清除,再切成小段抢占式交给业务现成,虽然总吞吐下降百分之三十,但能避免长暂停。 第三层,可观测性与混沌验证,你要能回答下一次并发模式失败还有多久?二零二六年的 g c 治理核心不再是减少 f g c, 而是预测性止损。通过 jvm 的 x log 冒号 g c 星等于 debug, 配合 open telemetry 实时绘制老年代占用率加净身速率加碎片化指数的三维曲线。 当碎片化指数超过预值,系统自动触发警凑式 g c, 即 z g c 的 并发整理,或者在线牵引炮的到新节点,而不是等 cms 炸了再重启。 混沌工程每周演练人为注入碎片化场景,连续分配大对象再释放,让老年代碎片率飙到百分之九十。观察你的监控能否提前三十分钟报警调度,系统能否自动摘流并触发堆外整理。所以这道题考的是什么?不是 cms 分 哪四步,而是你有没有从背诵垃圾回收器步骤进化到 理解每个步骤在生产环境下的真实代价和替代方案。普通工程师觉得 cms 是 经典实现,比虚会高级架构师清楚,二零二六年还在面试里追问 cms 四部的公司大概率还活在 java 八,而真正前沿的系统已经在分代 zgce 上把停顿压到亚豪庙, 把病发模式失败变成历史名词。最后问一句,你上一次被 cms 的 病发模式失败搞到凌晨是什么时候?那个系统现在还在用 cms 吗?啊?这个就叫专业。

呃,同学们好,然后紧接着再给大家分享一个面试的长安问题啊,叫 supreme 的 声明式事物什么时候失效? 那正常咱们要清楚啊,正常咱们搞这种编程式事物的时候呢,其实就是自己呃,基于 connection 对 象去做开启事务,提交事务,还有回滚事务的操作。而 supreme 的 声明式事物呢,其实本质也是这些事,只不过 supreme 基于它的 a o p 帮咱们实现了这套内容, 所以说 spring 的 声明事务呢,更方便了咱们的操作。但是咱们也要清楚,用了它这种方式之后,什么时候我的事务会出现这种失效的情况,咱们也要尽可能的去规避啊。 来到这,咱们大概的整理一下这块点的话呢,其实就比较多了,就是声明式事务失效的这个情况很多。 首先第一点呢,咱们也聊到过了, spring 的 声明事物呢,是基于 aop 去实现的,所以说你就要确认一下你当前的这个对象能不能用 aop 去实现出它的代理对象。 而 spring 的 aop 本质用的就是 jdk 动态代理,还有 cj lab 动态代理这两种。如果说你类的一些这种修饰方式啊,或者方法的一些修饰符导致了我没有办法代理, 那自然你的声明是不是失效的,就第一个咱们清楚,这个声明式事物是基于 a o p 去实现的,如果说咱们当前类或者是方法无法被正常代替,那自然声明式事物就失效了。而这块大概有几种,第一个就是咱们的类 没有实线的接口,并且类被 final 修饰,那这两个操作如果一块上好了, jdk 动态代理是基于接口去玩的, siri lab 呢,是基于继承你这个类去玩的,你直接把两个路全封死了好吧,这不能说,并且啊,这这这个就得加并且,好吧。然后呢,最后来一个或者 方法被 private 修饰,那这样的话,你的方法也无法被正常代理这两个情况。记住,是两个情况都会导致你的声明是事务失效,因为我没有办法对你进行正常的代理。 好,那其次还有一个点的话,就是正常我事物回滚,肯定是你的方法逻辑出现了异常,然后我捕获到了这个异常,走异常增强,我才能去帮你做事物的回滚。但如果说你没有让我的 a o p 去捕获这个异常, 而是你自己手动的把一场捕获掉了,那我这边也是没有办法帮你正常回滚事务的,那咱们的事务也就失效了。所以第二点就是 声明事物是基于异常增强捕获异常信息,然后呢,执行事物的回滚操作,那咱们如果自己手动地将异常 catch 住, 没有让咱们的 a o p 去捕捉异常信息,那事物就会失效了。 好,导致你没有办法正常的回滚。好,那除此之外的话,还有一个点也是针对咱们这边异常的一个情况,声明式事物 捕获的是 runtime exception 的 异常信息,那如果说你抛出去的异常并不是运行时异常, 你抛了其他的异常,那我的这种异常增强也是捕获不到的,所以说抛出的异常不是 run time exception, 那 么也会导致失效。好吧,这也加上 会导致失效,那除此之外的话呢? spring 的 声明事物其实还有很多其他的设置,比如说啊,它有一个叫做传播特性的东西,在这个传播特性中呢,如果说你将事物的传播特性设置为了 not support, 它就会以无事物的方式去执行,所以这点就是声明式事物 中的传播特性如果设置为 not support, 应该是这么写,那当前方法会以无事物的方式啊,以无事物 这个字还不认识无啊,我打错字了啊,无事物的方式执行 好,那这就比较好理解了啊,声明事物当中提供了传播特性,各种传播特性。那往下来第二块就是咱们刚才说到了,你要是设置为 not support 好 了,那这个事物也不会正常的去执行了, ok? 然后其次呢,其实还有很多,比如说一个之前真实出现的一个问题啊,就是什么呢?呃,比如说买词或者版本可能比较低 啊,并不是,现在玩的五点六、五点七、五点五甚至八点零,可能是更早的版本,那在更早的降 ms 或者版本当中,它的默认存储引擎是 mysim, 而 mysim 这个存储引擎的特点就是它不支持事务好吧,它不支持事务,所以如果说你 操作的数据库它本身就不支持事务的话,你用这玩意也没啥意义好吧,所以说如果数据库本身 不支持事物好,那举个例子就是比如说 my server, my s m 存储引擎不支持事物,那事物自然会啊,这个声明式事物 自然会失效好,其实这些的话呢,是一些很常见的这种导致咱们事物失效的一种情况吧, 而这种东西除了它之外呢,其实还有很多很多这种呃,一些奇奇怪怪的方式,但一般这几个东西也就足够咱们面试的时候去跟面试官正常去沟通了, 但也不是希望大家去背啊,更多的还是以 a o p 这个维度去聊会更舒服一些,因为无论是咱们的这个类啊,没有实现的接口,并且被反复修饰啊,这是我当前对象就没有办法被代理, 而方法被普洱味的修饰也是啊,我这个方法没有办法被代理的方式去执行,就这两个都是基于 aop 的, 而这个呢,其实也是基于 aop 的, 因为 aop 的 这个事务的提交啊,跟回滚啊,都是基于各种增强方式去走的,我要把我的切面给你植入进去, 如果说你压根就没抛出异常啊,你把异常自己捕获了,那我 aop 自然没有办法去做其他的处理。 再往下的话是关于咱们的 runtime exception, 因为毕竟这个 aop 它的异常增强捕获的就是 runtime exception 的 类型,你不是这个方式,那自然也不行了。而下面这两个呢,倒是跟 aop 啊没有什么太大关系了,不过还有一点,咱们要加上 没有基于 spring 获取对象去执行当前方法, 你这是什么意思呢?其实也是一样的,我应该把它放到第一个归类里面,因为正常代理对象是 siri 帮我构建好的,我构建好之后你没用, 你在方法内部给我来个什么这次点,那我也没有办法去基于我的代理对象去执行好,甚至说在 aop 这个维度,咱们可以再加一,再加一波什么呢?就是 用啊,采用子县城去执行啊,子县城执行 方法,那这个时候的话也会导致失误。失效其实本质上跟他是一样的,你搞了一个子县城去执行的话,他拿到的并不是 spring 容器代理之后的对象了, 那就乱套了。而且用到了子县城的话,你可能会涉及到多个 connection, 甚至可能会出现这种在单体项目里搞了一个分布式事务的一个逻辑,那更是得不偿失了。 好吧,所以这种东西呢,一般情况下啊,很多点可能需要咱们注意,比如说 runtime exception, 咱们要记得别弄错了。而其他的一些东西啊,咱们很少会按照这种逻辑去写,但是也要注意一下,比如说方法被 priority 的 修饰,这个呢,还是有人会首悟,对吧?啊,可能会出现这种问题。 行,那这是关于咱们 spring 声明式事物什么时候失效的一个面试题。