新闻详情

新闻详情

首页 / 资讯中心 / 详情

基于SpringBoot+Vue+Android的个人日记管理系统全栈实战

发布时间:2026/9/28 12:39:24来源:尧图网络
基于SpringBoot+Vue+Android的个人日记管理系统全栈实战
上周还有个学弟来找我说他毕设选了“基于SpringBootVue的个人日记管理系统”结果开题答辩被老师追问了半个小时你这个系统除了增删改查还有什么新东西这恐怕是选这个题目的同学最难受的地方。就着这个题目我干脆把整套基于 Java、Android 手机端、SpringBoot 后端和 Vue 管理端的个人日记记录一体化方案完整梳理一遍。这个题目远不止是“写日记”它背后涉及账号体系、富文本记录、多媒体附件、标签聚合、心情统计、两端数据同步等一系列问题。希望这篇内容能帮后来人少走弯路也能帮你把毕设从“能用”做到“能讲”。先说明一下我提到的很多细节都是基于个人实际项目里的通用做法做的补充。每个学校的毕设要求不一样但核心逻辑是相通的你完全可以按自己环境调整。1. 一个被问爆的毕设题目个人日记管理平台到底在做什么1.1 需求和功能模块拆解很多人一看“日记管理系统”第一反应就是“不就是写日记、看日记吗”。真把需求文档捋一遍功能点远比想象中多。拿我帮学弟梳理的版本来说这个系统至少要拆成六个核心模块用户模块注册、登录、个人信息维护。日记属于强私密数据所以登录认证不是摆设后面所有日记接口都得校验身份。日记管理模块新增、编辑、删除、查看日记。这是主体功能但往往会扩展出“日记列表分页”“按时间线浏览”“按日历查看”几种视图。标签与分类模块给日记打标签支持一个日记多个标签按标签筛选日记。这一步做好了才是“智能管理”的体现。情绪与天气辅助字段记录当天的心情状态和天气情况后续做数据统计时这些字段能直接作为分组维度。多媒体管理模块上传图片作为日记封面或正文插图。移动端拍照记录是刚需Web端也得能看。统计面板按月份、标签、心情做日记数量统计用图表展示写作频率和情绪分布。这是我的划分实际做的时候不一定要全都上。但建议不要把“智能”理解成AI生成内容老师眼里更合理的“智能”体现在标签归类、时间聚合、心情统计这些能跑出结果的功能上。很多同学答辩翻车就是因为题目太大、功能太散最后每个模块都说不深。宁可做五个完整模块不要把十个模块都做成半成品。1.2 推进节奏怎么安排最稳妥毕设项目最忌按顺序从注册登录一路写到统计图表因为前期时间花太多后面移动端可能来不及。我建议把整个项目切成三个里程碑第一个里程碑做 Web 端的“日记闭环”也就是登录、写日记、看列表、改日记、删日记这几件事必须在一个星期内跑通。第二个里程碑再加上标签、上传图片、统计图表这些“增值模块”。第三个里程碑再做 Android 端因为 Android 端本质上是复用同一套后端接口核心业务逻辑都在服务端移动端更像一个“壳”。把最难啃的后端先搞定Android 端做起来会轻松很多也不至于到答辩前发现接口还没写好。2. 技术选型背后的真实理由SpringBoot Vue Android 为什么能站住脚2.1 这个组合是“毕设标准答案”但绝不是偷懒网上大量毕设都是 SpringBoot Vue老师基本不会在技术上质疑你“为什么选这个”。但这不意味着你可以不准备理由。我自己的理解是这套组合的核心优势在于“分工清晰”SpringBoot 负责提供 RESTful API内置 Tomcat不需要额外配置一键打包成 jar 就能跑部署演示成本低。Vue 负责构建 Web 管理端组件化开发页面响应快生态里拿 Element Plus 或 Vant 都能快速搭出后台界面。Android 原生负责移动端用 Java 开发直接调用同一个后端 API真正实现“一体化记录”。有人问既然有 Vue 了为什么移动端不直接用 H5 套壳或者干脆上一个 Flutter这个问题答辩老师很可能问。我是这样理解的题目本身就要求学生掌握原生 Android 开发基础。原生 App 能够调用相机、处理本地缓存、做离线存储这些都是 H5 套壳做不到的。而且 Android 原生能展示你对生命周期、权限管理、网络请求这些基本功的掌握这点对本科生答辩很重要。2.2 后端细节点选型和坑后端框架层面SpringBoot 3.x 还是 2.x我建议选 2.x。SpringBoot 3 要求 JDK 17部分教学环境还没完全跟上而且 MyBatis-Plus 老版本在 3.x 上有兼容问题。除非你对自己环境很有把握否则不要为了追新版本给自己埋雷。持久层我用的是 MyBatis-Plus日记列表分页、条件查询、逻辑删除这些功能都有现成支持能省不少代码量。权限认证这块拦截器 JWT 就够用Session 在多端场景下不太灵活移动端和 Web 端都要带 Token 才能访问接口。图片文件存储起步阶段直接存本地磁盘配置一个静态资源映射目录即可千万不要一上来就引入 MinIO 或 OSS容量规划、网络带宽、依赖配置都是成本答辩老师也不会因为你用了 OSS 就加分太多但会问你“桶策略怎么配”“为什么不用本地存储”到时候反而不好圆。2.3 Vue 和 Android 的定位差异再强调一次Vue 端和 Android 端不是简单的页面复制。Web 端更侧重“管理”比如日记列表、统计图表、标签筛选适合在电脑上快速浏览整理。Android 端更侧重“记录”打开 App 两步就能写一篇日记拍照插入断网也能先存本地。两端的核心套路是共享同一套后端接口但交互侧重点不一样。答辩的时候如果能讲出这层思考老师基本不会觉得你是“一个模板打两遍”。3. 数据库设计日记本体、标签、附件与统计的建模细节3.1 数据表规划合理的表结构是这个项目最核心的部分。表设计不好后面写代码会遇到各种别扭。我规划了五张核心表数据表名用途关键字段user用户信息id, username, password, avatar, create_timediary日记主表id, user_id, title, content, summary, mood, weather, cover_image, create_time, update_time, delete_flagtag标签表id, user_id, tag_name, create_timediary_tag日记-标签关联表id, diary_id, tag_iddiary_image日记图片表id, diary_id, image_url, sort_order, create_time这个设计里有一个容易被忽略的地方diary表加不加delete_flag我认为一定要加原因很简单日记属于用户私密数据如果用户误删了至少给一个“放进回收站”的可能性而不是物理删除。物理删除对于毕设来说虽然省事但答辩问到“数据安全性”的时候会很单薄。用逻辑删除一个delete_flag字段就能解决MyBatis-Plus 还内置了逻辑删除支持配置一下就能自动拼上WHERE delete_flag 0成本极低。3.2 字段设计的细节考量summary摘要字段是我建议加的。列表页不需要把整篇日记的内容都加载出来只展示 50~100 字的摘要点击进去再看全文。这样列表接口返回的数据量小前端渲染也流畅。摘要可以在后端保存时自动截取正文前 100 字不需要用户手动填。mood和weather这类字段很多人会纠结单独建表还是直接存字符串。我的建议是直接存字符串比如 mood 存“开心/sad/excited”weather 存“晴/雨/阴”。因为它们只是为了筛选和统计不需要单独维护字典。如果建个心情字典表反而要写多余的表关联逻辑对毕设来说没必要。标签用关联表还是tag_ids字段存逗号拼接这个问题我踩过坑。一开始我用的是diary表加一个tag_ids字段类似“1,3,5”。后来发现两个明显问题按标签筛选时要用FIND_IN_SET或模糊匹配效率低且写法不优雅统计每个标签下有多少篇日记时SQL 写起来非常痛苦。后来改成diary_tag关联表查询变得清晰很多。多对多关系就该用关联表哪怕只是单纯为了毕设好解释。关于图片我单独建了diary_image表而不是把多张图的 URL 拼接到一个字段里。原因和标签类似后面做相册展示、删除某一张图、调整图片顺序时用独立表操作更合理。封面封面 URL 存在diary.cover_image正文插图存在关联表中的image_url两者分工明确。3.3 SQL 索引设计索引不需要多三五个足够。diary表的user_id必须建索引因为所有查询都带着WHERE user_id ?。diary表的create_time建索引用于按月统计和日历视图。diary_tag表的diary_id和tag_id各建一个普通索引或者建联合索引(diary_id, tag_id)注意别在关联表里把两个字段都设成主键否则同一个日记打多个标签时主键会冲突选一个自增 id 做主键最省心。4. 后端核心链路日记增删改查、检索与统计是怎么落地的4.1 项目分层与接口规划后端我不建议搞太复杂的微服务架构一个单体 Maven 项目包结构按controller/service/mapper/entity/common划分就够。接口统一走/api/**路径登录接口放行其余接口都走 JWT 拦截器校验。下面是我当时用的接口规划方法路径说明POST/api/user/register注册POST/api/user/login登录返回 tokenGET/api/diary/list分页列出当前用户日记GET/api/diary/detail/{id}日记详情POST/api/diary/add新增日记POST/api/diary/update修改日记DELETE/api/diary/delete/{id}逻辑删除日记GET/api/tag/list标签列表GET/api/statistics/month按月统计POST/api/file/upload上传图片返回 URL接口数量看起来很常规但每个接口写起来都有细节。我以“新增日记”为例把后端的处理流程说清楚。4.2 新增日记接口的实现逻辑下面是简化后的 controller 和 service 关键代码我保留主流程省略参数校验等细节RestController RequestMapping(/api/diary) public class DiaryController { Resource private DiaryService diaryService; PostMapping(/add) public Result add(RequestBody DiaryDto dto) { // 从拦截器放入的 ThreadLocal 中拿到当前登录用户 id Long userId UserContext.getUserId(); diaryService.addDiary(dto, userId); return Result.ok(); } }Service 层做的事情就三件Service public class DiaryServiceImpl implements DiaryService { Resource private DiaryMapper diaryMapper; Resource private DiaryTagMapper diaryTagMapper; Override Transactional(rollbackFor Exception.class) public void addDiary(DiaryDto dto, Long userId) { // 1. 保存日记主表 Diary diary new Diary(); diary.setUserId(userId); diary.setTitle(dto.getTitle()); diary.setContent(dto.getContent()); diary.setSummary(DiaryUtil.buildSummary(dto.getContent())); diary.setMood(dto.getMood()); diary.setWeather(dto.getWeather()); if (dto.getCoverImage() ! null) { diary.setCoverImage(dto.getCoverImage()); } diaryMapper.insert(diary); // 2. 处理标签先确认标签存在再插入关联表 ListLong tagIds dto.getTagIds(); if (tagIds ! null !tagIds.isEmpty()) { for (Long tagId : tagIds) { DiaryTag diaryTag new DiaryTag(); diaryTag.setDiaryId(diary.getId()); diaryTag.setTagId(tagId); diaryTagMapper.insert(diaryTag); } } // 3. 保存图片关联把前端传入的图片 URL 写入日记图片表 ListString imageUrls dto.getImageUrls(); if (imageUrls ! null) { for (int i 0; i imageUrls.size(); i) { DiaryImage image new DiaryImage(); image.setDiaryId(diary.getId()); image.setImageUrl(imageUrls.get(i)); image.setSortOrder(i); diaryImageMapper.insert(image); } } } }这里有一个关键点新增日记涉及多张表的写入操作务必加Transactional事务注解。否则日记主表插入成功、标签表插入失败时会出现脏数据。答辩的时候老师很喜欢问“你怎么保证数据一致性”事务就是你最直接的回答。还有UserContext是我用ThreadLocal封装的工具类拦截器里从 JWT 解析出 userId 后放进去Controller 或 Service 里直接取。比每个接口都从参数里带 userId 干净得多。4.3 全文检索和统计查询的实现思路日记内容检索不要一上来就上 Elasticsearch。对毕设项目来说日记数据量撑死几千条用 MySQL 自带的全文索引或者简单的 LIKE 查询完全够用。我这里给出一个性能与复杂度折中的方案标题和摘要用LIKE %关键词%配合 MySQL 全文索引MATCH...AGAINST。或者直接用 MyBatis-Plus 的LambdaQueryWrapper做likeRight和like的组合查询。统计模块按月份统计日记数量SQL 大概是这个意思SELECT DATE_FORMAT(create_time, %Y-%m) AS month, COUNT(*) AS total FROM diary WHERE user_id #{userId} AND delete_flag 0 GROUP BY DATE_FORMAT(create_time, %Y-%m) ORDER BY month DESC按心情统计也是一样的套路把分组字段换成mood即可。我建议这类统计逻辑都写到 Mapper XML 里用专门的统计方法返回ListMapString, Object后端不要做二次聚合代码更简洁也方便让老师看到你 SQL 功底。4.4 文件上传的本地存储方案文件上传能用原生 SpringMVC 就足够了。配置一个上传目录比如D:/diary-files/然后用/upload/**映射到这个目录。保存文件时用 UUID 重命名文件防止用户文件名中有中文字符导致 URL 乱码。上传接口返回的 URL 是http://localhost:8080/upload/xxx.jpg前端拿到这个 URL 后存到diary_image表里。需要注意后端返回的 URL 不能写死 IP 和端口否则手机 App 在真机调试时访问不到。正确做法是前端拿到相对路径/upload/xxx.jpg由前端根据当前环境动态拼出完整地址。这个细节我在 Android 端联调时吃过亏后面专门踩坑。5. Vue Web端页面从登录到日记墙的完整交互流5.1 工程搭建和页面结构Vue 端我用的是 Vite Vue3 Pinia Element Plus 的组合。没有用 Vue2因为 Vue3 的响应式逻辑更舒服而且毕设答辩时面试官看“是不是新版本”也是一个加分项。项目结构大致是这样src/ api/ // 封装 axios 请求 router/ // 路由配置 stores/ // Pinia 状态管理 views/ // 页面组件 LoginView.vue DiaryListView.vue DiaryDetailView.vue DiaryEditView.vue StatsView.vue layout/ // 通用布局组件路由设计时要注意所有日记相关的页面都应该在登录后访问。所以我给路由加了全局前置守卫没有 token 就重定向到登录页。这里头有一个坑刷新页面时 Pinia 里的 userInfo 会丢失必须从 localStorage 或者后端重新获取。我建议在main.js初始化时读一次 localStorage这样刷新不会退出登录。5.2 日记列表页的时间轴与筛选Web 端日记列表我做了“时间轴 标签筛选”的组合。左侧是按时间倒序排列的日记卡片每张卡片展示封面图、标题、摘要、心情图标、标签右侧是一个标签云面板点击某个标签列表就只展示打上该标签的日记。这个设计看起来简单但能同时把“日记、标签、筛选”三个核心功能全部打通答辩时的演示效果很好。前端调用列表接口时Axios 封装里需要做两件事请求拦截器自动带上Authorization头响应拦截器识别401状态码并跳转登录页。这部分贴一个简单实例// src/api/request.js import axios from axios import router from /router const request axios.create({ baseURL: /api }) request.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization Bearer ${token} } return config }) request.interceptors.response.use( response response.data, error { if (error.response error.response.status 401) { localStorage.removeItem(token) router.push(/login) } return Promise.reject(error) } ) export default request写日记的编辑页面我用的是富文本编辑器。刚开始想自己封装 contenteditable后来发现工作量太大直接用 wangEditor 或 tinymce 就好。富文本保存的是 HTML 字符串后端存到diary.content。这里要注意 XSS 问题日记内容是用户自己的私密内容虽然不像博客那么容易被攻击但后端最好还是加一个简单的 HTML 标签过滤。当初学弟的毕设里有个面试官追问“富文本内容如何防 XSS”他没答上来很可惜。你至少能够说出“对script、iframe等标签做过滤或者使用第三方库做清洗”这就够了。5.3 统计面板的图表展示统计页面我用了 ECharts。第一个图是月度日记数量柱状图X 轴是月份Y 轴是日记数量第二个图是心情分布饼图统计一段时间内各种心情出现的比例。ECharts 的配置不需要写太多用init方法 setOption就行关键是后端要把数据格式整理成图表需要的结构。我这里统一返回[{ name: 2025-03, value: 12 }]这种数组格式前端直接映射。图表不需要花哨清晰即可。5.4 跨域问题开发时 Vue 在 5173 端口后端在 8080 端口跨域是必然的。最省事方式是在 Vite 配置 devServer 代理把/api转发到http://localhost:8080。这样前端请求地址就保持相对路径也不用在后端加CrossOrigin。如果整个项目打包到一起部署后端直接处理静态资源反而没有跨域问题。CORS 配置留到生产环境才考虑开发环境用代理最方便。6. Android客户端的记录体验拍照、富文本与自动同步6.1 Android 端技术框架选型Android 端我采用的是标准的 MVVM 分层结构视图层用 Activity Fragment 和 RecyclerView网络层用 Retrofit OkHttp本地存储用 Room。这个组合非常常规但很稳妥。Retrofit 的接口定义如下public interface DiaryApi { GET(api/diary/list) CallApiResponsePageResultDiaryVO list(Query(page) int page, Query(size) int size); POST(api/diary/add) CallApiResponseVoid add(Body DiaryAddRequest request); POST(api/diary/update) CallApiResponseVoid update(Body DiaryAddRequest request); DELETE(api/diary/delete/{id}) CallApiResponseVoid delete(Path(id) long id); POST(api/file/upload) CallApiResponseString upload(Part MultipartBody.Part file); }Retrofit 接口定义看起来简单但对接后端时有一个很容易踩的坑后端接口返回的 JSON 结构必须和前端实体类字段一一对应。比如后端的createTime如果前端用create_time去接收反序列化就会失败。我建议后端统一使用驼峰命名并且配置 Jackson 的spring.jackson.property-naming-strategySNAKE_CASE或者在 Android 端加SerializedName(create_time)注解这样两边的命名规范可以协调。我选的是后者因为改动范围小Android 端自己控制。6.2 Room 本地缓存与离线支持个人日记最大的场景是随时记录但手机网络不稳定时不能卡住用户。Room 在这里的作用是把已加载的日记列表缓存到 SQLite 中。首次联网拉取成功后写入 Room之后进入 App 先查 Room再发起网络请求更新。用户写的日记内容我先存到 Room 里的“待同步表”等网络恢复后再自动提交到后端。这个设计是 Android 端展示“智能”的重要亮点答辩时一定要讲到。Room 实体和 DAO 写起来不复杂核心是建一个diary_entity表和对应的 DAOEntity(tableName diary_entity) public class DiaryEntity { PrimaryKey private Long id; private String title; private String content; private String mood; private String coverImage; private Long createTime; private int syncStatus; // 0 已同步1 待同步 }同步逻辑我用 WorkManager 做定时任务每半个小时检查一次待同步数据。这个机制比 Service 更推荐因为 WorkManager 能处理系统重启、任务延迟等场景也算是一个加分项。当然如果不想引入 WorkManager用简单的Executor配合 BroadcastReceiver 也能实现但可讲的技术点会少很多。6.3 拍照上传和文件路径问题Android 端拍照插入日记是最常用的功能。我用的是 FileProvider 来生成图片 Uri因为 Android 7.0 以后不能直接暴露file://路径。调起摄像头后拿到图片经过压缩再上传到后端。这部分有一个在真机调试时特别容易踩的坑就是图片上传成功后后端返回的 URL 需要拼接域名才能显示。如果你用模拟器访问localhost没问题但真机上必须换成电脑的局域网 IP比如http://192.168.1.101:8080。这个地址不能写死在代码里我是在 App 的BuildConfig里配置了一个BASE_URL常量打包时用 buildType 区分。演示现场如果遇到网络问题第一个先检查 IP 通不通第二个检查 Android 的网络安全配置是否允许明文 HTTP 请求。Android 9 之后默认禁止明文流量需要在 manifest 里配置android:usesCleartextTraffictrue我见过不少人在这一步卡住。文件上传时要注意图片不要原图上传。手机拍摄的照片动辄 3~5MB上传慢且消耗流量后端存储也是压力。我在上传前做了压缩处理尺寸压缩到 1280px 宽质量压缩到 80%图片体积能控制在 200KB 左右列表页加载明显更流畅。6.4 日记列表的展示Android 端日记列表用 RecyclerView结合 GridLayoutManager 或 StaggeredGridLayoutManager 做成瀑布流。每张日记卡片和 Web 端类似显示封面、标题、时间和心情图标。RecyclerView 的 Adapter 里需要注意图片加载库我用的是 Glide。列表虽然简单但涉及性能优化复用时如果封面图没有重置会出现图片错位加一行.clear()或者.override()能避免。这类细节答辩时提一嘴专业感就出来了。7. 部署、测试和答辩避坑的经验清单7.1 本地部署的全流程演示环节是最容易出问题的。我建议提前准备一套完整的部署流程写成 README现场照着走也不会慌张。后端打包用 Maven 插件执行mvn clean package生成 jar然后java -jar启动。Vue 端先用npm run build构建出dist目录然后把dist拷贝到 SpringBoot 的static目录下后端直接托管前端静态资源这样演示时只需要启动一个 Java 进程不用再单独开一个 Vue 服务省心很多。Android 端安装到手机时注意签名问题。直接用 debug 签名安装最容易但有些手机限制安装未知来源应用需要在开发者模式里打开“允许安装未知应用”。如果到场演示的是模拟器最后提前在模拟器里把 App 启动一次免得现场模拟器启动慢演示过程干等。7.2 测试用例设计虽然毕设不要求写完整的自动化测试但至少要准备几个手工测试用例防止功能漏洞被答辩老师当场发现。我建议重点覆盖以下几类不同长度正文的日记摘要是否正确截取。同一用户并发新增多条日记列表分页是否正确。标签最多选 5 个防止无限制选择导致关联表数据膨胀。上传非图片类型文件后端能否拒绝。删除一篇带标签和图片的日记刷新列表后是否彻底消失。修改日记后旧图片是否被清掉。这些测试点提到的边界情况很多同学根本就不会测实际上非常容易出现 bug。比如删除日记时只删了主表没删diary_tag和diary_image结果用户日志里的数据还在关联表里躺着。我在开发时用事务处理了这个问题答辩时举例也是加分项删除日记要把三张表的数据联动清理。7.3 答辩高频问题应对表最后给你做了个高频问题清单这是我陪好几个学弟模拟答辩时整理出来的直接抄作业老师可能问的问题建议回答思路为什么不用 MongoDB 而用 MySQL日记数据结构相对固定MySQL 支持事务多表关联查询方便而且群组统计场景用 SQL 聚合更简单。密码是怎么存的BCrypt 哈希加密不存明文。演示时可以说加盐哈希。日记数据安全怎么保证JWT 校验 用户数据隔离查询条件强制带 userId防止横向越权。为什么不用 MongoDB 存日记内容内容长度不会特别大MySQL 的 TEXT 类型足够后续做全文索引更顺手。Web 端和 App 端同步机制是什么两端共用同一套后端接口App 端通过 Room WorkManager 实现离线缓存和自动补交。系统最大的扩展点在哪日记内容加入全文检索、心情分析、基于标签的推荐、多端多用户协作等。前端为什么用 Vue 不用 React项目需要快速搭建管理页面Vue 生态成熟中文资料多小组合作更容易上手。你可以根据自己实际项目再补充几个针对性问题。最关键的一点是回答问题时不要只背概念尽量往自己的代码逻辑上引。比如问“JWT 和 Session 有什么区别”你不要只背无状态和有状态就说“我在拦截器里解析 token拿到 userId 后放 ThreadLocal每个接口通过 UserContext 取当前用户”这叫可落地的回答。7.4 几个让我印象深刻的教训最后聊几句实在话。我对这个题目的最大感受是真正决定毕设质量上限的不是技术难度而是细节完整性。比如逻辑删除很多人忽略结果演示误删了一篇日记后直接消失再比如图片上传后 URL 拼接错误手机端图片全部加载不出来演示现场看起来特别狼狈。这些坑我在做这个项目时基本都踩过一遍。如果你时间紧张至少要把“新增日记、列表分页、标签筛选、统计图表、App 离线同步”这五个链路全部走通它们是这个题目的骨架。答辩时老师大概率不会刁难你只要把每个模块的“为什么这样设计”说出来就已经比大多数选手强了。这套思路不止适用于这个毕设任何前后端分离的跨端项目都可以参照。希望上面这些经验能让你少走一些弯路祝答辩顺利。
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

从零构建AI工程系统:五层骨架实战指南 2026/9/28 13:22:42

从零构建AI工程系统:五层骨架实战指南

1. 这不是教你怎么调包,而是带你亲手“造轮子”:从零构建AI工程系统的真实路径“AI Engineering from Scratch”——看到这个标题,很多人第一反应是:“又要学Python?又要装CUDA?又要配环境?”其…

阅读更多 →
YOLO轮胎字符识别实战:小目标、畸变、强干扰下的工业OCR落地 2026/9/28 13:22:36

YOLO轮胎字符识别实战:小目标、畸变、强干扰下的工业OCR落地

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

阅读更多 →
Hive去重:distinct与group by的执行原理及优化 2026/9/28 13:22:30

Hive去重:distinct与group by的执行原理及优化

刚入行那年,我在一次面试里被问过这么一个问题:“Hive 里去重到底用 distinct 还是 group by?”我当时的回答是“优先 group by,distinct 慢”,但对方追问了一句“为什么慢,慢在哪一步”,我一下…

阅读更多 →
安全分析与市场分析同一化:用预期商业损失统一风险与机会评估 2026/9/28 13:22:30

安全分析与市场分析同一化:用预期商业损失统一风险与机会评估

1. 为什么安全分析与市场分析必须放在同一张桌上1.1 大多数团队最大的问题:安全与市场各说各话在绝大多数公司里,安全团队和市场团队是两种完全不同的生物。安全团队天天讲漏洞、攻击面、数据泄露概率、等保合规,汇报用的是一套“风险语言”。…

阅读更多 →
机器学习基本面量化实战:财报数据因子建模与回测防泄漏 2026/9/28 13:22:30

机器学习基本面量化实战:财报数据因子建模与回测防泄漏

简介:这是一份将基本面分析与多种机器学习算法相结合的量化投资研究项目,面向金融、统计及计算机背景的学生、研究者和入门量化分析师。包内167个CSV文件构成基本面因子数据集(涵盖销售、ROA、ROE、市值、净经营资产等指标)&#…

阅读更多 →
Betaflight 4.5 DSHOT双向通信配置避坑指南:STM32F411飞控实战 2026/9/28 13:22:29

Betaflight 4.5 DSHOT双向通信配置避坑指南:STM32F411飞控实战

1. 穿越机飞控避坑手册:Betaflight 4.5的DSHOT双向通信配置陷阱解析1.1 为什么DSHOT双向通信值得单独写一篇避坑指南DSHOT双向通信(Bidirectional DSHOT)是Betaflight 4.x时代最实用的功能升级之一。简单说,它让飞控和电调之间的通…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

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

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