美文网首页
程序员修炼之道

程序员修炼之道

作者: 啥也不说了 | 来源:发表于2019-01-29 15:29 被阅读4次

    第1章 注重实效的哲学

    1 我的源码让猫给吃了


    在所有的弱点中,最大的弱点就是害怕暴露弱点
    ——J. B. Bossuet,Politics from Holy Writ,1709


    为你自己和你的行为负责的这一观念,是注重实效哲学的一块基石。 注重实效的程序员对他自己的职业生涯负责,并且不害怕承认无知或错误。这是说在出了问题的时候我们必须诚实和坦率——可以为成绩和能力自豪,也必须对无知和错误诚实。

    负责

    责任是你主动担负的东西。
    你承诺确保某件事情正确完成,但是你不一定能直接控制事情的每一个方面。这里面有两点:1)超出了自己控制范围的风险,有权不去为之负责;2)确实同意要为某件事情负责,就应切实负起责任。
    如果是自己需要负责的事情出现了风险,应该提供各种选择而不是寻找蹩脚的借口。如果一定要说,就先对你的猫说。没有解决方案的借口没有任何好处,还会影响在别人心中的形象。

    2. 软件的熵

    不要容忍破窗户

    通过不容忍”破窗户“的方式来控制软件系统的熵。

    灭火

    优秀完整的代码,及时灭火的时候大家也不想弄脏他。所以不仅不要破窗,还要保持窗户的干净整洁。

    3. 石头汤与煮青蛙

    石头汤是指”3个士兵通过煮石头调动了周围村民的热情,齐心合力的做了一顿最好吃的饭“。煮青蛙是指”任谁煮青蛙“。
    煮石头的故事首先告诉大家如何去调动资源。通过核心人物、事情做出成果,然后吸引更多的人来加入。要做变化的催化剂,在这个过程中,可以考虑”请求原谅比获取许可更容易“。
    与煮青蛙相比,煮石头对村民是带了了好处。但是很多时候煮青蛙式的变化,会导致人民忽略变化,而使事物发展超出控制。所以在起变化催化剂的时候,需要关注大图景

    起变化的催化剂,但是不要像青蛙一样,要留心大图景。要持续观察周围发生的事情,而不只是你自己在做的事情。

    4.足够好的软件


    欲求更好,常把好事变糟。
    ——李尔王 1.4


    让你的用户参与权衡

    1. 系统的范围和质量应该作为系统需求的一部分规定下来。

    使质量成为需求问题。

    知道何时止步

    不要因为过度修饰和过于求精而损坏完好的程序,让你的代码凭着自己的质量站立一会。

    5. 你的知识资产


    知识上的投资总能得到最好的回报。
    ——本杰明·富兰克林


    知识是一种资产,但是它是一种有时效性的资产。随着你的知识的价值降低,对你的公司或者客户来说,你的价值也在降低。

    你的知识资产

    关于计算技术和所工作的应用领域的全部事实、以及他们的所有经验视为他们的知识资产。

    可以发现程序员的知识资产分为3中:1)计算机相关技术;2)在某个业务领域的知识;3)其他的经验等技能。所以不能把资产只看做技术这一块。

    管理知识资产和管理金融资产非常相似:

    1. 严肃的投资者定期投资——作为习惯。
    2. 多元化是长期成功的关键。
    3. 聪明的投资者在保守投资和高风险、高回报的投资之间平衡他们的资产。
    4. 投资者设法低买高卖,以获取最大回报。
    5. 应周期性的重新评估和平衡资产。

    经营你的资产

    • 定期投资。必须定期投资,即使投资了很小习惯自身也和总量一样重要。
    • 多元化。你知道的不同事情越多,你就越有价值。底线是你需要知道你目前所用的特定技术的各种特性。但是不要止步,掌握的技术越多,越能更好的进行调整——不会信息过载,更好的可以赶上变化。
    • 管理风险。
    • 低买高卖。在新技术刚出现的时候学习它可能和找到被低估的股票一样困难。
    • 重新评估和平衡。计算机是一个非常动荡变化的行业,所以需要及时评估。

    定期为你的知识资产投资。

    目标

    前面介绍了何时以及增加什么到你的知识资产中 ,现在你已经拥有了一些指导方针,那么什么是获得智力资本、从而为你的资产提供资金的最佳方式呢?这里有一些建议。

    • 每年至少学习一种新语言。不同语言以不同的方式解决着相同的问题。通过学习不同的方法,可以帮助你扩宽思维,并避免墨守成规。
    • 每季阅读一本技术书籍。刚开始阅读与项目有关的书籍,后续拓宽范围阅读一些与你项目无关的书籍。
    • 也要阅读非技术书籍。记住计算机是由人——你在设法满足需求的人——使用的,这十分重要。不要忘了等式中人这一边。

    这个点非常重要,以人为本。

    • 上课。在学院、大学或者展会上寻找有趣的课程。
    • 参加本地用户组织。不要只是去听听,而是要参与。与世隔绝对你的职业生涯可能是致命的,打听一下你们公司以外的人都在做什么。
    • 试验不同的环境。用惯了windows可以换个Linux等。
    • 跟上潮流。订阅商务杂志和其他期刊。选择所涵盖的技术与你当前的项目不同的刊物。
    • 上网。

    持续投入非常重要。要把学到的知识进行使用,及时没有使用该技术也可以借鉴一些想法,思想的“异化授粉”非常重要。

    学习的机会

    即使站在了所有突破性进展的前沿,当别人问你问题你却回答不上来时,也需要坦然承认,然后去寻找答案。
    可能自己通过上网、图书馆等无法找到问题,但是一定有人可以知道答案。
    在学习上面,不仅不能止步,而且还要随时学习。

    批判的思考

    批判性的思考你读到的和听到的,你需要确保你的资产中的知识是准确的,并且没有收到供应商和媒体操作的影响。

    **批判地分析你读到的和听到的,要为自己的知识资产负责。

    6 交流


    我相信,被打量比被忽略要好。


    问题不是你有什么,而是看你怎样包装它。

    知道你想要说什么

    先梳理好大纲,问自己“这是否讲清了我要说的所有内容?”。而不是坐下来就写“1.介绍”。

    了解你的听众

    只有当你在传达信息时,你才是在交流。为此,你要了解听众的需要、兴趣、能力。
    图1.1显示WISDOM离合诗可能会有帮助。

    离合诗

    选择时机

    需要弄清楚听众的“轻重缓急”,这样才可以事半功倍。

    选择风格

    调整你的交流风格,让其适应你的听众。

    让文档美观

    你的注意很重要,它们应该以美观的方式传递给你的听众。

    让听众参与

    尝尝发现,与制作文档的过程相比,制作出的文档最后并没有那么重要。如果可能,让你的读者参与文档的早期草稿的制作。获取它们的反馈,汲取它们的智慧。

    做倾听者

    如果你想要大家听你说话,你必须使用一种方法:听他们说话。通过鼓励大家提问来交谈,或是让他们总结你告诉他们的东西。把会议变成对话,你将能更有效的阐明你的观点。

    回复他人

    你说什么和你怎么说同样重要。

    交流越有效,你就越有影响力。在回复他人时需要做到及时——即使是“稍后回复”,而且还要在发送前做检查,以达到准确。

    在发送前检查一定要做,尤其现在智能输入法的情况下,很容易出现错别字。如果平时聊天还好,在稍微重要的场合就非常尴尬。

    第2章 注重实效的途径

    7. 重复的危害

    因为知识会随着需求、环境、政策等的变动而变动,所以知识是不稳定的。当知识散落在应用的各处时,维护就是一场噩梦。

    系统中的每一项知识都必须具有单一、无歧义、权威的表示。要遵守“RRY”——不要重复你自己的原则。
    我刚开始对DRY原则的理解是不要做重复的事情,这样可以提高开发效率,忽略了其中最重要的一点:在有重复的情况下,发生变更的时候就是噩梦。

    重复是怎样发生的

    • 强加的重复。开发者觉得无可选择。
    • 无意的重复。开发者没有意识到他们在重复。
    • 无耐性的重复。开发者偷懒。
    • 开发者之间的重复。同一团队的人重复了同样的信息。

    强加的重复

    信息的多种表示。同一种信息被以多种方式表示,例如支持不同语言的代码,这种情况可以抽象成一个元数据,根据元数据用代码生成多语言信息。
    代码中的文档。程序员一直被要求写注释,但是没人告诉他们为什么写注释:糟糕的代码才需要注释。DRY原则告诉我们,低级知识放在代码中,把注释留给高级说明。
    文档与代码。例如需求变更之后,应该测试代码也需要发生变更。
    语言的问题。有些文件会在源码中强加客观的重复。

    无意的重复

    有时,重复来自设计中的错误。
    例如一个线段类如下:

    class Line{
      public:
        Point start;
        Point end;
        double length;
    }
    

    第一眼看上去,这个类似乎是合理的:一个线段有起点、终点和长度。但是长度是有起点和终点决定的,所以最好让长度是成为一个计算字段:

    class Line{
      public:
        Point start;
        Point end;
        double length(){
          return start.distanceTo(end);
        };
    }
    

    在以后的开发过程中,你可以因为性能原因而选择违反DRY原则。例如每次都计算length很耗费时间,可以使用字段进行存储。如下:

    class Line{
      private:
        bool changed;
        double length;
        Point start;
        Point end;
    
       public:
        void setStart(Point p){ 
          start=p;
          changed=true;
         }
    
        void setEnd(Point p){ 
          end=p;
          changed=true;
         }
    
        Point getStart(void)  {return start;}
        Point getEnd(void)  {return end;}
    
        double getLength(){
          if(changed){
            length = start.distanceTo(end);
            changed=false;
          }
          return length;
        };
    }
    

    这个例子说明了像Java或C++这样的面向对象语言的一个重要问题:在可能的情况下应该总是用访问器函数读写对象的属性,这将使未来增加功能(比如缓存)变得更容易。

    使用了访问器,那么类有没有这个私有属性不重要。即getLength()方法里面可以直接计算,也可以为了缓存增加length这个字段。
    这里特意强调是因为在写代码的时候用了lombok的注解,导致潜意识中把私有变量和访问器变成了对等的,实际上他们是完全可以独立的。

    8.正交性

    什么是正交性

    正交性是一个数学用语,在计算机中表示某种不相依赖性或解耦性。如果两个或更多事物中的一个发生变化,不会影响其他事物,这些事物就是正交的。

    正交的好处

    消除无关事物之间的影响

    我们要设计自足的组件:高内聚(独立、具有单一、良好的目的)。
    如果你编写正交的系统,有两个主要好处:提高生产率和降低风险。

    提高生产率

    • 改动得以局部化,所以开发时间和测试时间得以降低。
    • 正交的途径还能够促进复用。如果组件有明确而具体的、良好定义的责任,就可以用其最初实现着未曾想过的方式,把它们与新组件组合在一起。
    • 如果你对正交的组件进行组合,生产效率会有相当微妙的提高。例如做M件事的组件和其正交的做N件事的组件结合,那么就会有MxN件事情,如果非正交就有重合的部分。

    降低风险

    • 正交的途径能够降低任何开发中固有的风险。
    • 有问题的代码区域被隔离开来。某个模块有毛病,不会扩散到系统的其余部分。
    • 所得系统更健壮。对特定区域做出的改动与修正,所导致的任何问题都将局限在该区域中。
    • 正交系统很可能得到更好的测试。
    • 你不会与特定的供应商、产品或是平台紧绑在一起。

    项目团队

    设计

    不要依赖你无法控制的事物属性。

    工具箱与库

    引入工具箱和库的时候,要注意保持系统的正交性。

    编码

    • 让你的代码保持解耦。编写“羞怯”的代码——不会没有必要的向其他代码暴露任何事情、也不依赖其他模块的实现模块。
    • 避免使用全局数据。每当你使用全局数据时,它都会把自己与共享该数据的其他组件绑在了一起。
      单例模式是确保特定类的对象只有一个实例的一种途径,许多人也把singleton对象用作某种全局变量,使用时要小心,可能会造成不必要的关联。
    • 避免编写相似的函数。你常吃会遇到看起来全都很像的一组函数,使用策略模式。

    测试

    正交地设计和实现的系统也更易于测试,因为各个系统的各组件间的交互是形式化的和有限的,更多的系统测试可以在耽搁的模块级就行。

    9.可撤销性

    如果某个想法是你唯一的想法,再没有比这更危险的事情了。

    可撤销性

    不存在最终决策。要做到“中流换马”。

    灵活的架构

    灵活性不仅指代码,还有架构、供应商等等。
    如果你必须把大量的某些语句分布在代码中,该怎么办?把该需求放入到元数据,并且使用某种自动机制——例如Aspect——把必要的语句插入代码。可以自动插入就可以自动消除。

    10.曳光弹

    一种是在黑暗中通过精确计算得到位置击中目标;一种是用曳光弹。普通子弹可以击中的曳光弹也可以。

    黑暗中发光的代码

    用户对自己不清晰的时候,如果通过传统的方式把未知元素、各项需求、限定环境一一列举,那么工作量非常大。但是可以通过曳光弹得分方式,先动起来。

    • 用户能够及早看到能工作的东西。及早反馈。
    • 开发者构建了一个他们可以在其中能够工作的结构。
    • 你有一个集合平台。
    • 你有了可用于演示的东西。
    • 你将能够看到工作进展。

    相关文章

      网友评论

          本文标题:程序员修炼之道

          本文链接:https://www.haomeiwen.com/subject/mvnnjqtx.html