欢迎来到我的博客 记录学习,分享生活

软工作业1:Hello Software Engineering

软件工程课程第一次个人作业,我喜欢编程

这个作业属于哪个课程 H202601 软件工程与软件工程实践
这个作业要求在哪里 第一次个人作业
这个作业的目标 完成课程作业的提前准备,创建博客园,使用 Hugging Face 体验大模型 API 与前端交互开发,了解 GitHub 并通过 GitHub Pages 建设个人技术主页,同时通过自我评估明确本学期的学习方向
学号 102401533

一、About Me

1.1 自我介绍

92b89b71a0aa5a18a40fd09273d4e63c

哈啊,读者好!这是我在博客园发布的第一篇文章,也是我在博客园的第一次作业。我是福州大学计算机与大数据学院计算机科学与技术专业 2024 级本科生,我的名字是丁晓炜,目前主要关注 Python、数据分析、系统结构、大模型的预训练和微调等领域,本人目前大三,喜欢健身、攀岩、台球等休闲运动,喜欢学习看起来比较酷炫的东西,也喜欢玩恐怖游戏像恐鬼症、七日杀、或者是逃生,也喜欢打打cs(不是computer science),目前在专业中的成绩是3/243,主要是以保研为目标,对计算机也比较有兴趣,希望和老师或是助教成为良师益友,这篇文章也希望能被读完:),个人介绍详情见https://ddxww.github.io

133e81f4fd65446b498cf02b39411528

1.2 当前技能树与自我评估

已具备的知识与能力

  1. 编程与数据处理

    能够使用 Python 完成基础程序设计,并使用 NumPy、Pandas 等工具进行数据处理。我完成过线性规划、回归、聚类、主成分分析、时间序列、图论和启发式算法等练习(虽然大部分都忘记了),对c语言和c++也有一定的了解,算法与数据结构也有保持偶尔练习的习惯,对例如队列、栈、堆、二叉树等结构还是有点记忆或者是贪心算法或者是动态规划的简单题目,能敲出来,偶尔去cf或者是力扣、洛谷上刷刷题,但是对开发还是不太熟悉的,有机会也学习一下。

  2. 机器学习与深度学习基础

    学习完过尚硅谷的数据分析、机器学习、深度学习、nlp的课程等(讲的还是不错的),学习过线性回归、逻辑回归、KNN、朴素贝叶斯、决策树、随机森林和神经网络等内容,能够理解训练、预测和评价的基本流程;接触过 CNN、RNN、LSTM、GRU、Seq2Seq、Attention 和 Transformer 等模型,完成过文本预处理、评论分析、输入法语言模型和机器翻译等练习,还做过十分经典的手写数字识别,对解码器、编码器、分词、词表示、序列模型和注意力机制有初步认识,尝试过调用HF早期模型bert或者是T5来进行自然语言处理的实战,虽然只是调用过进行过文本处理的模型,但是有时间的话还是会试试别的....

  3. GitHub 与技术写作基础

    能够使用 GitHub 管理代码、搭建GitHub Pages,并使用Markdown编写技术记录,对仓库、提交和分支等概念已有基本认识(虽然大部分都是ai做的,额度在燃烧,还用ai做过坦克大战ᕙ(`▽´)ᕗ详情可以去我的GitHub上找找,虽然好多bug),但是对GitHub的指令并不是很了解,大部分也都是用AI帮忙的。

技术偏好与兴趣方向

目前我更感兴趣的是人工智能应用开发,尤其是生成式 AI、自然语言处理,以及模型 API 与 Web 系统的结合。我希望学习的不只是模型本身,也包括如何设计接口、组织前后端代码、保护密钥、处理错误,并把原型逐渐完善为可靠的软件,对底层的实现也是很感兴趣的,反正对挺多都感兴趣吧。

仍然欠缺的能力

  1. 软件工程方法不够系统:对需求分析、UML、架构设计、测试、持续集成和项目管理的实践较少。
  2. 代码质量意识需要加强:部分练习以“运行成功”为目标,在模块划分、命名、异常处理、复用性和测试覆盖方面仍有提升空间。
  3. 计算机基础需要继续巩固:数据结构与算法、操作系统、计算机网络和数据库知识还没有形成完整体系(菜就多练这一块)。
  4. 团队协作经验不足:对规范化分支管理、代码评审、Issue 管理和多人协作中的冲突处理缺少真实项目经验。
  5. 部署与运维能力较弱:对 Linux、容器、自动化部署、日志监控和性能分析仍处于入门阶段。

这份自评提醒我,掌握某个库的调用方法并不等于具备完整的软件开发能力。本学期,我需要把关注点从“能写出功能”进一步转向“能以规范、可维护、可协作的方式完成软件”,慢慢进步,每天进步一点点。

1.3 代码量与本学期目标

我对当前较能代表个人练习的代码进行了统计。排除 node_modules、第三方主题、字体和图片等内容后,Python 学习脚本与本次 FLUX Web 项目合计约 一两万行有效代码吧,说实话我对此也并不是很了解,没有具体算过,而且这个数字只能反映练习规模,不能直接代表代码质量;重复代码、实验性代码与完整项目代码的价值也不相同。完成本学期课程后,我希望个人有效代码量达到 3万行左右。比行数更重要的是,新增代码应尽量来自完整项目和持续迭代,并具备清晰的结构、版本记录、必要的测试和文档,而不是单纯追求数字增长。

1.4 未来三年规划

我希望在未来的三年,我能学到更多的东西,对于接下来的一年目标还是比较明确的,但是对于剩下的两年的目标我也只有个大概,首先是这一年内,我要学习完STM32单片机(特意买了一个51单片机来学习),成为一名合格的单片机大蛇,逐步学习硬件知识,系统架构,顺便也学一下当下比较热门的agent,熟练掌握torch库或者是相关库,然后平常练练代码巴拉巴拉,学习算法数据结构什么的,还有一堆东西感觉没学,当然还有锻炼吧,自从暑假攀岩后感觉攀岩有点上瘾了啊( ⁰▿⁰).....然后剩下的两年就走一步看一步吧,因为两年还是比较遥远的,但是我相信在这剩余的两年内,我应该也是会偶尔学习一下代码技巧,或者是先进领域的知识,或者是补补某些技能需要的数学原理什么什么的,并且也要多多参与团队协作,毕竟人多力量大,还是要多多团队协作。

二、Hugging Face API 调用与前端实现

2.1 实现目标

我选择调用 Hugging Face 上的 XLabs-AI/flux-RealismLora 模型,完成一个写实图像生成网页。用户可以在页面中输入提示词,点击“生成图像”后,由前端请求本地 Express 服务,再由服务端携带 Hugging Face Token 调用模型。生成成功后,图片会直接显示在网页中(之前用过几次,所以只能生成一张图片了TAT)。

整个调用流程如下:

用户输入提示词
    -> 浏览器发送 POST /api/generate
    -> Express 服务端校验提示词
    -> Hugging Face Inference API 调用 FLUX 模型
    -> 服务端返回图片二进制数据
    -> 前端创建图片 URL 并展示结果

为了避免泄露密钥,我没有把 Hugging Face Token 写进前端代码,而是将它保存在服务端的 .env 文件中,通过 process.env.HF_TOKEN 读取。这样浏览器只能访问本地接口,无法直接看到 API Token。

2.2 核心代码

服务端使用 Express 提供 /api/generate 接口,并通过 @huggingface/inference 调用模型。为了保护密钥,程序从环境变量中读取 HF_TOKEN;收到图片后,再以二进制形式返回给浏览器。主要代码如下:

const express = require("express");
const { InferenceClient } = require("@huggingface/inference");
require("dotenv").config();

const app = express();
app.use(express.json());

if (!process.env.HF_TOKEN) {
  throw new Error("没有读取到 HF_TOKEN,请检查 .env 文件");
}

const client = new InferenceClient(process.env.HF_TOKEN);

app.post("/api/generate", async (req, res) => {
  const prompt = String(req.body.prompt || "").trim();
  if (!prompt) {
    return res.status(400).json({ error: "提示词不能为空" });
  }

  const startTime = Date.now();

  try {
    const image = await client.textToImage({
      model: "XLabs-AI/flux-RealismLora",
      inputs: prompt,
      parameters: {
        negative_prompt:
          "cartoon, anime, illustration, blurry, low quality, distorted",
        width: 1024,
        height: 1024,
        num_inference_steps: 28,
        guidance_scale: 3.5,
      },
    });

    const buffer = Buffer.from(await image.arrayBuffer());
    const duration = Date.now() - startTime;

    console.log(`API调用成功,状态:200,耗时:${duration}ms`);
    res.setHeader("Content-Type", image.type || "image/png");
    res.setHeader("X-Generation-Time", String(duration));
    res.send(buffer);
  } catch (error) {
    res.status(500).json({
      error: "图像生成失败",
      detail: error.message,
    });
  }
});

前端监听表单提交事件,通过 fetch 将提示词发送给服务端。在等待过程中禁用按钮并显示状态;成功后把响应转换为 Blob,创建临时 URL 并显示图片;失败时则向用户展示错误原因。主要交互代码如下:

const form = document.querySelector("#generate-form");
const promptInput = document.querySelector("#prompt");
const button = document.querySelector("#generate-button");
const statusText = document.querySelector("#status");
const resultImage = document.querySelector("#result");

let imageUrl;

form.addEventListener("submit", async (event) => {
  event.preventDefault();
  button.disabled = true;
  statusText.textContent = "正在生成图片,请稍候……";

  try {
    const response = await fetch("/api/generate", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ prompt: promptInput.value }),
    });

    if (!response.ok) {
      const data = await response.json();
      throw new Error(data.detail || data.error);
    }

    const blob = await response.blob();
    if (imageUrl) URL.revokeObjectURL(imageUrl);

    imageUrl = URL.createObjectURL(blob);
    resultImage.src = imageUrl;
    resultImage.hidden = false;

    const duration = response.headers.get("X-Generation-Time");
    statusText.textContent = `生成成功,耗时 ${duration} 毫秒`;
  } catch (error) {
    statusText.textContent = `生成失败:${error.message}`;
  } finally {
    button.disabled = false;
  }
});

2.3 提示词设计与修改过程

最终使用的提示词为:

realism, a candid documentary photograph of a small Chinese neighborhood
breakfast shop at 7:00 AM, an elderly shop owner naturally preparing steaming
baozi behind a slightly worn stainless-steel counter, several local customers
waiting in the background, soft morning sunlight entering from the left side,
realistic skin texture, natural facial expressions, subtle steam in the air,
authentic Chinese signs and everyday objects, slightly imperfect real-world
environment, shot at eye level with a 35mm full-frame camera, 50mm lens, f/2.8,
natural depth of field, balanced exposure, neutral colors, fine photographic
grain, highly detailed, photorealistic, unedited news photography

我的设计思路是把“写实”拆成多个可以被模型理解的具体条件,而不只写一个抽象的 photorealistic

设计维度 具体设计 设计目的
主体与场景 选择清晨的社区早餐店、店主制作包子这一日常场景 减少画面的摆拍感
环境细节 加入略有磨损的不锈钢柜台、蒸汽、中文招牌和等候的顾客 让画面更接近真实生活
光线与镜头 指定左侧自然晨光、平视角度、全画幅相机、50mm 镜头和 f/2.8 控制画面的透视和景深
质感约束 要求自然肤质、自然表情、中性色彩和轻微颗粒感 避免过度磨皮或广告摄影效果
负面提示词 排除卡通、动漫、模糊、低质量和畸变等内容 减少不符合写实目标的生成结果

修改过程中,我逐步从“一个真实的早餐店”扩充到“主体 + 环境 + 光线 + 镜头 + 质感”的结构。相比宽泛的初版,最终提示词对时间、人物动作、构图和摄影参数都有约束,生成结果也更稳定、更贴近纪实照片。从最终图片来看,晨光、蒸汽、旧式店面和人物肤质的写实效果比较明显,说明环境与摄影语言起到了作用。不过,画面中的中文招牌出现了不自然的文字,人物站位略显刻意,桌面上的食物也更接近面饼而不是包子。如果继续修改提示词,我会减少对具体中文文字的要求,改为 signboards without readable text;同时加入 customers naturally eating or orderingclearly shaped round steamed baozi in bamboo steamers,进一步约束人物动作与食物形态。

2.4 调用结果

首次调用 API 成功,接口返回状态为 200,图像生成耗时约 9725 ms。前端能够在等待期间禁用按钮并显示生成状态,成功后自动展示图片。生成结果呈现了清晨早餐店的光线、蒸汽、人物和环境细节,整体写实感较强,与提示词设定基本一致。

终端中“API 调用成功,状态:200,耗时:9725ms”的记录:

联想截图_20260906230630

FLUX 模型成功生成的写实早餐店图片:

image

后来再次测试接口时,Hugging Face 返回了 You have depleted your monthly included credits,说明账号当月包含的推理额度已经用完。此时前端正确显示了服务端返回的失败原因,同时保留了上一次成功生成的图片。这次情况也让我认识到,使用第三方模型 API 时,除了代码逻辑,还需要考虑额度、限流和异常提示。

前端交互页面及 Hugging Face 额度不足提示:

11122

补充:重新生成一张福州晴天的风景图

不过看完之后还是觉得原图不太好看,尤其是招牌上的中文,看着有点奇怪,所以我新创了一个 Hugging Face 账号,重新生成了一张图片。这次换个方向,不生成人物和店铺了,关键词就定为 “福州、晴天、纯场景、无文字”,试试干净一点的风景图。

提示词最开始只有这几个关键词,但“福州”还是比较宽泛,所以我把场景进一步细化成了以福州西湖公园为灵感的湖景,加入湖面、树木、白墙灰瓦的亭阁、石板步道和远山。然后补充蓝天、自然日光、真实阴影和深景深,让晴天的感觉更明确。考虑到原图的中文效果不太好,这次直接加上无人、无汉字、无字母、无招牌、无标志和无水印的限制。这里是提示词的文字修改过程,最终版实际提交生成了一次。

这次实际使用的提示词:

realism, a photorealistic landscape photograph inspired by West Lake Park
in Fuzhou, Fujian, China, on a clear sunny day, calm lake with gentle ripples
reflecting the blue sky, lush banyan trees along the shore, traditional
Fujian pavilion with white walls and dark gray tiled roofs in the middle
distance, a quiet stone path in the foreground, distant green hills,
natural daylight, realistic shadows, balanced exposure, natural green
and blue colors, eye-level wide-angle composition, deep depth of field,
detailed architectural textures, scenery only, completely empty of people,
no text, no Chinese characters, no letters, no signs, no signboards,
no logos, no watermarks

同时补充了负面提示词:

people, person, crowd, text, letters, Chinese characters, signs, signboards,
logo, watermark, cartoon, anime, illustration, blurry, low quality, distorted

这次调用成功,模型仍然是 XLabs-AI/flux-RealismLora,本地接口返回状态为 200,耗时 11117 ms,大约是 11.12 秒。服务端保存了实际调用时间、提示词、图片类型和大小,下面的记录截图就是读取这次保存的数据展示的。

新图片的 API 调用成功记录:

image

前端页面最终生成图像的截图:

联想截图_20260907201249

这次生成的完整图片:

image

这张看着比原来的舒服一些,蓝天、湖水、倒影和石板路都比较自然,也没有明显的人物和可读文字。不过提示词里写的是榕树,生成出来更像垂柳,建筑也不能说就是福州西湖的真实建筑,所以它只是以福州西湖为灵感生成的风景图,不是实拍。经过这次修改,我觉得把场景和限制说清楚,比单纯堆“真实、高清、好看”这样的词更有用,但最后还是得自己看看结果有没有符合要求。

2.5 体验与心得

这次实践让我第一次把“大模型调用”从一段独立代码扩展为可以交互的网页功能,虽然设计的前端比较简陋,但好在能生成图片。真正实现后,我发现 API 调用只是其中一环:还需要考虑密钥保护、输入校验、异步等待、错误提示、二进制图片返回和前端状态更新,当然AI大人会出手。提示词也不是越长越好。有效的提示词需要围绕目标补充可观察的细节,并让不同描述彼此一致,还有生成图片确实不太会生成中文,但是人物和背景还是蛮不错的,但是中文生成的太烂了<(`^´)>,但是第二个图片的效果还是非常不错的( ´∀`)b!

三、GitHub 个人主页建设

我选择使用 GitHub Pages 建设个人主页,主页地址为 https://ddxww.github.io/。页面用于介绍个人情况、整理学习成果和记录技术实践,这个做了我几天,最初的模板是https://github.com/Huxpro/huxpro.github.io,然后经历了多次修改,以及参考别人的页面,才有了如今的版本。

当前主页主要包含以下内容:

  • 个人介绍与联系方式(我的qq和vx);
  • 学习日志和文章归档;
  • Python学习记录;
  • 项目与实践成果展示。

GitHub 个人主页或仓库页面:

联想截图_20260907181654

GitHub Pages 首页:

联想截图_20260907175520

进入后的个人页面:

联想截图_20260907201737

只能说一名合格的代码大蛇首先要有好看的个人主页,然后才是代码能力(bushi)。

四、对软件工程课程的期待

我最期待学习以下内容:

  • 对专业名词的学习,比如什么瀑布模型等;
  • 如何把模糊需求转化为清晰、可验证的功能需求;
  • 如何进行模块划分、接口设计和系统架构设计;
  • 如何通过单元测试、集成测试和代码评审保证质量;
  • 对团队协作小组任务的期待,以及如何使用 Git 分支、Issue、里程碑等工具开展团队协作(团队协作确实重要);
  • 如何规划迭代、估算任务并控制项目风险;
  • 如何让AI编程工具参与开发,同时验证输出、保护隐私并保持对代码的理解。

我希望本学期结束时,自己不只是能独立写出一个程序,还能解释设计选择,与同学或是在未来的伙伴协作完成一个可运行、可测试、可部署、可维护的软件项目,虽然听说经常会有工作上的矛盾相互甩锅((( ;´ω`;)))。

五、AI 生成的软件工程课程学习指南

5.1 使用的 AI 工具与提问方式

我选择 ChatGPT 生成学习指南,使用的提示词是:

请为一名已有Python、机器学习和简单Web开发基础,但缺少团队项目经验的大学生,生成一份简要的软件工程课程学习指南。指南要覆盖课前、课堂、个人实践、团队协作和复盘五个方面,并给出可执行的建议。

5.2 AI 生成的简要指南

  1. 课前准备:快速浏览本周主题,做到预习,对本节课内容有基本了解。
  2. 课堂学习:重点理解方法适用的场景和代价,不只记定义。
  3. 个人实践:每周完成一个小的工程化改进,如补充README、拆分模块、增加测试或配置持续集成,并保留提交记录,更加熟练GitHub使用。
  4. 团队协作:先约定分支、提交信息和代码评审规范;使用Issue拆分任务,明确负责人和完成标准;合并前由另一名成员检查。
  5. 复盘总结:每个迭代结束后记录完成情况、问题原因和下一步措施;关注缺陷数量、任务偏差和返工原因,而不是只看功能数量。

5.3 对指南的分析

这份指南总体合理,对我有实际帮助。它没有把软件工程理解成一组孤立的理论,而是强调把需求、设计、测试和协作落实到持续实践中。“每周完成一个工程化改进”和“合并前由另一名成员检查”都具有较强的可执行性,也正好对应我在测试与团队协作方面的不足。不过,这份指南仍然比较通用。它没有结合课程具体项目给出时间安排,也没有说明需求变更、技术债务和团队成员进度不一致时如何处理。AI可以帮助快速建立学习框架,但不能替代课程要求、教师反馈和真实项目中的判断。对我而言,最有帮助的使用方式是把这份指南转化为每周检查项:是否留下清晰提交记录、是否补充测试、是否及时更新Issue、是否完成复盘。总的来说,这个建议为我提供了多方面的大致方向,还是比较有用的。

六、总结

通过第一次个人作业,也是我在博客园的第一篇用markdown文章,首次搭建了GitHub pages,感觉收获还挺大的,虽然大部分都是AI做的,感觉也还挺好玩的,这次的学习也让我加深了对markdown的认识,不然也只会用井号打标题了。还有把 Hugging Face 模型调用、Express 接口和前端交互连接成了一个可运行的小项目。总的来说这次作业,在我和AI的共同努力下应该算是95%的完成度吧,今后也希望能在个人网站或者是在博客园上发表我自己的学习心得等,还有ai的发展确实很快,紧跟时代潮流也是有必要的,当然对于一些知识的学习也是必要的,就像老师所说,大部分的学科尽头都是哲学,我们不仅要学习理论知识,也要在学习的过程中受益匪浅,将所学到的知识运用到生活当中。所以不仅要做好对课内知识的掌握,将其运用到自身或者是未来,这才是大智慧_φ(❐_❐✧)。a527079e93ac5d01c652e5c192b7ae01

七、后台编辑页面截图

按照作业要求,本文使用 Markdown 编辑器完成。

博客园后台Markdown编辑页面以及关注截图:

联想截图_20260907182837
联想截图_20260907184813

完成作业后的我by bike:

0223414e621a5c4500ab8d42c972cea0

看在我这么辛苦的份上,给个好评吧(◍´꒳`◍),拜托了!

感谢您的观看!奖励你一只可爱的猫咪🐱:

ee94143b2e350289f9b4c5890876524b

To be continued...

posted @ 2026-09-07 19:15  ddddal  阅读(108)  评论(5)    收藏  举报
选择主题