简介:《软件工程实习记录》面向软件工程、计算机相关专业本科生及需要完成实习报告、毕业材料整理的学生,提供一份可直接参考和修改的本科实习记录范文。内容按周记录实习过程与实习方式,覆盖可行性分析、需求分析、概要设计、详细设计、编码、项目验收等开发流程,并穿插项目经理职责、开发岗位分工与技术栈说明。日志中还涉及文件查找与排序、教师信息页面、Node.js 与 MySQL 增删改查、Linux 与 ARM 开发环境等实践场景,便于读者对照自身实习经历补充日志、梳理项目环节和整理收获。包内共1个doc文件,约40KB,结构集中,适合快速查阅与二次编辑。目前已有2924人学习,可作为实习记录撰写、课程实践总结和就业材料准备的参考样本。
1. 二十五天、五个技术段:这份实习记录到底能替你省多少事
毕业前那张实习记录表,卡人的从来不是没东西写,而是不知道写到什么颗粒度才算合格。这份《软件工程实习记录》给的是一个五周、二十五天的逐日样本:从 Eclipse 里拖 Swing 控件做文件查找,到 Node.js 接 MySQL 做增删改查,中间夹着 IIS 站点权限、Tomcat 端口冲突、JSP 中文乱码几个必现故障,最后把项目丢进 Tomcat 跑起来。它不是教程,是一份带日期的施工日志,能直接拿来做大学实习记录的改写底稿。适合正在凑毕业实习材料、又不想写成流水账的人,也适合刚碰 Java Web、想看清一条从桌面端到 Web 部署的推进顺序的新手。真正值得抄的不是文字,是它每一步都在解决一个具体问题。
2. 五周技术主线拆解:从 Swing 面板到 Tomcat 部署的顺序为什么不能颠倒
把二十五天摊开看,它其实压了五条技术线:桌面 GUI、网页静态渲染、Node 服务端与数据库、Java Web 框架、部署与运维。顺序不是随便排的,每往上一段,都要吃掉上一段暴露出来的问题。你要是把顺序打乱,比如先上框架再写增删改查,会发现配置全会写,但说不清一个请求到底经过了哪几层,面试官追问两句就露底。这一章把五段线的衔接理由讲透,后面第 3 章再落到能跑的代码。
2.1 桌面端起步:视图和主程序拆两个包,不是多此一举
记录里 8 月 28 日到 30 日三天做的是同一件事的两半:先按文件名模糊查找,再把查到的结果按文件名排序。包名写的是com.shixi.viwe和com.shixi.main,注意第一个是拼错的 view,照抄的时候要么统一改对,要么全篇保持一致,别一半 viwe 一半 view,这是最容易被一眼看出的复制痕迹。
目录结构长这样:
shixi-search/ ├── src/ │ ├── com/shixi/viwe/SearchPanel.java # 只负责组件摆放与事件绑定 │ └── com/shixi/main/Main.java # 负责遍历磁盘、比较、排序、回填 └── out/ # 编译输出为什么非要拆?因为遍历磁盘是阻塞操作。文件名查找要递归整个目录树,几万个文件下去,如果直接写在按钮的actionPerformed里,Swing 的事件分发线程被占住,界面会假死到遍历结束,用户以为程序崩了。常见做法是把遍历放进SwingWorker的doInBackground(),中间用publish/process回填进度,这块在原文里没写,但这是把这段代码拿去交作业时最容易被追问的一点。
视图层要做的只有三件事:用JTextField收根目录和关键字,用JTextArea包一层JScrollPane显示结果,用JButton绑一个监听器。主程序负责构造JFrame、setDefaultCloseOperation、pack()、setVisible(true)。这种拆法带来的实际收益是:后面老板说排序规则要从文件名换成文件大小,你只改主程序那一个方法,界面一行都不用动。
选择先做桌面端还有一个训练目的:它把「输入—处理—输出」这条最短链路摆在你面前,没有 HTTP、没有序列化、没有容器,出问题只有两种可能——要么文件没找到,要么排序写错了。等后面切到 Web,链路一长,你就知道该从哪一段开始怀疑。
2.2 从静态数组到数据库:一次请求里数据到底走了几层
8 月 31 日到 9 月 7 日这六天,是整份记录里信息密度最高的一段。起点很朴素:HTML 的<table>把教师信息写死在数组里渲染出来;然后加三个<input>收编号、姓名、课程名,点添加就往页面上塞一行。这里原文提到一个真问题——反复点击会把数据重复渲染到页面上。原因很简单,JS 每次都往tbody里appendChild,从不清理旧节点。
// 错误写法:每次添加都往后追加,点三次出现三份 tbody.appendChild(tr); // 正确写法:先清空再用当前数据整体重绘 tbody.innerHTML = ''; data.forEach(item => tbody.appendChild(buildRow(item)));这个「先清空再重绘」的模式看着笨,但它是后面所有数据驱动界面的雏形。等你换成 Express 返回的 JSON,渲染逻辑一个字都不用改,只把data的来源从内存数组换成fetch的结果。
再往上就是 Node 那一段。9 月 4 日装 Node、npm init起项目,9 月 5 日用 Express 打通 GET/POST,9 月 6 日装 MySQL 并把 Excel 数据导进去,9 月 7 日用mysql驱动读数据、JSON.stringify转格式、再做增删改查。整条链路的完整形态是:
| 层 | 职责 | 断了的表现 |
|---|---|---|
| 浏览器 | 渲染表格、绑按钮事件 | 页面白屏、按钮无反应 |
| HTTP 请求 | fetch 发 GET/POST/DELETE | Network 面板显示 404 或 CORS |
| Express 路由 | 匹配路径、解析 body | 返回 500,日志有堆栈 |
| 连接池 | 复用数据库连接 | 首次查询超时、并发后卡死 |
| SQL 执行 | 增删改查 | 返回空数组或字段名不对 |
这张表的价值在于排错顺序:页面没反应时,先开浏览器 Network 看请求发出去没有,再看服务端控制台有没有进路由,最后才怀疑 SQL。新手最容易犯的错是一上来就改数据库连接串,改了半天发现是fetch的路径少写了个/api。
还有个小坑藏在 9 月 5 日那句「用数组静态存储学生信息」里。原文先拿数组顶着,后面才换数据库,这个替换在代码上只改一个函数,但暴露的问题很典型:数组版没有主键冲突、没有字符集、没有连接超时,一旦换成真库,这三样会同时找上门。所以记录里把「静态」到「动态」这一步单独占一天,是有道理的。
2.3 JSP 与三层框架:这段为什么不能从记录里删掉
9 月 10 日到 9 月 13 日穿插了 Linux 环境熟悉、网络服务器角色、IIS 站点权限、Tomcat 500 错误排查。9 月 14 日到 18 日转向框架:Struts 管表示层、Spring 管业务逻辑层、Hibernate 管持久层。很多人写实习记录时会把框架这段删掉,觉得「没写过项目,写框架太虚」。删了反而可惜,因为它是唯一一段能体现你理解分层的地方。
原文对三者的定位是准确的,可以照着这个骨架展开:
| 框架 | 位置 | 解决的问题 | 记录里能写的具体动作 |
|---|---|---|---|
| Struts | 表示层 | 把请求分发给对应 Action,统一跳转 | 配struts.xml的 action 映射 |
| Spring | 业务层 | IOC 管对象生命周期,AOP 管事务 | 声明式事务配在 service 方法上 |
| Hibernate | 持久层 | 对象与表映射,不手写 SQL | 配hbm.xml或注解映射实体 |
这里有个关键概念别写混:Spring 的 IOC 是控制反转,也叫依赖注入,对象不由你自己new,交给容器创建后注入进来;AOP 是面向切面,把日志、事务这类横切逻辑从业务代码里抽出来。记录里 9 月 17 日那天的表述基本对,但「ICO」是笔误,应该是 IOC,交之前务必改掉——这种错别字在答辩时特别扎眼。
JSP 那段(9 月 18 日)讲的是服务端渲染:页面里嵌 Java 代码片段和标签,浏览器不支持 Java 也能看到结果,因为渲染发生在服务端。和现在前后端分离的路子比,JSP 的优点是首屏快、不用写接口,缺点是前后端耦合、改个按钮颜色都得重启容器。这个对比写进记录里,比单纯抄一句「JSP 是动态技术标准」有价值得多。
五段线连起来看就清楚了:桌面端教你输入处理输出,静态页教你 DOM 操作,Node 那段教你 HTTP 与数据库,框架那段教你分层,部署那段教你环境。每一段都是下一段的前置知识,顺序颠倒就会有一段听不懂。
3. 四个可复现的最小实现:把记录里的功能点跑成能看的程序
光有日志没有代码,这份记录就只能当作文看。这一章把原文里最值得动手的四个点抽出来,每个都给到能直接跑的最小版本,并且说清楚参数改哪里、失败了看什么。
3.1 文件查找与排序:递归、模糊匹配和冒泡的三个边界
先看视图层,重点在布局和事件绑定的写法:
package com.shixi.viwe; import javax.swing.*; import java.awt.*; import java.io.File; import java.util.ArrayList; import java.util.List; public class SearchPanel extends JPanel { private final JTextField pathField = new JTextField("D:/test", 18); private final JTextField keywordField = new JTextField(12); private final JTextArea resultArea = new JTextArea(12, 40); public SearchPanel() { setLayout(new BorderLayout(8, 8)); JPanel top = new JPanel(new FlowLayout(FlowLayout.LEFT)); top.add(new JLabel("根目录:")); top.add(pathField); top.add(new JLabel("关键字:")); top.add(keywordField); JButton searchBtn = new JButton("查找"); top.add(searchBtn); add(top, BorderLayout.NORTH); add(new JScrollPane(resultArea), BorderLayout.CENTER); // 事件里只做调度,耗时遍历丢给后台线程 searchBtn.addActionListener(e -> new Thread(this::doSearch).start()); } private void doSearch() { resultArea.setText(""); List<File> hits = new ArrayList<>(); collect(new File(pathField.getText().trim()), keywordField.getText().trim().toLowerCase(), hits); sortByName(hits); for (File f : hits) { resultArea.append(f.getAbsolutePath() + "\n"); } } // 递归收集:目录继续下钻,文件才做匹配 private void collect(File dir, String kw, List<File> hits) { File[] files = dir.listFiles(); if (files == null) return; // 目录不存在或无权限,直接返回 for (File f : files) { if (f.isDirectory()) { collect(f, kw, hits); } else if (f.getName().toLowerCase().contains(kw)) { hits.add(f); // 模糊匹配就是 contains,不是 equals } } } // 冒泡:按文件名升序,忽略大小写 private void sortByName(List<File> hits) { for (int i = 0; i < hits.size() - 1; i++) { for (int j = 0; j < hits.size() - 1 - i; j++) { if (hits.get(j).getName().compareToIgnoreCase( hits.get(j + 1).getName()) > 0) { File tmp = hits.get(j); hits.set(j, hits.get(j + 1)); hits.set(j + 1, tmp); } } } } }主程序只负责装载:
package com.shixi.main; import com.shixi.viwe.SearchPanel; import javax.swing.*; public class Main { public static void main(String[] args) { SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame("文件查找"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(new SearchPanel()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); }); } }几个参数得说清楚。pathField默认值给绝对路径,相对路径在不同启动目录下指向不同位置,这是新手最常见的「找不到文件」原因。listFiles()有两种情况返回null:传进来的不是目录,或者当前用户对这个目录没有读权限,所以递归前必须先判空,否则第一次跑就抛空指针。模糊匹配用contains,但两边都做了toLowerCase,否则搜「Report」搜不到report.txt,这个大小写问题在 Windows 上不明显,换到 Linux 上会立刻暴露。
冒泡排序这里要说句实话:它是 O(n²),几百条结果没问题,上万条会明显卡顿。原文选冒泡是教学目的,真要用就把sortByName换成hits.sort(Comparator.comparing(File::getName, String.CASE_INSENSITIVE_ORDER)),一行搞定,性能是 O(n log n)。记录里把这个替换写进去,比只写「采用冒泡排序」显得懂行。
还有一个原文没提但一定会遇到的边界:符号链接和快捷方式会导致递归绕圈,Windows 下的 junction 目录尤其明显。稳妥做法是维护一个已访问路径集合,或者限制递归深度,比如超过 8 层就不再下钻。
3.2 Node + Express + MySQL:一套增删改查的最小骨架
先起项目,三条命令:
mkdir teacher-page && cd teacher-page npm init -y npm install express mysql2用mysql2而不是老的mysql包,因为它原生支持 Promise,写await不用回调套回调。建表语句一起给上:
CREATE DATABASE IF NOT EXISTS teacher_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE teacher_db; CREATE TABLE IF NOT EXISTS teacher ( id VARCHAR(20) PRIMARY KEY, -- 编号做主键,重复插入直接报错 name VARCHAR(50) NOT NULL, course VARCHAR(80) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;服务端骨架:
// server.js const express = require('express'); const mysql = require('mysql2/promise'); const app = express(); app.use(express.json()); // 解析 POST 的 JSON body app.use(express.static('public')); // 静态页放 public 目录,直接访问 const pool = mysql.createPool({ host: '127.0.0.1', port: 3306, user: 'root', password: '改成你自己的密码', database: 'teacher_db', charset: 'utf8mb4', // 关键:和建表字符集保持一致 connectionLimit: 10 // 连接池上限,本地开发 10 足够 }); // 查 app.get('/api/teachers', async (req, res) => { const [rows] = await pool.query( 'SELECT id, name, course FROM teacher ORDER BY id'); res.json(rows); // 直接返回数组,前端好渲染 }); // 增 app.post('/api/teachers', async (req, res) => { const { id, name, course } = req.body; try { await pool.query( 'INSERT INTO teacher (id, name, course) VALUES (?, ?, ?)', [id, name, course]); // 占位符防注入,别拼字符串 res.json({ ok: true }); } catch (err) { res.status(400).json({ ok: false, msg: err.code }); // 主键冲突走这里 } }); // 改 app.put('/api/teachers/:id', async (req, res) => { const { name, course } = req.body; await pool.query( 'UPDATE teacher SET name = ?, course = ? WHERE id = ?', [name, course, req.params.id]); res.json({ ok: true }); }); // 删 app.delete('/api/teachers/:id', async (req, res) => { await pool.query('DELETE FROM teacher WHERE id = ?', [req.params.id]); res.json({ ok: true }); }); app.listen(3000, () => console.log('http://127.0.0.1:3000'));前端渲染那段,核心就一句tbody.innerHTML = '',前面已经讲过。这里补一个原文踩到的坑:添加信息重复显示。除了不清理节点,还有一个更隐蔽的原因——表单提交后页面刷新,如果提交走的是<form>的默认行为而不是fetch,浏览器会把上一次的渲染结果和刷新后的结果同时呈现,看起来像重复。正确的做法是给按钮绑click,处理函数里第一行e.preventDefault()。
参数层面要记住三个:connectionLimit控制并发连接数,本地开发设 10、上线按数据库最大连接数的七成来配;charset必须和建表时一致,否则中文进去是问号;port改成 89 之类的非标准端口时,前端fetch的地址也要跟着改,这一点会在第 5 章展开。
3.3 中文乱码与端口占用:两条必现故障的定位链
这两个问题在原文里各占一天(9 月 21 日和 9 月 28 日),几乎是照着实操就会撞上的。先把中文乱码的排查顺序列出来,它是三处编码必须同时对齐,只改一处等于没改:
| 位置 | 要设成什么 | 改哪里 |
|---|---|---|
| 数据库与表 | utf8mb4 | 建库建表语句,或ALTER TABLE ... CONVERT TO |
| 连接串 | charset=utf8mb4 | createPool/ JDBC URL |
| 页面 | pageEncoding与contentType | JSP 头部两行 |
| 响应头 | Content-Type: application/json; charset=utf-8 | res.json一般自带,手写res.send要补 |
原文里把数据库和页面都改成 GBK 也解决了问题,这属于「两处一致就行」的土办法,能跑但不推荐——GBK 存不下 emoji,一旦有特殊字符就炸。新项目一律 utf8mb4,代价只是存储空间多一点点。
端口占用更好定位,Windows 下先查再杀:
# 查谁占了 8080 netstat -ano | findstr :8080 # 最后一列是 PID,比如 12345,直接结束 taskkill /PID 12345 /FLinux 下换成ss -lntp | grep 8080或lsof -i:8080。原文的处理方式是换端口,把 Tomcat 的Connector port从 8080 改成 89 并重启。这个办法能救急,但要提醒一句:89 属于低位端口,某些系统上非管理员账号绑不上,正常做法是换到 8081、8090 这类高位端口,同时记得同步改前端请求地址和 Nginx 反代配置,否则会从「端口冲突」变成「页面 404」,排查成本翻倍。
Tomcat 那个 500 错误也值得单说。原文最后定位到是 jar 包和数据库版本不匹配,这个结论对,但过程可以更省时间:500 出现后第一件事是看logs/catalina.out或localhost.log,堆栈第一行往往就写明了类找不到还是驱动不兼容。JDBC 驱动版本和数据库大版本必须对上,比如 SQL Server 2000 那代要用老版驱动,拿新驱动去连就会在建立连接时直接抛异常,而不是等到执行 SQL 才报错。
4. 从日记到交付物:二十五条记录怎么改才不像流水账
技术点跑通了,接下来是文字。原文的日记体优点是细节多,缺点是每天都以「今天来到公司」开头,二十五天读下来像复读机。改写的核心思路是:保留每天的具体动作,砍掉重复的开场白,把「我知道了什么」换成「我改了什么、结果从 A 变成 B」。
4.1 六步流程落到周维度:每周必须出现的三类句子
原文第一天就把软件开发的六个阶段列全了:可行性分析、需求分析、概要设计、详细设计、编码、项目验收。但后面二十五天里,这六个词再没出现过。这是实习记录最常见的断裂——开头抄一段标准流程,后面全是干活,评审老师一看就知道流程那段是贴上去的。
改法是让流程词在每周的记录里各落一次,落到具体动作上:
| 周次 | 技术主线 | 记录里该出现的流程词 | 可验证的产物 |
|---|---|---|---|
| 第一周 | 桌面查找与排序、静态单页 | 需求分析(明确查找/排序规则)、详细设计(包结构划分) | 两个包、一个可运行面板 |
| 第二周 | Node 搭服务、MySQL 建表、增删改查 | 概要设计(接口清单)、编码 | 四个接口、一张表 |
| 第三周 | Linux 环境、IIS、Tomcat 500 | 环境验证、缺陷修复 | 日志片段、端口配置 |
| 第四周 | 三层框架、JSP 回显、项目建模 | 详细设计(分层)、模型评审 | 分层目录、实体映射 |
| 第五周 | 商城增删改查、乱码、部署上线 | 编码、项目验收 | 可访问的首页地址 |
这张表还有个用法:写的时候倒过来,先定每周的产物,再补那一周的经过。产物是硬的,经过是软的,先硬后软就不会通篇空话。「我在struts.xml里配了三个 action 映射」比「我学习了 Struts 框架」强十倍。
另外原文第一周那句判断值得保留并强化:代码实现只占整个开发过程的百分之十五。这个比例不一定精确,但它是一个有观点的句子,比平铺直叙的记录更让人记住。改写时可以说清楚这百分之十五之外的时间花在哪——环境搭建、数据准备、联调、改 bug,正好对应第三周和第五周的内容,前后就呼应上了。
4.2 岗位与技术栈:别写成招聘网站的 JD
原文 8 月 29 日列了 IT 行业的主要职位:软件开发员、项目经理、技术总监、架构师、总经理、售前售后。这段如果照抄招聘网站的职责描述,就成了废话。正确写法是每个职位配一个你当天看见的动作:
| 职位 | 职责一句话 | 记录里能落到哪个场景 |
|---|---|---|
| 软件开发员 | 按设计文档实现功能模块 | 你写查找面板、写增删改查的那几天 |
| 项目经理 | 拆任务、排期、控进度 | 分组那天,谁做什么功能谁定 |
| 架构师 | 定分层、定技术选型 | 决定用 Express 还是 JSP 的那一刻 |
| 技术总监 | 跨项目协调、把技术方向 | 不太可能接触到,写「了解到」即可 |
| 售前售后 | 需求对接、上线后支持 | 需求分析阶段客户提的修改意见 |
技术栈那段同理。原文摘要里列了前端 HTML/CSS/JS、后端 Java/Python、数据库 MySQL/Oracle/SQL Server,这属于教科书式罗列。落到记录里应该收敛成一句:这次用到的是 HTML + CSS + JS 做页面,Node/Express 做接口,MySQL 存数据,Java Web 那条线另外走了 JSP + 三层框架。用了什么就写什么,没用过的别列,否则被问到「Oracle 你建过几个表空间」就答不上来。
4.3 措辞自检:这四类句子必须替换成自己的细节
改完之后通读一遍,凡是符合下面特征的句子,一律换掉:
第一类是「通过今天的实习我了解到……」开头的总结句。换成「今天在 X 文件的第 N 行把 A 改成了 B,页面从空白变成有数据」。第二类是「这对我以后的就业有很大的帮助」。这类展望句在实习记录里出现一次是礼貌,出现三次就是凑字数,直接删。第三类是「遇到了很多问题,同事都很耐心地帮我解决」。问题是什么、怎么解决的,一句没写,等于没发生。第四类是纯概念复述,比如「JSP 是由某机构倡导、许多公司参与建立的一种动态技术标准」,这种句子百度一搜一大把,改成「JSP 把 Java 代码嵌进 HTML,在服务端渲染完再发给浏览器,所以浏览器不装 Java 也能看」。
还有一个格式层面的细节:原文日期是「2018 年 8 月 27 日」这种中文写法,二十五条全部统一,没问题;但如果你的模板要求2018-08-27,就全篇统一成短横线格式,别混着来。周次标题「第一周」「第二周」也要和模板的层级对上,有的模板要求周次作为一级标题、日期作为二级,提前看清楚再动笔。
5. 避坑:复现这份记录时最容易翻车的五个地方
这一章全是血泪经验。原文里有几处当时解决了、但没写清原因的地方,照着做大概率会再撞一次。
5.1 环境与依赖类
现象一:MySQL 装到一半失败,服务起不来。原因在原文 9 月 20 日已经点破——安装时没选「开发者」选项。安装向导里的几个预设配置决定了端口、字符集、服务名和初始账号,选错预设后面要改一堆配置文件。解决办法是卸载重装,安装类型选 Developer Default,端口保持 3306,字符集选 utf8mb4,装完立刻用命令行连一次确认服务在跑。别在装失败的状态下硬改配置文件,那是给自己挖坑。
现象二:中文能存进去,但查出来是问号。原因是有三处编码没对齐,只改了其中一处。最常见的是建库时用了默认的 latin1,连接串写了 utf8,页面又是 GBK。解决办法按第 3.3 节那张表逐项核对,改完表字符集后记得把已有数据重新导一次,ALTER TABLE只影响新写入的行,老数据不会自动转码。这一步没做,你会以为改了没用。
现象三:Tomcat 启动报端口被占用,换成 89 之后前端 404。原因是端口改了,但前端请求地址、反向代理配置、防火墙规则三处没同步。解决办法是换端口时列一张清单:server.xml的 Connector、前端 fetch 的 baseURL、Nginx 的proxy_pass、以及任何写死地址的配置文件,四处一起改。我一般的习惯是先在netstat里确认新端口没被占,再动配置,改完立刻curl一次验证,别等整套跑起来才发现。
现象四:JDBC 连接报错,堆栈指向驱动类找不到。原文 9 月 13 日那个 500 错误就是这个。原因是驱动 jar 的版本和数据库大版本对不上,或者 jar 根本没放进WEB-INF/lib。解决办法是先看堆栈第一行的异常类型:ClassNotFoundException是 jar 没进类路径,SQLException带版本信息的是驱动不匹配。前者检查 lib 目录和构建路径,后者换对应版本的驱动,别去改连接串浪费时间。
5.2 内容交付类
现象五:记录交上去被退回,理由是「像模板」。原因不是你写得不好,是二十五天里有二十天用了同一个开头。评审看三页就疲劳了。解决办法很简单:把每天的记录按「今天要解决什么 → 卡在哪 → 怎么绕过去 → 结果」四段来写,开头那句「今天来到公司」直接删掉,从任务写起。同一件事换个角度描述,比如 8 月 28 日和 8 月 30 日都是新建com.shixi.viwe包、都是拖 Swing 组件,那就把第二天写成「在上次的面板上加了排序按钮和排序逻辑」,体现延续性而不是复制粘贴。
还有一条不属于技术但很容易踩:记录里别写具体公司名、具体人名、具体项目名。原文里出现的经理姓氏、商城项目名,交付前统一替换成「带队经理」「某商城项目」这类代称。这不只是合规问题,也是保护自己——材料一旦流传出去,具体信息越少越安全。
6. 进阶自检:给每个技术点配一条能验证的证据
改写完成后,我建议再做一件事:给记录里出现的每个技术点配一条可验证的证据。这不是为了交材料,是为了答辩时被追问能立刻拿出来。做法是建一张三列的表——技术点、验证方式、我当时看到的输出。
| 技术点 | 验证方式 | 期望输出 |
|---|---|---|
| Swing 查找 | 在 D:/test 放三个含关键字的文件,点查找 | 三行绝对路径,按文件名升序 |
| Express 接口 | curl http://127.0.0.1:3000/api/teachers | JSON 数组,中文正常显示 |
| MySQL 字符集 | SHOW VARIABLES LIKE 'character_set_%' | 关键项均为 utf8mb4 |
| Tomcat 部署 | 浏览器访问http://127.0.0.1:8081/项目名/index.jsp | 页面正常,无 404/500 |
| 端口占用 | netstat -ano | findstr :8081 | 只有 Tomcat 一个 PID |
这张表还有个副作用:它会逼你把没跑通的部分删掉。凡是拿不出输出的技术点,要么补跑一遍,要么从记录里降级成「了解到」而不是「实现了」。我见过太多材料写了「完成增删改查」,一问连接池怎么配的、字符集设的什么,全答不上来。
更进一步,把每天的记录对应到一段能复现的操作上。比如 9 月 26 日解决了中文乱码,那就在记录旁边附上改之前和改之后的两次查询结果截图或者命令行输出。文字可以润色,输出骗不了人。这也是我判断一份实习记录能不能用的标准:随便挑一天,能不能在半小时内把那天的事重新做一遍。能,就是真的;不能,就还得改。
说个我自己的教训。早年帮人改这类材料,我总想着把文字打磨漂亮,结果对方拿去答辩,被问了三个环境配置问题就卡住了,回来找我,我们花了一整晚把 MySQL 字符集、Tomcat 端口、Node 版本三件事重新跑了一遍,材料反而改得更朴素,但每一句都站得住。从那以后我每次改完记录,都强制走一遍这张证据表,跑不通的句子一律删掉,宁可少写三天,也不留一句没法验证的话。希望帮到你。
本文还有配套的精品资源,点击获取