7
6
2020
6

品《当我开始做软件开发时,最希望听到的七条建议》

本文来自依云's Blog,转载请注明。

在 Twitter 上看到一张写在长图片里的文字《当我开始做软件开发时,最希望听到的七条建议》,记录一下感想。

读书

书确实要读,但每年都读软件工程方面的书,会受边际效用递减的影响的。毕竟软件工程并不是很大的话题,而工程还是得实践出真知。看过几本之后,不如把精力花在更理论和学术的方面,比如编程语言理论、分布式算法、概率论与统计、博弈论,等等。总之就是要「move on」。而实际上我读的书更杂一些。

编程语言

学习多种编程语言是极好的。但也千万不要限于两种,尤其是别 Java + C# 或者 C + C++ 这种组合。会一叶障目的。我在大学期间学习过非常多种编程语言(几乎是把我听说到的都学了个开头)。

我的建议是,至少 C 系一门,ML 系一门,Lisp 系一门,脚本系一门,简单学一学。然后挑自己感兴趣、用得上和有钱途的深学。了解过的编程语言越多样,学习新语言就越容易,甚至可以在不学习的情况下上手阅读、做小改动。

测试

测试确实挺有用的。但更多的时候,它挺烦的:不是代码本身坏了,而是测试坏了……

现在我更看重的是,一个像 Rust 甚至是 Idris 那样强大的类型系统,能在省力的同时发现更多的疏忽。

Python 的类型注解不是很强大,不过也是非常有用的。

重构

我不太明白作者在这里讲重构是什么意思。

我的习惯是,按需重构。如果一份代码一直良好运行,我才不管它写得有多糟糕呢。但当我要修改它的时候(不管是为了添加新功能还是修 bug),我会把看着不舒服的代码给顺势改掉。

一个很重要的点是,不要为了重构而重构。另一个点是,重构中的代码应当是可以正确运行的。至少每天工作结束时提交,提交的时候代码应当是可以正确运行的(可能有 bug,但不能有未完成而无法运行的部分)。这样,重构可以随时因为各种原因中止,不会影响后续不相关的工作,也不会分出分支来时间一长根本合不回去。

我才不要假设我的代码可以使用五年。再过两个月 lilac 就要六岁了,而 nvchecker 已经七岁了呢。

lilac 经历过三次重构。开始重构的原因是,一开始并没有想到会发展成现在这样子,管理一千多个包,每天都要打好几十个。所以那时候的代码写得很烂,全局变量也很多,以至于新功能加不上去。前两次重构都是在我有闲的时候,拉一个分支出来,看哪里不顺眼就改哪里。可问题是,改了几天之后,我完全无法预测这代码还跑不跑得动。另一方面,修新 bug 当然是在老代码上改的。那我重构到一半的新代码怎么办呢?作为业余项目,这种情况持续一些天之后,我稍一忙碌,把它放下之后,我就再也想不起来我当时的重构思路了。

第三次重构,并不彻底,但是它很有效。因为每次改完收工的时候,我会判断它现在能正常跑起来吗?如果觉得不行,那就 git checkout .。有希望才提交,然后上线。跑出 bug 就去修。忙了就放下,等有时间才继续。思路不那么重要了,因为代码是好的,换个思路也可以继续。

当然了,类型注解在重构过程中我加上了许多,也避免了很多疏忽导致的 bug 被提交上线。

结对编程

并没有人和我结对啊……

工作经验和舒适区

我不是很理解什么叫「舒适区」。不过我主动做的工作,要么能解决我当前面对的问题,或者是想要达成的目的,要么能让我学到有意思的东西。一直重复昨天的事,你们把这个叫「舒适」??

分享

这正是我正在做的事情呢。不过很可惜的是,我并不太会讲话,所以现在流行的直播我还是算了。写作还是比视频有意思,又省力、又能有深度,多好。

Category: 编程 | Tags: 编程 程序员 软件开发 随思 | Read Count: 11599
Max 说:
Jul 06, 2020 10:54:49 AM

结对编程才是最重要的

陌辞寒 说:
Jul 14, 2020 06:30:30 PM

感觉以类似鸡蛋里挑骨头的做法,我也可以写一个“读《品〈当我开始做软件开发时,最希望听到的七条建议〉》有感”。

## 读书

可能没什么人觉得机械工程并不是很大的话题,但对软件工程有偏见的人还是有很多的,比如认为几本书就能把软件工程讲得明明白白。如果软件工程如此易懂,最近几十年的很多大软件公司为什么一个个或壮烈或寂静地倒下了呢?有人会说这不是技术上的问题,但软件工程从来都不只和技术相关。而作者强调读一些软件工程的书,就是因为它容易被重视技术的软件开发人员所忽视。

作者并不是说不需要读技术方面的书,不用去关注理论和学术方面的东西,相反很多人都知道这些的重要性,反而无需特别强调。作者也没说软件工程方面光读书就可以了,无需实践。实践的重要性对软件开发人员来说同样属于常识,即使入门的编程书都会讲要自己敲代码练习而不是只看书。

## 编程语言

作者说应该学习两种编程语言,是对那些认为只学一门的人来说的。他们认为编程语言都大同小异,学明白一种,其他的照猫画虎就可以了。作者并没有说只能学两种,多学一种就是多余的。而且作者限定了“头两年”的时间,在两年里能学好两门编程语言就已经很难了(想想很多大学生四年过去了还不能灵活使用一门编程语言)。过了“头两年”自然想学什么学什么,作者自己也列出七种他用过的编程语言,显然并不排斥多学多用。

## 测试

作者当然知道它挺烦的,不然也不会说“你会讨厌它的”和“你会认为这是浪费时间”。“代码本身”,测试代码也是代码,测试代码出的问题也是问题。如果只把测试代码当二等公民,就很难享受到测试的好处了。维护代码肯定是需要成本的,这成本也不会白白流失,就像原文写的,“当这些测试捕捉到其他人没有注意到的错误时,……”。

如果一个人认为单元测试没用,他就不会仔细写测试代码,不会仔细想怎么提升测试代码的健壮性,以致于它很容易挂掉。那么单元测试对他来说就确实没什么用,因为他用实际行动促使了这个结果。

除了单元测试,还有很多可以帮人发现问题或者疏忽的方法(作者并没有说不存在这样的东西),但这些和单元测试并不冲突,也无法取代单元测试。

## 重构

如果“一份代码一直良好运行”就无需去管,那么相信自我感觉良好的人不会发现任何需要自己去管的代码,无论接手他代码的人如何控制想要大骂的冲动。对了,他们可能还会认为自己写的代码看起来都很舒服,别人看着不舒服,大概是他们的问题吧。

作者并没有说要为了重构而重构,也没有说代码还没能正确运行就得开始重构了(还在“构”中,何来“重”),更没有说重构后的代码可以不正确运行(那不是重构而是破坏吧)。

## 工作经验和舒适区

所谓的舒适区,不是指一个人感觉舒适他就在舒适区里。它特指一个人习惯了他熟悉的环境(不管实际上舒不舒适),不愿意去接触陌生领域的场景。比如一个人在工作中并不顺心,经常有烦心事,但毕竟他对这个环境很熟悉,不愿意换一个新环境接触新东西,他也把自己困在舒适区了。把舒适区称作适应区也许更好理解一些。

我好像自动跳过了几乎所有我同意的内容,好像那些内容并不存在。没错,现学现用,效果不好,见笑了。

Avatar_small
依云 说:
Jul 14, 2020 08:19:46 PM

对,软件工程是个大话题。然而作为开始,我的建议是先博后专,而不是相反。

只学一种就……不如转行吧。我没太注意到头两年,不过科班出身的话,学两门的时间应该很充分?新人就当我没说好了。至于那种大学四年还无法灵活使用一门编程语言的人,要么是太听话了所以没自己将之应用于学习之外,要么还是转行吧……

测试的维护成本挺高的,甚至不亚于项目本身。所以对于小项目,尤其是需求不稳定的项目,我还是倾向于把精力花在其它策略上。不同的策略之间是冲突的——它们都需要投入精力。另,如果一个人认为单元测试没用,他会让测试很不容易挂掉的……

「他们可能还会认为自己写的代码看起来都很舒服」,好吧,这种人我的确遇到了。但你让他重构,也只是让代码越来越怪异。

我的意思是,让重构中的代码也处于可运行的状态,而不是等到结束。因为通常大的重构会持续许多天,重构的时候想着「破而后立」,等要「立」的时候通常会发现代码跑不起来了,又要改。

「适应区」确实是一个更容易理解的说法。如果以这个意思来理解的话,那其实就是学无止境的意思了。

同意又没有补充的内容,当然直接跳过啦。同语反复还不如去给维基百科重写版权内容呢。

陌辞寒 说:
Jul 14, 2020 09:54:42 PM

我也挺讨厌单元测试的。而且很多时候是公司强制推行,用软件分析单测覆盖率,不达到百分之多少还不能提测。然后大家基本都应付了事,结果单测代码质量普遍不行,动不动就挂了,也基本不实用。等管得不严了,测试代码就被废弃了,白白浪费人力。

但有些场景它还是挺有用的。比如一个人最开始写一个功能时,基本会仔细思考各种异常情况,写对应的代码处理。但日后再看时,可能就忘了某些异常情况了,也许认为某段代码写得啰嗦,随手一改,清晰多了,结果就漏掉了某种异常情况的处理。如果他当时仔细写单测代码,覆盖了这种异常,那马上就会发现问题。增加功能或者调整逻辑时也同理,最初写的时候明明白白的事情,之后可能就忘了,不小心就改错了。

功能不稳定的情况确实不适合写单测代码,至少不是那么详细地写,但也得让自己的代码是好测的。

重构的坑我也感觉很深。以前我也维护过几个让我特别难受的模块,有些代码空格和 Tab 都是混用的,甚至怎么配置编辑器都看不齐。还有弄了两个类,一个 Task,一个 TaskManager,互相调用,功能放哪个类似乎看心情……这些基本也是代码能跑起来就行的后果,之后重构的人都提心吊胆的。

如果是特别棘手的情况,分次重构可能好些。第一次尽量把相互之间关系薄弱的部分拆开,接口理清楚了。之后重构就可以只针对某个细分的部分,就不会出现持续很多天的情况。但实际上大型的重构很难发生,因为直接收益不明显,得不到足够资源,即使大家经常修 bug,也没办法集中时间重构,这就不是技术上的问题了。我当时维护的好几个模块,最后都没有重构,后来在小修小补中熬到了下线。

其他的基本同意。

| Theme: Aeros 2.0 by TheBuckmaker.com