1

工程开发经验总结二,如果我是甲方,该如何外包?

 2 years ago
source link: https://yuanjie-ai.github.io/2021/12/09/project-experience-2/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

本来是想直接写下的,半路除了点问题,写一篇中吧。具体出了什么意外呢?当然是自己不太熟悉的 git 操作,实在是缺乏和别人一起开发项目的经验。后来又陆续有一些其他的收获,一并整理。

承接上文,在代码开发与测试完成后,其实工作量才完成了一半,对的,你没听错。

关于代码提交

提交代码自然而然用的是 git,但是甲方的代码开放程度是不同的,甲方的主代码我们称为 master 分支,每个组有一个 ownerowner 能直接获取 master 的仓库,而开发人员只能获取 owner 的仓库。

这种操作就导致了一个问题,代码更新不及时,开发者和甲方沟通低效。开发者想要更新仓库,就必须先让 owner 更新;甲方提出代码的问题,就必须由 master 转发。

暂且假设更新成功,本地提交时,创建分支,提交代码,由于没获取 master 仓库的权限,只能由 owner 发起 pull request。而众所周知:一件事情经过的转手次数越多,经过的人员越多,处理速度就越慢。脑补你办一件事情,一张纸要盖很多章,那些人踢皮球的水平超乎你的想象。

其实这也不能怪 owner,如果这是在公司,上班时间我们开发的会很快;但是这是在学校,且还是研究生,你永远不知道你的老师会在什么时间给你安排什么奇奇怪怪的任务,事情一多就容易耽误,且心累。

再次假设,pull request 成功了,由于 master 频繁收录提交的代码进行更新,刚刚提交的 pull request 很可能代码冲突,此时就需要手动处理。我尝试了用 gitee 的界面进行处理,结果,呵呵,我们组全部的 pr 被我弄没了,全部重新提交,大型操作失误现场。

之后尝试用命令行操作,手动处理冲突并提交,pr 处显示没冲突,但是代码审核就是有冲突,冲突的位置我看了一下,本地明明已经处理好了。也许是我 git 操作不熟练,也许是线上环境的问题,很奇怪,最后也没有修复,重新拉取最新,草草提交了。

这前前后后大概浪费了三天宝贵的时间,这也在提醒我,抽时间学 git

关于修改程序

因为需求性分析搞错了方向,导致我在这上面吃了大亏。当时大概有两种可行路线,一种是 A 路线,一种是 B 路线,两者只是表现形式不一样,但最终结果是一样的。我当时盲目自信,以为都行,就选择了 A 路线。后来个甲方沟通才知道,要实现 B 路线。这就导致了代码大改,白白的浪费时间和精力。 以至于为了赶进度,我还叫别人帮我一起改,可真是愧疚。

实现代码的改动会带动原型定义代码、测试代码的一起变动,难确实不难,恶心是真的恶心。我也第一次体会到,实际开发中,测试代码会比实现代码多的多。而且改代码的时候需要注意,改一点编译一点,不要一次性改一堆然后一次性编译,出错了都不知道是哪错了。

用一句话总结吧,中国有个成语叫管中窥豹,但也有见微知著,有一叶知秋,也有一叶障目不见泰山,无论如何都有个成语,叫自以为是。

从甲方的视角看代开发

因为在开发的过程中遇到了一些困难,不是实现代码的困难,而是理解逻辑的困难。所以引出了这个思考,如果我是甲方,我把项目外放给别人,我应该怎么描述问题,才能让对面完成的更好?毕竟花同样一份钱,我希望拿到更好的程序。

第一点是提前告知项目的所有内容。这次开发有两个任务,第一个任务是开发和测试,第二个任务是适配。当时大家都以为适配很简单,外什么呢?因为一开始根本看不到第二个任务的说明书和文档,只有做完第一个任务才能看到后续任务的文档。相比之下,我们都认为适配会比开发简单的多,所以时间花费不合理,导致在开发浪费的过多的精力。等看到第二个任务的文档时,才发现代码量不会比开发低,但此时已经没有时间了,只能延期。如果是我,我会提前告知,以及在开发期间进行适当的催促。

第二点是整理常用的编译命令。因为大型项目的编译不是点按钮就能实现了,需要在命令行执行很长的了命令。我会写单独的一个文档,把这些命令从文档的各个角落收集起来,方便开发人员的粘贴。不然翻来翻去太麻烦了,真的。

最后一点,也是我认为最重要的一点。在文档之中,而不是文档之前进行一个逻辑说明,而不是单纯的告诉用户哪个文件的程序该怎么写。为什么呢?配置环境,如何开发等基础文档在这里就先忽略了,不是重点。

如果把概念性的东西写在最前面,开发者读起来会晕,而且不知所云。放在文档中间,当用户写完程序后,相对有了一定了解,知道代码写的是什么,在看到概念性的东西会比较直观。这就像看当代论文一样,先看摘要和引言,丝毫不知道在说什么,往往看到最后才明白。这其实和中国人的思维不符。举个例子,中国人盖房先打地基,自底向上,外国人盖房先设计房顶,自顶向下。两者都没有错,可中国人习惯了自底向上,被迫看自顶向下的东西不舒服。再举个例子,学计算机网络,是从物理层学到网络层,还是从网络层学到物理层?

其次,我要告诉用户他写的那些文件之间是什么逻辑。假设有 A B C 三个代码,开发者可能以为 A 会调用 B,为保证运行正确,B 中需要进行初始化操作;但其实呢,A 不会调用 B,B 也不用初始化,因为初始化工作已经在 C 中完成了。相信我,当项目规模十分庞大的时候,复杂的文件以及这些调用关系不是人眼能看出来的。即使能看出来,你也不会相信这种调用关系,不信?我举个例子。A 是测试代码,里面含有正确结果,B 是实现代码,B 需要把返回结果写到数组中,但数组大小未知。

  • 第一种情况,B 不需要经过运算获得数组大小,直接把结果写到测试代码的结果里面就好。
  • 第二种情况,B 需要运算并获取数组大小,开辟新的数组,将结果写到新的数组,并返回与测试结果对比。

正确答案是第一种情况。为什么不用具体实现?实际调用代码的时候没人会给你测试代码提供结果啊?代码不实现功能怎么能行?刚开始我也这么想的,但后来发现在实际使用的时候,会在一个默默无闻的 C 文件的代码中对 B 文件中的代码进行初始化,这就是没有搞清楚逻辑的后果,再次导致了代码的改动,而这种改动是可以在一开始避免的。

那么对于乙方,如何避免这种情况呢?开发的时候多和身边的人聊一聊,要多问多交流,而不是闷头凭自己的感觉和想象写程序,独行快,众行远。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK