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

手机号登录与高并发思考

基础逻辑

一般来说这个验证码登录分为手机号、以及邮箱登录

手机号短信验证,以腾讯云SMS 服务为例:

这个操作无非对后端来说就是两个接口:

一个是获取验证码,这块后端生成6位数字+expire_time 去推送到腾讯云sdk ,腾讯云sdk再去推送运营商,运营商再去推送到用户

一个就是验证验证码,根据phone+ expire 去redis查就行了

注意 第一个用户 使用手机号获取验证码的时候,不要插库,因为没有经过验证,所有涉及到手机号相关的,特别是绑定、登录等必须要验证手机号

腾讯云短信sms 服务sdk 封装,注意python只有同步线程版,故使用asyncio.to_thread 封装

import asyncio
import jsonfrom tencentcloud.common import credential
from tencentcloud.sms.v20210111 import sms_client, modelsfrom producer.utils.custom_exception_utils import CustomExceptiondef send_sms_sync(phone, code, expiration_date):try:cred = credential.Credential(settings.TENCENT_SMS_SECRET_ID, settings.TENCENT_SMS_SECRET_KEY)client = sms_client.SmsClient(cred, settings.TENCENT_SMS_REGION)req = models.SendSmsRequest()req.SmsSdkAppId = settings.TENCENT_SMS_APP_IDreq.SignName = settings.TENCENT_SMS_SIGN_NAMEreq.TemplateId = settings.TENCENT_SMS_TEMPLATE_IDreq.TemplateParamSet = [code, expiration_date]req.PhoneNumberSet = [phone]resp = client.SendSms(req)logger.info(resp.to_json_string(indent=2))# 将 JSON 字符串转换为字典r = json.loads(resp.to_json_string())if r["SendStatusSet"][0]["Code"] == "Ok":return relse:error_message = r["SendStatusSet"][0]["Message"]logger.error(f"短信SMS服务失败:{error_message}")raise CustomException(message=f"{phone}短信SMS服务失败\n原因:{error_message}")except Exception as e:logger.error(f"发送短信失败: {str(e)}")raise CustomException(message=str(e))async def send_sms_async(phone, code, expiration_date):result = await asyncio.to_thread(send_sms_sync, phone, code, str(expiration_date))return result

注意先插redis 再发送,因为 发送可能有异常,但是能保证测试的时候redis 有数据

一般来说会以redis 作为expire处理:

    async def get_code(self, telephone: str):"""获取验证码"""code = await self.login_code_services.create_login_code(telephone)await send_sms_async(phone=telephone, code=code, expiration_date=settings.SMS_VALIDATION_CODE_EXPIRATION)

创建六位数字的逻辑

create_login_code的逻辑:

    async def create_login_code(self, telephone: str) -> str:"""根据手机号生成登录验证码并存储到 Redis 中:param telephone: 用户手机号:return: 生成的验证码"""# 生成验证码# 生成验证码  generate_code 则是加密函数code = self.generate_code(telephone)# Redis 键名(可用手机号做区分)redis_key = f"{self.login_core_prefix}:{telephone}"# 使用 Redis 存储验证码,有效时间 10 分钟async with redis_client.get_client() as client:try:# 删除已有的验证码await client.delete(redis_key)logger.info(f"Existing login code for {telephone} deleted from Redis.")# 设置新的验证码await client.set(redis_key, code, ex=self.login_code_expiration)logger.info(f"New login code for {telephone} stored in Redis: {code}")except Exception as e:logger.error(f"Failed to store login code in Redis: {e}")raisereturn code

以上展示的是最简单的验证登录(设计sdk + 简单的expire 处理)

高并发请求限制

1、问题:假设你的系统面对高并发用户时,短信验证码的请求频率可能会非常高。如何防止恶意用户利用暴力破解或刷验证码的方式发起过多请求?

考察点

• 防止频繁请求(限流)。

• 防止滥用验证码接口。

解决方案

限流机制:使用 Redis 或类似工具实现用户请求频率限制。比如,使用令牌桶算法(Token Bucket)或者漏桶算法(Leaky Bucket)来限制每个手机号每分钟的验证码请求次数。

令牌桶

Token Bucket 令牌桶 [适用于需要平滑请求速率的场景,特别是在高并发的情况下,它可以平衡请求流量。]

令牌桶 本质:

先查redis 对应的键里面的值 的长度 是否超标了

超标了 就refuse 否则就是pass

插入redis的逻辑: 使用zset (有序集合)在[0, time] 插入值

import redis
import timeredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)# 配置
max_tokens = 5  # 最大令牌数
rate = 1  # 每秒生成一个令牌,每秒只能插入一个新的令牌时间戳(即每秒最多允许一个请求),
# 如果超出这个速率,后续的请求就会被拒绝。
interval = 60  # 限流时间窗口,单位为秒def generate_token(phone_number):# 构造桶键bucket_key = f"sms_rate_limit:{phone_number}"# 获取当前时间(秒),这个就是rate 内容current_time = int(time.time())# 清除过期的令牌# •	这行代码用来移除掉超过时间窗口 interval 的过期令牌。# 如果设置的是 interval=60,那么每次请求时都会移除掉超过 60 秒的令牌,# 确保令牌桶中只包含当前时间窗口内的令牌。# 删除 score 在 [0, current_time - interval] 之间的所有元素。redis_client.zremrangebyscore(bucket_key, 0, current_time - interval)# 获取当前桶内的令牌数(即时间戳数)tokens = redis_client.zrange(bucket_key, 0, -1)# 如果桶里有足够的令牌,则拒绝请求if len(tokens) >= max_tokens:return False  # 限流拒绝else:# 向桶中添加当前时间戳作为新的令牌redis_client.zadd(bucket_key, {current_time: current_time})return True  # 允许请求def check_rate_limit(phone_number):# 获取桶的令牌数量bucket_key = f"sms_rate_limit:{phone_number}"tokens = redis_client.llen(bucket_key)# 如果桶内令牌超过最大容量,表示请求超限if tokens >= max_tokens:return False  # 拒绝请求else:return True  # 允许请求

漏桶算法

漏桶算法 (Leaky Bucket)

它的水流速率是固定的,水桶有固定容量。当水桶满了,任何新的请求都会被丢弃。[适用于流量稳定的场景,具有更强的固定速率处理能力。]

import redis
import timeredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)# 配置
bucket_key = "sms_rate_limit:phone_number"
max_capacity = 5  # 桶的容量,最大允许的请求数
rate = 1  # 处理请求的速率(每秒处理一个请求)def process_request(phone_number):bucket_key = f"sms_rate_limit:{phone_number}"# 当前时间current_time = int(time.time())# 清理过期请求(处理漏桶)redis_client.zremrangebyscore(bucket_key, 0, current_time - 60)# 判断请求是否超出容量限制if redis_client.zcard(bucket_key) >= max_capacity:return False  # 超出请求限制,拒绝请求# 添加当前请求时间戳redis_client.zadd(bucket_key, {current_time: current_time})return True  # 允许请求

,但漏桶着重于处理速率限制和固定容量控制,而令牌桶则关注请求的流量速率和生成令牌的动态过程。

滑动窗口限流

验证码有效期:设置合理的验证码过期时间(通常是 3-5 分钟),避免用户在很长时间内尝试。

滑动窗口限流:每次请求时,记录用户请求的时间戳,在每次请求时检查用户在最近一分钟内的请求次数,如果超过限制,则拒绝该请求。

# 假设我们用 Redis 记录每个手机号的请求次数
import redis
from time import timeredis_client = redis.StrictRedis(host='localhost', port=6379, db=0)def check_sms_limit(phone_number):key = f"sms_request_count:{phone_number}"current_time = int(time())expire_time = 60  # 1 minutemax_requests = 5  # 最大请求次数# 检查手机号最近一段时间内的请求次数requests = redis_client.lrange(key, 0, -1)requests = [int(r) for r in requests]# 删除过期请求(超过1分钟的请求)requests = [r for r in requests if r > current_time - expire_time]if len(requests) >= max_requests:return False  # 超过最大请求次数# 添加当前请求时间redis_client.rpush(key, current_time)redis_client.expire(key, expire_time)return True

验证码泄漏

2、问题:用户的手机可能存在被盗的风险,如何结合其他认证机制提高安全性?比如通过 动态密码生物识别 进一步加强登录安全性。

考察点

• 多因素认证(MFA)。

• 双重验证的实现。

双重验证(2FA)方案,结合了 一次性密码(OTP)二维码生成 来增强系统的安全性。这个过程通常分为两个步骤:

  1. 生成一次性密码:通过一个标准的算法(如 TOTP)生成一次性密码。

  2. 二维码展示与扫描:将 OTP 所需的密钥(通常是一个随机生成的密钥)通过二维码的方式呈现给用户,用户可以使用 TOTP 兼容的应用(如 Google Authenticator 或 Authy)来生成验证码。

使用 TOTP (基于时间的一次性密码) 生成 OTP

TOTP(Time-based One-Time Password)算法基于时间生成一次性密码,通常使用 HMAC-SHA1 算法。这个算法确保了每隔一段时间生成一个新的密码。

Time-Based One-Time Password

import pyotp
import qrcode
from hashlib import sha256# 假设用户的手机号是唯一标识符
user_phone_number = "13800000000"# 使用手机号作为种子生成唯一的 secret
# 使用 hashlib 将手机号进行哈希处理,生成一个固定的 secret
# 这样即使服务重启,每次生成的 secret 都是一样的
secret = pyotp.random_base32()  # 你可以先生成一个固定的 secret, 并保存到数据库# 如果希望生成基于手机号的 secret,可以使用 hashlib 和手机号
hashed_phone = sha256(user_phone_number.encode()).hexdigest()
secret = hashed_phone[:16]  # 使用手机号的哈希值的一部分作为 secret# 将用户手机号与生成的 secret 绑定存储(此处示例,实际应存数据库)
user = {"phone_number": user_phone_number,"2fa_enabled": True,"2fa_secret": secret
}# 生成二维码URL
totp = pyotp.TOTP(secret)
uri = totp.provisioning_uri(user_phone_number, issuer_name="YourApp")# 生成二维码(可以通过Web页面显示)
qr = qrcode.make(uri)
qr.show()  # 展示二维码# 用户扫码后,输入验证码(假设用户输入了 '123456')
user_input_otp = "123456"# 验证用户输入的OTP是否有效
if totp.verify(user_input_otp):print("2FA Verification Success")
else:print("Invalid OTP")

验证码频繁失效

问题:验证码的过期时间通常比较短,但某些场景下可能会发生验证码失效,用户却没有及时看到短信,如何处理这种情况?

延长验证码的过期时间虽然能够解决部分问题,但带来的一些安全和性能隐患也是不容忽视的。最好的解决方案是在验证码过期之前提供验证码重发、动态刷新或者适当的过期提醒等方式来保障用户的体验,同时确保系统的安全性和效率。

跨设备验证码

问题:同一个用户在不同设备上登录时,可能会因为设备间验证码的同步问题导致登录失败或需要重复输入验证码。如何在跨设备的场景下保证一致性?

考察点

• 跨设备的一致性。

• 设备间验证码的共享和同步。

. 生成设备标识(Device ID)

每次用户登录时,前端可以生成一个唯一的设备标识(Device ID),并将其作为参数与验证码一起发送到后端。这个设备标识可以基于设备的硬件信息、安装的应用ID,或者生成一个唯一的UUID。比如可以通过浏览器的 localStorage、sessionStorage 或者移动端的设备ID生成。

2. 发送验证码时包含设备标识

后端在发送验证码时,将设备标识与手机号和验证码一起存储在 Redis 或数据库中。这样,无论用户在哪个设备上获取验证码,都能根据设备标识进行有效的关联。

相关文章:

手机号登录与高并发思考

基础逻辑 一般来说这个验证码登录分为手机号、以及邮箱登录 手机号短信验证,以腾讯云SMS 服务为例: 这个操作无非对后端来说就是两个接口: 一个是获取验证码,这块后端生成6位数字expire_time 去推送到腾讯云sdk ,腾…...

Linux系统管理与编程07:任务驱动综合应用

兰生幽谷,不为莫服而不芳; 君子行义,不为莫知而止休。 [环境] windows11、centos9.9.2207、zabbix6、MobaXterm、Internet环境 [要求] zabbix6.0安装环境:Lamp(linux httpd mysql8.0 php) [步骤] 2 …...

12:表的内外连接

1. 内连接 内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,前面学习的查询都是内连接,也是在开发过程中使用的最多的连接查询。 新的内连接的语法: select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件; //通过…...

Mybatis的基础操作——03

写mybatis代码的方法有两种: 注解xml方式 本篇就介绍XML的方式 使用XML来配置映射语句能够实现复杂的SQL功能,也就是将sql语句写到XML配置文件中。 目录 一、配置XML文件的路径,在resources/mapper 的目录下 二、写持久层代码 1.添加mappe…...

在CentOS系统上运行Ruby on Rails应用的详细步骤

以下是AI生成,仅做备份。 1. 安装必要的依赖 在CentOS上,首先要安装一些基础的开发工具和依赖库,它们能确保后续的安装和运行过程顺利进行。 sudo yum update -y sudo yum install -y git gcc-c patch readline readline-devel zlib zlib-…...

《AI大模型趣味实战》第6集:基于大模型和RSS聚合打造个人新闻电台

《AI大模型趣味实战》第6集:基于大模型和RSS聚合打造个人新闻电台 摘要 本文将带您探索如何结合AI大模型和RSS聚合技术,打造一个功能丰富的个人新闻电台系统。我们将使用Python和PyQt5构建一个桌面应用程序,该应用可以从多个RSS源抓取新闻&…...

Unity 与 JavaScript 的通信交互:实现跨平台的双向通信

前言 在现代游戏开发和 Web 应用中,Unity 和 JavaScript 的结合越来越常见。Unity 是一个强大的跨平台游戏引擎,而 JavaScript 是 Web 开发的核心技术之一。通过 Unity 和 JavaScript 的通信交互,开发者可以实现从 Unity 到 Web 页面的功能扩…...

Sql Server 索引性能优化 分析以及分表

定位需优化语句 根据工具 skywking 或者开启慢查询日志 找到 慢sql 的语句根据 执行过程 来 判断 慢的原因 row filter 指标 看查了多少数据 比例多少 type 看下是单表 还是 join联表 比如 执行步骤多 没索引 优化方向 减少执行次数索引 没索引考虑加索引 加索引 尽量选择 i…...

Vue.js 模板语法全解析:从基础到实战应用

引言 在 Vue.js 的开发体系中,模板语法是构建用户界面的核心要素,它让开发者能够高效地将数据与 DOM 进行绑定,实现动态交互效果。通过对《Vue.js 快速入门实战》中关于 Vue 项目部署章节(实际围绕 Vue 模板语法展开)…...

【JVM】内存区域划分,类加载机制和垃圾回收机制

本篇内容为了解 JVM 的内存区域划分,类加载机制,垃圾回收机制。实际开发中几乎用不到,但为了某些情况我们又不得不了解。 目录 一、JVM中的内存区域划分 1.1 内存区域划分考点 二、JVM的类加载机制 2.1 类加载流程 2.2 类加载什么时候会…...

代码随想录算法训练营第十四天|替换数字

文档讲解:代码随想录 难度:easy 附:冲 passion!!!passion!!!passion!!! 替换数字 卡码网题目链接(opens new window) 给定一个字符串…...

Java实体类(Javabean)-编程规范

Java学习笔记-Java实体类详解 今天我们要聊一个看似简单却至关重要的知识点——Java实体类。就像快递小哥打包物件需要包装盒一样,在Java世界里处理数据也需要专门的容器,这就是我们的实体类! 一、实体类是什么?——程序的"…...

深入解析 Java Stream API:筛选子节点的优雅实现!!!

🚀 深入解析 Java Stream API:筛选子节点的优雅实现 🔧 大家好!👋 今天我们来聊聊 Java 8 中一个非常常见的操作:使用 Stream API 从 Map 中筛选出特定条件的元素。🎉 具体来说,我们…...

Vala编程语言教程-面向对象编程语基础

基础 尽管Vala语言并不强制你使用对象进行编程,但有些功能只能通过对象的方式来实现。因此,在大多数情况下,你肯定会希望采用面向对象的编程风格。与大多数当前的编程语言一样,为了定义你自己的对象类型,你需要编写一个…...

写读后感的时候,可以适当地引用书中的内容吗?

写读后感时,适当地引用书中的内容是可以的,这样可以更好地支持你的观点和感受,增强文章的可信度和说服力。 引用书中的内容可以帮助读者更好地理解你所讨论的主题和人物,同时也可以展示你对原著的深入理解和阅读能力。但是&#…...

计算机网络高频(二)TCP/IP基础

计算机网络高频(二)TCP/IP基础 1.什么是TCP/IP⭐⭐ TCP/IP是一种网络通信协议,它是互联网中最常用的协议之一。TCP/IP有两个基本的协议:TCP(传输控制协议)和IP(互联网协议)。 TCP(Transmission Control Protocol,传输控制协议)是一种可靠的、面向连接的协议。它负…...

蓝桥杯 之 数论

文章目录 习题质数找素数 LCM报数游戏 快速幂数字诗意 组合数与错位排序小蓝与钥匙 同余取模 数论,就是一些数学问题,蓝桥杯十分喜欢考察,常见的数论的问题有:取模,同余,大整数分解,素数&#x…...

无法写入文件:(FileSystemError): Error: EPERM: operation not permitted, open...)

问题分析: 当我想在Visual Studio Code中编写文件时,出现无法写入文件的错误,发现是权限的问题 解决办法: 右键应用图标 → 以管理员身份运行就可以了...

Java爬虫抓取B站视频信息

依赖 <dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.17.2</version> <!-- 最新版可去官网查看 --></dependency>编码 public static List<VideoDto> parseSearchPage(Str…...

Sql Server数据迁移易错的地方

背景&#xff1a;之前一直台式机&#xff0c;毕业准备答辩了&#xff0c;要将代码搬到笔记本运行才方便些。这个Sql数据弄过来搞了好几个小时 还原备份报错&#xff1a;媒体簇的结构不正确。SQL Server 无法处理此媒体簇。 解决&#xff1a;升级到sql server版本比备份的那个高…...

七、服务器远程桌面报错

&#x1f33b;&#x1f33b;目录&#x1f33b;&#x1f33b; 一、远程桌面报错-用户账户限制&#xff08;例如&#xff0c;时间限制&#xff09;会阻止你登录。 一、远程桌面报错-用户账户限制&#xff08;例如&#xff0c;时间限制&#xff09;会阻止你登录。 原因是被远程的系…...

JAVA 之「优先队列」:大顶堆与小顶堆的实现与应用

Java 优先队列&#xff1a;大顶堆与小顶堆的实现与应用 文章目录 Java 优先队列&#xff1a;大顶堆与小顶堆的实现与应用一、什么是优先队列和堆&#xff1f;1. 优先队列2. 堆 二、Java PriorityQueue 基本用法1. 默认小顶堆示例代码输出 2. 实现大顶堆示例代码输出 三、大顶堆…...

压缩壳学习

壳是什么 壳就是软件的一个保护套&#xff0c;防止软件被进行反编译或被轻易地修改。 其作用就是为了保护软件。 常见的大类壳有压缩壳、加密壳、VM 壳的分类。 压缩壳顾名思义就是用来减小软件的文件大小的&#xff1b;加密壳&#xff0c;通过加密软件来保护软件&#xff…...

VRRP配置双出口ipsec隧道建立。

背景&#xff1a;在做毕设时&#xff0c;发现规划的不是那么合理&#xff0c;vrrp主备切换后&#xff0c;ipsec隧道并没有跟着切换到与备防火墙建立隧道&#xff0c;这是因为配置了双出口&#xff0c;路由的设计导致vrrp主备切换ipsec隧道没有跟着切换。 fw1为主&#xff0c;fw…...

机器学习——Numpy的神奇索引与布尔索引

在 NumPy 中&#xff0c;神奇索引&#xff08;Fancy Indexing&#xff09; 和 布尔索引&#xff08;Boolean Indexing&#xff09; 是两种强大的索引方式&#xff0c;用于从数组中提取特定元素或子集。以下是它们的详细说明和示例&#xff1a; 1. 神奇索引&#xff08;Fancy In…...

Linux:进程间通信

文章目录 前言一、进程间通信介绍1.1 进程间通信的目的1.2 进程间通信的发展与分类 二、管道2.1 匿名管道原理2.2 通信管道会出现的情况和特性&#xff08;重要&#xff09;2.3 命名管道2.3.1 命名管道与匿名管道的区别 三、system V3.1 共享内存原理3.2 键值3.2.1 键值生成原理…...

Mysql配套测试之查询篇

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 条件查询简单测试&#xff1a; 1.查询英语成绩不及格的同学(<60) 2…...

基于SSM框架的汽车租赁平台(源码+lw+部署文档+讲解),源码可白嫖!

摘要 时代在飞速进步&#xff0c;每个行业都在努力发展现在先进技术&#xff0c;通过这些先进的技术来提高自己的水平和优势&#xff0c;汽车租赁平台当然不能排除在外。汽车租赁平台是在实际应用和软件工程的开发原理之上&#xff0c;运用Java语言以及SSM框架进行开发&#x…...

常考计算机操作系统面试习题(三下)

20. 请求页式存储管理系统缺页率计算 题目&#xff1a; 假设一个作业的页面走向为 1、2、3、4、1、2、5、1、2、3、4、5&#xff0c;当分配给该作业的物理块数分别为 3 和 4 时&#xff0c;计算采用下述页面置换算法的缺页率&#xff1a; (1) 先进先出&#xff08;FIFO&…...

Spring IOC核心详解:掌握控制反转与依赖注入

文章目录 前言一、IOC核心思想二、IOC容器实现1.核心接口&#xff1a;2.XML配置范例 三、Bean管理实践1.创建对象&#xff08;1&#xff09;基于xml方式创建对象&#xff08;2&#xff09;用注解的方式创建对象 2.依赖注入&#xff08;1&#xff09;基于xml方式注入属性基础类型…...

Servlet、HttpServletRequest、HttpServletResponse、静态与动态网页、jsp、重定向与转发

DAY15.2 Java核心基础 JavaWeb 要想通过浏览器或者客户端来访问java程序&#xff0c;必须通过Servlet来处理 没有Servlet&#xff0c;java是无法处理web请求的 Web交互&#xff1a; 接收请求HttpServletRequest&#xff1a;可以获取到请求的信息&#xff0c;比如uri&#…...

Linux 内核源码阅读——ipv4

Linux 内核源码阅读——ipv4 综述 在 Linux 内核中&#xff0c;IPv4 协议的实现主要分布在 net/ipv4/ 目录下。以下是一些关键的源文件及其作用&#xff1a; 1. 协议栈核心 net/ipv4/ip_input.c&#xff1a;处理接收到的 IPv4 数据包&#xff08;输入路径&#xff09;。net…...

组合总和 II:去重逻辑深度解析

组合总和 II&#xff1a;去重逻辑深度解析 在算法中&#xff0c;解决“组合总和 II”这类问题时&#xff0c;去重往往是最具挑战性的一环。如何避免重复组合&#xff0c;同时保证所有组合的唯一性&#xff0c;是实现高效算法的关键。今天&#xff0c;我们就来深度解析组合总和…...

蓝桥杯备考:二分答案之路标设置

最大距离&#xff0c;找最小空旷指数值&#xff0c;我们是很容易想到用二分的&#xff0c;我们再看看这个答案有没有二段性 是有这么个二段性的&#xff0c;我们只要二分就行了&#xff0c;但是二分的check函数是有点不好想的&#xff0c;我们枚举空旷值的时候&#xff0c;为了…...

[HY000][1366] Incorrect string value: ‘张三‘ for column ‘name‘ at row 1

常见原因 字符集不兼容 插入的数据包含当前字符集&#xff08;如 latin1&#xff09;不支持的特殊字符&#xff08;如中文、Emoji 等&#xff09;。 表、列或连接的字符集未正确配置为支持目标字符&#xff08;如未使用 utf8mb4&#xff09;。 客户端/服务端编码不一致 客户…...

什么是C++对象之间的view proxies

在C中&#xff0c;view proxies 是一种轻量级的对象&#xff0c;用于提供对另一个对象的间接访问或视图&#xff0c;而不直接拥有或管理该对象的数据。它们通常用于简化对复杂数据结构的访问&#xff0c;或在不需要复制数据的情况下提供特定的视图。 1. View Proxies 的核心概…...

MyBatis参数赋值技巧:#{} 和 ${} 的区别与实践

目录 一、前言二、 #{} 和${} 的使用方法和区别2.1 #{}使用方法2.2 ${}使用方法2.3#{} 和 ${} 的主要区别2.4使用建议 三、总结 一、前言 在 MyBatis 中&#xff0c;#{} 和 ${} 都用于在 SQL 语句中绑定参数&#xff0c;但它们在具体实现和安全性方面有所不同。理解它们的区别…...

5-1 使用ECharts将MySQL数据库中的数据可视化

方法一&#xff1a;使用Python Flask框架搭建API 对于技术小白来说&#xff0c;使用ECharts将MySQL数据库中的数据可视化需要分步骤完成。以下是详细的实现流程&#xff1a; 一、技术架构‌ 后端服务‌&#xff1a;使用Python Flask框架搭建API&#xff08;简单易学&#xff…...

协程的调度的对称与非对称

下图表示的就是对称协程&#xff0c;进入到该协程之后只能有一个操作就是yield&#xff0c;把cpu让回给调度器; 下图表示非对称协议&#xff0c;可以有两个操作&#xff0c;就是resume和yield&#xff0c;从哪里resume的&#xff0c;yield就会回到该位子&#xff1b;...

C# 中比较实用的关键字,基础高频面试题!

前言 在C#编程中关键字是构建逻辑和实现功能的基石&#xff0c;它承载着编程语言的语法规则和编程智慧。熟练掌握这些基础高频关键字对提升编程能力和面试表现至关重要&#xff0c;它们是日常开发和解决复杂问题的关键。 DotNetGuide 全面的C#/.NET/.NET Core学习、工作、面试指…...

文献分享: XTR——优化Token级检索的高效多向量模型

原文章 文章目录 1. XTR \textbf{1. XTR} 1. XTR原理 1.1. \textbf{1.1. } 1.1. 导论 1.2. XTR \textbf{1.2. XTR} 1.2. XTR的训练和推理 2. \textbf{2. } 2. 实验与分析 2.1. \textbf{2.1. } 2.1. 实验配置与结果 2.2. \textbf{2.2. } 2.2. 结果分析 3. \textbf{3. } 3. 其它分…...

【数据结构】C语言实现树和森林的遍历

C语言实现树和森林的遍历 导读一、树的遍历二、森林的遍历2.1 为什么森林没有后序遍历?2.2 森林中存不存在层序遍历?三、C语言实现3.1 准备工作3.2 数据结构的选择3.3 树与森林的创建3.4 树与森林的遍历3.4.1 先根遍历3.4.2 后根遍历3.4.3 森林的遍历3.5 树与森林的销毁3.6 算…...

《Python深度学习》第七讲:生成式深度学习

在深度学习的世界里,生成式模型是一种非常有趣且富有创造力的技术。它们能够生成全新的内容,比如文本、图像、音乐等,甚至可以创造出从未见过的虚拟世界。这一讲,我们将深入探讨生成式深度学习的核心技术,包括 LSTM 文本生成、DeepDream、神经风格迁移、变分自编码器(VAE…...

Spring的IOC

在现代 Java 开发中&#xff0c;Spring 框架几乎无处不在&#xff0c;特别是其核心的 IOC&#xff08;Inversion of Control&#xff09; 容器&#xff0c;几乎所有Spring的功能都与它紧密相关。 一、什么是IOC IOC&#xff0c;全称为 Inversion of Control&#xff08;控制反…...

常考计算机操作系统面试习题(四)

目录 1. Peterson 算法伪代码 2. 信号量生产者消费者问题分析 3. 注释 Peterson 主函数并分析输出结果 4. 用 fork 创建子进程的程序 1. Peterson 算法伪代码 题目&#xff1a; 写出 Peterson 算法的伪代码。 参考答案&#xff1a; // 定义变量 boolean flag[2]; //…...

Visual Studio Code 连接 SAP ERP 系统

首先确保服务打开 在vscode&#xff0c;在extension安装ABAP remote filesystem&#xff0c;然后打开设置SAP 系统的地址配置 CtrlshiftP 执行代码&#xff1a;AbapFS connect to an ABAP system&#xff0c;可以根据要求一步一步配置。 根据配置。加载系统 也可以直接在extens…...

从报错到成功:Mermaid 流程图语法避坑指南✨

&#x1f680; 从报错到成功&#xff1a;Mermaid 流程图语法避坑指南 &#x1f680; &#x1f6a8; 问题背景 在开发文档或技术博客中&#xff0c;我们经常使用 Mermaid 流程图 来可视化代码逻辑。但最近我在尝试绘制一个 Java Stream 转换流程图时&#xff0c;遭遇了以下报错…...

TDengine 中的 show 命令

简介 SHOW 命令可以用来获取简要的系统信息。若想获取系统中详细的各种元数据、系统信息和状态&#xff0c;请使用 select 语句查询 INFORMATION_SCHEMA 数据库中的表, 详见 元数据查询 SHOW APPS SHOW APPS;显示接入集群的应用&#xff08;客户端&#xff09;信息。 SHOW …...

博弈论中的均衡精炼:完美贝叶斯均衡、序贯均衡与颤抖手均衡详解

博弈论中的均衡精炼&#xff1a;完美贝叶斯均衡、序贯均衡与颤抖手均衡详解 1. 引言&#xff1a;为什么需要均衡精炼&#xff1f; 在博弈论中&#xff0c;纳什均衡是分析策略互动的核心工具&#xff0c;但其存在一个显著缺陷&#xff1a;无法排除不合理的均衡。例如&#xff0…...

github代理 | 快速clone项目

代理网址&#xff1a; https://ghproxy.com/ https://ghproxy.com/代理网址&#xff1a; https://ghproxy.com/ 比如需要克隆的项目git地址为&#xff1a;https://github.com/AUTOMATIC1111/stable-diffusion-webui.git git clone https://ghproxy.com/https://github.com/AUTO…...