精华内容
下载资源
问答
  • 本篇文章是对《程序员修炼之道:从小工专家》一书的总结和解读。 该书作者是 Andrew Hunt 和 David Thomas。他们都是敏捷宣言的17个创始者之一。Andrew还是敏捷联盟(Agile Alliance)的创始人。David 则是著名的 ...

    本篇文章是对《程序员修炼之道:从小工到专家》一书的总结和解读。

    该书作者是 Andrew Hunt 和 David Thomas。他们都是敏捷宣言的17个创始者之一。Andrew还是敏捷联盟(Agile Alliance)的创始人。David 则是著名的 DRY(Don’t Repease Yourself) 一词的发明者。这本书也广泛出现在各类计算机推荐书单之中,其受欢迎程度不言自明。

    该书目前有两个版本,我阅读的是第一版:

    在这里插入图片描述

    第二版是这样的:

    在这里插入图片描述

    两版内容稍有不同。

    刚毕业那会读过一遍,但有很多地方没看明白,感觉云里雾里的。今年在制定每天的阅读分享计划时一下就想到了它,结合一定的工作经验再次阅读这本书,然后对每个章节都进行思考和总结,感觉才算是挖掘出了它的价值。这本书写作时间虽然比较久了(初版1999年),里面引用的一些语言,一些技术框架都已经很少使用甚至过时了,但本书强调的如何做一名注重实效的程序员,及众多建议却不会过时。

    以下内容是对各个章节的总结,篇幅有些长,12000+ 字,大家可以按顺序或者按自己感兴趣的章节进行阅读。

    第一节:我的源码让猫给吃了。
    1、开发过程中出现未曾预料的技术问题,交付晚了等情况,没关系,这些是无法避免的。发生了,我们就要尽可能想方设法地职业的去处理它们。程序员这个职业需要诚实和坦率,要敢于承认自己的错误。

    2、要对担负的东西负责,如果某些东西真的超出了你的控制范围可以不处理,需要尽早提出这个不可控的点。自己职责所在的事情就需要为其结果负责。当结果不达标,比如磁盘垮了,但你却没有备份代码,那这就是你的错。不要为出错的情况找借口,想老板说"我的源码让猫给吃了”,对问题没有任何帮助,而要向他们提供可行的解决方案,做什么能够最大的挽回局面。

    第二节:软件的熵
    1、熵是一个热力学概念,指的是在某个系统中的“无序”的总量,热力学定律指出宇宙中的熵总是倾向于最大化。软件工程里中也存在这么一个定律,工程越庞大,代码的“无序”状态越严重。
    2、破窗理论指出,当一个东西本身就破旧时,不但没人爱惜,还会朝他仍石头,导致更多破窗。软件开发中也一样,如果我们项目留有很多“破窗户”(低劣的设计、错误的决策、糟糕的代码),之后接手的人也会倾向于是它变得更糟糕。如果代码很漂亮,你自己以及之后接手的人,都可能会格外注意,不把它弄脏的。所以我们应该尽早处理工程中遗留的问题。
    第三节:石头汤和煮青蛙
    1、三个士兵返乡,路上饿了,路过一个村子,想跟村民借点吃的,但村民粮食贫乏不愿意出借。士兵们没有气馁,他们煮开了一锅水,往里面放了几块石头。村民好奇为他们在干嘛,士兵解释,这叫石头汤,如果能放点胡萝卜的话会更好喝。村民跑回家拿来了胡萝卜,士兵说如果放些土豆会更美味,又有人跑回家带来了土豆。后面又有人加了别的东西,最后士兵和大家一起吃了一顿饱饭。

    2、有时候你确切的知道自己需要什么以及怎么做,但请求许可这件事往往会遭遇拖延和漠然,每个人都会护卫他们自己的资源,这让事情变得复杂,这叫“启动杂役”(start-up fatigue)。这时候我们不应该等着所有事情都准备好,而应该先拿出“石头”煮起来,就是想让事情启动起来。只要是有益的事情,你把做出的一部分结果拿给别人看,然后告诉他们如果加的别的什么会更好,大家一般都会帮忙的。

    第四节:足够好的软件
    1、使质量成为需求问题。很多时候对于质量的评估都是开发人员在进行,我们对质量要求低,交付时会出现很多问题,我们对质量要求高,会很大程度延误工期。所以指定需求时,把质量这一块考虑进去,在商定的时间内,由产品或者客户决定他们可以接受的质量是什么样的。

    2、没有完美的软件,应该知道何时止步。今天了不起的软件常常比明天的完美软件更可取。及早让客户使用,他们的反馈常常会把你引向更好的解决方案。

    第五节:你的知识资产
    1、本杰明·富兰克林说过:知识上的投资总能得到最好的回报。这没问题,但遗憾的是知识是有时效的资产,特别是计算机领域。我们可以把我们了解的技术实现、工作经验视为知识资产,并使用管理金融资产的形式管理这些知识。

    2、经营知识资产可以从以下方面进行:

    定期投资:定期投入时间学习,即使很小的投资也是很重要的。

    多元化:作为底线我们需要对当前所从事的技术熟练掌握。但不要就此止步,技术的发展变化很快,掌握的知识越多,就越能更好的进行调整,赶上变化。

    管理风险:不要把所有的“技术鸡蛋”放到一个篮子里。

    低买高卖:新技术流行之前就掌握它往往比之后跟风再学得到更大的回报。

    这些知道方针里最重要也是最简单的就是:定期为你的知识资产投资。

    3、具体方案介绍

    每年至少学习一种新语言。

    每季度阅读一本技术书籍,习惯之后可以一个月就阅读一本。

    也要阅读非技术书籍,记住计算机是由人使用的。

    在本地大学或者网上系统地学一门课程。

    体验不同的环境,如果你只在 Windows 上工作,可以试下 Unix。如果你只使用某一种 IDE 那可以试试其他 IDE。

    第六节:交流
    1、知道你想要说什么

    当我们面临会议,重要通话,或者只是撰写技术文档,问下自己你要表达的中心想法是什么,围绕这一点进行展开。

    2、了解你的听众

    比如你要做一场分享,你可以按照 WISDOM 的形式思考这几个问题:

    你想让他们学到什么

    他们对你讲的什么内容感兴趣

    他们有多富有经验

    他们需要多少细节

    你想要谁拥有这些信息

    你如何促使他们听你说话

    3、选择风格

    传达一个消息,可以是正式的邮件,黑板上的绘图,口头描述,及时消息,选一个适合你的目的的方式。

    4、让文档美观

    技术文档不光要注意内容也要注意形式,使用 LaTeX 或者 Markdown 进行排版。

    5、让听众参与

    引导他们提问,以问答的形式推进分享进程。

    6、回复他人

    你说什么和你怎么说同样重要。尽量不要忽视别人的询问,即使回复他们稍后再联系都会更好一些。

    第七节:重复的危害
    1、可靠的开发软件,并让我们的开发更易于理解和维护的唯一途径,是遵循我们称之为 DRY 的原则:系统中的每一项都必须具有单一、无歧义、权威的表示。

    DRY 是 Dont’t Repeat Yourself 的缩写。

    2、重复的产生通常有以下种类:

    强加的重复。开发者觉得他们无可选择,其实是有一些方法让我们避免重复的。

    无意的重复。开发者没有意识到他们在重复信息。这个需要通过提高代码意识或者 CR 进行减少。

    无耐性的重复。开发者偷懒,因为重复可以让事情更容易。有时往往会遇速则不达,在这类重复面前我们应该更慎重。

    开发者之间的重复。同一个团队或者不同团队的几个人重复了同样的信息。需要一个统筹的人引导大家交流,提供一个中央区域,管理维护公共代码。

    第八节:正交性
    1、正交性是一个从几何学中借鉴而来的术语,如果两条直线相交成直角,他们就是正交的。这在向量中的解释是沿着一条直线移动,你投影到另一条直线上的位置不变。

    在计算机中,该术语用于表示某种不相依赖性或解耦性。

    2、正交的好处是它提高生产效率,各个组件不相互依赖,使得改变得以局部化,促进复用,对于正交组件进行组合也可以提高生产效率,同时它还降低了代码的风险。

    3、延伸开来,项目团队的配合也应该遵循正交性。如果成员之间任务重叠较多容易让大家疑惑问题和责任的归属如何划分,这会造成配合的效率低下。

    代码设计的时候也应该尽可能考虑正交性,这需要结合一些特定的设计模式以达成目的。

    第九节:可撤销性
    如果某个想法是你唯一的想法,再没有什么比这更危险的事情了。在设计软件时,我们需要为可能出现的某种错误做准备,比如数据库的更换,开发平台的更换。这需要我们设计之初就考虑到构建一个相对灵活的架构。

    第十节:曳(ye)光弹
    1、在黑暗中使用机枪射击有两种方式。

    方式一:你需要知道目标准确的位置,然后考虑当时的温度、湿度、气压、风力等一系列因素,计算完位置之后进行射击。

    方式二:使用曳光弹,发射时,曳光弹中的磷点燃,会照亮它经过的地方和最终位置,我们用曳光弹确认位置之后,就不需要那些繁杂的计算,直接使用机枪进行射击。

    2、在黑暗中发光的代码。通常一个项目的开发是非常复杂的,如果只是一个模块一个模块的开发,我们可能直到最后才能确认项目运行情况。更好的做法是,我们要让系统尽早的跑起来,然后根据需要给它完善细节。这样会有以下好处:

    用户能够及早看到能工作的东西。

    开发者构建了一个能在其中工作的结构。

    你有了可用于演示的东西。

    你能够感觉到工作进展。

    第11节:原型与便笺
    1、原型是你可以在忽略细节的情况下,考虑项目走流程,主要使用场景,他们是否正确,是否可行。通常也可以用用于演示

    2、原型制作是一种学习经验,其价值并不在于所产生的代码,而在于所学到的经验教训。那才是原型制作的要点所在。

    3、制作原型甚至不需要编码,你可以用便笺,白板上制作原型。制作原型时你需要尝试回答以下问题:

    主要组件的责任是否得到了良好定义?是否恰当?

    主要组件间的协作是否得到了良好的定义?

    耦合是否得以最小化?

    你能否克服确认重复的潜在来源?

    接口定义和各项约束是否可接受?

    第12节 领域语言
    1、计算机语言会影响你思考问题的方式,以及你看待交流的方式。

    2、领域语言通常是为了简化流程,用于配置或者控制应用程序。

    3、DSL 可以理解为一个小型语言,它可以是扩展自已有语言。

    4、在设计一种 DSL 时,考虑可读性还是简单性时,主要权衡的应该是可扩展性和可维护性,因为通常大多数应用都会超出预期的使用期限。

    第13节 估算
    1、通过学习估算,并将此技能发展到事物的数量级有直觉的程度,你就能展现出一种魔法般的能力,确定他们的可行性。

    2、多准确才足够准确?130 个工作日和大概 6 个月,是不同的,显然,前者表示的精度更高。我们在做估算的时候也需要选好描述估算时间的单位值。

    3、估算结果怎么来呢。

    首先需要确认你是否理解了需求所涉及的各个方面,这个是前置条件。

    然后你需要建立系统模型,在这个系统中,把模型分拆成各个组件,然后给每个参数设置定一个值,最后根据模型计算一个时间。

    4、模型应该是一个动态的,它像一个人工智能模型,你需要持续不断的训练它,才能使它真正准确起来。每次的估算都需要记录,反思估算效果,找出影响因素,加入新的影响项或者调整对应参数。

    5、被要求进行估算时间时,我们可以这样回答:我等会儿回答你。然后花点时间仔细检查我们在这一节描述的步骤,你总能得到更好的结果。

    第14节 纯文本的威力
    本节是第三章:基本工具,首节内容,章节介绍里有一句话:

    许多新程序员都会犯下错误,采用单一的强力工具,比如特定的集成开发环境(IDE),而且再也不离开其舒适的界面。这实在是一个错误。我们要乐于超越IDE所施加的各种限制。要做到这一点,唯一的途径是保持基本工具集的“锋利”与就绪。

    1、纯本文由可打印字符组成,人可以直接阅读和理解其形式。

    这里强调可打印含义是字符时经过编码的可阅读字符,而不是二进制。这在现在看来几乎是不用争辩的,谁还会用二进制存储信息,但当时计算机算力和存储都有限,纯文本会占据更多空间,解码会耗费算力。但源于技术的发展,这些都是可以忽略不计了。

    2、纯文本的优点之一:保证不过时。这一点需要我们扩展纯文本能够自描述。自描述的含义是它自己能告诉我们它的含义。

    123-45-6789

    123-45-6789
    上面的例子中下面一条就是自描述的,我们能通过 SSNO 推断出这里存的就是社会保障号,另外根据 这一标记我们可以很轻松的将对应内容提取出来。

    3、另外两个优点是杠杆作用和更易于测试。这里说的是我们可以利用各种工具 diff、fc、git,或一些语言例如 Python 等对纯文本进行各种调整和查看工作。

    第15节 Shell 游戏
    1、对于操纵文本的文件的程序员,命令 Shell 就是工作台。我们可以利用 Shell 启动各种应用、搜索文件、查询系统状态,甚至还可以构建复杂的宏命令,完成各种常见活动。

    2、对于习惯 GUI 的开发者来说一直使用 Shell 有些极端。GUI 的好处是所见即所得,但他的缺点却是,所见即全部所得。GUI 环境通常受限于它们的设计者想要提供的能力。

    3、比如我们想要做一件事:在一个代码仓库里,查找上周没有修改过的,使用了 awt 库的 java 文件。

    如果使用Shell,可以执行:

    find . -name ‘*.java’ -mtime +7 -print | xargs grep ‘java.awt’
    如果使用 GUI,你可以设想一下,这个过程会很麻烦,也很容易出错。

    4、Shell 可能比较晦涩,但是掌握之后它能很大程度提高你的效率。Shell 可以做各种组合搭配,然后构建一个命令序列,让常做的事情自动化。

    第16节 强力编辑器
    1、我们认为你最好是精通一种编辑器,并将其用于所有编辑任务:代码、文档、备忘录、系统管理等等。

    进行编辑活动时,你不必停下来思考怎样完成文本操作,编辑器将成为你双手的延伸,键会在滑过文本和思想时歌唱起来。

    这就是我们的目标。

    2、好的编辑器应该具有这些特性:可配置、可扩展、可编程、语法突显、自动缩进、类IDE特性。

    3、编辑器对生产效率是有影响的。试想当我们需要一个字符一个字符或者一行一行移动时,按一次键,就以词,行,块的单位移动,显然效率更高。

    4、然后做什么。选一种强大的编辑器,好好学习它。不断学习,减少你敲击的次数。设法扩展它,让它能胜任更多任务。

    推荐两款编辑器:vim、Emacs

    第17节 源码控制
    1、原谅我们犯错的按钮是 UNDO 键,通常他们还支持多级 UNDO 和 REDO。而源码控制系统就相当于一个巨大的 UNDO 键,一个项目级的时间机器。源码控制系统(SCCS)能够追踪你在源码和文档中做的每一项改动。

    2、应该总是使用源码控制,即使团队只有你一人,即使项目很小。

    3、可以尝试的源码控制系统有 CSV、RCS、ClearCase 等。(那时 Git 还没流行起来)

    第18节:调试
    1、调试心理学。调试的目的是解决问题,不要因为别人提出 bug 而发起进攻。

    2、当你目睹 bug 发生或者看到 bug 报告时,第一反应不要是“那不可能”。很明显已经发生了,把时间用在思考它为什么产生上面。

    3、使数据可视化。例如循环引用问题,如果可视化的话可以很轻易地进行排查。

    4、跟踪代码。发生 crash 我们能够查看系统的调用堆栈,但这些数据不一定够。对于非 crash 类错误,因为没有抛出,我们甚至不知道发生了什么。所以添加所谓的跟踪日志很有必要,这类日志最好采用统一规范,便于后期我们可以自动解析他们。

    5、橡皮鸭,也叫小黄鸭调试法。遇到无法定位的问题时,对着小黄鸭(屏幕)解释自己的实现逻辑,很可能在说的过程中你自己就发现了问题所在。

    6、不要第一时间怀疑 OS,IDE,三方库的问题,他们出问题的概率比你代码出问题概率小得多。我们应该首先确认和排查自己的问题。

    7、对 bug 原因进行复盘。修复了一个 bug,不要就让它结束了,想一下,为什么它会出现了,如何避免。定位过程如果耗时较长,也需要复盘下为何花费了那么长时间,以及后续如何优化。

    第19节 文本操纵
    1、学习一种文本操纵语言。文本操作语言对于编程的意义,就像是刳刨机对于木工活的意义。

    2、文本操作的案例。

    我们的测试数据有好几万条,散落在不同文件,如果需要进行合并并转换为特定格式,手动处理是无法想象的。但如果使用 Perl 几个小时就可以完成。

    数据库 schema 维护。可以写一组 Perl 脚本读取数据库 schema 定义的纯文本文件,根据它生成,用于创建数据库的 SQL 语句。schema 的 XML 版本等

    生成 web 文档。可以编写 Perl 程序,分析数据库 schema,C 或 C++ 源文件,及其他资源,生成 HTML 文档。

    文中很多案例使用 Perl,这些工作也可以使用 Python 代替或者 Shell 里的 awk,sed 代替。

    第20节 代码生成器
    1、作为程序员,有时会需要我们在不同地方重复相同信息。如果出现这种情况,你就可以考虑构建代码生成器了。代码生成器就是编写能编写代码的程序。

    2、有两类代码生成器:被动代码生成器和主动代码生成器。

    3、被动代码生成器是独立执行的。它可以用来生成模板,版权声明,每个新文件的标准注释等等。

    4、主动代码生成器会在每次需要其结果时被使用。比如根据数据库 schema 创建代码。

    5、代码生成器不一定要生成代码,它可以用来输出任何格式的内容,比如 HTML、XML、纯文本等。

    比如 iOS 里的三方库 R.Swift[1] 就是一个根据资源名自动生成对应结构体的主动代码生成器。

    第21节 按合约设计
    1、注重实效的程序员会不信任自己,所以他们针对自己的错误行为进行防卫性编码。

    2、按合约设计(Design By Contract,简写DBC)是 Bertrand Meyer 为 Eiffel 语言发展的概念。它的核心是用文档记载模块的权利与责任,并进行校验。它的目的是对函数做一些前置检查和后置保证,结合编译器的支持,我们能够尽早的发现代码问题。

    3、DBC 有三个概念。

    前条件:为了调用例程必须为真的条件。

    后条件:例程保证会做的事情,其完成时的状态。

    类不变项:其确保从调用者的视角来看,该条件总是为真。

    4、Java 中的 iContract 框架是专为 DBC 设计的,它通过注释里的 @pre、@post、@invariant 声明这三个概念。它会读取注释并生成包含断言逻辑的源文件。Eiffel 则是通过 require、ensure、is 三个值表示对应概念。但是支持 DBC 的语言真的很少。

    第22节:死程序不说谎
    1、对待程序我们通常会有“它不会发生”的心理状态,这会导致我们忽视一些问题。对于注重实效的程序员来说,如果我们忽略了一个错误,将是非常糟糕的事情。

    2、我们一些异常情况,我们应该及早崩溃,用于强调问题的存在。

    3、引起崩溃的时候不要造成破坏,比如申请的资源还没有释放等情况。

    4、死程序带来的额危害通常比有隐患的程序要小得多。

    第23节 断言式编程
    1、如果它不可能发生,用断言确保它不会发生。

    assert(string != NULL)
    断言里写的为真的条件,当不为真时触发断言,程序退出。

    2、断言检查的是决不应该发生的事情,而不是错误处理。

    3、断言应该一直开着,不要在线上环境关掉它。

    断言对应的是一种强提示,它迫使我们必须遵守。像是单元测试,我们通常都使用断言的形式进行检查。

    第24节 何时使用异常
    1、异常很少应作为程序的正常流程的一部分使用,异常应该保留给意外情况。如果移除了所有的异常处理器,代码就无法运行,那说明异常正在被用于非异常情况中。

    2、是否应该使用异常取决于实际情况。比如打开文件,文件不存在,是否应该发生异常?如果文件应该在那里,那么异常就有正当理由。如果不确定文件是否在那里,返回错误就可以了。

    第25节 怎样配平资源
    1、对于资源(内存、事务、现成、文件、定时器等)的管理要有始有终,你分配了对应的资源,就需要考虑对应的解除逻辑。要有始有终。

    2、嵌套的资源分配,应该使用与分配次序相反的顺序进行解除。

    3、异常的配平需要避免违反 DRY 原则。例如文件打开的异常情况,会导致 try…catch 有两条路径,那如何避免在正常流程和 catch 流程都处理 error 情况呢?C++ 可以依赖对象自动析构的特性,Java 可以依赖 finally子句。

    4、当无法配平资源时,需要设定一个规则,决定谁为某个聚集数据结构中的数据负责,以及如何负责。这里有点类似引用计数方案,无引用时释放。

    5、自动化检查资源配平状态,可以依赖一些三方工具。

    第26节 解耦与得墨忒(tei)耳法则
    1、把你的代码组织成最小单位(模块),并限制他们之间的交互。如果随后必须替换某个模块,其他模块仍能够继续工作。

    2、应使耦合减至最少。对象间直接的横贯关系,有可能很快带来依赖关系的组合爆炸。比如对某个模块的“简单”改动会传遍系统中的一些无关模块。

    3、函数的得墨忒耳法则,它规定了某个对象的任何方式都应该只调用属于以下情形的方法:

    它自身

    传入该方法的任何参数

    它创建的任何对象

    任何直接持有的组件对象

    4、得墨忒耳法则的好处是它使得代码的适用性更好,更健壮,但这也有一定的代价。如果某些解耦的操作很复杂,或者解耦带来某些时间和空间的重大开销,这时就需要根据实际情况考虑,可以暂时舍弃该法则。

    第27节 元程序设计
    1、元数据是关于数据的数据,即对应用进行描述的数据。典型情况,元数据在运行时,而不是编译时被访问和使用。

    2、我们想要让我们的系统变得高度可配置,像是屏幕颜色,提示文本等,这些应该作为配置项而不是作为代码集成到项目中。

    3、以声明方式思考(规定要做什么,而不是怎么做),并创建高度灵活的可适应的程序。结合元数据就是,将抽象放进代码,细节放进元数据。

    4、Enterprise Java Beans 是一个用于简化分布式、基于事务的环境中的编程框架。它处理了不同机器、在不同数据库供应商之间,不同线程及复杂平衡的事务。它的使用只需我们编写一个 bean,并将其放到 bean container 中。

    5、更好的协作式配置是让应用自身适应其环境,进行动态配置。

    第28节 时间耦合
    1、时间耦合就是关于时间的各种事项。

    2、软件设计中,时间的角色通常有两方面对我们来说很重要:并发(事情同一时间发生)、次序(事情在时间中的相对位置)。我们期望的是要容许并发,并考虑解除任何时间次序上的依赖。

    3、可以选择使用 UML 活动图进行工作流分析,以改善其并发性。

    4、在设计架构时,用服务进行设计而不是组件。饥饿的消费者模型是在多个消费者进程间进行快速而粗糙的负载平衡的一种有效途径。

    5、编写线性代码,我们很容易做出一些假定,把我们引向不整洁的编程。但并发会迫使你更仔细的对事情进行思考。

    6、尽可能使用线程安全的类,开发时也应尽可能设计线程安全的类。

    第29节 它只是视图
    1、我们都知道应该将程序分而治之,划分成不同模块。这里模块(或类)的定义是,具有单一的定义良好的责任。那如何在不同模块之间进行通信,处理事件呢?有以下两种方式。

    2、发布/订阅模式,又叫 Observer(观察者)模式。它的工作模式是,由订阅者 Subscriber 向发布者 Publisher 进行注册,注册之后,Publisher 的事件会通知到 Subscriber。未注册和解除注册将不会收到之后的事件通知。

    3、Model-View-Controller 是一种将模型与表示模型的 GUI 分离的架构模型,它能有效降低数据和视图之间的相互影响。

    第30节 黑板
    1、设想侦探破案的过程,他借助于一块黑板,把不同线索写出来;其他侦探也可以写下自己的推断和已掌握的案情细节。所有这一切串联起来将共同帮助案件侦破,但不同的线索之间是可以独立进行的。

    2、这里的黑板可以抽象为一种处理事件的模型。不同于原始的工作流需要考虑各种状况,不同组合,先后顺序等,黑板系统只管写入,读取,查询,通知等基础功能,任意符合条件的事件都可以进入这个系统。

    3、黑板模型也是一种解耦形式。

    第31节 靠巧合编程
    从本节开始进入书目的第6章,本章主要讲在编码时应该注意的各类事项。传统智慧认为,项目一旦进入编码阶段,工作主要就是机械的把设计转换成可执行语句。我们认为,这种态度是许多程序丑陋、结构糟糕、不可维护的最大一个原因。编码不是机械工作,要想让程序长久无误的运行,每一分钟都需要做出决策,且需要对这些决策进行仔细的思考和判断。

    1、靠巧合编程即代码正好是可运行的,至于为什么能够正常运行,却不清楚。这是我们应该极力避免的。

    2、在打算重构某个看起来有问题的代码时,我们会面临这样的疑惑,是否有必要冒着把能工作的东西弄糟的风险呢?这时我们可以考虑一下几个理由:

    它也许不是真的能工作,只是看起来能工作。

    你依靠的边界条件也许只是一个巧合。

    多余和没必要的调用会让你的代码变慢并增加新 bug 的风险。

    3、如何深思熟虑的编程,有以下建议:

    总是意识到你在做什么。

    按照计划(设计)行事。

    依靠可靠的事物而非假设。

    不要只是测试你的代码,还要测试你的假定。

    不要让已经做完的事情限制你的下一步,做好重构的准备。

    第32节 算法效率
    1、注重实效的程序员几乎每天都要使用估算,估算的资源包括:时间、处理器、内存等等。

    2、估算算法即是我们熟知的时间复杂度,用O()表示,它有以下几种常见类型。

    O(1),常量时间,不随数据的多少变化

    O(n),线性时间,简单的循环

    O(m*n),嵌套循环

    O(log(n)),二分法,平衡二叉树的查询

    O(nlog(n)),分而治之,快排

    O(2^n),指数级,斐波那契数列

    3、不同的时间复杂度在达到一定数量级的时候将相差很多,所以某些情况我们要想方设法优化算法的效率。我们主要需要关注的是是复杂度的阶。在确认了算法之后,还需要对其进行测试。

    4、最好的并非总是最好的,是否使用最优算法,还需要根据我们遇到的实际情况。有时数据量很小的情况,算法的效率是可以忽略不计的。

    第 33 节 重构
    1、重写、重做和重新架构代码合起来,称为重构。

    2、当代码出现以下特征,就应该考虑重构了:

    出现重复内容,违反DRY原则。

    非正交的设计。

    知识过时了,或者你对某部分的了解更深一步。

    对性能造成了影响。

    3、重构的原则:早重构、常重构。重构面临的敌人通常都是时间,但这个借口并不成立,因为之后由此引发的时间额外消耗很可能更多。

    4、如何重构。

    不要试图在重构的同时增加功能。

    重构之前,确保拥有良好的测试。

    采取短小,深思熟虑的步骤,不要一次改动太多内容。

    第34节 易于测试的代码
    1、软件 IC 是人们在讨论可复用性和基于组件的开发时喜欢使用的比喻。意思是集成电路芯片可以很容易的进行组合,我们希望软件开发也能达到这个效果。芯片的设计有完善的测试,同样的软件开发也可以做同样的事情。

    2、针对合约进行测试及为测试而设计,即 TDD 测试驱动开发。

    3、编写单元测试,对比较大的项目,将每个测试都放进一个子目录。

    4、使用测试装备。构建一套完善的测试体系,它能够记录测试状态,分析输出结果是否符合预期,以及选择和运行测试。

    5、推进测试文化,尽可能完善地测试你的软件,否则你的用户就得替你测试。

    第35节 邪恶的向导
    1、这里的向导指的是那些用于帮助我们构建程序自动生成的代码,通常他们还被称为脚手架。为什么称向导(wizard)是邪恶的呢,这是因为通过工具生成的代码,很容易被我们忽略,在这种情况下你编写的过程更倾向于靠巧合编程。

    2、这里不是抵制向导代码,而是在强调,不要使用你不理解的向导代码。如果使用,一定要清楚它的机制。

    3、开发每天都在使用不完全理解的事物,比如集成电路的工作原理,处理器的中断结构、用于调度的算法、各种系统库的工作机制等。需要注意的是,这些属于底层依赖,他们也是向导,但不是应用本身的一部分,我们可以对这部分有所了解,但他们不属于邪恶的向导。

    第36节 需求之坑
    从本节开始进入了第七章节:在项目开始之前。本章节讨论了在项目开始之前的一些建议。

    1、完美,不是在没有什么需要增加,而是在没有什么需要去掉时达到的。这句话的一种解读时,不要搜集需求,需求太多,容易让我们抓不住重点,更应该深挖需求,围绕核心功能不断打磨。

    2、挖掘需求,需要我们与用户一同工作,像用户一样思考。

    3、制定需求文档。看待用例的一种方式是强调其目标驱动的本质,它强调的是要重视需要做成什么以及需要什么条件。需求文档最好配一些UML用例图。

    4、需求的制定不能太具体,要保持一定的抽象。需求不是架构,不是设计,需求只是需要。这个有点类似于开发中的面向接口而不是面向具体实现编程。

    5、维护词汇表。“客户”和“顾客”,可能表达不同的含义,但如果混用会让人迷惑,我们可以维护一个词汇表,专门用户描述他们的具体含义。

    6、把需求文档发布到内网,参与人员都可以随时查看和提出意见。

    第37节 解开不可能解开的谜题
    1、戈尔迪斯结号称是没人能解开的结,后来亚历山大大帝来了,用剑劈开了这个结。

    2、面对看似不可能解决的问题,一定要转换思路,不要受任何先人之见影响。不要在盒子外面思考,要找到盒子。

    3、有时你会发现,自己在处理的问题比你以为的要难得多,总会感觉一定有更容易的方法。这时你可以退回一步,问问自己:

    有更容易的方法吗

    你是在解决真正的问题,还是被外围的技术问题转移了注意力

    这件事情为什么是一个问题

    是什么使它如此难以解决

    它必须以这种方式完成吗

    很多时候,对需求的重新诠释能让整个问题全部消失— 就像戈尔迪斯结。

    第 38 节:等你准备好
    1、倾听反复出现的疑虑。当你遇到一个反复让你疑虑的问题,需要注意它,给自己时间去理解,之后它可能就会变成某种更坚实的东西。

    2、对于某些东西,我们可能不愿意轻易做出承诺,总希望再等等,更多意见的提出。但这很可能是一种拖延,怎么区分是有效的等待还是拖延的接口呢?我们应该快速地构建原型,并进行推延,可能很快我们就找到了更好的解决方案。

    第 39 节:规范陷阱
    1、编写规范是一项重要的职责,但问题是很多人可能会陷在这里,不断地增加规范项。我们可以做这样一个尝试,写一份简单的描述,告诉别人怎样系鞋带。

    这可能是一份并不能帮助他人的描述,因为对有些事情“做”胜于“描述”。因为无意识的行为更快,考虑规范反而会拖慢进度。

    2、对待开发文档也一样,不要编写过于详细的规范。因为很可能开发者在思考某个问题时会想到两种不同方案,经过简单对比,选择一个更优的那个。但面对严格的规范文档,一步步思考,这更可能束缚开发者的发挥。

    第 40 节:圆圈与箭头
    1、设计文档里的圆圈和箭头用来解释他们指代的作用,但这还有可能是推翻我们原先设定的证据。感觉这个是承接上一节的内容,不要被以前的假设和设计所限制,留有一定的弹性空间。

    2、我们相信,盲目地采用任何技术,而不把他们放进你的开发实践和能力的语境中,这样的处理日后可能会让你后悔。

    3、不要迷信工具以及各种方法学,注重实效的程序员会批判地看待他们,并从中提取精华,融合成每个月都在变得更好的一套工作习惯。

    第41节 注重实效的团队
    1、书籍的前几章讲了几条如何成为注重实效的开发者的建议,当然他们也对团队有所帮助,如果个体都是注重实效的,那他对整体起的作用更大。

    2、不要留破窗户:作为整体的团队更不应该容忍代码质量的问题,不规范的不在乎质量的团队,很有可能把那些注重实效的开发者带偏。

    3、煮青蛙:整体中的个人更难觉察到作为团队所存在的问题,可以指定一个“检测员”,让他去检查团队整体进度,依赖项的准备情况,各个环节的配合等内容。

    4、交流:杰出的项目团队往往有着截然不同的个性,更能与其他团队进行配合。有一个简单的帮助团队凝聚力的方法:创立团队品牌,以品牌代指整个团队。

    5、不要重复你自己(DRY):由于个人理解程度的不同或者新成员的加入,团队总会面临重复的内容,适当的指派一名管理员,让他专门维护这些资料,所有对此有疑问的人都不必自我寻找,只要去找管理员就行了。

    6、正交性:对于较大的团队,更应该通过功能进行组织划分,而不是工作职务。比如开发多个项目,会有多名开发,多名测试,多名设计,他们之间更应该按照具体项目进行划分,一个项目的开发,测试和设计为一个小团体。

    7、自动化:确保一致性和准确的一种很好的方式是使团队所做的每件事情都能自动化,如果还没有做到那就尝试去做。

    8、知道如何停止绘画:团队是由个体组成的,给每个成员足够的空间,并支持他们,而不是一直给他们具化各种需求。

    第42节 无处不在的自动化
    1、文明通过增加我们不加思索就能完成的重要操作的数目而取得进步。— 阿尔弗雷德·诺思·怀特海

    2、我们应该在尽可能多的场景下使用自动化,因为人工流程及不能保证一致性也无法保证重复性。

    3、在一些特定场景下我们可以选择适当的工具进行自动化处理:

    执行周期任务时可以使用 Cron

    项目编译时虽然可以使用 IDE,但是 Makefile 更适合自动化场景

    使用生成代码解决不得不做的重复性代码问题

    构建自动化,其实就是目前比较常用各类 CI/CD 工具

    自动化管理,这是一种更自由的自动化场景,比如要回复 Email,要发布网站,审批流程等,这些可以使用 Shell 或者 Perl、Python 等高级脚本语言。

    第43节 无情的测试
    1、注重实效的程序员会受到找到自己 bug 的驱使,以免以后经受由别人找到我们 bug 带来的羞耻。

    2、早测试,常测试,自动化测试。要通过全部测试,编码才算完成。

    3、测试主要围绕三个方面进行:测试什么、怎样测试、何时测试。

    4、测试什么。测试类型有以下这些:

    单元测试:单元测试是函数级,有时也算做模块级的测试,要保证他们都正常通过。

    集成测试:组成项目的子系统能工作,且它们之间能很好的协同。

    验证和校验:这个类似AB测,是产品层面的测试。

    异常测试,资源耗尽,错误情况,如何恢复等。

    性能测试,压力测试,负载测试:这些情况通常是服务器相关的测试流程。

    可用性测试:也是产品项的测试,需要分析和调研,需求是否是有用的。

    5、怎样测试。主要介绍有哪些测试方法:

    回归测试:回归测试通常是测试的后面阶段,新旧功能一起测试,新功能不应该影响旧功能。

    测试数据:对于一些特殊场景,测试数据能起到很大帮助,比如需要大量数据,强调边界条件的数据,能展现特定字段的数据等。

    GUI系统:UI通常不好测试,所以应该做好解耦,将逻辑和视图拆分开进行测试。

    对测试进行测试:故意制造一些bug,观察你的测试系统能否发现。

    彻底测试:这里需要强调的是测试覆盖率,这其中需要强调的是测试状态的覆盖,而不是代码覆盖。要对不同状态都覆盖到。

    6、何时进行测试。尽早测试,而且测试应该是自动完成的,我们在提交代码时就应该保证测试已经全部通过。

    第44节 全都是写
    1、代码要跟文档紧密结合,我们要认真对待注释及文档,他们不是可有可无的东西。

    2、我们喜欢看到简单的模块级头注释,关于重要数据和类型声明的注释,以及给每个类和每个方法所加的简要头注释,用于描述函数的用法和任何不明了的事情。

    3、应当使用特定的格式进行注释,通常对应语言或者 IDE 有推荐的注释格式。

    4、可执行文档,即使按照特定格式进行注释,然后利用工具提取注释内容并生成文档。例如 JavaDoc

    5、有时文档撰写者和开发并不是同一人,但他们应当接受同样的原则,特别是 DRY,正交性,以及自动化原则等。

    iOS也有一个文档生成工具:jazzy[2],支持 OC 和 Swift,它可以根据标准的注释生成文档。

    第45节 极大的期望
    1、某个项目团队奇迹般的完成了一个非常复杂的项目,但却遭到用户抵制,原因是该引用没有帮助系统。所以考虑现实,项目的成功是由它在多大程度上满足了用户的期望来衡量的。

    2、要与客户之间多交流期望,了解他们的需求,而不是一味沉溺在技术的世界里。

    3、适当制造惊喜,会有些通用性的技巧能让项目获得更好的体验。比如:

    气球式帮助

    快捷键

    日志文件分析器

    自动化安装

    第46节 傲慢与偏见
    1、注重实效的程序员不会逃避责任,相反,我们乐于接受挑战,乐于使我们的业务知识广为人知。

    2、过去时代的手艺人为能在他们的作品上签名而自豪,你也应该如此。Sign Your Work.

    3、Kent Beck 在极限编程(XP)里的建议是采用公共的代码所有权,其还要求了结对编程,以防匿名的危险。所有权的好处是能为优秀的开发带来自豪感,并且当人们在一段代码上看到你的名字时,会将其认为质量的保证。

    参考资料
    [1]
    R.Swift: https://github.com/mac-cain13/R.swift

    [2]
    jazzy: https://github.com/realm/jazzy

    在这里插入图片描述

    ▊《程序员修炼之道:从小工到专家》

    [美] 亨特(Andrew Hunt),托马斯(Daid Thomas) 著

    马维达 译

    全球票选程序员读物

    常读常新的不老神话

    从开发到架构注重实效永不过时

    一本被所有编程翘楚力荐过的书

    本书由一系列独立的部分组成,涵盖的主题从个人责任、职业发展,直到用于使代码保持灵活、并且易于改编和复用的各种架构技术,利用许多富有娱乐性的奇闻轶事、有思想性的例子及有趣的类比,全面阐释了软件开发的许多不同方面的较佳实践和重大陷阱。无论你是初学者,是有经验的程序员,还是软件项目经理,本书都适合你阅读。

    在这里插入图片描述

    (京东满100减50,快快扫码抢购吧!)

    在这里插入图片描述

    ▊《程序员修炼之道:通向务实的最高境界(第2版)》

    [美] David,Thomas(大卫托马斯),Andrew,Hunt(安德鲁亨特) 著

    云风 译

    《从小工到专家》重磅新版

    雄踞“全球程序员至爱书单”顶端

    开发新兵走向卓越领袖

    本书之所以在全球范围内广泛传播,被一代代开发者奉为圭臬,盖因它可以创造出真正的价值:或编写出更好的软件,或探究出编程的本质,而所有收获均不依赖于特定语言、框架和方法。时隔20年的新版,经过全面的重新选材、组织和编写,覆盖哲学、方法、工具、设计、解耦、并发、重构、需求、团队等务实话题的最佳实践及重大陷阱,以及易于改造、复用的架构技术。本书极具洞察力与趣味性,适合从初学者到架构师的各阶层读者潜心研读或增广见闻。

    在这里插入图片描述

    (京东满100减50,快快扫码抢购吧!)

    展开全文
  • 《程序员修炼之道–从小工专家》 《程序员修炼之道–从小工专家》[美]Andrew Hunt / David Thomas 著 马维达 译   图片来源-百度图片    看这本书主要使用了检视阅读中略读的方法,大体了解本书所讲的...

    《程序员修炼之道–从小工到专家》

    《程序员修炼之道–从小工到专家》[美]Andrew Hunt / David Thomas 著 马维达 译 


     
    图片来源-百度图片 

     

    看这本书主要使用了检视阅读中略读的方法,大体了解本书所讲的主要内容。

    (1)整体来说,这本书到底在谈些什么?

    本书围绕“注重实效”讲述了关于编程的各种话题,个人责任、拽光弹开发、调试策略、元程序设计、按合约设计、重构、无情的测试,等等。作者认为注重实效的程序员的特征是程序员在处理问题、寻找解决方案时的态度、风格、哲学,他们能够超越直接的问题去思考,总是设法把问题放在更大的语境中,总是设法注意更大的图景。

    (2)作者细部说了什么,怎么说的?

    作者在短短的300多页的一书中论述的内容非常多,共8章,论述了程序员如何实现“注重实效”。作者论述的逻辑一般是首先解释所提及主题的关键概念,在论述每个小主题时,作者通常(不是所有)列出一个相关的名言警句。例如谈到“需求之坑”时,有“完美,不是在没有什么需要增加,而是在没有什么需要去掉时达到的–Antoine de St.Exupery, Wind, Ssand, and Stars. 1939”。作者会在文中特别给出一些提示,帮助你更好掌握作者的思路,然后会给出一些目标(即建议)指导你怎么在工作中实践作者所提的观点或解决存在的问题。

    在书的最后,作者总结出书中的提示和检查清单,在索引“注重实效的程序员之快速参考指南”列出。很容易去查找,看这些就可以复习书中方法和观点,很方便平时温故而知新。

    (3)这本书说的有道理吗?是全部有道理,还是部分有道理?

    书中很多方法对我来说是很有帮助的,我完全可以根据里面所说的一些建议进行实践,提高自己的编程能力。书本里直接列出了一些提示,目标和挑战,这都是可以直接实践的。例如在注重实效的哲学谈到了定期为你的知识资产投资,列出了这几个目标:

    • 每年至少学习一种新语言。持续投入十分重要,一旦你熟悉了某种语言或新技术,继续前进,学习另一种。
    • 每季度阅读一本技术书籍。
    • 也要阅读非技术书籍。
    • 上课。在本地的学院或大学、或是将要来临的下一次会展上寻找有趣的课程。
    • 参加本地用户组织。
    • 试验不同的环境。
    • 跟上潮流。
    • 上网。想要了解某种新语言或其他技术的各种特性?要了解其他的相关经验,了解他们使用的特定行话,等等,新闻组是很好的方式,上网冲冲浪,查找论文、商页站点、以及其他任何你可以找到的信息来源。

    由于我缺乏实践经验,很难鉴别书中所论述的一些我不熟悉的方法是否有效。在今后的工作实践中再来领悟肯定有新的收获。

    (4)这本书跟你有什么关系?

    即将毕业,我很快将会开始我的程序员生涯,作为编程初学者,我可以书中了解到各种编程技术和方法,根据书中的指引拓展我的编程生涯。

    文档生成工具

    阅读这本书了解到了写程序文档也是很重要的,介绍了文本操纵的很重要意义。里面提到了作者常用perl语言编写脚本来操纵文本,例如格式化书本、生成程序的HTML文档。我对此还是感到比较新奇,因为从未使用过这样的工具。去网上搜索了一下,果然搜出一大批文档生成工具,例如doxygen,找到两篇博客很好地介绍了相关的文档生成工具:

    告别手写 API文档生成工具推荐

    Doxygen给C程序生成注释文档

    使用文档生成工具的好处是可以更快速的实现文档随代码的变化而自动更新,免去很多反复修改文档的繁琐重复工作。

    注重实效的程序员之快速参考指南

     


     
    图片来源-百度图片 

     

    在书的最后,作者总结出书中的提示和检查清单,在索引“注重实效的程序员之快速参考指南”列出。很容易去查找,看这些就可以复习书中方法和观点,很方便平时温故而知新。

    1.关心你的技艺 Care About Your Craft 
    如果你不在乎能否漂亮的开发出软件,你又为何要耗费生命去开发软件呢?

    2.思考!你的工作 Think! About Your Work 
    关掉自动驾驶仪,接管操作。不断地批评和评估你的工作。

    3.提供各种选择,不要找蹩脚的借口 Provide Options, Don’t Make Lame Excuses 
    要提供各种选择,而不是找借口。不要说事情做不到;说明能够做什么。

    4.不要容忍破窗户 Don’t Live with Broken Windows 
    当你看到糟糕的设计、错误的决策和糟糕的代码时,修正它们。

    5.做变化的催化剂 Be a Catalyst for Change 
    你不能强迫人们改变。相反,要向他们展示未来可能会怎样,并帮助他们参与对未来的创造。

    6.记住大图景 Remember the Big Picture 
    不要太过专注于细节,以至忘了查看你周围正在发生什么。

    7.使质量成为需求问题 Make Quality a Requirements lssue 
    让你的用户参与确定项目真正的质量需求。

    8.定期为你的知识资产投资 Invest Regularly in Your Knowledge Portfolio 
    让学习成为习惯。

    9.批判地分析你读到的和听到的 Critically Analyze What You Read and Hear 
    不要被供应商、媒体炒作、或教条左右。要依照你自己的看法和你的项目的情况去对信息进行分析。

    10.你说什么和你怎么说同样重要 It’s both What You Say and the Way You Say it 
    如果你不能有效地向他人传达你的了不起的想法,这些想法就毫无用处。

    11.不要重复你自己 DRY - Don’t Repeat Yourself 
    系统中的每一项知识都必须具有单一、无歧义、权威的表示。

    12.让复用变得容易 Make It Easy to Reuse 
    如果复用很容易,人们就会去复用。创造一个支持复用的环境。

    13.消除无关事物之间的影响 Eliminate Effects Between Unrelated Things 
    设计自足、独立、并具有单一、良好定义的目的的组件。

    14.不存在最终决策 There Are No Final Decisions 
    没有决策是浇铸在石头上的。相反,要把每项决策都视为是写在沙滩上的,并为变化做好计划。

    15.用曳光弹找到目标 Use Tracer Bullets to Find the Target

    曳光弹能通过试验各种事物并检查它们离目标有多远来让你追踪目标。

    16.为了学习而制作原型 Prototype to Learn 
    原型制作是一种学习经验。其价值并不在于所产生的代码,而在于所学到的经验教训。

    17.靠近问题领域编程 Program Close to the Problem domain 
    用你的用户的语言进行设计和编码。

    18.估算,以避免发生意外 Estimate to Avoid Surprises 
    在着手之前先进行估算。你将提前发现潜在的问题。

    19.通过代码对进度表进行迭代 Iterate the Schedule with the Code 
    用你在进行实现时获得的经验提炼项目的时间标度。

    20.用纯文本保存知识 Keep Knowledge in Plain Text 
    纯文本不会过时。它能够帮助你有效利用你的工作。并简化掉时和测试。

    21.利用命令shell的力量 Use the Power of Command Shells 
    当图形用户界面无能为力时使用shell。

    22.用好一种编辑器 Use a Single Editor Well 
    编辑器应该是你的手的延伸;确保你的编辑器是可配置、科扩展和可编程的。

    23.总是使用源码控制 Always Use Source Code Control 
    源码控制是你的工作的时间机器–你能够回到过去。

    24.要修正问题,而不是发出指责 Fix the Problem, Not the Blame 
    bug是你的过错还是别人的过错,并不是真的很有关系–它仍然是你的问题,它仍然需要修正。

    25.调试时不要恐慌 Don’t Panic When Debuging 
    做一次深呼吸,思考什么可能是bug的原因。

    26.“Select”没有问题 “Select” Isn’t Broken 
    在OS或编译器、甚或是第三方产品或库中很少发现bug。bug很可能在应用中。

    27.不要假定,要证明 Don’t Assume It - Prove It 
    在实际环境中–使用真正的数据和辩解条件–证明你的假定。

    28.学习一种文本操纵语言 Learn a Text Manipulation Language 
    你用每天的很大一部分时间处理文本,为什么不让计算机替你完成部分工作呢?

    29.编写能编写代码的代码 Write Code That Writes Code 
    代码生成器能提高你的生产率,并有助于避免重复。

    30.你不可能写出完美的软件 You Can’t Write Perfect Software 
    软件不可能完美。保护你的代码和用户,使它(他)们免于能够预见的错误。

    31.通过合约进行设计 Design with Contracts 
    使用合约建立文档,并检验代码所做的事情正好是它声明要做的。

    32.早崩溃 Crash Early 
    死程序造成的危害通常比有问题的程序要小得多。

    33.用断言避免不可能发生的事情 Use Assertions to Prevent the Impossible 
    断言验证你的各种假定。在一个不确定的世界里,用断言保护你的代码。

    34.将异常用于异常的问题 Use Exceptinos for Exceptional Problems 
    异常可能会遭受经典的意大利面条式代码的所有可读性和可维护性问题的折磨。将异常保留给异常的事物。

    35.要有始有终 Finish What You Start 
    只要可能,分配某资源的例程或对象也应该负责解除其分配。

    36.使模块之间的耦合减至最少 Minimize Coupling Between Modules 
    通过编写“羞怯的”代码并应用得墨忒耳法则来避免耦合。

    37.要配置,不要集成 Configure, Don’t Integrate 
    要将应用的各种技术选择实现为配置选项,而不是通过集成或工程方法实现。

    38.将抽象放进代码,细节放进元数据 Put Abstractions in Code, Details in Metadata 
    为一般情况编程,将细节放在被编译的代码库之外。

    39.分析工作流,以改善并发性 Analyze Workflow to Imporve Concurrency 
    利用你的用户的工作流中的并发性。

    40.用服务进行设计 Design Using Services 
    根据服务–独立的、在良好定义、一致的接口之后的兵法对象–进行设计。

    41.总是为并发进行设计 Always Design for Concurrency

    容许并发,你将会设计出更整洁、具有更少假定的接口。

    42.使视图与模型分离 Separate Views from Models

    要根据模型和视图设计你的应用,从而以低廉的代码获取灵活性。

    43.用黑板协调工作流 Use Blackboards to Coordinate Workflow

    用黑板协调完全不同的事实和因素,同时又使各参与方保持独立和隔离。

    44.不要靠巧合编程 Don’t Program by Coincidence

    只依靠可靠的事物。注意偶发的复杂性,不要把幸运的巧合与有目的的计划混为一谈。

    45.估算你的算法的阶 Estimate the Order of Your Algorithms

    在你编写代码之前,先大致估算事情需要多长时间。

    46.测试你的估算 Test Your Estimates

    对算法的数学分析并不会告诉你每一件事情。在你的代码的目标环境中测定它的速度。

    47.早重构,常重构 Refactor Early, Refactor Often

    就和你会在华园里除草、并重新布置一样,在需要时对代码进行重写、重做和重新架构。要铲除问题的根源。

    48.为测试而设计 Design to Test

    在你还没有编写代码时就开始思考测试问题。

    49.测试你的软件,否则你的用户就得测试 Test Your Software, or Your Users Will

    无情地测试。不要让你的用户为你查找bug。

    50.不要使用你不理解的向导代码 Don’t Use Wizard Code You Don’t Understand

    想到可以生成大量代码。在你把它们合并进你的项目之前,确保你理解全部这些代码。

    51不要搜集需求–挖掘它们 Don’t Gather Requirements - Dig for Them

    需求很少存在于表面上。它们深深地埋藏在层层假定、误解和政治手段的下面。

    52.与用户一同工作,以像用户一样思考 Work with a User to Think Like a User

    要了解系统实际上将如何被使用,这是最好的方法。

    53.抽象比细节活得更长久 Abstractions Live Longer than Details

    “投资”于抽象,而不是实现。

    54.使用项目词汇表 Use a Project Glossary

    创建并维护项目中使用的专用术语和词汇的单一信息源。

    55.不要在盒子外面思考–要找到盒子 Don’t Think Outside the Box - Find the Box

    在遇到不可能解决的问题时,要确定真正的约束。问问你自己:“它必须以这种方式完成吗? 它真的必须完成吗?”

    56.等你准备好再开始 Start When You’re Ready

    你的一生都在积累经验。不要忽视反复出现的疑惑。

    57.对有些事情“做”胜于“描述” Some Things Are Better Done than Described

    不要掉进规范的螺旋

    58.不要做形式方法的奴隶 Don’t Be a Slave to Formal Methods

    如果你没有把某项技术放进你的开发时间和能力的语境中,不要盲目地采用它。

    59.昂贵的工具不一定能制作出更好的设计 Costly Tools Don’t Produce Better Disigns

    小心供应商的炒作,行业教条,以及价格标签的诱惑。要根据工具的价值判断它们。

    60.围绕功能组织团队 Organize Teams Around Fucntionality

    不要把设计师与编码员分开,也不要把测试员与数据建模员分开。按照你构建代码的方式构建团队。

    61.不要使用手工流程 Don’t Use Manual Procedures

    shell脚本或批文件会一次次地以同一顺序执行同样的指令。

    62.早测试,常测试,自动测试。 Test Early. Test Often. Test Automatically

    与呆在书架上的测试计划相比,每次构建试运行的测试要有效得多。

    63.要到通过全部测试,编码才算完成。 Coding Ain’t Done ‘Til All the Tests Run

    就是这样。

    64.通过“蓄意破坏”测试你的测试。 Use Saboteurs to Test Your Testing

    在单独的软件副本上故意引入bug,以检验测试能够抓住它们。

    65.测试状态覆盖,而不是代码覆盖 Test State Coverage, Not Code Coverage

    确定并测试重要的程序状态。只是测试代码行是不够的。

    66.一个bug只抓一次 Find Bugs Once 
    一旦测试员找到一个bug,这应该是测试员最后一次找到它。此后自动测试应该对其进行检查。

    67.英语就是一种编程语言 English is Just a Programming Language 
    像你编写代码一样编写文档:遵守DRY原则、使用元数据、MVC、自动生成、等等。

    68.把文档建在里面,不要栓在外面 Build Documentation In, Don’t Bolt It On 
    与代码分离的文档不太可能被修正和更新。

    69.温和地超出用户的期望 Gently Exceed Your Users’ Expectations 
    要理解你的用户的期望,然后给他们的东西要多那么一点。

    70.在你的作品上签名 Sign Your Work 
    过去时代的手艺人为能在他们作品上签名而自豪。你也应该如此。

    检查清单

    —————————*

    71.要学习的语言 
    厌倦了C、C++和JAVA?试试CLOS、Dylan、Eiffel、Objectve C、Prolog、Smailltalk或TOM。它们每一种都有不同的能力和不同的“风味”。用其中的一种或多种语言在家里开发一个小项目。

    72.WISDOM离合诗 
    What do you want them to learn? 你想让他们学到什么? 
    What is their interest in what you’ve got to say? 他们对你讲的什么感兴趣? 
    How sophisticated are they? 他们有多富有经验? 
    How much detail do they want? 他们想要多少细节? 
    Whom do you want to own the information? 你想要让谁拥有这些信息? 
    How can you motivate them to listen to you? 你如何促使他们听你说话?

    73.怎样维持正交性 
    设计独立、良好定义的组件。 
    使你的代码保持解耦。 
    避免使用全局数据。 
    重构相似的函数。

    74.应制作原型的事物 
    架构 
    已有系统中的新功能 
    外部数据的结构或内容 
    第三方工具或组件 
    性能问题 
    用户界面设计

    75.架构问题 
    责任是否得到了良好定义? 
    写作是否得到了良好定义? 
    耦合是否得以最小化? 
    你能否确定潜在的重复? 
    接口定义和各项约束是否可接受? 
    模块能否在需要时访问所需数据?

    76.调试检查清单 
    正在报告的问题是底层bug的直接结果,还是只是症状? 
    bug真的在编译器里?在OS里?或者是在你的代码里? 
    如果你向同事详细解释这个问题,你会说什么? 
    如果可疑代码通过了单元测试,测试是否足够完整?如果你用该数据运行单元测试,会发生什么? 
    * *·造成这个bug的条件是否存在于系统中的其它任何地方?

    77.函数的得墨忒耳法则 
    某个对象的方法应该只调用属于以下情况的方法: 
    它自身 
    传入的任何参数 
    它创建的对象 
    组件对象

    78.怎样深思熟虑地编程 
    总是意识到你在做什么。 
    不要盲目地编程。 
    按照计划行事。 
    依靠可靠的事物。 
    为你的假定建立文档。 
    不要只是测试你的代码,还要测试你的假定。 
    维护的工作划分优先级。 
    不要做历史的奴隶。

    79.何时进行重构 
    你发现了对DRY原则的违反。 
    你发现事物可以更为正交。 
    你的知识扩展了。 
    需求演变了。 
    你需要改善性能。

    80.劈开戈尔迪斯结 
    在解决不可能解决的问题时,问问你自己: 
    有更容易的方法吗? 
    我是在解决正确的问题吗? 
    这件事情为什么是一个问题? 
    是什么使它如此难以解决? 
    它必须以这种方式完成吗? 
    它真的必须完成吗?

    81.测试的各个方面

    单元测试 
    集成测试 
    炎症和校验 
    资源耗尽、错误及恢复 
    性能测试 
    可用性测试 
    对测试自身进行测试

    展开全文
  • 好书推荐,《程序员修炼之道》

    千次阅读 2019-10-28 17:53:54
    记得四年前刚开始工作时从公司拿的第一本书,就是这本《程序员修炼之道》(英文版),作为新入职员工study group的学习材料,当时在senior engineer带领下和其他同事一起学习了这本书。虽然之前就听说这是一本好书,...

    这本书里包含了很多的看似粗浅朴素的道理,实则是若干经验的心血总结。

    比如谁都知道不要对自己家的破窗户置之不理,可实际中听到太多的妥协:这个代码已经这样了,只能继续在上面贴上丑陋的workaround,这其实是一种对责任的推卸和对未来的不负责,当然现实不是完美的,有时救火队员也不得不放下破窗户而迁就其他,但最为一个pragmatic程序员,保持追求完美的心态还是很有必要的,正因为这个心态,我们才会去追求代码的优美、设计/实现的正交、DRY(Dont' Repeat Yourself)原则...

    我们看到太多重复造轮子的故事。

    正如书中提到“鞋匠的孩子没鞋穿”,作为一个pragmatic程序员,合理地使用工具/库/以及自己积累的开发的轮子,会让自己的productivity不断提升。这让我想起公司里一个让人崇拜的“牛”,产品一直想把进程内cache做成多进程共享,正在大家还在讨论该怎么做的时候,“牛”已经用短短几天时间完成了,众人再次崇拜一把,原来“牛”是备有很多现成代码的,完成这个功能只是把之前积累的封装良好的模块重用就可以了。

    记得四年前刚开始工作时从公司拿到的第一本书,就是这本《程序员修炼之道》(英文版),作为新入职员工study group的学习材料,当时在senior engineer带领下和其他同事一起学习了这本书。虽然之前就听说这是一本好书,但当时看的时候只是觉得,讲的都有道理,但这些是很自然的阿,干吗花这么大的篇幅说来说去?所以只是囫囵吞枣地翻过也就扔在一边了。

    之后也看过很多类似的书籍,《修炼之道》也一直是公司新人的必备学习材料,而我却一直再没重拾这本书仔细通读一遍,直到最近周筠老师发给我中文电子版,我才又从书架上翻出当年的英文版,对照着中文电子版仔细通读了一遍。

    此次重读,感受颇多,也颇能理解为何公司一直选用此书作为新人教材。

    另外一个书中推崇的方法:曳光弹,自己之前用prototype,但一直犹豫于代码是否需要重用,原则上prototype的代码是应该抛弃型的,但在有时候前期做的一些工作其实是为了确定方案、构建框架,而这些其实是会作为后起工作的基础的。事实上在项目先期是值得仔细考虑究竟该采用prototype还是曳光弹,它们的适用场景会有所不同(对于产品开发,曳光弹的应用场景可能相对会更多一些)

    当然,至于书中提到的对知识资产的管理(知识投资)、沟通和交流的重要性等等,我想这就不单单对于程序员适用了,任何一个人要想有所作为的,这些方面的重要性都毋庸多说了。而对于自动化和文本处理等方面的经验,也是在很多书中都提到的经验之谈(Unix编程艺术、卓有成效的程序员...)

    最后,说一下这本书的翻译,译者马维达,最早是在学校时读过他翻译的ACE文档及相关资料,收益颇多,ACE可谓网络编程技术的集大成者,而这本《修炼之道》则可谓编程的集大成者,从项目管理、软件架构和设计、代码编写和测试,各方面在此书中都有精到的阐述。此书的翻译质量应该说很是准确,基本很实在真实地表达了原书的意思,但正因直译,可能有些语句理解上会有一点难度(比如P146, "只要对于那些被耦合在一起的模块而言,这是众所周知的和可以接受的,你的设计就没有问题。"),但细读这本书,这些有所晦涩的内容还是能理解的,当然一点建议是作者可以适当加些“译注”,这样会让理解更容易和顺畅(比如书中直接用古鲁来翻译Guru,如果能加些解释可能会更好,又比如Law of Demeter,原书没有解释得太清楚,如果能多加些解释可能会更便于理解)

    感谢周筠老师让我有机会重温这本优秀的书籍,为了完成作业,也为了让自己认识提升。

    其他的一些感悟:

    正交性(高内敛,最后达到两个模块之间互补影响)
    曳光弹或是原型(轻量级引导程序,直达目标,方便调整)
    断言式编程,异常使用(暴露程序的问题,不要隐藏他)
    解耦与墨忒尔法则(低耦合,减少依赖)
    算法数率与重构(更优质的代码)
    无处不在的自动化(减少重复代码,和无意义的代码,不仅会让编程更有趣,而且会减少错误)
    这些算是比较高级的技巧了。对于初学变成的人其实不太友好。过多的限定总是会让新手止步不前。
    不过《程序员修炼之道》还提到了几条对于任何阶段的程序员都应该遵循的法则
    1.你的知识资产
    你应该一直投资知识资产,这是你成长的根本
    包括但不限与,定期读书,定期学习新的语言,尝试新的工具
    2.破窗原则
    任何时候你都应该使用你当时最高水品的技术去完成一个项目,如果你发现又不好的设计或实现应该修正它。就算时间不够你至少应该打上一个补丁,以警告和提示开发人员这个地方需要修补。
    3.打上你的标签
    不再怀有侥幸,在你负责和修改的地方打上标签。迫使自己编写更高水平的代码。
     

    我的源码让猫吃了
    对于工作勇于负责,正确评估自己的负责范围,别找一些蹩脚的借口。
    Provide Options,Don't Make Lame Excuses.选择各种选择,不要找蹩脚的接口。

    软件的熵
    软件无序增长被称为“软件腐烂”(Software rot)
    对于软件中错误应该及时修复,千万别把软件弄“脏”了,否则软件将迅速恶化。
    Don't Live with Broken Windows.不要容忍破窗户

    石头汤与煮青蛙
    让他们瞥见未来,你就能让他们聚在你周围。
    Be a Catalyst for Change.做变化催化剂
    很多软件灾难都是从小事开始,以至于积少成多,影响了团队。
    Remember the Big Picture.记住大图景

    足够好的软件
    所有系统都必须满足其用户的需求,才能获得成功。让用户参与到你的工作吧,让他们去权衡。但是过度修饰和过于求精,而损坏完好的程序就有点画蛇添足了。
    Make Quality a Requirements lssue.使质量成为需求问题

    你的知识资产(Knowledge Portfolios)

    知识是有时效的资产(expiring asset)

    经营知识资产:定期投资、多元化、管理风险、低买高卖、重新评估和平衡

    Invest Regularly in Your Knowledge Portfolios.定期为你的知识资产投资

    每年至少学一种新语言,每个月至少阅读一本书,阅读非技术书籍,上课,参加本地用户组织,试验不同的环境,跟上潮流,上网。

    学习时,也要进行批判的思考。咕噜们和互联网不一定时最权威的。
    Critically Analyze What You Read and Hear.批判分析你读到的和听到的。

    交流(Communcation)

    在说话前要做到以下准备:

    1.知道要说什么

    2.知道要对谁说

    3.选择什么时候说

    4.说话的风格(简报;论述;幽默;严肃)要让文档看起来漂亮说话是一个互动行为(Not noly Speaker but alse Listener)礼貌回复一切别人向你提出的问题。
    It's Both What You Say and the Way You Say it.你说什么和你怎么做一样重要

    重复的危害

    DRY原则(Don't reapeat youorself):系统中的每一项知识都必须具有单一,无歧义,权威的表示

    四种重复:

    加强的重复(impsed duplication):环境似乎要求重复(信息多种表示,注释,文档与代码,语言问题)

    无意的重复(inadvertent duplication):没有意识到信息的重复

    无耐性的重复(impatient duplication):开发者偷懒,似乎那样更容易

    开发者之间的重复(interdeveloper duplication):大家重复同样的东西

    复用是解决重复一个最好的方法

    Make it easy to Rease.让复用变得容易

    正交性

    如果两个或多事物中的一个发生变化,不会影响其他事物,这些事物就是正交的。

    Eliminate Effect  Between Unrelated Things.消除无关事物之间的影响。

    自足(self-contained)的组件:独立,具有单一,良好定义的目的。

    正交的好处:提高生产效率,降低风险。

    经常问问自己:如果我显著地改变某个特定功能背后地需求,有多少模块会受影响。

    编码:让代码保持解耦,避免使用全局数据;避免编写相似地函数

    可撤销性

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

    一个灵活的框架随时适应变化的需求。

    “薛定谔的猫”——任何结果都是可能的。

    需求随时在变,而软件就变不起了,如果连软件框架都变来变去,那软件一定会失败。

    曳光弹

    做软件的时候可以时不时地抛出一个曳光弹,看看打中目标没有。

    Use Tracer Bullets to find the Target.用曳光弹找到目标。

    曳光弹代码并非用过就扔的代码,你编写它是为了保留它。

    曳光弹代码有点:

    用户能够及早看到能工作的东西;

    开发者构建了一个他们能在其中工作的结构;

    有一个集成的平台;

    有了可用于演示的东西;

    能感觉到工作的进展;

    原型制作生成用过就扔的代码;曳光弹虽然简约,但却是完整的,最终构成系统骨架一部分。

    原型与便笺

    为工作流和应用逻辑等动态事物制作原理,便笺是一个很好的选择。

    应制作原型的事物:

    1.架构;2.已有系统中的新功能;3.外部数据的结构或内容;4.第三方工具或组件;5.性能问题;6.用户界面;

    怎样使用原型:

    在制作原型时可忽略的细节:正确性,完整性,健壮性,风格;

    用一些“胶合剂”把组件粘起来

    用便笺、索引卡片在白板上将系统建模;

    原型嘛,又不是曳光代码,用完就扔了它。

    领域语言

    语言的界限就是一个人的世界的界限;

    用业务的语言去描述业务问题,而不用编程语言,这样就不会钻牛角尖。

    举个例子:在一组X.25线路上侦听由ABC规则12.3定义的交易,把它们转译成XYZ公司的43B格式,在卫星上行链路上重新传输,并存储起来,供

    分析使用将来。

    剪裁后的小语言:

    From X25Line1 (Format=ABC123){

      Put TELSTAR1 (Format=XYZ43B);

      Store DB;

    }

    用户又添加一个需求:不应存储余额为负的交易,而应以原来的格式在X.25线路上发送回去:

    From X25Line1 (Format=ABC123){

      if (ABC123.balance<0){

        Put X25Line1 (Format=XYZ43B);

      }

      else{

        Put TELSTAR1 (Format=XYZ43B);

        Store DB;

      }

    }

    Program Close to the Problem domian(靠近问题领域编程)

    使用小型语言扩展现有语言

    估算

    Estimate to avoid surprise(估算,以避免发生意外)

    130工作日和6个月,哪个显得更精确呢?

    估算来自:

    理解提问内容,注意问题域的范围;

    建立系统的模型;

    把模型分解为组件;

    给每个参数制定值;

    计算答案;

    追踪估算能力;

    Iterate the Schedule with the Code.(通过代码对进度表进行迭代) 

    让工具变为双手的延伸

    纯文本的威力

    Keep knowledge in Plain Text.用纯文本保存知识。

    文本的威力:不过时;杠杆作用(每一样工具都可以工作在纯文本上);更易于测试;

    纯文本是永远的公共通信标准。

    Shell游戏

    别受限于GUI界面,回到文本操作吧,让Shell成为你的朋友。

    Use the Power of Command Shells.利用命令Shell的力量。

    Cygwin,UWIN是Windows下的Unix Shell工具实现。

    强力编辑

    Use s Single Editor Well.用好一种编辑器。

    编辑器特性:可配置,可扩展,可编程;

    Emacs是一个很好的编辑器,Vi也是,EditPlus也是。

    源码控制

    进步远非游变化组成,而是取决于好记性。不能记住过去的人,被判重复过去。

    源码控制系统(SCCS)是一个长效的Undo功能。我们可以在主干上开发,也可以生成一些完整的分支提供给客户。如果分支情况良好,可以考

    虑将分支和主支合并。

    Always Use Source Code Control.总是使用源码控制。

    无论怎么样,只要你在计算机上工作就要使用它。

    VSS,CVS,PCVS,SVN都是很不错的版本控制系统,还有就是ClearCase.

    调试

    调试的目的:解决问题

    Fix the Problem,Not the Blame.修正问题而不是指责。

    面对Bug千万不要恐慌或者认为那是不可能的,既然发生了就要积极面对它。

    如何暴露Bug:

    1.最好可以和报告Bug的人面谈一下,这样可以搜集更多的数据;

    2.人工合成测试不能足够地演练应用,必须设计测试边界条件同时实现在现实中用户地使用模式;

    测试策略

    别让Bug离你太远,否则会捉不到它地。

    1.使数据可视化:Variable name = data value.(直观地数据表达方式)

    2.跟踪:

      a.把小诊断消息打印到屏幕上或者文件中,例如什么printf或者System.out.println之类的;

      b.栈的踪迹(Stack trace)。

    3.橡皮鸭:对着别人解释你的代码,说着说着Bug就出来了;

    4.消除过程:找问题先找自己的问题,再找别人的问题;再提交Bug报告前,必须先消除你代码中的Bug.

    造成惊讶的要素:发生了,就认了把,然后努力去解决它。

    Don't Assume it-Prove it.不要假定,要证明。

    以后就别在说:“ Oh,My god”了。

    文本操纵

    Learn a Text Mainpulation Language.学习一种文本操纵语言。

    用途列举:数据库维护,属性访问,测试数据生成,写书,接口,生成文档……

    代码生成器

    Write Code that Writes Code.编写能编写代码的代码。

    被动代码生成器:只运行一次来生成结果

    1.创建新的源文件;

    2.在变成语言只间进行一次转换;

    3.生成查询表及其他运行时很昂贵的资源;

    主动代码生成器:在每次需要其结果时被使用

    取某项知识的一种表示形式,将其转换未你的应用需要的所有形式,说白了就是格式转换。

     

    世界上没有完美的代码,也没有完美的程序员。只有防卫性地编码和注重实效地程序员。

    按合约设计(DBC)

    Design with Contracts.通过合约进行设计

    用合约的方法帮助软件模块进行交互;

    程序做它生命要做的事情,用文档记载这样的声明,并进行校验;

    例程对世界状态的期望:

    前条件(precondition):调用例程必须的条件;

    后条件(postcondition):例程完成后世界的状态;

    类不变项(class invariant):类确保从调用者角度看,条件总为真;

    Liskov替换原则:子类必须要能通过基类的接口,而使用者无须知道其区别;

    实现DBC:断言与语言支持(Java:iContract)

    不变项的用法:1.循环不变项;2.语义不变项

     

    死程序不说谎

    Crash Early.早崩溃

    有时候宁愿要程序崩溃,也千万不要让它把坏数据写入;

    检查每一个可能的错误——特别是意料之外的错误——是一种良好的实践;

    断言式编程

    If It Can’t Happen,Use Assertions to Ensure That Won’t.

    如果它不可能发生,用断言确保它不会发生

    不能用断言代替真正的错误处理

    Java断言类实现

    import java.lang.System;

    import java.lang.Thread;

    public class Assert{

           public static void TEST(Boolean conition){

                  if(!conition){

                         System.out.println(“Assertion Failed”);

                         Thread.dumpStack();

                         System.exit(1);

                  }

           }

    }

    如何使用异常

    Use Exceptions for Exceptional Problems.将异常用于异常问题

    对于出错或可能出错的地方尽量使用异常抛出,if来if去多麻烦。

    怎么配平资源

    Finish What You Start.要有始有终

    记得释放你的资源,否则世界会因为你占有太多资源不堪重负,最终崩溃;

    嵌套分配

    1. 以与资源分配的次序相反的次序解除资源的分配;

    2. 在代码的不同地方分配同一组资源时,总是以相同的次序分配它们;

    无论是谁分配的资源,它都应该负责解除该资源的分配;

    在Java开发中使用完某个对象都,将其设为NULL,这可以使垃圾回收器将它自动回收。

     

    解耦与得墨忒耳法则

    好篱笆促成好邻居

    对象间直接得横贯关系有可能很快带来依赖关系得组合爆炸:如果n个对象相互了解,那么对一个对象得改动就可能导致其他n-1个对象都需要改动。

    函数的得墨忒耳法则

    尽可能遵守得墨忒耳法则的“羞涩”代码

    Minimize Coupling Between Modules.

    使模块间耦合减至最少

    元程序设计

    再多天才也无法胜过对细节专注;

    动态配置:对于算法、界面之类,应该使用配置选项,而不是通过集成或工程实现;

    Configure,Don’t Integrate.要配置,不要集成

    元数据驱动的应用

    Put Abstractions in Code, Details in Metadata.将抽象放进代码,细节放进元数据

    在一个复杂工作流系统中,你将通过编写规则,而不是修改代码来配置它。

    时间耦合

    Analyze Workflow to Improve Concurrency.分析工作流,以改善并发行

    在多个消费者进程间进行快速而粗糙的负载平衡的一种途径:饥饿的消费者(hungry consumer)模型

    Design Using Services.用服务进行设计

    在并发设计时应该注意公共变量,对其加以保护。同时也要保证线程安全

    Always Design for Concurrency.总是为并发进行设计

    它只是视图

    模块具有单一的,定义良好的责任

    模块间不需要互相知道太多

    一件事件就是一条特殊消息

    发布/订阅:Subscriber只对感兴趣的话题向Publisher进行订阅,而Publisher负责监听并分发消息。

    MVC架构:

    模型:表示目标对象的抽象数据模型。模型对任何视图或控制器没有直接的了解;

    视图:解释模型的方式。它订阅模型中的变化和来自控制器的逻辑事件;

    控制器:控制视图,并向模型提供新数据的途径。它既向模型,也向视图发布时间;

    黑板

    黑板系统让我们完全解除了我们的对象之间的耦合,并提供一个“论坛”,只是消费者和生产者都可以在那里匿名、异步地交换数据;

    对黑板进行分区并组织上面资料以防止组合爆炸;

    黑板方式地编程消除了太多接口需要,从而能带来更优雅、更一致地系统

    Use Blackboards to Coordinate Workflow.用黑板协调工作流

    编程不是机械工具

    靠巧合编程

    避免靠巧合编程,不要依靠运气和偶然地成功,而要深思熟虑地编程;

    巧合编程:实现地偶然;语境地偶然;隐含地假定;

    Don’t Program by Coincidence.不要靠巧合编程

    深思熟虑地编程

    1.  总是意识到自己在做什么

    2.  不要盲目地编程

    3.  按照计划行事,不管计划写在哪里

    4.  依靠可靠地事务

    5.  为你地假定建立文档

    6.  不要只是测试你的代码,还要测试你的假定

    7.  为你的工作划分优先级

    8.  不要让已有地代码支配将来的代码

    算法的效率

    推荐:Sedgewick关于算法的书

    常识估算:

    简单循环O(n);嵌套循环O(n*n);二分法O(nlgn);组合:效率失控

    Estimate the Order of Your Algorithms.估算你的算法的阶

    Test Your Estimate.测试你的估算

    重构

    重写、重做和重新架构代码合起来,成为重构(refactoring)

    应该重构代码的条件:

    1.  重复,违反DRY原则

    2.  非正交设计

    3.  过时的知识

    4.  性能不好

    Refactor Early,Refactor Often.早重构,常重构

    如何进行重构:

    1.  不要试图在重构的同时增加功能;

    2.  在开始重构之前,确保你拥有良好的测试;

    3.  采取短小,深思熟虑的步骤

    易于测试的代码

    单元测试是对模块进行演练的代码,也是针对合约的测试

    Design to Test.为测试而设计

    测试驱动法:先测试代码,再进行模块测试

    Print法——>即兴测试

    Test Your Software,Or Your Users Will.测试你的软件,否则你的用户就得测试

    邪恶的向导

    慎用设计向导,否则那些自动生成的代码会让你崩溃

    Don’t Use Wizard Code You Don’t UnderStand.不要使用你不理解的向导代码

    需求之坑

    Don’t Gather Requirements—Dig for them.不要搜集需求——挖掘它们

    挖掘需求

    需求是对需要完成的某件事的陈述

    “我能否在你们工作时在这里呆上一周”——注意不要妨碍别人工作

    Work with a User to Think Like a User.与用户一同工作,以像用户一样思考

    建立需求文档

    将挖掘出来的需求建立需求文档;

    看待用例的一种方式是强调其目标驱动;

    把形式化的模板用作备忘录;

    规定过度

    制作需求文档时的一大危险是太具体;

           需求不是架构,需求不是设计,也不是用户界面,需求是需要;

    看远些

           Abstractions Live Longer than Details.抽象比细节活得更长久

    再摸一层薄薄的薄荷

           许多项目的失败都被归咎于项目范围的增大——也称为特性膨胀,蔓延特性论或需求蔓延

    维护词汇表

           对用户和领域专家的属于进行有条例地记录并随时维护

           Use a Project Glossary.使用项目词汇表

    把话说出来,放在Web上,大家一起看。

    解开不可能解开的谜题

    自由度

    Don’t Think Outside the Box—Find the Box.不要在盒子外面思考——要找到盒子

    对于各种约束和条件边界,应该从更高角度看,忽略一些不适用的约束,并确定你确实拥有自由度。

    一定有更容易的方法

    对于“不能解决的问题”经常问问自己:

    1.  它真的必须完成吗?

    2.  它必须以这种方式完成吗?

    3.  是什么使它如此难以解决?

    4.  这件事为什么是一个问题?

    5.  你是在设法解决真的的问题,还是被外围的技术问题转移了注意力?

    6.  有更容易的方法吗?

    等你准备好了

    Listen to Nagging Doubts—Start When You’re Ready.倾听反复出现的疑虑——等你准备好再开始

    是良好的判断,还是拖延?

           对于无法判断项目是否拖延,可采取一种行之有效的技术构建原型,而对于有困难的地方,可进行“概念验证”(proof of concept)

           最可怕的事情:花了几周认真开发,却发现原来只要一个原型。

    规范陷阱

    注:这里的规范通常就是我们平常说的设计

    程序规范就是把需求规约到程序员能够接管的程度;规范也是与用户的约定,一份隐含的合约。

    Some Things Are Better Done than Described.对有些事情“做”胜于“描述”

    应把需求挖掘、设计以及实现视为同一个过程,而不要信任:需求分析、编写规则、编码是独立的分开进行的。因为这些步骤本身就是无缝的。

    太细的规范可能会演变为“分析瘫痪”(analysis paralysis)

    圆圈与箭头

    盲目采用任何形式方法,其结果往往令人失望

    形式方法缺点:

    1.  大多数形式方法结合图和文字说明,但用户通常喜欢原型

    2.  形式方法鼓励专门化,大家更希望了解整个系统,而不是冰山一角

    3.  元数据让我们运行时改变应用特征,而大多数形式方法鼓励你在对象间建立静态关系

    Don’t Be a Slave to Formal Methods.不要做形式方法的奴隶

    批判地看待方法学而从中提取精华,融合到每项工作中。

    Expensive Tools Do Not Produce Better Designs.昂贵地工具不一定能制作出更好地设计。

    注重实效的团队

    不要留破窗户——对软件质量负责,要及时修复缺陷和错误,可以考虑配置一个“质量官员”;

    煮青蛙——确保每个人都主动监视环境变化,要不要设置一个“首席水情检测官”呢?

    交流——沉默寡言的团队是最糟糕的团队,导致文档、设计、编码……一切工作的混乱;

    不要重复你自己——还是要团队内的交流(项目资料管理员);

    正交性——项目活动不会孤立发生,Organize Around Functionality Not Job Functions.围绕功能,而不是工作职务进行组织;

    自动化——确保一致和准确的方式是使团队所做每件事情自动化;

    给团队每个成员足够空间,支持他们,让他们在项目中以自己的方式闪亮。

    无处不在的自动化

    我们需要保证项目的一致性和可重复性,而人工流程不能保证一致性,也无法保证可重复性,因此我们应该尽可能的使用自动化。

    一切都要自动化

    Don’t Use Manual Procedures.不要使用手工流程

    通过一些自动化工具,如cron等,使任务(例如备份、夜间构建等)在无人照管的情况下自动地、周期地运行。

    让如makefile进行如项目编译、生成代码、回归测试、信息生成(包括Web信息)以及最终的构建等,此类工具还有Ant

    构建自动化:在晚上进行完整构建,运行所有测试

    自动化管理:包括了资料与网站自动生成,一些工作流程自动化等;

    推荐书目《项目自动化之道-如何建构、部署》

    无情的测试

    Test Early,Test Often,Test Automatically.早测试,常测试,自动测试

    测试如捕鱼,捕什么鱼用什么测试

    好的项目拥有测试代码可能比产品代码还要多

    Coding Ain’t Done ‘Til All the Test Run.要到通过全部测试,编码才算完成

    测试种类:

    1. 单元测试:对某个模块进行演练的代码

    2. 集成测试:组成项目的主要子系统能工作,并很好协同

    3. 验证和校验:满足客户需要吗?

    4. 资源耗尽、错误和恢复

    5. 性能测试、压力测试和负载测试

    6. 由真实用户在真实环境条件下进行可用性测试

    测试方法:

    1. 回归测试:测试输出的对比

    2. 测试数据:大量的、强调边界条件的、展现特征统计属性的数据

    3. 演练GUI系统

    4. 对策是进行测试:Use Saboteurs To Test Yout Testing.通过“蓄意破坏”测试你的测试。(故意引发一些测试)

    5. 彻底测试:覆盖分析(Coverage Analysis)Test State Coverage,Not Code Coverage.测试状态覆盖,而不是代码覆盖

    6. 测试时间:当项目开始后,随时测试,千万不要流到最后一分钟

    Find Bugs Once.一个Bug只抓一次.

    全都是写

    文档和代码时同一底层模型的不同视图,不要让文档变成二等公民

    将文档与代码进行结合,使用如JavaDoc之类的工具自动产生文档

    Treat English(Chinese) as Just Author Programming Language.把英语(中文)当作又一种编程语言

    Build Documentation In, Don’t Bolt It On.把文档建在里面,不要拴在外面.

    匈牙利表示法:把变量类型信息放在变量名自身里.

    不应出现源码注释:

    1. 文件种的代码导出的函数列表

    2. 修订历史

    3. 该文件使用其他文件列表

    4. 文件名

    可执行文档:例如数据库Schhema或带有标记的纯文本

    DocBook是一种机遇SGML的标记语言

    极大的期望

    项目的成功是由它在多大程度上满足了用户的期望来衡量

    Gently Exceed Your Users’ Expectations.

    温和地超出用户的期望

    管理期望(managing expectations):主动控制用户对他们能从系统中得到什么应该抱有的希望.

    如果你和用户紧密协作,分享他们的期望,并同他们交流你正在做的事情,那么当项目交付时,就不会发生多少让人吃惊的事情了.

    傲慢与偏见

    Sign Your Work.在你的作品签名

    尊重别人的代码,对自己的代码负责,使自己的签名变成质量的保证。为自己的代码负责,告诉别人“这就是我的代码”。

     

    其他的好书推荐:

    推荐书籍目录如下,后续蛤蟆会陆续增加到本篇当中
    1、《程序员修炼之道》 
    2、《重构》
    3、 《设计模式》
    4、《测试驱动发开》
    5、《UNIX编程艺术》
    6、《算法导论》
    7、《计算机程序设计艺术》
    8、《数据结构》 叫这个数目的书很多,推荐作者是:Ellis Horowitz, Sartaj Sahni, Susan Anderson-Freed 

    9、《代码大全》

    展开全文
  • 原文 1、关心你的技艺 Care About Your Work 如果你不在乎能否漂亮地开发出软件,你又为何要耗费生命去开发软件呢?...不要说事情做不;说明能够做什么。 4、不要容忍破窗户 Don’t Live with Broken Window

    原文

    1、关心你的技艺
    Care About Your Work
    如果你不在乎能否漂亮地开发出软件,你又为何要耗费生命去开发软件呢?

    2、思考!你的工作
    Think!About Your Work
    关掉自动驾驶仪,接管工作。不断地批评和评估你的工作。

    3、提供各种选择,不要找蹩脚的借口
    Provide Options,Don’t Make Lame Excuses
    要提供各种选择,而不是找借口。不要说事情做不到;说明能够做什么。

    4、不要容忍破窗户
    Don’t Live with Broken Windows
    当你看到糟糕的设计、错误的决策和糟糕的代码时,修正它们。

    5、做变化的催化剂
    Be a Catalyst for Change
    你不能强迫人们改变。相反,要向他们展示未来可能会怎样,并帮助他们参与对未来的创造。

    6、记住大图景
    Remember the Big Picture
    不要太过专注于细节,以致忘了查看你周围正在发生什么。

    7、使质量成为需求问题
    Make Quality a Requirement Issue
    让你的用户参与确定项目真正的质量需求。

    8、定期为你的知识资产投资
    Invest Regularly in Your Knowledge Portfolio
    让学习成为习惯。

    9、批判地分析你读到的和听到的
    Critically Analyze What You Read and Hear
    不要被供应商、媒体炒作、或教条左右。要依照你自己的看法和你的项目的情况去对信息进行分析。

    10、你说什么和你怎么做同等重要
    It’s Both What You Say and the Way You Say It
    如果你不能有效地向他人传达你的了不起的想法,这些想法就毫无用处。

    11、不要重复你自己
    DRY—Don’t Repeat Yourself
    系统中的每一项知识都必须具有单一、无歧义、权威的表示。

    12、让复用变得容易
    Make It Easy to Reuse
    如果复用很容易,人们就回去复用。创造一个支持复用的环境。

    13、消除无关事物之间的影响
    Eliminate Effects Between Unrelated Things
    设计自足、独立、并具有单一、良好定义的目的组件。

    14、不存在最终的决定
    There Are No Final Decisions
    没有决策是浇铸在石头上的。相反,要把每项决策都视为是写在沙滩上的,并为变化做好计划。

    15、用曳光弹找到目标
    Use Tracer Bullets to Find the Target
    曳光弹能通过试验各种事物并检查它们离目标有多远来让你追踪目标。

    16、为了学习而制作原型
    Prototype to Learn
    原型制作是一种学习经验。其价值并不在于所产生的代码,而在于所学到的经验教训。

    17、靠近问题编程
    Program Close to the Problem Domain
    用你的用户的语言进行设计和编码。

    18、估算,以避免发生意外
    Estimate to Avoid Surprises
    在着手之前先进行估量。你将提前发现潜在的问题。

    19、通过代码对进度进行迭代
    Iterate the Schedule with the Code
    用你在进行实现时获得的经验提炼项目的时间标度。

    20、使用纯文本保存知识
    Keep Knowledge in Plain Text
    纯文本不会过时。它能够帮助你有效利用你的工作,并简化调试和测试。

    21、利用命令shell的力量
    Use the Power of Command Shells
    当图形用户界面无能为力时使用shell。

    22、用好一种编辑器
    Use a single Editor well
    编辑器应该是你的手的延伸;确保你的编辑器是可配置、可拓展和可编程的。

    23、总是使用源码控制
    Always Use Source Code Control
    源码控制是你的工作的时间机器————你能够回到过去。

    24、要修正问题,而不是发出指责
    Fix the Problem,Not the Blame
    bug是你的过错还是别人的过错,并不是真的很有关系————它仍然是你的问题,它仍然需要修正。

    25、不要惊慌
    Don’t Panic When Debuging
    做一次深呼吸,思考什么可能是bug的原因。

    26、“Select”没有问题
    "Select"Isn’t Broken
    在OS或编译器、甚或是第三方产品或库中很少发现bug。bug很可能在应用中。

    27、不要假定,要证明
    Don’t Assume it - Prove it
    在实际环境中————使用真正的数据和边界条件————证明你的假定。

    28、学习一种文本操纵语言
    Learn a Text Manipulation language
    你用每天的很大一部分事件处理文本,为什么不让计算机替你完成部分工作呢?

    29、编写能编写代码的代码
    Write Code the Writes Code
    代码生成器能提高你的生产率,并有助于避免重复。

    30、你不可能写出完美的软件
    You Can’t Write Perfect Software
    软件不可能完美。保护你的代码和用户,使他们免于能够预见的错误。

    31、通过合约进行设计
    Design with Contracts
    使用合约建立文档,并检验代码所做的事情正好是它声明要做的。

    32、早崩溃
    Crash Early
    死程序造成的危害通常比有问题的程序要小得多。

    33、用断言避免不可能发生的事情
    Use Assertions to Prevent the Impossible
    断言验证你的各种假定。在一个不确定的世界里,用断言保护你的代码。

    34、将异常用于异常的问题
    Use Exceptions for Exceptional Problems
    异常可能会遭受经典的意大利面条式代码的所有可读性和可维护性为题的折磨。将异常保留给异常的事物。

    35、要有始有终
    Finish What You Start
    只要可能,分配某资源的例程或对象也应该负责解除其分配。

    36、使模块之间的耦合减至最少
    Minimize Coupling Between Modules
    通过编写“羞怯的”代码并应用得墨忒耳法则来避免耦合。

    37、要配置,不要集成
    Configure, Don’t Integrate
    要将应用的各种技术选择实现为配置选项,而不是通过集成或工程方法实现。

    38、将抽象放进代码,细节放进元数据
    Put Abstractions in Code ,Details in Metadata
    为一般情况编程,将细节放在被编译的代码库之外。

    39、分析工作流,以改善并发性
    Analyze Workflow to Improve Concurrency
    利用你的用户的工作流中的并发性。

    40、用服务进行设计
    Design Using Services
    根据服务————独立的、在良好定义、一致的接口之后的并发对象————进行设计。

    41、总是为并发进行设计
    Always Design for Concurrency
    容许并发,你将会设计出更整洁、具有更少假定的接口。

    42、使视图与模型分离
    Separate Views from Models
    要根据模型和视图设计你的应用,从而以低廉的代码获取灵活性。

    43、用黑板协调工作流
    Use BlackBoards to Coordinate Workflow
    用黑板协调完成不同的事实和因素,同时又使各参与方保持独立和隔离。

    44、不要靠巧合编程
    Don’t Program by Coincidence
    只依靠可靠的事物。注意偶发的复杂性,不要把幸运的巧合与有目的的计划混为一谈。

    45、估算你的算法的阶
    Estimate the Order of Your Algorithms
    在你编写代码之前,先大致估算事情需要多长时间。

    46、测试你的估算
    Test Your Estimates
    对算法的数学分析并不会告诉你每一件事情。在你的代码的目标环境中测定它的速度。

    47、早重构,常重构
    Refactor Early,Refactor Often
    就和你会在花园里除草】并重新布置一样,在需要时对代码进行重写、重做和重新架构。要铲除问题的根源。

    48、为测试而设计
    Design to Test
    在你还没有编写代码时就开始思考测试问题。

    49、测试你的软件,否则你的用户就得测试
    Test Your Software,ou Your Users Will
    无情地测试。不要让你的用户为你查找bug。

    50、不要使用你不理解的向导代码
    Don’t Use Wizard Code You Don’t Understand
    向导可以生成大量代码。在你把它们合并进你的项目之前,确保你理解全部这些代码。

    51、不要搜集需求——挖掘它们
    Don’t Gather Requirements - Dig for Them
    需求很少存在于表面上。它们深深地埋藏在层层假定、误解和政治手段的下面。

    52、与用户一同工作,以像用户一样思考
    Work with a User to Think Like a User
    要了解系统实际上将如何被使用,这是最好的方法。

    53、抽象比细节活得更长久
    Abstractions Live Longer than Details
    “投资”于抽象,而不是实现。抽象能在来自不同的实现和新技术的变化的“攻击”之下存活下去。

    54、使用项目词汇表
    Use a Project Glossary
    创建并维护项目中使用的专用术语和词汇的单一信息源。

    55、不要在盒子外思考——要找到盒子
    Don’t Think Outside the Box-Find the Box
    在遇到不可能解决的问题时,要确定真正的约束。问问你自己:“它必须以这种方式完成吗?它真的必须完成吗?”

    56、等你准备好再开始
    Start What You’re Ready
    你的一生都在积累经验。不要忽视反复出现的疑虑。

    57、对有些事情"做"胜于"描述"
    Same Things Are better Done than Described
    不要掉进规范的螺旋————在某个时刻,你需要开始编码。

    58、不要做形象方式的奴隶
    Don’t be Slave to Formal Methods
    如果你没有把某项技术放进你的开发实践和能力的语境中,不要盲目地采用它。

    59、昂贵的工具不一定能制作出更好的设计
    Costly Tools Dont’t Produce Better Designs
    小心供应商的炒作,行业教条、以及价格标签的诱惑。要根据工具的价值判断它们。

    60、围绕功能组织团队
    Organize Teams Around Functionality
    不要吧设计师与编码员分开,也不要把测试员与数据建模员分开。按照你构建代码的方式构建团队。

    61、不要使用手工流程
    Don’t Use Manual Procedures
    shell脚本或批文件会一次次地以同一顺序执行同样的指令。

    62、早测试,常测试,自动测试
    Test Early.Test Often.Test Automatically
    与呆在书架上的测试计划相比,每次构建时运行的测试要有效得多。

    63、要到通过全部测试,编码才算完成
    Coding Ain’t Done 'Til All the Tests Run
    就是这样。

    64、通过“蓄意破坏”测试你的测试
    Use Saboteurs to Test Your Testing
    在单独的软件副本上故意引入bug,以检验测试能够抓住它们。

    65、测试状态覆盖,而不是代码覆盖
    Test State Coverage,Not Code Coverage
    确定并测试重要的程序状态。只是测试代码行是不够的。

    66、一个bug只爪一次
    Find Bugs Once
    一旦测试员找到一个bug,这应该是测试员最后一次找到它。此后自动测试应该对其进行检查。

    67、把英语当成又一种编程语言
    English is Just a Programming Language
    像你编写代码一样编写文档:遵守DRY原则、使用元数据、MVC、自动生成,等等。

    68、把文档建在里面,不要栓在外面
    Build Documentation In ,Don’t Bolt It On

    69、温和地超出用户的期望
    Gently Exceed Your User’s Expectations
    要理解你的用户的期望,然后给他们的东西要多那么一点。

    70、在你的作品上签名
    Sign Your Work
    过去时代的手艺人为能在他们的作品上签名而自豪。你也应该如此。

    展开全文
  • 《程序员修炼之道–从小工专家》的读书笔记 《程序员修炼之道–从小工专家》[美]Andrew Hunt / David Thomas 著 马维达 译 看这本书主要使用了检视阅读中略读的方法,大体了解本书所讲的主要内容。 (1)整体来说...
  • PostgreSQL修炼之道:从小工专家

    千次阅读 2017-05-02 17:31:00
    PostgreSQL修炼之道:从小工专家   唐成著 图书在版编目(CIP)数据 PostgreSQL修炼之道:从小工专家/唐成著. —北京:机械工业出版社,2015.4 (数据库技术丛书) ISBN 978-7-111-49872-8 I. P… II. ...
  • 如果你编写正交的系统,好处:提高生产率与降低风险。 设计 对于正交设计,有一种简单的测试方法。一旦设计好组件,问问你自己:如果我显著地改变某个特定功能背后的需求,有多少个模块会受影响,在正交系统中...
  • PostgreSQL修炼之道:从小工专家 为什么要写这本书 PostgreSQL数据库是目前功能最强大的开源数据库,它基本包含了其他所有商业或开源的数据库中能找到的功能,甚至还包含了一些商业数据库中没有的功能。它是最...
  • 最近用两天多的时间读了一本和工匠有关的书籍《程序员修炼之道-从小工专家》这本书,现在分享给大家,因本人能力有限,拙劣之处请包涵。从这本书的名字说起,这本书现在的名字体现不出来书中的主题内容,书的原名...
  • 开发内功修炼CPU篇

    2020-04-17 21:30:55
    我账号的名称之所以命名为开发者内功修炼,就是想我在内核、物理层上的一些理解思考总结分享给大家,帮助这些同学提升自己的技术木桶短板。本轮数十篇的分享中,我我工作中关于CPU底层性能的先放了出来,后面还...
  • 程序员修炼之道-书评

    千次阅读 2016-04-10 11:20:08
    要提供各种选择,而不是找接口,不要说事情做不:说明能够做什么 2.软件的熵 启发:不要容忍破窗户 Don’t Live with Broken Windows 当你看到糟糕的设计,错误的决策和糟糕的代码时,修正他们 3.石头汤与煮青蛙 ...
  • 我最近一直在写读书札记,也许很多人不喜欢看,我却乐此不疲,能够自己的感悟跃然于纸上,感觉就像一个“好”的程序员,你觉得呢?今天继续来看编程之道的下半部分,看看我在通往优秀程序员的路上还需要做些什么。...
  • 代码生成器能提高你的生产率,并有助于避免重复。 30. 你不可能写出完美的软件 软件不可能完美。保护你的代码和用户,使它们免于能遇见的错误。 31. 通过合约进行设计 使用合约建立文档,并检验代码所做...
  • 读书之《程序员修炼之道》

    千次阅读 2015-03-11 10:22:19
    读书分享《程序员修炼之道》 0.0几篇序 读书之前首先看到的内容,让大家知道这不是一本烂书,本书从项目管理,软件架构和设计、代码编写和测试,各方面都有精彩的阐述。序中的重点内容: 《领悟程序员的哲学》 l 这...
  •  25. RadioButtonID 。  26. 对话窗口上的 ICON 图标。 【 7 】 Android 利用交互与手机模块把持  1. PendingIntent 与 AlarmManager 。  2. PendingIntent 与 SmsManager 。  3. Intent 与 ...
  • 网络规划设计师5天修炼 新近主著、参编图书有《攻克要塞-系统集成项目管理工程...
  • 程序员内功修炼

    2018-08-15 17:35:00
    算法思想:它重复地走访要排列的数列,一次比较两个元素,如果他们的顺序错误就他们交换过来 走访数列的工作是重复地进行直到没有再需要交换,也就是说数列已经排序完成。 冒泡排序就是要每趟排序过程中通过两两...
  • 不要抱怨,总是问题归咎于别人; 辩解听起来很愚蠢,说话之前先将借口清除,谈话之前自己先预演一遍; 提供选择,而不是找借口,不要说做不,而是能够做什么挽回局面; 2 软件的熵 破窗口理论; 不要容忍任何...
  • 上一篇文章记录了GDB调试从入门熟练掌握的学习全过程。点击链接查看:【软件开发底层知识修炼】十九 GDB调试从入门熟练掌握超级详细实战教程学习目录 还记得在以前的学习Binutils工具的时候,学习了很多工具来...
  • 程序员的修炼之道从小工专家阅读笔记03 在书的最后,“注重实效的程序员之快速参考指南”列出书中的提示和检查清单。方便复习。 1.关心你的技艺 Care About Your Craft 如果你不在乎能否漂亮的开发出软件,你又...
  • ### 25、Don't Panic 不要恐慌(不要对未来感到恐惧) 在你开始调试之前,选择恰当的思维方式十分重要。你需要关闭每天用于自我保护的许多防卫措施,忘掉你可能面临的任何项目压力,并让自己放松下来。 从何处开始? ...
  • 《高效能程序员的修炼》读书笔记

    千次阅读 2015-11-08 22:04:52
    《高效能程序员的修炼 》 EffectiveProgramming More Than Writing Code  2013年 作者: Jeff Atwood 问答网站stack overflow创始人  软件开发远不只是写代码那么简单------   软件开发过程中的人文因素。 做个...
  • 小菜读书---《程序员修炼之道–从小工专家》 可能由于水平有限,对于其中一些珠玑理解没有那么强的感受。这里主要讲一些我感触特别深的点。 一、关于知识资产的概念对我而言这是一个全新的概念,想想...
  • 软件测试修炼之道

    2020-06-04 17:33:05
    软件测试发展今天,已经逐渐形成一门学科,但是还不够系统。  初学者面对铺天盖地的资料应该如何选取?应该从哪里入手?如何迅速的掌握各种业务各项测试技能以便开展工作?在保证测试质量的前提下,一日内编写或...
  • OKR 强调上下对齐、左右对齐,是为了帮助组织树立贯穿整体的目标,资源集中企业的重要战略板块,帮助企业实现突破。 以上,对OKR 做了一个简单的介绍。企业如果需要实施OKR,在领会OKR 思想精髓的基础上,可以...
  • 这对中台服务团队会起督促作用,同时调查的结果也为提高团队的服务能力提供了非常有价值的参考信息。 8.3 区块链组织:面向未来的社会化组织协作方式 本节来探讨未来社会的组织形态。近几年随着数字货币的火热,...
  • ● 请讲述一个例子,说明你如何获得了技能,并且这些技能转化了实际工作中。 可以看出,问问题的关键点是:要问点子上、问题短而精、多问基于事实的行为问题(为什么这么做)、少问假设性问题。 除问好问题外...
  • 1.针对软考难的考试,结合2017年以前所有历年试题讲解...3.通过科学的、分析统计的方法找到网络规划设计师重点、难点、要点,提高考生复习效率,减少不必要的知识复习时间。 4.包含上午考试、案例考试、论文的讲解。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,482
精华内容 1,392
关键字:

怎么把修炼提高到25