实验:不可变坐标变换
约 55 分钟
实验:不可变坐标变换
从 Programming I 的可运行函数出发
上一门课让我们能从规格写出函数和测试;现在软件开始有多个模块、长期状态、共享资源和同时进行的任务。围绕类、对象与组合,先明确实验:不可变坐标变换要解决的变化压力:什么必须稳定,什么允许替换,谁创建并释放资源,失败或取消时哪条性质仍要成立。今天的实验是:围绕实验:不可变坐标变换先画对象与资源关系,再运行正常、边界、失败和确定性交错四组实验,保存状态轨迹。
(本段工程对象:实验:不可变坐标变换;位置:2-7。)
跟我画接口、状态与责任图
第一步列公开输入输出和调用者;第二步把内部状态、文件、锁、任务与对象画成节点;第三步用箭头标出依赖、引用、所有权转移和等待关系;最后依据实验:不可变坐标变换必须声明公开接口、隐藏状态、所有权或资源责任、允许的并发交错、失败后的不变量以及可替换实现走一次正常路径和一次失败路径。每条箭头都回答“谁能改、活多久、谁清理、能否并发”,图与代码不一致时先修正模型。
(本段工程对象:实验:不可变坐标变换;位置:2-7。)
从具体实现抽出稳定抽象
先写一个直接但正确的实现,再寻找真正会变化的轴。若只是两个函数,模块接口可能足够;若状态与行为必须共同保持不变量,才引入类;若多种类型共享操作能力,再考虑协议或泛型。抽象不是层数越多越好,而是让调用者依赖更少、更稳定、可测试的承诺。
(本段工程对象:实验:不可变坐标变换;位置:2-7。)
对实验:不可变坐标变换采用三轮递进:第一轮阅读最小实现并标注每个状态变化;第二轮替换一个实现或注入一次失败,预测哪些调用者不应受影响;第三轮合上示例,从接口与不变量独立重写。若替换需要修改所有调用点,或失败留下半更新状态,说明边界没有真正建立。
(本段工程对象:实验:不可变坐标变换;位置:2-7。)
内存、资源与生命周期
每个对象区分值、引用和底层资源。记录创建、借用、共享、移动、关闭和销毁事件;别名存在时说明谁可写,跨线程时说明同步关系。Python的垃圾回收不能代替文件、锁、事务等确定性清理,C++所有权也不能只靠“记得delete”。资源责任必须体现在上下文、RAII式封装或清晰的释放协议中。
(本段工程对象:实验:不可变坐标变换;位置:2-7。)
并发与异步的确定性推理
并发正确性不能用“多跑几次没出错”证明。把共享状态访问拆成原子步骤,列出关键交错;用锁保护最小临界区,用条件谓词应对伪唤醒直觉,用固定锁顺序避免环等待。异步任务还要处理取消、超时、结果顺序和清理。测试使用屏障、事件、排序后结果或模型模拟,避免依赖睡眠和偶然调度。
(本段工程对象:实验:不可变坐标变换;位置:2-7。)
可运行实现与四组测试
参考实现使用 Python 3 标准库或 C++17,并由判题器真实运行。四组测试覆盖正常组合、空或单元素边界、资源/异常失败和确定性交错回归。若本节识别出5个状态类,每类至少4测,基础清单是5×4=20项;数量之外还要说明每项排除了哪个所有权、同步或接口假设。
(本段工程对象:实验:不可变坐标变换;位置:2-7。)
常见失败与首个错误决定
本节严格边界是:实验:不可变坐标变换不能靠全局可变状态、无限重试或偶然调度正确;别名、清理、取消、锁顺序和性能退化必须显式处理。遇到故障先保存接口调用、资源状态、线程或任务状态、期望不变量与实际轨迹;再缩小到首个错误决定。不要用扩大锁范围、捕获全部异常、复制全部数据或关闭并发来掩盖设计缺陷;这些办法可能暂时安静,却会制造死锁、泄漏、延迟或一致性问题。
(本段工程对象:实验:不可变坐标变换;位置:2-7。)
性能与设计权衡
正确之后才测量。记录工作负载、输入规模、预热、重复次数和分位数;区分算法成本、对象分配、序列化、锁竞争和I/O等待。优化必须保持公开契约和测试,通过基准前后对照说明收益;若复杂度提高而收益不超过噪声,撤销优化。围绕实验:不可变坐标变换同时写出时间、空间、可读性和失败恢复代价。
(本段工程对象:实验:不可变坐标变换;位置:2-7。)
项目证据与自检
把本节产物纳入中型项目:接口说明、对象/所有权图、可运行实现、四类测试、一次失败注入、一次性能记录和评审结论。完成单选、多选与计算题后,合上材料解释实验:不可变坐标变换的接口、不变量、资源责任、允许交错、失败清理和替换边界。能换实现而不破坏调用者,才算掌握抽象。
(本段工程对象:实验:不可变坐标变换;位置:2-7。)
Practice
本课练习
先独立作答再提交;编程题会在隔离沙箱中真实编译、运行并对拍。