概述
言之有物,论之有据才是有效的交谈。
我们是工程师,我们的理想是做出完美的产品,我们希望人类能够通过我们的产品来改变某种生活习惯。在很多情况下我们都在默默的付出,为商务人员对客户的售后提供强力而有效的技术保障。可能是因为我们习惯了默默的奉献,平时没有注意过与人交流,故而会出现自己明明知道的东西却说不出来的情况。我们是曾经努力过,我们是做出许多傲人的成绩,但是如果我们不能说出来,别人会知道吗?难道能让别人去猜我们是什么样的人?
默默的付出其实就是在闭门造车,我们要把自己的想法的打算说出来,我们要告诉产品经理我们队建设良好应用的看法。我们要告诉领导,我们对架构的设计。我们要告诉其它工程师,我们对代码的想法。或许你真的是才华横溢,但如果连介绍自己都不会,没人会看好你。我们是工程师,不是程序员也不是码农,我们需要为自己的闭门造车打开一扇窗户。
本文主要是以我亲身的经历,从发言者的角度来探索该如何去发言,如何表达出内心的想法。本文也是我对自己犯过的错的反思。
问题
我们勤奋努力,我们有理想有追求,我们认为做比说更重要,但是我们无法完美的表达自己,我们的辛苦几乎不被人理解。
层次
层次就是对具体事物的抽象,想要有效的表达你的思想。不要再试图向业务人员/客户或与项目不相干的人员介绍你的代码,他们只关心功能。我曾经试过向客户从技术角度来解释我所负责的项目的优势,我告诉他以我们的的系统经过预编译,多级缓存等策略优化后,我们的系统能够在双机环境下吞吐量达到300。客户只回复了我:"xx公司的系统并发能达到5000。"听见客户这么说我真的想给他解释清楚在双机条件下涉及到大数据分析的时候,我们无法使用内存存储全部数据,所谓的并发5000真的是不可能,xx公司肯定是在骗人。
工程师都知道,系统访问一次数据库都需要几十至数百毫秒,何况我们业务的要求每次核心操作都需要操作数十次数据库中的数据。先不说应用进程与数据库进程之间的通信损耗,单是磁盘寻址时间就是现代服务器无法克服的性能瓶颈。但是我们能告诉客户吗?即便花上一两个小时给客户分析明白为什么说300就是极限,为什么5000是骗人又有什么意义呢?客户关心的只是业务,只要能在保证数据精准无差的前提下把功能给实现了,这就是合格。
一个项目有技术层次的理解,有业务层次的理解,有对细节方面的理解,也有对整体流程的理解。我们要给项目进行一个抽象,分别建立出业务层,架构层,代码层和核心功能层,简要介绍层。当遇到一个圈外人只想知道这个项目能干嘛的时候,我们只需要给别人简单的说一下简要介绍层的知识。例如当一个从没用过微信的人问你微信可以干嘛,你就应该回答他:“微信是一个实时聊天工具,可以免费的跟朋友进行聊天,通话与视频。”可以试想一下如果你拿业务层的知识来回答:“微信可以发表情,表情是一种比聊天更好玩的交流方式。可以建群聊,可以发朋友圈,朋友圈是。。。”,这样对方一定很疑惑。如果你直接回答:“微信是一个C/S架构的,有数万台服务集群提供服务,拥有2亿用户高性能高可用的应用。。。”对方一定会直接懵了。
在向别人介绍你你自己或你的产品之前,首先你要对要介绍的内容根据听众的需求进行抽象,抽象的方法就是尽量讲些让听众能够清晰理解的,尽量少用专业名词。当然恰当的使用专业名词更能说明你的专业性。
条理
条理不清晰是一个贬义词,意思是说一个人说话天马行空,无迹可寻。条理不清晰就意为着可能你滔滔不绝的长篇大论过后,听众都不知道你在说什么。
以你工作中都是如何进行性能优化这个话题为例。你可能不假思索的就可以回答:
- 首先我会优化慢SQL,因为在现在系统中一般情况下性能瓶颈都是出现在数据库上,所以第一步先优化SQL。
- 代码上的优化,如不要在循环中写异常捕获等具体优化方法。
- 看系统中有没有长时间阻塞的线程,优先进行去锁优化,如果实在需要保证线程安全,那就尽量使用轻量级锁,读写锁,注意重入锁等作为优化策略。
- 其次根据实际需要设置大小合适的堆空间,然后选择合适的垃圾收集算法(如注重响应时间就选择CMS或G1)。
上述回答的确是一般的优化方法,你能回答以上的答案可以证明你确实做过性能优化,知道一般的优化点在哪里,但是这么讲解着实有不妥之处。当我们要回答一个问题时,我们首先需要知道在哪会发生这个问题,然后寻找问题发生的原因,最后再提出解决方案,动手解决问题。性能优化和我们在生活中遇见的大多数问题一样,没有什么固定程序的解决方案。
还回到上个问题上面,当我们发布性能优化的论述时,如果按照以下步骤可能有条理点:
当项目不再能满足性能需求时,首先我们需要找到性能的瓶颈点。可以通过linux的top命令分析一下各个服务器的主要瓶颈是在cpu上、内存上还是I/O上。
首先是应用服务器,如果瓶颈在CPU上,首先定位最耗资源的进程,借助jvm的一些工具如JProfiles,jvisualvm等工具我们还可以将问题定位到代码上。然后再详细分析哪些操作造成了高密度的CPU运算,尝试是否有优化的余地。
如果系统CPU阻塞时间比很大且I/O负载过高,则首先去分析这个负载是来自于磁盘还是网卡,则尝试寻找降低阻塞原因,找到硬件资源瓶颈,然后使用NIO等技术降低系统阻塞。
如果系统内存占用很大,则需要定位具体进程。如果占用内存过大的是我们的应用,则需要查看JVM堆空间设置,看是否是堆空间设置不合理或者使用了大量的直接内存而没有释放。
如果还没定位到问题,则尝试分析JVM中的线程快照,看是否有死锁或长时间持有互斥锁的线程,并尝试优化这些。
接着才是垃圾回收策略的等虚拟机参数级的优化。
若问题在以上应用服务器优化思路下没有优化空间,或者优化后也无法满足性能需求,可以考虑布置集群或给集群增加机器。
以上几条只是简要的说明了应用服务器的优化思路,对于数据库服务器和缓存服务器,根据他们不同的业务需要有专属的优化方案,本文不再对此作出详细讨论。当我们要向听众去介绍一个方案或设计时,可以依照先定位问题,再分析问题,最后再提出解决方案,实施方案的过程来逐步的展现我们的思想。在这种条理下我们的私立也鞥更加清晰,不至于因漫谈而忘记重点。
总结
刚刚说到了条理,我们怎么能让我们演讲时更有条理呢?想要有条理就要善于总结,并且将总结作为一种习惯。只有经过总结后的语言才能更有条理,除非你有很高的演讲技巧,否则不要将总结的时间放到你将要说话前一刻,不然你在演讲前的紧张会让你根本无心总结。
为演示总结的好处,我在这里提问一个简单的问题,什么样的代码才是好代码?
作为工程师,你一定有自己的衡量代码好坏的标准,不知你是否总结过这个问题? 假如你没有总结过,这个问题你可能这么回答:
- 可扩展性
- 易读性
- 架构,符合项目需求
- 代码不要太冗余
- 整体的风格保持统一
- 好性能
当然你可能有回答出其他的特性,我们暂且抛开,我这边有几条经过总结后可能更好的答案:
- 领域驱动,完全满足需求,可测试
- 整洁规范,注释清晰,可读性高
- 简单高效,逻辑清晰,性能优秀
- 善于抽象,层次合理,避免重复
- 高内聚,低耦合,易于扩展维护
事实
事实胜于雄辩!再好的理论如果没有实例的支撑也只是空谈。
比如我们上面所说到的“总结”这一节里,我们总结了几条好代码的标准,乍一听好像很有理,但仔细想又空无一物,这种情况出现的原因就是我们没有拿出事实论证,没有实例去支撑。对于“简单高效,逻辑清晰,性能优秀”这条,我们可以进行一个举例说明。假如我们以前使用100行代码才能完成一个Excel文件导出的代码,而现在我们只需要10行代码就能完成这项工作,那么这10行代码相对来说就是好代码。
对于其它几条所涉及的事实,这边不再一一讲述,如果你对此有兴趣,可以翻看一下spring的源码,看看spring是如何的设计成“高内聚,低耦合,易于扩展维护”如何层次合理。
故而当我们需要表达时,说出理论总结后,或者在总结前,尽量的拿出具体事实来为自己的总结做一个证据,让别人对你的观点深信不疑。
最后
在文章的背后我还是要说明,我们是工程师,应当以知识为重。所有的交流都在我们具有业务知识或技术知识的前提之下,所以不可因锻炼交流放弃知识学习。你会什么很重要,把你的知识或者知识转化的产品分享出来同样重要。
引用
在写作本文的受过一位阿里的不知名的前辈的提点,为为在此谢过。今天必是我在成为架构师之路上迈出的又一关键步伐。
关于
本项目和文档中所用的内容仅供学习和研究之用,转载或引用时请指明出处。如果你对文档有疑问或问题,请在项目中给我留言或发email到
weiwei02@vip.qq.com 我的github:
https://github.com/weiwei02/ 我相信技术能够改变世界 。