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

Go支付中台方案:多平台兼容与多项目对接

一、中台的概念

中台是一种企业级的架构模式,它处于前台应用和后台资源之间,将企业核心能力进行整合、封装,形成一系列可复用的业务能力组件。这些组件就像乐高积木一样,可以被不同的前台业务快速调用,从而避免重复开发,提高业务创新和响应速度。中台的核心思想是数据共享、能力复用,通过将通用的业务逻辑和数据处理抽取出来,为企业的数字化转型提供坚实的架构基础。

二、使用支付中台的意义和价值

(一)提高支付系统的复用性

在企业的业务场景中,往往存在多个需要支付功能的项目,如各种类型的电商应用、游戏项目、企业内部的管理系统等。如果没有支付中台,每个项目都需要独立开发支付模块,这不仅会导致大量的重复工作,而且不同项目中的支付模块可能存在差异,增加了维护成本和难度。而支付中台将支付相关的核心功能进行统一封装,各个项目可以直接复用这些功能,大大提高了开发效率,减少了代码冗余。

(二)提升支付业务的敏捷性和创新能力

市场环境变化迅速,支付方式和业务需求也在不断更新。使用支付中台,企业可以在中台层面快速响应这些变化,对支付功能进行升级和优化,而无需在每个使用支付功能的项目中逐一修改。例如,当新的支付平台出现或者支付安全标准提高时,只需在支付中台进行调整,所有依赖中台的项目都能受益。这种敏捷性使得企业能够更快地推出新的支付业务模式,满足用户多样化的需求,增强市场竞争力。

(三)保障支付数据的一致性和安全性

支付数据的处理和存储是支付系统的关键环节。不同项目独立处理支付数据可能会导致数据不一致的问题,例如订单状态在不同系统中的不同步。支付中台通过统一的数据管理和处理机制,确保支付数据在各个项目中的一致性。同时,中台可以集中实施安全策略,如对支付请求的加密、对支付平台 API 密钥的安全存储和管理等,有效降低支付安全风险,保护用户和企业的利益。

(四)降低系统的复杂性和耦合度

在没有中台的情况下,各个项目与不同支付平台的对接会使整个系统变得非常复杂,项目之间以及项目与支付平台之间的耦合度很高。支付中台作为一个中间层,将项目与支付平台解耦,对外提供统一的支付接口给各个项目,对内负责与不同支付平台的对接和交互。这样,每个项目只需要关注自身的业务逻辑和与支付中台的交互,无需了解支付平台的具体细节,降低了系统的复杂性,提高了系统的可维护性。

三、支付中台的设计目标

(一)多支付平台支持

全面支持微信支付、支付宝支付等主流支付方式。这要求系统能够精确处理不同支付平台的支付请求,包括但不限于参数解析、签名验证、发起支付以及处理支付回调等操作,从而确保支付流程的顺畅性和安全性,为用户提供可靠的支付体验。

(二)多项目对接能力

  1. 针对其他 Go 应用项目,提供简洁、规范且易于集成的接口。这些接口应充分遵循 Go 语言的编程风格和设计模式,确保代码的可读性、可维护性以及可扩展性,方便 Go 应用快速接入支付功能。
  2. 对于游戏项目,考虑到游戏内支付具有小额高频、与虚拟货币系统交互等特殊需求,支付中台需具备高度的灵活性,能够在不影响游戏流畅性和用户体验的前提下,高效处理支付事务。
  3. 在与 Java 管理系统对接时,通过合适的通信协议(如 RESTful API)实现数据的准确交互。确保 Java 系统能够方便地发起支付请求,并及时获取支付结果,实现跨语言项目的协同工作。

(三)高性能与高可靠性

支付中台需要在高并发的支付请求环境下保持高性能运行,确保快速响应。同时,必须保证支付过程的可靠性,避免出现支付失败、数据丢失或不一致等问题,切实保障用户和商家的利益。

四、设计模式的选择

(一)工厂模式

在处理不同支付平台的支付请求时,工厂模式发挥着关键作用。以下是一个简单的工厂模式示例代码:

// PaymentProcessor 是支付处理器接口
type PaymentProcessor interface {ProcessPayment(paymentRequest PaymentRequest) error
}// PaymentRequest 包含支付请求的信息
type PaymentRequest struct {Amount   float64Platform string// 其他支付相关信息
}// WeChatPaymentProcessor 微信支付处理器结构体
type WeChatPaymentProcessor struct{}// ProcessPayment 实现微信支付处理逻辑
func (wp *WeChatPaymentProcessor) ProcessPayment(paymentRequest PaymentRequest) error {// 微信支付处理逻辑,如调用微信支付 API 等return nil
}// AlipayPaymentProcessor 支付宝支付处理器结构体
type AlipayPaymentProcessor struct{}// ProcessPayment 实现支付宝支付处理逻辑
func (ap *AlipayPaymentProcessor) ProcessPayment(paymentRequest PaymentRequest) error {// 支付宝支付处理逻辑,如调用支付宝支付 API 等return nil
}// PaymentProcessorFactory 支付处理器工厂结构体
type PaymentProcessorFactory struct{}// CreatePaymentProcessor 根据支付平台类型创建相应的支付处理器
func (f *PaymentProcessorFactory) CreatePaymentProcessor(platform string) PaymentProcessor {switch platform {case "wechat":return &WeChatPaymentProcessor{}case "alipay":return &AlipayPaymentProcessor{}default:return nil}
}

通过这种方式,根据支付平台类型(如 “wechat” 或 “alipay”)创建相应的支付处理器对象,将不同支付平台的处理逻辑解耦,便于后续的扩展和维护。当需要添加新的支付平台时,只需在工厂类的CreatePaymentProcessor方法中添加相应的创建逻辑即可。

(二)策略模式

对于不同的支付策略(如扫码支付、APP 内支付等),策略模式是一种理想的选择。

以下是一个简单的策略模式示例:

// PaymentStrategy 支付策略接口
type PaymentStrategy interface {Pay(paymentInfo PaymentInfo) error
}// ScanCodePayment 扫码支付策略结构体
type ScanCodePayment struct{}// Pay 实现扫码支付逻辑
func (s *ScanCodePayment) Pay(paymentInfo PaymentInfo) error {// 扫码支付处理逻辑return nil
}// InAppPayment APP 内支付策略结构体
type InAppPayment struct{}// Pay 实现 APP 内支付逻辑
func (i *InAppPayment) Pay(paymentInfo PaymentInfo) error {// APP 内支付处理逻辑return nil
}// PaymentContext 支付上下文结构体,用于执行支付策略
type PaymentContext struct {strategy PaymentStrategy
}// SetStrategy 设置支付策略
func (pc *PaymentContext) SetStrategy(strategy PaymentStrategy) {pc.strategy = strategy
}// ExecutePayment 执行支付操作
func (pc *PaymentContext) ExecutePayment(paymentInfo PaymentInfo) error {return pc.strategy.Pay(paymentInfo)
}

每个支付策略都实现PaymentStrategy接口,在运行时根据用户选择或业务逻辑选择合适的支付策略。这种设计模式使得支付中台能够灵活应对各种支付场景,并且方便对每个支付策略进行单独的测试和优化。

(三)外观模式

在对接不同类型的项目(Go 应用、游戏项目、Java 管理系统等)时,外观模式可创建一个统一的接口层。以下是一个简单的外观模式示例:

// PaymentFacade 支付外观结构体
type PaymentFacade struct {paymentProcessorFactory *PaymentProcessorFactory
}// NewPaymentFacade 创建支付外观实例
func NewPaymentFacade() *PaymentFacade {return &PaymentFacade{paymentProcessorFactory: &PaymentProcessorFactory{},}
}// ProcessPayment 通过外观模式处理支付请求
func (pf *PaymentFacade) ProcessPayment(paymentRequest PaymentRequest) error {processor := pf.paymentProcessorFactory.CreatePaymentProcessor(paymentRequest.Platform)if processor == nil {return fmt.Errorf("unsupported payment platform")}return processor.ProcessPayment(paymentRequest)
}

这个接口层隐藏了支付中台内部复杂的实现细节,对外提供简单、一致的接口。不同类型的项目只需与这个外观接口进行交互,大大降低了项目集成支付功能的难度。

五、开发框架的选择

(一)Go 的 Web 框架:Gin (最主流的框架)

Gin 是一款轻量级且高性能的 Go Web 框架,非常适合构建支付中台的 API 服务。其核心优势在于快速的路由功能和强大的中间件支持。

以下是使用 Gin 构建支付中台 API 的基本示例代码:

package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {router := gin.Default()// 定义支付请求处理路由router.POST("/payment", func(c *gin.Context) {var paymentRequest PaymentRequestif err := c.ShouldBindJSON(&paymentRequest); err!= nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}// 使用支付外观处理支付请求paymentFacade := NewPaymentFacade()if err := paymentFacade.ProcessPayment(paymentRequest); err!= nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, gin.H{"message": "Payment processed successfully"})}router.Run(":8080")
}

咱们仍然使用目前闪送项目的running-server-pro的框架做开发,区别是新启动一个支付中台的项目。

在支付中台开发中,利用 Gin 来处理来自不同项目的支付请求。它可以接收 HTTP 请求、解析请求参数,然后调用相应的支付处理逻辑,并返回结果。通过中间件,可以轻松实现一些通用的功能,如身份验证、请求日志记录、错误处理等。

(二)数据库框架:GORM

支付中台需要妥善存储支付相关的数据,如订单信息、支付记录等。GORM 作为一个功能强大的 Go 语言 ORM 框架,支持多种数据库(如 MySQL、PostgreSQL 等),为数据库操作提供了极大的便利。

以下是使用 GORM 创建订单模型和进行基本数据库操作的示例代码:

package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// Order 订单结构体
type Order struct {gorm.ModelOrderNumber string  `gorm:"unique"`Amount      float64Status      string// 其他订单相关字段
}func main() {// 连接数据库db, err := gorm.Open(mysql.Open("user:password@tcp(127.0.0.1:3306)/payment_db?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{})if err!= nil {panic("failed to connect database")}// 自动迁移订单表db.AutoMigrate(&Order{})// 创建新订单示例newOrder := Order{OrderNumber: "20241117001",Amount:      100.0,Status:      "pending",}db.Create(&newOrder)// 查询订单示例var order Orderdb.Where("order_number =?", "20241117001").First(&order)
}

使用 GORM 可以方便地进行数据库操作,如创建表、插入数据、查询数据等。同时,GORM 还提供了模型关联、事务处理等高级功能,有助于保证支付数据的完整性和一致性。

六、支付中台的核心功能模块

(一)支付请求处理模块

  1. 接收来自不同项目的支付请求,通过 Gin 框架解析请求中的支付信息,包括支付金额、支付平台、支付方式、订单编号等。
  2. 根据支付平台类型,利用工厂模式创建相应的支付处理器,然后调用支付处理器的支付方法,发起支付请求。在这个过程中,要处理可能出现的各种错误,如网络问题、支付平台接口返回错误等,并将错误信息以合适的格式反馈给发起支付请求的项目。
  3. 以下是支付请求处理模块的简化代码示例:
func handlePaymentRequest(c *gin.Context) {var paymentRequest PaymentRequestif err := c.ShouldBindJSON(&paymentRequest); err!= nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}paymentFacade := NewPaymentFacade()if err := paymentFacade.ProcessPayment(paymentRequest); err!= nil {c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})return}c.JSON(http.StatusOK, gin.H{"message": "Payment processed successfully"})
}

(二)支付结果回调处理模块

  1. 接收支付平台的支付结果回调,首先验证回调的合法性,如进行签名验证等操作。
  2. 根据回调结果更新支付状态,例如将订单状态从 “支付中” 更新为 “已支付” 或 “支付失败”。同时,通过合适的方式(如消息队列、HTTP 通知等)通知相关项目支付结果,以便它们进行后续的业务处理,如发货、更新用户账户余额等。
  3. 以下是支付结果回调处理模块的部分代码示例:
func handlePaymentCallback(c *gin.Context) {var callbackData PaymentCallbackDataif err := c.ShouldBindJSON(&callbackData); err!= nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}if!verifyCallbackSignature(callbackData) {c.JSON(http.StatusForbidden, gin.H{"error": "Invalid callback signature"})return}// 根据回调数据更新订单状态updateOrderStatus(callbackData)// 通知相关项目支付结果notifyRelatedProjects(callbackData)c.JSON(http.StatusOK, gin.H{"message": "Callback processed successfully"})
}

(三)订单管理模块

  1. 负责订单的创建、查询、更新和删除等操作。当接收到支付请求时,创建相应的订单记录,并将订单信息存储到数据库中。可以使用 GORM 框架来实现订单数据的持久化操作。
  2. 提供订单查询接口,方便其他项目查询订单状态。同时,在支付结果回调处理时,根据支付结果更新订单状态。以下是订单创建和查询的示例代码:
func createOrder(paymentRequest PaymentRequest) (*Order, error) {newOrder := Order{OrderNumber: generateOrderNumber(),Amount:      paymentRequest.Amount,Status:      "pending",}db.Create(&newOrder)return &newOrder, nil
}func getOrderByNumber(orderNumber string) (*Order, error) {var order Orderdb.Where("order_number =?", orderNumber).First(&order)return &order, nil
}

(四)配置管理模块

  1. 存储支付中台的配置信息,如各个支付平台的 API 密钥、回调地址、支付参数等。可以将配置信息存储在配置文件(如 JSON 格式或 YAML 格式)中,或者使用环境变量来存储敏感信息。
  2. 提供配置的读取和更新功能,以便在需要时修改支付平台相关的配置,同时保证配置信息的安全性。对于敏感信息,如 API 密钥,要进行加密存储和安全传输。以下是读取配置文件的示例代码(假设使用 JSON 格式配置文件):
type PaymentConfig struct {WeChatConfig WeChatConfig `json:"wechat"`AlipayConfig AlipayConfig `json:"alipay"`// 其他配置项
}type WeChatConfig struct {AppID     string `json:"app_id"`APIKey    string `json:"api_key"`Callback  string `json:"callback"`// 其他微信支付相关配置
}type AlipayConfig struct {AppID     string `json:"app_id"`APIKey    string `json:"api_key"`Callback  string `json:"callback"`// 其他支付宝支付相关配置
}func readConfig() (*PaymentConfig, error) {data, err := ioutil.ReadFile("payment_config.json")if err!= nil {return nil, err}var config PaymentConfigif err := json.Unmarshal(data, &config); err!= nil {return nil, err}return &config, nil
}

七、与不同项目的对接实现

(一)与 Go 应用项目对接

在 Go 应用项目中,通过引入支付中台的 Go 包,使用 Go 语言的依赖管理工具(如 Go Modules)来管理依赖。以下是对接示例:

package mainimport ("fmt""your_payment_middleware_package"
)func main() {paymentRequest := your_payment_middleware_package.PaymentRequest{Amount:   50.0,Platform: "wechat",// 其他支付信息,如订单号等OrderID: "202411170001", }paymentFacade := your_payment_middleware_package.NewPaymentFacade()err := paymentFacade.ProcessPayment(paymentRequest)if err!= nil {fmt.Printf("支付失败: %v\n", err)return}fmt.Println("支付成功")
}

(二)与游戏项目对接

  1. 游戏内支付流程 对于游戏内支付,游戏服务器充当与支付中台交互的桥梁。游戏客户端发起支付请求后,游戏服务器收集支付相关信息,如玩家 ID、支付金额、购买的虚拟物品信息等,并构建支付请求发送给支付中台。
  2. 代码示例 以下是游戏服务器处理支付请求的简化代码:
package mainimport ("your_payment_middleware_package""log"
)func handleGamePayment(playerID string, itemID string, amount float64) {paymentRequest := your_payment_middleware_package.PaymentRequest{Amount:   amount,Platform: "wechat", // 假设游戏主要使用微信支付,可根据玩家选择调整OrderID:  generateOrderID(playerID, itemID), // 根据玩家和物品生成唯一订单号// 其他游戏相关支付信息,如游戏内订单描述等Description: fmt.Sprintf("购买游戏物品 %s", itemID), }paymentFacade := your_payment_middleware_package.NewPaymentFacade()err := paymentFacade.ProcessPayment(paymentRequest)if err!= nil {log.Printf("玩家 %s 支付失败: %v", playerID, err)// 通知游戏客户端支付失败,可回滚游戏内相关操作,如不扣除虚拟货币notifyGameClient(playerID, false) return}// 支付成功,更新游戏内玩家数据,如增加虚拟物品、扣除虚拟货币updatePlayerData(playerID, itemID) notifyGameClient(playerID, true)
}

(三)与 Java 管理系统对接

  1. 通过 RESTful API 实现对接 支付中台提供一组 RESTful 接口,Java 管理系统通过 HTTP 请求调用这些接口来发起支付请求和获取支付结果。在 Java 端,可以使用 Java 的 HTTP 客户端库(如 Apache HttpClient 或 OkHttp 等)来发送请求,并处理支付中台返回的 JSON 格式的结果数据。
  2. 代码示例(使用 Apache HttpClient)
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.google.gson.Gson;public class PaymentClient {public static void main(String[] args) {try {CloseableHttpClient httpClient = HttpClients.createDefault();HttpPost httpPost = new HttpPost("http://your_payment_middleware_server/payment");PaymentRequest paymentRequest = new PaymentRequest();paymentRequest.setAmount(100.0);paymentRequest.setPlatform("alipay");paymentRequest.setOrderID("202411170002");Gson gson = new Gson();String json = gson.toJson(paymentRequest);StringEntity entity = new StringEntity(json);httpPost.setEntity(entity);httpPost.setHeader("Content-Type", "application/json");CloseableHttpResponse response = httpClient.execute(httpPost);HttpEntity responseEntity = response.getEntity();if (response.getStatusLine().getStatusCode() == 200) {String result = EntityUtils.toString(responseEntity);PaymentResponse paymentResponse = gson.fromJson(result, PaymentResponse.class);if (paymentResponse.isSuccess()) {System.out.println("支付成功");} else {System.out.println("支付失败: " + paymentResponse.getErrorMessage());}} else {System.out.println("请求支付中台失败");}} catch (Exception e) {e.printStackTrace();}}
}class PaymentRequest {private double amount;private String platform;private String orderID;// 生成对应的getter和setter方法public double getAmount() {return amount;}public void setAmount(double amount) {this.amount = amount;}public String getPlatform() {return platform;}public void setPlatform(String platform) {this.platform = platform;}public String getOrderID() {return orderID;}public void setOrderID(String orderID) {this.orderID = orderID;}
}class PaymentResponse {private boolean success;private String errorMessage;// 生成对应的getter和setter方法public boolean isSuccess() {return success;}public void setSuccess(boolean success) {this.success = success;}public String getErrorMessage() {return errorMessage;}public void setErrorMessage(String errorMessage) {this.errorMessage = errorMessage;}
}

八、安全与性能优化

(一)安全措施

  1. 数据传输加密 在支付请求和结果回调过程中,使用 SSL/TLS 协议对数据进行加密传输,防止数据在网络传输过程中被窃取或篡改。对于支付中台与支付平台之间的交互,确保使用符合安全标准的加密方式。
  2. API 密钥管理 对各个支付平台的 API 密钥进行严格的安全存储。可以将密钥存储在加密的配置文件中,或者使用专门的密钥管理系统。在运行时,仅在需要时解密和使用密钥,并且限制对密钥存储区域的访问权限,防止内部泄露。
  3. 输入验证和安全防护 在支付中台内部,对所有接收的输入数据进行严格验证,防止恶意攻击,如 SQL 注入、跨站脚本攻击(XSS)等。对于用户输入的支付金额、订单号等信息,进行格式和范围检查。同时,使用安全的编码实践,如对输出数据进行编码,避免在前端显示时出现安全漏洞。

(二)性能优化

  1. 并发处理优化 利用 Go 语言的高并发特性,对支付请求进行并发处理。例如,使用goroutinechannel机制来实现异步处理支付请求,提高系统的吞吐量。但在并发处理过程中,要注意资源的合理利用和并发安全问题,如使用互斥锁来保护共享资源,避免数据竞争。
  2. 数据库性能优化 对支付相关数据的存储操作进行优化。合理设计数据库表结构,根据查询和业务逻辑创建合适的索引。例如,对订单表的订单号、支付状态等经常查询的字段建立索引,提高查询效率。同时,可以采用缓存机制来缓存一些常用的数据,如支付平台的配置信息、频繁查询的订单状态等,减少数据库的查询压力,提高系统的响应速度。
  3. 性能测试与监控 定期对支付中台进行性能测试,模拟高并发的支付场景,使用性能测试工具(如 Gatling 等)来检测系统的响应时间、吞吐量等性能指标。同时,建立完善的监控系统,实时监控支付中台的运行状态,包括服务器资源使用情况、支付请求处理情况等,及时发现性能瓶颈并进行优化。

九、结论

通过合理选择设计模式和开发框架,开发一个基于 Go 语言的支付中台,可以有效地支持微信、支付宝等主流支付平台,并能方便地与多个类型的项目进行对接。在开发过程中,注重安全和性能的优化是至关重要的,这可以满足商业环境中对支付系统的高要求,为用户和商家提供稳定、高效、安全的支付服务,推动企业数字化业务的顺利开展。同时,支付中台的架构应具有一定的灵活性和可扩展性,以适应未来支付业务的发展和变化。

十、交流讨论

大家有什么问题和建议,请直接评论留言这篇方案,我会继续优化。

集思广益,一起进步!

欢迎关注 ❤

我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。

没准能让你能刷到自己意向公司的最新面试题呢。

感兴趣的朋友们可以私信我:面试

相关文章:

Go支付中台方案:多平台兼容与多项目对接

一、中台的概念 中台是一种企业级的架构模式,它处于前台应用和后台资源之间,将企业核心能力进行整合、封装,形成一系列可复用的业务能力组件。这些组件就像乐高积木一样,可以被不同的前台业务快速调用,从而避免重复开…...

设计模式:23、享元模式

目录 0、定义 1、享元模式的三种角色 2、享元模式的UML类图 3、示例代码 0、定义 运营共享技术有效地支持大量细粒度的对象 1、享元模式的三种角色 享元接口(Flyweight):是一个接口,该接口定义了享元对外公开其内部数据的方…...

如何使用靜態IP代理?【詳細教程】

靜態IP地址是手動分配給設備或伺服器的固定不變的 IP。與動態 IP 地址不同,動態 IP 地址由 DHCP 伺服器自動分配,並且會隨時間而變化。​​​​​​​ 如何獲取和設置靜態IP地址 一、檢查是否需要靜態IP? 在配置靜態 IP 之前,請…...

C++day3

1、把课上类的三个练习题的构造函数写出来 #include <iostream> #include <cstring>using namespace std;class Car {string color;string brond;double speed; public:Car(string c,string b,double s):color("black"),brond("Benz"),speed(…...

ABAP开发-批量导入BAPI和BDC_1

系列文章目录 文章目录 系列文章目录[TOC](文章目录) 前言一、概念二、BDC和BAPI数据导入1、BDC数据导入&#xff08;录屏&#xff09;2、BAPI数据导入 三、实例1、BAPI2、BDC 总结 前言 一、概念 SAP中&#xff0c;对一个事务码反复操作并且达到批量处理数据的效果&#xff0…...

iOS 语音循环播放设置

本地文件、网络文件&#xff0c;区别就是URL创建方式 1、使用AVPlayerItem与AVPlayer&#xff08;这个简单&#xff0c;只需要设置回调&#xff09;&#xff0c;而不是AVAudioPlayer&#xff08;这个麻烦&#xff0c;需要设置代理、计时器等等&#xff09; 2、设置AVPlayerIte…...

PlantUML——类图

背景 类图是UML模型中的静态视图&#xff0c;其主要作用包括&#xff1a; 描述系统的结构化设计&#xff0c;显示出类、接口以及它们之间的静态结构和关系。简化对系统的理解&#xff0c;是系统分析与设计阶段的重要产物&#xff0c;也是系统编码和测试的重要模型依据。 在U…...

ASP.NET Core实现鉴权授权的几个库

System.IdentityModel.Tokens.Jwt 和 Microsoft.AspNetCore.Authentication.JwtBearer 是两个常用的库&#xff0c;分别用于处理 JWT&#xff08;JSON Web Token&#xff09;相关的任务。它们在功能上有一定重叠&#xff0c;但侧重点和使用场景有所不同。 1. System.IdentityM…...

生成:安卓证书uniapp

地址&#xff1a; https://ask.dcloud.net.cn/article/35777 // 使用keytool -genkey命令生成证书&#xff1a; 官网&#xff1a; keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore ----------------------------------…...

探索Web3:从去中心化应用到全球数字化未来

Web3 是互联网发展的下一步&#xff0c;它通过去中心化的理念重新定义了数字世界。与传统的Web2相比&#xff0c;Web3将数据主权交还给用户&#xff0c;让每个人都可以在没有中介的情况下安全地交换信息和价值。本文将探索Web3的基本概念&#xff0c;去中心化应用&#xff08;D…...

AR向左,AI向右,智能眼镜来到十字路口

从Google Glass到Vision Pro&#xff0c;人类对智能眼镜的探索有进展&#xff0c;但都不算成功&#xff0c;直至Ray-Ban Meta的出现&#xff0c;这才让行业对智能眼镜重燃信心&#xff0c;从去年开始&#xff0c;随着AI大模型应用的深入&#xff0c;智能眼镜又有了新的故事可说…...

CTF靶场搭建及Web赛题制作与终端docker环境部署

写在前面 ╔══════════════════════════════════════════════════════════════════════════╗ 哈喽大家好&#xff01;我是Myon&#xff0c;趁着我的云服务器还没过期&#xff0c;这次给大家出一…...

Java 应用程序CPU 100%问题排查优化实战

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

计网(王道的总结)-数据链路层-网络层-传输层

由于时间有限&#xff0c;把每个王道的章节最后一节放在一起&#xff0c;分别看看复习知识点。 3.6.4 IEEE 802.11 无线局域网 重点&#xff1a; 3.7 广域网 真题考频&#xff1a;极低 3.8以太网交换机 4.1网络层的功能 4.2.1IPv4分组 最重要的&#xff1a; TTL&#xff1a;…...

1-4 C单向链表

目录 1.0 基本概念 2.0 初始化链表 2.0 插入数据 3.0 删除数据 4.0 获取链长度 5.0 查询链表 6.0 返回第一个节点 7.0 打印链表节点 8.0 释放内存 9.0 链表调用 1.0 基本概念 线性表的顺序存储&#xff1a;用一块连续的内存空间&#xff0c;线性表的链式存储&#xff…...

在Windows 10中使用SSH远程连接服务器(附花生壳操作方法)

SSH 在 linux 中是一种重要的系统组件&#xff0c;用户可以使用 SSH 来远程连接 linux 系统的计算机&#xff0c;或者传输文件。不过在 win10 以前&#xff0c;windows 并不原生支持 SSH&#xff0c;需要借助第三方工具来使用 SSH 功能。而实际上&#xff0c;微软在 2015 年就曾…...

韶音科技嵌入式面试题及参考答案

Bootloader 的启动流程是什么&#xff1f; Bootloader 是在操作系统内核运行之前运行的一段小程序。它的启动流程主要分为以下几个阶段。 首先是硬件初始化阶段。这个阶段会对处理器以及一些关键的硬件设备进行初始化。比如&#xff0c;会配置处理器的工作模式、设置堆栈指针等…...

C++ ——— 类的 6 个默认成员函数之 构造函数

目录 何为默认成员函数 一、构造函数 构造函数的概念 构造函数的特性 日期类的构造函数 栈的构造函数 编译器自动生成的构造函数 总结 何为默认成员函数 默认成员函数就是用户没有显示实现&#xff0c;但是编译器会自动生成的成员函数称为默认成员函数 一、构造函数 …...

【优选算法篇】:揭开二分查找算法的神秘面纱--数据海洋中的精准定位器

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;c篇–CSDN博客 文章目录 一.二分查找算法二.算法模板模板一模板二模板三 三.例题演练1.x的平…...

【机器学习算法】——数据可视化

1. 饼图&#xff1a;显示基本比例关系 import matplotlib.pyplot as pltplt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False# ——————————————————————————————————————————————————————…...

比特币与区块链原理解析:矿机挖矿与去中心化的未来

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

SpringBoot教程(十四) SpringBoot之集成Redis

SpringBoot教程&#xff08;十四&#xff09; | SpringBoot之集成Redis 一、Redis集成简介二、集成步骤 2.1 添加依赖2.2 添加配置2.3 项目中使用之简单使用 &#xff08;举例讲解&#xff09;2.4 项目中使用之工具类封装 &#xff08;正式用这个&#xff09;2.5 序列化 &…...

Qt之第三方库QCustomPlot使用(二)

Qt开发 系列文章 - qcustomplot&#xff08;二&#xff09; 目录 前言 一、Qt开源库 二、QCustomPlot 1.qcustomplot介绍 2.qcustomplot下载 3.qcustomplot移植 4.修改项目文件.pro 5.提升QWidget类‌ 三、技巧讲解 1.拖动缩放功能 2.等待更新 总结 前言 Qt第三方…...

机器学习决策树原理详解

一、引言 在当今蓬勃发展的人工智能与大数据领域&#xff0c;大模型正以前所未有的影响力改变着众多行业的格局。而决策树作为机器学习算法家族中的经典成员&#xff0c;以其简洁直观的特点和广泛的适用性&#xff0c;不仅能独立解决诸多实际问题&#xff0c;更是诸多先进大模…...

深入探索JavaScript循环语句:从基础到高级应用

深入探索JavaScript循环语句&#xff1a;从基础到高级应用 在前端开发中&#xff0c;JavaScript 的循环语句是构建动态和交互式网页的关键工具。本文将全面介绍 JavaScript 中的几种主要循环语句&#xff0c;包括 for、while、do...while 以及 for...in 和 for...of&#xff0…...

从0开始深度学习(35)——YOLO V5原理详解

以YOLO V5s为例&#xff0c;介绍YOLO V5的网络结构&#xff0c;以及其中具体的功能模块 1 YOLO V5的整体网络结构 YOLO V5网络结构分为四个部分&#xff1a; 输入端&#xff1a; 输入端负责对输入图像进行预处理&#xff0c;包括数据增强、锚框计算等。骨干网络&#xff08;Ba…...

高级数据库模式设计与性能优化

数据库模式设计不仅仅是创建表和字段那么简单&#xff0c;还需要考虑数据的一致性、性能优化、安全性和可扩展性等多个方面。本文将深入探讨数据库模式设计的高级技巧&#xff0c;并提供一个实际的例子来展示如何在项目中应用这些技巧。 1. 数据库模式设计的高级技巧 1.1 多对…...

【开源免费】基于SpringBoot+Vue.JS图书进销存管理系统(JAVA毕业设计)

博主说明&#xff1a;本文项目编号 T 082 &#xff0c;文末自助获取源码 \color{red}{T082&#xff0c;文末自助获取源码} T082&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…...

监控易助力扩容1000个点位

铁路交通作为城市发展的重要动脉&#xff0c;其IT系统的稳定运行对于保障铁路运输的安全与高效至关重要。近期&#xff0c;四川某铁路用户为了进一步提升IT基础资源的监控和管理水平&#xff0c;决定对现有的运维体系进行扩容升级&#xff0c;引入了监控易一体化运维软件&#…...

克服大规模语言模型限制,构建新的应用方法——LangChain

大模型 大模型的出现和落地开启了人工智能(AI)新一轮的信息技术革命&#xff0c;改变了人们的生 活方式、工作方式和思维方式。大模型的落地需要数据、算力和算法三大要素。经过几 年发展&#xff0c;大模型的数据集(包括多模态数据集)制作已经形成了规约&#xff0c;Meta、Go…...

MacOS 下 pico/pico2 学习笔记

1.安装开发工具 cmake brew install cmakeopenocd brew install openocdarm-none-eabi-gcc 用 brew 安装的版本会出现如下错误&#xff1a; arm-none-eabi-gcc: fatal error: cannot read spec file nosys.specs: No such file or directory用 arm 官方的版本没有问题。 cd …...

Leetcode 每日一题 1.两数之和

目录 问题描述 示例 示例 1 示例 2 示例 3 提示 解决方案 算法思路 过题图片 代码实现 复杂度分析 注意事项 题目链接 结论 问题描述 给定一个整数数组 nums 和一个目标值 target&#xff0c;请你找出数组中和为目标值的那两个整数&#xff0c;并返回它们的数组下…...

柯桥职场商务英语生活英语口语培训外贸纺织口语学习

"等一下"该怎么说&#xff1f; 大家应该都知道&#xff0c;wait a moment是一个祈使句&#xff0c;祈使句就难免带有命令的口吻&#xff0c;还有点不耐烦。 如果你把“等一下”说成wait a moment&#xff0c;外国人多半认为你是个傲慢无礼的人。毕竟在他们看来wait a…...

ElasticSearch如何做性能优化?

大家好&#xff0c;我是锋哥。今天分享关于【ElasticSearch如何做性能优化&#xff1f;】面试题。希望对大家有帮助&#xff1b; ElasticSearch如何做性能优化&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Elasticsearch 中&#xff0c;性能优化是…...

深度学习常用损失函数介绍

均方差损失&#xff08;Mean Square Error&#xff0c;MSE&#xff09; 均方误差损失又称为二次损失、L2损失&#xff0c;常用于回归预测任务中。均方误差函数通过计算预测值和实际值之间距离&#xff08;即误差&#xff09;的平方来衡量模型优劣。即预测值和真实值越接近&…...

PSHuman 部署笔记

目录 github地址&#xff1a; 依赖项&#xff1a; xformers安装&#xff1a; 解决方法&#xff0c;安装xformers smpl_data下载&#xff1a; 推理步骤&#xff1a; SMPLDataset 香港科技大学提出了一种叫PSHuman的新框架。这个方法利用了一个多视角扩散模型的“先验知识…...

怎么样能使Ubuntu的文件浏览器显示当前目录的路径,而不是只显示一个文件名?

默认情况下Ubuntu的文件浏览器是只显示当前目录的目录名的&#xff0c;这很不便我们查看路径或直接利用路径进行定位&#xff0c;那么怎么样能使Ubuntu的文件浏览器显示当前目录的路径呢&#xff1f; 两种方法&#xff1a; 第1种-临时方法 按下快捷键 Ctrl L&#xff0c;导航…...

自回归模型(AR )

最近看到一些模型使用了自回归方法&#xff0c;这里就学习一下整理一下相关内容方便以后查阅。 自回归模型&#xff08;AR &#xff09; 自回归模型&#xff08;AR &#xff09;AR 模型的引入AR 模型的定义参数的估计方法模型阶数选择平稳性与因果性条件自相关与偏自相关函数优…...

工具推荐-js爬取工具

现在测试方向都偏向于从js中的接口来入手找到可以进的点&#xff0c;关于快速扫描js文件来发现敏感接口的工具有很多&#xff0c;下面的jjjjs就是其一 项目地址: GitHub - ttstormxx/jjjjjjjjjjjjjs: 爬网站JS文件&#xff0c;自动fuzz api接口&#xff0c;指定api接口&#x…...

CSS学习记录05

CSS外边距 CSS margin属性用于在任何定义的边框之外&#xff0c;为元素周围创建空间。通过CSS&#xff0c;您可以完全控制外边距&#xff0c;一些属性可用于设置元素每侧&#xff08;上、右、下和左&#xff09;的外边距。 Margin - 单独的边 CSS拥有用于为元素的每一侧指定…...

差异基因富集分析(R语言——GOKEGGGSEA)

接着上次的内容&#xff0c;上篇内容给大家分享了基因表达量怎么做分组差异分析&#xff0c;从而获得差异基因集&#xff0c;想了解的可以去看一下&#xff0c;这篇主要给大家分享一下得到显著差异基因集后怎么做一下通路富集。 1.准备差异基因集 我就直接把上次分享的拿到这…...

ISO 45001 职业健康安全管理体系的实施具有多方面的重要意义

对企业的意义 提升企业形象&#xff1a;实施 ISO 45001 体系体现了企业对员工职业健康安全的重视和承诺&#xff0c;有助于树立良好的企业形象&#xff0c;增强企业在社会公众、客户、投资者等方面的认可度和美誉度&#xff0c;提升企业的市场竞争力。增强员工满意度和忠诚度&a…...

HarmonyOS-中级(三)

文章目录 合理使用动画和转场Web组件和WebView给应用添加通知和提醒 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;HarmonyOS专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月08日12点12分 合理使用动画和转场 动效场景设计&#x…...

报错:Invalid HTTP method: PATCH executing PATCH http://XXX.XXX

分析&#xff1a; 问题在于我使用feignclietn调用PatchMapping方法时&#xff0c;发送的 PATCH 请求方法出现了不匹配的情况。虽然说springboot自带了RESTful风格的方法&#xff08;GET、POST、PUT、DELETE、PATCH&#xff0c;但是PATCH相较于前几个来说算是新的HTTP方法&#…...

Open WebUI项目源码学习记录(从0开始基于纯CPU环境部署一个网页Chat服务)

感谢您点开这篇文章:D&#xff0c;鼠鼠我是一个代码小白&#xff0c;下文是学习开源项目Open WebUI过程中的一点笔记记录&#xff0c;希望能帮助到你&#xff5e; 本人菜鸟&#xff0c;持续成长&#xff0c;能力不足有疏漏的地方欢迎一起探讨指正&#xff0c;比心心&#xff5e…...

WPF Prism 01-BootstrapperShell

Prism介绍 Prism 是一个用于在 WPF、.NET MAUI、Uno 平台和 Xamarin Forms 中构建松耦合、可维护和可测试的 XAML 应用程序的框架。每个平台都有单独的发布版本&#xff0c;并且这些版本将在独立的开发时间线上进行开发。Prism 提供了一组设计模式的实现&#xff0c;这些模式有…...

在Ubuntu22.04 jammy下用qemu模型riscv32环境装鸿蒙(未完成,待续)

在使用实体ESP32C3 安装鸿蒙失败后&#xff0c;就是这个&#xff1a;完全按照手册win10里装Ubuntu 虚拟机然后编译ESP32&#xff08;主要是想针对ESP32C3和S3&#xff09;开发板的鸿蒙系统(失败)-CSDN博客转向用qemu模拟环境装鸿蒙 学习手册riscv32_virt/README_zh.md OpenHar…...

第2章:CSS基本语法 --[CSS零基础入门]

CSS(层叠样式表,Cascading Style Sheets)是用来描述HTML或XML(包括各种XML:SVG, MathML 或 XHTML)等文档的外观和格式的语言。以下是CSS的基本语法: 1.选择器 1.元素选择器 元素选择器是基于HTML标签名称来选择元素的。当你使用元素选择器时,你是在告诉浏览器对页面…...

win11 恢复任务栏copilot图标, 亲测有效

1、修改C:\Windows\System32\IntegratedServicesRegionPolicySet.json&#xff0c;解除中国不能使用copilot的限制。 使用Notepad搜索copilot全文搜索&#xff0c;将下面两处的“CN,”删除&#xff0c;删除后如下&#xff1a; {"$comment": "Show Copilot on t…...

Python爬虫实战:抓取拼多多商品详情数据(基于pdd.item_get接口)

在当前的电商市场中&#xff0c;拼多多以其独特的拼团模式和优惠价格吸引了大量用户&#xff0c;成为继淘宝、京东之后的又一大电商平台。对于数据分析和市场研究者来说&#xff0c;获取拼多多的商品详情数据显得尤为重要。本文将介绍如何使用Python爬虫技术&#xff0c;通过调…...