
1. 项目背景与核心价值作为一名在技术社区混迹多年的老鸟我见过太多人陷入刷题焦虑——LeetCode、牛客、Codeforces各种平台来回切换题目刷了几百道却依然在面试中手足无措。问题的核心往往不在于刷题数量而在于缺乏系统性的理解和沉淀。这正是我开发【牛客tracker 每日一题】工具的初衷。这个工具本质上是一个浏览器插件本地数据追踪系统的组合体主要解决三个痛点自动记录牛客网刷题轨迹避免手动统计的遗漏和误差根据历史数据智能推荐每日练习题目生成可视化的能力成长曲线和薄弱环节分析注意本工具完全基于牛客网公开API开发不涉及任何违规爬取行为所有数据存储均在用户本地2. 技术架构与核心模块2.1 浏览器插件层实现采用Chrome Extension MV3架构开发主要包含以下组件// background.js 核心逻辑片段 chrome.runtime.onMessage.addListener((request, sender, sendResponse) { if (request.type record_submission) { const {questionId, status, timestamp} request.data; chrome.storage.local.get([trackerData], (result) { const newData updateTrackerData(result.trackerData, questionId, status); chrome.storage.local.set({trackerData: newData}); }); } }); function updateTrackerData(existingData, questionId, status) { // 数据结构示例 // { // 12345: { // 题目ID // attempts: 3, // lastStatus: AC, // timestamps: [1625097600, 1625184000, 1625270400], // tags: [动态规划, 二叉树] // } // } return {...existingData, [questionId]: {...existingData[questionId], ...newData}}; }2.2 本地数据分析引擎使用Python构建的本地服务主要功能模块包括题目推荐算法基于协同过滤知识图谱能力雷达图生成使用matplotlib刷题进度预测模型简单的时间序列分析# recommendation_engine.py 核心逻辑 def generate_daily_recommendation(user_data): # 1. 获取用户历史记录 weak_tags analyze_weaknesses(user_data) # 2. 从本地题库中筛选匹配题目 candidate_questions [] for qid in question_db: if set(question_db[qid][tags]) set(weak_tags): if qid not in user_data: candidate_questions.append(qid) # 3. 结合热度、难度等因素排序 return sorted(candidate_questions, keylambda x: (-question_db[x][hot], question_db[x][difficulty]))[:3]3. 关键实现细节与避坑指南3.1 牛客网API的逆向工程牛客网的题目提交数据主要通过XHR请求获取需要特别注意认证信息需要从cookies中获取NOWCODER_CLIENT_ID分页加载采用特殊的_参数作为时间戳个人提交记录接口存在频率限制约5次/分钟实战技巧在插件中实现请求队列和自动重试机制避免频繁触发反爬3.2 本地数据存储方案选型对比了三种方案后最终选择IndexedDB方案优点缺点适用场景localStorage简单易用容量限制(5MB)小规模数据IndexedDB大容量支持API复杂结构化数据SQLite强大查询能力需要额外集成桌面应用实际使用中的坑点IndexedDB是异步操作需要妥善处理回调链数据结构变更时需要手动处理版本迁移浏览器隐私模式下可能无法使用3.3 推荐算法优化历程第一版采用简单的随机推荐用户反馈效果不佳。迭代过程V1随机推荐未做题目 → 准确率12%V2基于标签匹配推荐 → 准确率35%V3加入题目热度因素 → 准确率41%V4融合用户做题时间模式 → 准确率58%关键突破点在于发现了时间上下文的重要性——用户在不同时间段如通勤时vs周末对题目难度的接受程度差异很大。4. 效果验证与用户反馈4.1 量化指标对比收集了20位测试用户一个月的数据指标使用前使用后提升每日刷题量1.2题2.8题133%题目通过率63%82%30%重复刷题率41%12%-71%4.2 典型用户场景案例1王同学求职季痛点盲目刷题经常重复做已掌握的题型使用后系统自动标记已掌握知识点针对性推荐新题型结果面试手撕代码通过率从3/10提升到7/10案例2李工程师在职提升痛点只有碎片化时间选题效率低使用后每日推荐1道匹配当前水平的题目结果三个月系统刷完所有二叉树相关题目5. 扩展方向与进阶用法5.1 企业内训适配版为某互联网公司定制的版本新增功能私有题库接入部门内排名系统匿名知识点掌握度团队报告// 团队数据分析示例 function generateTeamReport(usersData) { const tagStats {}; usersData.forEach(user { user.weakTags.forEach(tag { tagStats[tag] (tagStats[tag] || 0) 1; }); }); return Object.entries(tagStats) .sort((a,b) b[1]-a[1]) .slice(0, 3); }5.2 移动端适配方案由于浏览器插件无法在移动端使用开发了配套方案浏览器插件数据同步到GitHub私有仓库通过GitHub Actions定时运行分析脚本结果推送到企业微信/钉钉机器人典型工作流用户刷题 → 插件记录 → 定时同步到GitHub → CI运行分析 → 生成报告 → 推送通知6. 常见问题排查手册6.1 数据不同步问题症状浏览器插件显示的数据与本地分析结果不一致 排查步骤检查chrome.storage.local的配额使用情况验证IndexedDB的版本号是否一致查看控制台是否有序列化错误如Date对象直接存储6.2 推荐质量下降可能原因牛客网题目标签体系更新2023年有过大调整用户行为模式发生变化如从算法转战系统设计 解决方案手动触发数据重新索引重置个人能力评估问卷检查网络请求是否被浏览器插件拦截在开发过程中最深的体会是工具的价值不在于技术复杂度而在于能否精准解决特定场景下的真实痛点。这个项目从v0.1到现在的1.4版本核心算法重构了三次但最受用户好评的功能反而是最初那个简单的今日已打卡提醒——因为它击中了人性中最根本的成就感和持续性需求。