高效程序员的45个习惯——敏捷开发修炼之道

《高效程序员的45个习惯——敏捷开发修炼之道》

[美]Venkat Subramaniam / Andy Hunt 著 钱安川 郑柯 译

--------------------- 
原文:https://blog.csdn.net/libing403/article/details/72904713 



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

作者是在企业从事软件开发的,可以想到作者必定是做了大量的实践而不是理论的研究,从作者简介、推荐序就可以了解到,这本书并不是在论述“敏捷开发”这样的一个方法论,而是较全面论述如何在实践“敏捷开发”,从题目的“45个习惯”就可知道这是告诉了我们敏捷开发的具体行动是什么,如何运用这45个习惯。

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

作者详细论述了敏捷开发的这45个习惯以及如何在实践中运用。在谈及每个习惯前,都引入一段话,旁边配有一个魔鬼木刻像,这段话是一些诱使你养成不良习惯的观点或做法,作者会讨论这些不良习惯或做法的危害。与这些诱惑相对的是敏捷开发的良好习惯,在每个良好习惯最后,会出现一位守护天使木刻像,并在旁边给出我们应该遵循的一些良策。整本书采用这样一种完全一致的逻辑,让人很容易理解和掌握作者的核心思想。

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

对我来说书本里说的敏捷开发方法在其特定的的环境下式很有效的,但是事情都有两面性,作者很清楚这一点,因此在每个推荐的策略后还会附上“平衡的艺术”这样的几句说明,提醒读者使用这些策略的时候要把握好分寸,以达到平衡点,获得最好的效果。因此在运用这些策略的时候,需要注意平衡的艺术,才能避免出现反面效应。

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

作者所论述的方法涉及软件开发的整个生命周期,其中的很多策略有助于我理解领导的管理策略,实现和团队成员的高效合作,对如何做好自己工作有很多启发。通过这本书我了解到了一些新的概念和方法,例如单元测试、持续集成、测试驱动开发。



高效程序员的45个习惯

态度决定一切

1. 做事

出了问题,大家的重点是做事。你应该把重点放在解决问题上,而不是在指责犯错者上面纠缠。

指责不会修复bug。把矛头对准问题的解决方法,而不是人,这是真正有用处的正面效应。

勇于承认自己不知道的答案,这会让人感觉放心。一个重大的错误应该被当作是一次学习而不是指责他人的机会。团队成员们在一起工作,应互相帮助,而不是互相指责。
2. 欲速则不达

千里之提,溃于蚁穴,一次又一次的快速修改,每次都不探究问题的根源,久而久之就形成一个危险的沼泽地,最终会吞噬整个项目的生命。
工作压力之下,不深入了解真正的问题以及可怕后果,就快速修改代码,这样只是解决表面问题,最终会引起大问题
要理解开发过程;不要孤立地编码;使用单元测试。
不要坠入快速的简单修复之中,要投入时间和精力保持代码的整洁、敞亮。
在项目中,代码应该是敞亮的,不应该有黑暗死角。你也许不知道每块代码的细节,或者每个算法的步骤,但是你对整体的相关知识有很好的谅解。没有任何一块代码被警戒线或者“切勿入内”的标志隔开。
3.对事不对人

对于决策和方案选择,要专业而不是自我。
对事不对人。让我们骄傲的应该是解决了问题,而不是比较出谁的主意更好。
一个团队能够公正地讨论一些方案的优点和缺点,你不会因为拒绝了有太多缺陷的方案二伤害别人,也不会因为采纳了某个不甚完美(但是更好的)解决方案二被人忌恨。
4.排除万难,奋勇前进

当发现问题,或其他人代码有问题,要诚实,要有勇气说出实情,有时,这样做很困难,所以我们要有足够的勇气。
勇气会让人觉得有点不自在,提前鼓足勇气更需要魄力。但有些时候,它是扫除障碍的唯一途径,否则问题就会进一步恶化下去。鼓起你的勇气,这能让你从恐惧中解脱出来。
学无止境

5.跟踪变化

敏捷需要持续不断的学习和充电,给自己投资,让自己与时俱进。
迭代和增量式学习;了解最新行情;参加本地的用户组活动;参加研讨会议;如饥似渴地阅读。
你不需要精通多有技术,但是需要清楚知道行业的动向,从而规划你的项目和职业生涯。
你能嗅到将要流行的新技术,知道他们已经发布或投入使用。如果必须把工作切换到一种新的技术领域,你能做到。
6.对团队投资

“午餐会议”是在团队中分享知识非常好的方式。通过午餐会议可以增进每个人的知识和技能,并帮助大家聚集在一起进行沟通交流。唤起人们对技术和技巧的激情,将会对项目大有裨益。
每周要求团队的一个人支持讲座,介绍一些概念,演示工具,或者一本书等等。
这样做,会让每个人都觉得自己越来越聪明。整个团队都要了解新技术,并指出如何使用它,或者指出需要注意的而缺陷。
7.懂得丢弃

敏捷根本之一是拥抱变化,变化是永恒的。

学习新的东西,丢弃旧的东西。在学习一门新技术的时候,要丢弃会阻止你前进的旧习惯。毕竟,汽车要比马车车厢强得多。

新技术会让人感到有一点恐惧。你确实需要学习很多东西。已有的技能和习惯为你打下了很好的基础。但是 不能依赖他们。
8. 打破砂锅问到底

不停地问为什么。不能只满足与别人告诉你表面现象。要不停地提问直到你明白问题的根源。
不仅要解决问题,还要深入理解问题。
这就好比是从矿石中采掘贵重的珠宝。你不停地筛选掉无关的物质,一次比一次深入,直到找到发光的宝石。你要感觉到真正地理解了问题,而不是只知道表面的症状。
9.把握开发节奏

很多失败的项目中,基本都是随意安排工作计划,没有规律。敏捷项目会有一个节奏和循环,让开发更轻松。
解决任务,在事情变得一团糟之前。保持事件之间稳定重复的间隔,更容易解决常见的重复任务。
项目开发需要有一致和稳定的节奏。编辑,运行测试,代码审核,一致的迭代,然后发布。如果知道什么时候开始下一个节拍,跳舞就会更加容易。
10.让客户做决定

在设计方面,做决定的时候必须有开发者参与,但业务方面的决定不应该参与。

开发者、经理或者业务分析师不应该做业务方面的决定,用业务负责人能够理解的语言,向他们详细解释遇到的问题,并让他们做决定。

业务应用需要开发者和业务负责人互相配合来开发。这种配合的感觉应该像一种良好的、诚实的工作关系。
11.让设计指导而不是操纵开发

好的设计仍然十分重要,但是设计满足实现即可,不要太详细。
设计分两层:战略和战术。前期的设计属于战略,不应深入到具体细节。
好设计是一张地图,它会进化。设计指引你向正确的方向前进。
好的设计应该是正确的,而不是精确的。也就是说,它描述的一切必须正确的,不应该涉及不确定或者可能会发生变化的细节。它是目标,不是具体的处方。
12.合理地使用技术

盲目地为项目选择技术框架,就好比是为了节省税款而生孩子,这是没有道理的。

在考虑新的技术或框架之前,先把你需要解决的问题找出来。然后考虑:

(1)这个技术框架真的能解决这个问题吗?要确保它能解决你的问题,并没有任何副作用。

(2)你将会被它拴住吗?一些技术是贼船,一旦你使用了它,就会被它套牢,再也不可能回头。

(3)维护的成本是多少?

根据需要选择技术。首先决定什么是你需要的,接着为这些具体的问题评估使用技术。对任何要使用的技术,多问一些挑剔的问题,并真实地做出回答。

新技术就应该像新的工具,可以帮助你更好地工作,它自己不应该成为你的工作。

13.保持可以发布

已提交的代码应该可以随时行动。

防止提交的代码影响系统的状态和整个团队的效率:

(1)在本地运行测试,通过所有单元测试

(2)检出最新的代码。

(3)提交代码。

保持你的项目时刻可以发布。保证你的系统随时可以编译、运行、测试并立即部署。

保持可以发布,不管什么时候,你的老板、董事长、质量保障人员、客户或者你的配偶来公司参观项目的时候,你都能自信并毫不犹豫给他们演示最新的构建的软件。你的项目一直处于可以运行的稳定状态。

14.提早集成,频繁集成

在产品的开发过程中,集成是一个主要的风险区域。你的子系统不停增长,而不去做系统集成,就等把自己置身于越来越大的风险中。
即使你觉得独立开发时速度更快,也不要避免或推迟集成。你一般需要每天集成几次,最好不要2~3天才集成一次。决不要做大爆炸式得集成。
提早集成,频繁集成。代码集成是主要的风险来源,要规避这个风险,只有提早集成,持续而有规律地集成。
如果你真正做对了,集成就不再会使一个繁重的任务。它只是编写代码周期中的一部分。集成时产生的问题,都会是小问题并且容易解决。
15.提早实现自动化部署

系统能在你的机器上运行,但是同时也需要能够部署在用户的机器上。
自动化部署系统,会更容易适应互相依赖的变化。
一开始就实现自动化部署应用。使用部署系统安装你的应用,在不同的机器上用不同的配置文件测试依赖的问题。质量保证人员要像测试应用一样测试部署。
这些工作都是无形的。系统的安装或者应该简单、可靠。一切都很自然。
16.使用演示获得频繁反馈

你无法冻结需求,正如你无法冻结市场、竞争、知识、进化或成长一样。
如果你期望用户在项目开始之前,就能给你可靠和明确的需求,那就大错特错了。
应该定期地,每隔一段时间,例如一个迭代的结束,就与客户会晤,并且演示你已经完成的功能特性。
清晰可见的开发。在开发的时候,要保持应用可见(而且客户心中也要了解)。每隔一周或者两周,邀请所有的客户,给他们演示最新完成的功能,积极获得他们的反馈。
项目启动了一段时间后,你应该进入一种舒适的状态,团队与客户建立了一种健康的富有创造性的关系。突发时间应极少发生。客户应该能感觉到,他们可以一定程度上控制项目的方向。
17.使用短迭代,增量式发布

迭代开发是,在小且重复的周期里,你完成各种开发任务:分析、设计、实现、测试和获得反馈,所以叫迭代。
对付大项目,最理想的办法就是小步前进,这也是敏捷方法的核心。
使用短迭代和增量开发,可以让开发者更加专注于自己的工作。如果别人告诉你有一年的时间来完成系统,就你会觉得时间很长。
增量式开发。发布带有最小却可用的功能开的产品,每个增量开发中,使用1~4周左右迭代周期。
迭代让人感觉非常专注且具有效率。你能看到一个实际并且确切的目标。严格的最终期限迫使你做出一些艰难的决策,没有留下长期悬而未决的问题。
18.固定价格就意味着背叛承诺

固定价格的合同是敏捷团队的一点难题。可以试试下面的方法:

(1)主动提议先构建系统的最初的、最小的和有用的部分。

(2)第一个迭代结束时客户有两个选择:可以选择一系列新的功能,继续进入下一个迭代;或者可以取消合同,仅支付第一个迭代的几周费用。

(3)如果他们选择继续前进,应该就能很好地预测下一个迭代工作。

基于真实工作的评估。让团队与客户一起,真正地在当前项目中工作,做具体实际的评估,有客户控制他们要的功能和预算。

敏捷反馈

19.守护天使

代码频繁地变化,自动化单元测试是维持代码健康状况的守护天使。

组合本地单元测试,运行每个编译,构架机器不断编译和运行单元测试,这样你就拥有了一个守护天使。

单元测试是一种最受欢迎的敏捷实践,帮你起步的资料有很多,例如《单元测试之道》,《项目自动化之道》。

单元测试的理由很多:

(1)单元测试能及时提供反馈

(2)单元测试让你的代码更加健壮。

(3)单元测试是有用的设计工具。

(4)单元测试时让你自信的后台。

(5)单元测试时解决问题的探测器

(6)单元测试时可信的文档。

(7)单元测试时学习工具。

使用自动化的单元测试。好的单元测试能够让你的代码问题提供及时警报。如果没有到位的单元测试,不要进行任何设计和代码修改。

如果代码没有测试,你会觉得不舒服,就像是在高空作业没有系安全带一样。

20.先用它再实现它

编程之前,先写测试,你就会站在代码用户的角度来思考,而不仅仅是一个单纯的实现者。
将TDD作为设计工具,它会为你带来更简单更有效的设计。
这种感觉就是,只在有具体理由的时候才开始编码。你可以专注于设计接口,而不会被很多实现的细节干扰。
21.不同环境,就有不同问题

运用持续集成工具,要在多个平台上测试,你只要为每个平台设置持续集成系统就行了。
使用持续集成工具,在每一种支持的平台和环境中运行单元测试,要积极地寻找问题,而不是等问题来找你。
这既是在做单元测试,也是跨越不同的世界的单元测试。
22.自动验收测试

使用FIT(集成测试框架),可更能容易地使用HTML表格定义测试用例,并比较测试结果数据。客户可以定义带有新功能的使用样本。
为核心的业务逻辑构建测试。让你的客户单独验证这些测试,要让它们想一般的测试一样可以自动运行。
23.度量真实的进度

时间表很难真实反映工作的完成状况,因此它不能用来进行项目的计划、评估或者表现评估。
在你最后真正完成一项任务时,要清楚知道完成这个任务正真花费的时间,这可以为下一次估计工作量提供参考。
不要用不恰当的度量来欺骗自己或者团队。要评估那些需要完成的待办事项。
要清楚哪些任务已经完成,哪些没有完成,以及它们的优先级,这样你就会心里有数,觉得很舒服。
24.倾听用户的声音

当出了错误,你要尽可能地提供详细信息。
黑屏和含义不明的“退出”按钮是很不友好的行为。
不管是产品bug,还是文档bug,或者用户理解bug,那都是团队行为,而不是用户问题。
每一个抱怨的背后隐藏了一个事实。找出真相,修复真正的问题。
对客户的愚蠢抱怨,即不要生气,也不要轻视。
没有愚蠢的用户,只有愚蠢,自大的开发人员。


敏捷编码

25.代码要清晰地表达意图

设计软件有两种方式。一种是设计得尽量简单,明显没有缺陷。另一种是设计复杂,没有明显的缺陷。
开发代码时,应该更注重可读性,而不是只图自己方便。
要编写清晰的而不是讨巧的代码。
向代码阅读者明确表明你的意图。可读性差的代码一点都不聪明。
应该让自己或团队任何人,可以读懂自己一年前写的代码,而且只读一遍就知道它的运行机制。
26.用代码沟通

建立代码文档无外乎两种方式:利用代码本身;利用注释来沟通代码之外的问题。
变量名运用正确、空格使用得当、逻辑分离清晰,以及表达式非常简洁。
如何命名很主要,使用精心挑选的名称和清晰的执行路径,代码几乎不需要注释。
为代码中的每个类或模块添加一个短小的描述,说明其目的以及是否有任何特别需求。
用注释沟通。使用细心选择的、有意义的命名。用注释描述代码意图和约束。注释不能替代优秀的代码。
注释就好像是你的朋友,可以先阅读注释,然后快速浏览代码,从而完全理解它做了什么,以及如何做。
27.动态评估舍取

没有最佳解决方案

动态评估权衡。考虑性能、便利性、生产力、成本和上市时间。

如果性能表现足够了,就将注意力放在其他因素上。
不要为了感觉上的性能提升或者设计上的优雅,而将设计复杂化。
即使不能面面俱到,你也应该觉得得到了最重要的东西-客户认为有价值的特性。
过早的优化是万恶之源。
真正的高性能系统,从一开始设计时就在向这个方向努力。
28.增量式编程

增量式编程可以精炼并结构化你的代码。

采取增量式编程,会倾向于创建更小的方法和更具体的内聚类

在很短的编辑/构建/测试循环中编写代码。这要比花长时间仅仅做编写代码的工作好得多。可以创建更加清晰、简单、易于维护的代码。
29.保持简单

不要过分进行设计,也不要将代码过分复杂化。不要过分着迷一些文章的设计模式,扪心自问,是不是真的需要它。
开发可以工作的,最简单的解决方案。除非有不可辩驳的原因,否则不要使用模式、原则和高难度技术之类的东西。
当你觉得所编写的代码中没有一行是多余的,并且仍能交付全部的功能时,这种感觉就对了。这样的代码容易理解和修改。
30.编写内聚的代码

内聚性用来评估一个组件(包、模块或配件)中成员功能的相关性。
内聚性的代码更容易维护,具有更高的可重用性。
让类的功能尽量集中,让组件尽量小。要避免创建很大的类或组件,不要创建无所不包的大杂烩类。
31.告知,不要询问

作为某段代码的调用者,不应该基于被调用对象的状态类做出任何决策,更不能去改变该对象的状态。
命令与查询分离开来,常规命令可能改变状态,查询不应该有任何副作用,不会改变对象的状态。
不要抢别的对象或者组件的工作。告诉它做什么,然后盯着自己的指责就好了。
32.根据契约进行替换

针对is-a关系使用继承;针对has-a或uses-a关系使用委托。
通过替换代码来扩展系统。通过替换遵循接口契约的类,来添加并改进功能特性。要多使用委托而不是继承。
相对于继承来说,委托更加灵活,适应力也更强。
继承不是魔鬼,只是长久以来被大家误解了。
如果你不确定一个接口做出了什么样的承诺,或是有什么样的需求,那就很难提供一个对其有意义的实现了。
敏捷调试

33.记录解决问题的日志

好的日志格式:问题发生日期|简述|解决方案|引用文章或网址|代码、设置或对话框的截屏。
要将日志保存为可供计算机搜索的格式,就可以进行关键字搜索以快速查找细节。
维护一个问题及其解决方案的日志。保留解决方案是修复问题过程的一部分,以后发生相同或类似问题时,就可以很快找到并使用了。
记录问题的时间不能超过在解决问题上花费的时间。
找到以前的解决方法非常关键。
如果通过搜索web,发现没人曾经遇到同样的问题,也许搜索的方式有问题。
要记录团队做出一个重要决策的原因。
34.警告就是错误

将警告视为错误。签入有警告的代码,就跟签入有错误或者没通过测试的代码一样,都是极差的做法。
签入构建工具中代码不应该产生任何警告信息。
由于编译器的bug或第三方工具或代码的原因,有些警告无法消除。
弃用的方法被弃用是有原因的。不要再使用它们了。至少,安排一个迭代来将它们安全地移除掉。
35.对问题各个击破

如果代码依赖其他模块,就应该使用mock对象,来把它从其他模块中分离开。这样做不但让代码更加健壮,且在发生问题时,也更容易定位来源。
用原型进行分离。
对问题各个击破。在解决问题时,要将问题域与其周边隔离开,特别是在大型应用中。
面对必须要隔离的问题时,感觉就像在一个茶杯中寻找一根针,而不是大海捞针。
如果将代码从其运行环境中分离后,问题消失不见了,这有助于隔离问题。
另一方面,如果将代码从其运行环境中分离后,问题还在,这同样有助于隔离问题。
在向问题发起攻击之前,先查找你的问题解决日志。
以二分查找的方式来定位问题是很有用的。也就是说,将问题空间分为两半,看看哪一半包含问题。再讲包含问题的一半进行二分,并不断重复这个过程。
36.报告所有的异常

捕捉到异常后,为了不看到编译器的提示,就把异常忽略掉–这种做法是危险的。
处理或是向上传播所有的异常。不要将它们压制不管,就算是临时这样做也不行,在写代码时要估计到会发生的问题。
当出现问题时,心里知道能够得到抛出的异常。而且没有空的异常处理方法。
决定由谁来负责处理异常是设计工作的一部分。
不是所有的问题都应该抛出异常。
报告的异常应该在代码的上下文中有实际意义。
要传播不能处理的异常。
37.提供有用的错误信息

要区分错误类型。程序缺陷 | 环境问题 | 用户错误
展示有用的错误信息。提供更易于查找错误细节的方式。发生问题时,要展示出尽量多的支持细节,不过别让用户陷入其中。
错误信息有助于问题的解决。当发生问题时,可以详细研究问题的细节描述和发生上下文。
像“无法找到文件”这样的错误信息,就其本身而言无助于问题的解决。“无法打开/project/file以供提取”这样的信息更加有效。
没有必要等待抛出异常来发现问题。在代码关键点使用断言以保证一切正常。当断言失败时,要提供与异常同样详细的信息。
在提供更多信息的同时,注意保密。
提供给用户的信息可以包含一个主键,以便于在日志文件或审核记录中定位相关内容。
敏捷协作

38.定期安排会面时间

只有开发团队可以参与scrum例会。
站立开发,回答三个问题: 昨天收获 | 今天计划 | 面临问题
使用立会。立会可以让团队达成共识。保证会议短小精悍不跑题。
大家都盼着立会。希望彼此了解各自的进度和手上的工作,而且不怕把各自遇到的问题拿出来公开讨论。
会议会占用开发时间,所以要尽量保证投入的时间有较大的产出。时间10-15分钟比较理想。
提前预定时间。
要注意报告的细节。会议中给出具体的进度,但不要陷入细节中。
迅速地开始可以保证会议短小。不要浪费时间等着会议开始。
39.架构师必须写代码

不可能在PowerPoint幻灯片中进行编码。
新系统的设计者必须要亲自投入到实现中去。
鼓励程序员参与设计,程序员在拒绝设计的同时,也就放弃了思考。
优秀的设计从积极的程序员那里开始演化。积极的编程可以带来深入的理解。不要使用不愿意编码的架构师-不知道系统的真实情况,是无法展开设计的。
不要允许任何人单独进行设计,特别是你自己。
40.实行代码集体所有制

相比找出谁的主意更好、谁的代码实现很烂而言,解决问题,并让应用满足用户的期望更为重要。
有好几双眼睛盯着一段代码,这样可以提升代码的整体质量,使其易于维护和理解,并降低出错率。
要强调代码的集体所有制。让开发人员轮换完成系统不同模块中的不同任务。
项目中的绝大部分的代码都必须能轻松应对。
如果不向整个团队分享知识,反而增加了丧失知识的风险。
41.成为指导者

教学相长-与团队其他人一起共事是很好的学习机会。
通过详细解释自己知道的东西,可以使自己的理解更深入。
与别人共事,激励他们变得更出色,同时可以提升团队的整体实力。
我们要成为指导别人的人,而不是折磨别人的人。
成为指导者。分享自己的知识很有趣-付出的同时便有收获。还可以激励别人活得更多的成果,而且提升了整个团队的实力。
如果一直在就同一个主题向不同的人反复阐述,不妨记录笔记,此后就此问题发一篇文章,甚至是一本书。
成为指导者是向团队进行投资的一种极佳的方式。
结对编程是一种进行高效指导的、很自然的环境。
42.允许大家自己想办法

授人以鱼,三餐之需;授人以渔,终生之用。
作为指导者,应该鼓励、引领大家思考如何解决问题。
给别人解决问题的机会。指给他们正确的方向,而不是直接提供解决方案。每个人都能从中学到东西。
用问题来回答问题,可以引导提问的人走上正确的道路。
如果有人真的陷入胶着状态,就不要折磨他么了。告诉他们答案,再解释为什么是这样。
43.准备好后再共享代码

完成一项任务后,应该马上提交代码,不应该让代码在开发机器上多停留一分钟。如果代码不能被别人集成使用,那又有什么用处呢?
通常情况下,提交的文件应该与一个特定的任务或是一个bug的解决相关。
要保证在提交代码之前,所有的单元测试都是可以通过的。使用持续集成是保证源代码控制系统中代码没有问题的一种良好方式。
准备好后再共享代码。绝不要提交尚未完成的代码。故意签入编译未通过,或没有通过单元测试的代码,对项目来说,应被视为玩忽职守的犯罪行为。
仍然应该频繁提交代码。
44.做代码检查

代码刚完成时,是寻找问题的最佳时机。
要寻找深藏不露的程序bug,正式地进行代码检查,其效果是任何已知形式测试的两倍,而且是移除80%缺陷的唯一已知方法。
复查所有代码。对于提升代码质量和降低错误率来说,代码复查是无价之宝。
不进行思考,类似于橡皮章一样的代码复查没有任何价值
代码复查需积极评价代码的设计和清晰程度,而不只是考量变量名和代码格式是否符合组织的标准。
如果不及时跟进讨论中给出的建议,代码复查时没有实际意义的。
要确保代码复查人员得到每次复查活动的反馈。
45.及时通报进展与问题

接收一个任务,就意味着做出了准时交付的承诺。
如果遇到技术难题,看起来不能准时完成,要积极通知其他各方,就等于给机会大家提前找出解决问题的方案。
即使通报进展与问题,他们也很愿意了解目前的进展状况,他们会知道合适应提供帮助。
及时通报进展与问题。发布进展状况,新的想法和目前正在关注的主题,不要等着别人来问项目状态如何。
做好及时通报进展与问题,当经理或同事询问工作进展、最新的设计、或研究状况时,不会感到头痛。

猜你喜欢

转载自www.cnblogs.com/chglog/p/9907630.html