当前位置: 首页 > news >正文

Java 微服务实用指南(一)

Java 微服务:基础

要真正理解 Java 微服务,就必须从最基本的东西开始:为人诟病的 Java 大型单体应用是什么,它的优点和缺点是什么。


什么是 Java 大型单体应用?

假设你正在为一家银行或一家金融科技初创公司工作。你为用户提供一款可以用它来开设新的银行账户的移动应用程序。

如果用 Java 代码来写,实现一个简化版的控制器类如下所示:

@Controller
class BankController {@PostMapping("/users/register")public void register(RegistrationForm form) {validate(form);riskCheck(form);openBankAccount(form);// 略……}
}

这段代码要:

  1. 验证注册表单。

  2. 对用户的地址进行风险检查,以决定是否可以给他一个银行帐户。

  3. 打开这个银行账户

部署的时候,你会将 BankController 类与所有其他源代码一起打包到 bank.jar 或 bank.war 中:在远古时期,这个庞然大物还是不错的,它包含你的银行系统运行所需的所有代码。(粗略估算,一开始你的 jar 或 war 文件的大小会在 1-100MB 范围之内。)

然后在服务器上运行.jar 文件——这就是部署 Java 应用程序所需要做的全部工作。

image

Java 大型单体应用存在什么问题?

本质上,Java 大型单体应用没有什么问题。但通过以往的项目经验,我们可以明显发现,如果你让许多不同的程序员 / 团队 / 顾问面临着高压和不明确需求,围绕同一款大型单体应用工作好几年,那么你那个小小的 bank.jar 文件就会变成一只巨大的、有千兆字节的代码怪物,每个人都不敢部署它。


如何让 Java 大型单体应用变得更小?

这自然就引出了如何缩小大型单体应用的问题。现在,你的 bank.jar 是在一个 JVM 中运行的,一台服务器上运行一个进程。

这时,你可能会产生一个想法:风险检查服务是公司其他部门使用的,我的这款银行应用与它没什么关系,不妨把它分离出去,将它作为自己的产品去部署,作为单独的进程来运行。


什么是 Java 微服务?

实际上,这意味着你不需要在你的 BankController 中调用 riskCheck() 方法,而是将该方法或 bean 及其所有辅助类移动到它自己的 Maven/Gradle 项目中,对其进行源代码配置管理,并将其独立部署,不依赖于你的银行系统。

整个提取过程本身会不会使你新的 RiskCheck 模块成为微服务呢?大家对微服务定义有着不同的解释:

  1. 如果它里面只有 5-7 个类,那么算不算微?

  2. 100 或者 1000 个类仍然算是微吗?

  3. 微服务和类的数量有什么关系吗?

我们不去钻理论上的牛角尖,而是关注其实用性,做以下两件事:

  • 调用所有可单独部署的服务(即与大小或领域边界无关的微服务)。

  • 重点关注服务间的通信这一重要主题,因为你的微服务需要相互通信的方式。

所以总结一下:你之前拥有一个 JVM 进程,即一个银行大型单体应用。现在,除了这个银行 JVM 进程,还有一个在自己 JVM 进程中运行的 RiskCheck 微服务,大型单体应用现在必须调用这个微服务进行风险检查。


如何在 Java 微服务之间进行通信?

基本上,有两种选择:同步通信或异步通信。

(http)/rest(同步通信)

同步微服务通信通常通过 HTTP 和返回 XML 或 JSON 的类似 rest 的服务来完成。

如果你需要立即响应,可以使用 REST 通信,具体到我们的案例就是这样做的,因为在开户之前必须进行风险检查:不做风险检查,就不给开户。在工具方面,可以看看哪些类库最适合同步 Java REST 调用。

消息传递(异步通信)

异步微服务通信通常通过JMS 实现或 AMQP 等协议的消息传递来完成。通常,是因为实际上如 email/smtp 驱动集成的数量是不可低估的。

有时,使用一个微服务并不需要得到立即响应,比如用户按下“立即购买”按钮并希望生成发票,不必在用户购买这一请求 / 响应周期内完成。


示例:在 Java 中调用 REST API

假设我们选择使用同步微服务通信,那么上面的Java 代码看起来就像是更底层的代码。因为对于微服务通信,通常会创建 client 类库,将实际的 HTTP 调用抽象出来。

@Controller
class BankController {@Autowiredprivate HttpClient httpClient;@PostMapping("/users/register")public void register(RegistrationForm form) {validate(form);httpClient.send(riskRequest, responseHandler());setupAccount(form);// 略......}
}

看到这段代码就会发现,现在必须部署两个 Java(微) 服务:Bank 和 RiskCheck 服务。最终会得到两个 jvm,两个进程。之前的关系图看起来将是这样的:

image

这就是开发一个 Java 微服务项目所需的全部内容:构建和部署更小的部件 (.jar 或.war 文件)。

但这就留下了一个问题:你究竟如何切分或配置这些微服务?这些小部件是什么?多大合适?


2

Java 微服务体系结构

实际上,公司可以通过各种方式来设计或架构微服务项目。具体情况取决于你是试图将一个现有的大型单体应用变成一个微服务项目,还是从一个全新的项目开始。

从大型单体应用到微服务

一个更有机的想法是将微服务从现有的整体中分离出来。请注意,这里的“微”实际上并不意味着提取出来的服务本身很小,它们本身可能仍然相当大。

我们来看一些理论。

想法:将一个大型单体应用拆分成微服务

将遗留项目转换为微服务,主要是出于以下三个原因:

  1. 它们通常难以维护 / 变更 / 扩展。

  2. 每个人,都想让事情变得更简单,从开发人员、运维人员到管理人员。

  3. 在某种程度上,你对你的领域有着明确的边界界定,也就是说:你知道你的软件应该做什么。

这意味着你可以好好看看你的 Java 银行应用这个庞然大物,并尝试沿着领域边界拆分它。

  • 你可以得出这样的结论:应该有一个“账户管理”微服务,它可以处理用户的姓名、地址、电话号码等数据。

  • 还有前面提到过的“风险模块”,用来检查用户的风险级别,可以供公司的许多其他项目甚至部门使用。

  • 还有一个发票模块,它通过 PDF 或实际的邮件发送发票。

现实:让别人来做

虽然这种方法在在纸上和 uml 类图上呈现出来很美,但是它也有缺点,例如最重要的一点使用这种方法需要很强的技术能力。为什么呢?

因为理解将高度耦合的帐户管理模块从大型单体应用中提取出来是个好主意是一回事,正确地去执行它是另一回事,两者之间存在着巨大的差异。

大多数企业项目都到了这样一个阶段,即开发人员不敢将已经用了 7 年的 Hibernate 版本升级到新的版本,这只是更新一个类库而已,但也需要做大量工作以确保不会破坏任何东西。

这些开发人员现在要深入挖掘旧的遗留代码(它们没有清晰的数据库事务边界),并提取定义良好的微服务?通常真正的挑战是无法在白板或架构会议上解决的。

这里引用推特上 @simonbrown 的话:

我一直都说……如果你不能正确地构建大型单体应用,那么微服务也帮不了你。Simon Brown


全新项目的微服务架构

开发全新的 Java 项目时,情况看起来有点不同。现在,这三点与之前那三点略有不同:

  1. 你要从头开始,所以没有要保留的旧包袱。

  2. 开发人员希望事情在未来保持简单。

  3. 问题:你对领域边界的认识还非常模糊:你不知道你的软件实际上想要做什么(提示:敏捷)。

于是就产生了各种不同的方法,公司可以使用它们尝试处理全新的 Java 微服务项目。

技术型微服务架构

对于开发人员来说,马上就会想到这样一种方法,尽管我们强烈建议不要使用它。Hadi Hariri 在 IntelliJ 中提出了“提取微服务(Extract Microservice)”重构功能,这一点很是值得称道。

image

下面的例子做了极度的简化,但实际项目中的情况却与之非常接近。

微服务之前

@Service
class UserService {public void register(User user) {String email = user.getEmail();String username =  email.substring(0, email.indexOf("@"));// ...}
}

使用了一个 substring 的 Java 微服务

@Service
class UserService {@Autowiredprivate HttpClient client;public void register(User user) {String email = user.getEmail();// 在这里,通过 http 调用 substring 微服务String username =  httpClient.send(substringRequest(email), responseHandler());// ...}
}

于是,你实际上是将一个 Java 方法调用包装成一个 HTTP 调用,事实上完全没有必要这么做,如果你做了,那么可能的理由就是明明缺乏经验却试图强行采用 Java 微服务方法。建议:不要这样做。


面向工作流的微服务体系架构

下一个常见的方法是,在工作流之后对 Java 微服务进行模块化。

举个现实生活中的例子:在德国,当你去看(公共)医生时,他需要在他的健康软件 CRM 中把你的预约记录下来。

为了让保险报销,他将把你的治疗数据和他所治疗的所有其他患者的数据通过 XML 发送给仲裁机构。

仲裁机构会看一下那个 XML 文件并做出处理(已做简化):

  1. 验证该文件是否是正确的 XML

  2. 验证它的合理性:例如一个 1 岁大的孩子每天从妇科医生做三次牙齿清洁,这合理吗?

  3. 使用其他一些形式数据对 XML 加以补充

  4. 将 XML 转发给保险以触发报销

  5. 然后向医生反馈结果,例如“成功”或“数据有异常,请重新核实修改后再次发送”

现在,如果你尝试使用微服务对这个工作流进行建模,至少会包括以上内容。

注意: 在本例中,微服务之间的通信与主题无关,但如果真要提一下的话,可以通过 RabbitMQ 之类的消息代理异步完成,因为医生不需立即得到反馈。

同样的,从纸面上看,这似乎挺不错的,但我们马上会发现以下几个问题:

  • 你觉得需要部署六个应用程序来处理一个 xml 文件吗?

  • 这些微服务真的相互独立吗?它们每一个可以独立部署吗?每个都具有不同的版本和 API 模式?

  • 如果验证微服务停了,那么合理性微服务会做什么?系统还会保持运行吗?

  • 这些微服务现在是否共享同一个的数据库(它们确实需要数据库表中的一些公共数据),或者你是否会采取更大的动作来为它们提供属于自己的数据库?

  • 以及基础设施或运维方面存在的其他问题。

有趣的是,对于一些架构师来说,上面的图理解起来更简单,因为现在每个服务都有它确切的、定义良好的用途。以前,它看起来像这个可怕的大型单体应用:

虽然这些图画起来简单,但是你肯定需要解决些额外的运维挑战。

  • 不仅需要部署一个应用程序,而是需要至少部署六个。

  • 甚至可能需要部署多个数据库,这取决于你希望微服务体系架构走多远。

  • 必须确保每个系统都保持在线、健康和工作。

  • 必须确保微服务之间的调用是有弹性的

  • 这么部署带来的一切差异——从本地开发配置到集成测试。

建议:除非你是 Netflix(但很显然你不是),你拥有超强的运维技能包:打开开发 IDE,出现故障,生产数据库被删掉,但你能轻易在 5 秒内自动恢复。或者你觉得自己像 @monzo,仅仅因为认为自己能行,就尝试了 1500 个微服务。否则,就不要这么做。

尝试根据领域边界对微服务建模是一种非常明智的方法。但是,领域边界(比如用户管理和发票)并不意味着拿来一条工作流将其分解为几个最小的部分(接收 XML、验证 XML、转发 XML)。

因此,每当你开始一个新的、领域边界还非常模糊的 Java 微服务项目时,且领域边界仍然非常模糊,请尽量保持微服务的规模,并保证当前系统在之后能够添加更多模块,确保整个团队 / 公司 / 部门都拥有非常强大的 DevOps 技能,以支持你新的基础架构。


多语言或面向团队的微服务架构

还有第三种,几乎是以自由意志主义的方法来开发微服务:让你的团队甚至个人有可能使用他们想用的任何语言或微服务来实现用(行业术语:多语言编程)。

例如,上面的合理性微服务是用 Haskell 编写的,保险的转发微服务应该用 Erlang 编写,而 XML 验证服务可以用 Java 编写。

从开发人员的角度来看很有趣的东西(即在一套隔离的环境中使用你的完美语言开发一个完美的系统),基本上不是组织想要的同质化和标准化。

这意味着,应该有一套相对标准化的语言、库和工具,这样即便你不在了,其他开发人员将来也可以继续维护。

有趣的是,回溯历史可以发现,标准化走得太远了。某些财富 500 强公司甚至不允许他们的开发人员使用 Spring,因为它“不在公司的技术蓝图中”。

建议:如果你打算使用多语言,请尝试减少同一编程语言生态系统中的多样性。例如选择Kotlin 和 Java(它们都基于 JVM,彼此之间 100% 兼容),而不是 Haskell 和 Java。


3

Java 微服务的部署和测试

请快速回顾一下本文开头提到的基础知识,任何服务器端的 Java 程序,都是.jar 或.war 文件,因此也包括微服务。

在 Java 生态系统(更确切地说是 JVM)中,有一件事情很棒:只写一次 Java 代码,基本上就可以在任何你想要的操作系统上运行,只要你用来编译代码的 JVM 版本不高于运行代码的 JVM 版本即可。

理解这一点很重要,尤其是涉及到 Docker、Kubernetes 或云这样的主题时。为什么呢?让我们看看以下几个不同的部署场景:


一个简单的 Java 微服务部署示例

我们继续以上文的银行系统为例,我们现在有一个 monobank.jar 文件(大型单体应用)和新提取的 riskengine.jar(第一个微服务)。

我们假设这两个应用程序与世界上的任何其他应用程序一样,都需要.properties 文件,里面保存数据库 url 和凭证。

因此,最简单的部署可能只包含两个目录,大致如下:

-r-r------ 1 ubuntu ubuntu     2476 Nov 26 09:41 application.properties
-r-x------ 1 ubuntu ubuntu 94806861 Nov 26 09:45 monobank-384.jar
ubuntu@somemachine:/var/www/www.monobank.com/java$ java -jar monobank-384.jar.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
...-r-r------ 1 ubuntu ubuntu     2476 Nov 26 09:41 application.properties
-r-x------ 1 ubuntu ubuntu 94806861 Nov 26 09:45 risk-engine-1.jar
ubuntu@someothermachine:/var/www/risk.monobank.com/java$ java -jar risk-engine-1.jar.   ____          _            __ _ _/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
...

现在,还剩下一个问题:如何将.properties 和.jar 文件放到服务器上呢?这个问题的答案可就多喽。


使用构建工具、SSH & Ansible 部署

对于 Java 微服务的部署,最无聊但又完美的答案是过去 20 年中管理员为公司部署 Java 服务器端程序的方式。它包括:

  • 你最喜欢的构建工具 (Maven、Gradle)

  • 古老但好用的 SSH/SCP,用于将你的 jar 包复制到服务器

  • 用于管理部署脚本和服务器的 Bash 脚本

  • 或者一些更好的:Ansible 脚本。

如果你并不想自动处理所有的负载均衡,随时防备着攻击,时时关注着 ZooKeeper 的 leader 选举,那么这种配置就足以应付很长时间了。


如何使用 Docker 进行 Java 微服务部署

几年前,出现了 Docker 和容器化的主题。如果你以前没有使用过它,那么可以先了解一下它对最终用户或开发人员的意义所在:

  • 容器(简化过的)就像一个古老的虚拟机,但更轻量级。

  • 容器是可移植的,它可以在任何地方运行。

image

有趣的是,由于 JVM 的可移植性和向后兼容性,这个好处听起来好像没那么了不起。你可以在任何服务器、树莓派(甚至是移动电话)上下载一个 JVM.zip 文件,解压缩后运行任何你想要运行的.jar 文件。

但是,对于 PHP 或 Python 之类的语言来说,情况就有点不同了,因为这些语言的版本不互相兼容或其部署配置历来都比较复杂。

或者,如果你的 Java 应用程序依赖于大量其它要安装好的服务(使用正确的版本号):比如像 PostgreSQL 之类的数据库或者像 Redis 之类的键值存储。

所以,Docker 对于 Java 微服务,或者说 Java 应用程序的主要好处在于:

  • 使用像 Testcontainers 这样的工具来搭建同质化的测试或集成环境。

  • 使复杂的部署“更容易”。以 Discourse 论坛软件为例。你可以用一个 Docker 镜像部署,它包含了你需要的所有东西:从用 Ruby 编写的 Discourse 软件,到 PostgreSQL 数据库,再到 Redis 和几乎所有的一切。

如果你想在开发机上运行一个小巧的 Oracle 数据库,那么试试 Docker 吧。

所以总结一下,现在不再是简单地 scp 一个.jar 文件,而是将 jar 文件打包成 Docker 镜像,将该 docker 镜像传输到一个私有的 docker 注册表,在目标平台上拉取该镜像,然后运行它,或者将 Docker 镜像直接 scp 到你的生产系统,然后运行它。


使用 Docker Swarm 或 Kubernetes 部署

假设你正在尝试 Docker。现在每次部署 Java 微服务时,你都要创建一个 Docker 镜像,它绑定了你的.jar 文件。你有若干这样的 Java 微服务,你希望将这些服务部署到若干机器上:即集群。

那么问题来了:如何管理集群,也就是运行 Docker 容器、执行健康检查、发布更新、扩展等等?

答案可能有两个:Docker Swarm 和 Kubernetes。

由于篇幅所限,本文就不详细介绍它们了,本质上它们最终都是基于你编写 YAML 文件来管理你的集群。

那么,Java 微服务的部署过程现在看起来可能是这样的:安装和管理 Docker Swarm/Kubernetes,执行上面所述的 Docker 步骤,编写和执行 YAML,直到所有的东西都正常工作。


如何测试 Java 微服务

假设你解决了在生产环境中部署微服务的问题,但是在开发过程中如何集成测试微服务呢?如何查看完整的工作流是否正常工作?

在实践中,你会找到三种不同的方法:

  1. 做一点点额外的工作(如果你正在使用 Spring 之类的框架), 你可以把你所有的微服务包装成一个运行器类,使用一个 Wrapper.java 类来启动所有的微服务,当然,前提是你的机器上有足够的内存来运行所有的微服务。

  2. 你可以尝试在本地也安装一套 Docker Swarm 或 Kubernetes。

  3. 不再在本地进行集成测试,而是搭建一套专用的开发 / 测试环境。现实中,很多团队都是这么做的,以避免承受在本地部署微服务之痛。

此外,除了 Java 微服务之外,你可能还需要一个运行一个消息代理(比如:ActiveMQ 或 RabbitMQ),或者一个电子邮件服务器或任何其他消息传递组件,你的 Java 微服务需要通过这些组件来彼此通信。

DevOps 方面的复杂度被大大低估了,建议了解一下微服务测试类库。

最后编辑于:2025-01-18 17:11:49


喜欢的朋友记得点赞、收藏、关注哦!!!

相关文章:

Java 微服务实用指南(一)

Java 微服务:基础 要真正理解 Java 微服务,就必须从最基本的东西开始:为人诟病的 Java 大型单体应用是什么,它的优点和缺点是什么。 什么是 Java 大型单体应用? 假设你正在为一家银行或一家金融科技初创公司工作。你为…...

Windows图形界面(GUI)-QT-C/C++ - QT Frame

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 一、概述 二、使用场景 1. 分隔内容区域 2. 装饰性边框 3. 自定义控件容器 三、常见样式 1. 框架形状(Shape) 2. 框架阴影(Shadow)…...

优选算法合集————双指针(专题二)

好久都没给大家带来算法专题啦,今天给大家带来滑动窗口专题的训练 题目一:长度最小的子数组 题目描述: 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, …...

WebSocket协议里客户端发送给服务器的数据会用4字节的掩码循环异或的分析

首先,我需要回顾WebSocket协议中对掩码处理的具体要求。根据RFC 6455,客户端发送到服务器的帧必须使用掩码,而服务器发送的帧不需要掩码。掩码是4字节的,应用于有效载荷数据,每个字节依次与掩码的对应字节异或&#xf…...

【字节青训营-9】:初探字节微服务框架 Hertz 基础使用及进阶(下)

本文目录 一、Hertz中间件Recovery二、Hertz中间件跨资源共享三、Hertz 响应四、Hertz请求五、Hertz中间件Session 一、Hertz中间件Recovery Recovery中间件是Hertz框架预置的中间件,使用server.Default()可以默认注册该中间件,为Hertz框架提供panic回复…...

新版AndroidStudio 修改 jdk版本

一、问题 之前,在安卓项目中配置JDK和Gradle的过程非常直观,只需要进入Android Studio的File菜单中的Project Structure即可进行设置,十分方便。 如下图可以在这修改JDK: 但是升级AndroidStudio之后,比如我升级到了Android Stu…...

cocos spine执行动画报错Cannot read properties of null (reading ‘data‘)

cocos v3.8.3 当想this.spine.setAnimation(0, "action1", false);播放spine动画时报错↓ 解决方法一: 在setAnimation之前调用this.spine.__preload() 解决方法二: 不要让spine或其父节点通过active显隐...

笔记:新能源汽车零部件功率级测试怎么进行?

摘要:本文旨在梳理主机厂对新能源汽车核心零部件功率级测试需求,通过试验室的主流设备仪器集成,快速实现试验方案搭建,并体现测试测量方案的时效性、便捷性优势。目标是通过提升实现设备的有效集成能力、实现多设备测试过程的有效协同、流程化测试,可快速采集、分析当前数…...

【starrocks学习】之将starrocks表同步到hive

目录 方法 1:通过HDFS导出数据 1. 将StarRocks表数据导出到HDFS 2. 在Hive中创建外部表 3. 验证数据 方法 2:使用Apache Spark同步 1. 添加StarRocks和Hive的依赖 2. 使用Spark读取StarRocks数据并写入Hive 3. 验证数据 方法 3:通过…...

Linux提权--SUDO提权

​sudo​ 是 Linux 中常用的特权管理工具,允许普通用户以其他用户(通常是 root 用户)的身份运行命令。如果配置不当,攻击者可能通过滥用 sudo​ 权限来提升自己的权限。 一.常见的 sudo 提权方法: 误配置的 sudo 权限&…...

【AIGC提示词系统】基于 DeepSeek R1 + Claude 的新年运势占卜系统设计与实现

提示词在最下方 DeepSeek R1调试了整体的提示词,使用Claude进行渲染 引言 在人工智能与传统文化交融的今天,如何让 AI 充分理解并传递东方玄学文化的精髓,成为一个极具挑战性的课题。本文将详细介绍一个基于 Claude 的新年运势占卜系统的设计…...

11. Global Object 全局对象的使用

Global Object 全局对象 1 引言2 制作全局对象3 调用全局对象4 扩展使用1 引言 全局对象适用于大量重复的对象,比如阀门,电机等,如果这些设备的基本逻辑与状态都是一样的,那么就可以使用全局对象的方法来做HMI,省时省力。并且在后期修改的时候只需要修改全局对象即可。 …...

Java synchronized锁升级

偏向锁、轻量级锁和重量级锁是Java中synchronized关键字的三种锁状态,用于优化多线程环境下的性能。以下是它们的简要说明: 1. 偏向锁(Biased Locking) 目的:减少无竞争时的锁开销。适用场景:只有一个线程…...

【Hadoop】Hadoop的HDFS

这里写目录标题 HDFS概述HDFS产出背景及定义HDFS产生背景HDFS定义 HDFS优缺点HDFS优点HDFS缺点 HDFS组成架构HDFS文件块大小 HDFS的Shell操作常用命令实操准备工作上传下载HDFS直接操作 HDFS的API操作客户端环境准备HDFS的API案例实操HDFS文件上传HDFS文件下载HDFS文件更名和移…...

JAVA异步的TCP 通讯-客户端

一、客户端代码示例 import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; import java.util.concurrent.ExecutorService; impo…...

4.回归与聚类算法 4.1线性回归

4.1.1 线性回归的原理 1 线性回归应用场景: 房价预测 销售额度预测 金融:贷款额度预测,利用线性回归以及系数分析因子 2 什么是线性回归 1) 定义:利用回归方程(函数)对一个或者多个自变量…...

联想拯救者开机进入bios

如果你的联想拯救者(Lenovo Legion)笔记本电脑开机后直接进入 BIOS 设置界面,可能是以下原因之一导致的。以下是解决方法: 1. 检查启动顺序 进入 BIOS 后,找到 Boot(启动)选项卡。检查启动顺序…...

【贪心算法篇】:“贪心”之旅--算法练习题中的智慧与策略(四)

✨感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢✨ ✨ 个人主页:余辉zmh–CSDN博客 ✨ 文章所属专栏:贪心算法篇–CSDN博客 文章目录 前言例题1.合并区间2.无重叠的区间3.用最少数量的箭引爆气球…...

Junit5使用教程(3)

第三部分:JUnit 5 进阶 3. 动态测试 一、动态测试是什么? 动态测试(Dynamic Test)允许在运行时生成测试用例,而不是在编译时通过 Test 静态定义。它通过 TestFactory 注解标记的方法动态生成一组测试用例&#xff0…...

WPS中解除工作表密码保护(忘记密码)

1.下载vba插件 项目首页 - WPS中如何启用宏附wps.vba.exe下载说明分享:WPS中如何启用宏:附wps.vba.exe下载说明本文将详细介绍如何在WPS中启用宏功能,并提供wps.vba.exe文件的下载说明 - GitCode 并按照步骤安装 2.wps中点击搜索,输入开发…...

通向AGI之路:人工通用智能的技术演进与人类未来

文章目录 引言:当机器开始思考一、AGI的本质定义与技术演进1.1 从专用到通用:智能形态的范式转移1.2 AGI发展路线图二、突破AGI的五大技术路径2.1 神经符号整合(Neuro-Symbolic AI)2.2 世界模型架构(World Models)2.3 具身认知理论(Embodied Cognition)三、AGI安全:价…...

kamailio-osp模块

该文档详细讲解了如何在Kamailio中配置和使用OSP模块(Open Settlement Protocol Module),以实现基于ETSI标准的安全多边对等互联(Secure Multi-Lateral Peering)。以下是核心内容的总结: 1. 模块功能 OSP模…...

【Linux网络编程】:URL(encode),HTTP协议,telnet工具

🎁个人主页:我们的五年 🔍系列专栏:Linux网络编程 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 ​ Linux网络编程笔记: https://mp.csdn…...

SpringMVC SpringMVC响应 一、数据处理及跳转

1. 结果跳转方式 ①.ModelAndView 设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面 <bean id"templateResolver" class"org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver"><property name"p…...

C++SLT(三)——list

目录 一、list的介绍二、list的使用list的定义方式 三、list的插入和删除push_back和pop_backpush_front和pop_frontinserterase 四、list的迭代器使用五、list的元素获取六、list的大小控制七、list的操作函数sort和reversemergeremoveremove_ifuniqueassignswap 一、list的介…...

基于Coze平台实现抖音链接提取文案转小红书文案的智能体开发全流程解析

文章目录 引言:跨平台内容运营的AI解法实例最终效果1. 平台特性对比与转化需求分析1.1 用户画像与内容风格对比1.2 文案转化核心需求2. Coze平台技术架构解析2.1 Coze核心能力矩阵2.2 关键技术组件选型3. 智能体工作流设计3.1 完整处理流程3.2 关键节点说明4. 核心模块实现详解…...

32. 最长有效括号

动态规划 dp[i]表示以i下标为结尾的最长有效括号的长度&#xff0c;取dp[i]中的最大值即可。 i从1开始判断&#xff0c;只有s[i])才需要判断&#xff1a; 如果s[i-1](&#xff0c;那么dp[i]dp[i-2]2&#xff0c;注意判断i-2的范围否则&#xff0c;如果dp[i-1]>0&#xff0…...

Linux常见问题解决方法--2

如何反爬 后台对访问进行统计&#xff0c;如果单个 IP 访问超过阈值&#xff0c;予以封锁 后台对访问进行统计&#xff0c;如果单个 session 访问超过阈值&#xff0c;予以封锁 后台对访问进行统计&#xff0c;如果单个 userAgent 访问超过阈值&#xff0c;予以封锁 以上的组…...

STM32H7和F7 主要区别

STM32H7和F7系列是STMicroelectronics推出的高性能ARM Cortex-M微控制器系列&#xff0c;二者在性能、外设和用途上有显著区别。以下是它们的主要区别&#xff1a; 1. 内核与性能 STM32H7&#xff1a; 内核&#xff1a;Cortex-M7&#xff08;单核或双核&#xff0c;部分型号带…...

软件测试丨PyTorch 图像目标检测

随着人工智能和机器学习的飞速发展&#xff0c;图像目标检测技术在各个领域扮演着越来越重要的角色。无论是在安防监控、自动驾驶车辆&#xff0c;还是在医疗影像分析和智能家居中&#xff0c;图像目标检测都发挥着不可或缺的作用。今天&#xff0c;我们将深入探讨其中一种热门…...

利用TensorFlow.js实现浏览器端机器学习:一个全面指南

引言 随着深度学习技术的不断发展&#xff0c;机器学习已从传统的服务器端运算逐渐转向了前端技术。TensorFlow.js 是 Google 推出的一个用于在浏览器中进行机器学习的开源库&#xff0c;它允许开发者在浏览器中直接运行机器学习模型&#xff0c;而无需依赖后端服务器。Tensor…...

全流程安装DeepSeek开源模型

目录 安装Ollama选择大模型安装大模型对话备注 安装Ollama 安装DeepSeek首先需要安装一个Ollama&#xff0c;这个软件相当于运行DeepSeek模型的底层&#xff0c;没有这个底层就没办法跑DeepSeek AI模型。 下载地址&#xff1a; https://ollama.com/点击下载windows版本&…...

VulnHub | Prime - 1

https://vulnhub.com/entry/prime-1,358/https://vulnhub.com/entry/prime-1,358/ 0x01&#xff1a;靶场简介 Prime 1 是 VulHub 中的一台用于 OSCP 考试练习的靶机。通过本靶机&#xff0c;我们可以系统的了解的渗透测试的全流程。本靶机的通关目标如下&#xff1a; Get The…...

实验十 Servlet(一)

实验十 Servlet(一) 【实验目的】 1&#xff0e;了解Servlet运行原理 2&#xff0e;掌握Servlet实现方式 【实验内容】 1、参考课堂例子&#xff0c;客户端通过login.jsp发出登录请求&#xff0c;请求提交到loginServlet处理。如果用户名和密码相同则视为登录成功&#xff0c…...

寒假刷题Day22

一、2570. 合并两个二维数组 - 求和法 class Solution { public:vector<vector<int>> mergeArrays(vector<vector<int>>& nums1, vector<vector<int>>& nums2) {int i 0, j 0, n1 nums1.size(), n2 nums2.size();int tmp 0;…...

KES数据库实践指南:探索KES数据库的事务隔离级别

引言 前两篇文章我们详细讲解了如何安装KES金仓数据库&#xff0c;并提供了快速查询和搭建基于coze平台的智能体的解决方案。今天&#xff0c;我们的焦点将放在并发控制机制和事务隔离级别上。 本文将通过一系列实验操作&#xff0c;深入探讨KES数据库中的并发控制机制和事务…...

基于STM32的智能加湿器设计(新版本)

目录 1、设计要求 2、系统功能 3、演示视频和实物 4、系统设计框图 5、软件设计流程图 6、原理图 7、主程序 8、总结 &#x1f91e;大家好&#xff0c;这里是5132单片机毕设设计项目分享&#xff0c;今天给大家分享的是加湿器。设备的详细功能见网盘中的文章《12、基于…...

Electricity Market Optimization 探索系列(三)

本文参考链接link 电网容量规划是一个寻求最优发电容量的过程&#xff0c;找到的最优发电容量能够可靠地满足未来电网的需求 发电机的容量和发电成本呈正相关关系&#xff0c;一台发电机的发电量不能超过其额定发电容量&#xff0c;结合我之前的博客所说的内容&#xff0c;可…...

JAVA进阶之线程

为神马有线程&#xff1f;这玩意儿在干嘛&#xff1f;&#xff1f;&#xff1f; 回答这个问题&#xff0c;就先要知道一点点计算机的工作方式。 总所周知&#xff0c;计算机有五部分&#xff1a;输入输出、计算器、存储器、控制器。而在计算机内&#xff0c;CPU、内存、I/O之…...

浙江安吉成新照明电器有限公司分布式光伏发电项目--安科瑞Acrel-1000DP分布式光伏监控系统

安科瑞 崔丽洁 项目背景 随着可再生能源的发展&#xff0c;分布式光伏发电成为重要的能源利用方式。浙江安吉成新照明电器有限公司 3234.465kWp 分布式光伏发电项目应运而生。该公司是螺旋节能灯毛管专业生产企业&#xff0c;于 2007 年 6 月成立&#xff0c;具备全自动生产线、…...

pytorch实现主成分分析 (PCA):用于数据降维和特征提取

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 使用 PyTorch 实现主成分分析&#xff08;PCA&#xff09;可以通过以下步骤进行&#xff1a; 标准化数据&#xff1a;首先&#xff0c;需要对数据进行标准化处理&#xff0c;确保每个特征的均值为 0&#xff0c;方差…...

2025_2_4 C语言中关于free函数及悬空指针,链表的一级指针和二级指指针

1.free函数 free函数所接受的参数只能是动态分配出来的内存&#xff0c;&#xff0c;否者free的行为是未定义的同一片内存空间不能被free两次 free过后的内存可能会引发悬空指针的问题 2.悬空指针 悬空指针的问题主要是free过后的内存空间&#xff0c;原先指向这片空间的指…...

pytorch逻辑回归实现垃圾邮件检测

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 完整代码&#xff1a; import torch import torch.nn as nn import torch.optim as optim from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.model_selection import train_test_split …...

一次线程数超限导致的hive写入hbase作业失败分析

1.集群配置 操作系统:SuSe操作系统 集群节点:100台相同配置的服务器 单台:核心112Core,内存396G 2.问题现象 现象1:跑单个入库任务报错,批量提交任务后出现OOM异常 执行12个hivesql,将数据写入hbase.hbase入库有近一半的任务报错。 每次报错的任务不是同一个,hivesql…...

JAVA安全—反射机制攻击链类对象成员变量方法构造方法

前言 还是JAVA安全&#xff0c;哎&#xff0c;真的讲不完&#xff0c;太多啦。 今天主要是讲一下JAVA中的反射机制&#xff0c;因为反序列化的利用基本都是要用到这个反射机制&#xff0c;还有一些攻击链条的构造&#xff0c;也会用到&#xff0c;所以就讲一下。 什么是反射…...

Java集合面试总结(题目来源JavaGuide)

问题1&#xff1a;说说 List,Set,Map 三者的区别&#xff1f; 在 Java 中&#xff0c;List、Set 和 Map 是最常用的集合框架&#xff08;Collection Framework&#xff09;接口&#xff0c;它们的主要区别如下&#xff1a; 1. List&#xff08;列表&#xff09; 特点&#xf…...

【区块链】深入理解椭圆曲线密码学(ECC)

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 深入理解椭圆曲线密码学(ECC)1. 概述2. 椭圆曲线的数学基础2.1 基本定义2.2 有限…...

接口游标分页

由于数据库本身的的限制(以MySQL为例),以 page_num,page_size 为代表的偏移分页方式不可避免的会遇到深分页问题。 不过用户若要找符合条件的少量数据,通过翻页则十分低效,且大多用户也不会往后翻很多页,故对于C端筛选数据场景,限制分页数量增加筛选条件才是标准解决方…...

大数据数仓实战项目(离线数仓+实时数仓)2

目录 1.课程目标和课程内容介绍 2.数仓维度建模设计 3.数仓为什么要分层 4.数仓分层思想和作用 5.数仓中表的种类和同步策略 6.数仓中表字段介绍以及表关系梳理 订单表itcast_orders 订单明细表 itcast_order_goods 商品信息表 itcast_goods 店铺表 itcast_shops 商…...

C++输入输出(上)

cin和cout cin是C中提供的标准输入流对象,一般针对的是键盘,也就是从键盘上输入的字符流,使用 cin来进行数据的提取,cin一般是和 >> (流提取运算符) 配合使用的。 cin的功能和scanf是类似的 cout是C中提供的标准输出流对象,一般针对的是控制台的窗口,也就是将数据以字符…...