2026秋软件工程个人作业(第一次)
2026秋软件工程个人作业(第一次)
| 这个作业属于哪个课程 | H202601软件工程与软件工程实践 |
|---|---|
| 这个作业要求在哪里 | 2026秋软件工程个人作业(第一次) |
| 这个作业的目标 | 完成账号准备、HuggingFace API调用实验、GitHub个人主页搭建;撰写博客园随笔,梳理个人技能树,使用AI生成软件工程学习指南并分析,熟悉Markdown写作,完成软件工程第一次作业。 |
| 学号 | 102401114 |
软件工程第一次作业
一、准备工作
已关注老师和两位助教
截图:博客园后台编辑页面截图
二、huggingface-API的调用
2.1 作业目标
- 在 huggingface.co 注册个人账号并获取访问令牌(Token)。
- 调用托管在 Hugging Face Inference Providers 上的 XLabs-AI/flux-RealismLora,生成一张最贴近真实世界的图像。
- 在 Python 调用代码的基础上,结合前端页面实现「交互式生成」(提示词、参数、历史记录、调用日志)。
- 完整记录 API 调用过程(成功日志、请求 / 响应字段),并附上提示词迭代思路与最终生成结果。
截图1:API调用成功记录
截图2:前端页面生成图像【
】
2.2 模型选型说明
| 项目 | 说明 |
|---|---|
| 作业指定模型 | XLabs-AI/flux-RealismLora |
| 基础模型 | black-forest-labs/FLUX.1-dev(Black Forest Labs) |
| LoRA 作用 | 对 FLUX.1-dev 进行「写实摄影风格」的轻量化微调,使生成结果更接近真实相机照片 |
| 托管推理 | Hugging Face Inference Providers(fal-ai 提供实际 GPU 算力) |
| 许可证 | FLUX.1 [dev] Non-Commercial License(非商业用途) |
为什么用 Inference Providers 而不是本地 diffusers?
FLUX.1-dev 完整模型约 24 GB,本地推理需要 ≥24 GB 显存的 GPU。Hugging Face 提供的 Inference Providers 把这个能力按调用次数计费,免费账户每月有少量免费额度,课程作业只需 1–3 次调用就能完成,非常合适。
2.3 提示词设计思路与迭代过程
初始提示词:A girl on a rainy street

优化后提示词:A girl on a rainy street, photorealistic, cinematic, ultra HD, detailed skin texture

最终提示词:photorealistic candid photograph of a young woman standing on a rain-soaked city street at dusk, wearing a beige trench coat, hair damp from the drizzle, looking slightly off camera, warm neon reflections on wet asphalt, shallow depth of field, 85mm f/1.4 lens, natural skin texture with visible pores, soft rim light from a street lamp, subtle film grain, muted cinematic color grading, ultra detailed, 8k, raw photo

思路:一开始描述过于简单,生成画面细节不足;逐步增加写实风格、电影感、超高清、皮肤纹理等关键词,让图像更贴近真实照片效果。
2.4 API调用体验与心得
FLUX 对英文提示词的响应比中文更稳定,关键风格词(photorealistic, candid, 8k, raw photo)直接用英文效果更好。
反向提示词不是越多越好,只列真正想排除的项(插画 / 卡通 / 塑料皮肤 / 形变)即可,过多会稀释主体权重。
镜头参数(85mm f/1.4)+ 物理光学词汇(shallow depth of field, rim light)能把「写实感」从「照片感」提升到「纪实摄影感」。
同一个种子下,num_inference_steps=28→50、guidance_scale=2.5→3.5 会让画面「实」一档,但超过 3.5 容易色彩过饱和。
2.5 实验代码
调用 Hugging Face FLUX 写实模型
模型:XLabs-AI/flux-RealismLora(基于 FLUX.1-dev 的写实 LoRA),经 Inference Providers 由 fal-ai 托管推理,免本地 24GB 显存。
1. 模型调用核心(hf_flux.py)
import time, uuid
from datetime import datetime
from pathlib import Path
from huggingface_hub import InferenceClient
MODEL_ID = "XLabs-AI/flux-RealismLora" # 写实 LoRA
FALLBACK_MODEL_ID = "black-forest-labs/FLUX.1-dev" # 基础模型(兜底)
DEFAULT_PROVIDER = "fal-ai" # 托管推理提供商
OUTPUT_DIR = Path("outputs")
def generate(prompt, negative_prompt="", width=1024, height=1024,
num_inference_steps=28, guidance_scale=3.5, seed=None):
token = get_token() # 从环境变量或 .env 读取 HF_TOKEN
if not token:
raise RuntimeError("未找到 HF_TOKEN,请在 .env 中配置")
request_id = uuid.uuid4().hex[:12]
# 三级降级链:指定组合 → 同模型自动路由 → 基础模型自动路由
chain = [(MODEL_ID, DEFAULT_PROVIDER),
(MODEL_ID, "auto"),
(FALLBACK_MODEL_ID, "auto")]
attempts, last_error = [], None
for mdl, prv in chain:
t0 = time.time()
try:
client = InferenceClient(provider=prv, api_key=token)
image = client.text_to_image(
prompt, # 正向提示词
model=mdl,
negative_prompt=negative_prompt or None, # 反向提示词
width=width, height=height, # 输出分辨率
num_inference_steps=num_inference_steps, # 去噪步数
guidance_scale=guidance_scale, # CFG 引导强度
seed=seed) # 固定种子可复现
out = OUTPUT_DIR / f"flux_{datetime.now():%Y%m%d-%H%M%S}_{request_id}.png"
out.parent.mkdir(exist_ok=True)
image.save(out)
attempts.append({"model": mdl, "provider": prv, "status": "200 OK",
"latency_ms": int((time.time() - t0) * 1000)})
return image, out # 成功即返回(调用记录另落盘为日志)
except Exception as exc: # 失败则降级到下一个组合
last_error = f"{type(exc).__name__}: {exc}"
attempts.append({"model": mdl, "provider": prv,
"status": "ERROR", "error": last_error})
raise RuntimeError(f"三次尝试均失败:{last_error}")
2. 后端接口(app.py)
推理耗时 10~25 秒,所以用「提交任务返回 job_id + 前端轮询」的异步模式,避免 HTTP 请求阻塞:
import uuid
from concurrent.futures import ThreadPoolExecutor
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI(title="Flux Realism 交互式生成器")
executor = ThreadPoolExecutor(max_workers=2)
JOBS = {} # job_id -> 任务状态
class GenerateRequest(BaseModel):
prompt: str = Field(..., min_length=1)
negative_prompt: str = ""
width: int = Field(1024, ge=256, le=2048)
height: int = Field(1024, ge=256, le=2048)
num_inference_steps: int = Field(28, ge=1, le=60)
guidance_scale: float = Field(3.5, ge=0.0, le=20.0)
seed: Optional[int] = None
@app.post("/api/generate")
def api_generate(p: GenerateRequest):
job_id = uuid.uuid4().hex[:12]
JOBS[job_id] = {"status": "queued", "result": None, "error": None}
executor.submit(_run_job, job_id, p) # 线程池里执行 hf_flux.generate()
return {"job_id": job_id} # 立刻返回,不等推理完成
@app.get("/api/jobs/{job_id}")
def api_job(job_id: str):
return JOBS.get(job_id, {"status": "not_found"})
3. 前端交互(原生 JS)
async function generate() {
const payload = {
prompt: document.getElementById("prompt").value,
negative_prompt: document.getElementById("negative").value,
width: 1024, height: 1024,
num_inference_steps: 34,
guidance_scale: 3.5,
seed: 20260910
};
// 提交任务,立即拿到 job_id
const res = await fetch("/api/generate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
const { job_id } = await res.json();
pollJob(job_id); // 然后轮询进度
}
function pollJob(jobId) {
const timer = setInterval(async () => {
const job = await (await fetch("/api/jobs/" + jobId)).json();
if (job.status === "done") { // 成功:展示图片 + 元信息
clearInterval(timer);
document.querySelector("#canvas img").src = "/" + job.result.image_path;
} else if (job.status === "error") { // 失败:展示错误
clearInterval(timer);
alert("生成失败:" + job.error);
}
}, 700);
}
三、Github个人主页搭建
本次选择方案:个人资料README
仓库链接:个人仓库
截图:GitHub个人主页效果
四、技能树梳理与自我评估
4.1 当前技能树与技术偏好梳理
能力 A:编程语言与基础开发能力(已具备,较熟练)
- 掌握 Python 的基本语法,能独立完成课程作业级别的小程序,理解函数、面向对象等基本概念。
- 了解 C 语言 的基础,理解指针、内存等底层概念。
- 特点:能写出"正确"的代码,但代码组织随意,缺乏工程化的结构和规范意识。
能力 B:工具与开发环境使用(已具备,入门级)
- 会使用 IDE 和基本的命令行操作,了解 Git 的基本命令(clone / commit / push)。
- 对"用工具替代重复劳动"有较强兴趣,喜欢琢磨编辑器配置、脚本自动化这类效率技巧。
- 特点:工具使用停留在"查一个用一个",Git 只会单人直进直出,没用分支协作过。
能力 C:逻辑思维与自学习能力(已具备,是相对优势)
- 遇到问题习惯先自己查文档、搜索、试错,再求助,自驱力较强。
- 做题和作业时能把问题拆解成小步骤逐一解决,逻辑推演能力尚可。
- 特点:自学是优势,但学习路径不成体系,容易"会一块缺一块"。
感兴趣的技术方向
- 测试与软件质量:很好奇"工业级的软件是怎么保证不出 bug 的",对测试用例设计、自动化测试有强烈兴趣。
- Web 开发:希望能独立做出一个完整可用的网站。
- AI 应用开发:对大模型 API、AI 辅助编程工具如何改变开发流程很感兴趣。
还欠缺的能力(短板清单)
| 编号 | 欠缺能力 | 影响 |
|---|---|---|
| 1 | 数据结构与算法基础薄弱 | 写出的代码效率低,复杂问题不知如何下手 |
| 2 | 没有参与过多人协作的完整项目 | 不了解代码评审、分支管理、模块分工 |
| 3 | 几乎没写过测试 | 代码出 bug 靠肉眼 print,不知道怎么系统性验证 |
| 4 | 数据库只停留在会写简单 SQL | 不会设计表结构,不理解事务与索引 |
| 5 | 软件工程"过程"类知识零散 | 需求分析、UML、迭代计划等只在书上见过,没有实践过 |
| 6 | 代码量不足 | 手感不够熟,写代码时还需要频繁查语法 |
4.2代码量说明
- 目前累计代码量:约 3,000 行(构成:课程作业约 2,000 行、个人小练习与脚本约 1,000 行;均为手写有效代码,不含自动生成部分)。
- 本学期课程结束后的目标:累计达到 15,000 行。
- 达成路径的粗略拆解:
- 课程实验与作业:+5,000 行;
- 团队课程项目:+5,000 行(重点体验协作开发而非单纯堆量);
- 个人项目(一个带测试的完整小项目)+ 算法练习:+2,000 行。
- 我理解代码量不是唯一指标,但对我现阶段而言,量是"熟练度"的必要前提——先写够,再谈写得好不好。
4.3本课程中最期待学习的知识,以及希望获得的收获
最期待的知识点(按期待程度排序):
- 软件质量保障——测试用例设计、单元测试、Debug 方法论。我最想弄明白"一段代码写完之后,怎么证明它是对的",这恰恰是我现在完全空白的部分。
- 从需求到设计的完整推演过程——需求分析、用例建模、UML 图,想知道"一个想法是怎么一步步变成可开发的设计文档的"。
- 团队协作工程实践——版本控制规范、分支策略、代码评审,这是我从来没经历过的。
- 软件生命周期与项目管理——敏捷开发、迭代计划、风险控制。
希望获得的收获:
- 养成写测试的习惯:课程结束后,写任何代码都会顺手配上基本的测试。
- 完成一次完整的团队项目经历:从需求 → 设计 → 编码 → 测试 → 交付全流程走一遍。
- 建立工程化思维:从"写作业的学生"转变为"做软件的人"。
- 沉淀一套可复用的个人开发流程(环境配置、Git 规范、测试习惯),让能力在课程结束后仍能持续生长。
4.4 AI生成软件工程课程学习指南与分析
以下是我用deepseek生成的学习指南
阶段一:基础重建期(第 1–6 周)
- 目标:补齐工程基础,进入"课程语境"。
- 行动:
- 每周精读教材对应章节,用自己的话输出一页"概念卡片";
- 重刷 Git 操作,达到不看教程独立完成分支创建与合并;
- 每周至少 2 道算法题,保持手感;
- 搭建个人开发环境模板(编辑器配置、代码规范、提交模板)。
阶段二:方法实践期(第 7–12 周)
- 目标:把课程方法论用到自己的小项目上,重点实践测试。
- 行动:
- 选一个真实的小需求,独立走完"需求分析 → 用例图 → 简单设计 → 编码 → 测试"全流程;
- 为项目核心模块编写单元测试,学习一个测试框架(如 Python 的 pytest)并坚持使用;
- 每写完一个函数,先自己设计 2–3 个测试用例(含边界情况)再提交;
- 开始写开发日志,记录每个决策的理由和踩过的坑。
阶段三:协作冲刺期(第 13–18 周)
- 目标:在团队项目中承担明确角色。
- 行动:
- 主动认领一个模块并负责到底,而不是"哪里缺人补哪里";
- 严格执行分支规范与代码评审,哪怕团队嫌麻烦也坚持;
- 争取承担项目中测试相关的工作(测试计划、用例设计),把最期待的知识用足;
- 每周复盘一次:流程哪里卡了、下次怎么改。
贯穿全程的习惯
- 输入:每周精读 1 篇软件工程相关文章/案例;
- 输出:每周一篇学习随笔(就是本文所在的这一系列);
- 度量:每月统计一次代码量与提交记录,对照目标校准。
五、学习指南的合理性与帮助分析
逐条自评(合理之处):
- "三阶段"划分合理:先补基础 → 再单独实践 → 后团队协作,符合能力成长曲线。对我这种"会写单文件程序但没做过工程"的背景,第一阶段的重建期尤其必要——直接跳到团队项目会让我在协作规范上持续踩坑。
- 以"测试"为主线实践合理:我最期待的是测试与质量,指南在阶段二、三都为此安排了具体动作(学 pytest、每函数配用例、承担测试角色),兴趣和能力短板正好对上,学习动力和补短板一举两得。
- "输出倒逼输入"合理:概念卡片、开发日志、周随笔都是输出型任务。被动听课的知识留存率很低,这一点符合学习科学的基本结论。
- 量化目标合理:代码量按月度量、按目标拆解到任务,把"15,000 行"这种大目标变成了可执行的小动作,避免期末才发现差一大截。
潜在风险与不足(需要警惕的地方):
- 代码量指标可能误导:指南中代码量目标清晰,但"行数"容易诱导写注水代码。对策:给自己加一条约束——统计时剔除空行与生成代码,宁可少而实。
- 时间投入估计偏乐观:阶段二要求全流程独立走一遍,叠加其他课程可能吃不消。对策:把小项目范围压缩到 2 周能完成的最小可用版本(MVP),先走通流程再迭代。
- 团队协作部分不完全可控:课程项目队友的投入度不由我决定。对策:把自己可控的部分(规范执行、日志、复盘)做满,不可控的部分只求"完整经历、认真复盘"。
- 算法练习强度偏低:每周 2 题对补短板来说只是"维持"而非"追赶"。可以在阶段二视情况提到每周 4 题。
结论:这份指南能否对我带来帮助?
能,且帮助主要在三点:一是它把"学好软件工程"这个模糊愿望翻译成了周级别的具体动作,我知道每周该做什么;二是它的阶段划分与我的短板清单一一对应,是"对症"而非"通用模板",尤其测试主线正中我最期待也最欠缺的部分;三是它内嵌了复盘机制,指南本身也会被迭代,而不是开学写完就锁进抽屉。
最大的前提是执行。这份指南最可能的失败方式不是"写得不合理",而是"期中之后不再看它"——因此我把它写进随笔,作为公开的自我承诺,也方便老师和助教在学期中随时检查我的执行情况。





浙公网安备 33010602011771号