你离架构师还有多远?

  软件架构师在整个软件开发过程中都起着重要的作用,并随着开发进程的推进而其职责或关注点不断地变化,总结下面几点。

  在需求阶段,软件架构师主要负责理解和管理非功能性系统需求,比如软件的可维护性、性能、复用性、可靠性、有效性和可测试性等等,此外,架构师还要经常审查客户及市场人员所提出的需求,确认开发团队所提出的设计;

  在需求越来越明确后,架构师的关注点开始转移到组织开发团队成员和开发过程定义上;
  在软件设计阶段,架构师负责对整个软件体系结构、关键构件、接口和开发政策的设计;
  在编码阶段,架构师则成为详细设计者和代码编写者的顾问,并且经常性地要举行一些技术研讨会、技术培训班等;
  随着软件开始测试、集成和交付,集成和测试支持将成为软件架构师的工作重点;
  在软件维护开始时,软件架构师就开始为下一版本的产品是否应该增加新的功能模块进行决策。

  在中国不缺程序员,缺的是高级架构师,先来看看两者的薪酬对比,就知道两者间的差距:

 

   但为什么在如此庞大的基数下,架构师的数量这么少,中间差了什么?对于普通程序员来说,成为高级架构师的门槛主要有以下几点:

1、错误的学习方法。在技术日新月异的今天,谁在单位时间学到的知识更多,谁的学习方法更高效,谁就获得更强的竞争优势。而很多程序员在工作中,还用着学校时的学习方法,非常低效,公司不是学校,啃书本的学习方法已不再有效。

2、完整的知识体系。没有形成系统化的知识架构,最重要的是不知道哪些技术需要重点掌握,学习时频繁踩坑,最终浪费大量时间。

3、对编程的认知。顶级程序员和平庸程序员,本质区别是遇到问题时的思考方式,这就是所谓的顶级程序员思维,一种高效解决问题的思维方式。这种思维方式,不是读几本Java书能学到的,而需要经过大量项目实战,才能总结提炼出来。

4、差的学习环境。很多程序员的学习环境很差,在公司经常加班,工作几年后,发现自己除了更熟悉公司业务外,能力没有得到半点提升,或周末基本不学习,而是出去玩。这么差的自制力和学习环境,很难让能力提到大的提升。

   上面四点,每一点都非常难做到,也正因为这样,才会出现平庸的程序员很多,架构师却凤毛麟角的现象。

  那如何才能克服上面四点,成为一名合格的Java架构师呢?

   俗话说“没有见过好程序,怎么可能写出好程序”,同样,也可以说“不了解架构师的能力、工作,怎么可能成为架构师”,如果没有接触过顶级架构师,那你怎么知道自己要往哪个方向努力?所以,最好的方法是找个顶级架构师,去教你“高效的学习方法”、“完整的知识体系”和“对编程正确的认知”,让他去督促你学习,为你营造出“良好的学习环境”。

  但是大牛很忙,不太可能单独给你开小灶,更不可能每天都给你开1个小时的小灶;而且一个团队里面,如果大牛平时经常给你开小灶,难免会引起其他团队成员的疑惑,我个人认为如果团队里的大牛如果真正有心的话,多给团队培训是最好的。然而做过培训的都知道,准备一场培训是很耗费时间的,课件和材料至少2个小时(还不能是碎片时间),讲解1个小时,大牛们一个月做一次培训已经是很高频了。

  因为第一个原因,所以一般要找大牛,都是带着问题去请教或者探讨。因为回答或者探讨问题无需太多的时间,更多的是靠经验和积累,这种情况下大牛们都是很乐意的,毕竟影响力是大牛的一个重要指标嘛。然而也要特别注意:如果经常问那些书本或者google能够很容易查到的知识,大牛们也会很不耐烦的,毕竟时间宝贵。经常有网友问我诸如“jvm的-Xmn参数如何配置”这类问题,我都是直接回答“请直接去google”,因为这样的问题实在是太多了,如果自己不去系统学习,每个都要问是非常浪费自己和别人的时间的。

  大牛不多,不太可能每个团队都有技术大牛,只能说团队里面会有比你水平高的人,即使他每天给你开小灶,最终你也只能提升到他的水平;而如果是跨团队的技术大牛,由于工作安排和分配的原因,直接请教和辅导的机会是比较少的,单凭参加几次大牛的培训,是不太可能就成为技术大牛的。

  所以要想成为技术大牛,首先还是要明白“主要靠自己”这个道理,适当的时候可以通过请教大牛或者和大牛探讨来提升自己,但大部分时间还是自己系统性、有针对性的提升。

  既然java架构师,首先你要是一个高级java工程师,熟练使用各种框架,并知道它们实现的原理。

  1. jvm虚拟机原理、调优,懂得jvm能让你写出性能更好的代码;
  2. 池技术,什么对象池,连接池,线程池,java反射技术,写框架必备的技术,但是有严重的性能问题,替代方案java字节码技术;
  3. nio,值得注意的是“直接内存”的特点,使用场景;
  4. java多线程同步异步;
  5. java各种集合对象的实现原理,了解这些可以让你在解决问题时选择合适的数据结构,高效的解决问题,比如hashmap的实现原理,好多五年以上经验的人都弄不清楚,还有为什扩容时有性能问题?不弄清楚这些原理,就写不出高效的代码,还会认为自己做的很对;总之一句话越基础的东西越重要,很多人认为自己会用它们写代码了,其实仅仅是知道如何调用api而已,离会用还差的远。
  6. 熟练使用各种数据结构和算法,数组、哈希、链表、排序树...,就是一句话要么是时间换空间要么是空间换时间,这里展开可以说一大堆,需要有一定的应用经验,用于解决各种性能或业务上的问题。

熟练使用linux操作系统,必备。

  1. 熟悉tcp协议,创建连接三次握手和断开连接四次握手的整个过程,不了解的话,无法对高并发网络应用做优化;
  2. 熟悉http协议,尤其是http头,我发现好多工作五年以上的都弄不清session和cookie的生命周期以及它们之间的关联。
  3. 系统集群、负载均衡、反向代理、动静分离,网站静态化。
  4. 分布式存储系统nfs,fastdfs,tfs,Hadoop了解他们的优缺点,适用场景。
  5. 分布式缓存技术memcached,redis,提高系统性能必备,一句话,把硬盘上的内容放到内存里来提速,顺便提个算法一致性hash。
  6. 工具nginx必备技能超级好用,高性能,基本不会挂掉的服务器,功能多多,解决各种问题。
  7. 数据库的设计能力,mysql必备,最基础的数据库工具,免费好用,对它基本的参数优化,慢查询日志分析,主从复制的配置,至少要成为半个mysqldba。其他nosql数据库如mongodb。
  8. 还有队列中间件。如消息推送,可以先把消息写入数据库,推送放队列服务器上,由推送服务器去队列获取处理,这样就可以将消息放数据库和队列里后直接给用户反馈,推送过程则由推送服务器和队列服务器完成,好处异步处理、缓解服务器压力,解藕系统。

  那成为架构师所需要具备哪些技能?

  架构师思考的是全局的东西,是如何组织你的系统,以达到业务要求,性能要求,具备可扩展性(scalability),可拓展性(extendability),前后兼容性等。可能涉及到的东西包括了从硬件到软件的方方面面。

  一个合格的架构师要耐得住寂寞,在同事不停的在打荣耀而你只能不停的学习,是踩着坑上位的,是无数次推翻之前自己设计 的 “狗屎”架构,无数次日日夜夜加班而炼成的。

  架构师不仅要上知技术实现细节,而且还要会项目管理、设计理论、性能优化、熟练使用各种工具,为公司各种业务提供技术支持,从前端到后台再到数据库、运维,哪里需要去哪里,还要一副好口才能睡服领导同事。

  现在的架构师还要懂微服务、不会点分布式、大数据技术、机器学习也会被鄙视的。

 

  想成为架构师不是懂了一大堆技术就可以了,这些是解决问题的基础、是工具,如果这些技术问题不懂怎样做到,如何能够找到解决方案呢?这是成为架构师的必要条件。
  架构师还要针对业务特点、系统的性能要求提出能解决问题成本最低的设计方案才合格,人家一个几百人用户的系统,访问量不大,数据量小,你给人家上集群、上分布式存储、上高端服务器,为了架构而架构,这是不可取的,所以总结两点:架构师的作用就是第一满足业务需求,第二最低的硬件网络成本和技术维护成本。
  如果想要成为一名优秀的架构师还需要根据业务发展情况,提前预见发展到下一个阶段系统架构的解决方案,并且设计当前架构时将架构的升级扩展考虑进去,做到易于升级;否则等系统瓶颈来了,出问题了再去出方案,或现有架构无法扩展直接扔掉重做,或扩展麻烦问题一大堆,这会对企业造成损失。

大厂的大神还有如下的几个建议:

  首先是要多读一些书,其中最基础的是类似于重构和设计模式这种书,你需要知道很多小尺度级别上的问题解决技巧(如果你要做导演,你首先要做得是能熟练地把一个句子翻译为一组镜头),以及这些作者梳理问题的方式,反过来问一下自己,如果让你来写设计模式这本书,你有哪些知识点可以写?你如何组织这些知识点?如何让大家接受你的观点。

  看完这两本书之后,非常推荐你看一下 Martin Fowler 写的《企业应用架构模式》和 Eric Evans 的《领域驱动设计》这类书,他能扩大你的视野,专注于更有意义的问题,而不是设计模式究竟有多少种这种缺乏意义的问题。有一句话叫,“如果要成功,就要远离那些廉价的娱乐”。类似的,对于软件工程师来讲,要想让自己更强,就要远离那些廉价的争论(vim vs emacs, linux vs unix, redhat vs debian, 这些争论其实并没有太大的价值)。

  其次,你要对大量开源软件的实际特性有深入的了解,容量究竟多大?高可用怎么做?如何扩容?是否易维护?这些知识部分来自网上的各种测试和经验文章,部分还要来自你的亲手测试。作为架构师,你的每一个技术选型都是在挖坑,给你的开发、测试、运维团队挖坑,而你的作用之一,就是保证你的团队能够在你的帮助下从坑里走出来。

  另外,要解决很多大尺度的问题,你需要从很多同行去吸收经验,我个人的经验就是,阅读每年两次 QCon 和 ArchSummit 架构相关的幻灯片,先只看题目和问题部分,自己想一想解决方案是啥,然后再看一下演讲者给出的解答,通过这种方式来淬炼自己的思维,丰富自己的工具箱。我想提醒的一点是,由于软件行业还远不成熟,所以一个架构师会长期跟进一个项目,这就导致了一个架构师如果不主动去练习的话,一辈子也做不了几个架构,至少相对于建筑专业的结构工程师来讲,我们每年的项目缺少少很多。你做的架构越少,你就越容易自满。

  最后,我希望你是一个终身学习者,不管多忙,一定要规划你的学习时间,一个星期也许不用太多,几个小时即可,但这几个小时一定要用在刀刃上,所以最好是哪些需要几十个小时甚至更多时间才能弄清楚的课题,而且一直要坚持到这个课题结束。千万不能是学一点这个概念,遇到新事物,就马上转移方向。如果你有这样的习惯,我建议你先把新想法放到一个池子里,等手边的课题学习完,再到池子里边捞一个新课题来继续学习。不过关于学习,这个是一个很大的话题,就不在这儿阐述了。

那如何学习呢?

  如何掌握有效的学习方法呢,参考网友给的一些不错的方法拿来分享,光看不用效果很差,怎么办?

例如:

  1. 学习了jvm的垃圾回收,但是线上比较少出现FGC导致的卡顿问题,就算出现了,恢复业务也是第一位的,不太可能线上出现问题然后让每个同学都去练一下手,那怎么去实践这些jvm的知识和技能呢?

  2. Netty我也看了,也了解了Reactor的原理,但是我不可能参与Netty开发,怎么去让自己真正掌握Reactor异步模式呢?

  3. 看了《高性能MySQL》,但是线上的数据库都是DBA管理的,测试环境的数据库感觉又是随便配置的,我怎么去验证这些技术呢?

  4. 框架封装了DAL层,数据库的访问我们都不需要操心,我们怎么去了解分库分表实现?

诸如此类问题还有很多,我这里分享一下个人的经验,其实就是3个词:learning、trying、teaching!

1)Learning

  这个是第一阶段,看书、google、看视频、看别人的博客都可以,但要注意一点是“系统化”,特别是一些基础性的东西,例如JVM原理、Java编程、网络编程,HTTP协议等等,这些基础技术不能只通过google或者博客学习,我的做法一般是先完整的看完一本书全面的了解,然后再通过google、视频、博客去有针对性的查找一些有疑问的地方,或者一些技巧。

2)Trying

  这个步骤就是解答前面提到的很多同学的疑惑的关键点,形象来说就是“自己动手丰衣足食”,也就是自己去尝试搭建一些模拟环境,自己写一些测试程序。例如:

  1. Jvm垃圾回收:可以自己写一个简单的测试程序,分配内存不释放,然后调整各种jvm启动参数,再运行的过程中使用jstack、jstat等命令查看jvm的堆内存分布和垃圾回收情况。这样的程序写起来很简单,简单一点的就几行,复杂一点的也就几十行。

  2. Reactor原理:自己真正去尝试写一个Reactor模式的Demo,不要以为这个很难,最简单的Reactor模式代码量(包括注释)不超过200行(可以参考Doug Lee的PPT)。自己写完后,再去看看netty怎么做,一对比理解就更加深刻了。

  3. MySQL:既然有线上的配置可以参考,那可以直接让DBA将线上配置发给我们(注意去掉敏感信息),直接学习;然后自己搭建一个MySQL环境,用线上的配置启动;要知道很多同学用了很多年MySQL,但是连个简单的MySQL环境都搭不起来。

  4. 框架封装了DAL层:可以自己用JDBC尝试去写一个分库分表的简单实现,然后与框架的实现进行对比,看看差异在哪里。

  5. 用浏览器的工具查看HTTP缓存实现,看看不同种类的网站,不同类型的资源,具体是如何控制缓存的;也可以自己用Python写一个简单的HTTP服务器,模拟返回各种HTTP Headers来观察浏览器的反应。

  还有很多方法,这里就不一一列举,简单来说,就是要将学到的东西真正试试,才能理解更加深刻,印第安人有一句谚语:I hear and I forget. I see and I remember. I do and I understand ,而且“试试”其实可以比较简单,很多时候我们都可以自己动手做。

  当然,如果能够在实际工作中使用,效果会更好,毕竟实际的线上环境和业务复杂度不是我们写个模拟程序就能够模拟的,但这样的机会可遇不可求,大部分情况我们还真的只能靠自己模拟,然后等到真正业务要用的时候,能够信手拈来。

3)Teaching

  一般来说,经过Learning和Trying,能掌握70%左右,但要真正掌握,我觉得一定要做到能够跟别人讲清楚。因为在讲的时候,我们既需要将一个知识点系统化,也需要考虑各种细节,这会促使我们进一步思考和学习。同时,讲出来后看或者听的人可以有不同的理解,或者有新的补充,这相当于继续完善了整个知识技能体系。

  这样的例子很多,包括我自己写博客的时候经常遇到,本来我觉得自己已经掌握很全面了,但一写就发现很多点没考虑到;组内培训的时候也经常看到,有的同学写了PPT,但是讲的时候,大家一问,或者一讨论,就会发现很多点还没有讲清楚,或者有的点其实是理解错了。写PPT、讲PPT、讨论PPT,这个流程全部走一遍,基本上对一个知识点掌握就比较全面了。

  最后撒点鸡汤,所谓学而时习之,温故而知新,即使是架构师也需要不停的学习、思考,新的技术层出不穷,不变的是那颗不甘安逸的心。

posted @ 2018-04-10 08:51  欢醉  阅读(5463)  评论(23编辑  收藏  举报