粉丝5.9万获赞68.8万

先看单读,我当时直接,好家伙,那这哥们跟我吐槽说写了五年 java, 今天去面试居然被问什么是多肽?那关键是这种基础中的基础他还没打上来。我一直以为这种题只有十亿声效噪才会被问, 结果我去面试呀,看了一圈评论,发现一堆人都在海南,有人说学了一年,今天才真正理解多肽,还有人说写了四年代码,现在再看,居然还有新收获。所以今天我们不兜圈子,把多肽说透,让你以后面试不再翻车。 那翻译成人话就是八个字,一个指令,多种表现。 比如你写代码 animal a 等于 new dog, 那 左边是爸爸 animal, 右边是儿子 dog, 你 调用 a 点 salt, 虽然你拿着爸爸来引用,但 jimmy 会在运行时自动识别他是只狗,于是说出,汪汪。如果你把右边换成 cat, 他 就说出喵喵,那这就叫做你只管发指令。那具体怎么干,让指令自己去决定。那这里送给大家一个底层口诀,专门解决那些骚扰的鄙视点。 翻译看左边,运行看右边,编辑器,根据左边的复列,看到你能调用哪些方法,那真正执行时, jimmy 根据右边的实际对象,把虚方表里的子类版本找出来跑。 这时候有同学要问了,搞这么复杂干嘛?那直接用纸叠不香吗?兄弟,多肽不是为了秀操作,是让你少改代码少加班。你想啊,今天系统里有猫有狗,那明天产品经理脑子一热,非要加个猪?如果你没有多肽,你要到处改一副钥匙, 那有了多肽,你只需要先写一个 pick 类继承 animal 就 行了,原来的业务代码一行都不用动,直接兼容。那这就是架构里常说的对扩展开放,对修改关闭。那么实现多肽有三件事必须满足,第一,有继承或时间关系,那第二,子类重写方法,第三,父类引用指向子类对象,缺一不可。这 三点拍在桌上。再补一句,结偶和扩展性,那面试官基本没得挑。好了,最后问大家一句,你们觉得这题问的有意义吗?那多肽在实际工作中常用吗?评论区告诉我,我们下期见。

什么是 maven? 它解决了什么问题?如果你是一名开发者或 it 从业者,这期视频你一定要看完,因为 maven 有 很多可以借鉴的开发设计思想。 为了彻底把 maven 讲清楚,这期视频干货有点多,时长七分钟,如果你当前没有时间看完,可以先点赞收藏,等你有时间的时候慢慢看。好了,我们正式开始。在 maven 出现之前, java 开发者用的是 ant, ant 可以 帮你写构建脚本、翻译代码、打包项目。看起来挺好用,那它有一个致命问题,只负责执行,不负责管理。什么意思?就是说 ant 只是个执行工具,依赖库,你自己去下赞,这二包你自己放到项目里,版本冲突你自己想办法解决。项目结构你自己爱怎么定义就怎么定义, 这带来什么后果?每个项目的目录结构都不一样,每个团队都有自己的一套规则,你接手一个新项目,第一件事不是写代码, 而是花半天时间研究这个项目到底是怎么跑起来的。更要命的是依赖问题,一个项目可能依赖十几个甚至几十个第三方库,而这些库之间还会互相依赖。你不仅要下载 a 库,还要搞清楚 a 依赖了哪些版本的 b、 c、 d 库, 一旦版本不一致,项目就报错,然后你就开始漫长的排查到底是哪个版本不对,哪两个库冲突了。这种开发体验用一个词形容就是依赖地域。 may 提出了一个革命性的想法,为什么不能让工具自己知道该做什么? 为什么不能让依赖自动下载?为什么不能有一个统一的标准,让所有 java 项目都用同样的方式构建,这就是 maywen 怎么做。你只需要告诉他我要什么, 剩下的 maywen 自己搞定。让我们先说说 maywen 最强大的功能,依赖管理。 maywen 彻底解决了传统方式的依赖地域问题。 假设你要用 spring 框架,你只需要在 palm 点 xml 文件里写一行配置声明。你要用 spring, maywen 会自动从中央仓库下载 spring 以及 spring 依赖的所有其他库。 maywen 有 一套依赖传递和冲突解决机制,会自动选择一个合适的版本,不会存在版本冲突问题。 这套机制的核心是坐标系统,每个 java 库都有三个坐标, group id、 artifact id 和 version。 就 像地球上的经纬度,可以定位任何一个地点。 mawen 的 坐标可以精确定位全球任何一个公开发布的 java。 你 想用 spring boot 三点零点零写三行配置就行,想升级到三点一点零改一个数字, maven 自动处理所有依赖变化。 maven 中央仓库是这套系统的基础设施。这是一个全球公开的仓库,存放了几乎所有开源的 java 库。 你声明一个依赖 mac, 先在你电脑的本地仓库找,找不到就去中央仓库下载,下载后缓存到本地,下次再用,直接从本地拿,不需要重复下载。这套依赖管理系统彻底解放了 java 开发者。依赖管理只是 mac 的 第一个贡献, 第二个贡献是标准化了 java 项目的目录结构。 maven 定义了一套标准结构,而且这套标准非常简单,源代码放在 s r c mine, java 测试代码放在 s r c test, java 资源文件放在 s r c mine resources 编辑后的文件放在 target 就 这么简单,但威力巨大。这套结构现在已经成为 java 社区的事实标准。你打开任何一个,没问项目,不需要问任何人就知道代码在哪,测试在哪,配置文件在哪。 这种标准化极大降低了团队合作的沟通成本,也让开源项目的学习曲线变得平缓。第三个贡献是自动化构建。 maven 定义了一套完整的项目生命周期,从编导到部署,每个阶段都有标准的命令。想编一项目,运行 mvn compile, 想运行测试, 运行 mvn test, 想打包成这儿文件,运行 mvn package, 想发布到服务器,运行 mvn deploy。 这套生命周期不仅标准化了构建流程,更重要的是 它让持续集成成为可能。你可以在 jenkins、 gitlab, c i 这些工具里用同样的 maven 命令构建项目。开发环境能跑,测试环境能跑,生产环境也能跑,因为构建流程完全一致。而且 maven 的 生命周期是有顺序的。 当你运行 m v n package 时, web 会自动先执行 compile 和 test, 确保代码翻译通过,测试通过才会打包。这种设计把质量保证内置到了构建流程里。说了这么多功能, web 到底是怎么工作的?核心就两个字,声明。 web 的 核心是 palm 点 xml 文件, 全称 project object model, 项目对象模型。这个文件描述了项目的所有源信息、项目名称、版本号,依赖库构建插件打包方式,每文档读取这个文件,然后自动完成所有工作。 你不需要写脚本告诉每文档先翻译这个文件,再翻译那个文件,你只需要声明我的项目依赖 spring boot, 每文档就知道该下载什么,该怎么编辑,该怎么打包。 这种声明式的设计让 maven 的 配置文件非常简洁。一个典型的 pom 点 xml 文件可能只有几十行,但它描述的是一个完整的项目构建流程。当然, maven 也支持扩展, 如果标准的生命周期不够用,你可以通过插件机制来扩展功能。 maven 有 一个庞大的插件生态,从代码质量检查到文档生成,从数据库迁移到容器化部署,几乎所有你能想到的构建任务都有对应的插件。 说到这里,我们可以总结一下 web 到底给 java 开发带来了什么价值。第一,极大降低了项目配置的复杂度。以前你需要手动管理几十个 java, 现在只需要几行配置。以前你需要写复杂的构建脚本,现在一个命令就能完成。第二,提升了团队协助效率。 所有人用同样的项目结构,同样的构建流程,同样的依赖版本,在我电脑上能跑,在你电脑上不能跑,这种问题基本不会再出现。 第三,让持续集成和自动化部署成为可能。因为构建流程标准化了,你可以用同样的方式在任何环境构建项目, 开发、测试、生产完全一致。第四,促进了 java 生态的繁荣。因为有了 maven, 中央仓库,开源项目的分发变得极其简单。 你写了一个好用的库,发布到中央仓库,全世界的开发者都能用一行配置引入,这种便利性极大推动了 java 开源社区的发展。如果你是 java 开发者,理解 web 不 仅仅是学会用几个命令,而是理解现代软件工程中的一些核心理念。 约定优于配置,通过合理的默认值和标准约定,减少不必要的配置,让开发者专注于业务逻辑。声明式编程,告诉系统要什么而不是怎么做,让系统自己决定执行。细节依赖管理, 通过自动化的依赖解析和冲突处理,让复杂的依赖关系变得可控。这些理念不仅适用于 web, 也适用于整个软件工程领域,它们代表了软件开发工具的引进方向,更自动化、更标准化、更智能化。 maven 改变了 java 开发的方式,而它背后的理念正在改变整个软件工程的面貌,这才是 maven 真正的价值所在。

面试官问你,在 for each 循环里执行 remove 操作到底会发生什么?很多同学可能会脱口而出,这题我熟,会秒抛 concurrent modification exception 异常。兄弟们, 如果你只达到这一层面,士官心里估计已经给你贴上基础不牢的标签了。今天咱们就来彻底拆解一下为什么阿里巴巴 java 开发手册集合处理第十四条中,要把禁止在 forward 循环里进行元素的 remove i d d 操作列为强制级别的归约。 注意啊,这可不是什么参考建议,这是 p 三 c 代码扫描插件会直接阻断的严重违规问题。面试官,其实是在用暗号考你,你小子认真在生产环境这么写过吗?视频完整笔记我都整理进了两百万次 java 加 ai 面试题库里了,里面包含了主流技术站与几十个项目场景题,还有各个工作年限的简历模板,以及 java 和 ai 大 模型的学习路线。 你想啊,如果你尝试删除 list 中的首个元素,确实代码一跑,立刻秒抛并发修改异常。但这还不是最可怕的,我们来看现场二,假设你尝试删除 list 中的倒数第二个元素,你猜怎么着,程序居然不报错?但是这里藏着一个致命隐患, 最后一个元素被悄无声息地跳过了。结合大厂常见的生产事故来看,在对账清算这种对数据准确性要求极高的核心业务中,漏掉一条数据,那就是一场灾难。 那到底为什么会出现这种诡异的现象呢?我们得提问了, for rich 的 真实面目到底是什么?其实 for rich 只是 java 给你的一层语法堂表象, 把它变异解糖之后,底层的真相是一个 viterator has next 循环。这就引出了核心矛盾,循环便利归 itrater 这个对象管, 但是你删除元素用的却是 list 自己的方法。这两套系统在同时操作同一份数据。 java 为了防止这种乱象,底层设计了一个 filebus 快 速失败触发器机制 初识化的时候, editor 会记录一个 expected mod count 等于 mod count, 这时候天平是平衡的。但是呢,当 list 执行 remove 操作后,它的 mod count 会加一天平瞬间倾斜了。 紧接着 etr 执行 next 获取下一个元素时,会进行强制校验,一旦发现这两个值不等,立刻熔断,抛出 cm 异常。那为什么删导出第二个元素就不报错呢?因为发生了一场致命的数学巧合。 当你删除倒数第二个元素后, less size 会缩小。一巧就巧在此时, iter 的 游标 cursor 恰好等于了当前的 size。 当循环再去判断 his next 的 时候,它的条件是 cursor 不 等于 size, 结果返回了 false, 循环直接提前结束了。真相就是程序根本没机会去执行下一次的 next 方法,直接逃避了 failfast 的 严格叫验,不仅隐藏了 bug, 还遗漏了最后的数据。 既然这里面坑这么深,那在真正的生产环境里,咱们架构师到底该怎么写?给你推演三套方案,第一套方案官方正解,正面应当就是老老实实写 iterate 迭代器。 关键点在于一定要使用 iterate 自带的 remove 方法,它的原理是内部会自动同步 expect mod count 等于 mod count, 规避异常。这套方案朴实性最强,兼容老旧系统和所有 jdk 版本,缺点就是样板代码偏多,有点繁琐。 第二套方案也是我最推荐的优雅首选。如果你的环境是 jdk 八以上,直接用 list remove f 一行代码直接搞定,底层自动帮你封装了迭代器的所有细节与同步机制,高效易读,这是绝大多数常规业务中最契合现代 java 工程的写法。 第三套方案叫函数式防御,咱们直接用 stream api, 通过 filter 过滤生成一个全新的 list。 它的核心思想是无状态设计,绝不修改原集合,也就是 immutable 思想。 虽然不修改原对象,但这套面试调用的方案特别适合并发极高,需要严格保护原始数据的核心业务流。最后咱们总结一下面试终局如何分三步稳稳拿下 offer。 第一步谈原理,你要主动揭露 for each 的 语法堂本质,讲透 modcount 的 fail fast 机制。第二步谈风险,直击倒数第二个元素,不仅不报错,还会漏数据的灵异现象,向面试官凸显你身后的排查实战经验。 第三步谈工程化,顺势给出 removeif 或 stream 的 规范级解法,展现你作为自身开发的架构大局观。记住一句话, 技术选型没有绝对的对错,但优秀的工程师永远会选择那个预期最明确、隐患最少的方案,这才是真正能拿高薪的架构师思维。

很多同学连 java 工程里面的分层啊,命名规则都不明白,今天我一个视频从前到后给你们讲清楚 java 工程里面每一层每一个类的后缀,比如 service 到 entity, 到底是什么意思啊?第一个 controller 包,是 web 项目中的控制层,负责接收 web 请求, nvc 加包中的 c, 比如外部掉了一个什么接口,这个接口往往就是指 controller 类里面的某一个带 request mapping 注入的一个方法。还有老的项目呢,叫 action 层。第二个是 map 或者到层啊,这个是项目中的数据库操作类, 那以前呢,我们都叫到层 d o 就是 data access, object 数据库访问对象。现在呢,都基本叫 map, 因为 mybites 框架里边的设计习惯就是 map 接口啊,所以大家现在都习惯叫做 map 了,其实呢, map 和到是一个意思。第三层是 service 层, 这一层要特别注意啊,以前呢,我们一般会把业务逻辑都写在 service 层,但是呢,现在一般公司里面会把 service 层分成两个包, 分别是 service, b i z 或者 manage 啊, bo 啊这类名字由 service 层呢来包装到层的方法组成,最基本的数据库单元能力或者抽象能力。然 把业务逻辑都写在 b i z 啊, manager 啊, build 啊这一层,好处呢是职责更加清晰。上层呢,写具体的业务,下层呢,写抽象的业务,由 b i z 层调到 service 层,并且把事物也放在 b i z 层。 第四个是 common 公共的包,一般呢,写一些常用的类,比如美举类啊,公共参数啊这些东西。第五个啊,是 job 或者 schedule 包,这些呢,一般写定时任务的一些类。第六个啊,是 youtube 包,一般呢写工具类,比如日期处理类加解密类。类名呢,基本上都以 youtube 来结尾,方法呢,基本上都是 static 的。 第七个是 entity 包,实体包,一般呢放实体对象可能包含的类有 poo, d o, d o, entity, d t o, v o, b o 这些类。下面呢,我分别解释一下,上面这些 o 是 什么意思啊? poo 九的意思是最基本的 java 对 象,没有任何业务属性或者技术属性。下面什么 po 啊, d o 啊什么都是它的子集。 po, d o, entity 这三个呢,一般是一个意思啊, 指的是数据库,持久对象和表呢,是一一对应的。 d t o 呢是数据库传输对象,一般呢用在跨系统间进行传输, 比如啊, r p c 调用中的参数。 v o 呢是试图对象是 control 了,用来去接收前端参数和返回结果的。所以呢,一般命名可能是叉叉叉 request v o 或者叉叉 respond v o 是 业务对象,一般会组装多个数据库对象。 p o 在 上面说了这个 b i c 层里面去用。 最后说明一下,上面这些 o 啊,只是命名规范和开发习惯,如果你能够 hold 得住的话,那可以用一个 entity 就 从头写到尾。

各位朋友大家好,今天我们来聊聊一个在 java 世界里,从第一天起就伴随着每一位程序员的老朋友 string 类。到了二零二五年, java 已经发展到了二十一版本, 但这个类的核心地位依然无可动摇。它就像我们编程语言里的空气和水,无处不在, 却又因其设计精妙而常常被我们忽略其深度。简单来说, s t r i n g。 在 java 里代表一个不可变的函数训练。什么意思呢? 就是你一旦创建了一个函数串对象,里面的内容就再也不能被改变了。这种不可变性是它所有特性的基石,带来了安全、高效和简洁。它不属于八大基本数据类型,而是一个真正的类。 但 java 给了它像基本类型一样直接赋值的特权,比如 string greeting 等于。你好,二零二五好! 理解了它的本质,我们一起来逛逛它身上那些琳琅满目的能力,也就是它的方法。这些方法大体可以分为几类, 创建与构造、信息获取、比较、判断、查找、解锁、操作变换以及一些非常实用的现代工具。首先,怎么诞生一个 string 呢? 除了直接写双引号,我们还可以用 new string 这个构造器。它有很多重载形式,比如传入一个字母数组叉, 可以把一堆散落的字母组装成字母串,传入一个字节簇组 byte, 并指定字母集名称 charson name。 可以 把网络传输或文件读取来的二进制数据解码成我们认识的文字。 这里要注意字母集这个参数直观重要。处理中文或特殊符号时,如果选错,就可能出现乱码。字母串诞生后,我们自然想了解它。 link 方法,返回字母的个数, 这是对象方法。 is empty 和 is blank, 这是 java 十一引入的,都能判断是否为空。 is empty 要求长度为零, 而 is blank 连纯空白字体如空格制表符也认为是空。 charit into index 是 对象方法,根据下标获取单个字体。记住,下标是从零开始的,可别越界哦。接下来是比较和判断。 equals object, an object 是 最常用的,它比较内容是否完全相同, 强烈建议用它替代,等于来比较内容。 equals ignore case, string another string 则忽略大小写。 compared to string another string 和 compared to ignore case 则用于排序比较,按字典顺序返回差值。 starts with s t r i n g prefix ends with s t r i n g suffix 用来检查开头和结尾。 contains char sequence s, 看看是否包含某个子序列。这些都是对象方法, 需要你有一个字序链来调用。当我们需要在字序串这个文本海洋里查找定位时, 有一组强大的工具, index off index, off string string。 从前往后找某个字母或子串第一次出现的位置找不到,返回负一。它们还有重载版本,可以指定起始搜索点。 from index 对 应的 last i, n, d, e, x, o, f 系列 则从后往前找。这些方法在解析路径,截取内容时非常有用,重头戏来了,操作和变幻。因为字母串不可变, 所以所有这些方法都会返回一个全新的字母串,原串丝毫不变。 sub string int begin index 或 sub string int begin index, int and index 用于截取子串。注意参数是开始下标和结束下标 不包含结束点。本身 concaten string 用来连接,但现在我们更常用加号或者 string join replace char old char char new char or replace char sequence, target char sequence replacement 进行字母或序列的替换, to lower case 和 to upper case 进行大小写转换。 trim 能去掉首尾的空白符,而 java 十一的 strip strip leading strip trail 则对空白符的定义更广泛,更推荐使用 split。 string regx 是 重量级方法,它根据给定的正则表达式,把字串分割成一个字串数组。这个正则表达式参数 rejects 功能强大,但需要学习, 比如用逗号分割就是 split 逗号反过来把多个字母串拼接起来。我们可以用类方法, string join char sequence de limiter char sequence elements。 第一个参数是连接符,后面是可变长参数,用起来非常优雅。例如 string join 两千零二十五零一零一。 java 八之后, string 也加入了函数式编程的潮流。 char 方法返回一个 i, n, t, s, t, r, e, a, m, 让你可以用流的方式处理每个字母。 java 十一的 lines 方法则直接把一个多行字幕串按行分割成一个流,处理文本文件内容简直不要太方便。还有几个非常实用的新方法, repeat int count 可以 将字幕串重复多次。 formatted object arcs 作为实利方法,相当于 string format 的 快捷方式,用来做字幕串格式化。说到类方法,除了刚才提到的 join, 最重要的就是 format string format object arg, x 和 value 系列了。 format 方法利用格式函数串和参数生成格式化后的函数串功能强大,而 v a, l, u, e, o, f 可以 把几乎任何类型整数、浮点数、对象等转换为其函数串, 表示他是一个多才多艺的静态工厂。最后,我们不能忘记字母串的内部秘密,应 turn 这个方法,他会主动将字母串放入字母串长量池。对于大量重复字母串的场景,合理使用它可以节省内存, 但一般情况下我们不需要手动调用。好了,关于 java 二十一中 string 类的核心方法,我们就先聊到这里,他就像一把设计精良的瑞士军刀, 每一个方法都为了解决特定问题而生。理解他们不仅能让你编码更高效,也能让你更深的体会到 java 这门语言在 api 设计上的深思熟虑。希望这次漫步 能让你重新认识这位最熟悉的陌生人。下次当你敲下 s t r i n g 点的那一刻,或许会有更多得心应手的感觉。感谢您的耐心观看,我们下期再见!

二零二六年了,还在为 java 基础语法发愁吗?今天这节没有花里胡哨的特效,全是干货。标识符、关键字、数据类型、变量、常量、运算符、类型转换、输入输出统统讲透。 而且每讲一个知识点,我立刻就切到代码,你能看到代码怎么敲,怎么翻译,怎么运行。遇到报错,我们当场排查解决。不装高手, 我还会把踩了十年的坑一次性分享给你。视频末尾你会写出第一个交互式程序, 建议现在点收藏,以后写代码会经常回来查,准备好你的 idea 或 vs code, 马上发车。标识符就是你给类方法变量起的名字,规则很简单,字母、数字、下划线、美元符号组成, 绝对不能。数字开头也不能用关键字,特别注意 true, false, no 是 字面量,它们同样不能当标识服用,很多新手栽在这里。关键字一共有五十多个,比如 class, public, 这些单词在 java 里有特殊含义,不能占为己有。 student name 比 s 要好维护得多, 光说不练假把式,我们去 vs code 里验证一下。现在我们写一个类来测试合法的标识符。注意,我起的变量名都是符合规则的,如果你把变量名改成数字开头或者关键字,翻译器会直接报红字提醒你 整数。四种 bite short, int, long 赋点两种 float 和精度更高的 double 字母就是叉儿不尔值,只有 true 和 false。 记住它们占用的字节数和取值范围。 byte 一个字节 short, 两个 int, 四个 long, 八个字节赋值时记得加 l 后缀。 float 赋值要加 f 后缀,否则默认是 double。 实际开发中 int 和 double 用得最多, 除非内存特别紧张才会考虑 byte 或 short。 现在我们写个类,把八种类型都声明一遍。这个类里我声明了所有基本数据类型。 注意 long 数字后面的大写 l, 还有 float 数字后面的小写 f。 翻译运行一下看看控制台输出 变量就是一个可以存放数据的容器。声明变量就是告诉翻译器要多大,内存格式是数据类型加变量名分号结尾始化就是第一次给变量赋值, 也可以声明的同时就始化,一步到位。 java 要求局部变量使用前必须始化, 否则编辑器会报错,这是安全机制。如果变量值不想被修改,就用 final 修饰。 final 修饰的变量叫长量,只能复制一次。长量命名一般全部大写单词用下划线隔开, 比如 max 下划线 value, 一 看就知道是长量。下面我们写代码演示变量和长量的区别。 我声明了一个 int 变量 h 并赋值,又声明并出示化了字母串 name 还有 final 常量 pi, 尝试修改它就会报错。运行一下看看控制台输出结果。 运算符是告诉计算机执行什么操作的符号。算数运算符就是加减乘除和取余数,整数相处,结果还是整数,小数部分直接砍掉关系。运算符用来比较大小,结果是不尔值。 注意等于号是两个等号,一个等号是负值。逻辑运算符处理不尔值与或非运算短路效应是面试高频考点。 如果左边已经能决定结果,右边就不算了,自增自减分。前缀和后缀效果不一样,前缀是先加后用,后缀是先用后加。我们马上写个累,把这些运算符都测一遍。 这个类掩饰了算术关系逻辑和自增熵算符。重点看整数除法和取余的结果,还有自增前缀和后缀的区别。翻译运行,观察控制台每一行的输出 类型。转换是让不同数据类型一起参与熵算。小范围转大范围是自动的,很安全。比如 int 赋值给 int, 但是大范围转小范围必须强制转换。强制转换的语法是括号里写目标类型, 比如浪转 int 要写成括号 int。 强制转换有风险,可能丢失精度或溢出, 实际开发中要小心。 int 转 byte 超过一百二十七就会变成负数,很坑。字串和基本类型转换要用包装类方法,比如 integer 点 parseint 字串。我们写个例子看看转换会发生什么。 这里演示了自动转换和强制转换。注意 double 转 int 会直接砍掉小数 int 一 百三转 byte 变成了负一百二十六。运行一下,看看控制台输出,理解易出现象, 程序不能只输出,还得能接收用户输入。 java 用 scanner 类实现键盘输入。第一步,导入 java 点 u t i 要点 scanner。 第二步,创建 scanner, 对 象参数是 system in, 然后就可以用对象点方法读取数据了。 next line 读一行字符串, next int 读整数, next double 读小数,非常直观。注意会用 next line 和其他方法时有坑,因为回车符残留会导致 next line 直接跳过。解决办法是额外多写一句 next line 是 调换行, 最后养成好习惯,用 close 方法释放资源。我们马上写一个可以和用户对话的程序, 这个程序会问你的名字、年龄和身高。运行后在控制台输入对应信息,注意输入身高时用英文句点而不是逗号。试试看,你已经能写出交互程序了, 恭喜你坚持到了最后,非常了不起。这一节我们把 java 基础语法全过了一遍,而且不是纸上谈兵,每个点都写了代码, 你最好把演示代码自己敲三遍以上。光看视频是学不会编程的,一定要动手把代码里故意埋的错误也自己重现一遍。 比如 int 一 百三转, byte 一 出,比如变量未初始化就使用汇报错,只有亲手遇到问题再解决,记忆才深刻。下节课我们讲流程控制、 if else 和循环, 到时程序就能做判断和重复执行了。感谢你认真看完这节干货满满的视频,如果觉得有用,记得收藏,方便以后复习,我们下节课再见!

如果你刚开始学 java, 或者你已经安装了 vs code, 却还不知道怎么把它变成一个可以编辑运行和调试 java 程序的开发环境,那么这期内容一定非常适合你。 想要在 vs code 中进行 java 开发,其实很简单,就四步,安装和配置, jdk 安装、 vs code 安装这二把插件。 vs code 中配置 java 运行环境、 jdk 的 安装与配置以及 vs code 的 安装前面已经讲过了,接下来 就进入下一步。在 vs code 中安装 java 插件,打开 vs code, 点击左侧活动栏中的扩展按钮,然后在顶部的搜索框中输入 extension pack for java, 找到之后点击安装。 安装成功后,欢迎界面提示用户要安装 jdk, 因为前面我已经装好了 jdk, 这里就不再单独讲 jdk 的 安装了。接下来只需要在 vsco 的 里面把 java 运行时的 jdk 环境配置好,后面就可以正常创建运行和调试 java 项目。 在菜单栏中点击文件,然后选择首选项,接着选择设置,打开设置界面,点击右上角打开设置, 在配置文件中设置 java 运行环境。 name 表示 java 版本。 path 填你的 jdk 安装路径, default 冒号处就是设为默认,如果路径不一样,记得改成你自己的保存配置。重启 vs code, 让它重新识别 java 运行环境。点击左侧活动栏中的资源管理器, 点击左侧创建 java 项目。选择 nobel tools 创建普通 java 项目。选择项目保存位置, 这里我把项目位置选在桌面,然后点击 select project location, 输入项目名称,输入完成之后按下 enter 回车键,确认创建项目。稍等一下, 项目结构会自动生成,如果这时候弹出了是否信任此文件夹的提示框,直接选择是我信任此作者。项目创建完成之后,打开 scr 文档, 这里已经自动生成了 main 方法,同时也写好了默认的输出代码,在代码区域点击右键选择 run java, 运行成功之后,下方终端会显示程序输出结果,这里已经输出了 hello world, 说明程序已经成功运行。如果这期视频对你有帮助, 记得点个赞收藏一下,如果你还想看,我继续分享更多软件编程技术,别忘了关注我!

java 里面的 spi 是 什么?有什么用呢?这是阿里 p 六面试过程中,第二面的时候遇到了一个真实问题,如果你不理解 spi, 建议你先看完完整的视频,下面我们来看一下这个问题的考察目的。 这道题的考察难度我认为是偏中等的,对于没怎么去研究过原班同学来说, spi 是 一个非常陌生的概念,它的考察人群主要还是偏向于三到五年,三到五年属于中高端的一个 java 开发人员,因此呢,考察目的也很明, 第一个了解你对于技术领域的一个理解程度,第二个去实现高级开发的一个人才选拔。加入这个行业其实没有一个明确的人才评估标准,所以在面试的时候呢,面试官也比较难去界定你的职级,所以在互联网企业里面,技术面的考察会比较深一点,所以要想回答好这个问题,还是要有一定的自己的见解。 另外,二零二五年两百万字面试文档再次升级,包含市面上百分之九十的业务场景题,有需要的评论区留言。 java s t i 全程是 service provider in the face, 它是一种基于接口的动态扩展机制,相当于 java 你 们提供了一套接口标准,然后呢,第三方可以实现这个接口来完成功能的扩展和实现。 举个简单例子,在 java 的 s d k 里面,提供了一个数据库驱动的接口,叫 java 点 c 点 driver, 它的作用是提供数据库的访问能力。不过在 java 里面并没有提供这个接口的实现,因为不同的数据库厂商会有不同的语法和实现方式,所以只能由第三方的数据库厂商来去实现。比如说 oracle 的 是 oracle 点 gdb 点, oracle javascript 呢是 com 点 javascript 点 gdb 点 javascript。 然后我们在应用开发的时候呢,根据你集成的驱动来去实现链接到对应的数据库。 java 中的 spi 机制主要的思想是把装配的控制权转移到了程序 之外来实现标准和实现的解偶,以及呢,提供了动态和插拔的能力。在模块化的设计中啊,这种思想非常重要,实现 java spi 需要满足几个基本的要求,第二个在 classpath 目录下去创建一个 meta info service 文件的目录,在这个目录下以接口的权限命名命名的配置文件,文件内容是这个接口的实现类。在应用程序里面,我们使用 service load 就 可以根据接口名称找到 class pass 下所有的扩展实现, 然后根据上下文的场景来选择实现类,完成功能的调用。 java spi 有 一定的不足之处,比如不能根据需求去加载扩展实现,每一次都会加载扩展接口的所有实现类,并进行实体化,实体化会造成性能开销,并且加载一些不需要用到的实现类会导致内存资源的浪费。 ok, 下面我们来看一下高手对这个问题的回答方式。 java s p i 是 java 里面提供的一种接口扩展机制,我认为它有两个作用,第一个就是把标准定义和接口实现分离,在模块化开发中很好地实现了结偶。第二个是实现功能的扩展,它更好地去满足了定制化的一些需求。除了 java 的 s p i 以外呢,基于 s p i 思想的扩展还有很多,比如说像 spring 里面的 brain factory loader 以及 double 里面的 extension load, 并且 double 呢,还在 s p i 基础上做了一些进一步的优化,提供了激活扩展点和自适应扩展点。以上就是我的理解, ok, 大家知道该怎么回答了吗?如果喜欢我的作品,记得点赞、收藏加关注!我是 mike, 我 们下期再见!

大家好,今天我们来学习 java 中非常重要的两个概念,封装与访问控制。封装是面向对象三大特性之一,它能让你的代码更安全,更容易维护。 访问控制通过 private、 public 等关键字实现,它们决定了谁可以访问类的成员。 学完这节课,你将能够设计出符合 java bin 规范的类,并避免很多新手常犯的安全错误。 我会结合实际工作场景演示封装如何保护数据,并给出常见问题的排查方法。最后记得多动手敲代码。 先看一个没有封装的例子,我们定义 student name 和 h, 没有加任何修饰符,默认是包即可见。在外部,我们可以直接通过点号访问 h 属性,甚至把它复制为复数。这显然不符合现实逻辑, 如果程序里到处都能直接修改对象,内部数据一旦出现错误,排查会非常困难。 封装的核心思想就是将属性隐藏起来,对外提供受控的访问方法,就像药品封装在胶囊里。接下来我们学习如何用访问修饰符实现封装。 java 提供了四种访问修饰符控制成员变量和方法的可见范围。最严格的是 private, 被它修饰的成员只能在本类内部访问,外部完全看不见。 如果不写任何修饰符,就是 default, 也叫包级私有。同一个包下的类可以访问 protected 比 default 多了一个权限,子类可以访问,哪怕子类在不同包, 最宽松的是 public, 任何地方的代码都能访问。实际开发中,我们通常用 private 加 public 方法实现封装。标准的封装做法,用 private 修饰属性,然后提供 public 的 getter 和 setter 方法。 getter 用于获取属性值,命名规则是 get 家属姓名首字母大写,返回类型与属性一致。 setter 用于修改属性值,命名规则是 set 家属姓名首字母大写,参数类型与属性一致,一般没有返回值。 这样外部就不能直接访问 name 和 age 了,必须通过方法。如果以后需要改变内部存储方式,只需修改 geter setter 即可。很多框架如 spring my betas 也依赖这种命名规范来操作属性。 实际工作中,我们经常在 setter 里加入参数校验,防止无效数据进入对象。 比如年龄应该在零到一百五十之间,如果传入负数或过大数值,就抛出 illegal argument exception。 异常 姓名不能为 now, 也不能是空字浮串,用 trim 检查是否全是空白字母。这种防御性编程能极大提高程序的健壮性。错误在复制阶段就被发现了。 注意,异常信息要清晰,方便调用者知道哪里出错了。这是企业级代码的常见实践。构造方法负责在创建对象时初使化属性。为了保持较验逻辑统一,我们可以在构造方法中调用 setter。 这样无论是通过构造方法还是后续的 set 修改,都会执行相同的校验规则。如果类需要支持无参构造,比如某些框架要求就显示写出无参构造方法。 注意,一旦你写了有参构造,默认的无参构造就不再自动提供,需要手动添加。 好的封装习惯是所有对私有属性的写入都经过 set, 哪怕是构造方法内部。 我们来看一个实际工作场景,银行账户类 balance 是 私有属性,外部不能直接修改。提供 deposit 存款方法,金额必须为正数,否则抛出异常,然后增加余额。 提供 withdrawal 取款方法同样需要正数,而且不能超过当前余额,否则提示余额不足。 get balance 方法只读,没有 settle, 因为余额只能通过存取款改变,不能随意设置。 这种设计符合真实业务规则。封装保证了账户金额的完整性,这就是封装的力量。 新手最容易犯的错误,试图直接访问 private 属性,编辑器汇报 name has private access。 解决方法是改用 setter 方法,记住外部永远不能直接点出私有字段。 另一个常见错误, geter setter 命名不规范,比如 setage 写成 setage 首字母没大写 jabao bin。 规范要求方法名是 set 后跟属性名首字母大写,否则很多框架无法识别。排查技巧,仔细检查方法名拼写,或者用 id 自动生成 geter setter, 避免手写错误。 另一个常见异常是 no pointer exception, 你 声明了 person 变量,但忘记 new, 直接调用 setter 就 会报错。解决方法,确保用 new 创建对象,或者从工厂方法获取非空对象。 还有参数名与成员变量同名时,如果不加 this, 会造成自己赋值给自己的问题。 正确写法是 this 点 name 等于 name, 用 this 区分成员变量和局部变量。我建议你们每次写 center 时都用 this 前缀,养成好习惯,能避免大量低级错误。 今天我们学习了封装与访问控制。封装的三要素,属性私有化提供公共方法,在方法中加入较验逻辑, 访问修饰符 private default protected public 的 可见范围要牢记,实际工作中,几乎所有的 java 类都会遵循 java bin 规范,即私有属性加 geter setter。 我 给你的建议是,自己动手创建一个 product 类,包含 id name price, 实现封装和校验。 光看视频是学不会编程的,一定要打开 i d e 亲手敲一遍代码,遇到错误自己排查。建议收藏本视频,反复练习。

今天是加法实习第三天,今天一整天都在弄那个,把昨天的那个依赖给它弄完,昨天那个依赖报错之后,今天一直在弄那个依赖,弄了一天都没弄完。那个依赖金融问题,我觉得很奇怪,他, 他那个那个依赖是一个用于是用来画图的一个一个依赖,然后他现在的依赖是三点三点叉版本,三点叉版本他的依赖依赖是二点多的,二点多的,然后我的同事他们用,他们用他们的电脑跑是可以跑通的,然后用我的电脑就跑不通, 然后我把那个三点多的依赖换成了跟他的子依赖一样的,一样的版本,都是二点多,二点多他就能用一半,但是还有一半可能用不了,所以说也不行。 这个依赖我足足搞了两天,我感觉明天可能还会再搞一天,如果说就是弄不好的话,这依赖我觉得非常奇怪,非常的邪门。我的那个同事,我的同事们,他们都用,用自己电脑都能跑的动,就我的 试了很多个办法,我同事他们也过来帮我看过,就是也还是没有弄完。其实弄这个暴躁,其实我觉得还行,就是用那个内网,用内网来检查暴躁非常难受,要先把那个先把那个代码代码用数据线给他拉到自己电脑上,然后再去检查暴躁, 然后检查完报错之后,他有时候又去修改一下,修改一下就又要下载,下载的话他又要又要联网下载,我就得用其他办法,先联网,用那个用那个公司的电脑先联网,然后下载完之后 我要跑代码,跑代码我又得连内网连,连内网再去跑代码,然后又得把那个外网给他去掉,然后连内网这个动作非常的繁琐,巨无聊,巨浪费时间。然后今天一整天就是 连内网跑代码,检查报错,然后有报错下载依赖,连外网下载依赖,下载完依赖,然后又继续连内网跑代码,再检查报错,就这样检查这个报错,检查了一天我还没搞出来,我感觉再不搞出来我都感觉会被踢掉。 今天也没有什么内容,他全部内容基本上就是搞这个,搞这个报错,然后差不多就这样吧。 其实如果,如果今天把那个,把那个 bug 解决掉的话,今天应该就可以上手上手干活了。今天其实已经有活了,但是我那个 bug 还没改完,那个 bug 是 就是我要做的那个业务的那个页面, 然后那个页面跑不通的话,我后来醒完之后我不好,不好,就是不好,不好检查,所以就一直一直不能,今天就一直不能开展那个页面。

一分钟学会买色扣行锁表锁,当我开启事务,修改 id 等于一的数据不执行 commit, 我 再写一个修改 id 等于一的语句,点击执行,它被卡在这里了, 等到自动超时,现是你要操作的数据被别人锁住了,那我们写个修改 id 等于二的语句, 执行直接成功,这就是行锁之锁定需要操作的行,多个事物可以同时修改表中的不同行,当维尔条件不是锁匙,行锁就会退化为表锁。修改 id 唯一的会超时, 修改 id 为二的也会超时,依次锁定整张表,这就是表锁。表锁又分为读锁和解锁,常用于批量数据更新、读多写少的场景。当多个事物互相等待对方释放锁 时,导致所有事物都无法继续执行,这就会出现死锁。可通过添加锁引乐观锁,避免死锁的产生。你学会了吗?