【后端开发】系统设计101——通信协议,数据库与缓存,架构模式,微服务架构,支付系统(36张图详解)
【后端开发】系统设计101——通信协议,数据库与缓存,架构模式,微服务架构,支付系统(36张图)
文章目录
- 1、通信协议
- 通信协议
- REST API 对比 GraphQL(前端-web服务)
- grpc如何工作(后台-微服务)
- webhook和轮询(回调-通知系统)
- 如何提高API性能
- HTTP从1.0到3.0(从TCP到QUIC/UDP)
- API的发展史(SOAP-REST-GraphQL-RPC)
- 代码优先 vs API优先
- HTTP的响应代码
- API 网关是什么
- 如何设计有效和安全的 API?
- TCP/IP 封装
- 为什么 Nginx 被称为“反向”代理?
- 常见的负载均衡算法有哪些?
- URL、URI、URN - 你知道它们的区别吗?
- 2、数据库与缓存
- 云服务中不同数据库的便捷速查表
- 支撑数据库的8种数据结构
- SQL语句在数据库中是如何执行的?
- CAP定理
- 内存和存储的类型
- 可视化SQL查询
- SQL语言
- 数据无处不缓存
- Redis 为何如此快速?
- Redis 可以如何使用?
- 顶级缓存策略
- 3、架构模式
- MVC、MVP、MVVM、MVVM-C 和 VIPER
- 每位开发者都应该了解的18个关键设计模式
- 4、微服务架构
- 典型的微服务架构是什么样子的?
- 微服务最佳实践
- 常用于微服务的技术栈是什么?
- Kafka 为什么快
- 5、支付系统
- 如何学习支付系统?
- 为什么信用卡被称为“银行最赚钱的产品”?VISA/Mastercard是如何赚钱的?
- 当我们在商家店里刷信用卡时,VISA是如何工作的?
- 世界范围内的支付系统:印度的统一支付接口(UPI)
用图像和简单语言解释复杂系统。
参考资料:1, 2,3
文章目录
1、通信协议
通信协议
REST API 对比 GraphQL(前端-web服务)
grpc如何工作(后台-微服务)
webhook和轮询(回调-通知系统)
如何提高API性能
HTTP从1.0到3.0(从TCP到QUIC/UDP)
API的发展史(SOAP-REST-GraphQL-RPC)
代码优先 vs API优先
HTTP的响应代码
API 网关是什么
如何设计有效和安全的 API?
TCP/IP 封装
为什么 Nginx 被称为“反向”代理?
常见的负载均衡算法有哪些?
URL、URI、URN - 你知道它们的区别吗?
2、数据库与缓存
云服务中不同数据库的便捷速查表
支撑数据库的8种数据结构
SQL语句在数据库中是如何执行的?
CAP定理
内存和存储的类型
可视化SQL查询
SQL语言
数据无处不缓存
Redis 为何如此快速?
Redis 可以如何使用?
顶级缓存策略
3、架构模式
MVC、MVP、MVVM、MVVM-C 和 VIPER
每位开发者都应该了解的18个关键设计模式
4、微服务架构
典型的微服务架构是什么样子的?
微服务最佳实践
常用于微服务的技术栈是什么?
Kafka 为什么快
5、支付系统
如何学习支付系统?
为什么信用卡被称为“银行最赚钱的产品”?VISA/Mastercard是如何赚钱的?
当我们在商家店里刷信用卡时,VISA是如何工作的?
世界范围内的支付系统:印度的统一支付接口(UPI)
1、通信协议
通信协议
通信协议(Communication protocols)
架构风格定义了应用程序编程接口(API)的不同组件之间的相互交互方式。
因此,它们通过提供一种标准的设计和构建API的方法,确保了效率、可靠性和与其他系统的轻松集成。
以下是最常用的几种风格:
- RESTful(表现层状态转移):流行、易于实现、基于HTTP方法的协议。适用于Web服务。
- gRPC:现代化、高性能、使用Protocol Buffers(协议缓冲区)的协议。适用于微服务架构。
- Webhook:事件驱动、使用HTTP回调、异步的协议。在事件发生时通知系统。
- WebSocket:实时、双向、持久连接的协议。非常适合低延迟的数据交换。
- GraphQL:一种查询语言,用于请求特定的数据。减少网络开销,提供更快的响应。
- SOAP(简单对象访问协议):成熟、全面、基于XML的协议。适用于企业应用程序。
REST API 对比 GraphQL(前端-web服务)
REST:
- 使用标准的HTTP方法(如GET、POST、PUT、DELETE)进行CRUD操作。
- 在需要在独立服务/应用之间使用简单、统一的接口时表现良好。
- 缓存策略易于实现。
- 不足之处在于可能需要多次往返请求来组装来自不同端点的相关数据。
GraphQL:
- 为客户端提供单一的端点,以准确获取所需的数据。
- 客户端可以指定嵌套查询中需要的确切字段,服务器返回仅包含这些字段的优化负载。
- 支持用于修改数据的Mutations和用于实时通知的Subscriptions。
- 适用于从多个来源聚合数据,并且与快速变化的前端需求配合良好。
- 然而,它将复杂性转移到客户端,如果没有适当的保护措施,可能会允许滥用查询。
- 缓存策略可能比REST更复杂。
对比
- 在REST和GraphQL之间选择最佳方案取决于应用程序和开发团队的具体要求。
- 对于复杂或经常变化的前端需求,GraphQL是一个很好的选择。
- 而对于偏好简单和一致性契约的应用程序,REST更合适。
grpc如何工作(后台-微服务)
RPC(Remote Procedure Call)之所以被称为“远程”,是因为它在微服务架构下,当服务部署在不同的服务器上时,可以实现远程服务之间的通信。
从用户的角度来看,它就像是本地函数调用一样。
gRPC的总体数据流程:
- 步骤1:客户端发起REST调用,请求体通常采用JSON格式。
- 步骤2-4:订单服务(gRPC客户端)接收到REST调用后,将其转换并发起RPC调用到支付服务。gRPC将客户端存根编码成二进制格式并发送给底层传输层。
- 步骤5:gRPC通过HTTP2将数据包发送到网络上。由于二进制编码和网络优化,gRPC被称为比JSON快5倍。
- 步骤6-8:支付服务(gRPC服务器)接收到网络上的数据包,解码并调用服务器应用程序。
- 步骤9-11:服务器应用程序返回结果,对其进行编码并发送到传输层。
- 步骤12-14:订单服务接收到数据包,进行解码并将结果发送给客户端应用程序。
webhook和轮询(回调-通知系统)
Webhook通常被称为反向API或推送API,因为服务器向客户端发送HTTP请求。
在使用Webhook时,我们需要注意以下三点:
- 我们需要为外部服务设计适当的API来调用。
- 我们需要为安全原因在API网关中设置适当的规则。
- 我们需要在外部服务中注册正确的URL。
例子:
假设我们运营一家电商网站。客户通过API网关将订单发送到订单服务,该服务将订单传递给支付服务进行支付交易。
然后,支付服务与外部支付服务提供商(PSP)进行通信,以完成交易。
处理与外部PSP的通信有两种方法。
-
1、短轮询
在向PSP发送支付请求后,支付服务会不断向PSP询问支付状态,经过多轮后,PSP最终返回状态。
短轮询有两个缺点:
不断轮询状态会占用支付服务的资源。
外部服务直接与支付服务通信,存在安全漏洞。 -
2、Webhook
我们可以在外部服务中注册Webhook。这意味着:当您有关于该请求的更新时,请在某个URL上回调我。当PSP完成处理后,它将调用HTTP请求以更新支付状态。
通过这种方式,编程范式发生了改变,支付服务不再需要浪费资源来轮询支付状态。
如果PSP从未回调怎么办?我们可以设置一个定期作业,每小时检查一次支付状态。
如何提高API性能
-
分页:
当结果集较大时,分页是一种常见的优化方式。将结果流式返回给客户端,以提高服务的响应性。 -
异步日志记录:
同步日志记录每次调用都要处理磁盘,可能会减慢系统速度。异步日志记录会先将日志发送到无锁缓冲区,然后立即返回。日志将定期刷新到磁盘上。这可以显著减少I/O开销。 -
缓存:
我们可以将经常访问的数据缓存起来。客户端可以首先查询缓存,而不是直接访问数据库。如果缓存未命中,客户端可以从数据库中查询。像Redis这样的缓存将数据存储在内存中,因此数据访问速度比数据库快得多。 -
负载压缩
可以使用gzip等方式压缩请求和响应,以使传输的数据大小更小。这可以加快上传和下载速度。 -
连接池
在访问资源时,我们通常需要从数据库中加载数据。打开和关闭数据库连接会增加很大的开销。因此,我们应该通过一组打开的连接连接到数据库。连接池负责管理连接的生命周期。
HTTP从1.0到3.0(从TCP到QUIC/UDP)
HTTP 1.0 -> HTTP 1.1 -> HTTP 2.0 -> HTTP 3.0 (QUIC)
-
HTTP 1.0在1996年完成并完整记录。每个针对同一服务器的请求都需要单独的TCP连接。
-
HTTP 1.1于1997年发布。TCP连接可以保持打开以供重用(持久连接),但它不能解决HOL(head-of-line)阻塞问题。
HOL阻塞:当浏览器中允许的并行请求数量用完时,后续请求需要等待前面的请求完成。 -
HTTP 2.0于2015年发布。它通过请求多路复用解决了HOL问题,该技术在应用层消除了HOL阻塞,但在传输(TCP)层仍存在HOL问题。
如您在图表中所看到的,HTTP 2.0引入了HTTP“流”的概念:一种抽象,允许在同一TCP连接上多路复用不同的HTTP交换。每个流不需要按顺序发送。 -
HTTP 3.0的第一版草案于2020年发布。它是HTTP 2.0的拟议后继者。它使用QUIC而不是TCP作为底层传输协议,从而消除了传输层中的HOL阻塞。
QUIC基于UDP。它在传输层引入了流作为一等公民。QUIC流共享相同的QUIC连接,因此不需要创建新连接时进行额外的握手和慢启动,但是QUIC流是独立交付的,因此在大多数情况下影响一个流的数据包丢失不会影响其他流。
API的发展史(SOAP-REST-GraphQL-RPC)
随着时间的推移,不同的API架构风格被发布。每种风格都有其自己的标准化数据交换的模式。
您可以在图表中查看每种风格的用例。
代码优先 vs API优先
-
微服务增加了系统的复杂性,我们需要将不同的服务分离出来,以便服务于系统的不同功能。
虽然这种架构有利于解耦和职责分离,但我们需要处理服务之间的各种通信。 -
在编写代码之前,最好先仔细思考系统的复杂性,并精心定义服务的边界。
-
不同的功能团队需要使用相同的语言,专门的功能团队只负责自己的组件和服务。建议通过API设计使组织使用相同的语言。
我们可以模拟请求和响应来验证API设计,然后再编写代码。 -
提高软件质量和开发者生产力。由于我们在项目开始时已经解决了大部分不确定性,因此整个开发过程更加顺畅,软件质量也得到了极大的提高。
开发人员也对这个过程感到满意,因为他们可以专注于功能开发,而不必应对突然的变化。 -
在项目生命周期的后期出现意外的可能性降低了。
由于我们首先设计了API,因此可以在代码开发时设计测试。
在某种程度上,当使用API优先开发时,我们也具有TDD(测试驱动设计)。
HTTP的响应代码
HTTP的响应代码分为五个类别:
- 信息性响应(100-199)
- 成功响应(200-299)
- 重定向响应(300-399)
- 客户端错误 (400-499)
- 服务端错误 (500-599)
API 网关是什么
步骤1 - 客户端向API网关发送HTTP请求。
步骤2 - API网关解析和验证HTTP请求中的属性。
步骤3 - API网关执行允许列表/拒绝列表检查。
步骤4 - API网关与身份提供者进行身份验证和授权。
步骤5 - 请求被应用速率限制规则。如果超过限制,请求将被拒绝。
步骤6和7 - 现在,请求已经通过基本检查,API网关通过路径匹配找到相关的服务进行路由。
步骤8 - API网关将请求转换为适当的协议并将其发送到后端微服务。
步骤9-12:API网关可以适当地处理错误,并在错误需要更长时间恢复时处理故障(断路器)。它还可以利用ELK(弹性-Logstash-Kibana)堆栈进行日志记录和监控。我们有时会在API网关中缓存数据。
如何设计有效和安全的 API?
请注意,API设计不仅仅是URL路径设计。
大多数情况下,我们需要选择适当的资源名称、标识符和路径模式。
同样重要的是,在API网关中设计适当的HTTP标头字段或设计有效的速率限制规则。
TCP/IP 封装
数据是如何通过网络传输的?为什么OSI模型需要这么多层?
下面的图表展示了数据在网络传输过程中的封装和解封装过程。
-
第一步:当设备A通过HTTP协议向设备B发送数据时,首先在应用层添加HTTP头部。
-
第二步:然后在传输层将TCP或UDP头部添加到数据中,并封装为TCP段。头部包含源端口、目标端口和序列号。
-
第三步:接着在网络层将段封装为IP头部。IP头部包含源/目标IP地址。
-
第四步:在数据链路层为IP数据报添加MAC头部,包含源/目标MAC地址。
-
第五步:封装好的帧被发送到物理层,并以二进制位的形式在网络中传输。
-
第六至十步:当设备B从网络中接收到位流时,它执行解封装过程,这是封装过程的逆向处理。头部被逐层移除,最终设备B可以读取数据。
-
我们需要网络模型中的各层,因为每个层都专注于自己的职责。每个层都可以依赖头部进行处理指令,而不需要了解上一层数据的含义。
为什么 Nginx 被称为“反向”代理?
下面的图表展示了正向代理和反向代理之间的区别。
正向代理是位于用户设备和互联网之间的服务器。
正向代理通常用于:
- 保护客户端
- 绕过浏览限制
- 阻止访问某些内容
反向代理是一种服务器,它接收客户端的请求,将请求转发给Web服务器,并将结果返回给客户端,就好像代理服务器已经处理了请求一样。
反向代理适用于以下情况:
- 保护服务器
- 负载均衡
- 缓存静态内容
- 加密和解密SSL通信
常见的负载均衡算法有哪些?
静态算法
- 轮询(Round Robin)
将客户端请求按顺序发送到不同的服务实例。这些服务通常需要是无状态的。 - 粘性轮询(Sticky Round Robin)
这是轮询算法的一种改进。如果Alice的第一个请求发送到服务A,则后续请求也会发送到服务A。 - 加权轮询(Weighted Round Robin)
管理员可以为每个服务指定权重。权重高的服务处理的请求比其他服务多。 - 哈希(Hash)
此算法对传入请求的IP或URL应用哈希函数。请求基于哈希函数的结果路由到相关实例。
动态算法
- 最少连接数(Least Connections)
将新请求发送到并发连接最少的服务实例。 - 最短响应时间(Least Response Time)
将新请求发送到响应时间最快的服务实例。
URL、URI、URN - 你知道它们的区别吗?
-
URL
URL代表统一资源定位符,是HTTP的关键概念。它是Web上唯一资源的地址。它可以与其他协议一起使用,如FTP和JDBC。 -
URN
URN代表统一资源名称。它使用urn方案。URN不能用于定位资源。图表中给出的简单示例由命名空间和命名空间特定字符串组成。 -
URI
URI代表统一资源标识符。它标识Web上的逻辑或物理资源。URL和URN是URI的子类型。 URL定位资源,而URN命名资源。
URI由以下部分组成: scheme:[//authority]path[?query][#fragment]
2、数据库与缓存
云服务中不同数据库的便捷速查表
为项目选择合适的数据库是一项复杂的任务。众多的数据库选项,每种都适用于不同的用例,很容易让人产生选择疲劳。
我们希望这份速查表能够为您提供高层次的指引,帮助您找到与项目需求相符的合适服务,避免潜在的问题。
支撑数据库的8种数据结构
答案会根据您的用例而有所不同,下面这些因素都会影响您选择数据库索引格式的决策
- 数据索引,包括内存或磁盘
- 数据格式,包括数字、字符串、地理坐标等
- 系统,可能是写入密集型或读取密集型的
以下是一些用于数据索引的最流行的数据结构:
- Skiplist(跳表): 常见的内存索引类型,在Redis中使用。
- 哈希索引(Hash Index): “映射”数据结构(或“集合”)的常见实现方式。
- SSTable(Sorted String Table): 不可变的磁盘上“映射”实现方式。
- LSM树(Log-Structured Merge Tree): Skiplist + SSTable。具有高写入吞吐量。
- B树(B-Tree): 基于磁盘的解决方案。具有一致的读/写性能。
- 倒排索引(Inverted Index): 用于文档索引。在Lucene中使用。
- 后缀树(Suffix Tree): 用于字符串模式搜索。
- R树(R-Tree): 多维度搜索,例如寻找最近邻居。
SQL语句在数据库中是如何执行的?
图表展示了这个过程。请注意,不同数据库的架构是不同的,这个图表演示了一些常见的设计。
- 第一步 - 通过传输层协议(例如TCP)将SQL语句发送到数据库。
- 第二步 - SQL语句被发送到命令解析器,在那里经过语法和语义分析,然后生成一个查询树。
- 第三步 - 查询树被发送到优化器。优化器创建一个执行计划。
- 第四步 - 执行计划被发送到执行器。执行器从执行中检索数据。
- 第五步 - 访问方法提供了执行所需的数据提取逻辑,从存储引擎中检索数据。
- 第六步 - 访问方法决定SQL语句是否是只读的。如果查询是只读的(SELECT语句),则传递到缓冲管理器进行进一步处理。缓冲管理器在缓存或数据文件中查找数据。
- 第七步 - 如果语句是UPDATE或INSERT,则传递到事务管理器进行进一步处理。
- 第八步 - 在事务期间,数据处于锁定状态。这由锁管理器保证。它还确保了事务的ACID属性。
CAP定理
CAP定理是计算机科学中最著名的术语之一,但我相信不同的开发者对它有不同的理解。让我们来看看它是什么,以及为什么它可能令人困惑。
CAP定理指出,一个分布式系统不能同时提供以下三个特性:
- 一致性(Consistency): 所有客户端无论连接到哪个节点,都能够看到相同的数据。
- 可用性(Availability): 任何请求数据的客户端都能够在某些节点不可用的情况下获得响应。
- 分区容错性(Partition Tolerance): 分区指的是两个节点之间的通信中断。分区容错性意味着系统在网络分区的情况下仍然能够继续运行。
“三选二”这种简化形式确实有其用处,但这种简化也可能引起误解。
- 选择一个数据库并不容易。仅仅基于CAP定理来为选择提供理由是不够的。例如,公司之所以选择Cassandra作为聊天应用的存储系统,并不仅仅是因为它是一个AP系统。Cassandra之所以成为存储聊天消息的理想选择,是因为它具备一系列良好的特性。我们需要进行更深入的研究。
- “CAP只限制了设计空间中的一个小部分:在分区存在的情况下实现完美的可用性和一致性,而这种情况非常罕见。”这是来自于论文《CAP Twelve Years Later: How the “Rules” Have Changed》的引述。
- 该定理是关于100%的可用性和一致性。在没有网络分区的情况下,更现实的讨论应该是在延迟和一致性之间进行权衡。详细内容可以参考PACELC定理。
内存和存储的类型
可视化SQL查询
执行SQL语句涉及多个步骤,包括:
- 解析SQL语句并检查其有效性
- 将SQL转换为内部表示,例如关系代数
- 优化内部表示并创建利用索引信息的执行计划
- 执行计划并返回结果
SQL的执行非常复杂,涉及许多考虑因素,例如:
- 索引和缓存的使用
- 表连接的顺序
- 并发控制
- 事务管理
SQL语言
1986年,SQL(Structured Query Language,结构化查询语言)成为了一个标准。
在接下来的40年里,它成为了关系数据库管理系统中的主导语言。阅读最新的标准(ANSI SQL 2016)可能会耗费很多时间。我该如何学习它呢?
SQL语言有5个主要组成部分:
- DQL(数据查询语言):用于查询数据库中的数据,主要命令是SELECT(选择)。
- DDL(数据定义语言):用于定义数据库结构的语言,如CREATE(创建)、ALTER(修改)、DROP(删除)等。
- DML(数据操作语言):用于操作数据库中的数据,包括INSERT(插入)、UPDATE(更新)、DELETE(删除)等命令。
- DCL(数据控制语言):用于控制数据库访问权限的语言,包括GRANT(授权)、REVOKE(撤销)等命令。
- TCL(事务控制语言):用于管理数据库的事务,包括COMMIT(提交)、ROLLBACK(回滚)等命令。
作为后端工程师,你可能需要了解其中大部分内容。作为数据分析师,你可能需要深入了解DQL。请选择与你最相关的主题进行学习。
数据无处不缓存
在典型架构中我们会在哪些地方缓存数据?
在数据流中有多个层次。
- 客户端应用程序:浏览器可以缓存 HTTP 响应。我们第一次通过 HTTP 请求数据时,会在 HTTP 头中返回一个过期策略;我们再次请求数据时,客户端应用程序会首先尝试从浏览器缓存中检索数据。
- CDN:CDN 缓存静态网络资源。客户端可以从附近的 CDN 节点检索数据。
- 负载均衡器:负载均衡器也可以缓存资源。
- 消息基础设施:消息代理首先将消息存储在磁盘上,然后消费者按自己的节奏检索消息。根据保留策略,数据在 Kafka 集群中缓存一段时间。
- 服务:服务中有多个层次的缓存。如果数据未缓存在 CPU 缓存中,服务将尝试从内存中检索数据。有时服务还有第二级缓存,用于将数据存储在磁盘上。
- 分布式缓存:像 Redis 这样的分布式缓存在内存中保存多个服务的键值对。它比数据库提供更好的读写性能。
- 全文搜索:我们有时需要使用全文搜索,如 Elastic Search 用于文档搜索或日志搜索。数据的副本也被索引在搜索引擎中。
- 数据库:即使在数据库中,我们也有不同级别的缓存:
- WAL(预写式日志):在构建 B 树索引之前,数据首先写入 WAL。
- 缓冲池:分配给缓存查询结果的内存区域。
- 材料化视图:预先计算查询结果并将其存储在数据库表中,以获得更好的查询性能。
- 事务日志:记录所有事务和数据库更新。
- 复制日志:用于记录数据库集群中的复制状态。
Redis 为何如此快速?
有三个主要原因:
- Redis 是基于 RAM 的数据存储。与随机磁盘访问相比,RAM 访问速度至少快 1000 倍。
- Redis 利用 IO 多路复用和单线程执行循环以提高执行效率。
- Redis 利用了几种高效的低级数据结构。
问题:另一个流行的内存存储是 Memcached。您知道 Redis 和 Memcached 之间的区别吗?
- 如果有持久方面的需求或对数据类型和处理有要求的应该选择redis。
- 如果简单的key/value 存储应该选择memcached。
- memcache还可用于缓存其他东西,例如图片、视频等等
- Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储;
- 虚拟内存–Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;
- 灾难恢复–memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;
Redis 可以如何使用?
Redis 不仅仅是缓存。
Redis 可以在各种场景中使用:
- 会话:我们可以使用 Redis 在不同的服务之间共享用户会话数据。
- 缓存:我们可以使用 Redis 缓存对象或页面,特别是热点数据。
- 分布式锁:我们可以使用 Redis 字符串在分布式服务之间获取锁。
- 计数器:我们可以计算文章的点赞数或阅读量。
- 速率限制器:我们可以为特定用户 IP 应用速率限制器。
- 全局 ID 生成器:我们可以使用 Redis Int 作为全局 ID。
- 购物车:我们可以使用 Redis Hash 表示购物车中的键值对。
- 计算用户留存:我们可以使用 Bitmap 表示用户每天的登录情况,并计算用户留存。
- 消息队列:我们可以使用 List 作为消息队列。
- 排名:我们可以使用 ZSet 对文章进行排序。
顶级缓存策略
设计大规模系统通常需要仔细考虑缓存。以下是经常使用的五种缓存策略
3、架构模式
MVC、MVP、MVVM、MVVM-C 和 VIPER
这些架构模式是在应用开发中最常用的,无论是在iOS还是Android平台上。
开发者们引入了这些模式以克服早期模式的局限性。那么,它们有何不同之处呢?
MVC,作为最古老的模式,可以追溯到近50年前。
- 每种模式都有一个“视图”(V),负责显示内容并接收用户输入。
- 大多数模式包括一个“模型”(M),用于管理业务数据。
- “控制器”、“展示者”和“视图模型”是在视图和模型(在VIPER模式中称为“实体”)之间进行调解的翻译器。
每位开发者都应该了解的18个关键设计模式
设计模式是对常见设计问题的可重用解决方案,它们使开发过程更加顺畅、高效。它们充当着构建更好软件结构的蓝图。
以下是一些最受欢迎的设计模式(18个):
- 抽象工厂模式:家族创造者 - 创建相关物品的组合。
- 建造者模式:乐高大师 - 逐步构建对象,保持创建和外观的分离。
- 原型模式:克隆制造者 - 创建完全准备好的示例的副本。
- 单例模式:唯一实例 - 一个只有一个实例的特殊类。
- 适配器模式:通用插头 - 连接具有不同接口的对象。
- 桥接模式:功能连接器 - 将对象的工作方式与其所做的事情链接起来。
- 组合模式:树构建者 - 形成简单和复杂部分的树状结构。
- 装饰器模式:定制者 - 在不改变核心的情况下为对象添加功能。
- 外观模式:一站式购物 - 用单一、简化的接口代表整个系统。
- 享元模式:节省空间 - 高效共享小的可重复使用的物品。
- 代理模式:替身演员 - 代表另一个对象,控制访问或行为。
- 职责链模式:请求中继 - 将请求通过一系列对象传递,直到被处理。
- 命令模式:任务包装 - 将请求转化为一个可执行操作的对象。
- 迭代器模式:集合探险家 - 逐个访问集合中的元素。
- 中介者模式:通信中心 - 简化不同类之间的交互。
- 备忘录模式:时光胶囊 - 捕捉和恢复对象的状态。
- 观察者模式:新闻广播 - 通知类关于其他对象的变化。
- 访问者模式:技艺嘉宾 - 为类添加新操作而不改变它。
4、微服务架构
典型的微服务架构是什么样子的?
典型的微服务架构
- 负载均衡器:将传入的流量分发到多个后端服务。
- CDN(内容分发网络):CDN 是一组地理分布的服务器,保存静态内容以便更快地传递。客户端首先在 CDN 中查找内容,然后转到后端服务。
- API 网关:处理传入的请求并将它们路由到相关服务。它与身份提供者和服务发现进行通信。
- 身份提供者:处理用户的身份验证和授权。
- 服务注册表和发现:微服务的注册和发现发生在此组件中,API 网关在此组件中查找相关服务以进行通信。
- 管理:此组件负责监视服务。
- 微服务:微服务在不同的域中设计和部署。每个域都有自己的数据库。API 网关通过 REST API 或其他协议与微服务进行通信,同一域内的微服务使用 RPC(远程过程调用)相互通信。
微服务的好处:
- 可以快速设计、部署和水平扩展。
- 每个域可以由专门的团队独立维护。
- 由于每个域都可以定制业务需求并得到更好的支持,因此业务需求可以在每个域中得到更好的支持。
微服务最佳实践
开发微服务的 9 个最佳实践。
当我们开发微服务时,需要遵循以下最佳实践:
- 1、为每个微服务使用单独的数据存储
- 2、保持代码处于相似的成熟度水平
- 3、为每个微服务分别构建
- 4、为每个微服务分配单一职责
- 5、部署到容器中
- 6、设计无状态服务
- 7、采用领域驱动设计
- 8、设计微前端
- 9、编排微服务
无状态服务1:
- 无状态服务(stateless service)对单次请求的处理,不依赖其他请求,也就是说,处理一次请求所需的全部信息,要么都包含在这个请求里,要么可以从外部获取到(比如说数据库),服务器本身不存储任何信息
- 有状态服务(stateful service)则相反,它会在自身保存一些数据,先后的请求是有关联的
常用于微服务的技术栈是什么?
微服务技术栈,包括开发阶段和生产阶段
Pre-Production
- 定义 API - 这建立了前端和后端之间的契约。我们可以使用 Postman 或 OpenAPI 来实现。
- 开发 - Node.js 或 React 用于前端开发,Java/Python/Go 用于后端开发。此外,我们需要根据 API 定义更改 API 网关的配置。
- 持续集成 - JUnit 和 Jenkins 用于自动化测试。代码被打包成 Docker 镜像并部署为微服务。
Production
- NGinx 是负载均衡器的常见选择。Cloudflare 提供 CDN(Content Delivery Network 内容分发网络)。
- API 网关 - 我们可以使用 Spring Boot 作为网关,并使用 Eureka/Zookeeper 进行服务发现。
- 微服务部署在云上。我们可以选择 AWS、Microsoft Azure 或 Google GCP。 缓存和全文搜索 - Redis 是缓存键值对的常见选择。Elasticsearch 用于全文搜索。
- 通信 - 为了让服务彼此通信,我们可以使用消息基础设施 Kafka 或 RPC。
- 持久化 - 我们可以使用 MySQL 或 PostgreSQL 作为关系型数据库,Amazon S3 作为对象存储。如果需要,我们也可以使用 Cassandra 作为宽列存储。
- 管理和监控 - 为了管理这么多微服务,常用的运维工具包括Prometheus、Elastic Stack和Kubernetes。
Kafka 为什么快
有许多设计决策为Kafka的性能做出了贡献。
在本文中,我们将专注于其中的两个。我们认为这两个决策起到了最大的作用。
- 第一个决策是Kafka对顺序I/O的依赖。
- 第二个决策让Kafka拥有性能优势的是其专注于效率:零拷贝原则。
零拷贝是一种节省应用程序上下文和内核上下文之间多次数据复制的快捷方式。
生产者和消费者之间的数据传输方式以及零拷贝的含义:
- 步骤1.1-1.3:生产者将数据写入磁盘
- 步骤2:消费者在没有零拷贝的情况下读取数据
2.1 数据从磁盘加载到操作系统缓存中
2.2 数据从操作系统缓存中复制到Kafka应用程序中
2.3 Kafka应用程序将数据复制到套接字缓冲区中
2.4 数据从套接字缓冲区中复制到网络卡中
2.5 网络卡将数据发送给消费者 - 步骤3:消费者使用零拷贝读取数据
3.1:数据从磁盘加载到操作系统缓存中
3.2 操作系统缓存通过sendfile()命令直接将数据复制到网络卡中
3.3 网络卡将数据发送给消费者
5、支付系统
如何学习支付系统?
如何学习支付系统
为什么信用卡被称为“银行最赚钱的产品”?VISA/Mastercard是如何赚钱的?
信用卡支付流程中的经济学:
- 1、持卡人支付100美元给商家购买商品。
- 2、商家通过使用信用卡获得更高的销售额,并需要向发卡行和卡网络提供支付服务进行补偿。收单行与商家签订一个名为“商家贴现费”的收费协议。
- 3-4. 收单行保留0.25美元作为收单成本费,1.75美元作为交换费支付给发卡行。商家贴现费应该覆盖交换费。
由于每个发卡行与每个商家协商费用效率低下,因此卡网络设置了交换费。
- 1、卡网络与每家银行设置网络评估和费用,每月银行向卡网络支付其服务费。例如,VISA每次刷卡收取0.11%的评估费和0.0195美元的使用费。
- 2、持卡人向发卡行支付其服务费用。
为什么发卡行需要获得补偿?
- 持卡人向发卡行支付费用之前,发卡行已向商家支付费用。
- 即使持卡人未向发卡行支付费用,发卡行仍需向商家支付费用。
- 发卡行还有其他运营成本,包括管理客户账户、提供对账单、欺诈检测、风险管理、清算和结算等。
当我们在商家店里刷信用卡时,VISA是如何工作的?
VISA、Mastercard和美国运通是信用卡结算和清算的卡网络。
收单行和发卡行可以是不同的银行。如果银行之间逐笔结算而没有中介,每家银行都必须与其他所有银行结算交易,这是非常低效的。
VISA在信用卡支付流程中的角色。
有两个涉及的流程:1、授权流程发生在客户刷卡时,2、捕获和结算流程发生在商家想要在一天结束时收到钱时。
1、授权流程
- 步骤0:发卡行向其客户发放信用卡。
- 步骤1:持卡人想要购买商品,在商家店内的POS终端刷信用卡。
- 步骤2:POS终端将交易发送至提供POS终端的收单行。
- 步骤3和4:收单行将交易发送至卡网络,也称为卡方案。卡网络将交易发送至发卡行进行批准。
- 步骤4.1、4.2和4.3:如果交易被批准,发卡行会冻结资金。批准或拒绝的结果将返回给收单行和POS终端。
2、捕获和结算流程
- 步骤1和2:商家想要在一天结束时收到钱,因此他们在POS终端上点击“捕获”。交易以批处理方式发送到收单行。收单行将带有交易的批处理文件发送到卡网络。
- 步骤3:卡网络对来自不同收单行的交易进行清算,并将清算文件发送给不同的发卡行。
- 步骤4:发卡行确认清算文件的正确性,并向相关的收单行转移资金。
- 步骤5:收单行然后将资金转移至商家的银行。
- 步骤4:卡网络清理来自不同收单行的交易。清算是一种互相抵消交易的净额过程,因此总交易次数减少。
在此过程中,卡网络承担与每家银行交流的负担,并获得服务费。
世界范围内的支付系统:印度的统一支付接口(UPI)
UPI是由印度国家支付公司开发的即时实时支付系统。
它占印度数字零售交易的60%。
UPI = 支付标记语言 + 可互操作支付标准。
相关文章:
【后端开发】系统设计101——通信协议,数据库与缓存,架构模式,微服务架构,支付系统(36张图详解)
【后端开发】系统设计101——通信协议,数据库与缓存,架构模式,微服务架构,支付系统(36张图) 文章目录 1、通信协议通信协议REST API 对比 GraphQL(前端-web服务)grpc如何工作&#x…...
SpringMVC请求
一、RequestMapping注解 RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系 RequestMapping注解可以作用在方法和类上 1. 作用在类上:第一级的访问目录 2. 作用在方法上:第二级的访问目录 3. 细节:路径可以不编写 / 表示应…...
【学术征稿-组织单位 武汉理工大学西安理工大学、西安财经大学】第三届通信网络与机器学习(CNML 2025)
重要信息 官网:www.iccnml.org 大会时间:2025年2月21日-23日 大会地点:中国 南京 通信网络 通信是人与人之间通过某种媒体进行的信息交流与传递。网络是用物理链路将各个孤立的工作站或主机相连在一起,组成的数据链路。通信网…...
代码随想录算法训练营打卡第55天:并查集相关问题;
Java并查集的模板 //并查集模板 class DisJoint{private int[] father;public DisJoint(int N) {father new int[N];for (int i 0; i < N; i){father[i] i;}}public int find(int n) {return n father[n] ? n : (father[n] find(father[n]));}public void join (int …...
设计模式学习
1.设计模式分类 1.创建型模式 用于描述“怎样创建对象”,主要特点是“将对象的创建与使用分离”。 单例,原型,工厂方法,抽象工厂,建造者 2.结构型模式 用于描述如何将类或对象按某种布局组成更大的结构 代理&…...
js-对象-JSON
JavaScript自定义对象 JSON 概念: JavaScript Object Notation,JavaScript对象标记法. JSON 是通过JavaScript 对象标记法书写的文本。 由于其语法简单,层次结构鲜明,现多用于作为数据载体,在网络中进行数据传输. json中属性名(k…...
C/C++编译器
C/C 代码是不可跨平台的,Windows 和 Unix-like 有着不同的 API,C/C 在不同平台有着不同编译器。 MSVC Windows 平台,MSVC 是 Visual Studio 中自带的 C/C 编译器。 GCC Unix-like 平台,GCC 原名 GNU C Compiler,后…...
【R语言】数据操作
一、查看和编辑数据 1、查看数据 直接打印到控制台 x <- data.frame(a1:20, b21:30) x View()函数 此函数可以将数据以电子表格的形式进行展示。 用reshape2包中的tips进行举例: library("reshape2") View(tips) head()函数 查看前几行数据&…...
Linux 安装 RabbitMQ
Linux下安装RabbitMQ 1 、获取安装包 # 地址 https://github.com/rabbitmq/erlang-rpm/releases/download/v21.3.8.9/erlang-21.3.8.9-1.el7.x86_64.rpm erlang-21.3.8.9-1.el7.x86_64.rpmsocat-1.7.3.2-1.el6.lux.x86_64.rpm# 地址 https://github.com/rabbitmq/rabbitmq-se…...
“AI智能分析综合管理系统:企业管理的智慧中枢
在如今这个快节奏的商业世界里,企业面临的挑战越来越多,数据像潮水一样涌来,管理工作变得愈发复杂。为了应对这些难题,AI智能分析综合管理系统闪亮登场,它就像是企业的智慧中枢,让管理变得轻松又高效。 过去…...
2024最新版Java面试题及答案,【来自于各大厂】
发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全~ 篇幅限制就只能给大家展示小册部分内容了,需要完整版的及Java面试宝典小伙伴点赞转发,关注我后在【翻到最下方,文尾点击名片】即可免费获取…...
调用腾讯云批量文本翻译API翻译srt字幕
上一篇文章介绍了调用百度翻译API翻译日文srt字幕的方法。百度翻译API是get方式调用,参数都放在ur中,每次调用翻译文本长度除了接口限制外,还有url长度限制,而日文字符通过ur转码后会占9个字符长度,其实从这个角度来讲…...
【分块解决大文件上传的最佳实践】
前言 前几天看了一篇关于大文件上传分块实现的博客,代码实现过于复杂且冗长,而且没有进行外网上传的测试。因此,我决定自己动手实现一个大文件上传,并进行优化。 实现思路 在许多应用中,大文件上传是常见的需求&…...
机器学习中的关键概念:通过SKlearn的MNIST实验深入理解
欢迎来到我的主页:【Echo-Nie】 本篇文章收录于专栏【机器学习】 1 sklearn相关介绍 Scikit-learn 是一个广泛使用的开源机器学习库,提供了简单而高效的数据挖掘和数据分析工具。它建立在 NumPy、SciPy 和 matplotlib 等科学计算库之上,支持…...
【Elasticsearch】post_filter
post_filter是 Elasticsearch 中的一种后置过滤机制,用于在查询执行完成后对结果进行过滤。以下是关于post_filter的详细介绍: 工作原理 • 查询后过滤:post_filter在查询执行完毕后对返回的文档集进行过滤。这意味着所有与查询匹配的文档都…...
Git基础
目录 一、Git介绍二、Git下载与配置1、下载安装Git2、Git配置2.1 注册码云账号2.2 Git配置 三、Git开发流程1、相关代码2、上述代码执行截图示例 四、Git提交&撤销五、Git资料 一、Git介绍 Git是一种分布式版本控制系统,广泛用于软件开发项目的版本管理。它由L…...
深度学习系列--02.损失函数
一.定义 损失函数(Loss Function)是机器学习和深度学习中用于衡量模型预测结果与真实标签之间差异的函数,它在模型训练和评估过程中起着至关重要的作用 二.作用 1.指导模型训练 提供优化方向:在训练模型时,我们的目…...
如何在自己mac电脑上私有化部署deep seek
在 Mac 电脑上私有化部署 DeepSeek 的步骤如下: 1. 环境准备 安装 Homebrew(如果尚未安装): Homebrew 是 macOS 上的包管理工具,用于安装依赖。 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com…...
攻防世界 fileclude
代码审计 WRONG WAY! <?php include("flag.php"); highlight_file(__FILE__);//高亮显示文件的源代码 if(isset($_GET["file1"]) && isset($_GET["file2"]))//检查file1和file2参数是否存在 {$file1 $_GET["file1"];$fi…...
Ubuntu24登录PostgreSql数据库的一般方法
命令格式如 psql -U user -d db 或者 sudo psql -U user -d db 修改配置 /etc/postgresql/16/main/postgresql.conf 改成md5,然后重新启动pgsql sudo systemctl restart postgresql...
3.5 Go(特殊函数)
目录 一、匿名函数 1、匿名函数的特点: 2、匿名函数代码示例 2、匿名函数的类型 二、递归函数 1. 递推公式版本 2. 循环改递归 三、嵌套函数 1、嵌套函数用途 2、代码示例 3、作用域 & 变量生存周期 四、闭包 1、闭包使用场景 2、代码示例 五、De…...
设计模式学习(三)
行为模式 职责链模式(Chain of Responsibility Pattern) 定义 它允许多个对象有机会处理请求,从而避免请求的发送者与接收者之间的耦合。职责链模式将这些对象连成一条链,并沿着这条链传递请求,直到有对象处理它为止…...
挑战项目 --- 微服务编程测评系统(在线OJ系统)
一、前言 1.为什么要做项目 面试官要问项目,考察你到底是理论派还是实战派? 1.希望从你的项目中看到你的真实能力和对知识的灵活运用。 2.展示你在面对问题和需求时的思考方式及解决问题的能力。 3.面试官会就你项目提出一些问题,或扩展需求…...
堆(Heap)的原理与C++实现
1. 什么是堆? 堆(Heap)是一种特殊的树形数据结构,通常用于实现优先队列。堆可以分为两种类型: 最大堆(Max Heap):每个节点的值都大于或等于其子节点的值。最小堆(Min H…...
(10) 如何获取 linux 系统上的 TCP 、 UDP 套接字的收发缓存的默认大小,以及代码范例
(1) 先介绍下后面的代码里要用到的基础函数: 以及: (2) 接着给出现代版的 读写 socket 参数的系统函数 : 以及: (3) 给出 一言的 范例代码,获取…...
linux 进程补充
环境变量 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如:我们在编写C/C代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪 里,但是照样可以链接成功&#…...
通过docker安装部署deepseek以及python实现
前提条件 Docker 安装:确保你的系统已经安装并正确配置了 Docker。可以通过运行 docker --version 来验证 Docker 是否安装成功。 网络环境:保证设备有稳定的网络连接,以便拉取 Docker 镜像和模型文件。 步骤一:拉取 Ollama Docker 镜像 Ollama 可以帮助我们更方便地管理…...
vim-plug的自动安装与基本使用介绍
vim-plug介绍 Vim-plug 是一个轻量级的 Vim 插件管理器,它允许你轻松地管理 Vim 插件的安装、更新和卸载。相较于其他插件管理器,vim-plug 的优点是简单易用,速度较快,而且支持懒加载插件(即按需加载) 自动…...
Python 自学秘籍:开启编程之旅,人生苦短,我用python。
从2009年,用了几次python后就放弃了,一直用的php,现在人工智能时代,完全没php什么事情。必须搞python了,虽然已经40多岁了。死磕python了。让滔滔陪着你一起学python 吧。 开启新世界 在当今人工智能化的时代ÿ…...
DRGDIP 2.0时代下基于PostgreSQL的成本管理实践与探索(上)
一、引言 1.1 研究背景与意义 在医疗领域的改革进程中, DRG/DIP 2.0 时代,医院成本管理的重要性愈发凸显。新的医保支付方式下,医院的收入不再单纯取决于医疗服务项目的数量,而是与病种的分组、费用标准以及成本控制紧密相关。这…...
swift 专题三 swift 规范一
一、Swift编码命名规范 对类、结构体、枚举和协议等类型的命名应该采用大驼峰法,如 SplitViewController。 文件名采用大驼峰法,如BlockOperation.swift。 对于扩展文件,有时扩展定义在一个独立的文件中,用“原始类型名 扩展名…...
Vue的状态管理:用响应式 API 做简单状态管理、状态管理库(Pinia )
文章目录 引言单向数据流多个组件共享一个共同的状态I 用响应式 API 做简单状态管理使用 reactive()创建一个在多个组件实例间共享的响应式对象使用ref()返回一个全局状态II 状态管理库Pinia枚举状态管理引言 单向数据流 每一个 Vue 组件实例都在“管理”它自己的响应式状态了…...
排序算法--希尔排序
希尔排序是插入排序的改进版本,适合中等规模数据排序,性能优于简单插入排序。 // 希尔排序函数 void shellSort(int arr[], int n) {// 初始间隔(gap)为数组长度的一半,逐步缩小for (int gap n / 2; gap > 0; gap …...
HAL库 Systick定时器 基于STM32F103EZT6 野火霸道,可做参考
目录 1.时钟选择(这里选择高速外部时钟) 编辑 2.调试模式和时基源选择: 3.LED的GPIO配置 这里用板子的红灯PB5 4.工程配置 5.1ms的systick中断实现led闪烁 源码: 6.修改systick的中断频率 7.systick定时原理 SysTick 定时器的工作原理 中断触发机制 HAL_SYSTICK_Co…...
ESXI虚拟机中部署docker会降低服务器性能
在 8 核 16GB 的 ESXi 虚拟机中部署 Docker 的性能影响分析 在 ESXi 虚拟机中运行 Docker 容器时,性能影响主要来自以下几个方面: 虚拟化开销:ESXi 虚拟化层和 Docker 容器化层的叠加。资源竞争:虚拟机与容器之间对 CPU、内存、…...
前端 | JavaScript中的reduce方法
1. 什么是reduce reduce 方法是 JavaScript 中数组的重要方法之一,用于对数组中的元素进行累积计算。它接收一个回调函数作为参数,并返回一个最终计算结果。reduce 在许多场景下都非常有用,比如求和、数组扁平化、对象计数、数据转换等。 2…...
基于联合概率密度与深度优化的反潜航空深弹命中概率模型研究摘要
前言:项目题材来自数学建模2024年的D题,文章内容为笔者和队友原创,提供一个思路。 摘要 随着现代军事技术的发展,深水炸弹在特定场景下的反潜作战效能日益凸显,如何最大化的发挥深弹威力也成为重要研究课题。本文针对评估深弹投掷落点对命中潜艇概率的影响进行分析,综合利…...
将OneDrive上的文件定期备份到移动硬盘
背景: 我在oneDrive上存了很多文件,分布在多个文件夹中,也有套了好几层文件夹的情况。我希望每隔一段时间,将oneDrive上的所有文件向移动硬盘上拷贝一份,但是我只想将距离上一次向移动硬盘拷贝的文件相比,发…...
01vue3实战-----前言
01vue3实战-----前言 1.大前端时代2.技术栈3.项目大致展示4.创建Vue项目4.1Vue CLI4.2create-vue 5.参考资料 1.大前端时代 前端移动端iOS/android开发桌面端 window/mac 常用的electron框架来开发其它平台:穿戴设备、车载系统(智能汽车)、VR、AR…web3方向 2.技术栈 开发工…...
SQL 秒变三线表 sql导出三线表
🎯SQL 秒变三线表,校园小助手超神啦 宝子们,搞数据分析、写论文的时候,从 SQL 里导出数据做成三线表是不是特别让人头疼😩 手动调整格式,不仅繁琐,还容易出错,分分钟把人逼疯&#…...
C_位运算符及其在单片机寄存器的操作
C语言的位运算符用于直接操作二进制位,本篇简单结束各个位运算符的作业及其在操作寄存器的应用场景。 一、位运算符的简单说明 1、按位与运算符(&) 功能:按位与运算符对两个操作数的每一位执行与操作。如果两个对应的二进制…...
Rust错误处理:从灭火器到核按钮的生存指南
开篇:错误处理的生存哲学 在Rust的平行宇宙里,错误分为两种人格: panic! → 核按钮💣(不可恢复,全系统警报)Result → 灭火器🧯(可控制,局部处理࿰…...
YK人工智能(六)——万字长文学会基于Torch模型网络可视化
1. 可视化网络结构 随着深度神经网络做的的发展,网络的结构越来越复杂,我们也很难确定每一层的输入结构,输出结构以及参数等信息,这样导致我们很难在短时间内完成debug。因此掌握一个可以用来可视化网络结构的工具是十分有必要的…...
对象的实例化、内存布局与访问定位
一、创建对象的方式 二、创建对象的步骤: 一、判断对象对应的类是否加载、链接、初始化: 虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化…...
Java面试题2025-并发编程进阶(线程池和并发容器类)
线程池 一、什么是线程池 为什么要使用线程池 在开发中,为了提升效率的操作,我们需要将一些业务采用多线程的方式去执行。 比如有一个比较大的任务,可以将任务分成几块,分别交给几个线程去执行,最终做一个汇总就可…...
Vue Router 客户端路由解决方案:axios 响应拦截(跳转到登录页面)
文章目录 引言客户端路由 vs. 服务端路由简单的路由案例术语I Vue Router 提供的组件RouterLinkRouterViewII 创建路由器实例调用 createRouter() 函数创建路由选项III 注册路由器插件通过调用 use() 来完成注册路由器插件的职责对于组合式 API,Vue Router 给我们提供了一些组…...
Redis的通用命令
⭐️前言⭐️ 本文主要介绍Redis的通用命令 🍉欢迎点赞 👍 收藏 ⭐留言评论 🍉博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言 🍉博客中涉及源码及博主日常练习代码均已上传GitHub 📍内容导…...
[Python人工智能] 四十九.PyTorch入门 (4)利用基础模块构建神经网络并实现分类预测
从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解PyTorch构建回归神经网络。这篇文章将介绍如何利用PyTorch构建神经网络实现分类预测,其是使用基础模块构建。前面我们的Python人工智能主要以TensorFlow和Keras为主,而现在最主流的深度学习框…...
SpringBoot使用 easy-captcha 实现验证码登录功能
文章目录 一、 环境准备1. 解决思路2. 接口文档3. redis下载 二、后端实现1. 引入依赖2. 添加配置3. 后端代码实现4. 前端代码实现 在前后端分离的项目中,登录功能是必不可少的。为了提高安全性,通常会加入验证码验证。 easy-captcha 是一个简单易用的验…...
RabbitMQ 从入门到精通:从工作模式到集群部署实战(一)
#作者:闫乾苓 文章目录 RabbitMQ简介RabbitMQ与VMware的关系架构工作流程RabbitMQ 队列工作模式及适用场景简单队列模式(Simple Queue)工作队列模式(Work Queue)发布/订阅模式(Publish/Subscribeÿ…...