news 2026/9/28 11:22:46

微信小程序+Flask实战:校园表白墙与失物招领平台开发全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微信小程序+Flask实战:校园表白墙与失物招领平台开发全解析

做校园表白墙这类项目,选型第一件事就是想清楚:给谁用、跑在哪、谁维护。我见过不少同学一上来就上前后端分离,配 Vue + Node + MongoDB,结果部署时把自己卡死在服务器上。其实在校园这个场景里,微信小程序 + Flask 是我反复对比后觉得最实在的组合,没有之一。

表白墙本质是一个以匿名互动为核心的信息交流平台,核心需求就两件事:能发内容、能看内容,在此基础上再叠加评论、点赞、分类板块、信息匹配推荐这些扩展能力。微信小程序天然解决了“不用装 App、扫码即用”的入口问题,Flask 则保证了后端能在三天之内从零跑到上线——这对课设、毕设、甚至一个社团的校内小项目来说,开发效率和维护成本都太重要了。

这篇文章我会完整拆解这个小程序 + Flask 表白墙平台的搭建过程,从项目结构设计、数据库表怎么建,到后端接口怎么写、推荐匹配怎么做,再到小程序端页面怎么对接,最后把我在实际部署中踩过的坑一并列出来。无论你是准备做毕设、课设,还是真想在校内跑一个这样的小平台,照着这篇文章捋一遍,心里基本就有底了。

1. 项目整体设计与思路拆解

1.1 为什么选微信小程序 + Flask,而不是别的组合

先说结论:这个组合在“学生项目、轻量部署、快速上线”这三个条件下的性价比是最高的。

用微信小程序做前端,最大的好处是零安装成本。校园场景里没人愿意为了看个表白墙去下载一个 App,小程序扫码即用、用完即走,传播起来特别方便。另一个好处是它自带审核机制,平台上的内容天然有一个官方层面的监管兜底,这对内容安全非常重要。

后端用 Flask,核心理由是轻。它不像 Django 那样给你全套默认配置,但写这种中小型业务接口,Flask 一行路由对应一个函数,逻辑极其直观。再加上 Python 生态里现成的分词库、相似度计算库,后期做“失物招领智能匹配”这类功能时,几乎不用额外造轮子。

我遇到不少人在 Flask 和 FastAPI 之间纠结,实测下来:如果只是校内项目、不需要异步高并发,Flask 的成熟度、资料丰富度、部署方案成熟度都更稳。你要是真想用 FastAPI 也行,但从“复制粘贴报错到百度能搜到答案”这个角度看,Flask 的优势太明显了。

1.2 整体架构与核心功能模块

平台整体分三层:

  • 小程序端:负责展示、发布、互动。核心页面包括首页信息流、表白墙发布页、失物招领板块、个人中心。
  • Flask 后端:提供 RESTful API,处理登录鉴权、内容发布、评论点赞、关键词匹配推荐。
  • 数据库层:轻量起步用 SQLite,后期如果访问量上来了再平滑迁移 MySQL。

核心功能模块我按优先级分了三档:

  • 基础功能:匿名发布表白/树洞内容、内容审核、评论、点赞。
  • 扩展功能:分类板块(表白墙、失物招领、二手集市、校园树洞)。
  • 亮点功能:基于关键词相似度的失物招领智能匹配推荐。

1.3 为什么把失物招领和智能匹配放进同一个平台

很多人看到“校园表白墙”五个字,就觉得做个发帖、看帖功能就够了。但我在实际调研中发现,表白墙这种平台天然聚集了大量校内流量,学生对它的信任度很高。如果能把失物招领这种刚需功能嵌进去,平台的价值会从“娱乐社交”升级到“校园生活服务”。

最关键的是,失物招领是最适合做智能匹配的场景:用户描述丢失物品和捡到物品时,天然会用关键词来描述(品牌、颜色、物品类型、地点)。把这些关键词提取出来做相似度匹配,推荐精度会非常直观。

我当时的设计思路是:表白墙负责流量和氛围,失物招领负责实用价值,匹配推荐负责把两者串联起来。这也是整篇博文后面会重点展开的核心环节。

2. 数据库设计与后端核心实现

2.1 表结构设计:从用户到内容的完整链路

数据库是整个平台的地基。我首版设计的表结构共五张表,足够覆盖表白墙 + 失物招领的所有核心场景:

用户表(users)

字段类型说明
idINTEGER PK用户ID
openidVARCHAR(64)微信唯一标识,登录鉴权核心
nicknameVARCHAR(32)昵称
avatarVARCHAR(255)头像URL
roleTINYINT角色:0普通用户,1管理员
created_atDATETIME注册时间

帖子表(posts)

字段类型说明
idINTEGER PK帖子ID
user_idINTEGER FK发布者ID
categoryTINYINT分类:1表白,2树洞,3失物,4招领,5二手
contentTEXT正文内容
imagesTEXT图片URL,多个用逗号分隔
is_anonymousTINYINT是否匿名
statusTINYINT状态:0待审核,1通过,2拒绝
likes_countINTEGER点赞数
comments_countINTEGER评论数
created_atDATETIME发布时间

评论表(comments):记录评论者、所属帖子、内容、创建时间,关联帖子ID建索引。

点赞表(likes):联合唯一索引 (user_id, post_id),避免重复点赞。

匹配记录表(match_records):记录失物和招领之间的匹配关系,用于推荐展示和去重。

这里有一个关键设计决策:is_anonymous单独一个字段,而不是把用户信息抹掉。因为后台管理员需要看到真实用户ID来管理内容,而小程序端渲染时根据这个字段决定是否显示昵称。匿名只是展示层的匿名,不是数据库层的匿名,这一点在做内容审核时必须想清楚。

2.2 Flask 项目结构与API路由设计

后端代码结构我用的是蓝图的模块化方式:

flask-backend/ ├── app.py # 程序入口 ├── config.py # 配置 ├── models.py # 数据库模型 ├── extensions.py # db实例 ├── blueprints/ │ ├── auth.py # 登录鉴权 │ ├── posts.py # 帖子相关 │ ├── comments.py # 评论 │ ├── likes.py # 点赞 │ └── match.py # 失物招领匹配 └── utils/ ├── auth.py # JWT token处理 ├── sensitive.py # 敏感词过滤 └── similarity.py # 相似度算法

API 路由设计遵循 RESTful 风格,下面这几个是最核心的接口:

方法路径功能
POST/api/auth/login微信登录,换取JWT token
GET/api/posts获取帖子列表,支持分类、分页
POST/api/posts发布新帖子
GET/api/posts/{id}帖子详情
POST/api/posts/{id}/comment发表评论
POST/api/posts/{id}/like点赞/取消点赞
GET/api/match/recommend获取匹配推荐列表
GET/api/admin/posts/pending获取待审核列表
POST/api/admin/posts/{id}/audit审核帖子

以发布帖子为例,实际的 Flask 视图函数大概是这样的:

@posts_bp.route('/api/posts', methods=['POST']) @jwt_required def create_post(): user_id = get_jwt_identity() data = request.get_json() # 内容清洗与校验 content = data.get('content', '').strip() category = data.get('category', 1) if not content: return jsonify(code=400, msg='内容不能为空'), 400 if len(content) > 500: return jsonify(code=400, msg='内容不能超过500字'), 400 # 敏感词过滤 if sensitive_filter(content): return jsonify(code=400, msg='内容包含违规词汇'), 400 post = Post( user_id=user_id, category=category, content=content, images=','.join(data.get('images', [])), is_anonymous=data.get('is_anonymous', 1), status=0 # 新帖默认待审核 ) db.session.add(post) db.session.commit() return jsonify(code=200, msg='发布成功,等待审核', data={'post_id': post.id})

这里有几个细节要特别说明:

  • status 默认 0(待审核),而不是直接通过。因为表白墙是公开内容平台,先审后发是底线。
  • 长度校验和服务端二次校验,小程序端虽然做了限制,但后端的校验绝不能省。凡是能看到的内容,都有可能被直接调接口发过来。
  • 敏感词过滤封装成独立工具函数,不是简单 replace,而是用正则做得更细,比如谐音、中间插符号的情况也能命中。

2.3 登录鉴权:微信登录怎么做

微信小程序登录的标准流程是:小程序端调用wx.login()获取 code → 传给后端 → 后端拿着 code 调微信接口换 openid → 生成自定义登录态 token 返回给小程序。

@auth_bp.route('/api/auth/login', methods=['POST']) def login(): code = request.get_json().get('code') if not code: return jsonify(code=400, msg='缺少code参数'), 400 # 用code换取openid url = 'https://api.weixin.qq.com/sns/jscode2session' params = { 'appid': app.config['WX_APPID'], 'secret': app.config['WX_SECRET'], 'js_code': code, 'grant_type': 'authorization_code' } resp = requests.get(url, params=params).json() if 'errcode' in resp: return jsonify(code=400, msg='微信登录失败'), 400 openid = resp['openid'] # 查库,新用户自动注册 user = User.query.filter_by(openid=openid).first() if not user: user = User(openid=openid, nickname=f'用户{random.randint(1000,9999)}') db.session.add(user) db.session.commit() # 生成JWT token,有效期7天 token = create_access_token(identity=user.id, expires_delta=timedelta(days=7)) return jsonify(code=200, msg='登录成功', data={'token': token, 'user': user.to_dict()})

在实际开发中,微信支付、订阅消息等高级功能可以之后再加,但登录这一步是所有功能的前提,建议最早做通。这里有个容易踩的坑:微信小程序的 code 只能用一次,所以前端不能重复调wx.login(),否则会报invalid code。正确做法是登录成功后把 token 存进 storage,过期了才重新登录。

3. 微信小程序端实现要点

3.1 项目初始化与请求封装

小程序端我用的原生框架,没有引第三方框架。理由很实在:表白墙这种业务复杂度,原生开发完全够用,还能避免 uniapp 打包后的一些样式兼容问题。

创建项目后在app.js里做全局配置:

App({ globalData: { baseUrl: 'http://127.0.0.1:5000/api', // 本地调试 token: '', userInfo: null }, onLaunch() { // 从缓存恢复登录态 const token = wx.getStorageSync('token'); if (token) { this.globalData.token = token; } } })

请求封装是我最看重的一块。直接在页面里写wx.request会让自己陷入大量重复代码,而且后期改 baseURL、统一处理 401 都麻烦。所以我把它封装成一个独立的工具模块:

// utils/request.js const request = (url, method = 'GET', data = {}) => { return new Promise((resolve, reject) => { wx.request({ url: getApp().globalData.baseUrl + url, method, data, header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + getApp().globalData.token }, success(res) { if (res.statusCode === 401) { // token过期,跳转登录 wx.navigateTo({ url: '/pages/login/login' }); reject(res); } else if (res.data.code === 200) { resolve(res.data.data); } else { wx.showToast({ title: res.data.msg, icon: 'none' }); reject(res.data); } }, fail(err) { wx.showToast({ title: '网络异常', icon: 'none' }); reject(err); } }); }); };

页面里调用就变成:

const posts = await request('/posts?category=1&page=1', 'GET');

这里封装统一处理了 token 注入、状态码判断、错误提示,页面代码不用管这些乱七八糟的逻辑,专注业务就行。

3.2 核心页面与发布审核流程

首页信息流是最核心的页面。我采用标签页 + 下拉刷新 + 触底加载的交互方式,因为表白墙的内容形态本质上就是信息流,用户已经习惯了这种浏览方式。

首页的 tab 切换代码逻辑:

// pages/index/index.js Page({ data: { activeTab: 1, // 当前分类 posts: [], page: 1, hasMore: true, loading: false }, onLoad() { this.loadPosts(true); }, async loadPosts(reset) { if (this.data.loading) return; this.setData({ loading: true }); const page = reset ? 1 : this.data.page; const posts = await request(`/posts?category=${this.data.activeTab}&page=${page}`); this.setData({ posts: reset ? posts : [...this.data.posts, ...posts], page: page + 1, hasMore: posts.length === 10, loading: false }); }, onReachBottom() { if (this.data.hasMore) this.loadPosts(false); }, onPullDownRefresh() { this.loadPosts(true).then(() => wx.stopPullDownRefresh()); }, switchTab(e) { this.setData({ activeTab: e.currentTarget.dataset.id }, () => { this.loadPosts(true); }); } });

发布页的设计则要强调“引导性”。用户在输入框里打字时,如果内容围绕感情表达,就分类到表白墙;如果围绕物品描述,就提醒可以选失物招领。我当时的做法是放几个快捷标签,点击自动填入一些句式,降低用户输入门槛。

发布成功后不直接展示,而是弹窗提示“已提交,等待审核”。这个反馈很重要,它建立了用户对平台的信任感。审核列表页则独立放在管理员入口,普通用户不可见。

3.3 缓存处理与交互体验优化

小程序端的性能优化容易被忽视,但实际体验差异很大。我在开发中主要做了三件事:

第一,合理使用缓存。首页信息流数据用wx.setStorageSync缓存一份,用户再次进入时先渲染缓存、再请求最新数据,体验上会觉得“秒开”。缓存时间根据内容更新频率设置,表白墙的缓存可以设短一点,30到60秒比较合适。

第二,图片懒加载和列表虚拟化。表白墙帖子带图片的情况很常见,如果首页一次性渲染几十张图片,内存占用会明显升高。图片组件加上lazy-load属性,列表用wx:for渲染时给每条加一个wx:key,避免渲染时的性能损耗。

第三,处理顶部导航栏高度。不同手机型号的胶囊按钮位置不一样,如果做自定义导航,需要动态获取状态栏高度,否则按钮会偏。一个简单的适配方案:

const menuRect = wx.getMenuButtonBoundingClientRect(); const statusBarHeight = wx.getWindowInfo().statusBarHeight; this.setData({ navHeight: menuRect.height + (menuRect.top - statusBarHeight) * 2, statusBarHeight: statusBarHeight });

这些细节单个看起来不起眼,但全部做下来,整个小程序的流畅度会明显高于那些“功能能跑就行”的项目。

4. 智能匹配推荐:失物招领与表白墙的算法串联

4.1 为什么需要关键词相似度匹配,而不是简单等值查询

失物招领功能的本质是:失主描述“我丢了一个东西”和拾主描述“我捡到一个东西”,两种描述在语义上指向同一个实物。如果只做等值查询,用户得填完全一致的物品名称才能匹配,但在真实校园场景里这是几乎不可能的。

举一个非常典型的场景:

  • 失主发帖:“在二食堂门口丟了一个黑色华为手机,屏幕右下角有点碎。”
  • 拾主发帖:“捡到一部手机,黑色外壳,看型号是华为的。”

如果拿“黑色华为手机”和“捡到一部手机”做字符串匹配,完全匹配不上。但人一眼就能看出来这俩大概率是同一部手机。关键词相似度算法的价值就在这里:它能把描述里的关键实体词提取出来,计算两段文字在语义层面的重叠程度,从而自动捕捉这种“看起来不同、其实相关”的关系。

4.2 jieba分词 + 关键词权重计算

我用的技术方案是:jieba 分词 + 关键词集合 + Jaccard 相似度 + TF-IDF 权重的组合。这套组合在纯 Python 环境下就能跑,不需要额外安装重型机器学习库,非常适合轻量级平台。

核心匹配流程分三步:

第一步:分词并过滤无效词。把内容里的语气词、助词、标点全部去掉,只保留名词、动词、形容词等有实际语义的词。

import jieba import jieba.posseg as pseg STOP_WORDS = set(['的', '了', '在', '是', '我', '你', '他', '这个', '那个', '一个']) def extract_keywords(text): words = pseg.cut(text) keywords = [] for word, flag in words: if word in STOP_WORDS: continue if len(word) < 2: # 单字词信息量低,过滤 continue if flag in ['n', 'nr', 'ns', 'nt', 'v', 'vn', 'a']: # 名词、动词、形容词 keywords.append(word.lower()) return keywords

第二步:为关键词分配权重。物品类型词(手机、书包)权重最高,品牌词(华为、苹果)次之,颜色词再次之,地点词因为信息价值高也给了较高权重。

WEIGHT_MAP = { 'n': 1.5, # 普通名词(物品类型) 'nr': 1.5, # 人名(可能包含品牌) 'ns': 1.2, # 地点名 'v': 1.0, # 动词 'vn': 1.2, # 动名词(操作行为) 'a': 0.8, # 形容词(颜色、状态) } def build_weighted_keywords(text): keywords = extract_keywords(text) weights = {} for word, flag in pseg.cut(text): if word.lower() in keywords: weights[word.lower()] = WEIGHT_MAP.get(flag, 1.0) return weights

第三步:计算相似度。我用的是带权重的 Jaccard 相似度。标准 Jaccard 是交集大小除以并集大小,带权重版本则考虑共同命中词的权重之和,公式效果更贴合场景:

def calculate_similarity(lost_keywords, found_keywords): lost_set = set(lost_keywords.keys()) found_set = set(found_keywords.keys()) if not lost_set or not found_set: return 0.0 intersection = lost_set & found_set union = lost_set | found_set if not union: return 0.0 # 共同词的权重求和 weight_sum = 0 for word in intersection: weight_sum += min(lost_keywords[word], found_keywords[word]) return weight_sum / len(union)

以刚才那个例子计算:失主的关键词集合是 {二食堂, 门口, 黑色, 华为, 手机, 屏幕},拾主的关键词集合是 {手机, 黑色, 华为},交集是 {手机, 黑色, 华为},并集是 8 个词,相似度大概是 3/8 = 0.375。配合权重值跳高,整体能到 0.5 以上,这已经足够触发推荐了。

4.3 无效信息过滤与精度优化

匹配算法跑通之后,真正的难点是怎么避免误推荐。我做过一个很真实的测试:失主说“丢了一个黑色钱包”,系统把“黑色书包”也推荐过来了——核心词没对上,容易引起用户反感。

所以我加了三层过滤机制:

第一层:核心实体词必须命中。物品类型词(钱包、书包、手机、钥匙)构成用户最核心的需求,如果这些都没重叠,直接不推荐。我在权重映射里单独挑出一个“high_priority”集合,在计算相似度之后、推荐之前做硬性判断。

第二层:相似度阈值动态调整。实测下来,0.3 以下匹配结果几乎都是噪音;0.3 到 0.5 之间可以作为“可能相关”推荐给用户;0.5 以上直接进“高度匹配”列表。阈值可以在后台配置,方便后续根据实际数据微调。

第三层:时效加权。失物招领有很强的时间敏感性,一个丢失一个月的背包和刚捡到的背包,即使描述完全匹配,推荐价值也很低。所以我给时间衰减加了权重:发布 24 小时内的权重系数 1.0,超过 24 小时每过 1 天衰减 0.9,7 天后衰减到 0.3 以下就不再优先展示。

这套匹配功能跑起来之后,整个平台的实用感一下子上来了。表白墙解决了“看”的需求,失物招领解决了“找”的需求,而匹配推荐让“找”的过程变得智能——这一整套逻辑,远比一个单纯的发帖社区更有说服力。

5. 常见问题与实战避坑

5.1 表单重复提交与并发处理

表白墙项目最容易被忽视的问题之一,是用户疯狂点“发布”按钮导致的重复提交。小程序端的按钮如果不在回调里加 loading 状态,用户可以连点五六次,后端就会收到五六条重复内容。

前端层面,发布按钮点击后立刻进入disabled状态,同时显示一个 loading 动画;后端层面,我在发布接口加了一个基于用户 ID 的简单频率限制:

from flask_limiter import Limiter limiter = Limiter(key_func=lambda: str(get_jwt_identity())) @posts_bp.route('/api/posts', methods=['POST']) @limiter.limit('3 per minute') # 每用户每分钟最多3篇 def create_post(): ...

这种限制不算完美,但对校园平台来说完全够用,既防刷屏又不影响正常用户。

5.2 跨域问题与本地联调技巧

开发者刚上手时最容易卡住的问题,就是小程序请求本地 Flask 服务报url not in domain list或者跨域错误。

小程序开发者工具有一个开关:详情 → 本地设置 → 勾选“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”。勾上之后,本地调试模式下可以直接请求http://localhost:5000。

后端也需要处理跨域,用flask-cors几行代码搞定:

from flask_cors import CORS CORS(app, resources={r"/api/*": {"origins": "*"}})

这里有个关键点:调试时后端必须监听0.0.0.0,不能只监听127.0.0.1,否则手机真机预览时访问不到电脑上的服务。启动命令应该是:

flask run --host=0.0.0.0 --port=5000

5.3 部署到服务器后的三大经典坑

本地调试通之后,部署到服务器又是另一套磨难。根据我自己的部署经历,最经典的坑有这么几个:

第一:附件路径错误。本地开发时图片上传路径一般写./uploads,用的绝对路径没问题。但部署到 Linux 服务器后,如果用systemd启动 Flask,工作目录未必是项目目录,所有相对路径都可能飘移。解决方案是在config.py里用绝对路径:

import os BASE_DIR = os.path.dirname(os.path.abspath(__file__)) UPLOAD_FOLDER = os.path.join(BASE_DIR, 'uploads')

再配合 Nginx 做静态文件映射,把/uploads指向真实的图片目录,这样图片路径就不会乱。

第二:生产环境不能用开发服务器。flask run自带的服务器是 Werkzeug 开发服务器,性能差且不支持并发。部署必须用 gunicorn:

gunicorn -w 4 -b 127.0.0.1:5000 app:app

启动后由 Nginx 反向代理,把 80 端口流量转发到 5000,同时处理静态文件和 HTTPS。

第三:HTTPS 证书配不好,按播放不了。微信小程序正式版强制要求接口必须是 HTTPS 的合法域名。本地开发可以先不管,但上线前必须给 Nginx 配上 SSL 证书,域名也必须在微信公众平台后台配置到 request 合法域名里。这一步看似繁琐,但其实只要按流程走一遍就顺了。

5.4 内容审核与平台治理建议

表白墙这种内容平台,审核机制是生死线。我特别强调一下:内容安全是第一优先级。代码层面可以做敏感词过滤、评论过滤,但更重要的是一套人工审核流程。

我实际的项目中做了一个轻量的管理端:管理员小程序里有一个待审核列表,逐条查看新发布的内容,包含帖子内容、图片、发布时间、发布者ID,点击通过或拒绝。同时排班表上每天指定一名管理员轮值,处理当天新帖和举报内容。

举报功能也绝不能省。用户看到不妥内容一键举报,后台收到举报后必须及时处理。虽然低频,但一旦出现大面积不良内容而没有举报入口,平台会很被动。

提示:校园平台的内容审核不需要做得多复杂,但必须有人管、有入口、有响应。这既是技术问题,更是运营问题,一定要提前想清楚。

6. 延伸扩展:这个平台还能怎么玩

基础版本跑通后,这个平台的可玩性远比想象中高。我整理了几个扩展方向,按实现难度从低到高排序:

校园集市功能:在失物招领的架构上稍作调整,增加价格字段和交易方式字段,就能把二手交易做进来。分类逻辑和图片上传逻辑完全复用,新增成本极低。

表白匹配功能:这是最容易引发传播效应的功能。用户提交自己的匿名标签(院系、年级、兴趣爱好),系统做标签匹配,每天定时生成一组“今日默契榜单”。技术实现就是标签集合的 Jaccard 相似度,和失物招领匹配是一套算法体系。

订阅消息通知:失物招领场景里,发布失物信息后,用户希望有新匹配时能被通知到。微信小程序的订阅消息功能正好解决这个问题:新帖发布时引导用户订阅“匹配结果通知”,系统生成匹配后推送消息。这个功能对提升活跃度效果显著。

数据可视化看板:Flask 后端天然适合做数据统计,把表白墙发帖趋势、各板块占比、高频关键词统计出来,对接一个有图表库的管理后台,平台运营者能直观看到用户活跃情况。

这些扩展方向有一个共同点:基础架构不需要动,只要在现有表结构和接口上做增量开发。这也是当初选 Flask + SQLite 轻量架构的原因——后面想加功能,扩展成本是可控的。

根据我自己的实操体会,把这套系统从零跑到线上,工作量最大的其实不是写代码,而是设计好数据结构、想清楚审核流程、做好内容和部署的细节。只要这几条主线理清楚,剩下的事情都是时间和耐心的问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 11:19:55

大模型评测常用数据集怎么选?MMLU、SWE-Bench 与 TaoToken 配置实战

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

作者头像 李华
网站建设 2026/9/28 11:09:19

11.初级指针

第一章 数据在计算机内存中真实的存储形式1.1 变量存储的底层逻辑我们写代码定义变量&#xff0c;本质就是向操作系统申请一块内存空间&#xff0c;给这块空间起一个变量名&#xff0c;再把我们写的十进制数字放进内存里。 计算机只能识别 0 和 1 组成的二进制&#xff0c;我们…

作者头像 李华
网站建设 2026/9/28 11:04:51

layui 全屏功能实现:TaoToken 统一 Key 接入与配置验证

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

作者头像 李华
网站建设 2026/9/28 9:40:14

AI模块化架构:多Provider切换、RAG知识库与Agent编排实战

1. 这不是“又一个AI架构教程”&#xff0c;而是一套能落地的模块化设计实践我做AI工程化落地项目三年&#xff0c;从最早用LangChain硬写RAG流水线&#xff0c;到后来给制造业客户搭本地知识库系统&#xff0c;再到最近帮律所构建法律问答Agent&#xff0c;踩过的坑比读过的论…

作者头像 李华