架构师
链接:https://www.zhihu.com/question/19841397/answer/13707213
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
公司的大小往往决定了所做的项目规模,一般的大项目不太可能直接总包给小公司去做,但这并不妨碍小公司可以分包到大项目的一部分。在做小项目的同时也可以积累丰富的经验,我自己就是一个这样的例子。
我在小公司混迹了5年多,其中也偶尔有1两个大公司,比如大唐电信,但是基本上都是小公司,从基层的程序要到公司的开发总监都做过,甚至自己还设计过包括LED显示屏,密码键盘在内的收费系统,自己联系厂家OEM,当然这些今天已经广泛应用了,当时我们的客户用上之后还是非常震撼的。
知识面的宽广对于一名出色的架构师来说是必不可少的技能,也许很多人对架构的理解还停留在设计模式,重构,SOA等等的软件层面,然而这仅仅是非常基本的东西,架构师的脑子里不光需要知道让软件如何高效的运行,还需要知道如何去结合网络,存储,甚至一些文件系统的特性,比如GFS,NFS,XFS,NTFS等等,而且架构师还需要知道一些编程语言的特性,C,C++,Java,PHP,Python,Lisp,JS等等,现在是一个混合编程的时代,只了解一种语言,即使再精通也会使你在架构系统的时候受到很大的局限性。
再有一点,架构师需要对数据库技术有深刻的认识,因为现今是一个信息时代,大量的信息都是需要存储并检索的,数据库设计的不好,将会严重影响系统的性能,而这一点往往会被我们的设计人员忽略,他们只知道遵守那些范式而不会结合数据的特性去设计数据库。
看你的编程情况,你好像做PHP开发比较多,PHP比较适合B/S结构的应用开发,这会限制一个架构师的思路,我建议你再学习一门适合做C/S开发的语言,拓宽自己的视野。
从一个程序员到架构师是一个很大的变化,架构师需要从大的方面考虑,而不只是考虑这个模块该用哪种设计模式去开发。不能急于求成,也许是我自己变化的比较慢,我用了10年的时间,这10年里,我使用超过一年的编程语言包括了delphi,C++,Java,python,使用的数据库包括了oracle,infomix,sybase,sqlserver,mysql,javadb,sqlite等等,使用过大型机,小型机,服务器。unix,linux,windows都至少做过两年以上的开发,这些使用和开发的经历会大大增强一个人在做架构师这个职业时的技术素养。
总之,想要成为架构师,需要有耐心,不断学习,拓宽自己的视野,不仅仅局限于自己眼前的项目,关注开源技术,关注热门技术社区的新动向。
06年写的如何循序渐进向dotnet架构师发展,可参考:
微软的DotNet开发绝对是属于那种入门容易提高难的技术。而要能够成为DotNet架构师没有三年或更长时间的编码积累基本上是不可能的。特别是在大 型软件项目中,架构师是项目核心成员,承上启下,因此RUP方法论也认同以架构为核心,体现4+1视图在整个软件开发过程中的重要作用。架构人员既要精通 技术,又要熟悉业务,而且基本对软件生命周期各阶段的相关技术都需要有相关的积累和知识储备,而这些不经过多年的磨练是很难达到这个高度的。
要成为一个合格的架构师首先必须是一个合格或优秀的编码人员,对于开发来讲编码始终都是最重要的一项技能,在编码过程中只要自己善于去思考和分析问题,就 可以多学到很多相关的知识和技术。所以我们在开发过程中一定要注意新知识和新技术的学习,前人经验和成果的学习。编码过程中应该去思考的一些问题有:
1.在编码过程中自己是否做单元测试,是否使用相关工具做单元测试,如果没有的话是什么原因无法把单元测试做起来?
2.自己编码的泄露率情况,编码泄露的BUG的原因分析
3.是否有意识的对代码进行重构,重构过程中是否引入了相关设计模式的思想?
4.是否对C#语言的一些高级特性进行学习,如反射调用,异步处理等。
5.是否对Remoting和WebService两种分布式技术做过研究和对比分析?
6.是否经常研究开源项目和开源代码,如Duwamish,PetShop,NUnit,Enterprise Library,Nant等
7.是否对对象持久化机制和O/R Mapping等相关技术做过相关的研究
8.平时在编码过程中是否注重公用组件和公用类的复用和抽取
9.自己在平时工作和学习中是否经常开发些小工具提高工作效率,巩固学习知识
设计和编码其实是密切而不可分的,对于严格将设计和编码分开的瀑布模型一般也仅仅在大型项目中应用。而及时编码和设计分离,也不是将编码人员不需要思考, 编码活动始终是一项创造性的劳动,如果否定这个观点那就代表编码过程完全不需要人员介入而可以完全自动化。因此在这里谈设计主要还是指设计人员的系统化思 维能力,设计人员应该比开发人员站高一个层次来分析和思考问题。设计人员最重要的一个技能就是现实->抽象的转换,而这个就需要谈到方法论的问题 了,技术人员需要积累面对对象分析和设计或结构化分析知识的积累,需要有较强的数据库分析和设计能力。一个设计能否成为很好的架构师关键就在这种积累的深 度和广度上面了。
因此在设计过程中应该考虑的问题有:
1.你现在分析和设计能力能否胜任大中型的应用系统还是只是独立功能分析和设计?
2.设计过程中是否有意识的考虑到组件的复用和相关接口设计准则。是否能够很自然的将分析模式,设计模式的相关内容应用到自己的设计过程中。
3.是否对XP,RUP,面向对象,结构化等方法论都有过较系统化的学习和思考。
4.是否真正理解系统功能需求和非功能需求对系统设计的不同的指导作用。
5.对自己设计的功能是否会根据后期的变更来反思自己的设计为何不能很好的适应变更?
6.是否在设计过程中经常自己开发些原型来对自己的设计思路进行验证?
7.是否专注技术的同时开始专业业务流程的分析,关注业务建模?
如果我们在设计和开发过程中经常关注这些知识和技能的话,成为一个合格的架构师是早晚的事情。平时能够胜任工作开发用到的知识和技能是微不足道的,如果自 己不是有意识的去学习这些知识的话,那技能是很难得到进一步提高的。我参加过两次微软的架构师培训,在北京的微软架构峰会上也有机会专门参加了 P&P Workshop的学习,培训老师是微软总部SmartClient Architecture and Design Guide一书的作者Edward A.Jezieski,让我感受最深是老外深刻的技术底蕴,对程序开发的执著。
对于DotNet架构经常用到的知识和技能储备有
1.RUP方法论,4+1视图。用例驱动业务建模->分析模型->设计模型
2.用例模式->分析模式->设计模式
3.常用的分布式技术
4.对安全,异常,日志,性能等非功能性需求的关注
5.对应用系统整体业务的关注
相关的一些参考书籍(微软网站和电驴都可以下载到)
微软网站提供的参考书籍
Enterprise Solution Patterns Using Microsoft .NET
.NET Data AccessArchitecture Guide
Application Architecture for .NET:Designing Applications and Services
Caching Architecture Guide for .NET Framework Applications
Designing Application-Managed Authorization
Smart Client Architecture and Design Guide
其它架构方面的参考书籍
Software Architecture In Practice
Pattern-Oriented Software Architecture
The Art Of Software Architecture
Beyond Software Architecture
模式方面的书籍
Analysis Patterns
Design Patterns - Elements of Reusable Object-Oriented Software
Applying UML and Patterns
Design Patterns Explained
===================================================
2015年8月,增加架构设计和概要设计的区别
架构设计
架构设计包括了功能性架构和技术架构设计两个部分的内容,功能性架构解决业务流程和功能问题,而技术架构解决非功能性需求等问题。两种架构都包括了动态和静态两个方面的内容,对于功能性架构中动态部分为业务流程驱动全局用例,用例驱动的用例实现等;对于技术架构中动态部分为架构运行机制,而静态部分为框架,分层等方面的内容。
功能性架构包括了全局用例设计,这个本身是用例分析和设计的一个延续,而全局用例分析建议的思路仍然是业务流程,业务用例建模到系统用例建模的过程。全局用例分析清楚后可以开始考虑子系统和模块的划分,形成系统的功能架构图,当然在划分过程中一定要考虑到通过CRUD矩阵等分析方法来分析模块如何划分合理,如何保证模块本身高内聚和松耦合。
在全局用例分析完成后涉及到数据模型的设计,数据建模仍然从业务驱动,从最初的业务对象和单据入手,到最终的数据概念模型和逻辑模型等。架构设计中全局数据模型不一定覆盖所有的数据对象和数据表;但是核心的主数据,核心业务单据数据一定要覆盖到,模型到的层次到逻辑模型即可。如果用面向对象的分析方法,这里需要出的是UML建模中的概念模型和逻辑模型,体现核心对象和类,核心对象和类之间的关系。
将全局用例分析和数据模型建立融合在一起,可以看到这两者结合起来会形成一个系统完成的领域模型层。一直认为领域模型思路应该引入架构设计,只有领域模型才是真正关注功能性架构,而不用马上关注到具体的技术分层和技术实现。
前面两者做完后可以看到一个大系统被分解为了多个子系统或模块,那么接着要考虑的就是模块间的集成架构,分析完集成架构模块间的接口基本就出来了。接口设计应该是架构设计的另外一个核心内容。要明白架构设计一个重要作用就是架构设计完成后各个模块可以并行开始概要设计,详细设计和开发工作。只要大家都遵循架构设计约定的接口规则即可以了。
集成架构考虑完另外一个核心内容就是公共可复用组件的抽取和识别,包括了功能组件和技术组件,需要识别出来哪些是可复用的,如何进行复用。对于复用层次本身又包括了数据层复用,逻辑层组件复用,界面层UI组件的复用等。复用是架构价值体现的的另外一个关键点。
这些都做完后,接着一个步骤应该在架构设计阶段做的就是对架构输出成功进行模拟验证,前面完成了分解动作,必须通过模拟验证来看看后续分解内容能否很好的集成和组装。很多时候我们做架构设计的时候往往不做这块内容,导致架构设计一些内容变成空中楼阁,无法落地。
再回来看技术架构设计,首先谈下静态部分的内容。这里面就包括了软件开发的分层架构,开发框架等内容,包括开发规范约定,技术平台和语言的选择,使用的规约等都需要考虑。很多时候我们看到谈架构的时候说到的三层或多层架构,仅仅是完整架构设计里面很小的一部分内容。
除了分层架构外,接着考虑的就是各种非功能性需要,我们在架构上需要如何设计。这里面包括了事务,缓存,异常,日志,安全,性能,可用性,容错能力等。这些逐个点都要在架构设计中说清楚如何考虑,由于这些本身就属于一个应用系统中技术平台要考虑的内容,因此应该设计为较为公用的技术组件供上层的业务组件使用。要明白很多时候为何谈到AOP或可插拔架构,只有这样去考虑问题,才会考虑真正的功能性架构设计和功能实现和非功能性技术架构这块充分解耦,实现进一步的灵活装配。
再回到架构设计视图层面,还需要考虑的就是整个应用系统的部署架构,部署架构本身也包括了逻辑视图和物理视图,应用最终开发出来了如何进行部署,这涉及到了IT基础架构方面的细化,也需要考虑清楚。
概要设计
概要设计首先要明白的是根据架构设计的内容进一步对某个模块的设计进一步细化。架构设计在系统级,而概要设计在子系统或模块级。拿建筑来比喻,架构设计是把一个建筑的框架结构全部定清楚,包括地基要挖多深,核心框架和承重结构如何,每一层的结构图如何,应该分为几个大套间这些内容都应该定下来。每个大套间的水,电,气等管道接入点在哪里等。而概要设计要做的是拿着一个套间,来考虑这个套间内部该如何设计,如何划分功能区域,如何将水电气接入点进一步在房间内延伸,哪些地方需要进一步增加非承重的隔断等。
基于以上思路我们看到在架构设计的时候,除了很少部分的核心用例我们会谈到具体的用例实现完,大多数功能我们都不会谈到具体的用例实现层面。而到了概要设计则需要进一步的分解我这块模块究竟需要实现哪些功能点,具体的每个功能点究竟如何实现都必须要考虑到。
严格的概要设计,我们希望是到了概要设计的某个功能模块,模块所涉及到的核心的类全部会出来,类关系图全部会出来。数据库设计也进一步细化到该模块的数据库物理模型。对于用例进行用例实现分析,在实现分析过程中可以看到每个类核心的public方法全部会分析识别出来。
拿着架构设计的接口,概要设计也需要进一步细化,细化出接口具体的输入输出和使用方法,包括模块应该使用哪些外部接口,模块本身又提供哪些接口出去都必须细化清楚。做概要设计的时候一定要清楚当前做的这个模块在整个应用系统架构中的位置,和外部的集成和交互点。
概要设计不用到详细设计这么细化,包括类里面的私有方法,public方法的具体实现步骤和逻辑,伪代码等。但是我们要看到概要设计里面对于核心的业务逻辑必须要设计清楚如何实现,实现的机制和方法。很多时候我们到了概要设计画uml的时序图,很多时候一看没有任何意义,全是跨层的简单的交互和调用。这个应该在架构设计的架构运行机制说清楚即可。设计到多个业务类间的交互调用才是重点,一个简单的功能增删改查,完全没有必要画什么时序图。
其次架构设计中给出了各种安全,性能,缓存的设计。那么在概要设计中出来另外一个问题,即架构给出的各种实现方案和技术,我们在概要设计中如何选择,如何使用。不是所有功能都需要缓存,那就要说清楚哪些功能根据分析需要缓存,需要缓存哪些对象,缓存本身的时效性如何设置等问题。
概要设计作为我们要达到一个目的,就是不论是谁拿走概要设计来做,最终实现出来的功能模块不会走样,功能模块最终实现出来可能有性能,易用性等方面的问题,但是整个功能实现的大框架一定是定了的。
============================================================
2015-10月更新,架构思考
组件划分和服务接口
组件化开发思路在很早以前就已经提出,只是当时的组件间交互更多的谈接口而非服务,同时也没太关心单个组件本身的全生命周期管理。谈组件的时候一定不要先谈开发和技术框架,而是真正从业务架构和应用架构出发去考虑整个业务系统的组件划分,其中包括了业务组件和技术组件,各自应该暴露业务和技术服务能力。业务能力组件化和组件能力服务化也是一直强调的SOA核心思想。
在组件划分清楚后,需要优先考虑组件间的交互而需要暴露出来的服务接口,即组件之间只能通过服务进行协同以进一步实现组件间的松耦合。其次才是考虑单个组件在实现的时候,结合分层开发技术框架涉及到分层,在这里可以进一步参考领域模型驱动和设计的思路,否则很容易实现为数据库表驱动功能而不关心领域模型设计和领域逻辑的实现,即虽然技术框架分层了但是职责不清,逻辑混乱并多处实现。
组件内部的实现一个重点就是应用层和领域层之间的关系,即在应用和领域层之间增加了一个服务层,服务层重点是服务接口和服务的组合等工作,而具体业务规则和数据处理的逻辑在仓储类和规则类里面来实现。注意对于组件内部应用层和领域层交互的服务并不一定要做为分布式的Service服务,也可以直接使用内部的API服务接口即可。将服务层服务接口具体的逻辑实现分离的一个重点就是在后期很容易将服务接口发布为一个供其它组件远程调用的服务方法。
开源组件和技术
对于单一的技术往往很难满足互联网业务场景下不同的功能需求和非功能性需求,对于不同的功能或技术实现往往都需要选择大量的开源组件或技术进行集成。但是这些独立的技术组件如何集成为一个高效的整体就变得相当重要。任何技术的选择都必须为了业务需求服务,模式分析是选择技术的一个重点,即在什么样的业务场景下,面对什么问题我们究竟应该选择什么样的开源技术来实现最合适。
首先是开发技术框架层面的,即常说的基于MVC模式的多层框架,用的最多的估计还是SSH框架,其中在数据库层面又有Hibernate或iBatis多种实现,在控制层本身又有struts和spring mvc多种实现。在展现层相关的技术点更多,包括了一些前端基于javascript和jquery的框架引入,Ajax实现,包括当前互联网各种前端响应式框架,Html5技术等。技术框架的选择看似和业务无关,但是却需要进行业务场景分析,包括当前开发的应用是否需要同时支撑web端和移动app端,是否存在和外部集成和服务接口暴露,在业务交互和易用性层面有哪些要求,这些都需要考虑进去。
其次是实现核心技术能力的技术组件,其中包括了缓存,消息,流程引擎,搜索,安全,任务,日志等诸多内容,这些当前往往都有现成比较成熟的开源技术来实现。如通过memcached或redis来实现缓存,通过rabbitMQ或zeroMQ来实现消息和事件管理,基于lucence的全文检索引擎,开源的ETL技术实现数据集成,开源的jbpm流程集成等。在选择这些技术的时候要注意和前面整体技术框架的集成,技术组件应该保持其高内聚和独立性,仅仅技术组件的能力通过服务暴露出去实现和上层应用的集成。要做到这一点往往就需要对开源组件进一步进行封装和定制,以和技术框架形成一个完整的整体,同时又不要把底层技术组件的复杂度暴露给业务功能的开发过程中。还有就是互联网应用还涉及到外部技术服务能力的引入,如外部的邮件通知服务能力,地图能力,支付能力,各个外部开放平台开发的各种内容提供服务能力引入等。对于外部服务能力的引入建议是要在技术平台层单独进行管理和封装,即在技术能力层有独立和统一的服务代理。
最后是数据库和持久化层,包括常见的关系数据库,半结构化和基于key-value的redis,mongoDB等数据库,还有就是完全基于hdfs的非结构化文件存储能力。对于不同的业务场景和业务对象,往往需要底层不同的数据和存储能力进行支撑,如何形成一个完整能力的数据库服务能力层是架构设计时候需要考虑的。
去IOE化
对于去IOE化是这两年互联网架构设计谈得最多的问题,即去掉小型机,集中存储和商用数据库。如果简单来说下去IOE化的核心就是基于开源的类似Mysql数据库和集群技术,通过X86服务器硬件资源来实现和原来使用IOE架构时候同样的性能和高可用性。在之前淘宝有开源的corba基于mysql数据库来实现分布式数据库和集群,现在有开源的MyCat来实现,核心就是提供一个DaaS服务层和封装,来实现高性能和高可用的数据库中间件产品。
对于去IOE的热度在当前已经有所下降,这里面有两个原因一个是本身技术成熟度和CAP原则约束,一个方面的原因就是在去IOE和引入DaaS数据库中间件后本身是增加了架构复杂度和应用开发难度。一个方面是由于DaaS层引入导入的分布式事务问题和对于跨库查询和Sql语句本身的约束增加。一个是在架构设计中就需要考虑前端业务如何进行组件化,业务对于的数据存储如何进行分区和分片,究竟如何进行水平拆分和垂直拆分。
可以讲在架构设计中的去IOE设计和前面讲到的组件化和服务化设计思路密不可分,同时在去IOE下的组件化是彻底的组件化,即组件本身对应的数据库也是独立的,组件可以拥有完全独立的硬件资源和全生命周期管理。因此如果组件没有划分,在后期业务功能实现中就可能导致大量的跨库操作和分布式事务问题。这些都应该在架构设计阶段就思考清楚并制定清晰的架构设计约束,任何架构设计都不会有普适性的通用架构存在,架构约束定义是一个架构要发挥其高效能力的关键。
去中心化
首先来看一个最简单的场景,即客户和请求端是A,服务提供端是B,对于服务提供端已经实现为了分布式集群即(B1,B2,B3...Bn),在这种场景下可以看到对于请求会转发不同的集群节点进行处理。但是对于这种分布式架构来看,集群是可以完全平滑弹性扩展的,但是问题关键点在于A的请求究竟应该转发到哪个B节点去处理,这里面就有一个控制层或管理节点,而对于大多数分布式应用来讲管理节点本身是很难集群化扩展的。及时当前很多分布式架构实现过程中已经实现了消息请求和数据传输的分离,但是仍然存在对于管理节点无法水平扩展的问题。
对于水平弹性扩展问题的解决,往往会引入集群技术和硬件负载均衡,但是这不是一个完全意义上的去中心化架构,当前我们说的去中心化架构都是没有统一的管理节点,完全分布式,只有在这种架构下才是完全的去中心化。要做到去中心化就涉及到几个关键点的引入,一个是请求通过sdk包在客户端的植入进行前移,即客户端发起请求的时候就已经判断清楚;其次是对于管理职责后移,即管理端后续重点是从各个集群节点准实时采集数据再进行分析。要实现第二点往往又涉及到高性能的消息中间件的引入。- 对计算机这种工程学科,自学不一定不科学,但是要保持大量的实践。
- 为一个成型的产品Troubleshooting是进入架构领域的好办法。有一点必须强调:它不一定得是优秀的成熟产品。对善于总结的人来说,烂产品提供的反面教材从某种角度上看更加珍贵。
- 无论Troubleshooting经验如何丰富,最终我们必须要得到自己设计的机会。这是从经验积累落实到架构能力的唯一方法。如果条件许可,参与开源产品其实是个很好的机会(当然有的公司明令员工除非特许否则禁止参与开源项目,比如微软)。
具体用什么技术前面很多朋友都有精彩论述,我一做驱动的,就不多啰嗦了。
还有一点必须指出的是,尽管我也认同架构的重要性,但从楼主自己说的自学内容(目前属于自学,设计模式,算法导论,编译原理,UML2.0等都在看)来看,我感觉楼主还没搞明白架构师究竟是什么。如今业界人人都在讲架构,但所谓架构师细分起来实际上有很多种,即便只是算软件行业经常要打交道的(也就是说芯片架构师不算),我见过的情况就包括如下:- 网站基础设施设计师。比如一个能承受百万级访问量的网站该如何配置服务器等。这种架构师关注的是如何配置异地服务器,如何分流请求,如果做负载均衡、备份和同步等等。
- IT基础设施设计师。这种架构师和网站基础设施的架构师有一定交集,除此之外经常还需要考虑跟硬件有关的话题,比如机房空调温度,UPS,带宽升级等等。
- 软件设施设计师。这种架构师经常要负责对软件系统使用的部件做选择,比如安全系统上使用的是Kerbero还是SSH,图形系统选择本地UI还是跨平台库,网络协议或文件格式使用公开的标准还是自己设计等等。此类人往往还关心许多诸如性能、兼容性等方面的话题。
- 框架狂热综合症患者。此类“架构师”最喜欢的就是在一个项目里搞个所谓的类库,里面写上一堆抽象类和接口,然后到处宣称其类库设计极其便于扩展云云并强迫同事负责实现其具体功能。另外,此类人的一个显著特征是对各种新框架或语言特性异乎寻常地热衷,却从不屑于实现一个真正具有能用功能的部件。
楼主希望自己成为架构师,这本身很好。但作为善意的提醒,我想楼主现在更需要搞清楚的是自己究竟希望成为哪一种架构师(我猜测更可能是第一种),然后才能针对性地去学习。无论如何,前三类架构师的共同特征是他们都具备对各种实际功能代码或硬件优缺点的知识,并且懂得如何根据项目需求(而非个人喜好)选择合理的技术完成任务。甚至有时候一个顶尖的架构师必须同时理解三个不同的方向——换言之,架构师的知识广度必须超过普通程序员。而至于第四种“架构师”, 可能大家已经注意到我说到此类人时用了引号,因为恕我直言,在我看来他们只由两类人组成:只会招摇撞骗的骗子,或是半桶水却不自知的可怜虫。
当然了,要做第四种显然最容易,哈哈。这是个非常好的问题。
我想说,题主的心态已经保证了其已经成功了一半。
剩下的,我不想去抄各个教程书籍里面的大堆定义,因为以我的体验来说,基本没什么用,例如什么系统架构师,什么需求分析师,什么模块、组件、接口等等,都是政治正确的废话。
都正确,但是看了也白看,完全没有帮助。
所以,我基于我的经验给些建议吧。
第一、知识面要广
其实我认为做架构师的,从来都是CTO储备,因为需要涉及的能力太广。
做架构,其实最简单的理解就是一句话,就是在有各种限制的情况下想办法解决问题。
所谓的限制就是性能、稳定性、开发效率、可维护性等因素。
例如,百度贴吧这种应用场景,每天可能有几十亿次的访问,几千万甚至上亿次的写入。肯定是性能要求为先,可能为了做性能的提升牺牲一部分开发的效率。
再如,银行的应用场景,不是非常在意用户的体验和访问延迟,但是对于数据的安全性和一致性非常非常重视。这种时候,肯定是安全和稳定优先,性能后面考虑。
在限制中做权衡,也就是意味着要做大量的选择。但做选择那首先你得知道有哪些选择。
所谓的性能和安全,除了这几个字之外,具体的技术实施上,总得知道都有哪些方案吧。
1.例如java体系、php体系、c体系、还有python/nodejs/golang等,各自有各自的优势劣势,你总得有过相关开发经验才能做出正确的选择吧。道听途说是没有发言权的。
2.虽然现在数据库用的最多的是mysql,但是oracle/pgsql也都有其优势。
3.现在项目几乎没有不用到大数据的,那么大数据的算法至少得有些理解吧,大数据的平台得有些经验吧。
4.玩转整体项目还有许多许多的点,例如代码如何管理、上线部署,如何测试保证bug率,系统的监控,服务器部署,灰度发布等等。
不要听那些一提架构师就好像多么高大上,做的都是些设计师类似的工作,系统设计、软件设计等。那些都是人云亦云YY出来的。
没有哪个互联网公司让你去专门做设计,因为互联网公司领导们统统无一例外需要都是功能的实现,战略战术想法的实现。
所有的大型系统架构,全部都是基于面临的问题一步一步解决迭代出来的。没有场景会让人一步到位(甚至哪怕提前一段提前量)去设计一套牛逼系统的,因为世界变化太快,项目如果不赶紧实现,明天可能就挂了,哪有那些闲心去给未来几年做设计。
所以,做架构师最关键的是对整个项目的把控能力,可以让项目高效率的运转。
第二、卓越的代码能力
想要成为架构师,首先得是一个优秀的程序员。怎么样才算优秀的程序员呢?
光写代码不思考、不学习肯定是不行的。
最明确的,就是得深入掌握各类数据结构、各类设计模式、计算机网络、操作系统、各种常见的架构模式等。这些提的非常多,但是能做到深入理解的我感觉可能没几个人。
包括我自己,当年刚开始看设计模式的时候,1个多月就感觉已经全部理解了。但是之后每次或者复习的时候,或者看到写的非常好的代码的时候,重新去温故此方面的知识,都能感到有新的收获、都会有更深的领悟。
而且,理解也仅仅是开始。如何完完全全的融入自己的代码中,才是关键。
写代码经常也同样充斥着架构设计的感觉。其实我认为,程序员写代码叫编码或coding,而架构师写代码就叫架构设计。
因为两者写代码时考虑问题的角度完全不同。程序员可能更多考虑的是如何实现功能,而优秀的程序员才可能会考虑的例如性能、可读性、可维护性的问题。
而这些对于架构师来说则是必须考虑的,考虑的纬度经常还会更多一些。
所以,不要想着一步到位的跳过优秀程序员而直接成为架构师。不现实。
第三、对某些相关领域要有深度
刚才讲了技术的广度,但是如果什么都知道,但是什么也不善长,没有什么精通的。那依然只能做个程序员。
那么哪些领域算是关键的领域呢?
到此基本就由业务方向的不同而区分不同的架构师了。
例如金融领域的架构师,可能需要金融知识。
例如大数据领域,可能对hadoop/spark/hive之类的大数据领域知识要求深一些。
再如高并发领域,可能对整个系统的性能优化,分布式系统设计等更深入一些。
第四、要有技术洞见
这个技术洞见是借用《重新定义公司》里的词。换个易理解的词,就是技术上的远见卓识。
以事后诸葛亮的方式举几个例子:
1.当年的京东如果选用的不是windows平台,可能发展比现在好不少。
2.百度如果不是李XX的目光短浅,总是比市场慢几拍,现在也不致于被AT远远甩开。
这种事太多太多。
不要感觉好像很虚幻,如果你现在身为一个创业公司的架构师,你现在的一个貌似正确的决策可能直接导致未来公司的大量损失,甚至倒闭。
第五、管理能力
架构师少有不带项目、不带人的,所以管理能力肯定也是必须。
但管理能力是个很大的主题,这里就不多说了。
这些就是我多年架构经验的一些总结。谢谢。
————————————————————————
2017-7-19补充
回头看看,其实我写的也都是些方向性的东西。
但是由于架构师职业的特殊性,真的很难给出一条具体的道路,只要按照这个道路走下去就能成为优秀的架构师。
但有些原则性的方法还是有的:
我说过,作为架构师,其实所谓的设计能力并非关键,因为一个项目完全凭空设计的机会很少,而且也都可以基于当时情况的权衡,直接使用别人们的设计方案的组合。
这就是为什么看架构师相关的帖子看多了,就会发现所谓的分布式架构、大型网站架构,基本来来回回就那么几种。导致是个人出来都能喊两句架构怎样怎样。
那么关键的是什么?是项目的把控能力,以及面对具体问题的解决能力。
而要锻炼项目的把控能力和解决一些具体问题的能力,有时候光靠公司里的项目是不够的。
因为公司项目中你往往只是其中的一员,只是干某个具体的工作,例如前端js、app、后端业务等。项目整体的运转情况你一般是了解不到的。即使运气好,项目负责人对此的把控很到位,而且还愿意全部讲解给你听,但毕竟很多环境你没动手做出,光凭别人说是不大可能有深刻的理解的。
那怎么办?你应该自己抽空全新做一个自己的项目,例如一个BBS网站、一个有后台的app等。网站或app本身不重要,重要是你要自己开发、自己搞定上线系统、搞定监控系统、搞定发布系统、搞定测试系统等等。
就是像一个正式公司的正式产品一样对待这个自己的项目。
这样几个回合下来之后,你就会发现,你对整个项目的感知度提高极大。不再像以前那样,对项目除了自己负责的部分,其它都是迷迷糊糊的。
提升实力从点赞开始。
关于混合语言的问题。这个问题我觉得要辩证的看,混合不一定好,也不一定不好,关键是要看团队的接受能力,单一语言的特点是整个团队的执行效率高,维护成本低;混合语言的特点是软件整体优,但维护成本和整个团队的执行成本就会很高,架构师也应该有这方面的考虑。
学习,保持好奇心,按着“1000”考虑问题,按着“1024”设计架构,总有一天,会成长起来的
一句话概括的话,就是得犯过足够多、足够深刻的错误才行
稍微具体而言的话,架构设计一般有两个层次- 设计性能不敏感、或是低计算量的应用:这是个初级层级,在这个层次上的普遍思路是分解问题,然后通过组合各种“solver”来解决。架构师可以随便翩翩起舞,使用各种“框架”、“类库”,借鉴各种“模式”,发明各种“概念”(这些全部都是solver)。由于计算量低,所以最后总能“条条大路通罗马”
- 性能极端敏感,计算密集的应用:这时候初级层次的很多经验反而起反作用了。因为组合“solver”只能解决计算正确性目标,但不能解决性能目标。所以架构师需要能“脑内模拟”业务需要的必要数据流,然后充分利用(exploit)数据流的特性来尽可能地削减计算、避免瓶颈。这时算法功底就尤为重要,很多第三方的“框架”、“库”只有拆解以后“白盒利用”的意义。性能设计要优先于“代码的封装性”、“可读性”、“可测试性”、“可管理性”以及“团队可分工/协作性”(基本上软件工程里的原则都要让位于性能设计)