news 2026/10/8 20:14:19

多用户微信投票小程序源码:从数据库设计到防刷实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多用户微信投票小程序源码:从数据库设计到防刷实战

做投票类小程序这几年,我见过不下十种设计方案。有的用第三方问卷工具套个网页链接,有的直接在公众号文章里嵌表单,还有的干脆让用户截图私聊人工记票。这些方案的问题都出在一个点上:投票是强实时、强互动的场景,一旦参与人数上来,表单链接失效、数据统计混乱、重复投票完全挡不住。所以当我接到“多用户微信投票系统源码”这个需求时,第一反应就是:这必须是一个独立小程序,配一套完整后端接口,还得把“多用户”这三个字拆开想清楚。

这套源码解决的核心问题可以概括成一句话:不同管理员各自创建投票活动,各自的微信用户参与投票,每个活动的数据完全隔离,系统统一管理用户身份并防刷票。它适合三类人看:一是想给企业/学校/社区做内部评选的技术同学,二是接外包项目需要一套可复用投票模块的开发者,三是对小程序开发有基础、想低成本搭建一个可运营投票产品的创业者。下面我会从设计思路、数据库模型、接口实现、部署调试到踩坑记录,把整套方案掰开揉碎讲清楚。

1. 先想清楚:投票系统到底在解决什么问题

1.1 单活动网页投票和小程序投票,差的不是一星半点

很多人觉得投票无非是“展示几个选项,用户点一下,累计加一”。真做过一次活动就知道,完全不是这么回事。用网页做的投票,用户每次打开都要重新输入验证码,体验差强人意;数据存在第三方表格里,你想按规则剔除异常票根本无从下手;最要命的是重复投票,同一个用户换台手机换张SIM卡就能再投,主办方看着数据却毫无办法。

小程序投票最大的优势在于用户身份是天然的。微信生态提供了匿名但唯一的 openid,每个用户的身份通过 wx.login 可以稳定获取,这就给“一人一票”打下了基础。再加上小程序本身的传播路径短,用户从微信群点开小程序卡片到完成投票,整个过程三秒内可以结束,转化率比网页链接高一个数量级。

所以这套系统的设计原则就清晰了:身份靠微信,业务靠后端,数据隔离靠活动ID,防刷票靠多维校验。用户端不需要注册、不需要填手机号(用不到的时候坚决不弹窗),点开即投;管理员端看到的是实时更新的趋势数据,每一票都能追溯来源。

1.2 “多用户”的真实含义:不只一个用户能投票

标题里的“多用户”一定要拆成两个层面理解,否则数据库表设计这一步就会跑偏。

第一个层面是 C 端参与者众多。也就是成百上千的微信用户同时在一个活动里投票,系统要扛得住瞬时流量,要保证同一用户不能重复投票,还得能区分“真实用户”和“刷票机器人”。这是技术层面最枪的事情,我的建议是:身份唯一时用 openid,频次控制时配合 IP + 时间窗口,两条腿走路。

第二个层面是 B 端管理员众多。也就是系统里同时存在多个主办方,每个主办方各自创建活动、各自看各自的数据,互不可见。举个例子,同一个部署实例可以同时服务 A 公司的优秀员工评选和 B 社区的最美店主打 call,A 公司的管理员登录后看不到 B 社区的任何一个活动。这个隔离看着简单,实际做起来常见的坑就是查询时漏掉 activity_id 条件,导致数据串台。所以我在源码里把所有活动相关的 SQL 都强制带上 WHERE activity_id = ?,并在函数入口统一校验当前管理员的权限范围。

1.3 低成本的边界在哪里

低成本不等于零成本,这点必须先说清楚。微信小程序个人主体可以注册,但投票类目通常需要企业主体,认证费是省不掉的(300元/年)。域名和 HTTPS 证书也需要,证书可以用免费的 Let's Encrypt 或腾讯云免费证书,域名一年几十块。服务器这块,早期流量不大,一台最便宜的云主机(2核4G)就能跑 PHP + MySQL + Nginx,一个月几十块钱。整套算下来,第一年硬性成本一千元以内能覆盖,相比直接买商业投票 SaaS(通常按活动数收费,一个活动几百到几千不等),自建一套多用户系统的成本优势是数量级的。

真正的低成本还体现在开发效率上。我选了 PHP 作为后端语言而没有用 Java 或 Go,原因很实在:PHP 部署简单(一个 Nginx + PHP-FPM 就够)、生态里现成的鉴权库和工具链丰富、代码改完马上生效不用编译,单人维护成本极低。如果你团队里的同学不会 PHP,前端完全可以用微信原生框架写,后端换成 Node.js 或 Go 也完全可以,架构上不会受任何限制。

2. 系统设计与数据库模型拆解

2.1 技术栈选型:前后端怎么分工最合理

整套系统的架构分成三个部分:微信小程序前端、后端 API 服务、数据库。前端负责展示和交互,后端负责业务逻辑和权限校验,数据库负责持久化。

小程序前端我用了微信原生框架,没有上 uniapp。原因有几个:一是投票系统的小程序端页面很简单(列表页、详情页、统计页,总共就三四个页面),原生框架已经够用,引入 uniapp 反而多一层打包和兼容性成本;二是原生小程序对微信 API 的支持是最及时的,不需要等第三方框架适配;三是如果你后续要改需求,原生代码的调试体验更好。当然,如果你明确知道以后要同时发布到支付宝、抖音小程序,那就上 uniapp,这个属于产品规划层面的取舍。

后端选 PHP 是因为它和 MySQL 配合最省心,部署资料也最多。再说一次,这不是对语言有偏爱,而是综合考虑单人开发效率、服务器成本、排错便利度之后的最优选。只要保持接口返回 JSON、鉴权用 Token 模式、业务间不共享状态,这套后端逻辑用任何语言重写都不困难。

2.2 数据库核心表设计

数据库设计是整套系统的地基。我直接给出表结构,你建库的时候照着用就行。一共五张表:管理员表、用户表、活动表、选项表、投票记录表。

-- 管理员表 CREATE TABLE `admin` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(64) NOT NULL COMMENT '登录账号', `password_hash` varchar(255) NOT NULL COMMENT '密码hash', `created_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- C端用户表 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `openid` varchar(64) NOT NULL COMMENT '微信openid', `nickname` varchar(128) DEFAULT NULL, `avatar_url` varchar(512) DEFAULT NULL, `phone` varchar(32) DEFAULT NULL COMMENT '可选绑定手机号', `created_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_openid` (`openid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 投票活动表 CREATE TABLE `activity` ( `id` int(11) NOT NULL AUTO_INCREMENT, `admin_id` int(11) NOT NULL COMMENT '所属管理员', `title` varchar(128) NOT NULL COMMENT '活动标题', `description` text, `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '1开启 0关闭', `start_time` datetime DEFAULT NULL, `end_time` datetime DEFAULT NULL, `created_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_admin_id` (`admin_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 投票选项表 CREATE TABLE `activity_option` ( `id` int(11) NOT NULL AUTO_INCREMENT, `activity_id` int(11) NOT NULL, `title` varchar(128) NOT NULL COMMENT '选项名称', `image_url` varchar(512) DEFAULT NULL, `vote_count` int(11) NOT NULL DEFAULT '0' COMMENT '冗余票数', `sort` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `idx_activity_id` (`activity_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 投票记录表 CREATE TABLE `vote_record` ( `id` int(11) NOT NULL AUTO_INCREMENT, `activity_id` int(11) NOT NULL, `option_id` int(11) NOT NULL, `user_id` int(11) NOT NULL, `ip` varchar(64) DEFAULT NULL, `created_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_user_activity` (`user_id`, `activity_id`), KEY `idx_activity_id` (`activity_id`), KEY `idx_option_id` (`option_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这里有两个设计细节值得展开讲。第一是activity_option.vote_count字段,它保存的是冗余计数,目的是让列表页、排行榜页查询时直接按这个字段排序,不用每次实时 COUNT 投票记录表,性能会好很多。第二是vote_record表的唯一索引uk_user_activity,这个索引从数据库层面保证了“一个用户在一个活动中只能投一次票”,就算代码里出现并发提交,数据库也会拦下重复的那一条。这两个字段是整套系统数据一致性的关键,千万别省。

2.3 多活动与多用户的数据隔离方案

数据隔离这件事,做得好不好直接决定系统能不能真正“多用户”跑起来。我的做法很简单:所有业务表都带 activity_id,所有查询都带上这个过滤条件。管理员登录后,我生成一个 Token 存进 Redis 或者数据库 session 表,Token 里绑定 admin_id,每次写操作都校验“这个活动属于当前登录的管理员”。

给你举个串数据的具体场景:A 管理员创建了活动 1001,里面有几个候选选项。如果查询时没带 activity_id,而是直接SELECT * FROM activity_option WHERE id = ?,一旦 B 管理员的活动里恰好也有一个同 ID 的选项,那 A 管理员编辑或投票时就会操作到 B 的活动。这种 bug 在测试环境很难暴露,因为大家都只建一两个活动,但一上线、数据一多,问题就炸了。

所以我源码里在所有跨模块的地方都做了统一封装,比如check_activity_owner($activity_id, $admin_token)这个函数,每次操作前先校验归属,校验不通过直接返回 403。一句话总结:隔离靠的不是人的细心,而是系统层面的强制约束。

3. 核心接口与小程序端实现

3.1 微信登录态与手机号获取

微信小程序登录这块,接口流程是固定的,但初学者最容易在“session_key 过期”这件事上栽跟头。正确流程是:

  1. 小程序端调用wx.login()拿到临时 code。
  2. 把 code 传给后端,后端用 code 换 openid 和 session_key。
  3. 后端用 openid 查 user 表,不存在就自动注册一条新用户记录,然后返回自定义登录态 token。
// PHP 后端:用 code 换 openid $code = $_POST['code']; $appid = '你的AppID'; $secret = '你的AppSecret'; $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$secret}&js_code={$code}&grant_type=authorization_code"; $result = file_get_contents($url); $data = json_decode($result, true); // $data['openid'] 就是用户唯一身份 // $data['session_key'] 用于解密手机号等敏感信息,不要写进日志

很多人在这一步会犯一个错:把 code 当作登录态直接存到本地,下次登录继续用。这是不行的,微信的 code 是一次性的,用一次就废了。所以后端必须自己签发一个 token 返回给小程序,之后的每一次请求都带这个 token,后端再根据 token 查出用户身份。token 的过期时间建议设 7 天,用户在活动期间不用反复登录。

手机号获取这块,现在微信推广的是“手机号快速验证组件”,需要企业主体小程序才能申请。按钮是<button open-type="getPhoneNumber">,用户点击授权后,后端用 session_key 解密得到手机号。注意:手机号属于敏感信息,获取前要明确告知用户用途,而且一个用户只能主动触发一次授权,不要设计成“不填手机号就不能投票”这种强制逻辑,合规风险大,用户流失率也高。

3.2 投票主流程接口:从创建活动到数据入库

整套系统的核心接口就四个:创建活动(管理员)、获取活动详情(用户)、提交投票(用户)、查询统计(管理员/用户)。我把投票接口的关键代码贴出来,这是最考验正确性的一段逻辑。

// 提交投票接口 public function vote($user_id, $activity_id, $option_id) { // 1. 校验活动状态 $activity = $this->get_activity($activity_id); if ($activity['status'] != 1) { return $this->error('活动已结束'); } if (time() < strtotime($activity['start_time']) || time() > strtotime($activity['end_time'])) { return $this->error('不在投票时间范围内'); } // 2. 校验选项归属 $option = $this->get_option($option_id); if ($option['activity_id'] != $activity_id) { return $this->error('选项不合法'); } // 3. 写入投票记录,依赖唯一索引防重复 try { $this->db->beginTransaction(); $this->db->insert('vote_record', [ 'activity_id' => $activity_id, 'option_id' => $option_id, 'user_id' => $user_id, 'ip' => $this->get_client_ip(), 'created_at' => date('Y-m-d H:i:s'), ]); // 4. 累加选项票数 $this->db->query( "UPDATE activity_option SET vote_count = vote_count + 1 WHERE id = ? AND activity_id = ?", [$option_id, $activity_id] ); $this->db->commit(); return $this->success('投票成功'); } catch (Exception $e) { $this->db->rollback(); // 重复插入会触发唯一索引冲突,说明用户已经投过 return $this->error('您已经投过票啦'); } }

这段代码里有三个关键点。一是用了数据库事务,投票记录和票数累加要么同时成功、要么同时失败,不会出现“记录写进去了票数没变”的中间状态。二是如果把 vote_record 插入和 vote_count 更新分成两个独立步骤跑,一旦第二步失败,前端就会看到投票失败的提示,但后台数据已经写了,用户重试时又会被唯一索引拦住,体验特别差。三是投票前做的状态校验和归属校验,看起来啰嗦,但能挡住绝大多数的参数篡改。比如有人直接调接口传一个不存在的 option_id,或者传别人的活动里的 option_id,这两道校验就能挡下来。

3.3 小程序端页面组织与请求封装

小程序端我建议按这个结构组织页面:

  • pages/index/index:活动列表页,展示当前所有进行中的活动。
  • pages/detail/detail:活动详情页,展示活动信息、候选选项,点击投票。
  • pages/stats/stats:实时统计页,展示每个选项的票数和占比。
  • pages/admin/admin:管理员页,创建活动、管理选项、查看自己活动的数据。

请求封装是每个小程序项目都必须做的基础工作。我在 utils/request.js 里统一封装了 wx.request,自动带 token、统一处理 401 跳转登录、统一处理错误提示,业务代码只需要关心成功回调。

// utils/request.js function request(url, method, data) { return new Promise((resolve, reject) => { wx.request({ url: `https://你的域名.com/api/${url}`, method: method || 'GET', data: data || {}, header: { 'Content-Type': 'application/json', 'Authorization': wx.getStorageSync('token') }, success(res) { if (res.data.code !== 0) { if (res.data.code === 401) { wx.navigateTo({ url: '/pages/login/login' }); } wx.showToast({ title: res.data.msg, icon: 'none' }); reject(res.data); return; } resolve(res.data.data); }, fail(err) { wx.showToast({ title: '网络异常', icon: 'none' }); reject(err); } }); }); } module.exports = { request };

细节很重要:所有接口返回格式统一成{ code: 0, data: {...}, msg: 'success' },前端拿到 code 非 0 就统一弹 toast。这样以后不管加了什么新接口,前端逻辑都不用大改。自定义导航栏的时候要处理顶部安全区,调用wx.getWindowInfo()拿statusBarHeight和safeArea来做适配,否则在刘海屏手机上页面会被怼到状态栏底下,看起来特别业余。

3.4 防刷票的几种实用姿势

刷票是投票系统的永恒敌人,但“完美防刷”是不存在的,你要做的是把刷票成本抬高到对方不值得花这个力气。我从易到难给你列层:

第一层是 openid 唯一约束。这是地基,一个微信号只能投一票,数据库唯一索引保证,代码直接挡掉。缺点是有的人会去网上买群控批量注册微信小号来刷,光靠它拦不住。

第二层是 IP 维度限制。同一 IP 在短时间内(比如 1 小时)投票超过 N 次就触发验证码或者直接拒绝。这个方法对付普通用户手刷已经够了。注意获取客户端真实 IP 时,如果服务器用了 Nginx 反代,要读取HTTP_X_FORWARDED_FOR头,而不是直接取REMOTE_ADDR,否则所有用户都是一个 IP。

第三层是时间窗口和行为特征。比如从点开详情页到提交投票之间耗时小于 2 秒,大概率是脚本在跑;比如投票请求的 User-Agent 里不带微信浏览器的特征字段,大概率是模拟器。当然现在很多群控工具会伪造这些特征,所以这一层只能做辅助参考,不能一刀切拦截,否则容易误伤真实用户。

第四层是验证码和诱导授权。如果活动热度高、刷票刷得厉害,可以在投票前加入滑块验证或者“长按按钮 3 秒”这种低成本的验证方式。它拦不住专业团队,但能把随手刷票的路人挡掉百分之七八十,这就够了。记住一句话:你是做投票活动的,不是做杀软安全产品的,防刷力度要和活动成本匹配。

4. 部署、调试与常见问题实录

4.1 本地开发调试:开发者工具与抓包辅助

微信开发者工具是必备的,这是所有流程的起点。项目导入后,第一步先在“详情 - 本地设置”里勾选“不校验合法域名”,这样你本地开发时调用局域网 IP 接口不会被拦截。第二步在“项目配置 - AppID”里填自己的测试号或者正式号,确保 wx.login 能拿到 code。第三步,把工具里的调试器打开,直接看 Network 面板的请求详情,如果接口报错了,先看请求 URL、请求头、响应体,多半问题就定位了。

如果你想抓真机的请求包,Charles 是个好帮手,手机和电脑连同一个局域网,配置好 SSL Proxying 并安装证书,就能在电脑上看到小程序发的每个请求。这个方法在排查“手机上正常、电脑上不正常”的问题时特别有用,因为手机上微信请求的鉴权头、UA 等细节和开发者工具里模拟的其实有细微差别。

不过提醒一句:抓包工具是用来调试自己和后端交互的请求的,用脚本批量构造请求刷投票属于作弊行为,不在我们的讨论范围内。我把抓包这个方法放在这里,用途只有一个:自测接口在真实手机环境下的表现,排查线上问题。

4.2 服务器部署要点:域名、HTTPS 与微信配置

部署这套系统到云服务器,核心步骤就四步:

  1. 装环境:Nginx + PHP 7.4+ + MySQL 5.7+。PHP 需要装好pdo_mysql、openssl扩展,这两个是基础依赖。
  2. 配站点:把前端编译出来的小程序代码包上传到微信后台(这是前端发布的事,跟服务器无关);后端代码放到服务器,Nginx 配置好server_name,location/api/转发给 PHP-FPM。
  3. 配 HTTPS:申请免费证书,配置好后用https://你的域名打开能正常返回 JSON 就说明通了。
  4. 配微信后台:在微信公众平台 - 开发管理 - 服务器域名里,把 request 合法域名填成你的 HTTPS 域名。这一步忘了配置,线上小程序一调接口就报 “url not in domain list”,这是新手最常见的报错之一。
# Nginx 站点配置示例 server { listen 443 ssl; server_name vote.example.com; ssl_certificate /etc/nginx/cert/example.pem; ssl_certificate_key /etc/nginx/cert/example.key; root /var/www/vote/public; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }

数据库这块,上线前记得把 MySQL 的安全基线提上来:关闭 root 远程登录,单独建一个业务账号,密码用随机字符串,数据表统一用utf8mb4字符集。utf8mb4 不是可选项,是必须项,它能存表情符号,现在用户昵称里没有 emoji 的反而稀奇。

4.3 高频踩坑清单

我按“现象、原因、解决办法”整理了一张表,都是实际项目里高频出现的,照着排查能省你大量时间。

现象原因解决办法
开发工具里接口正常,手机真机上请求失败真机上微信会校验 request 合法域名,没配置或证书过期在微信后台配置 HTTPS 域名,确认证书链完整且未过期
用户投票显示“已经投过”但后台没记录前端按钮被点击两次,两个请求同时到达,一个写成功一个被唯一索引拦截前端提交时加 loading 锁;后端处理器返回的“已投过”文案改成“投票成功”也可以,但建议保留提示以体现真实意图
用户票数统计和投票记录数不一致vote_count 更新和记录写入不在一个事务里,或者统计时用了缓存用事务包裹两条 SQL;统计页直接读 vote_count,不做实时 count
活动列表页加载很慢活动表数据量大了,created 排序没走索引activity 表加KEY idx_status_start (status, start_time)组合索引
微信头像是灰色默认头像2021 年后头像昵称获取规则调整,用户未主动授权不会返回真实信息不用强制获取;如确需展示,引导用户点击授权头像昵称填写能力

这里把第 6 条展开说一下。微信在 2021 年 10 月后,小程序里通过wx.getUserProfile拿到的头像昵称已经没法直接用了,现在流行的是“头像昵称填写能力”,就是让用户在小程序里自己选一张头像、自己填一个昵称,微信只负责提供官方选图能力。所以做投票系统的时候,你就别纠结用户头像对不对了,直接用 openid 关联就好。活动页面展示“匿名用户 + 票数”反而更干净,还能避免有人用头像和昵称互相攻击。

4.4 多用户场景下的运营与安全建议

最后聊点运营层面的东西。如果是拿这套系统对外接单、服务多个客户,有三件事必须提前做好。

一是数据隔离的权限审计。至少要有一个超级管理员角色,能看到所有活动的基本信息和数据指标,但要看详细投票记录时要有审计日志。这个其实就是给 admin 表加一个role字段区分超管和普通管理员,接口层面做一层角色判断,逻辑不复杂但非常有用。

二是定时任务。投票活动的状态字段不能全靠用户请求时被动更新,我建议起一个 cron 每分钟跑一遍:把 end_time 小于当前时间且 status 还是 1 的活动批量置为 0(已结束)。这种脚本可以放在系统里作为独立 CLI 入口,不要放进 Web 接口里,免得被外部触发。

三是数据库自动备份。投票活动一旦冒出黑马选手,主办方会想要大量截图和实时报表,这时数据库就是命根子。建议至少每天凌晨自动备份一次,定期测试恢复流程。不要问我为什么要强调恢复流程——等你真遇到“备份文件坏了但你已经删掉线上数据”的时候,哭是没有用的。

这套系统从设计到上线,我前后迭代过三个版本。最深的体会是:投票系统的代码写起来不难,难的是把边界情况想清楚,比如并发重复投票、跨管理员数据串台、活动状态变更时机。把数据库表设计对了,把接口校验都写上,把事务用对地方,剩下的事情都不值得害怕。往后再扩展的话,你可以在这个基础上加抽奖转盘、加排行榜分享卡片、加管理员实时看板,骨架都不用变,往上摞功能就行。希望这篇拆解能帮你少走几段弯路。

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

RAG知识库问答系统落地全流程:从文档切块到检索调参与质量评测

简介&#xff1a;面向AI应用开发者的RAG实践手册&#xff0c;系统讲解构建知识库与问答系统的完整流程&#xff0c;可帮助解决大模型私有知识整合、问答准确率优化等问题。资源包为单个PDF文件&#xff0c;大小4.11MB&#xff0c;目前已有466人学习使用。内容结构清晰&#xff…

作者头像 李华
网站建设 2026/10/8 20:14:19

CH340N USB转串口模块设计全流程:从原理图到PCB焊接调试

最近整理元件盒的时候翻出一批CH340N&#xff0c;想起来年初给朋友做了好几个Type-C接口的USB转串口小模块&#xff0c;从选型到打样再到踩坑&#xff0c;整个过程挺值得记录。CH340N这颗芯片在CH340系列里属于“小而美”的代表&#xff0c;SOP8封装&#xff0c;内置晶振&#…

作者头像 李华
网站建设 2026/10/8 20:13:51

PostgreSQL 就绪检查实践:从端口探测到可查询的完整等待方案

在自动化部署里&#xff0c;我见过最多的一类“玄学故障”就是&#xff1a;脚本明明等到 PostgreSQL 进程起来了、端口也通了&#xff0c;紧接着的连接请求却摔在FATAL: the database system is starting up&#xff0c;或者更气人的直接Connection refused。问题不在于 Postgr…

作者头像 李华
网站建设 2026/10/8 20:10:42

随机SVD+软阈值:大数据集谐波去噪的快速稳健方案

做信号处理的人应该都有过这种体验&#xff1a;现场采集的电压、电流、振动或声学信号里&#xff0c;谐波成分就藏在噪声底下&#xff0c;想提取特征、做分析、诊断问题&#xff0c;第一步往往是先去掉噪声。传统做法里&#xff0c;奇异值分解&#xff08;SVD&#xff09;是相当…

作者头像 李华
网站建设 2026/10/8 20:10:33

2026菏泽景区古建牌坊检测排名 TOP5 CMA 资质机构提供牌坊裂缝检测、牌坊倾斜检测、老化检测 联系方式推荐

在菏泽&#xff0c;古建牌坊检测机构看似鳞次栉比&#xff0c;实则鱼龙混杂。景区石牌坊、乡村古牌楼、文物古建牌坊在开展结构安全鉴定、修缮验收或文保备案时&#xff0c;大量无资质机构出具的报告往往无法通过住建与文物部门的核验&#xff0c;令人进退两难。小编实地走访&a…

作者头像 李华
网站建设 2026/10/8 20:09:15

Linux密码破解与恢复:从shadow文件到弱口令防御

前阵子给一台老服务器做安全巡检&#xff0c;发现运维同事把 root 密码设成了Admin123这种一眼就能猜出来的组合。检查/etc/shadow的时候&#xff0c;我顺手用 John the Ripper 跑了一下&#xff0c;不到两分钟就解开了。这事其实挺常见——很多人以为 Linux 密码很安全&#x…

作者头像 李华