2026/11/2 3:41:41

软件工程实习知识地图:从需求分析到增删改查交付链路

软件工程实习知识地图:从需求分析到增删改查交付链路 简介《软件工程实习记录》面向本科软件工程专业学生及需要完成毕业实习材料整理的学习者提供一份可按周参考、修改的实习记录范本重点解决实习过程描述空泛、技术要点与岗位认知难以串联的问题。压缩包内仅含1个doc文件约40KB内容以时间线组织便于直接编辑和套用。记录从公司实习动员、分组开发到具体任务推进串联可行性分析、需求分析、概要设计、详细设计、编码与项目验收等开发流程并涉及项目经理职责、软件开发主要职位及前后端技术栈。文中还包含Eclipse与Swing界面实现、HTML/CSS/JavaScript页面、Node.js单页请求与数据库连接、MySQL增删改查、Linux环境与ARM开发板等实践片段可帮助读者补充技术细节、梳理实习周志结构。已有2924人学习适合作为实习记录撰写与内容完善的参考。1. 软件工程实习知识地图五周记录里藏着的六条主线毕业实习临近很多人开始补软件工程实习记录最容易写成“今天装环境、明天写页面”的流水账。这份五周记录真正值得复习的地方是它把一条软件交付链路走了一遍可行性分析与需求、桌面端小工具、Web 页面与动态数据、Node 服务端与数据库、Struts/Spring/Hibernate 分层、项目建模、编码乱码与部署排错。把它当知识地图看编码只是其中一段约15%的时间却在决定验收体验。适合正在写毕业实习记录、准备软件工程复试或做课程设计复盘的人。下面按模块拆重点、易错点和复习清单。2. 开发流程与岗位角色可行性分析到验收的六个节点软件工程实习记录里最容易被当成背诵题的是流程。真正要复习的是每个节点交付什么、谁来确认、出了问题回哪一步补。流程节点不是瀑布教条而是一张检查清单可行性分析决定做不做需求分析决定做什么概要设计决定分几块详细设计决定每块怎么落地编码决定能不能跑项目验收决定客户认不认。重点难点不在名词而在需求边界和验收标准这两处没写清后面编码越努力越容易返工。2.1 六个流程节点每个阶段到底交付什么把六个节点拆成“核心问题 典型产出 记录里的动作”复习时就不容易混。可行性分析不是写一段套话而是判断技术、经济、操作、进度四条线是否成立需求分析要把用户口中的“能查、能加、能改”转成输入、操作、预期输出和异常提示概要设计要划模块和接口详细设计要落到表结构、页面、类和流程编码要带自测项目验收要有客户确认和缺陷修复记录。阶段核心问题典型产出记录中的对应动作可行性分析值不值得做能不能做可行性结论、风险清单了解公司项目类型和开发流程需求分析用户要什么边界在哪需求清单、原型、验收用例明确查找、排序、录入、删除等功能概要设计分几个模块接口怎么定模块划分、接口表、数据流分视图包、主程序包、控制类详细设计每个模块怎么实现表结构、页面结构、类设计设计输入框、按钮、表格、SQL编码能不能按设计跑通代码、提交记录、自测记录完成查找、排序、增删改查项目验收客户认不认缺陷修没修验收单、用户手册、修复记录部署后访问主页、确认功能可用复习时可以用一张需求条目模板把“需求分析”和“验收”扣在一起。下面这份 YAML 不是正式文档格式而是把一条需求写到能测试的程度写不到“预期输出”说明需求还没想清楚。# 需求条目模板一条需求必须能落到验收动作 id: REQ-001 scene: 图书信息录入 input: 编号、书名、作者、价格 action: 点击“保存” expect: 页面提示成功数据库新增一条记录 priority: P0 evidence: 截图、接口返回、数据库查询结果说明id用于追踪需求变更scene写用户场景input和action定义操作入口expect是验收时的判断依据priority决定先做哪条evidence是验收证据。参数可以按项目改但expect不能写成“功能正常”这种无法判断的句子。小项目也要有轻量版一页需求清单、一张表结构、一张接口表、一份验收清单四样东西能挡住大部分返工。2.2 编码只占15%返工成本藏在需求与验收记录里提到“代码实现只占整个开发过程的15%”这句话容易被误解成编码不重要。更准确的理解是编码是把前面想清楚的东西翻译出来真正耗时间的是需求反复、设计返工、联调排错和验收扯皮。文件查找功能一开始只能从固定地址查找表面是代码问题实际是需求里没写“查找范围是否可配置”教师信息添加后重复显示表面是前端问题实际是“添加后应该重新渲染还是追加”没在设计里说清。这些坑都不是语法不会而是边界没定。需求变更不可怕可怕的是变更只停在聊天里。复习时记住三个动作变更先记一条写清影响哪个页面、哪张表、哪条验收用例设计跟着改至少改接口和表结构说明验收用例同步改否则最后客户按旧标准验开发按新功能做双方都觉得自己有理。把“能跑”当验收是另一个常见坑能跑只说明主流程通异常输入、重复提交、权限不足、中文乱码、端口占用都还没验。返工来源常见表现预防动作需求边界不清查找范围、排序规则、重复添加反复改需求条目写到输入、操作、预期设计漏异常空关键字、无结果、权限不足没处理详细设计加异常分支验收标准模糊“能查就行”最后变成“怎么查都不对”验收用例前置和需求条目对应环境差异本机能跑部署后 500编码阶段就记录依赖版本和端口重点在于把非功能需求也写进检查清单编码用哪种字符集端口是多少部署在哪个目录权限账号是谁日志在哪里看。这些内容在实习记录里往往以“翻车”形式出现复习时要把它们提前成设计项而不是等报错再补。2.3 岗位角色与项目经理谁对什么负责记录里列了软件开发员、项目经理、技术总监、架构师、总经理、售前售后等岗位复习时不要只背名称要看每个岗位在一条功能链上接哪一段。开发员对模块实现和自测负责项目经理对计划、组织、协调、控制负责架构师对技术选型、分层和关键接口负责技术总监对技术路线和团队能力负责售前售后是需求入口和交付出口总经理负责资源和经营。岗位不同关注点不同但都要能说清“这个功能现在卡在谁那里”。岗位核心职责与实习任务的对应软件开发员按设计实现模块完成自测查找、排序、页面、增删改查项目经理计划、组织、协调、控制探讨系统功能定优先级和边界架构师分层、选型、接口约束视图包、控制类、服务端分层技术总监技术路线与团队技术决策框架选型、环境规范售前售后需求收集、交付支持验收反馈、问题回访总经理资源与经营项目是否立项、投入多少项目经理最容易误解成“写代码最多的人”。实际更像三张表的维护者需求表说明做什么进度表说明先做哪条风险表说明哪里可能炸。实习记录里“我们扮演项目经理角色共同探讨功能”重点不是头衔而是先把图书录入、删除、编辑这些功能边界说清。复习就业方向时可以拿一个功能从需求到验收走一遍看自己在哪一段最能出力这比只背岗位名称有用。3. 桌面端与前端基础查找、排序、表格回显的三个实现要点桌面端小工具和前端页面是实习记录里最“可复现”的部分。复习重点不是界面多漂亮而是数据流是否清楚输入框拿到关键字过滤出结果按规则排序再渲染到页面或表格。查找、排序、表格回显这三个功能刚好覆盖了“输入—处理—输出”的最小闭环也最容易暴露路径写死、排序规则不清、重复渲染这些基础问题。下面用三段代码把关键点拆开代码是示意参数和目录可按项目改。3.1 文件查找从输入框到结果回显路径为什么要可配置文件查找的需求可以写成用户在输入框输入文件名或商品名片段系统在指定目录下模糊匹配匹配结果回显到页面。视图层用面板、输入框、按钮、结果列表搭出来组件设置相对位置和事件监听业务层负责遍历目录和匹配文件名。实习记录里最初只能从固定地址查找问题不在“不会遍历”而在根目录被写死在代码里。把根目录改成配置项或目录选择器功能才从演示程序变成可用的工具。// 在指定根目录下按关键字模糊查找文件返回匹配列表 public static ListFile searchFiles(File root, String keyword) { ListFile result new ArrayList(); if (root null || !root.exists() || keyword null || keyword.trim().isEmpty()) { return result; // 空关键字直接返回避免全盘扫描 } String key keyword.toLowerCase(); QueueFile queue new LinkedList(); queue.offer(root); while (!queue.isEmpty()) { File current queue.poll(); File[] children current.listFiles(); if (children null) continue; // 权限不足时跳过 for (File child : children) { if (child.isDirectory()) { queue.offer(child); } else if (child.getName().toLowerCase().contains(key)) { result.add(child); } } } return result; }说明root是查找根目录keyword是用户输入的关键字返回值是匹配到的文件列表。contains实现模糊查找toLowerCase让匹配忽略大小写用队列而不是递归避免目录太深时栈溢出listFiles返回null通常是没有权限直接跳过比抛异常更稳。重点是把root从固定路径改成可配置项并在界面上给出“无结果”和“目录不可读”的提示。复习时还要注意Swing 界面不要在事件线程里做长任务文件多时用后台任务否则界面会像卡死一样。3.2 文件排序按文件名冒泡排序与模糊查找的组合文件排序的需求是把磁盘中现存文件按文件名排序同时支持模糊查找再把结果回显。这里有两个容易混的点排序键是文件名还是完整路径排序发生在过滤前还是过滤后。合理顺序是先按关键字过滤再对结果排序最后渲染如果先对全盘排序再过滤数据量大时白做很多功。冒泡排序适合小数据量演示能看清比较和交换的过程但真实项目应换成Comparator或集合排序。// 按文件名升序排序小数据量演示用 public static void bubbleSortByFileName(File[] files) { for (int i 0; i files.length - 1; i) { for (int j 0; j files.length - 1 - i; j) { if (files[j].getName().compareToIgnoreCase(files[j 1].getName()) 0) { File temp files[j]; files[j] files[j 1]; files[j 1] temp; } } } }说明files是待排序文件数组compareToIgnoreCase按文件名忽略大小写比较外层循环控制轮次内层循环做相邻交换。冒泡的时间复杂度是 O(n²)文件少时够用文件多时性能会明显下降真实项目用Arrays.sort(files, Comparator.comparing(File::getName, String.CASE_INSENSITIVE_ORDER))更合适。重点难点是排序规则要写进需求数字文件名按字典序会出现10排在2前面如果用户预期是自然序就要单独处理。排序后回显的结果必须和查找结果一致不能一个列表过滤、另一个列表排序。3.3 教师信息表格数组静态渲染与添加前去重前端页面用 HTML 搭结构、CSS 做样式、JavaScript 做动态效果教师信息先用数组存静态数据再用表格显示。添加功能读取编号、姓名、课程名三个输入框点击按钮后把信息显示到页面。实习记录里出现“添加的信息重复显示”原因通常是每次添加都往表格后面追加一行却没有清掉上一轮渲染。解决方式不是删某一行而是把“数据”和“渲染”分开数组负责存渲染函数负责先清空容器再按数组重画。// 先清空再重渲染避免添加后重复显示 const teachers []; function renderTeachers() { const tbody document.querySelector(#teacherTable tbody); tbody.innerHTML ; // 关键每次渲染前清空旧行 teachers.forEach(t { const tr document.createElement(tr); tr.innerHTML td${t.id}/tdtd${t.name}/tdtd${t.course}/td; tbody.appendChild(tr); }); } function addTeacher() { const id document.querySelector(#id).value.trim(); const name document.querySelector(#name).value.trim(); const course document.querySelector(#course).value.trim(); if (!id || !name || !course) return alert(三项都不能为空); if (teachers.some(t t.id id)) return alert(编号不能重复); teachers.push({ id, name, course }); renderTeachers(); // 重新渲染而不是追加 }说明teachers是对象数组字段为id、name、courserenderTeachers先清空tbody再遍历数组生成行addTeacher读取三个输入框校验必填和编号唯一最后调用重渲染。参数来自页面输入编号作为唯一键重复时提示而不是覆盖。静态数组只适合演示真实数据要从数据库读两者最大差别不是代码长短而是数据来源、持久化和并发修改。复习时把“数组渲染”当成前端数据流练习后面接服务端时只需把数组换成接口返回的 JSON。对比项静态数组数据库数据来源页面内写死或初始化服务端查询持久化刷新即丢可长期保存重复校验前端数组判断主键或唯一索引多人使用各看各的需要事务和权限4. 服务端与数据库从 Express 路由到增删改查的闭环从静态页面走到服务端复习主线只有一条页面发请求服务端收请求数据库读写结果转成 JSON 回显。Node.js 项目初始化、Express 的 GET/POST、MySQL 建表和连接、增删改查映射都是这条主线上的节点。重点不是背 API而是知道每个按钮背后走哪条路由、执行哪条 SQL、失败时看哪层日志。框架分层也放在这一章一起梳理因为 Struts、Spring、Hibernate 和 JSP 解决的是同一件事让页面、业务、数据访问各归其位。4.1 Node.js 项目初始化与 Express 路由GET/POST 的边界Node 项目初始化先建目录再生成package.json然后安装 Express 和数据库驱动。npm init -y省去交互式填写npm install把依赖写进项目。Express 的最小路由先跑静态数组确认请求响应通了再换数据库这样排错时能分清是路由问题还是数据库问题。GET 用来查询参数放在 URL 或查询串POST 用来新增参数放在请求体服务端必须加解析中间件否则req.body是空。# 初始化一个最小 Node 项目并安装 Express 与 MySQL 驱动 mkdir demo-server cd demo-server npm init -y npm install express mysql2说明mkdir demo-server建项目目录npm init -y生成默认package.jsonnpm install express mysql2安装 Web 框架和数据库驱动。目录名、依赖版本按项目定重点是把依赖写进package.json换机器时用npm install还原而不是靠记忆装。// 最小路由GET 查询POST 新增数据先放内存数组 const express require(express); const app express(); app.use(express.json()); // 解析 JSON 请求体POST 必需 let students [{ id: 1, name: A同学, course: 软件工程 }]; app.get(/students, (req, res) { res.json(students); // 返回 JSON前端负责渲染 }); app.post(/students, (req, res) { const { id, name, course } req.body; if (!id || !name || !course) return res.status(400).json({ msg: 参数缺失 }); students.push({ id, name, course }); res.json({ ok: true }); }); app.listen(3000, () console.log(server on 3000));说明express.json()解析 JSON 请求体没有它 POST 拿不到字段app.get(/students)对应查询app.post(/students)对应新增端口3000可改路径可换成/books参数缺失返回 400前端据此提示。重点难点是 GET 和 POST 的语义边界查询用 GET新增用 POST删除和修改不要图省事全塞进 GET否则刷新、缓存和日志都会混淆。4.2 MySQL 数据导入与连接Excel 到表、字符集与 JSON 回显数据库这一步分三段建库建表、导入数据、代码连接。Excel 导入前先清洗列名和类型编号做主键姓名和课程名设非空建表时把字符集定好后面连接、页面、库表三处编码保持一致。连接代码用连接池查询结果直接是数组转 JSON 回显给前端。中文乱码经常不是数据库一个人的问题而是页面编码、连接字符集、库表字符集三处不一致只改一处另外两处还会把乱码带回来。-- 教师表主键编号字符集统一 utf8mb4 CREATE TABLE teacher ( id VARCHAR(20) PRIMARY KEY, name VARCHAR(50) NOT NULL, course VARCHAR(50) NOT NULL ) DEFAULT CHARSETutf8mb4;说明id做主键防重复name和course非空utf8mb4支持中文和更多字符。旧项目可能用gbk跑通但新项目优先utf8mb4如果历史数据是gbk导入时要先转换不能直接混用。// mysql2 连接池查询结果直接转 JSON 回显 const mysql require(mysql2/promise); const pool mysql.createPool({ host: 127.0.0.1, user: demo, password: demo123, database: school, charset: utf8mb4 }); async function listTeachers() { const [rows] await pool.query(SELECT id, name, course FROM teacher); return rows; // rows 是数组可直接 res.json(rows) }说明host、user、password、database按本地环境改charset要和库表一致连接池复用连接比每次查询新建连接稳query返回[rows, fields]rows可直接res.json。中文录不进去时先查连接字符集再查库表字符集最后查页面meta和表单提交编码。4.3 增删改查按钮事件到 SQL 的映射增删改查不是四个孤立函数而是一张映射表页面按钮触发事件事件发请求路由收参数SQL 执行结果回显。新增对应 INSERT删除对应 DELETE修改对应 UPDATE查询对应 SELECT删除前确认修改前先回显查询后统一渲染。前端删除成功后要重新拉列表不能只把页面那行删掉否则数据库没删刷新又回来。操作前端动作请求SQL新增表单提交POST /booksINSERT INTO book ...删除点击删除并确认DELETE /books/:idDELETE FROM book WHERE id?修改新窗口打开表单PUT /books/:idUPDATE book SET ... WHERE id?查询页面加载或搜索GET /books?keywordSELECT ... FROM book WHERE name LIKE ?// 删除按钮先确认再发 DELETE成功后重新拉列表 async function deleteBook(id) { if (!confirm(确认删除)) return; const resp await fetch(/books/${id}, { method: DELETE }); if (!resp.ok) return alert(删除失败查看服务端日志); loadBooks(); // 重新查询避免前端假删除 }说明id是路径参数confirm防误删resp.ok判断 HTTP 状态loadBooks重新查询保证页面和后端一致。重点难点是修改功能先用 GET 把旧数据回显到表单再 PUT 提交如果直接把列表页的超链接改成新窗口要确认新窗口能拿到id否则表单不知道改哪条。删除和修改都要做权限与存在性校验不能只靠前端按钮隐藏。4.4 框架分层Struts、Spring、Hibernate 与 JSP 各管哪一段记录里把 Struts 放在表示层Spring 放在业务逻辑层Hibernate 放在持久层这个分法适合先建立地图但复习时要再往下走一层。Struts 是 MVC 框架主要处理请求分发和页面跳转Spring 通过 IOC 管理对象依赖用 AOP 处理横切逻辑声明式事务也在这里配Hibernate 是 ORM 中间件把对象和表映射起来封装 JDBC减少手写 SQLJSP 是动态网页技术在页面里嵌 Java 片段和标签由服务端生成页面。它们不是三个标签而是一条请求链上的不同工位。框架/技术所在层主要职责容易混淆的点Struts表示层/控制接收请求、分发、跳转不是业务逻辑层Spring业务逻辑/容器IOC、AOP、事务管理IOC 不是“控制反转”四个字背完就行Hibernate持久层对象关系映射、封装 JDBCORM 不等于不用懂 SQLJSP页面技术动态生成页面、回显数据不是前端框架重点在于分层的目的分工部门用同一套模式写代码基本结构自动生成代码可读性和复用性提高成本下降。复习时用一个图书查询流程串起来JSP本文还有配套的精品资源点击获取