粉丝3736获赞3.3万


刚面了个三年后端,我问他 spring 事务什么时候会失效,他掰着手指说,方法不是 public 的, 异常被 catch 了, rowback four 没配,传播行为错了。我点点头,接着问了一个让无数 java 后端拍断大腿的真实场景,你们有个订单发货方法, 加了 a transactional, 业务逻辑是扣库存,生成物流单,更新订单状态,上线半年,一切正常。某天下午,运营同事批量导出发货单,突然发现有的订单扣了库存,但没有生成物流单, 数据不一致。你打开日制,发现批量处理,循环里调用了同一个类里的 deliver order 方法,循环包了个 try catch, 指望一条失败不影响其他。诡异的是,其中一条失败后,数据库并没有回滚, 库存扣了,但物流单没落进去。你检查了事物注解方法是 public 的, 异常也确实抛出到了外层。请问这个问题的根音最可能是什么?他想了想, 是不是 try catch 之后把事物搞没了?不对啊,异常我继续往外抛了啊。我笑了笑,如果告诉你事物注解完全没失效,而是在代理对象走丢的那一瞬间, spring 忘记给你开事物了,你猜是哪一行被你当成优化的代码,悄悄绕过了代理。他陷入沉思, 啊啊,这正是 spring 事物自调用陷阱的经典场景。同一个类里的无事物方法,调用 intersectional 方法,走的是 this 对 象,而不是代理对象,事物完全被跳过。如果你对这问题也不了解,我整理了让面试官沉默的大场必考题库, 包含 jvm 夺命连环问 spring 灵魂八股高并发必杀场景, radis 深度陷阱,点个赞,留个六六六,直接暴走 nice 为什么这个问题能筛出高手? 因为他考察的不是背过事物失效原因,而是对 spring a o p 底层代理机制有没有肌肉记忆。很多人以为自己懂了,结果在批量处理中写了个 this 点叉叉叉线上跑了一个月才出事。 一个能应对生产及事物失效问题的 java 工程师,必须有三层能力,第一层,现场快照与根音定位 检查调用方式,在报错日期里找到那个调用点,看是不是直接用 this 方法名或方法名。如果是,百分之一百走了原始对象而不是代理对象。 spring 的 事务是通过代理对象植入的, this 调用绕过去了,用 aop context current proxy 暴露问题。在可疑方法开头打印 aop context current proxy, 点 get class, 如果输出不是 enhanced by spring cg lab 或无代理,说明当前确实是原始对象,但注意需要配置 attainable aspect gt。 proxy 附线并打印调用站,写一个单元测试调用入口是 spring 注入的 service, 然后在事务方法内部抛出异常打印调用站。 如果站里没有 cclip proxy 或 jdk dynamic proxy, 而是一路 this 点叉叉叉 target method, 那 自调用实锤。第二层,事前防御与压测设计 code review, 强制拦截。 在 ci 中加入自定义规则,扫描所有 at transactional 方法的调用点。如果调用方和被调用方在同一个类,且不是通过 self proxy 点叉叉叉的方式直接报错, solar cube 有 现成的 spring transaction selfinfusion 规则。 压测必须包含异常回滚场景,压测脚本里故意注入异常,观察批量处理是否出现部分回滚数据不一致。 很多团队只压成功路径,从不测失败路径。事物边界可示画在开发或育发环境开启。 spring 事物日记 log in level dark dot spring framework, dot transaction dot interceptor equals trace。 每个事物的开启提交回滚都会打印日制,自调用时不会有 create new transaction 的 日制输出,这是最早的警报。第三层代码层的防御性设计方案一,把事物方法抽到单独的 service, 最推荐把 deliver order 放到一个新 service 类中,然后注入到当前类,这样调用 deliver service。 deliver order 一定是代理对象,事物完美生效。方案二,通过代理对象调用注入自身 at authorized private your service self, 然后调用 self transactional method, 或者用 a o p contest current proxy transactional method。 方案三,编程式事物彻底绕过代理, 在批量循环中,如果每一条需要独立事务,直接注入 platform transaction manager, 手动 new transaction template 执行。虽然代码如鱼,但事物边界绝对清晰,不受代理影响。设计规范,禁止在同一类内调用自己的 at transaction 方法 写入团队开发规范,并借助 arch unit 写单元测试,在编辑阶段扫描所有 this, 调用后方的背调方法,如果有 at transaction, 测试就失败。一个字,绝。 所以这道题考的是什么?它考的是你是否从知道事物注解怎么用升级为理解 spring 动态代理的本质。

哈喽,各位技术大咖们大家好,我是长安娱乐职业的曾老师。最近很多同学说现在 ai 这么火,拍手到处都是,是不是我们学 java 的 就要被淘汰了呢?我可以很负责任告诉大家,完全不用担心, java 不 仅不会掉队,是不用,官方还给咱们送来了大杀器。 今天我就给各位加法方向的同学们全方位介绍一下这个王炸级别的框架是不是 ai。 很多同学可能会问老师, ai 不是 拍手的专属吗?以前你想在加法项目里接入 ai 功能,比如智能客服 ai 画图那叫一个头痛,你得去研究 oppai 的 各种奇葩文档,写一堆不优雅的 http 请求代码, 改个模型还得动底层的架构,太痛苦了。但是就在这两年,视频官方终于出手了,他们推出了视频 ai。 一 句话,视频 ai 就是 让我们 java 开发者像用视频簿写普通业务一样去轻松集成 ai 能力, 不需要你懂深度的算法原理,你只要会调接口,就能让你的应用拥有智慧大脑。视频 ai 到底牛在哪? 第一,统一 api, 一 次编写到处跑。视频 ai 给所有 ai 服务商,比如美国的 open ai, 国内的阿里云统一签问,谷歌的界面里都统一提供了接口。假设老板让你把 open ai 换成国内阿里的模型, 以前你可能要改几百行代码,现在施工员 ai 下,你只需要改一行配置文件,核潜代码一行都不用改,这就是大厂喜欢的技术迁移性。第二,高级开发能力太强了。 施工员 ai 不 仅仅是一个 api 调用工具,它支持结构化输出,让 ai 生成的数据直接变成你加码你的对象,支持函数调用,让 ai 自己去调用你写的工具,还支持 ig 解锁增强和 a 警的智能体。 简单的说,你可以用思维 ai 轻松做出一套企业级智能客服,他能把学校的招生简章或者公司产品文档全读一遍,然后像真人一样回答用户问题。第三,和国产技术完美对接。很多同学担心国外 ai 卡脖子, 思聘 ai 和咱们国内的阿里云合作非常紧密,思聘 ai 阿里巴巴这个框架直接支持阿里的同一系列模型,还提供了工作流编排多 a 紧协助的能力。说实话,背靠阿里云,这就是咱们加码人在国内搞 ai 的 底气。 那么学了这个好就业吗?我们的就业数据跟踪发现,加码加 ai 的 复合型人才,目前薪资普遍比传统加码开发高出百分之三十到百分之五十。 现在的企业不缺只会侦查改查的程序员,缺的是那种能利用 ai 给传统加法项目提效的人。比如用 sql ai 做智能数据分析,用 ai 辅助生成文案。 第四,学习门槛非常简单。 sql ai 引用了 sql 的 编程习惯,你只要会 sql, 熟悉 webg、 dk, 十一以上跟着官方文档走,你就可以开始你的第一个 ai 应用了。 当然,很多同学可能会遇到模型参数不知道怎么调,现在数据库不知道怎么连,或者不知道怎么把 a 顶的部署到云上。这些交给我们长沙娱乐学校的老师们,我们的课程体系已经全面拥抱社会, ai 技术站会带着你做一个真正的企业级 ai 应用项目,让你带着实际经验去找工作, 无论是传统的 smart book, 还是现在最前沿的 ai 集成,长沙阅读职校致力于让每一位学子都能踩在技术的浪潮之巅。关注我,关注长沙阅读职校,带你解锁更多高新技术密码,我们下期见!

忙省钱这三件事,可别偷懒瞎糊弄,不然哪怕内容整的再好,照样会被直接毙掉,白忙活一场。第一件, 封面下划线一定要对其规整,懒得一点点微调的,直接在后面贴个白色矩形盖住就行, 这可是我的独门小技巧,又让你学到了哈。第二件,一定要把目录格式锁住,不然转 pdf 或者拿去打印格式直接乱套翻车快捷键 ctrl 加 i 全选,再摁 ctrl 加 f, 十一锁定就没毛了。第三件, 整体语言去优化一遍,别自己死磕同一词硬换,直接用双降模块,一边压住重复率,一边淡化 ai 痕迹。屏审老师一品, 嗯,九九成稀罕物,肯定会觉得是你自己用心打磨的。就这三个小细节,顺手花几分钟全部处理完,盲省直接拉高印象分。

这是一个基于 spring boot 的 毕业设计管理系统,我们来运行一下,系统运行成功了,我们访问网址就可以进入到系统了。我们先登录已有的教师 t 一 账号, 先新增一个课题, 新增课题成功了,然后需要管理员通过一下, 接着我们注册一个新的学生账号, 这里可以看到老师刚刚新增的课题,并且可以申请该课题。 接着我们登录教师用户端, 同意一下该 课题任务, 然后切换到学生用户端,看一下课题任务,同时上传课题任务。 学生提交完成后,我们切换到教师用户端,对该课题任务审核并且打分, 然后到这里就可以发布该学生的最终成绩了。 到此整个流程都演示完成了,最后带大家看一下管理员的各个功能模块吧。 项目源码分享链接,我已经放视频介绍了,需要自取,别忘了一键三连哦!

呃,你说一下 spring 里面的事物传播机制,包括你在项目里面是怎么用的?呃,我知道有七种, required, requires, new, sport, nested, 还有几种记不太清的,具体场景下要怎么选,我说不太明白,其实我并不想去听你这种死记硬背的名词,而是我想知道你懂不懂业务的嵌套场景下是否该怎么隔离,或者说我在什么样的场景里面去选择什么样的隔离级别。 如果你在面试过程中啊,遇到这个问题,你不知道该怎么去表达,不知道该怎么去提炼和表达自己的一个想法和理解。那我自己呢,专门整理了一份针对二零二六年的最新两百万字的 java 面试攻略,里面有结合 ai 的 全站高频面试题,还有全套的 java 家 ai 的 一个学习路线图, 关注我,扣三个六可以直接暴走。其实呢,对于这个问题呢,你要先抓住视频事物传播机制的核心本质,它解决的就是一个核心问题,就是当我们在多层方法欠套调用的时候,子方法到底是加入到负方法的一个事物,和负方法一起执行,一起回滚,还是自己独立的新建一个事物,单独运行,单独控制? 第一种也是项目里面默认用的最多的,效率快,他的意思就是有则加入,没有呢就新建。也就是说如果外层已经有事物了,那子方法就直接加入到同一 一个事物里面执行,如果外层没有,就自己新建一个事物。第二种也是必须要掌握的,线上使用的频率很高,叫 be quiet new, 它的特点就是不管有没有副事物,我都会独立去开一个新事物,那旧事物呢?先挂起那最经典的业务场景就是主业务下单失败需要整体回滚,但操作日记错误记录必须要永久保留,不能跟着回滚。 三种就是适配查询场景的叫 support, 它就属于佛系配置的类型,有事务就加入,没有事务呢,就非事务运行,它几乎只用在纯查询的接口。第四种, nesty 的 嵌套事务,它的核心逻辑是大事务套小事务。小事务呢,可以单独回滚,但是不影响主事务的整体执行。所以你搞懂了这些底层逻辑,你根本就不用去死记硬背。 所有的七种类型,你只要记住核心的选型逻辑,普通业务要保证一致性,用力 quite, 日制记录类需要隔离,用力 quite new。 而纯查询场景用 support, 复杂业务需要精细化的局部回滚,就用 nested ok。 内容就分享这里,如果内容对你有帮助,记得点赞收藏。我是 mike, 我 们下期再见。

你望着 spring j d b c。 的 query 方法,陷入了深深的沉思。它已经很简洁了,传入 sql, 传入参数,传入结果映射器就能拿到结果。但你总觉得还可以更简洁一点。你突然灵光一闪, spring j d b c。 的 那个 be in property roomapper 完全可以把它封装进方法里。你保留了可变参数 object 和 sql 矩阵参数增加, class 为给 be in property roomapper 的 构造方法。然后,你做了一件最关键的事,你用了范型, 你让返回类型跟着传入的 class 走。传 user class 就 返回 list。 user 传 order class 就 返回 list order。 你惊喜地发现,从这一刻起,你的查询可以返回任意类型的 list 了。只要提供范型类型,同时保留了字段与属性映射的功能。从此,你开启了 spring j d b c。 简化的新篇章。很快,新的问题又来了。 你发现 spring j d b c 只接收可变参数 object 点点点。这意味着你的条件全是散装的, 如果没有一个统一条件管理这些参数,这样使用起来会非常吃力。你陷入了新一轮的沉思。动态条件如何与可变参数结合呢?你决定暂时放过自己,等下一集再思考。

你在 myotis 里写 in 和 not in 集合条件,总是被 forage 标签折腾得够呛。 collection item, open close sufferer, 一 堆属性标签,表达式要记得清清楚楚。每次写集合查询都像是在给框架填表格。你受够了,决定在自己的框架里彻底终结这种繁琐。 你琢磨着自己需要的其实就两件事,一个包含站位幅的应片段和一组参数值。站位幅的数量跟着数组长度走,参数按顺序收集起来,这完全是重复劳动,框架完全可以替你完成。于是你写下了第二个重灾的 add 的 方法, 它接收一个 sql 片段和一个树组内部,自动把树组展开成嗯格式的站位符,自动把所有执案顺序收集到 parent list 里。你还顺手封装了一个小小的工具,方法叫 in。 它只做一件事,把树组转成 这种占位符形式。一行 string 点 format 配合 and copies, 简单的你都想笑。从此写应用查询只需要一行 add an id in ids。 写 not in 同样只需要一行 add an id, not in ids。 展开站位符收集参数全部自动完成。重要的是你的方法,单表连表都能用,你太牛了!你看着这行代码,心里舒坦多了,被 forage 标签支配的日子一去不复返了。

别把 system prompt 当咒语, cloud code 稳定的关键不是一整坨神秘文本,而是分层组装的输入管道。 一坨 prompt 当然能跑,问题是它长不大。规则、工具、技能、记忆和项目约定混在一起,模型很难判断当前该听谁。 system prompt 先定底座,它负责身份、行为边界和工具原则,但真正发给模型的输入还会继续拼上动态上下文 可以把它想成流水线。核心规则先放底座,再拼工具, schema 技能目录 memory c l a u d e m d, 最后加当前任务状态。 分层不是为了好看。 core 管长期规则, tools 管可调用能力, skills 管可加载知识, memory 管跨绘画经验, project 管项目规则, runtime 管当前任务。 真正的取舍是固定底座要稳,动态材料要按需进来,工具会变化。 skill 要筛选 memory 也不能每条都塞进去。 最小实现可以用 block, 每段 prompt 标记来源、优先级内容和是否起用,最后由 builder 统一排序拼接。 builder 只做一件事,组装先收集 blocks, 过滤无关内容,按优先级排序,再拼成清楚的 system message。 这里要分清 system prompt 指是 messages 里的底座,用户输入工具结果上下文片段还会在完整 messages 管道里一起出现。 判断规则看职责,稳定行为底线放 system 长期偏好走 memory, 当前目标走 task 工具,结果走 tool result。 最常见的误区是觉得 prompt 越长越强,其实常 prompt 可能只是把冲突、规则、过期记忆和无关知识堆在一起。 最后记住一句, system prompt 是 底座,真正的系统是输入管道,先分清来源和优先级,再谈 prompt 怎么写。