结对编程-stage_2
| 教学班 | 罗杰、任建班周五3、4节 |
|---|---|
| gitlab项目地址 | Here it is. |
| 成员 | 周远航(3004) 李辰洋(3477) |
结对编程体验
经过了上一阶段的磨合,第二阶段我们的配合更加流畅,也熟悉了对方的编程习惯,因此编程的效率有所提高。
和stage_1不同的感受是,stage_2我们讨论的时间明显减少,项目的基本框架已经成型,因此无需像第一阶段一样对大型设计架构进行讨论,只需要关注一些细节功能的实现方式即可。另外,本阶段代码规模明显增大,为了保证代码的可读性和优雅程度,我们花了更多时间在代码美观上,包括对一些冗长的方法进行了重写,提取更多工具性方法和工具类等。
在开始动笔前,我们还是首先进行了面对面讨论,更深入地挖掘了linux文件系统的原理,并对各个新增功能的实现方式进行敲定,并在第一阶段的讨论结束后开始动手。

由于和队友的课程时间不一致,能面对面编程的时间宝贵且有限,考虑到本次作业usersystem和filesystem的独立性较大,我们进行了一定的分工,并在仓库的alpha分支进行协作,将稳定版本merge到master分支触发评测,以节约评测资源。

截至目前,我们二人已在两分支进行了共186次commit。

然后,现实是残酷的,在动手一天后,主笔usersystem部分书写的L同学已经顺利完成了所有功能的实现和test的书写。然而主笔filesystem部分的Z同学陷入了啃不动指导书的绝境。于是乎在一个月黑风高的晚上,我们又一次进行了面对面现场合作。

在后期测试阶段,我们通过书写单元测试发现了一系列问题,延续了第一阶段的测试导向编程方法,即将test编写好后传递给对方,对方修改代码后通过测试。
设计思路
在第一阶段文件系统的基础上,本次迭代要求实现HardLink、SoftLink以及mv、cp、readline等指令,以及新增了用户系统及一系列功能,本阶段程序设计框架如下UML图所示:

MyFileSystem
文件系统核心类,继承官方接口FileSystem。用于记录root和currentPosition两个目录入口,并且维护指令流计数器。
DirectoryEntry
目录入口类。用于管理目录下的所有文件(包括目录文件、普通文件)以及文件树的上下级关系。
File
抽象类,所有文件类型对象的父类,定义了文件类型对象的公共属性和方法。
RegularFile
普通文件,继承File抽象类。
Directory
目录文件,继承File抽象类。
SoftLinkFile
软链接文件,继承File抽象类。保存了指向文件或目录的绝对路径。
MyUserSystem
用户系统核心类,继承官方接口UserSystem。用于管理系统所有用户和用户组信息,记录当前系统活跃用户信息。
User
用户类。保存用户名、用户主组及其所属用户组等信息。
Group
用户组类。保存用户组名及其包含的用户信息。
Parser
路径分析及格式检查工具类。
LookUpService
文件查询工具类。
实现过程
在本次任务中,我们继续使用TDD(测试驱动开发)的开发流程,尽量做到在编写代码之前做好测试单元的设计和编写,然而由于本次功能涉及的条件和特殊情况判断多且复杂,也让测试单元的编写举步维艰。
在代码编写过程中,出现了不少需要纠结具体细节实现的地方,出于对性能的考量,本次任务中使用JProfiler对极限数据进行了测试。
代码复审和测试阶段,我们发现,在对深度极大的文件树进行操作时,可能出现性能上的瓶颈,于是构造了大量超深目录创建和文件写入的测试数据,发现出现了爆栈、爆堆区空间等情况。对于爆栈的情况,我们将部分递归进行的函数去递归化,采用循环的方式进行处理。而对于爆堆区空间的问题,有些一筹莫展,于是我们使用JProfiler监测运行程序的内存占用状况,发现仅仅一次深度递归的mkdir,就产生了大量的内存占用:

右图中可以发现,Object[]的size达到了462MB,这让我们想到,为了让绝对路径不进行重复计算,我们对每个目录都使用ArrayList对路径中节点进行保存,但缓存机制除了占据巨大的内存,还有另一个缺点,速度:

可以看到,对当前目录ArrayList的计算中,需要使用addAll方法将父节点的路径列表加入当前节点,这不仅占用了大量内存,也在计算的速度中,并不讨好,因此,我们计划使用StringBuilder保存,虽然在速度上有所进步,但内存空间上的消耗大了将近1/3:

最后,我们分析,这种缓存虽然在计算上不需要过多时间,但如果存在大量的新增、移动、复制等命令,将大大降低运行效率,并且内存的使用量永远是一个隐患,因此,我们最终放弃缓存机制,对绝对路径的计算,仅采用即时计算的方式:


最终发现,在这种情况下,内存的使用量和速度都达到较好的水平,但在大量的getAbsPath方法调用中,可能依旧存在速度问题。鱼和熊掌不可兼得。
时间规划
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟 |
|---|---|---|---|
| Planning | 计划 | 20 | 20 |
| · Estimate | · 估计这个任务需要多少时间 | 20 | 20 |
| Development | 开发 | 555 | 815 |
| · Analysis | · 需求分析 (包括学习新技术) | 60 | 90 |
| · Design Spec | · 生成设计文档 | 15 | 15 |
| · Design Review | · 设计复审 (和同事审核设计文档) | 10 | 10 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 10 |
| · Design | · 具体设计 | 30 | 30 |
| · Coding | · 具体编码 | 180 | 240 |
| · Code Review | · 代码复审 | 120 | 150 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 120 | 270 |
| Reporting | 报告 | 60 | 60 |
| · Test Report | · 测试报告 | 20 | 20 |
| · Size Measurement | · 计算工作量 | 10 | 10 |
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 |
| 合计 | 636 | 895 |
整体来看,设计和主要代码的编写过程依然比较顺利,但代码复审、研读指导书细节、修改细节实现、测试复杂情况花费了比预计多了不止一倍的时间。而且,这些时间并不是集中的,而是遍布了作业进行期间的每一天。
结对编程-stage_2的更多相关文章
- 结对作业-stage_2
见队友博客:结对编程-stage_2
- 结对编程--基于android平台的黄金点游戏
游戏内容: 阿超的课都是下午两点钟,这时班上不少的同学都昏昏欲睡,为了让大家兴奋起来,阿超让同学玩一个叫“黄金点”的游戏: N个同学(N通常大于10),每人写一个0~100之间的有理数 (不包括0或1 ...
- 结对编程-地铁续(有种上个学期OO的既视感)
我们组比较特殊..三人结对 github:https://github.com/qingchanghan/WPFUI_Metro po一张照片: 石浩然,韩青长.陈彦吉 (台式机真的很高端,分屏贼帅) ...
- 结对编程项目——四则运算vs版
结对编程项目--四则运算vs版 1)小伙伴信息: 学号:130201238 赵莹 博客地址:点我进入 小伙伴的博客 2)实现的功能: 实现带有用户界面的四则运算:将原只能在 ...
- 关于软件工程结对编程作业 PairProject : Elevator Scheduler(电梯调度算法的实现与测试)的总结
1)结对编程队友 1106xxxx 张扬 1106xxxx 杨军 其中,此项目的编程实现主要由前者完成. 2)关于结对编程 结对编程的优点: 最直接的一点:在结对编程中,由于有另一个人在你身边和你配合 ...
- 结对编程—黄金点游戏WinForm单机版
本小游戏场景来自邹欣老师的<移山之道>一书: "阿超的课都是下午两点钟,这时班上不少的同学都昏昏欲睡,为了让大家兴奋起来,阿超让同学玩一个叫"黄金点"的游戏: ...
- Week4 结对编程
1.照片 1.1 结对编程参与者:李文涛.黎柏文 1.2 展示照片 2.结对编程的优点&缺点 2.1 优点 2.1.1.两人分工合作,减少了工作量 2.1.2.结对编程的伙伴往往能提供不同 ...
- 结对编程——关于Fault、Error、Failure程序设计
一.问题描述: 构造程序,分别是: •不能触发Fault •触发Fault,但是不能触发Error •触发Error,但是不能产生Fai ...
- GUI、模块化与结对编程(homework-03)
摘要: 在本次作业博客里,我将主要阐述作业3的收获.作业3表面是将之前的程序转换为图形界面(之前程序见http://www.cnblogs.com/shone/p/3348372.html),然而本质 ...
随机推荐
- 新年狂欢高倍币,1万枚VAST拿到手软
新一年NGK推出了新币VAST,成为了当前最瞩目的一颗星.有人认为VAST有价无市,有人认为VAST价值巨大,潜力无限.总之,众说风云! 选择数字货币,当然是挑选有价值的货币,从内外价值入手. 一.币 ...
- .NET微服务最佳实践 eShopOnContainers
本文翻译自微软Docs, 内嵌译者多年使用的参悟,如理解有误,请不吝赐教. 微软与社区专家合作,开发了功能齐全的云原生微服务示例应用eShopOnContainers. 该应用旨在展示使用.NET.D ...
- 2021-2-22:请你说下 CAP 理论并举例
CAP CAP 理论是分布式系统中的一个老生常谈的理论了,最早由 Eric Brewer 在一个讲座中提出.在这个讲座中,在传统 ACID 理论以及当时比较流行但是比较抽象的的设计指导理论 BASE ...
- Sqoop 数据迁移工具
Sqoop 数据迁移工具 sqoop : SQL to hadOOP 两个功能: 1. RDB 向HDFS导入 2. HDFS向RDB导入 注:拷贝mysql-connector.jar 和 json ...
- Java基础语法:abstract修饰符
一.简介 描述: 'abstract'修饰符可以用来修饰方法,也可以修饰类. 如果修饰方法,那么该方法就是抽象方法:如果修饰类,那么该类就是抽象类. 抽象类和抽象方法起到一个框架作用,方便后期扩展的重 ...
- 双重检验锁模式为什么要使用volatile?
并发编程情况下有三个要点:操作的原子性.可见性.有序性. volatile保证了可见性和有序性,但是并不能保证原子性. 首先看一下DCL(双重检验锁)的实现: public class Singlet ...
- Kubernetes: NGINX/PHP-FPM 502错误和优雅结束
我们有一个运行在Kubernetes上的PHP应用,每个POD由两个独立的容器组成 - Nginx和PHP-FPM. 在我们对应用进行缩容时,遇到了502错误,例如,当一个POD在结束中时,POD里面 ...
- alpine jdk 中文乱码
一.概述 使用alpine镜像构建了一个oracle jdk的镜像,运行java业务时,查看日志,显示中文乱码. 但是,基于Alpine Linux的Docker基础镜像的镜像文件很小,也有代价: 把 ...
- Manjaro安装后简单配置
一个相见恨晚的 Linux 操作系统 Manjaro 到底有多受欢迎? DistroWatch是一个包含了各种Linux发行版及其他自由/开放源代码的类Unix操作系统. (如OpenSolaris. ...
- MySQL:逻辑库与表管理
逻辑库管理 语句 说明 CREATE DATABASE 逻辑库名; 创建逻辑库 SHOW DATABASES; 显示所有逻辑库 DROP DATABASE 逻辑库名; 删除逻辑库 USE 逻辑库名; ...