ByteByteGo学习笔记:通知系统设计
引言
在当今这个信息爆炸的时代,通知系统已经成为了现代应用程序中不可或缺的重要组成部分。无论是突发新闻的即时推送、产品更新的及时告知、促销活动的精准触达,还是用户交互的实时反馈,通知都扮演着至关重要的角色。一个高效、可靠、可扩展的通知系统,不仅能够提升用户体验,增强用户粘性,还能有效地传递关键信息,驱动业务增长。
本文将深入探讨如何设计一个可扩展的通知系统,涵盖了从需求分析、高层设计到详细设计的各个环节,并着重强调了系统的可靠性、可扩展性、安全性以及其他关键的设计考量。
第一步:理解问题并确定设计范围
在任何系统设计的初期阶段,最重要的一步都是深刻理解问题和明确设计范围。对于通知系统而言,其功能看似简单——发送通知,但实际上,要构建一个能够发送数百万条通知的可扩展系统,其背后涉及到诸多复杂的技术细节和架构选择。
- 通知类型: 系统需要支持推送通知 (移动端 - iOS, Android, 桌面端 - 笔记本/台式机)、短信 和 电子邮件 三种主流通知形式。这三种形式各有特点,适用场景也不同,例如,推送通知更适合实时性要求高的场景,短信和邮件则更适用于非实时但需要保证送达的场景。
- 实时性: 系统被定义为 软实时系统。这意味着系统应尽可能快速地发送通知,但允许在系统高负载情况下出现轻微延迟。这种定义平衡了实时性需求和系统性能的考量,为后续设计提供了灵活性。
- 支持设备: 系统需要覆盖 iOS 设备、Android 设备以及 笔记本电脑/台式机。这要求系统需要能够兼容不同的平台和设备,并针对不同平台的特性进行适配。
- 触发方式: 通知可以由 客户端应用程序 触发,也可以在 服务器端 触发。这表明通知系统需要支持多种触发机制,以满足不同的业务场景需求。例如,用户行为可以触发客户端通知,而定时任务或系统事件可以触发服务器端通知。
- 用户选择退出: 系统必须允许用户 选择退出 接收通知。这体现了对用户隐私和选择权的尊重,也是现代应用程序设计的基本原则。选择退出机制需要在设计中予以充分考虑,并确保用户能够方便地管理自己的通知偏好。
- 日均发送量:1000万条移动推送通知、100万条短信和 500万封电子邮件。这些指标直接关系到系统的容量规划、性能优化和成本控制。高并发、大吞吐量是可扩展通知系统需要重点解决的问题。
通过以上问题的梳理,我们对通知系统的需求和设计范围有了清晰的认识,这为后续的高层设计奠定了坚实的基础。
第二步:提出高层设计并获得认可
在高层设计阶段,我们需要勾勒出系统的整体架构,明确各个组件的功能和交互关系。高层设计方案,清晰地展示了支持各种通知类型 (iOS 推送通知、Android 推送通知、短信和电子邮件) 的基本框架。其核心结构可以概括为以下三个方面:
1. 不同类型的通知
首先从技术层面剖析了各种通知类型的工作原理。
-
iOS 推送通知 (APNs): iOS 推送通知依赖于 Apple 推送通知服务 (APNs)。发送流程涉及三个关键组件:
- 提供者 (Provider): 负责构建通知请求,包括设备令牌 (Device Token) 和负载 (Payload)。负载是一个 JSON 字典,可以包含通知的标题、内容、徽章 (Badge) 等信息。
- APNs: 苹果官方提供的远程服务,负责将推送通知通过 “Apple to device” 协议传播到 iOS 设备。
- iOS 设备: 最终接收并展示推送通知的终端设备。
-
Android 推送通知 (FCM): Android 推送通知流程与 iOS 类似,但通常使用 Firebase 云消息传递 (FCM) 作为推送服务,而非 APNs。FCM 提供了跨平台的消息传递解决方案,也支持 Web 和 iOS 平台。
-
短信 (SMS): 短信服务通常会借助于第三方服务提供商,例如 Twilio、Nexmo 等。这些服务商提供了 API 接口,方便开发者集成短信发送功能。选择第三方服务可以降低自建短信网关的复杂度和成本,并通常能获得更好的送达率和功能支持。
-
电子邮件 (Email): 电子邮件服务同样可以自建邮件服务器,但更多公司倾向于选择商业电子邮件服务,如 SendGrid、Mailchimp 等。商业邮件服务在送达率、反垃圾邮件、数据分析等方面通常更具优势。
2. 联系信息收集流程
要成功发送通知,首先需要收集用户的联系信息,包括移动设备令牌、电话号码和电子邮件地址。
当用户首次安装或注册应用程序时,API 服务器负责收集用户联系信息,并将这些信息存储到数据库中。
这是一个简化的数据库表结构,用于存储联系信息。user
表存储用户的电子邮件地址和电话号码,device
表则存储设备令牌。一个用户可以拥有多个设备,这意味着可以向用户的所有设备发送推送通知。这种一对多的关系模型,支持多设备场景下的通知触达。
3. 通知发送/接收流程 (高层设计)
该设计方案的核心是一个 通知系统 组件,作为整个通知流程的中心枢纽。
- 服务 1 到 N: 代表各种需要发送通知的业务服务,例如,计费服务、电商平台、社交应用等。这些服务通过调用通知系统提供的 API 来触发通知发送。
- 通知系统: 核心组件,负责接收来自各个服务的通知请求,并将其转发给相应的第三方服务。初始设计中,所有通知处理逻辑都集中在一个通知服务器上。
- 第三方服务: 负责实际的通知发送,例如 APNs, FCM, 短信服务商, 邮件服务商等。
初始设计的局限性
虽然初始设计方案简洁明了,但也存在一些明显的局限性:
- 单点故障 (SPOF): 所有通知相关的组件都集中在一个服务器上,一旦该服务器发生故障,整个通知系统将瘫痪。
- 难以扩展: 随着业务增长,通知量不断增加,单一服务器在数据库、缓存和通知处理组件的扩展方面都面临挑战。垂直扩展 (Scale-Up) 终究有瓶颈,水平扩展 (Scale-Out) 在这种架构下也较为困难。
- 性能瓶颈: 通知处理和发送本身是资源密集型任务,例如构建 HTML 邮件、等待第三方服务响应等。在高并发场景下,单一服务器容易成为性能瓶颈,导致系统过载。
高层设计 (改进)
改进的核心在于引入了 消息队列、缓存 和 独立的数据库,并采用了 水平扩展 的策略。
- 消息队列 (Message Queue): 引入消息队列 (如 Kafka, RabbitMQ) 作为系统组件之间的缓冲层,实现了服务之间的 解耦。消息队列可以应对突发流量,平滑峰值,并提高系统的 异步处理能力 和 可靠性。不同类型的通知事件 (iOS PN, Android PN, SMS, Email) 可以分别进入不同的消息队列,实现更精细化的管理和隔离,避免单一类型的通知服务故障影响全局。
- 缓存 (Cache): 引入缓存 (如 Redis, Memcached) 用于存储用户信息、设备信息、通知模板等 高频访问但相对静态的数据。缓存可以显著提升数据读取速度,降低数据库负载,提高系统性能。
- 独立的数据库 (DB): 将数据库从通知服务器中分离出来,并可以采用 集群部署 或 分库分表 等技术,提升数据库的 可扩展性 和 可靠性。
- 通知服务器集群 (Notification Servers): 采用 水平扩展 策略,部署多个通知服务器实例,并通过 负载均衡 (Load Balancer) 将请求分发到不同的服务器实例。这显著提升了系统的 并发处理能力 和 可用性。
- Worker: 引入 Worker 组件,负责从消息队列中消费通知事件,并调用相应的第三方服务发送通知。Worker可以水平扩展,根据消息队列的积压情况动态调整Worker数量,实现 弹性伸缩。
改进后的高层设计流程
- 服务调用通知服务器 API: 业务服务通过调用通知服务器提供的 API 发送通知请求。API 设计需要考虑安全性,例如采用 内部 API 或 认证机制,防止恶意请求或垃圾邮件。
- 通知服务器元数据提取: 通知服务器接收到请求后,首先进行 基本验证 (例如,验证邮箱格式、电话号码格式等),然后从 缓存 或 数据库 中提取渲染通知所需的元数据,例如用户信息、设备令牌、通知设置等。
- 事件推送至消息队列: 通知服务器将通知事件推送到相应的 消息队列 (例如,iOS PN 队列, SMS 队列等)。
- Worker消费队列事件: Worker 组件从消息队列中拉取通知事件。
- Worker调用第三方服务发送通知: Worker根据事件类型,调用相应的 第三方服务 (APNs, FCM, 短信/邮件服务商) 发送通知。
第三步:设计深入
在高层设计的基础上,我们需要进一步深入探讨系统的细节设计,包括可靠性、附加组件以及其他重要的设计考量。
可靠性
可靠性是通知系统设计的核心要素之一。用户期望能够及时、准确地收到重要通知,任何数据丢失或延迟都可能影响用户体验甚至业务运营。
-
如何防止数据丢失?: 为了确保通知数据不丢失,系统需要做到 数据持久化 和 实现重试机制。
-
数据持久化: 将通知数据 (如图11 所示的 “通知日志数据库” 中的数据) 存储到数据库中,即使系统发生故障,数据也不会丢失,可以用于后续的重试或审计。
-
重试机制: 当通知发送失败时 (例如,第三方服务故障、网络异常等),系统需要具备 自动重试 的能力。重试机制需要考虑重试策略 (例如,指数退避、最大重试次数等),避免无限重试导致系统压力过大。
-
每个接收者是否恰好接收一次通知?: 在分布式系统中,由于网络延迟、消息重复等因素,很难保证 精确的一次性交付 (Exactly-Once Delivery)。通知系统 无法保证每个接收者恰好接收一次通知,但可以通过 去重机制 (Deduplication) 来 减少重复通知的发生。
-
去重机制: 一种简单的去重逻辑是 基于事件 ID。当通知事件触发时,首先检查事件 ID 是否已经处理过。如果已经处理过,则丢弃该事件;否则,发送通知并记录事件 ID。更复杂的去重机制可能需要借助分布式锁或状态管理系统。
附加组件和考量因素
除了核心的发送流程,一个完善的通知系统还需要考虑许多附加组件和因素,以提升用户体验、系统效率和可维护性。
-
通知模板 (Notification Templates): 对于大型通知系统,每天需要发送数百万条通知,其中很多通知的格式和结构是相似的。引入 通知模板 可以实现 模板复用,避免重复构建相似的通知,提高效率,并保持通知格式的一致性。
短信通知模板的示例:
你梦想的[ITEM NAME]回来了——仅此[DATE]。 CTA: 现在下单,或保存我的[ITEM NAME]。
通知模板可以使用占位符 (例如
[ITEM NAME]
,[DATE]
) 来表示动态参数,在发送通知时,将这些占位符替换为实际的内容。 -
通知设置 (Notification Settings): 用户通常会收到大量的通知,过多的通知容易引起用户的反感。因此,为用户提供 精细化的通知设置选项 至关重要。用户可以根据自己的偏好,选择接收哪些类型的通知,以及通过哪些渠道接收通知。
通知设置表的字段示例:
user_id
: 用户 IDchannel
: 通知渠道 (推送通知, 电子邮件, 短信)opt_in
: 用户是否选择接收该渠道的通知 (Boolean)rate_limiting
: 频率限制设置 (可选)
系统在发送通知前,需要 首先检查用户的通知设置,尊重用户的选择。
-
安全推送通知 (Secure Push Notifications): 对于推送通知,安全性至关重要。为了防止未授权的访问和滥用,需要采取安全措施。对于 iOS 和 Android 应用,可以使用
apnscert
和appsecret
进行 API 鉴权,只有经过身份验证的客户端才能通过 API 发送推送通知。 -
监控队列通知 (Monitoring Queue Notifications): 监控 是保证系统稳定运行的关键手段。对于通知系统,队列积压情况 是一个重要的监控指标。如果队列积压量过大,意味着通知事件处理速度跟不上产生速度,可能导致通知延迟。监控队列长度,并根据情况 动态调整Worker数量,可以有效避免通知延迟。
-
事件跟踪 (Event Tracking): 为了了解通知的 效果 和 用户行为,需要进行 事件跟踪。例如,追踪通知的 打开率、点击率、用户参与度 等指标。这些数据对于分析用户行为、优化通知内容和策略都非常有价值。通知系统需要与 分析服务 集成,将事件数据上报给分析服务进行处理和展示。
-
速率限制 (Rate Limiting): 为了防止系统被滥用 (例如,恶意发送大量垃圾邮件或短信),以及保护用户免受过多的通知打扰,需要实施 速率限制。速率限制可以针对不同的维度进行,例如,限制单个用户在单位时间内接收的通知数量,限制单个 IP 地址在单位时间内发送的通知请求数量等。
最终设计
整合所有上述组件和考量因素后,最终的通知系统设计。与之前的设计相比,最终设计更加完善和健壮,考虑了可靠性、安全性、监控、用户设置和速率限制等关键方面。
总结
构建一个可扩展的通知系统,需要重点关注以下几个方面:
- 需求明确: 深入理解业务需求,明确通知类型、实时性要求、支持设备、触发方式、用户偏好以及性能指标等。
- 架构合理: 采用分布式架构,引入消息队列、缓存、独立的数据库和通知服务器集群,提升系统的可扩展性、可靠性和性能。
- 可靠性保障: 实施数据持久化和重试机制,最大程度地减少数据丢失,并采用去重机制降低重复通知的概率。
- 功能完善: 提供通知模板、用户通知设置、安全推送、队列监控和事件跟踪等附加组件,提升用户体验和系统管理能力。
- 安全性考量: 采用 API 鉴权等安全措施,防止系统被滥用。
- 用户体验至上: 尊重用户选择,提供精细化的通知设置,并实施速率限制,避免过度打扰用户。
参考资料
ByteByteGo
相关文章:
ByteByteGo学习笔记:通知系统设计
引言 在当今这个信息爆炸的时代,通知系统已经成为了现代应用程序中不可或缺的重要组成部分。无论是突发新闻的即时推送、产品更新的及时告知、促销活动的精准触达,还是用户交互的实时反馈,通知都扮演着至关重要的角色。一个高效、可靠、可扩…...
[设计模式]1_设计模式概览
摘要:设计模式原则、设计模式的划分与简要概括,怎么使用重构获得设计模式并改善代码的坏味道。 本篇作概览与检索用,后续结合源码进行具体模式深入学习。 目录 1、设计模式原理 核心原则(语言无关) 本质原理图 原…...
Python + Qt Designer构建多界面GUI应用程序:Python如何调用多个界面文件
引言 Qt Designer是一个用户友好的图形用户界面设计工具,它可以帮助开发人员通过拖放的方式快速创建界面。在实际开发中,往往需要设计多个界面文件,并在Python代码中进行统一管理和使用。本文将介绍如何在Python中使用Qt Designer设计好的多…...
AGI大模型(7):提示词应用
1 生成数据 LLM具有⽣成连贯⽂本的强⼤能⼒。使⽤有效的提示策略可以引导模型产⽣更好、更⼀致和更真实的响应。LLMs还可以特别有⽤地⽣成数据,这对于运⾏各种实验和评估⾮常有⽤。例如,我们可以使⽤它来为情感分类器⽣成快速样本,如下所示: 提示: ⽣成10个情感分析的范…...
【倒霉bug2025】找不到vc_runtimeMinimum_x64.msi
今天是倒霉的一天,当喉咙痛到无法出门玩耍的我打开steam准备开始玩《冰封世界》时,游戏启动直接报错 在选择安装之后弹出一个经典窗口 然后在C:\ProgramData\PackageCache中找msi到位置点击确定继续报错说msi版本不对 上网一搜,找不到vc_ru…...
什么是强哈希算法pbkdf2(Password-Based Key Derivation Function)
文章目录 什么是pbkdf2使用场景 在线工具 什么是pbkdf2 维基百科:https://zh.wikipedia.org/zh-cn/PBKDF2 PBKDF2(Password-Based Key Derivation Function 2)是一种基于密码的密钥派生函数。它的主要作用是从密码和盐(salt&…...
Python 基础语法详解
一、变量和数据类型 变量 在 Python 中,变量无需声明类型,直接赋值即可。变量名区分大小写。 # 整数类型 age 25 print(age) # 输出:25# 浮点数类型 height 1.75 print(height) # 输出:1.75# 字符串类型 name "张三&…...
AI Agent 时代开幕-Manus AI与OpenAI Agent SDK掀起新风暴
【本周AI新闻: AI Agent 时代开幕-Manus AI与OpenAI Agent SDK掀起新风暴】 https://www.bilibili.com/video/BV1bkQyYCEvQ/?share_sourcecopy_web&vd_source32ed33e1165d68429b2e2eb4749f3f26 最近AI圈子里最火的话题非Manus莫属!这款由中国武汉创业公司“蝴…...
为什么会出现redis数据库?redis是什么?
什么是 Redis? 为什么要用 Redis? 下面我将从 Redis 出现的背景、Redis 的解决方案个来回答。 1、Redis 出现的背景 互联网的应用越来越多,例如社交网络、电商、实时服务发展的十分迅速,这就导致了传统技术栈(如关系型数据库)…...
每日一题---dd爱框框(Java中输入数据过多)
dd爱框框 实例: 输入: 10 20 1 1 6 10 9 3 3 5 3 7 输出: 3 5 这道题要解决Java中输入的数过多时,时间不足的的问题。 应用这个输入模板即可解决: Java中输入大量数据 import java.util.*; import java.io.*;pu…...
Flink-学习路线
最近想学习一下Flink,公司的实时需求还是不少的,因此结合ai整理了一份学习路线,记录一下。 当然,公司也有Scala版本Flink框架,也学习了一下。这里只说Java版本 1. Java基础 目标: 掌握Java编程语言的基础知识。 内容…...
一次Milvus迁移的记录
前言 希望把Linux上生产环境中使用docker compose运行的milvus迁移到本地(mac os)的docker compose中 操作过程 找到了官方有两个相关的项目: https://github.com/zilliztech/milvus-backup https://github.com/zilliztech/vts 但是…我都没用,因为使…...
矩阵的转置
对于的矩阵,使用两个指针变量,可以方便实现(i,j)处元素与(j,i)处元素交换位置。令指针Arow&A[i][0],则Arow[j]可实现对第i行j列元素的访问。令指针Bptr&A[0][i],则*Bptr就可以访问(0,i)处元素,然后,…...
使用 VLOOKUP 和条件格式在 Excel 中查找并标红匹配的串号
使用 VLOOKUP 和条件格式在 Excel 中查找并标红匹配的串号 你的步骤非常详细且清晰,能够帮助用户在 Excel 中通过 VLOOKUP 和条件格式来查找并标红匹配的串号。以下是对你提供的步骤的简要总结和补充说明: 1. 添加“是否匹配”列 在 a.xlsx 中新增一列…...
Python Matplotlib面试题精选及参考答案
目录 绘制函数 y=2x+5 在区间 [1,10] 的折线图,设置标题和坐标轴标签 在同一图中绘制 sin (x) 和 cos (x) 曲线,添加图例和网格线(x∈[0,2π]) 绘制分段函数:当 x<0 时 y=0,x≥0 时 y=x,设置不同线段颜色 绘制带数据点的折线图,使用红色虚线样式和圆形标记(数据…...
在线 SQL 转 SQLAlchemy:一键生成 Python 数据模型
一款高效的在线 SQL 转 SQLAlchemy 工具,支持自动解析 SQL 语句并生成 Python SQLAlchemy 模型代码,适用于数据库管理、后端开发和 ORM 结构映射。无需手写 SQLAlchemy 模型,一键转换 SQL 结构,提升开发效率,简化数据库…...
基于自定义线程池手写一个异步任务管理器
我们在后端执行某些耗时逻辑操作时往往会导致长时间的线程阻塞,在这种情况之下,我们往往会引一条异步线程去处理这些异步任务,如果每次都创建新的线程来处理这些任务,不仅会增加代码冗余,还可能造成线程管理混乱&#…...
基恩士PLC编程小技巧八:脚本过长如何实现换行及替换
基恩士PLC编程小技巧八:脚本过长如何实现换行? 一、问题点 我们在使用基恩士编程软件KV STUDIO 进行脚本编程时,经常遇到这样的问题:脚本的一行过长,程序不好阅读及维护。 IF MR1000 OR MR1001 OR MR1002 OR MR1003 OR…...
每日一题---数组中两个字符串的最小距离
数组中两个字符串的最小距离 给定一个字符串数组strs,再给定两个字符串str1和str2,返回在strs中str1和str2的最小距离,如果str1或str2为null,或不在strs中,返回-1。 链接:数组中两个字符串的最小距离__牛…...
【PTA题目解答】7-1利用STL比较数据大小并排序(15分)c++
1.题目: 2.算法原理 根据题目要求,模拟即可,set容器会帮我们把插入的数自动排序好 题目说输入非整型数据就停止,不用特意判断输入的数据是整型还是非整型,如果用户输入的是字符(例如 a)&#…...
如何用Deepseek制作流程图?
使用Deepseek制作流程图,本质上是让AI根据你的需求,生成相关流程图的代码,然后在流程图编辑器中渲染,类似于Python一样,ChatGPT可以生成代码,但仍需在IDE中执行。 你知道绘制流程图最高效的工具是什么吗&a…...
【09】单片机编程核心技巧:变量赋值,从定义到存储的底层逻辑
【09】单片机编程核心技巧:变量赋值,从定义到存储的底层逻辑 🌟 核心概念 单片机变量的定义与赋值是程序设计的基础,其本质是通过 RAM(随机存储器) 和 ROM(只读存储器) 的协作实现…...
vscode python相对路径的问题
vscode python相对路径的问题 最近使用使用vscode连接wsl2写python时,经常遇到找不到包中的方法的问题,最终发现vscode在执行python代码时目录不是从当前python文件开始算起,而是从当前工作区的目录开始算起,比如说我打开的是/ho…...
C语言中的指针与函数
引言 在C语言编程中,指针是一个非常重要且强大的概念。它不仅帮助我们高效地管理内存,还能提升程序的灵活性和性能。而指针与函数的结合使用,是C语言中非常常见且极具挑战性的一个话题。正确理解和使用指针与函数的关系,不仅能帮助程序员提高代码质量,还能优化程序的执行…...
深度学习-服务器训练SparseDrive过程记录
1、cuda安装 1.1 卸载安装失败的cuda 参考:https://blog.csdn.net/weixin_40826634/article/details/127493809 注意:因为/usr/local/cuda-xx.x/bin/下没有卸载脚本,很可能是apt安装的,所以通过执行下面的命令删除: a…...
理解langchain langgraph 官方文档示例代码中的MemorySaver
以下是langchain v0.3官方示例代码 from langgraph.checkpoint.memory import MemorySaver from langgraph.graph import START, MessagesState, StateGraph# 可以理解为:定义一个流程,这个流程中用到的数据类型是Messages。 <---定义一个有向图&…...
JumpServer基础功能介绍演示
堡垒机可以让运维人员通过统一的平台对设备进行维护,集中的进行权限的管理,同时也会对每个操作进行记录,方便后期的溯源和审查,JumpServer是由飞致云推出的开源堡垒机,通过简单的安装配置即可投入使用,本文…...
Spring @Bean注解使用场景二
bean:最近在写一篇让Successfactors顾问都能搞明白的sso的逻辑的文章,所以一致在研究IAS的saml2.0的协议,希望用代码去解释SP、idp的一些概念,让顾问了解SSO与saml的关系,在github找代码的时候发现一些代码的调用关系很难理解&…...
创业者认知、思辨、成长指南
一、为什么要创业? 1、因为没有家产继承和家庭关系,不能躺平; 比如父母留下了大量的财富,靠钱生钱吃利息,收租,做做投资这些形式,就可以活得很好; 再比如父母或者血亲有资源&#…...
ECharts中Map(地图)样式配置、渐变色生成
前言 ECharts是我们常用的图表控件,功能特别强大,每次使用都要查API比较繁琐,这里就记录开发中常用的配置。 官网:https://echarts.apache.org/handbook/zh/get-started 配置项:https://echarts.apache.org/zh/opti…...
PostgreSQL存储管理体系结构学习笔记2
1.表和元组的组织方式 在PostgreSQL中,同一个表中的元组按照创建顺序依次插入到表文件中。元组之间不进行关联,这样的表文件称之为堆文件。PostgreSQL系统中包含了四种堆文件:普通堆,临时堆,序列,TOAST表。…...
【PTA题目解答】7-3 字符串的全排列(20分)next_permutation
1.题目 给定一个全由小写字母构成的字符串,求它的全排列,按照字典序从小到大输出。 输入格式: 一行,一个字符串,长度不大于8。 输出格式: 输出所有全排列,每行一种排列形式,字典序从小到大。 输入样例…...
SOME/IP:用Python实现协议订阅、Offer、订阅ACK与报文接收
文章目录 前言一、代码层次二、详细代码1. eth_scapy_sd.py2、eth_scapy_someip.py3、network_define.py4、packet_define.py5、unpack_define.py6、someip_controller.py 前言 1、需要pip安装scapy库 2、需要修改根据实际情况配置network_define.py 3、执行someip_controller…...
嵌入式八股ARM篇
前言 ARM篇主要介绍一下寄存器和中断机制,至于汇编这一块…还请大家感兴趣自行学习 1.寄存器 R0 - R3 R4 - R11 寄存器 R0 - R3一般用作函数传参 R4 - R11用来保存程序运算的中间结果或函数的局部变量 在函数调用过程中 注意在发生异常的时候 cortex-M0架构会自动将R0-R3压入…...
剑指 Offer II 087. 复原 IP
comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20087.%20%E5%A4%8D%E5%8E%9F%20IP/README.md 剑指 Offer II 087. 复原 IP 题目描述 给定一个只包含数字的字符串 s ,用以表示一个 IP 地址…...
RCE-Labs超详细WP-Level10(无字母命令执行_二进制整数替换)
温馨提示 这关涉及的知识点较多, 写的很长, 中间留了很多错误引导(本人在实验时遇到的问题, 或许你们也会遇到), 在后文才逐步解释源码分析 跟前几关一样, 更改了 WAF 的过滤字段这个关卡, 只有0, 1, (单引号), $, <, \ , ( , )可以用解题分析(实验这些命令, 可以先在自己本…...
数据结构(泛型)
1,装箱 int i 10;Integer j Integer.valueOf(i);2.拆箱 Integer i 10;int j i.intValue(); 3.自动装箱 int i 10;Integer j i;int i 10;Integer j (Integer) i; 4,自动拆箱 Integer i 10;int j i;Integer i 10;int j (int) i; 有一段代码需要解析一下: …...
Android Dagger2 框架辅助工具模块深度剖析(六)
一、引言 在 Android 开发领域,依赖注入(Dependency Injection,简称 DI)作为一种至关重要的设计模式,能显著降低代码间的耦合度,提升代码的可测试性与可维护性。Dagger2 作为一款强大的依赖注入框架&#…...
LVGL第三方库的使用(中文库)
一、第三方库文档 3rd party libraries(第三方库) — LVGL 文档 FreeType 中文字库 SDL 模拟器使用freetype中文字库 1.开启字库 2.安装freetype 字库 sudo apt-get update sudo apt-get install libfreetype6-dev 3.修改makefile 添加字库 4.显示中…...
【愚公系列】《高效使用DeepSeek》009-PPT大纲自动生成
标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…...
使用easyexcel实现单元格样式设置和下拉框设置
1.单元格样式设置 1.1实体类 public class DemoData {ExcelProperty("PK")private String name;ExcelProperty("年龄")private int age;// 必须提供无参构造方法public DemoData() {}public DemoData(String name, int age) {this.name name;this.age …...
ngx_conf_read_token
file_size ngx_file_size(&cf->conf_file->file.info); 此时 file_size2656 当然还是和上次一样 for ( ;; ) {if (b->pos > b->last) { 此时 b->pos 0x57759a8b77f4 b->last 0x57759a8b8230 b->start0x57759a8b77d0 条件不成立 ch *b->po…...
Certbot实现SSL免费证书自动续签(CentOS 7 + nginx/apache)
在 CentOS 上,你可以使用 Let’s Encrypt 提供的 Certbot 工具来申请和自动续约免费的 SSL 证书。 1. 安装 Certbot CentOS 7 安装 EPEL 和 Certbot yum install -y epel-release yum install -y certbot python3-certbot-nginx如果使用的是 Apache: …...
【使用 Java 调用命令行工具:完整指南】
在 Java 中调用命令行工具是一个常见的需求,尤其是在需要与外部程序交互或执行系统命令时。本文将详细介绍如何使用 Java 调用命令行工具,并提供一个完整的示例来演示如何下载视频。 1. 为什么需要调用命令行工具? 命令行工具通常提供了强大…...
pythonSTL---sys
sys 是 Python 标准库中的一个内置模块,它提供了许多与 Python 解释器和系统环境进行交互的功能。 sys方法 1. 导入 sys 模块 在使用 sys 库的功能之前,需要先导入它: import sys2. 命令行参数 (sys.argv) sys.argv 是一个包含命令行参数…...
数据分布偏移检测:保障模型在生产环境中的稳定性
数据分布偏移检测:保障模型在生产环境中的稳定性 引言 在机器学习系统从开发环境部署到生产环境的过程中,数据分布偏移问题是影响模型性能的主要挑战之一。当训练数据与生产环境中的数据分布不一致时,即使是经过精心调优的模型也可能表现出明显的性能下降。本文将深入探讨…...
redis删除与先判断再删除的区别
在Redis中,“先判断存在再删除”与“直接删除”的区别主要体现在操作效率、原子性保障、并发安全性三个方面,具体对比如下: 1. 操作效率 直接删除:仅需执行DEL命令一次,无论键是否存在均直接操作…...
3.6、数字签名
目录 数字签名数字签名与验证过程 数字签名 数字签名是签名者使用自己的私钥对待签名数据的哈希值做密码运算得到的一个结果 第一签名者用自己的私钥来对我们待签数据的哈希值进行签名,直接对数据进行签名其实也是可以的,只是对数据签名,这…...
华为手机助手输入连接码时光标乱跳
问题复现:输入12345678,光标自动跳转导致连接码出现乱序情况。 千万别试着找出规律,已试动态规律非大牛误轻试 问题原因: 想啥呢?华哥的软件又不是我开发我要Know Why干啥 我只需关心解决方案 (可能时输入…...
本地化部署Deepseek关于Ollama 安全加固方案(新手易学)
本地化部署Deepseek关于Ollama 安全加固方案(新手易学) 本方案针对使用ChatBox调用Ollama部署DeepSeek-R1:14b模型时的安全防护需求,提供四重防护措施。 🔒 一、关闭外网访问(关键步骤) 1. 修改监听地址 …...