短链接服务从原理到落地:Base62编码与Flask实现

发布时间:2026/8/31 8:32:50

短链接服务从原理到落地:Base62编码与Flask实现
趁着手头项目刚跑通今天用一篇文章把“短链接服务”从原理到落地完整记录下来。如果你经常对接运营分享链路、短信跳转、渠道二维码或者正在做自己的工具站这套方案可以直接拿去改造成项目里需要用的模块。文章里既有短码生成的核心算法拆解也有基于 Python Flask SQLite 的可运行 demo读完你会搞清楚短链接是怎么生成、怎么存、怎么跳转的也能避开不少真实开发中容易踩的坑。1. 背景与核心概念1.1 什么是短链接短链接对应英文 Short Link技术圈通常叫“短链”就是把一个很长的 URL 通过某种算法映射成一个很短、便于记忆和传播的 URL。举个例子原始地址https://blog.csdn.net/xxx/article/details/1300000000?utm_sourcecsdnutm_mediumshare 短链地址https://your.domain/Ab3xQ9用户访问后面这个短地址时服务端会先找到映射关系再通过 HTTP 跳转把用户带到原始地址。整个过程对用户来说是无感的用户只看到地址很短体验上更干净也减少了链接被复制截断的概率。很多开发者会把这个流程和“URL 重定向”概念混在一起。严格来说短链接服务是基于重定向机制实现的业务系统重定向是底层 HTTP 行为短链接是上层业务封装。它做的事情可以概括为两步一是“短码生成”二是“短码到原始 URL 的映射查询”。1.2 短链接解决什么问题短链接不是一个新概念但它至今仍然活跃在很多业务场景里核心原因是它解决了几个实际问题第一长度受限场景。比如短信内容有字数限制微博、私信、评论这类场景也有文本长度限制直接把几百字符的长地址丢进去既不美观也容易被截断。短链能极大降低空间占用。第二渠道追踪需求。运营人员希望知道同一个活动页面在不同渠道的推广效果短链接可以在跳转前记录请求来源、时间、用户设备等信息相当于提前埋了一个可控的入口。第三提升分享体验。各类 IM 工具里一长串带参数的网址很容易被折叠或误判短链更简洁干净点击率通常更高。第四方便统一管理。平台可以批量创建、批量禁用、设置有效期也可以按短码维度统计点击数这在企业内部是高频需求。1.3 短链接服务的基本链路一个最简短的链接服务包含下面几个环节用户把原始 URL 提交给服务端。服务端校验 URL 合法性生成一个唯一短码。服务端把短码和原始 URL 的映射关系写入存储。用户访问短链地址。服务端根据短码查询原始 URL。服务端返回 302 或 301 跳转响应浏览器自动打开原始地址。2. 环境准备与版本说明2.1 基础环境为了让你能直接跟着文章跑通下面给出我本地的环境版本你的版本不一定要完全一致。操作系统Windows 10 / macOS / Linux 均可Python 版本3.8 及以上Web 框架Flask 2.x数据库SQLite 3Python 自带无需额外安装依赖文件只有 Flask 一个第三方库安装命令pip install flask如果网络环境使用国内镜像可以换成pip install flask -i https://pypi.tuna.tsinghua.edu.cn/simple2.2 项目结构为了保持代码清晰我们把项目拆成几个独立文件short-link/ ├── app.py # Flask 应用入口包含接口路由 ├── db.py # 数据库初始化和连接工具 ├── shortener.py # 短码生成算法 └── requirements.txt这个拆分方式在工程上比较推荐避免把路由、数据库、算法都塞在一个文件里。项目不大时也许无所谓但后面扩展功能时会发现拆开更好维护。3. 短码生成算法拆解短码是整个短链接服务的核心。一个好的短码生成方案需要考虑这几个问题唯一性同一个短码不能对应多个地址。长度越短越方便但太短容易碰撞。性能生成过程不能太重否则高并发下会拖垮服务。可扩展发码逻辑不能依赖单点。3.1 常见短码生成方案对比先梳理一下业界常用的方案方案原理优点缺点随机字符串直接生成固定长度随机字符串实现简单长度可控需要查重冲突概率随数量上升MD5/SHA1 摘要截取对原始 URL 做哈希截取片段相同 URL 会得到相同短码存在碰撞概率需要处理冲突自增 ID 转 Base62利用数据库自增 ID 换算成短码完全不冲突实现简单依赖发号器ID 可预测分布式发号器雪花 ID 等生成全局 ID 再编码适合分布式集群组件较重需要额外维护预生成短码池提前生成大量短码放入池子分配速度快维护成本高如果你的项目是小型应用、内部工具、个人博客自增 ID 转 Base62 是最省事的方案。它不需要判断短码是否重复因为数据库自增 ID 本身是唯一的只要把整数转成对应字符串即可。3.2 Base62 编码原理Base62 是一种基于 62 个字符的编码方式字符集一般由 0-9、a-z、A-Z 组成共 62 个字符。它的作用和把十进制数字转换成十六进制字符串类似只是基数从 16 变成了 62。Base62 的好处是可读性好没有 / 这些 URL 特殊字符不区分大小写的场景虽然会带来麻烦但多数系统默认是区分大小写的。自增 ID 转短码的公式十进制 ID 对 62 取模余数对应字符集里的某个字符。商继续对 62 取模直到商为 0 为止。从后往前拼接字符即为短码。下面是 Python 实现# 文件路径short-link/shortener.py BASE62_ALPHABET 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ BASE len(BASE62_ALPHABET) def encode_base62(num: int) - str: 将十进制整数转换为 Base62 字符串。 例如1 - 162 - 1063 - 11 if num 0: return BASE62_ALPHABET[0] code [] while num 0: num, remainder divmod(num, BASE) code.append(BASE62_ALPHABET[remainder]) return .join(reversed(code)) def decode_base62(code: str) - int: 将 Base62 字符串还原为十进制整数。 例如1 - 110 - 62 num 0 for char in code: num num * BASE BASE62_ALPHABET.index(char) return num使用divmod可以一次性得到商和余数代码更简洁。reversed是因为我们取余数时是从低位开始拼接时需要反转。3.3 冲突处理自增 ID 方案天然没有短码冲突但如果使用随机字符串或哈希截取方案就必须处理冲突。常见的做法是在生成短码后去数据库查询一次如果发现短码已存在就重新生成或加随机后缀重试。4. 完整实战案例基于 Flask SQLite 搭建短链接服务4.1 创建项目结构在本地创建一个名为short-link的目录并在里面创建四个文件。如果你使用命令行可以这样操作mkdir short-link cd short-link然后创建requirements.txtflask2.3.34.2 定义数据表与数据库工具创建db.py负责数据库初始化和连接获取。# 文件路径short-link/db.py import sqlite3 from flask import g DATABASE short_link.db def init_db(): 初始化数据库表结构。 每次启动服务时调用表已存在时不会重复创建。 conn sqlite3.connect(DATABASE) conn.execute( CREATE TABLE IF NOT EXISTS url_mapping ( id INTEGER PRIMARY KEY AUTOINCREMENT, code TEXT NOT NULL UNIQUE, original_url TEXT NOT NULL, created_at TEXT DEFAULT (datetime(now, localtime)), expire_at TEXT ) ) conn.commit() conn.close() def get_db(): 从 Flask 应用上下文中获取数据库连接。 Flask 会将连接保存在 g 对象上同一个请求复用同一连接。 if db not in g: g.db sqlite3.connect(DATABASE) g.db.row_factory sqlite3.Row return g.db这里用到了 Flask 的g对象它可以在一次请求中共享数据。每次请求结束后需要关闭连接否则会占用连接资源。关于关闭的逻辑我们稍后在主应用里注册teardown回调。4.3 实现短码生成模块shortener.py在上文已经给出这里我们再补充一个generate_code函数便于接口中直接调用。# 文件路径short-link/shortener.py BASE62_ALPHABET 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ BASE len(BASE62_ALPHABET) def encode_base62(num: int) - str: if num 0: return BASE62_ALPHABET[0] code [] while num 0: num, remainder divmod(num, BASE) code.append(BASE62_ALPHABET[remainder]) return .join(reversed(code)) def decode_base62(code: str) - int: num 0 for char in code: num num * BASE BASE62_ALPHABET.index(char) return num def generate_code(url_id: int) - str: 根据数据库自增 ID 生成短码。 为了兼容短链长度预期这里不做最小长度填充。 return encode_base62(url_id)4.4 实现 Flask 应用与接口创建app.py这里是最核心的部分。# 文件路径short-link/app.py import re import sqlite3 from flask import Flask, jsonify, redirect, request, render_template_string, g from db import init_db, get_db from shortener import generate_code app Flask(__name__) app.config[JSON_AS_ASCII] False INDEX_PAGE !DOCTYPE html html langzh head meta charsetUTF-8 title短链接分享小工具/title /head body h2输入一个长链接生成短链接/h2 form methodpost action/api/shorten input typeurl nameurl placeholderhttps://blog.csdn.net size50 required button typesubmit生成/button /form /body /html URL_PATTERN re.compile(r^https?://, re.IGNORECASE) app.teardown_appcontext def close_db(error): 请求结束后关闭数据库连接。 db g.pop(db, None) if db is not None: db.close() def is_valid_url(url: str) - bool: 简单校验 URL 是否以 http:// 或 https:// 开头。 生产环境通常还会校验域名白名单这里只做基础判断。 if not url or not isinstance(url, str): return False if len(url) 2048: return False return bool(URL_PATTERN.match(url)) app.route(/, methods[GET]) def index(): return INDEX_PAGE app.route(/api/shorten, methods[POST]) def shorten(): 生成短链接接口。 支持两种提交方式 1. JSON: {url: https://example.com/xxx} 2. 表单: url... data request.get_json(silentTrue) or request.form original_url data.get(url, ).strip() if not is_valid_url(original_url): return jsonify({error: 请输入合法的 http/https 链接}), 400 db get_db() cursor db.execute( INSERT INTO url_mapping (original_url) VALUES (?), (original_url,), ) db.commit() url_id cursor.lastrowid code generate_code(url_id) # 把生成的短码写回记录方便后续通过短码查询原始 URL db.execute( UPDATE url_mapping SET code ? WHERE id ?, (code, url_id), ) db.commit() short_url f{request.host_url}{code} return jsonify({ code: code, original_url: original_url, short_url: short_url, }) app.route(/code, methods[GET]) def redirect_to_original(code: str): 根据短码跳转到原始 URL。 短码未找到时返回 404不会盲目跳转。 db get_db() row db.execute( SELECT original_url FROM url_mapping WHERE code ?, (code,), ).fetchone() if row is None: return 短链接不存在或已过期, 404 original_url row[original_url] if not is_valid_url(original_url): return 原始链接不合法, 400 return redirect(original_url, code302) if __name__ __main__: init_db() app.run(host127.0.0.1, port5000, debugTrue)这里有几个细节要说明一下。第一创建短码时我们不直接在插入语句里生成code而是先插入原始 URL拿到自增 ID 后再更新code。因为自增 ID 需要数据库生成两种方式二选一即可。第二种方式更直观db.execute( INSERT INTO url_mapping (code, original_url) VALUES (?, ?), (generate_code(next_id), original_url), )第二种方式需要先查询下一个自增 ID在并发场景下不可靠所以上面的代码里采用“先插入再回写”的方式这是 SQLite 单库并发下最简单可靠的做法。第二跳转使用 302 临时重定向。这一点很重要如果使用 301 永久重定向浏览器会缓存原始地址后续无法通过短链统计点击数据也没办法做过期处理。所以做短链接服务时通常优先用 302。第三request.host_url返回的是当前请求的协议和域名例如http://127.0.0.1:5000/这样生成完整短链时不用手写域名。4.5 运行与验证在项目根目录执行python app.py看到类似输出说明启动成功* Running on http://127.0.0.1:5000打开浏览器访问http://127.0.0.1:5000/会看到一个简单的表单页面输入长链接后点击生成页面返回 JSON 结果。也可以使用 curl 来验证接口curl -X POST http://127.0.0.1:5000/api/shorten \ -H Content-Type: application/json \ -d {url: https://blog.csdn.net/nav/python}预期返回{ code: 1, original_url: https://blog.csdn.net/nav/python, short_url: http://127.0.0.1:5000/1 }访问http://127.0.0.1:5000/1后浏览器会 302 跳转到https://blog.csdn.net/nav/python。4.6 结果说明第一次生成时code是1因为数据库里第一条自增 ID 就是 1。Base62 编码结果为1此时短链长度只有 1 位。当 ID 增加到比较大的值时短码才会变长。5. 常见问题与排查思路5.1 访问短链返回 404问题现象常见原因解决思路访问短链 404短码不存在或数据库中无对应记录检查数据库中url_mapping表记录是否写入成功访问短链 404短码大小写不一致Base62 区分大小写确认访问路径与存储短码完全一致访问短链 404服务重启后数据库丢失确认没有误删short_link.db文件或改用持久化数据库5.2 中文 URL 或带特殊参数的 URL 报错URL 中包含中文时客户端提交之前通常会做 URL 编码。如果没有编码服务端收到的可能是非 ASCII 字符跳转时可能出现乱码。解决方法是在保存原始 URL 前统一转成标准格式或者依赖前端先执行一次encodeURIComponent。在服务端 Python 中也可以使用urllib.parse.quote做处理但要注意不要对完整 URL 整体编码否则http://里的冒号和斜杠也会被转义。建议的做法是解析 URL 后只对路径和参数部分重新编码。5.3 短码冲突如果使用随机字符串方案高并发下短码冲突概率会明显上升。遇到UNIQUE constraint failed报错时说明你生成的短码已经被使用过了。解决思路是捕获sqlite3.IntegrityError异常重新生成短码并重试重试次数通常控制在 3 到 5 次。5.4 并发写入 SQLite 报错SQLite 支持多个连接同时读写但在高并发写入场景下可能抛出database is locked。这是因为 SQLite 同一时刻只允许一个写事务。如果是个人项目或内部工具SQLite 完全够用。如果是公网服务建议切换 MySQL 或 PostgreSQL并引入连接池。查询量增大后可以在短码和原始 URL 的映射上增加 Redis 缓存。5.5 排查清单写一个通用的排查顺序确认短链接是否真的进入了数据库。确认短码是否被正确生成并回写。直接用 curl 访问短链观察响应头里的Location字段。查看 Flask 控制台日志确认请求是否匹配到路由。检查浏览器是否缓存了 301 跳转。6. 最佳实践与工程建议6.1 短码设计与压缩策略自增 ID 转 Base62 方案虽然简单但短码长度会随着 ID 变大而变化。业务上线一段时间后短码可能从 1 位变成 6 位、8 位这会给用户带来不稳定感。更常见的做法是生成固定长度短码例如 6 位或 7 位。使用随机字符串或哈希截取生成后查重。如果冲突加随机后缀重新生成。固定长度短码更适合对外展示。下面是一个基于随机字符串的实现思路import random import string CODE_LENGTH 6 def generate_random_code(): chars string.ascii_letters string.digits return .join(random.choices(chars, kCODE_LENGTH))选择 6 位 Base62 编码可以容纳 62 的 6 次方约 568 亿个组合正常情况下足够使用。6.2 存储与缓存SQLite 适合单体小项目但不适合高并发、分布式环境。生产环境建议使用 MySQL 或 PostgreSQL存储表结构可以这样设计字段类型说明idBIGINT主键codeVARCHAR(16)短码唯一索引original_urlVARCHAR(2048)原始 URLcreated_atDATETIME创建时间expire_atDATETIME过期时间可空click_countINT点击次数访问短链时如果每次都查询数据库在大流量场景下数据库压力很大。建议引入 Redis 缓存key: short:link:{code} value: original_url TTL: 按业务设置比如 7 天读取顺序请求短码先查 Redis。命中则直接跳转。未命中则查数据库回填 Redis再跳转。这里要注意缓存穿透问题也就是短码不存在时 Redis 也查不到。可以设置一个空值短 TTL或者使用布隆过滤器做第一层拦截。6.3 安全边界短链接服务天然是一个开放跳转入口如果被恶意利用很容易变成钓鱼链接或垃圾链接的跳板。安全方面至少要考虑这些问题原始 URL 合法校验不能允许javascript:、file:等非 HTTP 协议。URL 白名单企业场景下限制只能创建指定域名下的短链。恶意链接检测对接安全服务识别钓鱼、赌博、色情等恶意站点。防止内部地址泄露屏蔽127.0.0.1、localhost、内网 IP 段避免被用来做 SSRF 探测。跳转风险提示如果原始 URL 不在白名单可以在跳转前展示一个安全提醒页。6.4 可观测性与防刷短链接服务最容易遇到两类问题一是被刷接口二是无法追踪故障。防刷可以从几个维度入手接口限流按 IP、用户 ID、设备指纹维度限制单位时间内创建短链和访问短链的次数。签名校验系统内部调用时带上签名参数拒绝空签名或过期签名。验证码非登录用户创建短链时要求输入验证码。日志方面每一项创建和访问都应该记录操作者、原始 URL、短码、时间、IP、User-Agent。有了这些数据才能做链路排查和运营分析。7. 总结与学习路线本文从一个短链接服务的需求出发介绍了短链接的核心概念、短码生成算法、数据库表设计并用 Flask SQLite 实现了一个可运行的最小系统。重点在于理解短码生成的自增 ID 转 Base62 方案以及为什么要用 302 跳转而不是 301。如果你想继续深入可以考虑这几个方向使用 Redis 做缓存层提升高并发访问性能。使用雪花 ID 或美团 Leaf 发号器替代自增 ID支撑多实例部署。把创建短链、访问短链的日志接入消息队列做离线统计。增加用户体系和权限控制让短链可按用户维度管理。在实际开发中短链接服务看起来简单但每一步都有不少细节。特别是安全边界和并发处理一定要在项目上线前多做测试。希望这篇文章能帮你快速跑通第一版后续再根据自己的业务场景逐步完善。

相关新闻

PLC编程进制转换与数据类型详解:从通信报文到工程实战

PLC编程进制转换与数据类型详解:从通信报文到工程实战

2026/8/31 8:32:50

在实际 PLC 编程项目中,进制转换和数据类型从来不只是教科书里的基础概念。程序跑不起来、通信读出来是乱码、触摸屏显示数值不对、模拟量换算结果异常,追到根上,很多问题都出在这两个知识点上。PLC 的 CPU 内部只能处理 0 和 1,但…

别再手绘图表了:PPT Master 33 种 SVG 图表模板快速上手指南

别再手绘图表了:PPT Master 33 种 SVG 图表模板快速上手指南

2026/8/31 8:32:50

别再手绘图表了:PPT Master 33 种 SVG 图表模板快速上手指南 【免费下载链接】ppt-master AI turns documents or topics into real, native PowerPoint decks—with native shapes, transitions and animations, data-backed charts and tables on demand, audio n…

Cherry Studio 快速上手:三步本地跑通这个 300+ 助手的 AI 桌面工作台

Cherry Studio 快速上手:三步本地跑通这个 300+ 助手的 AI 桌面工作台

2026/8/31 8:32:50

Cherry Studio 快速上手:三步本地跑通这个 300 助手的 AI 桌面工作台 【免费下载链接】cherry-studio AI productivity studio with smart chat, autonomous agents, and 300 assistants. Unified access to frontier LLMs 项目地址: https://gitcode.com/GitHub_…

2026年PyTorch与TensorFlow选型:三小时入门路线与核心实战

2026年PyTorch与TensorFlow选型:三小时入门路线与核心实战

2026/8/31 9:32:53

如果你现在准备进入 AI 方向,或者在 2026 年这个节点想把研究、项目和求职往前推一步,第一个要拍板的问题大概率是:学 PyTorch 还是 TensorFlow? 先说结论:从论文开源率、模型生态、招聘 JD 和科研协作的整体趋势来看…

从零到一:Databricks AI Dev Kit完整学习路线图(新手必看)

从零到一:Databricks AI Dev Kit完整学习路线图(新手必看)

2026/8/31 9:32:53

从零到一:Databricks AI Dev Kit完整学习路线图(新手必看) 【免费下载链接】ai-dev-kit Databricks Toolkit for Coding Agents provided by Field Engineering 项目地址: https://gitcode.com/GitHub_Trending/ai/ai-dev-kit Databri…

Fooocus:3 步出图的免费离线 AI 绘图完整教程

Fooocus:3 步出图的免费离线 AI 绘图完整教程

2026/8/31 9:32:53

Fooocus:3 步出图的免费离线 AI 绘图完整教程 【免费下载链接】Fooocus Focus on prompting and generating 项目地址: https://gitcode.com/GitHub_Trending/fo/Fooocus 想用自己电脑生成 AI 图像,又不想折腾环境、调参数?Fooocus 可…

Pocket TTS torchao与torch.ao量化后端对比:ARM和x86引擎选择全解

Pocket TTS torchao与torch.ao量化后端对比:ARM和x86引擎选择全解

2026/8/31 9:32:53

Pocket TTS torchao与torch.ao量化后端对比:ARM和x86引擎选择全解 【免费下载链接】pocket-tts A TTS that fits in your CPU (and pocket) 项目地址: https://gitcode.com/GitHub_Trending/po/pocket-tts 🎯 Pocket TTS 是一款专为 CPU 设计的轻…

MiroFish 部署指南:Docker Compose 一键部署群体智能预测引擎

MiroFish 部署指南:Docker Compose 一键部署群体智能预测引擎

2026/8/31 9:32:52

MiroFish 部署指南:Docker Compose 一键部署群体智能预测引擎 【免费下载链接】MiroFish A Simple and Universal Swarm Intelligence Engine, Predicting Anything. 简洁通用的群体智能引擎,预测万物 项目地址: https://gitcode.com/GitHub_Trending/…

DQPSK调制解调Matlab仿真:从原理到误码率曲线全解析

DQPSK调制解调Matlab仿真:从原理到误码率曲线全解析

2026/8/31 9:22:52

简介:本资源是一份面向通信工程专业学生、初学者及MATLAB实践者的DQPSK调制解调完整仿真代码包,聚焦数字通信中差分四相键控的核心原理与工程实现。压缩包共7个MATLAB源文件(.m),总大小仅4KB,涵盖信号生成、…

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

2026/8/31 1:38:25

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

2026/8/31 7:20:57

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

2026/8/30 0:01:07

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

MCU无DAC如何用定时器+DMA 2D输出高保真任意波形

MCU无DAC如何用定时器+DMA 2D输出高保真任意波形

2026/8/31 0:02:27

接到一个仪表类项目,要在 LAT1189 上输出几种不同波形:正弦、三角、带可调死区的脉冲,频率和幅度都得能实时改。板子上没有 DAC,就一个定时器加几个 DMA 通道。我一开始觉得在定时器中断里改比较寄存器也能应付,后来把…

Cortex-M3 Flash下载失败?从编程错误标志到供电瞬态排查

Cortex-M3 Flash下载失败?从编程错误标志到供电瞬态排查

2026/8/31 0:02:27

前两周调试一块带着Cortex-M3内核的板子,IDE里下载固件时突然弹出一行刺眼的错误: error: flash download failed - cortex-m3 。这种报错在嵌入式开发里太常见了,常见到很多人第一反应就是换根数据线、重插一下调试器,但重启三…

STM32 TouchGFX屏幕切换Transition优化:原理、配置与排障实战

STM32 TouchGFX屏幕切换Transition优化:原理、配置与排障实战

2026/8/31 0:02:27

做STM32 GUI开发的朋友应该都有体会——界面搭得再漂亮,一旦屏幕切换卡成PPT,整个产品的档次瞬间就没了。早期我在LAT1212这个基于STM32的GUI工程上用TouchGFX做二次开发,最头疼的不是画界面,而是怎么让切换动画既流畅又自然。Tou…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/28 7:35:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/28 7:34:51

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/28 7:34:35

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…