读书笔记1
程序员所应该遵循的实用主义原则。
我的源码让猫给吃了:出现错误时,要诚实,不要推诿或者找借口。要提供各种可能的解决方案与后果并与他人沟通,而不是提供借口。
软件的熵:这是著名的破窗户原理。项目中一个小的、无人料理的问题可能带来后续编码时的懈怠,从而造成更大的问题。不要容忍任何小的错误,解决它或至少打上TODO标签。
石头汤与煮青蛙:这个小节很有趣,它讲述了小的变化如何能渐进式地演变为大的变化。
一方面,在面对一个毫无生气的团体、试图催生积极的变化时,可以去做第一个带来改变的人。这样,就会有人随之作出改变。可能每个改变都非常微小,但可以渐变式地带来大的改变。
另一方面,不管是个人和团体都很容易对于小的改变疏忽大意。这意味着有些时候小的改变会在不经意间催生出巨大的改变。不管是有人恶意为之还是意外累积而成,小的坏习惯、坏改变可能会积累成很大的问题,而程序员又可能最后才看出问题来。
这里有一个有趣的问题。石头汤显示我们可以通过小的积极改变催生大的积极改变,而煮青蛙显示我们可能会被小的消极改变迷惑,而忽略了他们在催生大的消极改变。在个体试图催生变化时如何判断是哪一种,消极与积极的改变又以什么作为判断标准?
我以为,催生改变有些时候是有用的,但仅当团体已经死气沉沉、无法通过常规方式作出改变时。当一个团体活力旺盛时,不应用欺骗式的方式催生改变,而应该对所有改变保持警觉,并保持良好的沟通,保证大家时刻都知道自己在做什么。这同样适用于个人。
足够好的软件:完美的软件是不存在的,幸运的是我们只需要制作足够好的软件。判断软件是否“足够好”时要让用户需求加入判断。
你的知识资产:cs行业变化迅速,所以不应止步不前。只有对知识投资才能有回报。要定期学习新的东西,并学习多元化的知识、管理风险。本书建议了一个知识投资计划:
每年至少学习一种新语言;每季度阅读一本技术书籍;也要阅读非技术书籍;上课;参加本地用户组织;试验不同的环境;跟上潮流;上网。
学习过程中,遇到问题时,要作为挑战并积极地寻找解答。另外,学习时要养成批判性的思维,不要迷信任何知识(大概也包括这本书提供的知识)。
交流:交流非常有用,但要学会高效交流。注意这些问题:想清楚自己要说什么,了解自己的听众,选择时机、选择风格,让文档保持美观并让用户加入文档的编写,也要倾听并回应他人。
读书笔记2
程序需要遵守的实用主义原则。
重复的危害:如果某个事物在代码中重复多次,就可能会在维护过程中带来问题,因为改动了一处而忘记改动另一处造成自相矛盾。这加大了维护难度。要遵守DRY原则,即Don’t repeat yourself。
重复通常由这些东西引起:
强加的重复,由文档或用户需求决定。这通常可以依照情况消除。需要重复表示的信息可以用元数据schema与代码生成器消除重复。注释与代码会重复,但实际上这种重复没有必要:注释不应重复代码中显而易见的东西,而应该表达更高级的东西。文档与代码也会重复,可以利用文档生成工具。有些语言会强加一些重复,这比较难解决,只能依情况而定,一些基本的技术是cpp中不要在其他文件中引用函数,而应该使用头文件。
无意的重复,由设计的疏忽造成,需要积极的检查和重构。如果为了性能需要违反DRY原则,记得将重复本地化,不要泄漏到模块外,并保持模块内行为良好。
无耐性的重复,可能造成远大于一时麻烦的痛苦后果。程序员要学会约束自己。
开发者之间的重复,需要加强开发者之间的沟通。
正交性:指系统各同层次的组件之间没有依赖关系,改变一个不影响另一个。如果系统不符合正交性,测试与维护会非常痛苦。而正交性的系统在出问题时更容易隔离修复,进行拓展时也不必改动已有模块,增加了生产力。
为了达到正交性,需要将团队分为几个清晰的小组分别工作,对系统进行模块化的设计。可以通过询问“讨论某个改动时需要设计多少人”判断小组分工是否正交,通过询问“改动某个模块背后的需求,会有多少模块受到影响?”判断系统设计是否正交。
引入第三方库时可能会破坏正交性,要小心不要使第三方库对整体代码造成改动。如果第三方库的接口存在问题,可以将第三方库用适合自己代码的方式进行封装。
编码也有可能破坏正交性,需要注意:使代码保持解耦,除了需要的功能不要暴露其它细节。避免使用全局数据。避免编写相似的函数。
对项目进行测试与debug也可以检查项目的正交性。如果测试或修正一个小模块会带来许多其它的影响,那么系统不够正交。
正交性同样适用于文档,文档内容与表达形式应该解耦。这让我想到了markdown……
可撤销性:许多需求会改变,许多政策会改变,所以编写项目时任何决策都应该可以撤销。项目结构应该保持灵活,不要依赖某个已有决策。
曳光弹:这个比喻有点晦涩。作者介绍了一种方法,编码之初先搭建一个大致框架,然后慢慢填充编码。这样既可以方便编码,又可以随时与用户沟通项目是否符合他们的需求。假如现有成果不符合需求,可以立马进行修改,而不必等代码基本固定时候再进行重构。
原型与便笺:不同于曳光弹,曳光弹在使用之后继续保留,只是逐渐“生长”成更完整的系统。原型是为了分析某个功能或需求建立的简化模型,将细节遮蔽以方便分析,用来找到最好的实现方式,然后便丢弃不用。如分析UI需求时先用绘图板确定最合适的UI,再用编码实现。
领域语言:任何领域都有自己的语言,如用于配制的语言,用于文档的语言,用于描述需求的语言。可以发展一种小型语言。小型语言分两种,配置语言方便解析但难以阅读,命令语言相当于小型的脚本语言,更近似于自然语言,但解析难度更高。小型语言可以是独立的语言,也可以嵌入高级语言的代码,方便直接执行。
这是一个非常有趣的设想,然而很可惜,在我们的项目中,受限于我们的项目规模,这个设想不太可行。然而这给了我两个启发:
1. 进行编程时,首先将用户需求抽象化。用户需求常常是用自然语言表达的,通常包含许多复杂的要求,如在某些情况下将某个数据传输到另一个服务器,在某些情况下丢弃数据,在某些情况下反馈警告等。直接试图将自然语言描述的需求转化成代码很可能会非常困难,这时候先将需求抽象成一个无关具体细节实现的逻辑框架会更容易,不管是流程框图、伪代码还是别的什么。这也是自顶而下的思想。
2. 很多时候编写代码需要满足的需求并不是用户的,而是直接对接的下一层的需求。比如负责数据库层的程序员可能需要满足负责算法层的程序员的需求。在这种情况下,交流时需要尽量良好地描述需求的逻辑。这也需要清晰的层与层之间的接口以及风格良好的文档。
3. 模块与模块之间的信息交流需要清晰、易于解析并易于扩展。
估算:要学会估算。估算的方法在于限定问题的情景范围,对系统建立模型,对模块进行拆分并分别估算,抹去可忽略不计的量。估算不需要过于精确,但需要细心。
标签:需求,语言,读书笔记,重复,正交,改变,文档 From: https://www.cnblogs.com/zyzyzrp/p/16746503.html