新闻详情

新闻详情

首页 / 资讯中心 / 详情

Windows 11编译安装pysqlcipher3全攻略:从环境配置到加密验证

发布时间:2026/10/2 13:06:00来源:尧图网络
Windows 11编译安装pysqlcipher3全攻略:从环境配置到加密验证
简介在Windows平台上编译Python扩展模块常因依赖缺失而失败尤其涉及透明加密数据库时更为复杂。SQLCipher作为SQLite的加密分支通过OpenSSL提供加密算法支持而pysqlcipher3是其Python绑定。编译过程依赖于MSVC工具链和OpenSSL版本匹配理解这些原理能显著降低踩坑概率。对于需要保护本地数据、桌面应用数据库安全的开发者掌握pysqlcipher3的编译安装是必要技能。本文基于Windows 11环境从零演示如何配置Visual Studio构建工具、选择合适OpenSSL版本、修改setup.py并编译安装最后通过文件头校验和错误密钥测试验证加密确实生效。1. Windows 11 编译 pysqlcipher3为什么这条路绕不开在 Windows 11 上装 pysqlcipher3最直接的做法是pip install pysqlcipher3但绝大多数人都会在安装日志里看到一大堆编译错误然后陷入「装一个库要先修半小时环境」的循环。原因是 pysqlcipher3 没有官方编译好的 Windows wheel 包PyPI 上的源码包依赖本机 OpenSSL 和 SQLCipher而 Windows 上没有像 Linux 那样统一的包管理路径导致构建脚本经常找不到头文件或链接库。这篇文章要解决的就是这件事从零开始在 Windows 11 上把 pysqlcipher3 编译安装成功并且让它稳定跑起来。适合需要在 Windows 上对 SQLite 做透明加密的 Python 开发者——比如做本地数据加密存储、桌面应用数据库保护的场景。后面每一步都是我在 Windows 11 上实际跑过的路径版本边界和坑点会一并标注。2. 编译前置环境Visual Studio 构建工具与 OpenSSL 的版本边界2.1 为什么必须用 MSVC 而不是 MinGWpysqlcipher3 的构建脚本setup.py在 Windows 上默认走 MSVC 编译器这是第一道门槛。如果你电脑上只装了 MinGW 或者压根没有 C 编译器编译会在第一轮就失败——报错通常是error: Microsoft Visual C 14.0 or greater is required。这个提示虽然烦人但方向是对的Windows 上的 Python 扩展模块必须和 Python 解释器用同一套 ABI 编译而官方 CPython for Windows 就是用 MSVC 构建的所以扩展模块也必须用 MSVC 编译才能保证二进制兼容。用 MinGW 不是完全不行但你要自己去处理导入库、运行库依赖和 ABI 对齐复杂度远高于直接装 MSVC。具体要装的是 Visual Studio Build Tools不是完整的 Visual Studio IDE。打开 Visual Studio Installer选择「使用 C 的桌面开发」工作负载右侧组件里确保勾选 MSVC v143 生成工具和 Windows 11 SDK。如果你机器上已经装了 VS 2022同样可以只去勾选这两个组件。装完之后在「开始」菜单里能找到「x64 Native Tools Command Prompt for VS 2022」后续编译建议全程在这个终端里做因为它已经把cl.exe、link.exe和 SDK 路径全部配好了。2.2 OpenSSL 版本选择1.1.1 系列最稳pysqlcipher3 的加密能力来自它链接的 OpenSSL所以编译前必须让构建脚本找到 OpenSSL 的头文件和库文件。这里有个致命的版本陷阱OpenSSL 1.1.0 以上的库文件名从libeay32.lib/ssleay32.lib改成了libcrypto.lib/libssl.lib而 pysqlcipher3 的老版本构建脚本在 Windows 上仍然引用了旧文件名。如果你装的是 OpenSSL 3.x构建脚本还可能在 API 层面遇到函数签名不匹配的问题。我的建议是直接用 OpenSSL 1.1.1 的预编译二进制这是 pysqlcipher3 在 Windows 上被验证过最稳的组合。装 OpenSSL 有两个主流路径。一是用 vcpkg命令是vcpkg install openssl:x64-windows优点是版本管理清晰缺点是默认编译的 OpenSSL 3.x 仍要改链接参数而且 vcpkg 生成的库路径比较绕。二是直接去 OpenSSL 官方 Wiki 找 1.1.1 的 Windows 预编译包文件名类似Win64 OpenSSL v1.1.1w安装到C:\OpenSSL-Win64。我推荐第二个方案原因在后文避坑篇里会详细解释。装完之后确认一下C:\OpenSSL-Win64\include下有openssl\evp.hC:\OpenSSL-Win64\lib下有libcrypto.lib这两个文件是后续编译是否顺利的关键。前置组件推荐版本用途Visual Studio Build Tools2022MSVC v143Windows 11 SDK编译 Python 扩展模块Python3.8 ~ 3.10构建与运行 pysqlcipher3OpenSSL1.1.1wx64提供加密算法实现SQLCipher4.5.x amalgamationSQLite 加密分支源码2.3 版本边界的经验值我手上的测试环境是 Python 3.10.11 OpenSSL 1.1.1w VS 2022 Build Tools这套组合编译 pysqlcipher3 一次通过。如果把 Python 换成 3.12大概率会撞上distutils被移除的问题——Python 3.12 起标准库不再包含distutils而 pysqlcipher3 的setup.py还在用from distutils.core import setup, Extension会直接报ModuleNotFoundError。解决方式是先pip install setuptools新版 setuptools 会通过 shim 兼容distutils调用但我实测下来 3.10 更省心。如果你必须用 3.12可以装 setuptools 之后继续但后面链接阶段可能还会遇到get_distutils_extension相关的兼容问题到时候按报错逐个处理。提示在开始之前先用python --version和cl.exe是否可用这两个命令把基础环境确认一遍省得后面排查问题时反复怀疑编译器没装对。3. 源码准备SQLCipher Amalgamation 与 setup.py 修改3.1 获取 pysqlcipher3 源码的正确渠道不要从 PyPI 下载 pysqlcipher3 的 sdist 包那个包里的源码版本停留在很多年前setup.py对 Windows 的适配很差。正确做法是从 GitHub 仓库riggle/pysqlcipher3拉取最新源码或者直接下载 zip 包解压到本地。拉取之后你会看到一个setup.py、pysqlcipher3目录和sqlcipher目录占位符。这个sqlcipher目录是空的需要你手动把 SQLCipher 的源码放进去。SQLCipher 是 SQLite 的加密分支它的发布页提供两种形态完整源码和 amalgamation。Amalgamation 是把所有 C 源码合并成sqlite3.c和sqlite3.h两个文件的版本对编译来说最省事。下载 SQLCipher amalgamation 压缩包后解压出sqlite3.c、sqlite3.h、sqlite3ext.h把这几个文件放进 pysqlcipher3 项目根目录下的sqlcipher/文件夹里。注意不是放到pysqlcipher3/sqlcipher/而是项目根目录下和setup.py平级的sqlcipher/。3.2 setup.py 需要改什么打开setup.py你会看到sqlcipher_dir、openssl_dir这些变量的定义默认值指向的目录在 Windows 上都不存在。核心要改的是三处sqlcipher_dir指到源码目录、openssl_dir指到 OpenSSL 安装目录、include_dirs和library_dirs要能同时覆盖 SQLCipher 和 OpenSSL 的头文件与库文件。另外前面提到的库文件名问题——你把openssl_dir配好后构建脚本拼出的库名仍然可能是libeay32.lib这是老脚本的历史遗留需要手动把libraries列表里的旧名字改成新名字。在改setup.py之前有个更干净的做法用环境变量去覆盖默认路径然后只在setup.py里做最小的改动。我的做法是在setup.py中找到openssl_dir os.environ.get(OPENSSL_DIR, /usr/local)之类的行然后直接将OPENSSL_DIR环境变量指向C:\OpenSSL-Win64。setup.py里还硬编码了include_dirs和library_dirs的拼接逻辑——它会基于sqlcipher_dir拼sqlcipher子目录路径基于openssl_dir拼include和lib路径。理论上只要这两个根目录设定正确拼接出来的路径就是对的。但我见过某些版本会在拼路径时把sqlcipher_dir后面多加一层sqlcipher导致头文件找不到。保险起见直接把include_dirs和library_dirs改成显式列表不要依赖拼接逻辑。# setup.py 关键片段修改后 sqlcipher_dir rC:\dev\pysqlcipher3\sqlcipher openssl_dir rC:\OpenSSL-Win64 ext Extension( _sqlcipher, sources[ pysqlcipher3/_sqlcipher.c, os.path.join(sqlcipher_dir, sqlite3.c), ], include_dirs[ os.path.join(sqlcipher_dir, .), # 指向 sqlcipher 源码目录本身 os.path.join(openssl_dir, include), ], library_dirs[ os.path.join(openssl_dir, lib), ], libraries[crypto], # 注意是 crypto不是 libeay32 define_macros[(SQLITE_HAS_CODEC, None), (SQLCIPHER_CRYPTO_OPENSSL, None)], )这段代码里有两个关键宏SQLITE_HAS_CODEC控制 SQLite 是否启用加密相关函数SQLCIPHER_CRYPTO_OPENSSL告诉 SQLCipher 使用 OpenSSL 作为加密后端。没有这两个宏编译出来的库即使链接成功了实际执行加密 SQL 语句时也会报错或者直接忽略加密请求。libraries列表里的crypto是 OpenSSL 1.1.0 之后的新库名如果你把 OpenSSL 1.1.1 装好后看到目录下只有libcrypto.lib和libssl.lib说明名字没改错。3.3 修改后的目录结构确认在开始编译之前花一分钟确认目录结构是你省掉后面一团乱麻的关键。正确状态是pysqlcipher3/setup.py存在pysqlcipher3/sqlcipher/sqlite3.c存在C:\OpenSSL-Win64\include\openssl\evp.h存在C:\OpenSSL-Win64\lib\libcrypto.lib存在。我用过一个笨办法在setup.py里临时加几行print()把include_dirs和library_dirs打出来然后跑构建看实际拼接的路径对不对。这不算麻烦但能直接暴露手工修改时漏掉的路径成分。4. 编译安装从命令行到 batch 脚本的完整流程4.1 第一个命令确认构建环境打开「x64 Native Tools Command Prompt for VS 2022」先激活 Python 虚拟环境。假设你已经在项目根目录下建好了虚拟环境具体命令如下python -m venv .venv .venv\Scripts\activate python --version where clwhere cl这个命令很多人会忽略但它非常关键——如果输出里找不到cl.exe说明你不在 VS 的 Native Tools 终端里或者 Build Tools 组件没装全后面的编译会直接以命令未找到失败。我一般还会顺手跑一个where link确保链接器也在 PATH 里。这个终端里运行python时会发现它继承的是系统 PATH如果你同时装了多个 Python 版本务必用python --version确认当前激活的是虚拟环境里的解释器而不是全局的其他版本。4.2 编译的完整命令流环境没问题之后执行构建和安装。此时setup.py已经按前面修改过的版本运行。我按照实际成功的顺序把命令整理成一段每一行都标注了用途# 1. 设置 OpenSSL 根目录环境变量setup.py 里会读取 set OPENSSL_DIRC:\OpenSSL-Win64 # 2. 构建扩展模块--inplace 表示把 .pyd 生成到当前目录 python setup.py build_ext --inplace # 3. 如果 build_ext 成功再安装到虚拟环境 python setup.py install先跑build_ext --inplace而不是直接install是有原因的install会先执行一次构建如果失败报错信息和build_ext相同但额外夹杂 setuptools 的安装逻辑干扰排查方向。--inplace还能让你在当前目录直接看到生成的.pyd文件确认构建产物真实存在。如果build_ext这步过了install基本不会再有编译层面的幺蛾子。构建过程中你可能会看到sqlite3.c在编译这个文件很大编译耗时一到两分钟属于正常现象。如果十几秒就结束了反而要怀疑是不是没有把sqlite3.c加进编译源文件列表——那样最后链接出来的库是没有实际 SQLite 引擎的。4.3 编译参数如何按需调整build_ext可以接受不少参数但实际项目里常用的就两三个。加-j 4可以启用并行编译缩短sqlite3.c的编译时间加--force会忽略缓存强制重新编译所有文件——这个参数在setup.py修改后却不重新编译时会非常有用。真正的分水岭不在build_ext的参数而在环境变量除了OPENSSL_DIR某些场景还需要设置INCLUDE和LIB环境变量把 OpenSSL 的头文件目录和库目录追加进去。我一般这样写set INCLUDE%INCLUDE%;C:\OpenSSL-Win64\include set LIB%LIB%;C:\OpenSSL-Win64\lib设置INCLUDE和LIB后MSVC 会在系统默认路径之外额外搜索这些目录即使setup.py里的include_dirs拼接有误差编译器也能兜底找到头文件。这招算是我处理 Windows 编译问题时的万能偏方但它不能解决库名错误的问题——那是逻辑层面的事环境变量覆盖不了。4.4 把整个流程固化成 batch 脚本命令行一步步敲没问题但如果你要在多台 Windows 机器上重复部署或者给同事用最好把流程写成一个 batch 脚本。脚本里要处理好路径变量、虚拟环境激活、编译失败时的退出码。下面这个脚本是我实际在用的版本注释里写了每个环境变量的作用echo off REM 编译安装 pysqlcipher3 的 Windows 批处理脚本 REM 使用前提VS2022 Build Tools 已安装OpenSSL 1.1.1 已安装到 C:\OpenSSL-Win64 set OPENSSL_DIRC:\OpenSSL-Win64 set INCLUDE%INCLUDE%;C:\OpenSSL-Win64\include set LIB%LIB%;C:\OpenSSL-Win64\lib cd /d %~dp0 python -m venv .venv || goto :error call .venv\Scripts\activate.bat python setup.py build_ext --inplace || goto :error python setup.py install || goto :error echo pysqlcipher3 build OK goto :eof :error echo Build FAILED, check messages above. exit /b 1脚本里的%~dp0表示脚本所在目录cd /d切换到该目录这样不管你从哪个路径双击执行脚本工作目录都是正确的。每个可能失败的步骤都加了|| goto :error这样在 CI 流水线里脚本就不会在失败后继续往下跑避免出现「install 失败但脚本返回成功」的假象。.venv存在时python -m venv .venv不会覆盖已有环境会直接复用所以重复执行脚本是安全的。注意如果你装的是 OpenSSL 3.x上面脚本里set OPENSSL_DIR仍然指向C:\OpenSSL-Win64但链接阶段大概率会报无法解析的外部符号因为 3.x 移除了不少 1.1.1 时代的 API。遇到这种情况不要硬调脚本先回头确认 OpenSSL 版本是否符合推荐。5. 避坑清单5 个高频翻车点的现象与根因5.1 找不到 openssl/evp.h路径拼接的经典陷阱现象build_ext在编译_sqlcipher.c时报fatal error C1083: 无法打开包括文件: openssl/evp.h。原因编译器在搜索头文件时没有找到 OpenSSL 的include目录。setup.py里的include_dirs拼接逻辑在老版本里写死了 Unix 风格路径比如/usr/local/include在 Windows 上完全没有意义——这个路径不存在编译器自然找不到。解决不要只依靠环境变量OPENSSL_DIR直接在setup.py里把include_dirs改成绝对路径列表[rC:\OpenSSL-Win64\include]或者在编译前执行set INCLUDE%INCLUDE%;C:\OpenSSL-Win64\include。两种方式都有效我推荐同时做这样即使setup.py被其他流程覆盖环境变量也能兜底。5.2 链接阶段报错找不到 libeay32.libOpenSSL 版本名变了现象编译阶段通过链接时报LNK1181: 无法打开输入文件 libeay32.lib。原因pysqlcipher3 的setup.py是从 SQLCipher 的老构建脚本继承来的在 Windows 上硬编码了 OpenSSL 1.0.x 时代的库名libeay32。OpenSSL 1.1.0 起库改名成了libcrypto和libssl而且不再有libeay32这个文件。解决修改setup.py里libraries列表把[libeay32]改为[crypto]或者更精确地写成[libcrypto]。注意 MSVC 的库名不用带.lib后缀写crypto就能匹配到libcrypto.lib。如果你需要用到 SSL 相关能力可以追加ssl但 pysqlcipher3 只依赖crypto库。5.3 编译通过但 import 时报 DLL load failed运行期找不到 OpenSSL现象python setup.py install成功后进入 Python 执行from pysqlcipher3 import dbapi2直接报ImportError: DLL load failed while importing _sqlcipher。原因扩展模块.pyd在编译时链接了libcrypto.lib但运行时需要对应的libcrypto-1_1-x64.dll。如果这个 DLL 不在系统搜索路径、Python 安装目录或虚拟环境的根目录里Windows 加载器就找不到它模块初始化直接失败。解决确认C:\OpenSSL-Win64\bin下有libcrypto-1_1-x64.dll然后把该目录加到系统PATH里或者更直接——把 DLL 复制到虚拟环境的Lib\site-packages\pysqlcipher3目录下和.pyd文件放一起。我一般用后一种方式因为它是复制不是引用删掉虚拟环境重建时不会带着旧路径的依赖残留。5.4 Python 3.12 报 ModuleNotFoundError: No module named distutils现象python setup.py build_ext --inplace一执行就报ModuleNotFoundError: No module named distutils。原因Python 3.12 从标准库移除了distutils而 pysqlcipher3 的setup.py还有from distutils.core import setup, Extension。这属于上游项目常年未更新的代价。解决先pip install setuptools最新版 setuptools 会提供distutils的兼容层。实测在 3.12 上这样做后setup.py能跑起来但后续链接阶段可能碰到其他兼容问题。如果你不需要非用 3.12 不可直接降到 Python 3.10 是最省时的方案。我的经验是pysqlcipher3 这类维护频率低的扩展库Python 小版本差半年踩坑时间可能差一天。5.5 vcpkg 装的 OpenSSL 编译报 LNK2038运行库不一致现象使用 vcpkg 安装的 OpenSSL 编译时报LNK2038: 检测到 RuntimeLibrary 不匹配错误信息里会出现MT和MD字样。原因OpenSSL 的预编译库采用的是动态运行库/MD而某些构建配置下 MSVC 默认用了静态运行库/MT被链接时就发生冲突。vcpkg 默认的 triplet 编译出来的是动态库但如果你在setup.py里额外加了/MT编译选项冲突就必然出现。解决不要在setup.py里手动添加/MT或/MD之类的编译选项确保 vcpkg 的 triplet 是x64-windows动态库不要用x64-windows-static。检查方法是在 vcpkg 目录里看triplets文件夹下安装的包名后缀。如果已经在折腾这个换成官方预编译 OpenSSL 1.1.1 包是最快的止损手段——它的libcrypto.lib就是/MD编译的和 Python 扩展模块的默认编译参数对齐。6. 进阶验证加密确实生效并固化编译流程花了大半天把 pysqlcipher3 编译安装成功之后第一件事不是急着跑业务代码而是验证「加密这件事真的发生了」。很多人以为connect时传了key参数就万事大吉实际上编译参数不对、宏定义缺失或者链接到的 SQLite 不是 SQLCipher 分支都会导致加密被静默忽略——数据库文件照样生成打开也是正常的但文件内容是明文。这个坑我踩过一次当时的教训至今印象深刻一个看起来正常工作的加密数据库用记事本打开全是明文。验证方法其实很简单用 pysqlcipher3 创建一个带 key 的数据库然后关掉连接用 Python 内置的只读方式去读那个文件。真正加密的 SQLite 数据库文件头是随机字节绝对不可能出现SQLite format 3这个明文标记。如果用十六进制工具或者 Python 的open().read(16)看一下文件头就能确认。同时你还可以再用 pysqlcipher3 重新打开并执行一条 SQL如果加密配置无效打开时传错的 key 也照样能读出数据这是最直接的破绽。下面这段代码是我每次编译完都会跑的验收脚本它会创建数据库、写入数据、关闭连接然后用两种方式去验证加密是否真实生效import os import tempfile from pysqlcipher3 import dbapi2 # 用临时目录创建测试库避免携带旧数据文件 tmpdir tempfile.mkdtemp() db_path os.path.join(tmpdir, encrypted.db) # 第一次连接设置加密key并写入数据 conn dbapi2.connect(db_path) conn.execute(PRAGMA keytest-passphrase) conn.execute(CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)) conn.execute(INSERT INTO users (name) VALUES (alice)) conn.commit() conn.close() # 检查文件头是否还是明文SQLite标记 with open(db_path, rb) as f: header f.read(16) assert header ! bSQLite format 3\x00, 加密未生效文件头仍是明文SQLite格式 # 用错误的key重新打开应该抛异常或查询失败 conn2 dbapi2.connect(db_path) conn2.execute(PRAGMA keywrong-passphrase) try: conn2.execute(SELECT * FROM users) rows conn2.fetchall() if rows: raise RuntimeError(加密未生效用错误key读出了数据) except dbapi2.DatabaseError as e: print([OK] 错误key被拒绝, 加密有效:, e) finally: conn2.close()这个脚本里PRAGMA key是 pysqlcipher3 启用加密的方式header ! bSQLite format 3\x00是核心断言——SQLite 无加密数据库的固定文件头就是这 16 个字节只要不相等说明至少文件结构已经被混淆了。后面用错误 key 打开执行查询时如果 SQLCipher 工作正常应该抛DatabaseError因为页解密失败。注意一个细节SQLCipher 在文件头没有正确解密时PRAGMA table_info这类查询也可能直接抛异常不需要逐条 SELECT所以拿到DatabaseError基本可以认定加密链路是通的。把这套验证脚本和编译脚本放一起然后我在多台机器上部署时就不再重复人工检查了——直接跑编译脚本再跑验证脚本输出[OK]就放行。从那以后我在做 Python 桌面应用本地存储时都会强制走一遍「编译 → 文件头断言 → 错误 key 拒绝」的完整验证流程而不是看了几行编译日志就觉得完事了。这一步没多花多少时间但能杜绝「编译成功但加密没生效」这种最隐蔽的翻车希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

OpenRig铝型材模拟赛车驾驶舱DIY实操:从选型到实测 2026/10/2 13:54:42

OpenRig铝型材模拟赛车驾驶舱DIY实操:从选型到实测

上个月我又把家里那张电竞桌拆了。原因很简单:夹在桌沿的直驱方向盘第八次把桌面板顶起了一道槽,再玩下去桌子先报废。玩模拟赛车两年、升级了三套设备之后我算是看明白了,真正的瓶颈根本不是电机扭矩,而是你缺一个足够刚性的驾驶…

阅读更多 →
OASIS文件格式原理与IC版图工程实践指南 2026/10/2 13:54:36

OASIS文件格式原理与IC版图工程实践指南

1. 为什么OASIS不是“鼠鼠文件格式”,而是IC版图工程师的生存刚需刚入行那会儿,我第一次收到流片厂发来的GDSII压缩包,解压后发现里面是几十GB的.oas文件,打开一看全是乱码和十六进制字符,同事随口一句“哦&#xff0c…

阅读更多 →
MCP协议实战:用Model Context Protocol打造企业级AI Agent工具链 2026/10/2 13:54:36

MCP协议实战:用Model Context Protocol打造企业级AI Agent工具链

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
数据安全治理1130框架落地实践:从资产盘点、分级分类到零信任闭环 2026/10/2 13:54:30

数据安全治理1130框架落地实践:从资产盘点、分级分类到零信任闭环

做了几年企业数字化转型和数据治理,我越来越发现一个问题:很多团队谈数据安全的时候,还是一上来就买设备、装软件,杀毒、防火墙、审计系统搞了一堆,结果业务部门照样把核心数据往外拖,数据泄露了也说不清楚…

阅读更多 →
没有AI反而火了!LibreOffice一周下载破100万,国产软件该想想了 2026/10/2 13:54:30

没有AI反而火了!LibreOffice一周下载破100万,国产软件该想想了

LibreOffice 26.8 发布。首周官网下载 103.1 万次,历史最高。在所有软件都抢着加 AI 的时候,它宣布:我没有 AI。更有意思的是,这不是忘了加,是故意不加。为什么?LibreOffice 是谁?免费开源办公套…

阅读更多 →
CSP-J2、CSP-S2暴零的原因有哪些 2026/10/2 13:54:29

CSP-J2、CSP-S2暴零的原因有哪些

CSP-J2/CSP-S2复赛暴零的原因90%都不是算法不会,而是踩了OI赛制的细节坑,下面按出现概率从高到低整理所有常见暴零原因,适配四年级信奥选手的认知水平: 📁 文件与提交类(占暴零总数60%,最容易踩…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉