存档

‘学习’ 分类的存档

Daniel-Journey Weekly Dose-2010/1/31

2010年1月31日 admin 没有评论
分类: SOA, 学习 标签: ,

转载:做人、做事,做架构师——架构师能力模型解析

2010年1月31日 admin 没有评论

要想从一名普通程序员发展成为优秀的架构师,“个人特性”与“技术技能”缺一不可;而“技术专业能力”、“人际关系能力”和“业务能力”更是优秀架构师重要的三种能力。
/ 周爱民(《程序员》2008年4月刊)
引子
究竟是什么让你在同一个位置上——例如程序员或技术负责人——工作了三年、五年或者更久,而仍然得不到任何的发展空间?你觉得自己已成为技术圈中的大牛,并信心满满地去拿明天就要颁发的某某大奖,然而却仍然停留在同样的技术职位上,去年到今年涨的薪水甚至填不平物价升幅?于是,你开始对老板不满,对员工不满,对昨天升职的那个同事不满……你开始计划明天就要跑单,或者准备考虑提出加薪却又心怀忐忑。
如果技术人员有发展的轨迹,那么他要么“看透工具的本质,把关注点转移到‘团队’的圈子里去”,要么“顺着代码铺就的道路,亦步亦趋地成为良匠大师”。仅以技术方向而言,你大概可以做到架构师、总架构师甚至首席架构师;但问题是:你现在还只是一个程序员。那要如何才能踏上通往架构师之路呢?本文为你解析一个架构师的能力模型。
你能不能做一个好的架构师?
架构师不是界定一个技术高下的职位名称,而是一个职务。所谓职务,包括职——职位,务——工作。前者决定了你具备哪些资源,可以影响到怎样的范围,以及面向的机构,后者则简单地是你需要完成的工作列表。
所以我说“架构师”不是指“一个能做架构的人”。前者是把架构师当职能,后者是当工人。能做一份工作列表中的事,并不等于就成为相应职位上的人。在管理体系里面,你的个人特性决定了你在哪个位置,而技术技能只是做事实施的必需。架构师这个职务,同时要求较高的个人素质和技术能力,因此它的进取之路总结起来就是:做人、做事,做架构师。
因此“模型”由“个人特性”和“技术技能”两个方面构成,在第一张图中,我特别说明“个人特性”既包括人际关系的能力,也包括(具体)业务能力;“技术技能”也是如此。所以个人特性主要与“做人”有关,部分地也包含“做事”的要素。

dd1
                                                           图1 架构师能力模型
“有效沟通”以及“学会谈判”与做具体的事无关,是个人能力特性的公共方面。前者是过程,后者是知道如何定目标与求结果。而“风险与防备”是做事过程控制的关键,与前面两项正好构成了一个做事基本能力的完整体系。基本上,这三项个人特性都是一个“普通程序员”所不具备的,甚至在大多数情况下,普通程序员并不愿意去具备这样的个人特性,因为在许多陷于技术泥淖的开发人员看来:沟通总是会使事情变得更加麻烦,谈判则徒耗时间而无济于事。然而事实上,在整个的架构决策过程中,架构师需要不停地沟通与谈判。将“架构”变成“决策”的过程,其实就是对各个技术角色(及其思想)兼容并包的过程,你需要不断地协调需求、实现之间的各种问题,也需要面对各种投资者(时间、资金、人才等方面的决策者)进行谈判,以确定项目的规模——没有规模也就没有范围,没有范围如何展开设计呢?
一部分开发人员会认为上述过程是“项目经理”的事情,但真的如此吗?当你作为一个更高级别的架构师,以至于要影响到多个项目的决策时,你就全然不会有这种感受了。因为这种情况下,你的决策将先于项目的启动,或者说你已经不单单是一个技术角色了。
设计是架构能力的一部分,但架构师不是设计师——看清楚二者之间的不同,你才真正迈出了架构师职业生涯的第一步。
抽象是思维能力、模型化是表达能力
个人特性中另一个非常重要的方面是“抽象思维”,而这是与架构师角色直接相关的一种能力。这种能力既有职业技能特征,又是普遍性的能力。
所谓普遍性的能力,是指“抽象”在我们——作为人这种个体的——生活中无处不在。例如我们说花、草,说桌、椅……我们用语言去指称任何一个既已存在的(可以脱离我们的语言而自然存在的)事物时,就用到了抽象。说“桌子”的时候,既没有描述桌子的具体形式,也没有说明它的规格,但我们用这个名词时,所有人都知道“桌子是什么”。所以,名词概念是整个抽象逻辑系统中的主体。如果失去了这些名词定义,我们基本上不能说话,也不能描述任何东西——那便到了“只可意会不可言传”的境地。
用现有的成熟语汇去描述你的系统时,大多数人会理解你所表达的含义,例如我们说“这个系统设计为一个三层结构”。然而架构师面临的系统在许多细节上并不见得能够用成熟的语汇去描述,因此必须自已构建一个抽象系统,这就需要概念抽象能力、概念表达能力和基于概念的逻辑表达能力。
概念抽象能力是一种思维能力。简单地说,就是“把目标分解或概括清楚”:你要么概而言之“它是什么”,要么详细地说明“它包括什么”。必须使用大量的语汇来陈述这个“什么”,这不单单是表达为文字,也表达为你在思想过程中的一个完整系统。通常用的方法是“映射系统”。例如你可以用数学中的“数轴”来映射“实数域”。将目标系统形式化为一个概念化的、可讨论的结构系统后,你的抽象过程就基本结束了。
dd3
                                          图2 能力模型中的个人特性
然而这个“抽象系统”可能只构建在你的思维意识里,还必须把它描绘出来。因为不能只是你自己思考清楚,系统就能设计完成。这个“描绘”就依赖于后面两种表达能力,一种是描绘概念实体,一种是描绘实体上的逻辑——有趣的是,这似乎又回到了“程序=结构+算法”。
现在大家回过头来看看UML,或者更多种类的ML(建模语言),他们就用于表达这两个方面的东西:要么是概念实体(例如用一个框表明系统边界),要么是实体上的逻辑(例如用箭头表明逻辑时序)。
所以大家应该清楚,我们再如何称赞UML,它也只是一种对模型化系统的“表达能力”,你只能把它当一种辅助表达的工具去使用,它本身既不能帮助思考,也不见得能作为抽象过程中的或抽象思维环境中的参考。
任何一个优秀的架构师都有自己独特的思考方式,这决定了他如何抽象系统,以及如何“创造性地”设计与构画这个系统。这种“独特的思考方式”贯彻他从孩童开始的整个成长过程,直至他形成独立的社会观、人生观与世界观。他认识世界的方式和接受世界的能力决定于他如何思考,也反映了他这种思考方式的“独特性”。但这并不表明他有特立独行的行为特性(我们这里只说他的思考方式),我们不应介意他是否用某种语言(例如UML或者形式化编程语言)来表达他的思考结果。
推动:设计做大,实施做小
架构师首先是把问题的真正目标确定下来,然后变成系统设计、平台设计或架构设计。而在此之后设计输出将会有两个方向的发展,一是被忠实地贯彻下来,二是被变形地发展下去。两个方向都存在致命的危险:架构最终能否被完整实现。对前者来说,可能是架构设计过度,或设计本身出现了错误;后者则是对架构直接的伤害。
所以架构师必须参与实施的全程——尤其是在架构被映射为目标系统的前期。在这个阶段中,架构师的任务就是推动架构实施,以保证在项目全程的设计/架构/体系的一致性。除了直接跟设计师或设计团队沟通,以保证他们的设计在你可以控制的范围之内以外,架构师还必须有阶段化设计的能力。这种能力用于将一个原本规模宏大的架构设计,变成较小的、易于实施的、对开发团队来说可控的关键点。例如在体系层次的规划上,设计可能是独立、异质的、可迁移的存储框架来实现数据层,但在(前期的)实施上,这里可能被表达为本地数据库,并要求前端开发人员必须通过一个清晰的数据交互层来访问——例如一组数据存取接口,或一个独立数据服务组件。开发人员可能在这里遇到障碍:因为要通过这些中间层来访问本地数据库,纯粹是多余的。然而,正是这“多余的工作”提供了系统弹性,为并行团队开发公共存储服务争取了周期,也为将来的灵活部署与数据迁移提供了可能。
这里的关键就在于,无论原始系统设定有多大,实施时总是在“做小”。每一个局部的实施块都是可控的,并为它在整个体系空间中留下了位置和接口,这样才可能由“小的部分”做大。一个大系统的架构师可能同时在考虑许多个项目中的、不同位置的架构,并且清楚这些项目最终的总体规模。而这,就是平台架构师和体系架构师所涉的领域。
dd4
                               图3 架构师模型图中的“实现能力”
架构真的是“好不好”的问题吗?如同我对工程的理解一样,架构问题的根本,也并不在于它是否完美或漂亮,而是在于是否合用。因此架构师必须对实施架构的团队以及实施过程有充分了解,知道他们的能力缺陷,知道实现过程要消耗的资源,清楚每个环节可能的故障以及先兆。只有这样,架构师才能设计一个让这个团队能实现,而且在实现过程中能受控的架构。
要知道,你作为架构师被请来,不是画几张图纸交给项目经理,说:你们去做吧,做不出来是你们不会做。即使你可以身体力行,在这个团队中教大家、培养大家,那么公司的开销呢?风险呢?这些东西难道就不考虑了?项目的周期因为实现的复杂程度而无法控制时,项目就死掉了。那么,追根究底来说,是不是架构师的问题?是啊,你为什么会做了一份“不合用”的架构呢?——你都不知道项目如何开发、由谁实施、如何管理等等,又如何能面对这些实际环境去设计架构呢?
所以这一部分能力,是要在你的开发经验、团队经验以及用人识人的经验中去找的。参考模型图的“实现能力”下的“设计能力→了解你的主要沟通对象”和“架构推行”等分支,对你或有一些可用的提示。
局部与全局
架构是一个从全局到局部的过程,而实施正好反过来,是从局部到全局。这也正是“设计做大,实施做小”的另一个层面的含义。设计大才可以见到全局,才知道此全局对彼全局的影响;实施小才可能关注细节,才谈得上品质与控制。
事实上,大多数情况下架构是在为“当前项目之外”去考虑,这可以看成全局关注的一个组成部分。因此我们需要界定所谓“全局”的范围:超出公司或整个产品系列、产品线或规划的范围才是多余的。
所以当架构决策谈及“全局”时,其目标并不见得是“保障当前项目”,而又必须由当前项目去完成。
一个经常被用到的例子是:如果仅为当前项目考虑,那么只需要做成DLL模块;如果为产品线考虑,可能会是“管道+插件”的结构形式。而“管道+插件”的形式显然比做成DLL模块更费时,这个时间成本(以及其它成本)就变成了当前项目的无谓开销。
这种全局策略对局部计划的影响是大多数公司不能忍受的,也被很多团队所垢病。然而这却是架构师角色对体系的“近乎必然”的影响——如果你试图在体系中引用架构师这个角色的话。一些情况下,体系能够容纳这种影响,例如“技术架构师”试图推动某种插件框架,而正好开发人员对这项技术感兴趣,那就顺其自然地花点工夫去实现了。但如果不是这样,实施者或实施团队看不到“多余的部分”对他们的价值时,来自局部的抵触就产生了。
这种情况下,平衡这些抵触就成了架构推行的实务之一。在我看来,“平衡”是全局的艺术和局部的技术。也就是说,一方面架构师要学会游说,另一方面也要寻求更为简洁的、成本更小的实现技术。只有当整个体系都意识到(你所推行的)架构的重要性,而且实施成本在他们可以接受的范围之内时,他们才会积极行动起来。
所以所谓平衡,其实也是折衷的过程。构架师只有眼中见大,才知道哪些折衷可以做,而哪些不能。所谓设计评估(模型图中的实现能力->设计能力->设计评估分支)并不是去分析一个设计结果好或不好,而是从中看到原始的需求,看到体系全局的意图,然后知道在将设计变得更为“适当”时可以做哪些折衷。同样的原因,架构师也必须知道自己的决策会产生的影响,才能控制它们,以防它们变成团队的灾难。有些时候,架构师甚至需要抛弃一些特性,以使得项目能够持续下去。因为产品的阶段性产出只是整个战略中的一个环节,而不是全部。
其它
“怎么做一个架构师”这个问题得分成两个部分来看,一个是“做到”,一个是“做好”。由于架构师本身不过是一个技术职位,所以时机成熟了自然会做得到。但问题是,真有一天你被放在这个位置上了,你能做得好吗?
我浏览过几套所谓培训机构的有关架构师的教程,也翻阅过一些讲架构的书。我发现他们普遍地是将架构作为一种“职业技术”来讲,就像培养程序员或者缝纫工一样来教育。但就我的经验来说,架构并不是一件纯粹表现技术能力的工作,所以并不是翻几本书学几种方法就可以投入“实战”的。更深层的问题是,架构师其实不是“战”出来的。昨天跟同事讨论这个话题,他把我们这几年来的一些思考用了三句话来概括,非常精彩:从无到有的,是架构;从表到里的,是抽象;从粗到细的,是设计。
那么到底什么是架构呢?从上面的概括中你是看不到答案的。到底如何做架构呢?从本文中你也是看不到答案的。然而我说,“你看不到答案”的根源其实是在于你的眼光与心性——后面这个词换成现代白话,就是“思想”。真正阻碍了你成为优秀架构师的,也许正是你既有的知识与思想方法,扔掉它们,接受一些全然有别的信息,也许正是良好的开端。
或许你现在正愤愤然:这篇文章怎么空洞无物?——我甚至能想象到一些读者的表情。然而请在问题面前停下来,不要急于给出答案。正如你将“?”稍微变下形,它就成为了“!”一样,问题的本身,就是答案。
作者简介
周爱民(aimingoo),具有十余年的软件开发、项目管理和团队建设的经验,现担任盛大网络的平台架构师,著有《大道至简》、《Delphi源代码分析》等。

分类: 学习, 软件设计 标签:

2010年的技术To-Lean列表

2010年1月8日 admin 没有评论

2009年3月份制定的2009年的To-Learn List,内容大致如下:

以下是计划在2009年重点学习的内容
1. Oracle
2. Erlang
3.Java Concurrency Programming
4.Java Network Programming
5. Memcached
6. Linux
7. JBoss
8. JVM
9. Mysql
10. UML
11. REST

2009年的To-Learn List执行的不好,Oracle,Erlang,JBoss,REST几乎没有涉及。

Java Concurrency Programming,JVM,Mysql,UML学习的深度都不够。不过2009年在面向对象设计、设计模式、单元测试这些之前有不错基础的内容上有了更深层次的学习,另外在分布式计算、SOA、Scalability方面也有了一些知识和经验的积累。2010年的To-Learn List获取应该会更符合自己的工作状况

1. JVM
2.JBoss

3. UML
4.Ruby

5.ErLang

6.Java

另外,2010年会考虑做一些好玩的东西已减轻目前的工作负担和复杂度。

分类: 学习 标签:

谈设计的学习和特定技术学习的平衡和取舍

2010年1月3日 admin 3 条评论

有位大三还在公司实习的同学问了我一个问题,说他在加入公司之前通过网上下载一些Hibernate、Spring之类的视频来学些一些主流的Java技术和框架,通过这种方式和内容的学习,他的作品得到了老师的认可,并成为了公司的实习生。可在到了部门以后,发现我特别强调面向对象设计、设计模式的运用、UML以及文档。可就他自己的感觉而言,他对这些内容的学习不怎么感冒,我当时没有直接回答这个问题,今天整理了一下我的思路,说不上是一个回答,只是谈一下我的感觉吧。

故事的起点其实并不久远,就在我加盟现在的公司,并在9月份开始接手了一个产品线的开发工作。至此以后,我面对了很多的难题:

  • 产品的规划、维护做的很差,看不出模块化的设计,很多模块混成一团,理不清减还乱。这种“人造”的复杂,再加上缺乏文档,开发人员的陆续离开,系统的理解、维护出现很大的真空。
  • 产品的升级、扩展、改造难度大。
  • 产品设计、编码质量很差。这种情况存在在部门负责的多个系统中,不只是我们的产品线有这样的问题。这一点给我提了一个大大的问号?甚至是让我产生了离开公司的想法,其中的纠结是很难向外人说明白的。
  • 团队绩效低下,新的团队成员很难摸清楚现有的业务逻辑、长期依赖原有的开发人员开展工作,要很长的时间才能成为某个模块的owner,至于说整个产品线的,更加困难。
  • 产品质量差,新增加一个功能往往会影响几个历史功能,每次有新的大小版本要发布,都提心吊胆。这一点不仅影响到了开发团队,连测试部门很增加了很多的压力。
  • 工作压力大,对工作的满意度差。由于上面的几点严重影响了工作的效率,导致我和我的团队加班越来越频繁,满意度、幸福感随之下降。

与此相反的是我和我的团队所负责的产品线,需要支持一个年收入30亿的公司的使用,有10几20个业务部门在该产品线上开展核心的非核心的业务,每年有上百个的功能改进需求,有4-5次的产品版本升级,以上种种任务都需要一个7人左右的开发团队来支撑。如此突出的矛盾,我如何解决呢?我把强化设计视为解决我和我团队诸多问题的方案之一。坦白的说,我之前的工作经历中,我和我之前的公司、同事都没有对相关的内容有特别的关注,正是客观的环境教育了我,使得我把近期把技术重点放到了相关的内容上来。

在这段时间,我特别要求我和我的开发团队做好产品线的设计工作,强烈地要求我的团队重视设计工作、强化设计能力、完善文档、做好产品模块化的设计。也直接地在具体的工作中对团队成员的面向对象设计、设计模式、UML等方面的知识有提出了一定的要求,这些内容或许给他们有了不少的压力,他们多数是刚刚走出校园的学生或从未对相关的内容进行系统的学习。

最后回到那位同学问我的问题,具体的技术和设计如何取舍。首先,我不认为两者存在什么冲突和矛盾,如果说要有什么冲突和矛盾,也是由于一定时间内人的学习精力和时间有限,所以很难在两者直接加以平衡。我对技术的整理可以以下面这张图来理解。黄色图框的面向对象、设计模式之类的技术都是那些超越了具体语言、框架、平台的内容,而蓝色图框中的都是针对的某些语言或某种平台。但大家不要错误地认为两者之间是“井水不犯河水”的,其实两者之间存在着紧密的联系,以Java语言为例,Web框架总是离不开MVC模式的运用,Spring最核心的功能——DI(依赖注入)也可以在很多讲述软件架构的书中找到说明和分析。以我个人的学习经验而言,很多蓝色图框中的技术、框架的学习,最后都在要通过对黄色图框中相应内容的学习,找到彻底的答案。例如,WebWork中的Interceptor是整个Webwork框架的核心概念和开发重点。如果只是去学习Webwork,甚至是看Webwork的源代码都很难理解在Webwork中为什么要有Interceptor这种概念,能给整个Web框架带来什么样的好处,这些问题的都可以在Interceptor的相关设计模式中找到答案。

beyong_language

所以请我们的同学根据自己的情况、从事的工作内容在黄色图框和蓝色图框间做好平衡。其实我们每天的工作就像镜子一样可以反映出我们的缺陷,引导我们加以改进,如果我们能更主动地来加以调整,我们每个人的学习成长经历会更有效率和充满乐趣。最后,附上一个“木桶原理”的示意图,供大家玩味。

分类: 学习, 软件设计 标签:

Daniel-Journey Weekly Dose-2009/12/26

2009年12月27日 admin 没有评论

Java

Memory overhead of Java HashMap compared to ArrayList

Top 5 IntelliJ IDEA Performance Tips

Windows

How to check which application is using which port

Separated Interface

Database

Top 20+ MySQL Best Practices

Programming

Buffer和cache的区别是什么?

最关键的区别其实在于,buffer主要作用是在于减少实际的I/O操作次数,即,将多次操作尽量合并成一次的成批操作,通常其中的数据在操作完成之后,buffer不会被继续使用;而cache的主要作用在于更好地利用局部性原理,减少不必要的I/O,避免代价昂贵(例如,速度很慢)的I/O操作。

Buffer 更多的(场景)是减小写操作的冲击,而 Cache 主要用于减小读 I/O 的重复开销。不过很多时候二者都混淆得面目不清

Architecture & Design

提高架构质量的10个观点

1. 架构是创意的表现,架构来自创意,创意是假设(Hypothesis);

2. 假设需要检验,以需求检验创意;

3. 创意根源于固有文化,设计是文化与技术相遇的地方;

4. 从文化感悟体悟序(Order)之美,追求建立软件的美之序;

5. 以序容易(包容改变),美之序能包容繁杂多变,创造无尽繁荣等等。

Reading

Top 5 Essays You Should Read

6 Books Every Programmer Should Own

分类: 学习, 软件设计 标签:

Daniel-Journey Weekly Dose-2009/12/06

2009年12月6日 admin 没有评论
分类: 学习, 软件设计 标签:

Daniel-Journey Weekly Dose-2009/11/29

2009年11月29日 admin 没有评论

Java

Spring 的优秀工具类盘点,第 1 部分: 文件资源操作和 Web 相关工具类

Spring 的优秀工具类盘点,第 2 部分: 特殊字符转义和方法入参检测工具类

Thoughts on Java logging and SLF4J

Getting Started with Terracotta

性能测试项目总结之内存泄露和内存溢出

Terrocotta – 基于JVM的Java应用集群解决方案

面向对象设计

Applying Strategy Pattern Instead of Using Switch Statements

What we gain by using Strategy Pattern?
  • The code is easier to read. I don’t need to go and read (or
    search) an “endless” switch statement to understand each
    aspect of the code.
  • The code is more maintainable. I only need to go to the
    relevant class that implement the algorithm in order to change it
    or refactor it when needed.
  • It is easier to add more algorithms. I only need to add more classes
    to the pile of algorithms and that is it. Doing so helps us to imply
    the Open / Closed Principle because in switch statement we are going 
    to have to change our code (add another case statement) in opposed
    to Strategy which we add another algorithm class.
  • Strategy Pattern is more testable.

数据库

Top 20+ MySQL Best Practices

其他

Transfer Obejcts vs Business Objects – Which Approach Works Best

分类: 学习, 软件设计 标签:

Daniel-Journey Weekly Dose – 2009/11/22

2009年11月22日 admin 没有评论

Java

Spring中常用的IO工具类的学习

Spring中常用的Collection工具类的学习

Analyzing Java Heap problems Part 1: Basic actions and tools

Best Open Source Reporting Tools

Analyzing Java Heap problems Part 2: Using Eclipse MAT

测试驱动

测试驱动开发与遗留代码的问题

下列原因之一可能是类似问题的根本原因:

  • 团队在重构方面做得不够,因此你的类没有做到最小化。
  • 团队在“尽量简单”方面的技能还不够,同样如此。
  • 团队还没有采取具备侵略性和快速度的微测试(microtesting,也就是单元测试),所以改变常常会破坏测试
  • 团队不知道如何处理跨团队、或是公司对公众之间的依赖,比如公布API的情况
  • 团队既没有结对,也没有在开放空间中工作,这极大降低了团队层面的知识理解和传递
  • 团队似乎没有具备快速构建的能力
  • 团队可能还在使用老古董级别的工具

也许“告知,不要询问”是最重要的设计原则:不要分离功能和数据……恶劣的代码常常把功能实现放在一个地方,从其他地方得到需要的数据,这就造成了依赖性方面的问题,同时代码缺少局部性(locality)。其症状就是:“添加一个新功能,要修改多处代码。”代码异味“散弹枪式手术”、“依恋情结”、“参数列表过长”都是这样造成的。

 

重构要比重写更好,其优势在于:你总是有可工作的代码。如果你的手工和自动化测试都很好,那你就可以交付代码了,即使目前的状态处于“优秀设计”和“恶劣设计”之间。

面向对象设计

The Open/Closed Principle – A real world example

开放封闭原则

关于开发封闭原则,其核心的思想是:

软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。

因此,开放封闭原则主要体现在两个方面:

对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。

对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。

设计模式之Decorator(油漆工)

分类: 学习, 软件设计 标签:

Daniel-Journey Weekly Dose-2009/11/15

2009年11月15日 admin 没有评论
分类: 学习, 软件设计 标签:

分享我的软件开发学习方法

2009年8月14日 admin 没有评论

最近跟team里面的几位新同事分享了自己的一些学习的方式、方法,同样也制作了一份Slide放到了博客上。如果大家有好的学习方法请推荐给我:-)。

分类: 学习 标签: